Mediatek DRM Next for Linux 5.15
1. MT8133 AAL support, adjust rdma fifo threshold formula. 2. Implement mmap as GEM object function. 3. Add support for MT8167. 4. Test component initialization earlier in the function mtk_drm_crtc_create. 5. CMDQ refinement. -----BEGIN PGP SIGNATURE----- iQJMBAABCgA2FiEEACwLKSDmq+9RDv5P4cpzo8lZTiQFAmEa8V0YHGNodW5rdWFu Zy5odUBrZXJuZWwub3JnAAoJEOHKc6PJWU4ko88P/jB880d6Pe5Fm23BvpOkUl7o gmlMgOc184ghUzDmCQrRE029ZgXqucCBW0onLdgyrkEXFA32/XmKbrLibUigsV8D sMoLrJToEKO+YM033xZMwuVe37owLdqsJkmLttQhZf3PSN/FJnKksQmRe6ShV9Dv 5Ls292U7F3NrWnhFwX7+XQpp/oVad1m6z8bTKd//EYpAyMHT1vVjixE4SJJddB5g CLKFUlE8Vg9qoCttFnRQtOYqSB2u+5KZilY7Av1/gXkjfpsMIkMFLKtjvewzs3fG LLSA9MV9Yr9YylRaR7YVlpM0gZfZpi8TmIiQdnqzANRjcjGvLHCXhNuur6URYWkL k/2LWIiLSDIiSISfCbBxhFQCpHWnAYSXnRdqD48vZfy+cTOGmhdYyBS9+JD9fN7H HbPRcjp61KMdV65uS4QKnWIihJRiHtDRa1mESKf01hlzQEsYd0JKERNXbc9Zjm06 DibfHz+HlRPZawO0+WDJmCqFB6g0VZzXOPzrTxxQvWFoYQTbCKst3NI7mCHblkNq FaR1IZ8pYulNg/FdjRBROehXV4Jkg1M+Sbh0ixhXpcDfyG/OGcIfoPrFuA4iTnhs lUT2T4fSv4xCoklRTCbpKtittFPR+LSp8TXW2eml8+p+Zc67EZj5aQ/469h57Bum nGitW8UfYpauo1/dNaD3 =OMls -----END PGP SIGNATURE----- Merge tag 'mediatek-drm-next-5.15' of https://git.kernel.org/pub/scm/linux/kernel/git/chunkuang.hu/linux into drm-next Mediatek DRM Next for Linux 5.15 1. MT8133 AAL support, adjust rdma fifo threshold formula. 2. Implement mmap as GEM object function. 3. Add support for MT8167. 4. Test component initialization earlier in the function mtk_drm_crtc_create. 5. CMDQ refinement. Signed-off-by: Dave Airlie <airlied@redhat.com> From: Chun-Kuang Hu <chunkuang.hu@kernel.org> Link: https://patchwork.freedesktop.org/patch/msgid/20210816232427.13368-1-chunkuang.hu@kernel.org
This commit is contained in:
Коммит
f97a1b6580
|
@ -7,7 +7,7 @@ channel output.
|
|||
|
||||
Required properties:
|
||||
- compatible: "mediatek,<chip>-dsi"
|
||||
- the supported chips are mt2701, mt7623, mt8173 and mt8183.
|
||||
- the supported chips are mt2701, mt7623, mt8167, mt8173 and mt8183.
|
||||
- reg: Physical base address and length of the controller's registers
|
||||
- interrupts: The interrupt signal from the function block.
|
||||
- clocks: device clocks
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
mediatek-drm-y := mtk_disp_ccorr.o \
|
||||
mediatek-drm-y := mtk_disp_aal.o \
|
||||
mtk_disp_ccorr.o \
|
||||
mtk_disp_color.o \
|
||||
mtk_disp_gamma.o \
|
||||
mtk_disp_ovl.o \
|
||||
|
|
|
@ -0,0 +1,167 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2021 MediaTek Inc.
|
||||
*/
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/component.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/soc/mediatek/mtk-cmdq.h>
|
||||
|
||||
#include "mtk_disp_drv.h"
|
||||
#include "mtk_drm_crtc.h"
|
||||
#include "mtk_drm_ddp_comp.h"
|
||||
|
||||
#define DISP_AAL_EN 0x0000
|
||||
#define AAL_EN BIT(0)
|
||||
#define DISP_AAL_SIZE 0x0030
|
||||
|
||||
|
||||
struct mtk_disp_aal_data {
|
||||
bool has_gamma;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct mtk_disp_aal - DISP_AAL driver structure
|
||||
* @ddp_comp - structure containing type enum and hardware resources
|
||||
* @crtc - associated crtc to report irq events to
|
||||
*/
|
||||
struct mtk_disp_aal {
|
||||
struct clk *clk;
|
||||
void __iomem *regs;
|
||||
struct cmdq_client_reg cmdq_reg;
|
||||
const struct mtk_disp_aal_data *data;
|
||||
};
|
||||
|
||||
int mtk_aal_clk_enable(struct device *dev)
|
||||
{
|
||||
struct mtk_disp_aal *aal = dev_get_drvdata(dev);
|
||||
|
||||
return clk_prepare_enable(aal->clk);
|
||||
}
|
||||
|
||||
void mtk_aal_clk_disable(struct device *dev)
|
||||
{
|
||||
struct mtk_disp_aal *aal = dev_get_drvdata(dev);
|
||||
|
||||
clk_disable_unprepare(aal->clk);
|
||||
}
|
||||
|
||||
void mtk_aal_config(struct device *dev, unsigned int w,
|
||||
unsigned int h, unsigned int vrefresh,
|
||||
unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
|
||||
{
|
||||
struct mtk_disp_aal *aal = dev_get_drvdata(dev);
|
||||
|
||||
mtk_ddp_write(cmdq_pkt, w << 16 | h, &aal->cmdq_reg, aal->regs, DISP_AAL_SIZE);
|
||||
}
|
||||
|
||||
void mtk_aal_gamma_set(struct device *dev, struct drm_crtc_state *state)
|
||||
{
|
||||
struct mtk_disp_aal *aal = dev_get_drvdata(dev);
|
||||
|
||||
if (aal->data && aal->data->has_gamma)
|
||||
mtk_gamma_set_common(aal->regs, state);
|
||||
}
|
||||
|
||||
void mtk_aal_start(struct device *dev)
|
||||
{
|
||||
struct mtk_disp_aal *aal = dev_get_drvdata(dev);
|
||||
|
||||
writel(AAL_EN, aal->regs + DISP_AAL_EN);
|
||||
}
|
||||
|
||||
void mtk_aal_stop(struct device *dev)
|
||||
{
|
||||
struct mtk_disp_aal *aal = dev_get_drvdata(dev);
|
||||
|
||||
writel_relaxed(0x0, aal->regs + DISP_AAL_EN);
|
||||
}
|
||||
|
||||
static int mtk_disp_aal_bind(struct device *dev, struct device *master,
|
||||
void *data)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mtk_disp_aal_unbind(struct device *dev, struct device *master,
|
||||
void *data)
|
||||
{
|
||||
}
|
||||
|
||||
static const struct component_ops mtk_disp_aal_component_ops = {
|
||||
.bind = mtk_disp_aal_bind,
|
||||
.unbind = mtk_disp_aal_unbind,
|
||||
};
|
||||
|
||||
static int mtk_disp_aal_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct mtk_disp_aal *priv;
|
||||
struct resource *res;
|
||||
int ret;
|
||||
|
||||
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
|
||||
priv->clk = devm_clk_get(dev, NULL);
|
||||
if (IS_ERR(priv->clk)) {
|
||||
dev_err(dev, "failed to get aal clk\n");
|
||||
return PTR_ERR(priv->clk);
|
||||
}
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
priv->regs = devm_ioremap_resource(dev, res);
|
||||
if (IS_ERR(priv->regs)) {
|
||||
dev_err(dev, "failed to ioremap aal\n");
|
||||
return PTR_ERR(priv->regs);
|
||||
}
|
||||
|
||||
#if IS_REACHABLE(CONFIG_MTK_CMDQ)
|
||||
ret = cmdq_dev_get_client_reg(dev, &priv->cmdq_reg, 0);
|
||||
if (ret)
|
||||
dev_dbg(dev, "get mediatek,gce-client-reg fail!\n");
|
||||
#endif
|
||||
|
||||
priv->data = of_device_get_match_data(dev);
|
||||
platform_set_drvdata(pdev, priv);
|
||||
|
||||
ret = component_add(dev, &mtk_disp_aal_component_ops);
|
||||
if (ret)
|
||||
dev_err(dev, "Failed to add component: %d\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mtk_disp_aal_remove(struct platform_device *pdev)
|
||||
{
|
||||
component_del(&pdev->dev, &mtk_disp_aal_component_ops);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct mtk_disp_aal_data mt8173_aal_driver_data = {
|
||||
.has_gamma = true,
|
||||
};
|
||||
|
||||
static const struct of_device_id mtk_disp_aal_driver_dt_match[] = {
|
||||
{ .compatible = "mediatek,mt8173-disp-aal",
|
||||
.data = &mt8173_aal_driver_data},
|
||||
{ .compatible = "mediatek,mt8183-disp-aal"},
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, mtk_disp_aal_driver_dt_match);
|
||||
|
||||
struct platform_driver mtk_disp_aal_driver = {
|
||||
.probe = mtk_disp_aal_probe,
|
||||
.remove = mtk_disp_aal_remove,
|
||||
.driver = {
|
||||
.name = "mediatek-disp-aal",
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = mtk_disp_aal_driver_dt_match,
|
||||
},
|
||||
};
|
|
@ -9,6 +9,15 @@
|
|||
#include <linux/soc/mediatek/mtk-cmdq.h>
|
||||
#include "mtk_drm_plane.h"
|
||||
|
||||
int mtk_aal_clk_enable(struct device *dev);
|
||||
void mtk_aal_clk_disable(struct device *dev);
|
||||
void mtk_aal_config(struct device *dev, unsigned int w,
|
||||
unsigned int h, unsigned int vrefresh,
|
||||
unsigned int bpc, struct cmdq_pkt *cmdq_pkt);
|
||||
void mtk_aal_gamma_set(struct device *dev, struct drm_crtc_state *state);
|
||||
void mtk_aal_start(struct device *dev);
|
||||
void mtk_aal_stop(struct device *dev);
|
||||
|
||||
void mtk_ccorr_ctm_set(struct device *dev, struct drm_crtc_state *state);
|
||||
int mtk_ccorr_clk_enable(struct device *dev);
|
||||
void mtk_ccorr_clk_disable(struct device *dev);
|
||||
|
|
|
@ -162,10 +162,10 @@ void mtk_rdma_config(struct device *dev, unsigned int width,
|
|||
/*
|
||||
* Enable FIFO underflow since DSI and DPI can't be blocked.
|
||||
* Keep the FIFO pseudo size reset default of 8 KiB. Set the
|
||||
* output threshold to 6 microseconds with 7/6 overhead to
|
||||
* account for blanking, and with a pixel depth of 4 bytes:
|
||||
* output threshold to 70% of max fifo size to make sure the
|
||||
* threhold will not overflow
|
||||
*/
|
||||
threshold = width * height * vrefresh * 4 * 7 / 1000000;
|
||||
threshold = rdma_fifo_size * 7 / 10;
|
||||
reg = RDMA_FIFO_UNDERFLOW_EN |
|
||||
RDMA_FIFO_PSEUDO_SIZE(rdma_fifo_size) |
|
||||
RDMA_OUTPUT_VALID_FIFO_THRESHOLD(threshold);
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
*/
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/mailbox_controller.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/soc/mediatek/mtk-cmdq.h>
|
||||
#include <linux/soc/mediatek/mtk-mmsys.h>
|
||||
|
@ -50,8 +52,11 @@ struct mtk_drm_crtc {
|
|||
bool pending_async_planes;
|
||||
|
||||
#if IS_REACHABLE(CONFIG_MTK_CMDQ)
|
||||
struct cmdq_client *cmdq_client;
|
||||
struct mbox_client cmdq_cl;
|
||||
struct mbox_chan *cmdq_chan;
|
||||
struct cmdq_pkt cmdq_handle;
|
||||
u32 cmdq_event;
|
||||
u32 cmdq_vblank_cnt;
|
||||
#endif
|
||||
|
||||
struct device *mmsys_dev;
|
||||
|
@ -222,9 +227,79 @@ struct mtk_ddp_comp *mtk_drm_ddp_comp_for_plane(struct drm_crtc *crtc,
|
|||
}
|
||||
|
||||
#if IS_REACHABLE(CONFIG_MTK_CMDQ)
|
||||
static void ddp_cmdq_cb(struct cmdq_cb_data data)
|
||||
static int mtk_drm_cmdq_pkt_create(struct mbox_chan *chan, struct cmdq_pkt *pkt,
|
||||
size_t size)
|
||||
{
|
||||
cmdq_pkt_destroy(data.data);
|
||||
struct device *dev;
|
||||
dma_addr_t dma_addr;
|
||||
|
||||
pkt->va_base = kzalloc(size, GFP_KERNEL);
|
||||
if (!pkt->va_base) {
|
||||
kfree(pkt);
|
||||
return -ENOMEM;
|
||||
}
|
||||
pkt->buf_size = size;
|
||||
|
||||
dev = chan->mbox->dev;
|
||||
dma_addr = dma_map_single(dev, pkt->va_base, pkt->buf_size,
|
||||
DMA_TO_DEVICE);
|
||||
if (dma_mapping_error(dev, dma_addr)) {
|
||||
dev_err(dev, "dma map failed, size=%u\n", (u32)(u64)size);
|
||||
kfree(pkt->va_base);
|
||||
kfree(pkt);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
pkt->pa_base = dma_addr;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mtk_drm_cmdq_pkt_destroy(struct mbox_chan *chan, struct cmdq_pkt *pkt)
|
||||
{
|
||||
dma_unmap_single(chan->mbox->dev, pkt->pa_base, pkt->buf_size,
|
||||
DMA_TO_DEVICE);
|
||||
kfree(pkt->va_base);
|
||||
kfree(pkt);
|
||||
}
|
||||
|
||||
static void ddp_cmdq_cb(struct mbox_client *cl, void *mssg)
|
||||
{
|
||||
struct mtk_drm_crtc *mtk_crtc = container_of(cl, struct mtk_drm_crtc, cmdq_cl);
|
||||
struct cmdq_cb_data *data = mssg;
|
||||
struct mtk_crtc_state *state;
|
||||
unsigned int i;
|
||||
|
||||
state = to_mtk_crtc_state(mtk_crtc->base.state);
|
||||
|
||||
state->pending_config = false;
|
||||
|
||||
if (mtk_crtc->pending_planes) {
|
||||
for (i = 0; i < mtk_crtc->layer_nr; i++) {
|
||||
struct drm_plane *plane = &mtk_crtc->planes[i];
|
||||
struct mtk_plane_state *plane_state;
|
||||
|
||||
plane_state = to_mtk_plane_state(plane->state);
|
||||
|
||||
plane_state->pending.config = false;
|
||||
}
|
||||
mtk_crtc->pending_planes = false;
|
||||
}
|
||||
|
||||
if (mtk_crtc->pending_async_planes) {
|
||||
for (i = 0; i < mtk_crtc->layer_nr; i++) {
|
||||
struct drm_plane *plane = &mtk_crtc->planes[i];
|
||||
struct mtk_plane_state *plane_state;
|
||||
|
||||
plane_state = to_mtk_plane_state(plane->state);
|
||||
|
||||
plane_state->pending.async_config = false;
|
||||
}
|
||||
mtk_crtc->pending_async_planes = false;
|
||||
}
|
||||
|
||||
mtk_crtc->cmdq_vblank_cnt = 0;
|
||||
mtk_drm_cmdq_pkt_destroy(mtk_crtc->cmdq_chan, data->pkt);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -378,7 +453,8 @@ static void mtk_crtc_ddp_config(struct drm_crtc *crtc,
|
|||
state->pending_vrefresh, 0,
|
||||
cmdq_handle);
|
||||
|
||||
state->pending_config = false;
|
||||
if (!cmdq_handle)
|
||||
state->pending_config = false;
|
||||
}
|
||||
|
||||
if (mtk_crtc->pending_planes) {
|
||||
|
@ -398,9 +474,12 @@ static void mtk_crtc_ddp_config(struct drm_crtc *crtc,
|
|||
mtk_ddp_comp_layer_config(comp, local_layer,
|
||||
plane_state,
|
||||
cmdq_handle);
|
||||
plane_state->pending.config = false;
|
||||
if (!cmdq_handle)
|
||||
plane_state->pending.config = false;
|
||||
}
|
||||
mtk_crtc->pending_planes = false;
|
||||
|
||||
if (!cmdq_handle)
|
||||
mtk_crtc->pending_planes = false;
|
||||
}
|
||||
|
||||
if (mtk_crtc->pending_async_planes) {
|
||||
|
@ -420,9 +499,12 @@ static void mtk_crtc_ddp_config(struct drm_crtc *crtc,
|
|||
mtk_ddp_comp_layer_config(comp, local_layer,
|
||||
plane_state,
|
||||
cmdq_handle);
|
||||
plane_state->pending.async_config = false;
|
||||
if (!cmdq_handle)
|
||||
plane_state->pending.async_config = false;
|
||||
}
|
||||
mtk_crtc->pending_async_planes = false;
|
||||
|
||||
if (!cmdq_handle)
|
||||
mtk_crtc->pending_async_planes = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -430,7 +512,7 @@ static void mtk_drm_crtc_update_config(struct mtk_drm_crtc *mtk_crtc,
|
|||
bool needs_vblank)
|
||||
{
|
||||
#if IS_REACHABLE(CONFIG_MTK_CMDQ)
|
||||
struct cmdq_pkt *cmdq_handle;
|
||||
struct cmdq_pkt *cmdq_handle = &mtk_crtc->cmdq_handle;
|
||||
#endif
|
||||
struct drm_crtc *crtc = &mtk_crtc->base;
|
||||
struct mtk_drm_private *priv = crtc->dev->dev_private;
|
||||
|
@ -468,14 +550,24 @@ static void mtk_drm_crtc_update_config(struct mtk_drm_crtc *mtk_crtc,
|
|||
mtk_mutex_release(mtk_crtc->mutex);
|
||||
}
|
||||
#if IS_REACHABLE(CONFIG_MTK_CMDQ)
|
||||
if (mtk_crtc->cmdq_client) {
|
||||
mbox_flush(mtk_crtc->cmdq_client->chan, 2000);
|
||||
cmdq_handle = cmdq_pkt_create(mtk_crtc->cmdq_client, PAGE_SIZE);
|
||||
if (mtk_crtc->cmdq_chan) {
|
||||
mbox_flush(mtk_crtc->cmdq_chan, 2000);
|
||||
cmdq_handle->cmd_buf_size = 0;
|
||||
cmdq_pkt_clear_event(cmdq_handle, mtk_crtc->cmdq_event);
|
||||
cmdq_pkt_wfe(cmdq_handle, mtk_crtc->cmdq_event, false);
|
||||
mtk_crtc_ddp_config(crtc, cmdq_handle);
|
||||
cmdq_pkt_finalize(cmdq_handle);
|
||||
cmdq_pkt_flush_async(cmdq_handle, ddp_cmdq_cb, cmdq_handle);
|
||||
dma_sync_single_for_device(mtk_crtc->cmdq_chan->mbox->dev,
|
||||
cmdq_handle->pa_base,
|
||||
cmdq_handle->cmd_buf_size,
|
||||
DMA_TO_DEVICE);
|
||||
/*
|
||||
* CMDQ command should execute in next vblank,
|
||||
* If it fail to execute in next 2 vblank, timeout happen.
|
||||
*/
|
||||
mtk_crtc->cmdq_vblank_cnt = 2;
|
||||
mbox_send_message(mtk_crtc->cmdq_chan, cmdq_handle);
|
||||
mbox_client_txdone(mtk_crtc->cmdq_chan, 0);
|
||||
}
|
||||
#endif
|
||||
mtk_crtc->config_updating = false;
|
||||
|
@ -489,12 +581,15 @@ static void mtk_crtc_ddp_irq(void *data)
|
|||
struct mtk_drm_private *priv = crtc->dev->dev_private;
|
||||
|
||||
#if IS_REACHABLE(CONFIG_MTK_CMDQ)
|
||||
if (!priv->data->shadow_register && !mtk_crtc->cmdq_client)
|
||||
if (!priv->data->shadow_register && !mtk_crtc->cmdq_chan)
|
||||
mtk_crtc_ddp_config(crtc, NULL);
|
||||
else if (mtk_crtc->cmdq_vblank_cnt > 0 && --mtk_crtc->cmdq_vblank_cnt == 0)
|
||||
DRM_ERROR("mtk_crtc %d CMDQ execute command timeout!\n",
|
||||
drm_crtc_index(&mtk_crtc->base));
|
||||
#else
|
||||
if (!priv->data->shadow_register)
|
||||
#endif
|
||||
mtk_crtc_ddp_config(crtc, NULL);
|
||||
|
||||
#endif
|
||||
mtk_drm_finish_page_flip(mtk_crtc);
|
||||
}
|
||||
|
||||
|
@ -755,14 +850,22 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
|
|||
for (i = 0; i < path_len; i++) {
|
||||
enum mtk_ddp_comp_id comp_id = path[i];
|
||||
struct device_node *node;
|
||||
struct mtk_ddp_comp *comp;
|
||||
|
||||
node = priv->comp_node[comp_id];
|
||||
comp = &priv->ddp_comp[comp_id];
|
||||
|
||||
if (!node) {
|
||||
dev_info(dev,
|
||||
"Not creating crtc %d because component %d is disabled or missing\n",
|
||||
pipe, comp_id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!comp->dev) {
|
||||
dev_err(dev, "Component %pOF not initialized\n", node);
|
||||
return -ENODEV;
|
||||
}
|
||||
}
|
||||
|
||||
mtk_crtc = devm_kzalloc(dev, sizeof(*mtk_crtc), GFP_KERNEL);
|
||||
|
@ -787,16 +890,8 @@ 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];
|
||||
struct mtk_ddp_comp *comp;
|
||||
struct device_node *node;
|
||||
|
||||
node = priv->comp_node[comp_id];
|
||||
comp = &priv->ddp_comp[comp_id];
|
||||
if (!comp) {
|
||||
dev_err(dev, "Component %pOF not initialized\n", node);
|
||||
ret = -ENODEV;
|
||||
return ret;
|
||||
}
|
||||
|
||||
mtk_crtc->ddp_comp[i] = comp;
|
||||
|
||||
if (comp->funcs) {
|
||||
|
@ -832,16 +927,20 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
|
|||
mutex_init(&mtk_crtc->hw_lock);
|
||||
|
||||
#if IS_REACHABLE(CONFIG_MTK_CMDQ)
|
||||
mtk_crtc->cmdq_client =
|
||||
cmdq_mbox_create(mtk_crtc->mmsys_dev,
|
||||
drm_crtc_index(&mtk_crtc->base));
|
||||
if (IS_ERR(mtk_crtc->cmdq_client)) {
|
||||
mtk_crtc->cmdq_cl.dev = mtk_crtc->mmsys_dev;
|
||||
mtk_crtc->cmdq_cl.tx_block = false;
|
||||
mtk_crtc->cmdq_cl.knows_txdone = true;
|
||||
mtk_crtc->cmdq_cl.rx_callback = ddp_cmdq_cb;
|
||||
mtk_crtc->cmdq_chan =
|
||||
mbox_request_channel(&mtk_crtc->cmdq_cl,
|
||||
drm_crtc_index(&mtk_crtc->base));
|
||||
if (IS_ERR(mtk_crtc->cmdq_chan)) {
|
||||
dev_dbg(dev, "mtk_crtc %d failed to create mailbox client, writing register by CPU now\n",
|
||||
drm_crtc_index(&mtk_crtc->base));
|
||||
mtk_crtc->cmdq_client = NULL;
|
||||
mtk_crtc->cmdq_chan = NULL;
|
||||
}
|
||||
|
||||
if (mtk_crtc->cmdq_client) {
|
||||
if (mtk_crtc->cmdq_chan) {
|
||||
ret = of_property_read_u32_index(priv->mutex_node,
|
||||
"mediatek,gce-events",
|
||||
drm_crtc_index(&mtk_crtc->base),
|
||||
|
@ -849,8 +948,18 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
|
|||
if (ret) {
|
||||
dev_dbg(dev, "mtk_crtc %d failed to get mediatek,gce-events property\n",
|
||||
drm_crtc_index(&mtk_crtc->base));
|
||||
cmdq_mbox_destroy(mtk_crtc->cmdq_client);
|
||||
mtk_crtc->cmdq_client = NULL;
|
||||
mbox_free_channel(mtk_crtc->cmdq_chan);
|
||||
mtk_crtc->cmdq_chan = NULL;
|
||||
} else {
|
||||
ret = mtk_drm_cmdq_pkt_create(mtk_crtc->cmdq_chan,
|
||||
&mtk_crtc->cmdq_handle,
|
||||
PAGE_SIZE);
|
||||
if (ret) {
|
||||
dev_dbg(dev, "mtk_crtc %d failed to create cmdq packet\n",
|
||||
drm_crtc_index(&mtk_crtc->base));
|
||||
mbox_free_channel(mtk_crtc->cmdq_chan);
|
||||
mtk_crtc->cmdq_chan = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -32,9 +32,6 @@
|
|||
|
||||
#define DISP_REG_UFO_START 0x0000
|
||||
|
||||
#define DISP_AAL_EN 0x0000
|
||||
#define DISP_AAL_SIZE 0x0030
|
||||
|
||||
#define DISP_DITHER_EN 0x0000
|
||||
#define DITHER_EN BIT(0)
|
||||
#define DISP_DITHER_CFG 0x0020
|
||||
|
@ -48,8 +45,6 @@
|
|||
|
||||
#define UFO_BYPASS BIT(2)
|
||||
|
||||
#define AAL_EN BIT(0)
|
||||
|
||||
#define DISP_DITHERING BIT(2)
|
||||
#define DITHER_LSB_ERR_SHIFT_R(x) (((x) & 0x7) << 28)
|
||||
#define DITHER_OVFLW_BIT_R(x) (((x) & 0x7) << 24)
|
||||
|
@ -190,36 +185,6 @@ static void mtk_ufoe_start(struct device *dev)
|
|||
writel(UFO_BYPASS, priv->regs + DISP_REG_UFO_START);
|
||||
}
|
||||
|
||||
static void mtk_aal_config(struct device *dev, unsigned int w,
|
||||
unsigned int h, unsigned int vrefresh,
|
||||
unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
|
||||
{
|
||||
struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
|
||||
|
||||
mtk_ddp_write(cmdq_pkt, w << 16 | h, &priv->cmdq_reg, priv->regs, DISP_AAL_SIZE);
|
||||
}
|
||||
|
||||
static void mtk_aal_gamma_set(struct device *dev, struct drm_crtc_state *state)
|
||||
{
|
||||
struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
|
||||
|
||||
mtk_gamma_set_common(priv->regs, state);
|
||||
}
|
||||
|
||||
static void mtk_aal_start(struct device *dev)
|
||||
{
|
||||
struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
|
||||
|
||||
writel(AAL_EN, priv->regs + DISP_AAL_EN);
|
||||
}
|
||||
|
||||
static void mtk_aal_stop(struct device *dev)
|
||||
{
|
||||
struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
|
||||
|
||||
writel_relaxed(0x0, priv->regs + DISP_AAL_EN);
|
||||
}
|
||||
|
||||
static void mtk_dither_config(struct device *dev, unsigned int w,
|
||||
unsigned int h, unsigned int vrefresh,
|
||||
unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
|
||||
|
@ -247,8 +212,8 @@ static void mtk_dither_stop(struct device *dev)
|
|||
}
|
||||
|
||||
static const struct mtk_ddp_comp_funcs ddp_aal = {
|
||||
.clk_enable = mtk_ddp_clk_enable,
|
||||
.clk_disable = mtk_ddp_clk_disable,
|
||||
.clk_enable = mtk_aal_clk_enable,
|
||||
.clk_disable = mtk_aal_clk_disable,
|
||||
.gamma_set = mtk_aal_gamma_set,
|
||||
.config = mtk_aal_config,
|
||||
.start = mtk_aal_start,
|
||||
|
@ -505,7 +470,8 @@ int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp,
|
|||
return ret;
|
||||
}
|
||||
|
||||
if (type == MTK_DISP_BLS ||
|
||||
if (type == MTK_DISP_AAL ||
|
||||
type == MTK_DISP_BLS ||
|
||||
type == MTK_DISP_CCORR ||
|
||||
type == MTK_DISP_COLOR ||
|
||||
type == MTK_DISP_GAMMA ||
|
||||
|
|
|
@ -110,6 +110,17 @@ static const enum mtk_ddp_comp_id mt2712_mtk_ddp_third[] = {
|
|||
DDP_COMPONENT_PWM2,
|
||||
};
|
||||
|
||||
static enum mtk_ddp_comp_id mt8167_mtk_ddp_main[] = {
|
||||
DDP_COMPONENT_OVL0,
|
||||
DDP_COMPONENT_COLOR0,
|
||||
DDP_COMPONENT_CCORR,
|
||||
DDP_COMPONENT_AAL0,
|
||||
DDP_COMPONENT_GAMMA,
|
||||
DDP_COMPONENT_DITHER,
|
||||
DDP_COMPONENT_RDMA0,
|
||||
DDP_COMPONENT_DSI0,
|
||||
};
|
||||
|
||||
static const enum mtk_ddp_comp_id mt8173_mtk_ddp_main[] = {
|
||||
DDP_COMPONENT_OVL0,
|
||||
DDP_COMPONENT_COLOR0,
|
||||
|
@ -172,6 +183,11 @@ static const struct mtk_mmsys_driver_data mt2712_mmsys_driver_data = {
|
|||
.third_len = ARRAY_SIZE(mt2712_mtk_ddp_third),
|
||||
};
|
||||
|
||||
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_driver_data mt8173_mmsys_driver_data = {
|
||||
.main_path = mt8173_mtk_ddp_main,
|
||||
.main_len = ARRAY_SIZE(mt8173_mtk_ddp_main),
|
||||
|
@ -294,16 +310,7 @@ static void mtk_drm_kms_deinit(struct drm_device *drm)
|
|||
component_unbind_all(drm->dev, drm);
|
||||
}
|
||||
|
||||
static const struct file_operations mtk_drm_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = drm_open,
|
||||
.release = drm_release,
|
||||
.unlocked_ioctl = drm_ioctl,
|
||||
.mmap = mtk_drm_gem_mmap,
|
||||
.poll = drm_poll,
|
||||
.read = drm_read,
|
||||
.compat_ioctl = drm_compat_ioctl,
|
||||
};
|
||||
DEFINE_DRM_GEM_FOPS(mtk_drm_fops);
|
||||
|
||||
/*
|
||||
* We need to override this because the device used to import the memory is
|
||||
|
@ -326,7 +333,7 @@ static const struct drm_driver mtk_drm_driver = {
|
|||
.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
|
||||
.gem_prime_import = mtk_drm_gem_prime_import,
|
||||
.gem_prime_import_sg_table = mtk_gem_prime_import_sg_table,
|
||||
.gem_prime_mmap = mtk_drm_gem_mmap_buf,
|
||||
.gem_prime_mmap = drm_gem_prime_mmap,
|
||||
.fops = &mtk_drm_fops,
|
||||
|
||||
.name = DRIVER_NAME,
|
||||
|
@ -392,6 +399,8 @@ static const struct component_master_ops mtk_drm_ops = {
|
|||
static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
|
||||
{ .compatible = "mediatek,mt2701-disp-ovl",
|
||||
.data = (void *)MTK_DISP_OVL },
|
||||
{ .compatible = "mediatek,mt8167-disp-ovl",
|
||||
.data = (void *)MTK_DISP_OVL },
|
||||
{ .compatible = "mediatek,mt8173-disp-ovl",
|
||||
.data = (void *)MTK_DISP_OVL },
|
||||
{ .compatible = "mediatek,mt8183-disp-ovl",
|
||||
|
@ -400,30 +409,46 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
|
|||
.data = (void *)MTK_DISP_OVL_2L },
|
||||
{ .compatible = "mediatek,mt2701-disp-rdma",
|
||||
.data = (void *)MTK_DISP_RDMA },
|
||||
{ .compatible = "mediatek,mt8167-disp-rdma",
|
||||
.data = (void *)MTK_DISP_RDMA },
|
||||
{ .compatible = "mediatek,mt8173-disp-rdma",
|
||||
.data = (void *)MTK_DISP_RDMA },
|
||||
{ .compatible = "mediatek,mt8183-disp-rdma",
|
||||
.data = (void *)MTK_DISP_RDMA },
|
||||
{ .compatible = "mediatek,mt8173-disp-wdma",
|
||||
.data = (void *)MTK_DISP_WDMA },
|
||||
{ .compatible = "mediatek,mt8167-disp-ccorr",
|
||||
.data = (void *)MTK_DISP_CCORR },
|
||||
{ .compatible = "mediatek,mt8183-disp-ccorr",
|
||||
.data = (void *)MTK_DISP_CCORR },
|
||||
{ .compatible = "mediatek,mt2701-disp-color",
|
||||
.data = (void *)MTK_DISP_COLOR },
|
||||
{ .compatible = "mediatek,mt8167-disp-color",
|
||||
.data = (void *)MTK_DISP_COLOR },
|
||||
{ .compatible = "mediatek,mt8173-disp-color",
|
||||
.data = (void *)MTK_DISP_COLOR },
|
||||
{ .compatible = "mediatek,mt8167-disp-aal",
|
||||
.data = (void *)MTK_DISP_AAL},
|
||||
{ .compatible = "mediatek,mt8173-disp-aal",
|
||||
.data = (void *)MTK_DISP_AAL},
|
||||
{ .compatible = "mediatek,mt8183-disp-aal",
|
||||
.data = (void *)MTK_DISP_AAL},
|
||||
{ .compatible = "mediatek,mt8167-disp-gamma",
|
||||
.data = (void *)MTK_DISP_GAMMA, },
|
||||
{ .compatible = "mediatek,mt8173-disp-gamma",
|
||||
.data = (void *)MTK_DISP_GAMMA, },
|
||||
{ .compatible = "mediatek,mt8183-disp-gamma",
|
||||
.data = (void *)MTK_DISP_GAMMA, },
|
||||
{ .compatible = "mediatek,mt8167-disp-dither",
|
||||
.data = (void *)MTK_DISP_DITHER },
|
||||
{ .compatible = "mediatek,mt8183-disp-dither",
|
||||
.data = (void *)MTK_DISP_DITHER },
|
||||
{ .compatible = "mediatek,mt8173-disp-ufoe",
|
||||
.data = (void *)MTK_DISP_UFOE },
|
||||
{ .compatible = "mediatek,mt2701-dsi",
|
||||
.data = (void *)MTK_DSI },
|
||||
{ .compatible = "mediatek,mt8167-dsi",
|
||||
.data = (void *)MTK_DSI },
|
||||
{ .compatible = "mediatek,mt8173-dsi",
|
||||
.data = (void *)MTK_DSI },
|
||||
{ .compatible = "mediatek,mt8183-dsi",
|
||||
|
@ -438,12 +463,16 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
|
|||
.data = (void *)MTK_DISP_MUTEX },
|
||||
{ .compatible = "mediatek,mt2712-disp-mutex",
|
||||
.data = (void *)MTK_DISP_MUTEX },
|
||||
{ .compatible = "mediatek,mt8167-disp-mutex",
|
||||
.data = (void *)MTK_DISP_MUTEX },
|
||||
{ .compatible = "mediatek,mt8173-disp-mutex",
|
||||
.data = (void *)MTK_DISP_MUTEX },
|
||||
{ .compatible = "mediatek,mt8183-disp-mutex",
|
||||
.data = (void *)MTK_DISP_MUTEX },
|
||||
{ .compatible = "mediatek,mt2701-disp-pwm",
|
||||
.data = (void *)MTK_DISP_BLS },
|
||||
{ .compatible = "mediatek,mt8167-disp-pwm",
|
||||
.data = (void *)MTK_DISP_PWM },
|
||||
{ .compatible = "mediatek,mt8173-disp-pwm",
|
||||
.data = (void *)MTK_DISP_PWM },
|
||||
{ .compatible = "mediatek,mt8173-disp-od",
|
||||
|
@ -458,6 +487,8 @@ static const struct of_device_id mtk_drm_of_ids[] = {
|
|||
.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",
|
||||
|
@ -526,11 +557,12 @@ static int mtk_drm_probe(struct platform_device *pdev)
|
|||
private->comp_node[comp_id] = of_node_get(node);
|
||||
|
||||
/*
|
||||
* Currently only the CCORR, COLOR, GAMMA, OVL, RDMA, DSI, and DPI
|
||||
* Currently only the AAL, CCORR, COLOR, GAMMA, OVL, RDMA, DSI, and DPI
|
||||
* blocks have separate component platform drivers and initialize their own
|
||||
* DDP component structure. The others are initialized here.
|
||||
*/
|
||||
if (comp_type == MTK_DISP_CCORR ||
|
||||
if (comp_type == MTK_DISP_AAL ||
|
||||
comp_type == MTK_DISP_CCORR ||
|
||||
comp_type == MTK_DISP_COLOR ||
|
||||
comp_type == MTK_DISP_GAMMA ||
|
||||
comp_type == MTK_DISP_OVL ||
|
||||
|
@ -630,6 +662,7 @@ static struct platform_driver mtk_drm_platform_driver = {
|
|||
};
|
||||
|
||||
static struct platform_driver * const mtk_drm_drivers[] = {
|
||||
&mtk_disp_aal_driver,
|
||||
&mtk_disp_ccorr_driver,
|
||||
&mtk_disp_color_driver,
|
||||
&mtk_disp_gamma_driver,
|
||||
|
|
|
@ -46,6 +46,7 @@ struct mtk_drm_private {
|
|||
struct drm_atomic_state *suspend_state;
|
||||
};
|
||||
|
||||
extern struct platform_driver mtk_disp_aal_driver;
|
||||
extern struct platform_driver mtk_disp_ccorr_driver;
|
||||
extern struct platform_driver mtk_disp_color_driver;
|
||||
extern struct platform_driver mtk_disp_gamma_driver;
|
||||
|
|
|
@ -14,11 +14,14 @@
|
|||
#include "mtk_drm_drv.h"
|
||||
#include "mtk_drm_gem.h"
|
||||
|
||||
static int mtk_drm_gem_object_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma);
|
||||
|
||||
static const struct drm_gem_object_funcs mtk_drm_gem_object_funcs = {
|
||||
.free = mtk_drm_gem_free_object,
|
||||
.get_sg_table = mtk_gem_prime_get_sg_table,
|
||||
.vmap = mtk_drm_gem_prime_vmap,
|
||||
.vunmap = mtk_drm_gem_prime_vunmap,
|
||||
.mmap = mtk_drm_gem_object_mmap,
|
||||
.vm_ops = &drm_gem_cma_vm_ops,
|
||||
};
|
||||
|
||||
|
@ -145,11 +148,19 @@ static int mtk_drm_gem_object_mmap(struct drm_gem_object *obj,
|
|||
struct mtk_drm_gem_obj *mtk_gem = to_mtk_gem_obj(obj);
|
||||
struct mtk_drm_private *priv = obj->dev->dev_private;
|
||||
|
||||
/*
|
||||
* Set vm_pgoff (used as a fake buffer offset by DRM) to 0 and map the
|
||||
* whole buffer from the start.
|
||||
*/
|
||||
vma->vm_pgoff = 0;
|
||||
|
||||
/*
|
||||
* dma_alloc_attrs() allocated a struct page table for mtk_gem, so clear
|
||||
* VM_PFNMAP flag that was set by drm_gem_mmap_obj()/drm_gem_mmap().
|
||||
*/
|
||||
vma->vm_flags &= ~VM_PFNMAP;
|
||||
vma->vm_flags |= VM_IO | VM_DONTEXPAND | VM_DONTDUMP;
|
||||
vma->vm_page_prot = pgprot_writecombine(vm_get_page_prot(vma->vm_flags));
|
||||
vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot);
|
||||
|
||||
ret = dma_mmap_attrs(priv->dma_dev, vma, mtk_gem->cookie,
|
||||
mtk_gem->dma_addr, obj->size, mtk_gem->dma_attrs);
|
||||
|
@ -159,37 +170,6 @@ static int mtk_drm_gem_object_mmap(struct drm_gem_object *obj,
|
|||
return ret;
|
||||
}
|
||||
|
||||
int mtk_drm_gem_mmap_buf(struct drm_gem_object *obj, struct vm_area_struct *vma)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = drm_gem_mmap_obj(obj, obj->size, vma);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return mtk_drm_gem_object_mmap(obj, vma);
|
||||
}
|
||||
|
||||
int mtk_drm_gem_mmap(struct file *filp, struct vm_area_struct *vma)
|
||||
{
|
||||
struct drm_gem_object *obj;
|
||||
int ret;
|
||||
|
||||
ret = drm_gem_mmap(filp, vma);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
obj = vma->vm_private_data;
|
||||
|
||||
/*
|
||||
* Set vm_pgoff (used as a fake buffer offset by DRM) to 0 and map the
|
||||
* whole buffer from the start.
|
||||
*/
|
||||
vma->vm_pgoff = 0;
|
||||
|
||||
return mtk_drm_gem_object_mmap(obj, vma);
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate a sg_table for this GEM object.
|
||||
* Note: Both the table's contents, and the sg_table itself must be freed by
|
||||
|
|
|
@ -39,9 +39,6 @@ struct mtk_drm_gem_obj *mtk_drm_gem_create(struct drm_device *dev, size_t size,
|
|||
bool alloc_kmap);
|
||||
int mtk_drm_gem_dumb_create(struct drm_file *file_priv, struct drm_device *dev,
|
||||
struct drm_mode_create_dumb *args);
|
||||
int mtk_drm_gem_mmap(struct file *filp, struct vm_area_struct *vma);
|
||||
int mtk_drm_gem_mmap_buf(struct drm_gem_object *obj,
|
||||
struct vm_area_struct *vma);
|
||||
struct sg_table *mtk_gem_prime_get_sg_table(struct drm_gem_object *obj);
|
||||
struct drm_gem_object *mtk_gem_prime_import_sg_table(struct drm_device *dev,
|
||||
struct dma_buf_attachment *attach, struct sg_table *sg);
|
||||
|
|
Загрузка…
Ссылка в новой задаче