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 -----BEGIN PGP SIGNATURE----- iQJMBAABCgA2FiEEACwLKSDmq+9RDv5P4cpzo8lZTiQFAmQ0mPkYHGNodW5rdWFu Zy5odUBrZXJuZWwub3JnAAoJEOHKc6PJWU4kv/wP/ixaRMppN9cIVB9UICxn31xJ vzMyXScZ2cei/0nlTtWh2BOiHuw5BPvdUK9W+FqNDTf/EgRE7q9TLvEyB6DGEGOM 2Ahkcqw2rSnigP5rGFUKt9zFoVIc6YtiCG2jS65Q3UhuoBvoQZckTi/HhKGlw9KQ piQCXZfTCSg67FHX109J1ASkh4B7hio8Pnk9X0+JqGI1U+y2RgWKhJV+o8BVmImE 3VFqEbqNPswy2GMYUWyRPTz89dw6ZPHswwbRPuOD5kGCY82QAZNxoVx8FkQD4GCv 1QTpZKb3dW8dUQBnkxXGtZ+8M/0H9ZjSvr4yjg0HF2HFQPof3UPie0MG7e4X1xUw 6spB4jSacvMHw89oIWg2eaIJ6D9iJVkevp8PiJsxS/pgvqHM4gCW9mCsEHxKVMQb M2I0Z5tyfmiljrsiK0TDyv5uKHuozW6SX/nmCfLwvL4c1k/KOZuA7JBAEH2zMTMs CBXMnFa9MgaVXdamEu/tbUOBfbaSsXde7dKWds1jYwIF3bAwRfuE/gtSkBVEqu1W EABKUZTyd8/VwfsaEaQSF7N3e7bBSf5tjGZH/m2RHp2Eu/FsfeWxZK8/l8LMmGnr 4gF/dHTNOFMBg469EXS8BKouh40kJJjoj0c1IAOp5wcmH73RuGgXExbnVu3W7siC fZPLDzUTSak5qC7tcpP1 =T2t7 -----END PGP SIGNATURE----- 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: Daniel 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
This commit is contained in:
commit
55bf14961d
|
@ -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
|
||||
|
|
|
@ -0,0 +1,182 @@
|
|||
# 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[] = {
|
||||
|
|
|
@ -0,0 +1,547 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2021 MediaTek Inc.
|
||||
*/
|
||||
|
||||
#include <drm/drm_fourcc.h>
|
||||
#include <drm/drm_of.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/component.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/reset.h>
|
||||
#include <linux/soc/mediatek/mtk-cmdq.h>
|
||||
#include <linux/soc/mediatek/mtk-mmsys.h>
|
||||
#include <linux/soc/mediatek/mtk-mutex.h>
|
||||
|
||||
#include "mtk_disp_drv.h"
|
||||
#include "mtk_drm_crtc.h"
|
||||
#include "mtk_drm_ddp_comp.h"
|
||||
#include "mtk_drm_drv.h"
|
||||
#include "mtk_ethdr.h"
|
||||
|
||||
#define MTK_OVL_ADAPTOR_RDMA_MAX_WIDTH 1920
|
||||
#define MTK_OVL_ADAPTOR_LAYER_NUM 4
|
||||
|
||||
enum mtk_ovl_adaptor_comp_type {
|
||||
OVL_ADAPTOR_TYPE_RDMA = 0,
|
||||
OVL_ADAPTOR_TYPE_MERGE,
|
||||
OVL_ADAPTOR_TYPE_ETHDR,
|
||||
OVL_ADAPTOR_TYPE_NUM,
|
||||
};
|
||||
|
||||
enum mtk_ovl_adaptor_comp_id {
|
||||
OVL_ADAPTOR_MDP_RDMA0,
|
||||
OVL_ADAPTOR_MDP_RDMA1,
|
||||
OVL_ADAPTOR_MDP_RDMA2,
|
||||
OVL_ADAPTOR_MDP_RDMA3,
|
||||
OVL_ADAPTOR_MDP_RDMA4,
|
||||
OVL_ADAPTOR_MDP_RDMA5,
|
||||
OVL_ADAPTOR_MDP_RDMA6,
|
||||
OVL_ADAPTOR_MDP_RDMA7,
|
||||
OVL_ADAPTOR_MERGE0,
|
||||
OVL_ADAPTOR_MERGE1,
|
||||
OVL_ADAPTOR_MERGE2,
|
||||
OVL_ADAPTOR_MERGE3,
|
||||
OVL_ADAPTOR_ETHDR0,
|
||||
OVL_ADAPTOR_ID_MAX
|
||||
};
|
||||
|
||||
struct ovl_adaptor_comp_match {
|
||||
enum mtk_ovl_adaptor_comp_type type;
|
||||
int alias_id;
|
||||
};
|
||||
|
||||
struct mtk_disp_ovl_adaptor {
|
||||
struct device *ovl_adaptor_comp[OVL_ADAPTOR_ID_MAX];
|
||||
struct device *mmsys_dev;
|
||||
bool children_bound;
|
||||
};
|
||||
|
||||
static const char * const private_comp_stem[OVL_ADAPTOR_TYPE_NUM] = {
|
||||
[OVL_ADAPTOR_TYPE_RDMA] = "vdo1-rdma",
|
||||
[OVL_ADAPTOR_TYPE_MERGE] = "merge",
|
||||
[OVL_ADAPTOR_TYPE_ETHDR] = "ethdr",
|
||||
};
|
||||
|
||||
static const struct ovl_adaptor_comp_match comp_matches[OVL_ADAPTOR_ID_MAX] = {
|
||||
[OVL_ADAPTOR_MDP_RDMA0] = { OVL_ADAPTOR_TYPE_RDMA, 0 },
|
||||
[OVL_ADAPTOR_MDP_RDMA1] = { OVL_ADAPTOR_TYPE_RDMA, 1 },
|
||||
[OVL_ADAPTOR_MDP_RDMA2] = { OVL_ADAPTOR_TYPE_RDMA, 2 },
|
||||
[OVL_ADAPTOR_MDP_RDMA3] = { OVL_ADAPTOR_TYPE_RDMA, 3 },
|
||||
[OVL_ADAPTOR_MDP_RDMA4] = { OVL_ADAPTOR_TYPE_RDMA, 4 },
|
||||
[OVL_ADAPTOR_MDP_RDMA5] = { OVL_ADAPTOR_TYPE_RDMA, 5 },
|
||||
[OVL_ADAPTOR_MDP_RDMA6] = { OVL_ADAPTOR_TYPE_RDMA, 6 },
|
||||
[OVL_ADAPTOR_MDP_RDMA7] = { OVL_ADAPTOR_TYPE_RDMA, 7 },
|
||||
[OVL_ADAPTOR_MERGE0] = { OVL_ADAPTOR_TYPE_MERGE, 1 },
|
||||
[OVL_ADAPTOR_MERGE1] = { OVL_ADAPTOR_TYPE_MERGE, 2 },
|
||||
[OVL_ADAPTOR_MERGE2] = { OVL_ADAPTOR_TYPE_MERGE, 3 },
|
||||
[OVL_ADAPTOR_MERGE3] = { OVL_ADAPTOR_TYPE_MERGE, 4 },
|
||||
[OVL_ADAPTOR_ETHDR0] = { OVL_ADAPTOR_TYPE_ETHDR, 0 },
|
||||
};
|
||||
|
||||
void mtk_ovl_adaptor_layer_config(struct device *dev, unsigned int idx,
|
||||
struct mtk_plane_state *state,
|
||||
struct cmdq_pkt *cmdq_pkt)
|
||||
{
|
||||
struct mtk_disp_ovl_adaptor *ovl_adaptor = dev_get_drvdata(dev);
|
||||
struct mtk_plane_pending_state *pending = &state->pending;
|
||||
struct mtk_mdp_rdma_cfg rdma_config = {0};
|
||||
struct device *rdma_l;
|
||||
struct device *rdma_r;
|
||||
struct device *merge;
|
||||
struct device *ethdr;
|
||||
const struct drm_format_info *fmt_info = drm_format_info(pending->format);
|
||||
bool use_dual_pipe = false;
|
||||
unsigned int align_width;
|
||||
unsigned int l_w = 0;
|
||||
unsigned int r_w = 0;
|
||||
|
||||
dev_dbg(dev, "%s+ idx:%d, enable:%d, fmt:0x%x\n", __func__, idx,
|
||||
pending->enable, pending->format);
|
||||
dev_dbg(dev, "addr 0x%pad, fb w:%d, {%d,%d,%d,%d}\n",
|
||||
&pending->addr, (pending->pitch / fmt_info->cpp[0]),
|
||||
pending->x, pending->y, pending->width, pending->height);
|
||||
|
||||
rdma_l = ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_MDP_RDMA0 + 2 * idx];
|
||||
rdma_r = ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_MDP_RDMA0 + 2 * idx + 1];
|
||||
merge = ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_MERGE0 + idx];
|
||||
ethdr = ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_ETHDR0];
|
||||
|
||||
if (!pending->enable) {
|
||||
mtk_merge_stop_cmdq(merge, cmdq_pkt);
|
||||
mtk_mdp_rdma_stop(rdma_l, cmdq_pkt);
|
||||
mtk_mdp_rdma_stop(rdma_r, cmdq_pkt);
|
||||
mtk_ethdr_layer_config(ethdr, idx, state, cmdq_pkt);
|
||||
return;
|
||||
}
|
||||
|
||||
/* ETHDR is in 1T2P domain, width needs to be 2 pixels align */
|
||||
align_width = ALIGN_DOWN(pending->width, 2);
|
||||
|
||||
if (align_width > MTK_OVL_ADAPTOR_RDMA_MAX_WIDTH)
|
||||
use_dual_pipe = true;
|
||||
|
||||
if (use_dual_pipe) {
|
||||
l_w = (align_width / 2) + ((pending->width / 2) % 2);
|
||||
r_w = align_width - l_w;
|
||||
} else {
|
||||
l_w = align_width;
|
||||
}
|
||||
mtk_merge_advance_config(merge, l_w, r_w, pending->height, 0, 0, cmdq_pkt);
|
||||
mtk_mmsys_merge_async_config(ovl_adaptor->mmsys_dev, idx, align_width / 2,
|
||||
pending->height, cmdq_pkt);
|
||||
|
||||
rdma_config.width = l_w;
|
||||
rdma_config.height = pending->height;
|
||||
rdma_config.addr0 = pending->addr;
|
||||
rdma_config.pitch = pending->pitch;
|
||||
rdma_config.fmt = pending->format;
|
||||
rdma_config.color_encoding = pending->color_encoding;
|
||||
mtk_mdp_rdma_config(rdma_l, &rdma_config, cmdq_pkt);
|
||||
|
||||
if (use_dual_pipe) {
|
||||
rdma_config.x_left = l_w;
|
||||
rdma_config.width = r_w;
|
||||
mtk_mdp_rdma_config(rdma_r, &rdma_config, cmdq_pkt);
|
||||
}
|
||||
|
||||
mtk_merge_start_cmdq(merge, cmdq_pkt);
|
||||
|
||||
mtk_mdp_rdma_start(rdma_l, cmdq_pkt);
|
||||
if (use_dual_pipe)
|
||||
mtk_mdp_rdma_start(rdma_r, cmdq_pkt);
|
||||
else
|
||||
mtk_mdp_rdma_stop(rdma_r, cmdq_pkt);
|
||||
|
||||
mtk_ethdr_layer_config(ethdr, idx, state, cmdq_pkt);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
struct mtk_disp_ovl_adaptor *ovl_adaptor = dev_get_drvdata(dev);
|
||||
|
||||
mtk_ethdr_config(ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_ETHDR0], w, h,
|
||||
vrefresh, bpc, cmdq_pkt);
|
||||
}
|
||||
|
||||
void mtk_ovl_adaptor_start(struct device *dev)
|
||||
{
|
||||
struct mtk_disp_ovl_adaptor *ovl_adaptor = dev_get_drvdata(dev);
|
||||
|
||||
mtk_ethdr_start(ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_ETHDR0]);
|
||||
}
|
||||
|
||||
void mtk_ovl_adaptor_stop(struct device *dev)
|
||||
{
|
||||
struct mtk_disp_ovl_adaptor *ovl_adaptor = dev_get_drvdata(dev);
|
||||
|
||||
mtk_ethdr_stop(ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_ETHDR0]);
|
||||
}
|
||||
|
||||
int mtk_ovl_adaptor_clk_enable(struct device *dev)
|
||||
{
|
||||
struct mtk_disp_ovl_adaptor *ovl_adaptor = dev_get_drvdata(dev);
|
||||
struct device *comp;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < OVL_ADAPTOR_MERGE0; i++) {
|
||||
comp = ovl_adaptor->ovl_adaptor_comp[i];
|
||||
ret = pm_runtime_get_sync(comp);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to enable power domain %d, err %d\n", i, ret);
|
||||
goto pwr_err;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < OVL_ADAPTOR_ID_MAX; i++) {
|
||||
comp = ovl_adaptor->ovl_adaptor_comp[i];
|
||||
|
||||
if (i < OVL_ADAPTOR_MERGE0)
|
||||
ret = mtk_mdp_rdma_clk_enable(comp);
|
||||
else if (i < OVL_ADAPTOR_ETHDR0)
|
||||
ret = mtk_merge_clk_enable(comp);
|
||||
else
|
||||
ret = mtk_ethdr_clk_enable(comp);
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed to enable clock %d, err %d\n", i, ret);
|
||||
goto clk_err;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
clk_err:
|
||||
while (--i >= 0) {
|
||||
comp = ovl_adaptor->ovl_adaptor_comp[i];
|
||||
if (i < OVL_ADAPTOR_MERGE0)
|
||||
mtk_mdp_rdma_clk_disable(comp);
|
||||
else if (i < OVL_ADAPTOR_ETHDR0)
|
||||
mtk_merge_clk_disable(comp);
|
||||
else
|
||||
mtk_ethdr_clk_disable(comp);
|
||||
}
|
||||
i = OVL_ADAPTOR_MERGE0;
|
||||
|
||||
pwr_err:
|
||||
while (--i >= 0)
|
||||
pm_runtime_put(ovl_adaptor->ovl_adaptor_comp[i]);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void mtk_ovl_adaptor_clk_disable(struct device *dev)
|
||||
{
|
||||
struct mtk_disp_ovl_adaptor *ovl_adaptor = dev_get_drvdata(dev);
|
||||
struct device *comp;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < OVL_ADAPTOR_ID_MAX; i++) {
|
||||
comp = ovl_adaptor->ovl_adaptor_comp[i];
|
||||
|
||||
if (i < OVL_ADAPTOR_MERGE0) {
|
||||
mtk_mdp_rdma_clk_disable(comp);
|
||||
pm_runtime_put(comp);
|
||||
} else if (i < OVL_ADAPTOR_ETHDR0) {
|
||||
mtk_merge_clk_disable(comp);
|
||||
} else {
|
||||
mtk_ethdr_clk_disable(comp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int mtk_ovl_adaptor_layer_nr(struct device *dev)
|
||||
{
|
||||
return MTK_OVL_ADAPTOR_LAYER_NUM;
|
||||
}
|
||||
|
||||
struct device *mtk_ovl_adaptor_dma_dev_get(struct device *dev)
|
||||
{
|
||||
struct mtk_disp_ovl_adaptor *ovl_adaptor = dev_get_drvdata(dev);
|
||||
|
||||
return ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_MDP_RDMA0];
|
||||
}
|
||||
|
||||
void mtk_ovl_adaptor_register_vblank_cb(struct device *dev, void (*vblank_cb)(void *),
|
||||
void *vblank_cb_data)
|
||||
{
|
||||
struct mtk_disp_ovl_adaptor *ovl_adaptor = dev_get_drvdata(dev);
|
||||
|
||||
mtk_ethdr_register_vblank_cb(ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_ETHDR0],
|
||||
vblank_cb, vblank_cb_data);
|
||||
}
|
||||
|
||||
void mtk_ovl_adaptor_unregister_vblank_cb(struct device *dev)
|
||||
{
|
||||
struct mtk_disp_ovl_adaptor *ovl_adaptor = dev_get_drvdata(dev);
|
||||
|
||||
mtk_ethdr_unregister_vblank_cb(ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_ETHDR0]);
|
||||
}
|
||||
|
||||
void mtk_ovl_adaptor_enable_vblank(struct device *dev)
|
||||
{
|
||||
struct mtk_disp_ovl_adaptor *ovl_adaptor = dev_get_drvdata(dev);
|
||||
|
||||
mtk_ethdr_enable_vblank(ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_ETHDR0]);
|
||||
}
|
||||
|
||||
void mtk_ovl_adaptor_disable_vblank(struct device *dev)
|
||||
{
|
||||
struct mtk_disp_ovl_adaptor *ovl_adaptor = dev_get_drvdata(dev);
|
||||
|
||||
mtk_ethdr_disable_vblank(ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_ETHDR0]);
|
||||
}
|
||||
|
||||
const u32 *mtk_ovl_adaptor_get_formats(struct device *dev)
|
||||
{
|
||||
struct mtk_disp_ovl_adaptor *ovl_adaptor = dev_get_drvdata(dev);
|
||||
|
||||
return mtk_mdp_rdma_get_formats(ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_MDP_RDMA0]);
|
||||
}
|
||||
|
||||
size_t mtk_ovl_adaptor_get_num_formats(struct device *dev)
|
||||
{
|
||||
struct mtk_disp_ovl_adaptor *ovl_adaptor = dev_get_drvdata(dev);
|
||||
|
||||
return mtk_mdp_rdma_get_num_formats(ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_MDP_RDMA0]);
|
||||
}
|
||||
|
||||
void mtk_ovl_adaptor_add_comp(struct device *dev, struct mtk_mutex *mutex)
|
||||
{
|
||||
mtk_mutex_add_comp(mutex, DDP_COMPONENT_MDP_RDMA0);
|
||||
mtk_mutex_add_comp(mutex, DDP_COMPONENT_MDP_RDMA1);
|
||||
mtk_mutex_add_comp(mutex, DDP_COMPONENT_MDP_RDMA2);
|
||||
mtk_mutex_add_comp(mutex, DDP_COMPONENT_MDP_RDMA3);
|
||||
mtk_mutex_add_comp(mutex, DDP_COMPONENT_MDP_RDMA4);
|
||||
mtk_mutex_add_comp(mutex, DDP_COMPONENT_MDP_RDMA5);
|
||||
mtk_mutex_add_comp(mutex, DDP_COMPONENT_MDP_RDMA6);
|
||||
mtk_mutex_add_comp(mutex, DDP_COMPONENT_MDP_RDMA7);
|
||||
mtk_mutex_add_comp(mutex, DDP_COMPONENT_MERGE1);
|
||||
mtk_mutex_add_comp(mutex, DDP_COMPONENT_MERGE2);
|
||||
mtk_mutex_add_comp(mutex, DDP_COMPONENT_MERGE3);
|
||||
mtk_mutex_add_comp(mutex, DDP_COMPONENT_MERGE4);
|
||||
mtk_mutex_add_comp(mutex, DDP_COMPONENT_ETHDR_MIXER);
|
||||
}
|
||||
|
||||
void mtk_ovl_adaptor_remove_comp(struct device *dev, struct mtk_mutex *mutex)
|
||||
{
|
||||
mtk_mutex_remove_comp(mutex, DDP_COMPONENT_MDP_RDMA0);
|
||||
mtk_mutex_remove_comp(mutex, DDP_COMPONENT_MDP_RDMA1);
|
||||
mtk_mutex_remove_comp(mutex, DDP_COMPONENT_MDP_RDMA2);
|
||||
mtk_mutex_remove_comp(mutex, DDP_COMPONENT_MDP_RDMA3);
|
||||
mtk_mutex_remove_comp(mutex, DDP_COMPONENT_MDP_RDMA4);
|
||||
mtk_mutex_remove_comp(mutex, DDP_COMPONENT_MDP_RDMA5);
|
||||
mtk_mutex_remove_comp(mutex, DDP_COMPONENT_MDP_RDMA6);
|
||||
mtk_mutex_remove_comp(mutex, DDP_COMPONENT_MDP_RDMA7);
|
||||
mtk_mutex_remove_comp(mutex, DDP_COMPONENT_MERGE1);
|
||||
mtk_mutex_remove_comp(mutex, DDP_COMPONENT_MERGE2);
|
||||
mtk_mutex_remove_comp(mutex, DDP_COMPONENT_MERGE3);
|
||||
mtk_mutex_remove_comp(mutex, DDP_COMPONENT_MERGE4);
|
||||
mtk_mutex_remove_comp(mutex, DDP_COMPONENT_ETHDR_MIXER);
|
||||
}
|
||||
|
||||
void mtk_ovl_adaptor_connect(struct device *dev, struct device *mmsys_dev, unsigned int next)
|
||||
{
|
||||
mtk_mmsys_ddp_connect(mmsys_dev, DDP_COMPONENT_MDP_RDMA0, DDP_COMPONENT_MERGE1);
|
||||
mtk_mmsys_ddp_connect(mmsys_dev, DDP_COMPONENT_MDP_RDMA1, DDP_COMPONENT_MERGE1);
|
||||
mtk_mmsys_ddp_connect(mmsys_dev, DDP_COMPONENT_MDP_RDMA2, DDP_COMPONENT_MERGE2);
|
||||
mtk_mmsys_ddp_connect(mmsys_dev, DDP_COMPONENT_MERGE1, DDP_COMPONENT_ETHDR_MIXER);
|
||||
mtk_mmsys_ddp_connect(mmsys_dev, DDP_COMPONENT_MERGE2, DDP_COMPONENT_ETHDR_MIXER);
|
||||
mtk_mmsys_ddp_connect(mmsys_dev, DDP_COMPONENT_MERGE3, DDP_COMPONENT_ETHDR_MIXER);
|
||||
mtk_mmsys_ddp_connect(mmsys_dev, DDP_COMPONENT_MERGE4, DDP_COMPONENT_ETHDR_MIXER);
|
||||
mtk_mmsys_ddp_connect(mmsys_dev, DDP_COMPONENT_ETHDR_MIXER, next);
|
||||
}
|
||||
|
||||
void mtk_ovl_adaptor_disconnect(struct device *dev, struct device *mmsys_dev, unsigned int next)
|
||||
{
|
||||
mtk_mmsys_ddp_disconnect(mmsys_dev, DDP_COMPONENT_MDP_RDMA0, DDP_COMPONENT_MERGE1);
|
||||
mtk_mmsys_ddp_disconnect(mmsys_dev, DDP_COMPONENT_MDP_RDMA1, DDP_COMPONENT_MERGE1);
|
||||
mtk_mmsys_ddp_disconnect(mmsys_dev, DDP_COMPONENT_MDP_RDMA2, DDP_COMPONENT_MERGE2);
|
||||
mtk_mmsys_ddp_disconnect(mmsys_dev, DDP_COMPONENT_MERGE1, DDP_COMPONENT_ETHDR_MIXER);
|
||||
mtk_mmsys_ddp_disconnect(mmsys_dev, DDP_COMPONENT_MERGE2, DDP_COMPONENT_ETHDR_MIXER);
|
||||
mtk_mmsys_ddp_disconnect(mmsys_dev, DDP_COMPONENT_MERGE3, DDP_COMPONENT_ETHDR_MIXER);
|
||||
mtk_mmsys_ddp_disconnect(mmsys_dev, DDP_COMPONENT_MERGE4, DDP_COMPONENT_ETHDR_MIXER);
|
||||
mtk_mmsys_ddp_disconnect(mmsys_dev, DDP_COMPONENT_ETHDR_MIXER, next);
|
||||
}
|
||||
|
||||
static int ovl_adaptor_comp_get_id(struct device *dev, struct device_node *node,
|
||||
enum mtk_ovl_adaptor_comp_type type)
|
||||
{
|
||||
int alias_id = of_alias_get_id(node, private_comp_stem[type]);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(comp_matches); i++)
|
||||
if (comp_matches[i].type == type &&
|
||||
comp_matches[i].alias_id == alias_id)
|
||||
return i;
|
||||
|
||||
dev_warn(dev, "Failed to get id. type: %d, alias: %d\n", type, alias_id);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static const struct of_device_id mtk_ovl_adaptor_comp_dt_ids[] = {
|
||||
{
|
||||
.compatible = "mediatek,mt8195-vdo1-rdma",
|
||||
.data = (void *)OVL_ADAPTOR_TYPE_RDMA,
|
||||
}, {
|
||||
.compatible = "mediatek,mt8195-disp-merge",
|
||||
.data = (void *)OVL_ADAPTOR_TYPE_MERGE,
|
||||
}, {
|
||||
.compatible = "mediatek,mt8195-disp-ethdr",
|
||||
.data = (void *)OVL_ADAPTOR_TYPE_ETHDR,
|
||||
},
|
||||
{},
|
||||
};
|
||||
|
||||
static int compare_of(struct device *dev, void *data)
|
||||
{
|
||||
return dev->of_node == data;
|
||||
}
|
||||
|
||||
static int ovl_adaptor_comp_init(struct device *dev, struct component_match **match)
|
||||
{
|
||||
struct mtk_disp_ovl_adaptor *priv = dev_get_drvdata(dev);
|
||||
struct device_node *node, *parent;
|
||||
struct platform_device *comp_pdev;
|
||||
|
||||
parent = dev->parent->parent->of_node->parent;
|
||||
|
||||
for_each_child_of_node(parent, node) {
|
||||
const struct of_device_id *of_id;
|
||||
enum mtk_ovl_adaptor_comp_type type;
|
||||
int id;
|
||||
|
||||
of_id = of_match_node(mtk_ovl_adaptor_comp_dt_ids, node);
|
||||
if (!of_id)
|
||||
continue;
|
||||
|
||||
if (!of_device_is_available(node)) {
|
||||
dev_dbg(dev, "Skipping disabled component %pOF\n",
|
||||
node);
|
||||
continue;
|
||||
}
|
||||
|
||||
type = (enum mtk_ovl_adaptor_comp_type)of_id->data;
|
||||
id = ovl_adaptor_comp_get_id(dev, node, type);
|
||||
if (id < 0) {
|
||||
dev_warn(dev, "Skipping unknown component %pOF\n",
|
||||
node);
|
||||
continue;
|
||||
}
|
||||
|
||||
comp_pdev = of_find_device_by_node(node);
|
||||
if (!comp_pdev)
|
||||
return -EPROBE_DEFER;
|
||||
|
||||
priv->ovl_adaptor_comp[id] = &comp_pdev->dev;
|
||||
|
||||
drm_of_component_match_add(dev, match, compare_of, node);
|
||||
dev_dbg(dev, "Adding component match for %pOF\n", node);
|
||||
}
|
||||
|
||||
if (!*match) {
|
||||
dev_err(dev, "No match device for ovl_adaptor\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mtk_disp_ovl_adaptor_comp_bind(struct device *dev, struct device *master,
|
||||
void *data)
|
||||
{
|
||||
struct mtk_disp_ovl_adaptor *priv = dev_get_drvdata(dev);
|
||||
|
||||
if (!priv->children_bound)
|
||||
return -EPROBE_DEFER;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mtk_disp_ovl_adaptor_comp_unbind(struct device *dev, struct device *master,
|
||||
void *data)
|
||||
{
|
||||
}
|
||||
|
||||
static const struct component_ops mtk_disp_ovl_adaptor_comp_ops = {
|
||||
.bind = mtk_disp_ovl_adaptor_comp_bind,
|
||||
.unbind = mtk_disp_ovl_adaptor_comp_unbind,
|
||||
};
|
||||
|
||||
static int mtk_disp_ovl_adaptor_master_bind(struct device *dev)
|
||||
{
|
||||
struct mtk_disp_ovl_adaptor *priv = dev_get_drvdata(dev);
|
||||
int ret;
|
||||
|
||||
ret = component_bind_all(dev, priv->mmsys_dev);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "component_bind_all failed!\n");
|
||||
|
||||
priv->children_bound = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mtk_disp_ovl_adaptor_master_unbind(struct device *dev)
|
||||
{
|
||||
struct mtk_disp_ovl_adaptor *priv = dev_get_drvdata(dev);
|
||||
|
||||
priv->children_bound = false;
|
||||
}
|
||||
|
||||
static const struct component_master_ops mtk_disp_ovl_adaptor_master_ops = {
|
||||
.bind = mtk_disp_ovl_adaptor_master_bind,
|
||||
.unbind = mtk_disp_ovl_adaptor_master_unbind,
|
||||
};
|
||||
|
||||
static int mtk_disp_ovl_adaptor_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct mtk_disp_ovl_adaptor *priv;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct component_match *match = NULL;
|
||||
int ret;
|
||||
|
||||
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
|
||||
platform_set_drvdata(pdev, priv);
|
||||
|
||||
ret = ovl_adaptor_comp_init(dev, &match);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
priv->mmsys_dev = pdev->dev.platform_data;
|
||||
|
||||
component_master_add_with_match(dev, &mtk_disp_ovl_adaptor_master_ops, match);
|
||||
|
||||
pm_runtime_enable(dev);
|
||||
|
||||
ret = component_add(dev, &mtk_disp_ovl_adaptor_comp_ops);
|
||||
if (ret != 0) {
|
||||
pm_runtime_disable(dev);
|
||||
dev_err(dev, "Failed to add component: %d\n", ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mtk_disp_ovl_adaptor_remove(struct platform_device *pdev)
|
||||
{
|
||||
component_master_del(&pdev->dev, &mtk_disp_ovl_adaptor_master_ops);
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct platform_driver mtk_disp_ovl_adaptor_driver = {
|
||||
.probe = mtk_disp_ovl_adaptor_probe,
|
||||
.remove = mtk_disp_ovl_adaptor_remove,
|
||||
.driver = {
|
||||
.name = "mediatek-disp-ovl-adaptor",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
|
@ -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);
|
||||
|
|
|
@ -4,8 +4,6 @@
|
|||
* Author: YT SHEN <yt.shen@mediatek.com>
|
||||
*/
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/component.h>
|
||||
#include <linux/iommu.h>
|
||||
#include <linux/module.h>
|
||||
|
@ -60,7 +58,7 @@ static const struct drm_mode_config_funcs mtk_drm_mode_config_funcs = {
|
|||
.atomic_commit = drm_atomic_helper_commit,
|
||||
};
|
||||
|
||||
static const enum mtk_ddp_comp_id mt2701_mtk_ddp_main[] = {
|
||||
static const unsigned int mt2701_mtk_ddp_main[] = {
|
||||
DDP_COMPONENT_OVL0,
|
||||
DDP_COMPONENT_RDMA0,
|
||||
DDP_COMPONENT_COLOR0,
|
||||
|
@ -68,12 +66,12 @@ static const enum mtk_ddp_comp_id mt2701_mtk_ddp_main[] = {
|
|||
DDP_COMPONENT_DSI0,
|
||||
};
|
||||
|
||||
static const enum mtk_ddp_comp_id mt2701_mtk_ddp_ext[] = {
|
||||
static const unsigned int mt2701_mtk_ddp_ext[] = {
|
||||
DDP_COMPONENT_RDMA1,
|
||||
DDP_COMPONENT_DPI0,
|
||||
};
|
||||
|
||||
static const enum mtk_ddp_comp_id mt7623_mtk_ddp_main[] = {
|
||||
static const unsigned int mt7623_mtk_ddp_main[] = {
|
||||
DDP_COMPONENT_OVL0,
|
||||
DDP_COMPONENT_RDMA0,
|
||||
DDP_COMPONENT_COLOR0,
|
||||
|
@ -81,12 +79,12 @@ static const enum mtk_ddp_comp_id mt7623_mtk_ddp_main[] = {
|
|||
DDP_COMPONENT_DPI0,
|
||||
};
|
||||
|
||||
static const enum mtk_ddp_comp_id mt7623_mtk_ddp_ext[] = {
|
||||
static const unsigned int mt7623_mtk_ddp_ext[] = {
|
||||
DDP_COMPONENT_RDMA1,
|
||||
DDP_COMPONENT_DSI0,
|
||||
};
|
||||
|
||||
static const enum mtk_ddp_comp_id mt2712_mtk_ddp_main[] = {
|
||||
static const unsigned int mt2712_mtk_ddp_main[] = {
|
||||
DDP_COMPONENT_OVL0,
|
||||
DDP_COMPONENT_COLOR0,
|
||||
DDP_COMPONENT_AAL0,
|
||||
|
@ -96,7 +94,7 @@ static const enum mtk_ddp_comp_id mt2712_mtk_ddp_main[] = {
|
|||
DDP_COMPONENT_PWM0,
|
||||
};
|
||||
|
||||
static const enum mtk_ddp_comp_id mt2712_mtk_ddp_ext[] = {
|
||||
static const unsigned int mt2712_mtk_ddp_ext[] = {
|
||||
DDP_COMPONENT_OVL1,
|
||||
DDP_COMPONENT_COLOR1,
|
||||
DDP_COMPONENT_AAL1,
|
||||
|
@ -106,13 +104,13 @@ static const enum mtk_ddp_comp_id mt2712_mtk_ddp_ext[] = {
|
|||
DDP_COMPONENT_PWM1,
|
||||
};
|
||||
|
||||
static const enum mtk_ddp_comp_id mt2712_mtk_ddp_third[] = {
|
||||
static const unsigned int mt2712_mtk_ddp_third[] = {
|
||||
DDP_COMPONENT_RDMA2,
|
||||
DDP_COMPONENT_DSI3,
|
||||
DDP_COMPONENT_PWM2,
|
||||
};
|
||||
|
||||
static enum mtk_ddp_comp_id mt8167_mtk_ddp_main[] = {
|
||||
static unsigned int mt8167_mtk_ddp_main[] = {
|
||||
DDP_COMPONENT_OVL0,
|
||||
DDP_COMPONENT_COLOR0,
|
||||
DDP_COMPONENT_CCORR,
|
||||
|
@ -123,7 +121,7 @@ static enum mtk_ddp_comp_id mt8167_mtk_ddp_main[] = {
|
|||
DDP_COMPONENT_DSI0,
|
||||
};
|
||||
|
||||
static const enum mtk_ddp_comp_id mt8173_mtk_ddp_main[] = {
|
||||
static const unsigned int mt8173_mtk_ddp_main[] = {
|
||||
DDP_COMPONENT_OVL0,
|
||||
DDP_COMPONENT_COLOR0,
|
||||
DDP_COMPONENT_AAL0,
|
||||
|
@ -134,7 +132,7 @@ static const enum mtk_ddp_comp_id mt8173_mtk_ddp_main[] = {
|
|||
DDP_COMPONENT_PWM0,
|
||||
};
|
||||
|
||||
static const enum mtk_ddp_comp_id mt8173_mtk_ddp_ext[] = {
|
||||
static const unsigned int mt8173_mtk_ddp_ext[] = {
|
||||
DDP_COMPONENT_OVL1,
|
||||
DDP_COMPONENT_COLOR1,
|
||||
DDP_COMPONENT_GAMMA,
|
||||
|
@ -142,7 +140,7 @@ static const enum mtk_ddp_comp_id mt8173_mtk_ddp_ext[] = {
|
|||
DDP_COMPONENT_DPI0,
|
||||
};
|
||||
|
||||
static const enum mtk_ddp_comp_id mt8183_mtk_ddp_main[] = {
|
||||
static const unsigned int mt8183_mtk_ddp_main[] = {
|
||||
DDP_COMPONENT_OVL0,
|
||||
DDP_COMPONENT_OVL_2L0,
|
||||
DDP_COMPONENT_RDMA0,
|
||||
|
@ -154,13 +152,13 @@ static const enum mtk_ddp_comp_id mt8183_mtk_ddp_main[] = {
|
|||
DDP_COMPONENT_DSI0,
|
||||
};
|
||||
|
||||
static const enum mtk_ddp_comp_id mt8183_mtk_ddp_ext[] = {
|
||||
static const unsigned int mt8183_mtk_ddp_ext[] = {
|
||||
DDP_COMPONENT_OVL_2L1,
|
||||
DDP_COMPONENT_RDMA1,
|
||||
DDP_COMPONENT_DPI0,
|
||||
};
|
||||
|
||||
static const enum mtk_ddp_comp_id mt8186_mtk_ddp_main[] = {
|
||||
static const unsigned int mt8186_mtk_ddp_main[] = {
|
||||
DDP_COMPONENT_OVL0,
|
||||
DDP_COMPONENT_RDMA0,
|
||||
DDP_COMPONENT_COLOR0,
|
||||
|
@ -172,13 +170,25 @@ static const enum mtk_ddp_comp_id mt8186_mtk_ddp_main[] = {
|
|||
DDP_COMPONENT_DSI0,
|
||||
};
|
||||
|
||||
static const enum mtk_ddp_comp_id mt8186_mtk_ddp_ext[] = {
|
||||
static const unsigned int mt8186_mtk_ddp_ext[] = {
|
||||
DDP_COMPONENT_OVL_2L0,
|
||||
DDP_COMPONENT_RDMA1,
|
||||
DDP_COMPONENT_DPI0,
|
||||
};
|
||||
|
||||
static const enum mtk_ddp_comp_id mt8192_mtk_ddp_main[] = {
|
||||
static const unsigned int mt8188_mtk_ddp_main[] = {
|
||||
DDP_COMPONENT_OVL0,
|
||||
DDP_COMPONENT_RDMA0,
|
||||
DDP_COMPONENT_COLOR0,
|
||||
DDP_COMPONENT_CCORR,
|
||||
DDP_COMPONENT_AAL0,
|
||||
DDP_COMPONENT_GAMMA,
|
||||
DDP_COMPONENT_POSTMASK0,
|
||||
DDP_COMPONENT_DITHER0,
|
||||
DDP_COMPONENT_DP_INTF0,
|
||||
};
|
||||
|
||||
static const unsigned int mt8192_mtk_ddp_main[] = {
|
||||
DDP_COMPONENT_OVL0,
|
||||
DDP_COMPONENT_OVL_2L0,
|
||||
DDP_COMPONENT_RDMA0,
|
||||
|
@ -191,13 +201,13 @@ static const enum mtk_ddp_comp_id mt8192_mtk_ddp_main[] = {
|
|||
DDP_COMPONENT_DSI0,
|
||||
};
|
||||
|
||||
static const enum mtk_ddp_comp_id mt8192_mtk_ddp_ext[] = {
|
||||
static const unsigned int mt8192_mtk_ddp_ext[] = {
|
||||
DDP_COMPONENT_OVL_2L2,
|
||||
DDP_COMPONENT_RDMA4,
|
||||
DDP_COMPONENT_DPI0,
|
||||
};
|
||||
|
||||
static const enum mtk_ddp_comp_id mt8195_mtk_ddp_main[] = {
|
||||
static const unsigned int mt8195_mtk_ddp_main[] = {
|
||||
DDP_COMPONENT_OVL0,
|
||||
DDP_COMPONENT_RDMA0,
|
||||
DDP_COMPONENT_COLOR0,
|
||||
|
@ -210,19 +220,19 @@ static const enum mtk_ddp_comp_id mt8195_mtk_ddp_main[] = {
|
|||
DDP_COMPONENT_DP_INTF0,
|
||||
};
|
||||
|
||||
static const unsigned int mt8195_mtk_ddp_ext[] = {
|
||||
DDP_COMPONENT_DRM_OVL_ADAPTOR,
|
||||
DDP_COMPONENT_MERGE5,
|
||||
DDP_COMPONENT_DP_INTF1,
|
||||
};
|
||||
|
||||
static const struct mtk_mmsys_driver_data mt2701_mmsys_driver_data = {
|
||||
.main_path = mt2701_mtk_ddp_main,
|
||||
.main_len = ARRAY_SIZE(mt2701_mtk_ddp_main),
|
||||
.ext_path = mt2701_mtk_ddp_ext,
|
||||
.ext_len = ARRAY_SIZE(mt2701_mtk_ddp_ext),
|
||||
.shadow_register = true,
|
||||
};
|
||||
|
||||
static const struct mtk_mmsys_match_data mt2701_mmsys_match_data = {
|
||||
.num_drv_data = 1,
|
||||
.drv_data = {
|
||||
&mt2701_mmsys_driver_data,
|
||||
},
|
||||
.mmsys_dev_num = 1,
|
||||
};
|
||||
|
||||
static const struct mtk_mmsys_driver_data mt7623_mmsys_driver_data = {
|
||||
|
@ -231,13 +241,7 @@ static const struct mtk_mmsys_driver_data mt7623_mmsys_driver_data = {
|
|||
.ext_path = mt7623_mtk_ddp_ext,
|
||||
.ext_len = ARRAY_SIZE(mt7623_mtk_ddp_ext),
|
||||
.shadow_register = true,
|
||||
};
|
||||
|
||||
static const struct mtk_mmsys_match_data mt7623_mmsys_match_data = {
|
||||
.num_drv_data = 1,
|
||||
.drv_data = {
|
||||
&mt7623_mmsys_driver_data,
|
||||
},
|
||||
.mmsys_dev_num = 1,
|
||||
};
|
||||
|
||||
static const struct mtk_mmsys_driver_data mt2712_mmsys_driver_data = {
|
||||
|
@ -247,25 +251,13 @@ static const struct mtk_mmsys_driver_data mt2712_mmsys_driver_data = {
|
|||
.ext_len = ARRAY_SIZE(mt2712_mtk_ddp_ext),
|
||||
.third_path = mt2712_mtk_ddp_third,
|
||||
.third_len = ARRAY_SIZE(mt2712_mtk_ddp_third),
|
||||
};
|
||||
|
||||
static const struct mtk_mmsys_match_data mt2712_mmsys_match_data = {
|
||||
.num_drv_data = 1,
|
||||
.drv_data = {
|
||||
&mt2712_mmsys_driver_data,
|
||||
},
|
||||
.mmsys_dev_num = 1,
|
||||
};
|
||||
|
||||
static const struct mtk_mmsys_driver_data mt8167_mmsys_driver_data = {
|
||||
.main_path = mt8167_mtk_ddp_main,
|
||||
.main_len = ARRAY_SIZE(mt8167_mtk_ddp_main),
|
||||
};
|
||||
|
||||
static const struct mtk_mmsys_match_data mt8167_mmsys_match_data = {
|
||||
.num_drv_data = 1,
|
||||
.drv_data = {
|
||||
&mt8167_mmsys_driver_data,
|
||||
},
|
||||
.mmsys_dev_num = 1,
|
||||
};
|
||||
|
||||
static const struct mtk_mmsys_driver_data mt8173_mmsys_driver_data = {
|
||||
|
@ -273,13 +265,7 @@ static const struct mtk_mmsys_driver_data mt8173_mmsys_driver_data = {
|
|||
.main_len = ARRAY_SIZE(mt8173_mtk_ddp_main),
|
||||
.ext_path = mt8173_mtk_ddp_ext,
|
||||
.ext_len = ARRAY_SIZE(mt8173_mtk_ddp_ext),
|
||||
};
|
||||
|
||||
static const struct mtk_mmsys_match_data mt8173_mmsys_match_data = {
|
||||
.num_drv_data = 1,
|
||||
.drv_data = {
|
||||
&mt8173_mmsys_driver_data,
|
||||
},
|
||||
.mmsys_dev_num = 1,
|
||||
};
|
||||
|
||||
static const struct mtk_mmsys_driver_data mt8183_mmsys_driver_data = {
|
||||
|
@ -287,13 +273,7 @@ static const struct mtk_mmsys_driver_data mt8183_mmsys_driver_data = {
|
|||
.main_len = ARRAY_SIZE(mt8183_mtk_ddp_main),
|
||||
.ext_path = mt8183_mtk_ddp_ext,
|
||||
.ext_len = ARRAY_SIZE(mt8183_mtk_ddp_ext),
|
||||
};
|
||||
|
||||
static const struct mtk_mmsys_match_data mt8183_mmsys_match_data = {
|
||||
.num_drv_data = 1,
|
||||
.drv_data = {
|
||||
&mt8183_mmsys_driver_data,
|
||||
},
|
||||
.mmsys_dev_num = 1,
|
||||
};
|
||||
|
||||
static const struct mtk_mmsys_driver_data mt8186_mmsys_driver_data = {
|
||||
|
@ -301,13 +281,12 @@ static const struct mtk_mmsys_driver_data mt8186_mmsys_driver_data = {
|
|||
.main_len = ARRAY_SIZE(mt8186_mtk_ddp_main),
|
||||
.ext_path = mt8186_mtk_ddp_ext,
|
||||
.ext_len = ARRAY_SIZE(mt8186_mtk_ddp_ext),
|
||||
.mmsys_dev_num = 1,
|
||||
};
|
||||
|
||||
static const struct mtk_mmsys_match_data mt8186_mmsys_match_data = {
|
||||
.num_drv_data = 1,
|
||||
.drv_data = {
|
||||
&mt8186_mmsys_driver_data,
|
||||
},
|
||||
static const struct mtk_mmsys_driver_data mt8188_vdosys0_driver_data = {
|
||||
.main_path = mt8188_mtk_ddp_main,
|
||||
.main_len = ARRAY_SIZE(mt8188_mtk_ddp_main),
|
||||
};
|
||||
|
||||
static const struct mtk_mmsys_driver_data mt8192_mmsys_driver_data = {
|
||||
|
@ -315,56 +294,133 @@ static const struct mtk_mmsys_driver_data mt8192_mmsys_driver_data = {
|
|||
.main_len = ARRAY_SIZE(mt8192_mtk_ddp_main),
|
||||
.ext_path = mt8192_mtk_ddp_ext,
|
||||
.ext_len = ARRAY_SIZE(mt8192_mtk_ddp_ext),
|
||||
};
|
||||
|
||||
static const struct mtk_mmsys_match_data mt8192_mmsys_match_data = {
|
||||
.num_drv_data = 1,
|
||||
.drv_data = {
|
||||
&mt8192_mmsys_driver_data,
|
||||
},
|
||||
.mmsys_dev_num = 1,
|
||||
};
|
||||
|
||||
static const struct mtk_mmsys_driver_data mt8195_vdosys0_driver_data = {
|
||||
.io_start = 0x1c01a000,
|
||||
.main_path = mt8195_mtk_ddp_main,
|
||||
.main_len = ARRAY_SIZE(mt8195_mtk_ddp_main),
|
||||
.mmsys_dev_num = 2,
|
||||
};
|
||||
|
||||
static const struct mtk_mmsys_driver_data mt8195_vdosys1_driver_data = {
|
||||
.io_start = 0x1c100000,
|
||||
.ext_path = mt8195_mtk_ddp_ext,
|
||||
.ext_len = ARRAY_SIZE(mt8195_mtk_ddp_ext),
|
||||
.mmsys_id = 1,
|
||||
.mmsys_dev_num = 2,
|
||||
};
|
||||
|
||||
static const struct mtk_mmsys_match_data mt8195_mmsys_match_data = {
|
||||
.num_drv_data = 1,
|
||||
.drv_data = {
|
||||
&mt8195_vdosys0_driver_data,
|
||||
&mt8195_vdosys1_driver_data,
|
||||
},
|
||||
static const struct of_device_id mtk_drm_of_ids[] = {
|
||||
{ .compatible = "mediatek,mt2701-mmsys",
|
||||
.data = &mt2701_mmsys_driver_data},
|
||||
{ .compatible = "mediatek,mt7623-mmsys",
|
||||
.data = &mt7623_mmsys_driver_data},
|
||||
{ .compatible = "mediatek,mt2712-mmsys",
|
||||
.data = &mt2712_mmsys_driver_data},
|
||||
{ .compatible = "mediatek,mt8167-mmsys",
|
||||
.data = &mt8167_mmsys_driver_data},
|
||||
{ .compatible = "mediatek,mt8173-mmsys",
|
||||
.data = &mt8173_mmsys_driver_data},
|
||||
{ .compatible = "mediatek,mt8183-mmsys",
|
||||
.data = &mt8183_mmsys_driver_data},
|
||||
{ .compatible = "mediatek,mt8186-mmsys",
|
||||
.data = &mt8186_mmsys_driver_data},
|
||||
{ .compatible = "mediatek,mt8188-vdosys0",
|
||||
.data = &mt8188_vdosys0_driver_data},
|
||||
{ .compatible = "mediatek,mt8192-mmsys",
|
||||
.data = &mt8192_mmsys_driver_data},
|
||||
{ .compatible = "mediatek,mt8195-mmsys",
|
||||
.data = &mt8195_vdosys0_driver_data},
|
||||
{ .compatible = "mediatek,mt8195-vdosys0",
|
||||
.data = &mt8195_vdosys0_driver_data},
|
||||
{ .compatible = "mediatek,mt8195-vdosys1",
|
||||
.data = &mt8195_vdosys1_driver_data},
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, mtk_drm_of_ids);
|
||||
|
||||
static int mtk_drm_match(struct device *dev, void *data)
|
||||
{
|
||||
if (!strncmp(dev_name(dev), "mediatek-drm", sizeof("mediatek-drm") - 1))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool mtk_drm_get_all_drm_priv(struct device *dev)
|
||||
{
|
||||
struct mtk_drm_private *drm_priv = dev_get_drvdata(dev);
|
||||
struct mtk_drm_private *all_drm_priv[MAX_CRTC];
|
||||
struct device_node *phandle = dev->parent->of_node;
|
||||
const struct of_device_id *of_id;
|
||||
struct device_node *node;
|
||||
struct device *drm_dev;
|
||||
int cnt = 0;
|
||||
int i, j;
|
||||
|
||||
for_each_child_of_node(phandle->parent, node) {
|
||||
struct platform_device *pdev;
|
||||
|
||||
of_id = of_match_node(mtk_drm_of_ids, node);
|
||||
if (!of_id)
|
||||
continue;
|
||||
|
||||
pdev = of_find_device_by_node(node);
|
||||
if (!pdev)
|
||||
continue;
|
||||
|
||||
drm_dev = device_find_child(&pdev->dev, NULL, mtk_drm_match);
|
||||
if (!drm_dev || !dev_get_drvdata(drm_dev))
|
||||
continue;
|
||||
|
||||
all_drm_priv[cnt] = dev_get_drvdata(drm_dev);
|
||||
if (all_drm_priv[cnt] && all_drm_priv[cnt]->mtk_drm_bound)
|
||||
cnt++;
|
||||
}
|
||||
|
||||
if (drm_priv->data->mmsys_dev_num == cnt) {
|
||||
for (i = 0; i < cnt; i++)
|
||||
for (j = 0; j < cnt; j++)
|
||||
all_drm_priv[j]->all_drm_private[i] = all_drm_priv[i];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool mtk_drm_find_mmsys_comp(struct mtk_drm_private *private, int comp_id)
|
||||
{
|
||||
const struct mtk_mmsys_driver_data *drv_data = private->data;
|
||||
int i;
|
||||
|
||||
if (drv_data->main_path)
|
||||
for (i = 0; i < drv_data->main_len; i++)
|
||||
if (drv_data->main_path[i] == comp_id)
|
||||
return true;
|
||||
|
||||
if (drv_data->ext_path)
|
||||
for (i = 0; i < drv_data->ext_len; i++)
|
||||
if (drv_data->ext_path[i] == comp_id)
|
||||
return true;
|
||||
|
||||
if (drv_data->third_path)
|
||||
for (i = 0; i < drv_data->third_len; i++)
|
||||
if (drv_data->third_path[i] == comp_id)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int mtk_drm_kms_init(struct drm_device *drm)
|
||||
{
|
||||
struct mtk_drm_private *private = drm->dev_private;
|
||||
struct platform_device *pdev;
|
||||
struct device_node *np;
|
||||
struct device *dma_dev;
|
||||
int ret;
|
||||
struct mtk_drm_private *priv_n;
|
||||
struct device *dma_dev = NULL;
|
||||
int ret, i, j;
|
||||
|
||||
if (drm_firmware_drivers_only())
|
||||
return -ENODEV;
|
||||
|
||||
if (!iommu_present(&platform_bus_type))
|
||||
return -EPROBE_DEFER;
|
||||
|
||||
pdev = of_find_device_by_node(private->mutex_node);
|
||||
if (!pdev) {
|
||||
dev_err(drm->dev, "Waiting for disp-mutex device %pOF\n",
|
||||
private->mutex_node);
|
||||
of_node_put(private->mutex_node);
|
||||
return -EPROBE_DEFER;
|
||||
}
|
||||
private->mutex_dev = &pdev->dev;
|
||||
|
||||
ret = drmm_mode_config_init(drm);
|
||||
if (ret)
|
||||
goto put_mutex_dev;
|
||||
|
@ -382,9 +438,12 @@ static int mtk_drm_kms_init(struct drm_device *drm)
|
|||
drm->mode_config.funcs = &mtk_drm_mode_config_funcs;
|
||||
drm->mode_config.helper_private = &mtk_drm_mode_config_helpers;
|
||||
|
||||
ret = component_bind_all(drm->dev, drm);
|
||||
if (ret)
|
||||
goto put_mutex_dev;
|
||||
for (i = 0; i < private->data->mmsys_dev_num; i++) {
|
||||
drm->dev_private = private->all_drm_private[i];
|
||||
ret = component_bind_all(private->all_drm_private[i]->dev, drm);
|
||||
if (ret)
|
||||
goto put_mutex_dev;
|
||||
}
|
||||
|
||||
/*
|
||||
* Ensure internal panels are at the top of the connector list before
|
||||
|
@ -393,37 +452,53 @@ static int mtk_drm_kms_init(struct drm_device *drm)
|
|||
drm_helper_move_panel_connectors_to_head(drm);
|
||||
|
||||
/*
|
||||
* We currently support two fixed data streams, each optional,
|
||||
* and each statically assigned to a crtc:
|
||||
* OVL0 -> COLOR0 -> AAL -> OD -> RDMA0 -> UFOE -> DSI0 ...
|
||||
* 1. We currently support two fixed data streams, each optional,
|
||||
* and each statically assigned to a crtc:
|
||||
* OVL0 -> COLOR0 -> AAL -> OD -> RDMA0 -> UFOE -> DSI0 ...
|
||||
* 2. For multi mmsys architecture, crtc path data are located in
|
||||
* different drm private data structures. Loop through crtc index to
|
||||
* create crtc from the main path and then ext_path and finally the
|
||||
* third path.
|
||||
*/
|
||||
ret = mtk_drm_crtc_create(drm, private->data->main_path,
|
||||
private->data->main_len);
|
||||
if (ret < 0)
|
||||
goto err_component_unbind;
|
||||
/* ... and OVL1 -> COLOR1 -> GAMMA -> RDMA1 -> DPI0. */
|
||||
ret = mtk_drm_crtc_create(drm, private->data->ext_path,
|
||||
private->data->ext_len);
|
||||
if (ret < 0)
|
||||
goto err_component_unbind;
|
||||
for (i = 0; i < MAX_CRTC; i++) {
|
||||
for (j = 0; j < private->data->mmsys_dev_num; j++) {
|
||||
priv_n = private->all_drm_private[j];
|
||||
|
||||
ret = mtk_drm_crtc_create(drm, private->data->third_path,
|
||||
private->data->third_len);
|
||||
if (ret < 0)
|
||||
goto err_component_unbind;
|
||||
if (i == 0 && priv_n->data->main_len) {
|
||||
ret = mtk_drm_crtc_create(drm, priv_n->data->main_path,
|
||||
priv_n->data->main_len, j);
|
||||
if (ret)
|
||||
goto err_component_unbind;
|
||||
|
||||
continue;
|
||||
} else if (i == 1 && priv_n->data->ext_len) {
|
||||
ret = mtk_drm_crtc_create(drm, priv_n->data->ext_path,
|
||||
priv_n->data->ext_len, j);
|
||||
if (ret)
|
||||
goto err_component_unbind;
|
||||
|
||||
continue;
|
||||
} else if (i == 2 && priv_n->data->third_len) {
|
||||
ret = mtk_drm_crtc_create(drm, priv_n->data->third_path,
|
||||
priv_n->data->third_len, j);
|
||||
if (ret)
|
||||
goto err_component_unbind;
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Use OVL device for all DMA memory allocations */
|
||||
np = private->comp_node[private->data->main_path[0]] ?:
|
||||
private->comp_node[private->data->ext_path[0]];
|
||||
pdev = of_find_device_by_node(np);
|
||||
if (!pdev) {
|
||||
dma_dev = mtk_drm_crtc_dma_dev_get(drm_crtc_from_index(drm, 0));
|
||||
if (!dma_dev) {
|
||||
ret = -ENODEV;
|
||||
dev_err(drm->dev, "Need at least one OVL device\n");
|
||||
goto err_component_unbind;
|
||||
}
|
||||
|
||||
dma_dev = &pdev->dev;
|
||||
private->dma_dev = dma_dev;
|
||||
for (i = 0; i < private->data->mmsys_dev_num; i++)
|
||||
private->all_drm_private[i]->dma_dev = dma_dev;
|
||||
|
||||
/*
|
||||
* Configure the DMA segment size to make sure we get contiguous IOVA
|
||||
|
@ -445,9 +520,12 @@ static int mtk_drm_kms_init(struct drm_device *drm)
|
|||
return 0;
|
||||
|
||||
err_component_unbind:
|
||||
component_unbind_all(drm->dev, drm);
|
||||
for (i = 0; i < private->data->mmsys_dev_num; i++)
|
||||
component_unbind_all(private->all_drm_private[i]->dev, drm);
|
||||
put_mutex_dev:
|
||||
put_device(private->mutex_dev);
|
||||
for (i = 0; i < private->data->mmsys_dev_num; i++)
|
||||
put_device(private->all_drm_private[i]->mutex_dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -492,18 +570,44 @@ static const struct drm_driver mtk_drm_driver = {
|
|||
.minor = DRIVER_MINOR,
|
||||
};
|
||||
|
||||
static int compare_dev(struct device *dev, void *data)
|
||||
{
|
||||
return dev == (struct device *)data;
|
||||
}
|
||||
|
||||
static int mtk_drm_bind(struct device *dev)
|
||||
{
|
||||
struct mtk_drm_private *private = dev_get_drvdata(dev);
|
||||
struct platform_device *pdev;
|
||||
struct drm_device *drm;
|
||||
int ret;
|
||||
int ret, i;
|
||||
|
||||
if (!iommu_present(&platform_bus_type))
|
||||
return -EPROBE_DEFER;
|
||||
|
||||
pdev = of_find_device_by_node(private->mutex_node);
|
||||
if (!pdev) {
|
||||
dev_err(dev, "Waiting for disp-mutex device %pOF\n",
|
||||
private->mutex_node);
|
||||
of_node_put(private->mutex_node);
|
||||
return -EPROBE_DEFER;
|
||||
}
|
||||
|
||||
private->mutex_dev = &pdev->dev;
|
||||
private->mtk_drm_bound = true;
|
||||
private->dev = dev;
|
||||
|
||||
if (!mtk_drm_get_all_drm_priv(dev))
|
||||
return 0;
|
||||
|
||||
drm = drm_dev_alloc(&mtk_drm_driver, dev);
|
||||
if (IS_ERR(drm))
|
||||
return PTR_ERR(drm);
|
||||
|
||||
private->drm_master = true;
|
||||
drm->dev_private = private;
|
||||
private->drm = drm;
|
||||
for (i = 0; i < private->data->mmsys_dev_num; i++)
|
||||
private->all_drm_private[i]->drm = drm;
|
||||
|
||||
ret = mtk_drm_kms_init(drm);
|
||||
if (ret < 0)
|
||||
|
@ -529,10 +633,14 @@ static void mtk_drm_unbind(struct device *dev)
|
|||
{
|
||||
struct mtk_drm_private *private = dev_get_drvdata(dev);
|
||||
|
||||
drm_dev_unregister(private->drm);
|
||||
mtk_drm_kms_deinit(private->drm);
|
||||
drm_dev_put(private->drm);
|
||||
private->num_pipes = 0;
|
||||
/* for multi mmsys dev, unregister drm dev in mmsys master */
|
||||
if (private->drm_master) {
|
||||
drm_dev_unregister(private->drm);
|
||||
mtk_drm_kms_deinit(private->drm);
|
||||
drm_dev_put(private->drm);
|
||||
}
|
||||
private->mtk_drm_bound = false;
|
||||
private->drm_master = false;
|
||||
private->drm = NULL;
|
||||
}
|
||||
|
||||
|
@ -588,6 +696,8 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
|
|||
.data = (void *)MTK_DISP_MUTEX },
|
||||
{ .compatible = "mediatek,mt8186-disp-mutex",
|
||||
.data = (void *)MTK_DISP_MUTEX },
|
||||
{ .compatible = "mediatek,mt8188-disp-mutex",
|
||||
.data = (void *)MTK_DISP_MUTEX },
|
||||
{ .compatible = "mediatek,mt8192-disp-mutex",
|
||||
.data = (void *)MTK_DISP_MUTEX },
|
||||
{ .compatible = "mediatek,mt8195-disp-mutex",
|
||||
|
@ -657,58 +767,15 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
|
|||
{ }
|
||||
};
|
||||
|
||||
static const struct of_device_id mtk_drm_of_ids[] = {
|
||||
{ .compatible = "mediatek,mt2701-mmsys",
|
||||
.data = &mt2701_mmsys_match_data},
|
||||
{ .compatible = "mediatek,mt7623-mmsys",
|
||||
.data = &mt7623_mmsys_match_data},
|
||||
{ .compatible = "mediatek,mt2712-mmsys",
|
||||
.data = &mt2712_mmsys_match_data},
|
||||
{ .compatible = "mediatek,mt8167-mmsys",
|
||||
.data = &mt8167_mmsys_match_data},
|
||||
{ .compatible = "mediatek,mt8173-mmsys",
|
||||
.data = &mt8173_mmsys_match_data},
|
||||
{ .compatible = "mediatek,mt8183-mmsys",
|
||||
.data = &mt8183_mmsys_match_data},
|
||||
{ .compatible = "mediatek,mt8186-mmsys",
|
||||
.data = &mt8186_mmsys_match_data},
|
||||
{ .compatible = "mediatek,mt8192-mmsys",
|
||||
.data = &mt8192_mmsys_match_data},
|
||||
{ .compatible = "mediatek,mt8195-mmsys",
|
||||
.data = &mt8195_mmsys_match_data},
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, mtk_drm_of_ids);
|
||||
|
||||
static int mtk_drm_find_match_data(struct device *dev,
|
||||
const struct mtk_mmsys_match_data *match_data)
|
||||
{
|
||||
int i;
|
||||
struct platform_device *pdev = of_find_device_by_node(dev->parent->of_node);
|
||||
struct resource *res;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!res) {
|
||||
dev_err(dev, "failed to get parent resource\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (i = 0; i < match_data->num_drv_data; i++)
|
||||
if (match_data->drv_data[i]->io_start == res->start)
|
||||
return i;
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int mtk_drm_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct device_node *phandle = dev->parent->of_node;
|
||||
const struct of_device_id *of_id;
|
||||
const struct mtk_mmsys_match_data *match_data;
|
||||
struct mtk_drm_private *private;
|
||||
struct device_node *node;
|
||||
struct component_match *match = NULL;
|
||||
struct platform_device *ovl_adaptor;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
|
@ -726,18 +793,24 @@ static int mtk_drm_probe(struct platform_device *pdev)
|
|||
if (!of_id)
|
||||
return -ENODEV;
|
||||
|
||||
match_data = of_id->data;
|
||||
if (match_data->num_drv_data > 1) {
|
||||
/* This SoC has multiple mmsys channels */
|
||||
ret = mtk_drm_find_match_data(dev, match_data);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Couldn't get match driver data\n");
|
||||
return ret;
|
||||
}
|
||||
private->data = match_data->drv_data[ret];
|
||||
} else {
|
||||
dev_dbg(dev, "Using single mmsys channel\n");
|
||||
private->data = match_data->drv_data[0];
|
||||
private->data = of_id->data;
|
||||
|
||||
private->all_drm_private = devm_kmalloc_array(dev, private->data->mmsys_dev_num,
|
||||
sizeof(*private->all_drm_private),
|
||||
GFP_KERNEL);
|
||||
if (!private->all_drm_private)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Bringup ovl_adaptor */
|
||||
if (mtk_drm_find_mmsys_comp(private, DDP_COMPONENT_DRM_OVL_ADAPTOR)) {
|
||||
ovl_adaptor = platform_device_register_data(dev, "mediatek-disp-ovl-adaptor",
|
||||
PLATFORM_DEVID_AUTO,
|
||||
(void *)private->mmsys_dev,
|
||||
sizeof(*private->mmsys_dev));
|
||||
private->ddp_comp[DDP_COMPONENT_DRM_OVL_ADAPTOR].dev = &ovl_adaptor->dev;
|
||||
mtk_ddp_comp_init(NULL, &private->ddp_comp[DDP_COMPONENT_DRM_OVL_ADAPTOR],
|
||||
DDP_COMPONENT_DRM_OVL_ADAPTOR);
|
||||
component_match_add(dev, &match, compare_dev, &ovl_adaptor->dev);
|
||||
}
|
||||
|
||||
/* Iterate over sibling DISP function blocks */
|
||||
|
@ -759,7 +832,13 @@ static int mtk_drm_probe(struct platform_device *pdev)
|
|||
comp_type = (enum mtk_ddp_comp_type)of_id->data;
|
||||
|
||||
if (comp_type == MTK_DISP_MUTEX) {
|
||||
private->mutex_node = of_node_get(node);
|
||||
int id;
|
||||
|
||||
id = of_alias_get_id(node, "mutex");
|
||||
if (id < 0 || id == private->data->mmsys_id) {
|
||||
private->mutex_node = of_node_get(node);
|
||||
dev_dbg(dev, "get mutex for mmsys %d", private->data->mmsys_id);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -770,6 +849,9 @@ static int mtk_drm_probe(struct platform_device *pdev)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (!mtk_drm_find_mmsys_comp(private, comp_id))
|
||||
continue;
|
||||
|
||||
private->comp_node[comp_id] = of_node_get(node);
|
||||
|
||||
/*
|
||||
|
@ -784,6 +866,7 @@ static int mtk_drm_probe(struct platform_device *pdev)
|
|||
comp_type == MTK_DISP_MERGE ||
|
||||
comp_type == MTK_DISP_OVL ||
|
||||
comp_type == MTK_DISP_OVL_2L ||
|
||||
comp_type == MTK_DISP_OVL_ADAPTOR ||
|
||||
comp_type == MTK_DISP_RDMA ||
|
||||
comp_type == MTK_DP_INTF ||
|
||||
comp_type == MTK_DPI ||
|
||||
|
@ -821,7 +904,7 @@ err_pm:
|
|||
pm_runtime_disable(dev);
|
||||
err_node:
|
||||
of_node_put(private->mutex_node);
|
||||
for (i = 0; i < DDP_COMPONENT_ID_MAX; i++)
|
||||
for (i = 0; i < DDP_COMPONENT_DRM_ID_MAX; i++)
|
||||
of_node_put(private->comp_node[i]);
|
||||
return ret;
|
||||
}
|
||||
|
@ -834,7 +917,7 @@ static int mtk_drm_remove(struct platform_device *pdev)
|
|||
component_master_del(&pdev->dev, &mtk_drm_ops);
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
of_node_put(private->mutex_node);
|
||||
for (i = 0; i < DDP_COMPONENT_ID_MAX; i++)
|
||||
for (i = 0; i < DDP_COMPONENT_DRM_ID_MAX; i++)
|
||||
of_node_put(private->comp_node[i]);
|
||||
|
||||
return 0;
|
||||
|
@ -845,16 +928,20 @@ static int mtk_drm_sys_prepare(struct device *dev)
|
|||
struct mtk_drm_private *private = dev_get_drvdata(dev);
|
||||
struct drm_device *drm = private->drm;
|
||||
|
||||
return drm_mode_config_helper_suspend(drm);
|
||||
if (private->drm_master)
|
||||
return drm_mode_config_helper_suspend(drm);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mtk_drm_sys_complete(struct device *dev)
|
||||
{
|
||||
struct mtk_drm_private *private = dev_get_drvdata(dev);
|
||||
struct drm_device *drm = private->drm;
|
||||
int ret;
|
||||
int ret = 0;
|
||||
|
||||
ret = drm_mode_config_helper_resume(drm);
|
||||
if (private->drm_master)
|
||||
ret = drm_mode_config_helper_resume(drm);
|
||||
if (ret)
|
||||
dev_err(dev, "Failed to resume\n");
|
||||
}
|
||||
|
@ -879,11 +966,13 @@ static struct platform_driver * const mtk_drm_drivers[] = {
|
|||
&mtk_disp_color_driver,
|
||||
&mtk_disp_gamma_driver,
|
||||
&mtk_disp_merge_driver,
|
||||
&mtk_disp_ovl_adaptor_driver,
|
||||
&mtk_disp_ovl_driver,
|
||||
&mtk_disp_rdma_driver,
|
||||
&mtk_dpi_driver,
|
||||
&mtk_drm_platform_driver,
|
||||
&mtk_dsi_driver,
|
||||
&mtk_ethdr_driver,
|
||||
&mtk_mdp_rdma_driver,
|
||||
};
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -0,0 +1,370 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2021 MediaTek Inc.
|
||||
*/
|
||||
|
||||
#include <drm/drm_fourcc.h>
|
||||
#include <drm/drm_framebuffer.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/component.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/reset.h>
|
||||
#include <linux/soc/mediatek/mtk-cmdq.h>
|
||||
#include <linux/soc/mediatek/mtk-mmsys.h>
|
||||
|
||||
#include "mtk_drm_crtc.h"
|
||||
#include "mtk_drm_ddp_comp.h"
|
||||
#include "mtk_drm_drv.h"
|
||||
#include "mtk_ethdr.h"
|
||||
|
||||
#define MIX_INTEN 0x4
|
||||
#define MIX_FME_CPL_INTEN BIT(1)
|
||||
#define MIX_INTSTA 0x8
|
||||
#define MIX_EN 0xc
|
||||
#define MIX_RST 0x14
|
||||
#define MIX_ROI_SIZE 0x18
|
||||
#define MIX_DATAPATH_CON 0x1c
|
||||
#define OUTPUT_NO_RND BIT(3)
|
||||
#define SOURCE_RGB_SEL BIT(7)
|
||||
#define BACKGROUND_RELAY (4 << 9)
|
||||
#define MIX_ROI_BGCLR 0x20
|
||||
#define BGCLR_BLACK 0xff000000
|
||||
#define MIX_SRC_CON 0x24
|
||||
#define MIX_SRC_L0_EN BIT(0)
|
||||
#define MIX_L_SRC_CON(n) (0x28 + 0x18 * (n))
|
||||
#define NON_PREMULTI_SOURCE (2 << 12)
|
||||
#define MIX_L_SRC_SIZE(n) (0x30 + 0x18 * (n))
|
||||
#define MIX_L_SRC_OFFSET(n) (0x34 + 0x18 * (n))
|
||||
#define MIX_FUNC_DCM0 0x120
|
||||
#define MIX_FUNC_DCM1 0x124
|
||||
#define MIX_FUNC_DCM_ENABLE 0xffffffff
|
||||
|
||||
#define HDR_VDO_FE_0804_HDR_DM_FE 0x804
|
||||
#define HDR_VDO_FE_0804_BYPASS_ALL 0xfd
|
||||
#define HDR_GFX_FE_0204_GFX_HDR_FE 0x204
|
||||
#define HDR_GFX_FE_0204_BYPASS_ALL 0xfd
|
||||
#define HDR_VDO_BE_0204_VDO_DM_BE 0x204
|
||||
#define HDR_VDO_BE_0204_BYPASS_ALL 0x7e
|
||||
|
||||
#define MIXER_INX_MODE_BYPASS 0
|
||||
#define MIXER_INX_MODE_EVEN_EXTEND 1
|
||||
#define DEFAULT_9BIT_ALPHA 0x100
|
||||
#define MIXER_ALPHA_AEN BIT(8)
|
||||
#define MIXER_ALPHA 0xff
|
||||
#define ETHDR_CLK_NUM 13
|
||||
|
||||
enum mtk_ethdr_comp_id {
|
||||
ETHDR_MIXER,
|
||||
ETHDR_VDO_FE0,
|
||||
ETHDR_VDO_FE1,
|
||||
ETHDR_GFX_FE0,
|
||||
ETHDR_GFX_FE1,
|
||||
ETHDR_VDO_BE,
|
||||
ETHDR_ADL_DS,
|
||||
ETHDR_ID_MAX
|
||||
};
|
||||
|
||||
struct mtk_ethdr_comp {
|
||||
struct device *dev;
|
||||
void __iomem *regs;
|
||||
struct cmdq_client_reg cmdq_base;
|
||||
};
|
||||
|
||||
struct mtk_ethdr {
|
||||
struct mtk_ethdr_comp ethdr_comp[ETHDR_ID_MAX];
|
||||
struct clk_bulk_data ethdr_clk[ETHDR_CLK_NUM];
|
||||
struct device *mmsys_dev;
|
||||
void (*vblank_cb)(void *data);
|
||||
void *vblank_cb_data;
|
||||
int irq;
|
||||
struct reset_control *reset_ctl;
|
||||
};
|
||||
|
||||
static const char * const ethdr_clk_str[] = {
|
||||
"ethdr_top",
|
||||
"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",
|
||||
};
|
||||
|
||||
void mtk_ethdr_register_vblank_cb(struct device *dev,
|
||||
void (*vblank_cb)(void *),
|
||||
void *vblank_cb_data)
|
||||
{
|
||||
struct mtk_ethdr *priv = dev_get_drvdata(dev);
|
||||
|
||||
priv->vblank_cb = vblank_cb;
|
||||
priv->vblank_cb_data = vblank_cb_data;
|
||||
}
|
||||
|
||||
void mtk_ethdr_unregister_vblank_cb(struct device *dev)
|
||||
{
|
||||
struct mtk_ethdr *priv = dev_get_drvdata(dev);
|
||||
|
||||
priv->vblank_cb = NULL;
|
||||
priv->vblank_cb_data = NULL;
|
||||
}
|
||||
|
||||
void mtk_ethdr_enable_vblank(struct device *dev)
|
||||
{
|
||||
struct mtk_ethdr *priv = dev_get_drvdata(dev);
|
||||
|
||||
writel(MIX_FME_CPL_INTEN, priv->ethdr_comp[ETHDR_MIXER].regs + MIX_INTEN);
|
||||
}
|
||||
|
||||
void mtk_ethdr_disable_vblank(struct device *dev)
|
||||
{
|
||||
struct mtk_ethdr *priv = dev_get_drvdata(dev);
|
||||
|
||||
writel(0x0, priv->ethdr_comp[ETHDR_MIXER].regs + MIX_INTEN);
|
||||
}
|
||||
|
||||
static irqreturn_t mtk_ethdr_irq_handler(int irq, void *dev_id)
|
||||
{
|
||||
struct mtk_ethdr *priv = dev_id;
|
||||
|
||||
writel(0x0, priv->ethdr_comp[ETHDR_MIXER].regs + MIX_INTSTA);
|
||||
|
||||
if (!priv->vblank_cb)
|
||||
return IRQ_NONE;
|
||||
|
||||
priv->vblank_cb(priv->vblank_cb_data);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
void mtk_ethdr_layer_config(struct device *dev, unsigned int idx,
|
||||
struct mtk_plane_state *state,
|
||||
struct cmdq_pkt *cmdq_pkt)
|
||||
{
|
||||
struct mtk_ethdr *priv = dev_get_drvdata(dev);
|
||||
struct mtk_ethdr_comp *mixer = &priv->ethdr_comp[ETHDR_MIXER];
|
||||
struct mtk_plane_pending_state *pending = &state->pending;
|
||||
unsigned int offset = (pending->x & 1) << 31 | pending->y << 16 | pending->x;
|
||||
unsigned int align_width = ALIGN_DOWN(pending->width, 2);
|
||||
unsigned int alpha_con = 0;
|
||||
|
||||
dev_dbg(dev, "%s+ idx:%d", __func__, idx);
|
||||
|
||||
if (idx >= 4)
|
||||
return;
|
||||
|
||||
if (!pending->enable) {
|
||||
mtk_ddp_write(cmdq_pkt, 0, &mixer->cmdq_base, mixer->regs, MIX_L_SRC_SIZE(idx));
|
||||
return;
|
||||
}
|
||||
|
||||
if (state->base.fb && state->base.fb->format->has_alpha)
|
||||
alpha_con = MIXER_ALPHA_AEN | MIXER_ALPHA;
|
||||
|
||||
mtk_mmsys_mixer_in_config(priv->mmsys_dev, idx + 1, alpha_con ? false : true,
|
||||
DEFAULT_9BIT_ALPHA,
|
||||
pending->x & 1 ? MIXER_INX_MODE_EVEN_EXTEND :
|
||||
MIXER_INX_MODE_BYPASS, align_width / 2 - 1, cmdq_pkt);
|
||||
|
||||
mtk_ddp_write(cmdq_pkt, pending->height << 16 | align_width, &mixer->cmdq_base,
|
||||
mixer->regs, MIX_L_SRC_SIZE(idx));
|
||||
mtk_ddp_write(cmdq_pkt, offset, &mixer->cmdq_base, mixer->regs, MIX_L_SRC_OFFSET(idx));
|
||||
mtk_ddp_write_mask(cmdq_pkt, alpha_con, &mixer->cmdq_base, mixer->regs, MIX_L_SRC_CON(idx),
|
||||
0x1ff);
|
||||
mtk_ddp_write_mask(cmdq_pkt, BIT(idx), &mixer->cmdq_base, mixer->regs, MIX_SRC_CON,
|
||||
BIT(idx));
|
||||
}
|
||||
|
||||
void mtk_ethdr_config(struct device *dev, unsigned int w,
|
||||
unsigned int h, unsigned int vrefresh,
|
||||
unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
|
||||
{
|
||||
struct mtk_ethdr *priv = dev_get_drvdata(dev);
|
||||
struct mtk_ethdr_comp *vdo_fe0 = &priv->ethdr_comp[ETHDR_VDO_FE0];
|
||||
struct mtk_ethdr_comp *vdo_fe1 = &priv->ethdr_comp[ETHDR_VDO_FE1];
|
||||
struct mtk_ethdr_comp *gfx_fe0 = &priv->ethdr_comp[ETHDR_GFX_FE0];
|
||||
struct mtk_ethdr_comp *gfx_fe1 = &priv->ethdr_comp[ETHDR_GFX_FE1];
|
||||
struct mtk_ethdr_comp *vdo_be = &priv->ethdr_comp[ETHDR_VDO_BE];
|
||||
struct mtk_ethdr_comp *mixer = &priv->ethdr_comp[ETHDR_MIXER];
|
||||
|
||||
dev_dbg(dev, "%s-w:%d, h:%d\n", __func__, w, h);
|
||||
|
||||
mtk_ddp_write(cmdq_pkt, HDR_VDO_FE_0804_BYPASS_ALL, &vdo_fe0->cmdq_base,
|
||||
vdo_fe0->regs, HDR_VDO_FE_0804_HDR_DM_FE);
|
||||
|
||||
mtk_ddp_write(cmdq_pkt, HDR_VDO_FE_0804_BYPASS_ALL, &vdo_fe1->cmdq_base,
|
||||
vdo_fe1->regs, HDR_VDO_FE_0804_HDR_DM_FE);
|
||||
|
||||
mtk_ddp_write(cmdq_pkt, HDR_GFX_FE_0204_BYPASS_ALL, &gfx_fe0->cmdq_base,
|
||||
gfx_fe0->regs, HDR_GFX_FE_0204_GFX_HDR_FE);
|
||||
|
||||
mtk_ddp_write(cmdq_pkt, HDR_GFX_FE_0204_BYPASS_ALL, &gfx_fe1->cmdq_base,
|
||||
gfx_fe1->regs, HDR_GFX_FE_0204_GFX_HDR_FE);
|
||||
|
||||
mtk_ddp_write(cmdq_pkt, HDR_VDO_BE_0204_BYPASS_ALL, &vdo_be->cmdq_base,
|
||||
vdo_be->regs, HDR_VDO_BE_0204_VDO_DM_BE);
|
||||
|
||||
mtk_ddp_write(cmdq_pkt, MIX_FUNC_DCM_ENABLE, &mixer->cmdq_base, mixer->regs, MIX_FUNC_DCM0);
|
||||
mtk_ddp_write(cmdq_pkt, MIX_FUNC_DCM_ENABLE, &mixer->cmdq_base, mixer->regs, MIX_FUNC_DCM1);
|
||||
mtk_ddp_write(cmdq_pkt, h << 16 | w, &mixer->cmdq_base, mixer->regs, MIX_ROI_SIZE);
|
||||
mtk_ddp_write(cmdq_pkt, BGCLR_BLACK, &mixer->cmdq_base, mixer->regs, MIX_ROI_BGCLR);
|
||||
mtk_ddp_write(cmdq_pkt, NON_PREMULTI_SOURCE, &mixer->cmdq_base, mixer->regs,
|
||||
MIX_L_SRC_CON(0));
|
||||
mtk_ddp_write(cmdq_pkt, NON_PREMULTI_SOURCE, &mixer->cmdq_base, mixer->regs,
|
||||
MIX_L_SRC_CON(1));
|
||||
mtk_ddp_write(cmdq_pkt, NON_PREMULTI_SOURCE, &mixer->cmdq_base, mixer->regs,
|
||||
MIX_L_SRC_CON(2));
|
||||
mtk_ddp_write(cmdq_pkt, NON_PREMULTI_SOURCE, &mixer->cmdq_base, mixer->regs,
|
||||
MIX_L_SRC_CON(3));
|
||||
mtk_ddp_write(cmdq_pkt, 0x0, &mixer->cmdq_base, mixer->regs, MIX_L_SRC_SIZE(0));
|
||||
mtk_ddp_write(cmdq_pkt, OUTPUT_NO_RND | SOURCE_RGB_SEL | BACKGROUND_RELAY,
|
||||
&mixer->cmdq_base, mixer->regs, MIX_DATAPATH_CON);
|
||||
mtk_ddp_write_mask(cmdq_pkt, MIX_SRC_L0_EN, &mixer->cmdq_base, mixer->regs,
|
||||
MIX_SRC_CON, MIX_SRC_L0_EN);
|
||||
|
||||
mtk_mmsys_hdr_config(priv->mmsys_dev, w / 2, h, cmdq_pkt);
|
||||
mtk_mmsys_mixer_in_channel_swap(priv->mmsys_dev, 4, 0, cmdq_pkt);
|
||||
}
|
||||
|
||||
void mtk_ethdr_start(struct device *dev)
|
||||
{
|
||||
struct mtk_ethdr *priv = dev_get_drvdata(dev);
|
||||
struct mtk_ethdr_comp *mixer = &priv->ethdr_comp[ETHDR_MIXER];
|
||||
|
||||
writel(1, mixer->regs + MIX_EN);
|
||||
}
|
||||
|
||||
void mtk_ethdr_stop(struct device *dev)
|
||||
{
|
||||
struct mtk_ethdr *priv = dev_get_drvdata(dev);
|
||||
struct mtk_ethdr_comp *mixer = &priv->ethdr_comp[ETHDR_MIXER];
|
||||
|
||||
writel(0, mixer->regs + MIX_EN);
|
||||
writel(1, mixer->regs + MIX_RST);
|
||||
reset_control_reset(priv->reset_ctl);
|
||||
writel(0, mixer->regs + MIX_RST);
|
||||
}
|
||||
|
||||
int mtk_ethdr_clk_enable(struct device *dev)
|
||||
{
|
||||
int ret;
|
||||
struct mtk_ethdr *priv = dev_get_drvdata(dev);
|
||||
|
||||
ret = clk_bulk_prepare_enable(ETHDR_CLK_NUM, priv->ethdr_clk);
|
||||
if (ret)
|
||||
dev_err(dev,
|
||||
"ethdr_clk prepare enable failed\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
void mtk_ethdr_clk_disable(struct device *dev)
|
||||
{
|
||||
struct mtk_ethdr *priv = dev_get_drvdata(dev);
|
||||
|
||||
clk_bulk_disable_unprepare(ETHDR_CLK_NUM, priv->ethdr_clk);
|
||||
}
|
||||
|
||||
static int mtk_ethdr_bind(struct device *dev, struct device *master,
|
||||
void *data)
|
||||
{
|
||||
struct mtk_ethdr *priv = dev_get_drvdata(dev);
|
||||
|
||||
priv->mmsys_dev = data;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mtk_ethdr_unbind(struct device *dev, struct device *master, void *data)
|
||||
{
|
||||
}
|
||||
|
||||
static const struct component_ops mtk_ethdr_component_ops = {
|
||||
.bind = mtk_ethdr_bind,
|
||||
.unbind = mtk_ethdr_unbind,
|
||||
};
|
||||
|
||||
static int mtk_ethdr_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct mtk_ethdr *priv;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < ETHDR_ID_MAX; i++) {
|
||||
priv->ethdr_comp[i].dev = dev;
|
||||
priv->ethdr_comp[i].regs = of_iomap(dev->of_node, i);
|
||||
#if IS_REACHABLE(CONFIG_MTK_CMDQ)
|
||||
ret = cmdq_dev_get_client_reg(dev,
|
||||
&priv->ethdr_comp[i].cmdq_base, i);
|
||||
if (ret)
|
||||
dev_dbg(dev, "get mediatek,gce-client-reg fail!\n");
|
||||
#endif
|
||||
dev_dbg(dev, "[DRM]regs:0x%p, node:%d\n", priv->ethdr_comp[i].regs, i);
|
||||
}
|
||||
|
||||
for (i = 0; i < ETHDR_CLK_NUM; i++)
|
||||
priv->ethdr_clk[i].id = ethdr_clk_str[i];
|
||||
ret = devm_clk_bulk_get_optional(dev, ETHDR_CLK_NUM, priv->ethdr_clk);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
priv->irq = platform_get_irq(pdev, 0);
|
||||
if (priv->irq < 0)
|
||||
priv->irq = 0;
|
||||
|
||||
if (priv->irq) {
|
||||
ret = devm_request_irq(dev, priv->irq, mtk_ethdr_irq_handler,
|
||||
IRQF_TRIGGER_NONE, dev_name(dev), priv);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to request irq %d: %d\n", priv->irq, ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
priv->reset_ctl = devm_reset_control_array_get_optional_exclusive(dev);
|
||||
if (IS_ERR(priv->reset_ctl)) {
|
||||
dev_err_probe(dev, PTR_ERR(priv->reset_ctl), "cannot get ethdr reset control\n");
|
||||
return PTR_ERR(priv->reset_ctl);
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, priv);
|
||||
|
||||
ret = component_add(dev, &mtk_ethdr_component_ops);
|
||||
if (ret)
|
||||
dev_notice(dev, "Failed to add component: %d\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mtk_ethdr_remove(struct platform_device *pdev)
|
||||
{
|
||||
component_del(&pdev->dev, &mtk_ethdr_component_ops);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id mtk_ethdr_driver_dt_match[] = {
|
||||
{ .compatible = "mediatek,mt8195-disp-ethdr"},
|
||||
{},
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(of, mtk_ethdr_driver_dt_match);
|
||||
|
||||
struct platform_driver mtk_ethdr_driver = {
|
||||
.probe = mtk_ethdr_probe,
|
||||
.remove = mtk_ethdr_remove,
|
||||
.driver = {
|
||||
.name = "mediatek-disp-ethdr",
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = mtk_ethdr_driver_dt_match,
|
||||
},
|
||||
};
|
|
@ -0,0 +1,25 @@
|
|||
/* 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);
|
||||
|
|
Loading…
Reference in New Issue