Commit f97a1b65 authored by Dave Airlie's avatar Dave Airlie

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

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: default avatarDave 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
parents 2819cf0e 9efb16c2
...@@ -7,7 +7,7 @@ channel output. ...@@ -7,7 +7,7 @@ channel output.
Required properties: Required properties:
- compatible: "mediatek,<chip>-dsi" - 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 - reg: Physical base address and length of the controller's registers
- interrupts: The interrupt signal from the function block. - interrupts: The interrupt signal from the function block.
- clocks: device clocks - clocks: device clocks
......
# SPDX-License-Identifier: GPL-2.0 # 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_color.o \
mtk_disp_gamma.o \ mtk_disp_gamma.o \
mtk_disp_ovl.o \ mtk_disp_ovl.o \
......
// 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 @@ ...@@ -9,6 +9,15 @@
#include <linux/soc/mediatek/mtk-cmdq.h> #include <linux/soc/mediatek/mtk-cmdq.h>
#include "mtk_drm_plane.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); void mtk_ccorr_ctm_set(struct device *dev, struct drm_crtc_state *state);
int mtk_ccorr_clk_enable(struct device *dev); int mtk_ccorr_clk_enable(struct device *dev);
void mtk_ccorr_clk_disable(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, ...@@ -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. * Enable FIFO underflow since DSI and DPI can't be blocked.
* Keep the FIFO pseudo size reset default of 8 KiB. Set the * Keep the FIFO pseudo size reset default of 8 KiB. Set the
* output threshold to 6 microseconds with 7/6 overhead to * output threshold to 70% of max fifo size to make sure the
* account for blanking, and with a pixel depth of 4 bytes: * threhold will not overflow
*/ */
threshold = width * height * vrefresh * 4 * 7 / 1000000; threshold = rdma_fifo_size * 7 / 10;
reg = RDMA_FIFO_UNDERFLOW_EN | reg = RDMA_FIFO_UNDERFLOW_EN |
RDMA_FIFO_PSEUDO_SIZE(rdma_fifo_size) | RDMA_FIFO_PSEUDO_SIZE(rdma_fifo_size) |
RDMA_OUTPUT_VALID_FIFO_THRESHOLD(threshold); RDMA_OUTPUT_VALID_FIFO_THRESHOLD(threshold);
......
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
*/ */
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/dma-mapping.h>
#include <linux/mailbox_controller.h>
#include <linux/pm_runtime.h> #include <linux/pm_runtime.h>
#include <linux/soc/mediatek/mtk-cmdq.h> #include <linux/soc/mediatek/mtk-cmdq.h>
#include <linux/soc/mediatek/mtk-mmsys.h> #include <linux/soc/mediatek/mtk-mmsys.h>
...@@ -50,8 +52,11 @@ struct mtk_drm_crtc { ...@@ -50,8 +52,11 @@ struct mtk_drm_crtc {
bool pending_async_planes; bool pending_async_planes;
#if IS_REACHABLE(CONFIG_MTK_CMDQ) #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_event;
u32 cmdq_vblank_cnt;
#endif #endif
struct device *mmsys_dev; struct device *mmsys_dev;
...@@ -222,9 +227,79 @@ struct mtk_ddp_comp *mtk_drm_ddp_comp_for_plane(struct drm_crtc *crtc, ...@@ -222,9 +227,79 @@ struct mtk_ddp_comp *mtk_drm_ddp_comp_for_plane(struct drm_crtc *crtc,
} }
#if IS_REACHABLE(CONFIG_MTK_CMDQ) #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 #endif
...@@ -378,6 +453,7 @@ static void mtk_crtc_ddp_config(struct drm_crtc *crtc, ...@@ -378,6 +453,7 @@ static void mtk_crtc_ddp_config(struct drm_crtc *crtc,
state->pending_vrefresh, 0, state->pending_vrefresh, 0,
cmdq_handle); cmdq_handle);
if (!cmdq_handle)
state->pending_config = false; state->pending_config = false;
} }
...@@ -398,8 +474,11 @@ static void mtk_crtc_ddp_config(struct drm_crtc *crtc, ...@@ -398,8 +474,11 @@ static void mtk_crtc_ddp_config(struct drm_crtc *crtc,
mtk_ddp_comp_layer_config(comp, local_layer, mtk_ddp_comp_layer_config(comp, local_layer,
plane_state, plane_state,
cmdq_handle); cmdq_handle);
if (!cmdq_handle)
plane_state->pending.config = false; plane_state->pending.config = false;
} }
if (!cmdq_handle)
mtk_crtc->pending_planes = false; mtk_crtc->pending_planes = false;
} }
...@@ -420,8 +499,11 @@ static void mtk_crtc_ddp_config(struct drm_crtc *crtc, ...@@ -420,8 +499,11 @@ static void mtk_crtc_ddp_config(struct drm_crtc *crtc,
mtk_ddp_comp_layer_config(comp, local_layer, mtk_ddp_comp_layer_config(comp, local_layer,
plane_state, plane_state,
cmdq_handle); cmdq_handle);
if (!cmdq_handle)
plane_state->pending.async_config = false; plane_state->pending.async_config = false;
} }
if (!cmdq_handle)
mtk_crtc->pending_async_planes = false; mtk_crtc->pending_async_planes = false;
} }
} }
...@@ -430,7 +512,7 @@ static void mtk_drm_crtc_update_config(struct mtk_drm_crtc *mtk_crtc, ...@@ -430,7 +512,7 @@ static void mtk_drm_crtc_update_config(struct mtk_drm_crtc *mtk_crtc,
bool needs_vblank) bool needs_vblank)
{ {
#if IS_REACHABLE(CONFIG_MTK_CMDQ) #if IS_REACHABLE(CONFIG_MTK_CMDQ)
struct cmdq_pkt *cmdq_handle; struct cmdq_pkt *cmdq_handle = &mtk_crtc->cmdq_handle;
#endif #endif
struct drm_crtc *crtc = &mtk_crtc->base; struct drm_crtc *crtc = &mtk_crtc->base;
struct mtk_drm_private *priv = crtc->dev->dev_private; 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, ...@@ -468,14 +550,24 @@ static void mtk_drm_crtc_update_config(struct mtk_drm_crtc *mtk_crtc,
mtk_mutex_release(mtk_crtc->mutex); mtk_mutex_release(mtk_crtc->mutex);
} }
#if IS_REACHABLE(CONFIG_MTK_CMDQ) #if IS_REACHABLE(CONFIG_MTK_CMDQ)
if (mtk_crtc->cmdq_client) { if (mtk_crtc->cmdq_chan) {
mbox_flush(mtk_crtc->cmdq_client->chan, 2000); mbox_flush(mtk_crtc->cmdq_chan, 2000);
cmdq_handle = cmdq_pkt_create(mtk_crtc->cmdq_client, PAGE_SIZE); cmdq_handle->cmd_buf_size = 0;
cmdq_pkt_clear_event(cmdq_handle, mtk_crtc->cmdq_event); cmdq_pkt_clear_event(cmdq_handle, mtk_crtc->cmdq_event);
cmdq_pkt_wfe(cmdq_handle, mtk_crtc->cmdq_event, false); cmdq_pkt_wfe(cmdq_handle, mtk_crtc->cmdq_event, false);
mtk_crtc_ddp_config(crtc, cmdq_handle); mtk_crtc_ddp_config(crtc, cmdq_handle);
cmdq_pkt_finalize(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 #endif
mtk_crtc->config_updating = false; mtk_crtc->config_updating = false;
...@@ -489,12 +581,15 @@ static void mtk_crtc_ddp_irq(void *data) ...@@ -489,12 +581,15 @@ static void mtk_crtc_ddp_irq(void *data)
struct mtk_drm_private *priv = crtc->dev->dev_private; struct mtk_drm_private *priv = crtc->dev->dev_private;
#if IS_REACHABLE(CONFIG_MTK_CMDQ) #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 #else
if (!priv->data->shadow_register) if (!priv->data->shadow_register)
#endif
mtk_crtc_ddp_config(crtc, NULL); mtk_crtc_ddp_config(crtc, NULL);
#endif
mtk_drm_finish_page_flip(mtk_crtc); mtk_drm_finish_page_flip(mtk_crtc);
} }
...@@ -755,14 +850,22 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev, ...@@ -755,14 +850,22 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
for (i = 0; i < path_len; i++) { for (i = 0; i < path_len; i++) {
enum mtk_ddp_comp_id comp_id = path[i]; enum mtk_ddp_comp_id comp_id = path[i];
struct device_node *node; struct device_node *node;
struct mtk_ddp_comp *comp;
node = priv->comp_node[comp_id]; node = priv->comp_node[comp_id];
comp = &priv->ddp_comp[comp_id];
if (!node) { if (!node) {
dev_info(dev, dev_info(dev,
"Not creating crtc %d because component %d is disabled or missing\n", "Not creating crtc %d because component %d is disabled or missing\n",
pipe, comp_id); pipe, comp_id);
return 0; 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); mtk_crtc = devm_kzalloc(dev, sizeof(*mtk_crtc), GFP_KERNEL);
...@@ -787,16 +890,8 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev, ...@@ -787,16 +890,8 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) { for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {
enum mtk_ddp_comp_id comp_id = path[i]; enum mtk_ddp_comp_id comp_id = path[i];
struct mtk_ddp_comp *comp; struct mtk_ddp_comp *comp;
struct device_node *node;
node = priv->comp_node[comp_id];
comp = &priv->ddp_comp[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; mtk_crtc->ddp_comp[i] = comp;
if (comp->funcs) { if (comp->funcs) {
...@@ -832,16 +927,20 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev, ...@@ -832,16 +927,20 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
mutex_init(&mtk_crtc->hw_lock); mutex_init(&mtk_crtc->hw_lock);
#if IS_REACHABLE(CONFIG_MTK_CMDQ) #if IS_REACHABLE(CONFIG_MTK_CMDQ)
mtk_crtc->cmdq_client = mtk_crtc->cmdq_cl.dev = mtk_crtc->mmsys_dev;
cmdq_mbox_create(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)); drm_crtc_index(&mtk_crtc->base));
if (IS_ERR(mtk_crtc->cmdq_client)) { if (IS_ERR(mtk_crtc->cmdq_chan)) {
dev_dbg(dev, "mtk_crtc %d failed to create mailbox client, writing register by CPU now\n", dev_dbg(dev, "mtk_crtc %d failed to create mailbox client, writing register by CPU now\n",
drm_crtc_index(&mtk_crtc->base)); 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, ret = of_property_read_u32_index(priv->mutex_node,
"mediatek,gce-events", "mediatek,gce-events",
drm_crtc_index(&mtk_crtc->base), drm_crtc_index(&mtk_crtc->base),
...@@ -849,8 +948,18 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev, ...@@ -849,8 +948,18 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
if (ret) { if (ret) {
dev_dbg(dev, "mtk_crtc %d failed to get mediatek,gce-events property\n", dev_dbg(dev, "mtk_crtc %d failed to get mediatek,gce-events property\n",
drm_crtc_index(&mtk_crtc->base)); drm_crtc_index(&mtk_crtc->base));
cmdq_mbox_destroy(mtk_crtc->cmdq_client); mbox_free_channel(mtk_crtc->cmdq_chan);
mtk_crtc->cmdq_client = NULL; 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 #endif
......
...@@ -32,9 +32,6 @@ ...@@ -32,9 +32,6 @@
#define DISP_REG_UFO_START 0x0000 #define DISP_REG_UFO_START 0x0000
#define DISP_AAL_EN 0x0000
#define DISP_AAL_SIZE 0x0030
#define DISP_DITHER_EN 0x0000 #define DISP_DITHER_EN 0x0000
#define DITHER_EN BIT(0) #define DITHER_EN BIT(0)
#define DISP_DITHER_CFG 0x0020 #define DISP_DITHER_CFG 0x0020
...@@ -48,8 +45,6 @@ ...@@ -48,8 +45,6 @@
#define UFO_BYPASS BIT(2) #define UFO_BYPASS BIT(2)
#define AAL_EN BIT(0)
#define DISP_DITHERING BIT(2) #define DISP_DITHERING BIT(2)
#define DITHER_LSB_ERR_SHIFT_R(x) (((x) & 0x7) << 28) #define DITHER_LSB_ERR_SHIFT_R(x) (((x) & 0x7) << 28)
#define DITHER_OVFLW_BIT_R(x) (((x) & 0x7) << 24) #define DITHER_OVFLW_BIT_R(x) (((x) & 0x7) << 24)
...@@ -190,36 +185,6 @@ static void mtk_ufoe_start(struct device *dev) ...@@ -190,36 +185,6 @@ static void mtk_ufoe_start(struct device *dev)
writel(UFO_BYPASS, priv->regs + DISP_REG_UFO_START); 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, static void mtk_dither_config(struct device *dev, unsigned int w,
unsigned int h, unsigned int vrefresh, unsigned int h, unsigned int vrefresh,
unsigned int bpc, struct cmdq_pkt *cmdq_pkt) unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
...@@ -247,8 +212,8 @@ static void mtk_dither_stop(struct device *dev) ...@@ -247,8 +212,8 @@ static void mtk_dither_stop(struct device *dev)
} }
static const struct mtk_ddp_comp_funcs ddp_aal = { static const struct mtk_ddp_comp_funcs ddp_aal = {
.clk_enable = mtk_ddp_clk_enable, .clk_enable = mtk_aal_clk_enable,
.clk_disable = mtk_ddp_clk_disable, .clk_disable = mtk_aal_clk_disable,
.gamma_set = mtk_aal_gamma_set, .gamma_set = mtk_aal_gamma_set,
.config = mtk_aal_config, .config = mtk_aal_config,
.start = mtk_aal_start, .start = mtk_aal_start,
...@@ -505,7 +470,8 @@ int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp, ...@@ -505,7 +470,8 @@ int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp,
return ret; return ret;
} }
if (type == MTK_DISP_BLS || if (type == MTK_DISP_AAL ||
type == MTK_DISP_BLS ||
type == MTK_DISP_CCORR || type == MTK_DISP_CCORR ||
type == MTK_DISP_COLOR || type == MTK_DISP_COLOR ||
type == MTK_DISP_GAMMA || type == MTK_DISP_GAMMA ||
......
...@@ -110,6 +110,17 @@ static const enum mtk_ddp_comp_id mt2712_mtk_ddp_third[] = { ...@@ -110,6 +110,17 @@ static const enum mtk_ddp_comp_id mt2712_mtk_ddp_third[] = {
DDP_COMPONENT_PWM2, 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[] = { static const enum mtk_ddp_comp_id mt8173_mtk_ddp_main[] = {
DDP_COMPONENT_OVL0, DDP_COMPONENT_OVL0,
DDP_COMPONENT_COLOR0, DDP_COMPONENT_COLOR0,
...@@ -172,6 +183,11 @@ static const struct mtk_mmsys_driver_data mt2712_mmsys_driver_data = { ...@@ -172,6 +183,11 @@ static const struct mtk_mmsys_driver_data mt2712_mmsys_driver_data = {
.third_len = ARRAY_SIZE(mt2712_mtk_ddp_third), .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 = { static const struct mtk_mmsys_driver_data mt8173_mmsys_driver_data = {
.main_path = mt8173_mtk_ddp_main, .main_path = mt8173_mtk_ddp_main,
.main_len = ARRAY_SIZE(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) ...@@ -294,16 +310,7 @@ static void mtk_drm_kms_deinit(struct drm_device *drm)
component_unbind_all(drm->dev, drm); component_unbind_all(drm->dev, drm);
} }
static const struct file_operations mtk_drm_fops = { DEFINE_DRM_GEM_FOPS(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,
};
/* /*
* We need to override this because the device used to import the memory is * 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 = { ...@@ -326,7 +333,7 @@ static const struct drm_driver mtk_drm_driver = {
.prime_fd_to_handle = drm_gem_prime_fd_to_handle, .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
.gem_prime_import = mtk_drm_gem_prime_import, .gem_prime_import = mtk_drm_gem_prime_import,
.gem_prime_import_sg_table = mtk_gem_prime_import_sg_table, .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, .fops = &mtk_drm_fops,
.name = DRIVER_NAME, .name = DRIVER_NAME,
...@@ -392,6 +399,8 @@ static const struct component_master_ops mtk_drm_ops = { ...@@ -392,6 +399,8 @@ static const struct component_master_ops mtk_drm_ops = {
static const struct of_device_id mtk_ddp_comp_dt_ids[] = { static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
{ .compatible = "mediatek,mt2701-disp-ovl", { .compatible = "mediatek,mt2701-disp-ovl",
.data = (void *)MTK_DISP_OVL }, .data = (void *)MTK_DISP_OVL },
{ .compatible = "mediatek,mt8167-disp-ovl",
.data = (void *)MTK_DISP_OVL },
{ .compatible = "mediatek,mt8173-disp-ovl", { .compatible = "mediatek,mt8173-disp-ovl",
.data = (void *)MTK_DISP_OVL }, .data = (void *)MTK_DISP_OVL },
{ .compatible = "mediatek,mt8183-disp-ovl", { .compatible = "mediatek,mt8183-disp-ovl",
...@@ -400,30 +409,46 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = { ...@@ -400,30 +409,46 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
.data = (void *)MTK_DISP_OVL_2L }, .data = (void *)MTK_DISP_OVL_2L },
{ .compatible = "mediatek,mt2701-disp-rdma", { .compatible = "mediatek,mt2701-disp-rdma",
.data = (void *)MTK_DISP_RDMA }, .data = (void *)MTK_DISP_RDMA },
{ .compatible = "mediatek,mt8167-disp-rdma",
.data = (void *)MTK_DISP_RDMA },
{ .compatible = "mediatek,mt8173-disp-rdma", { .compatible = "mediatek,mt8173-disp-rdma",
.data = (void *)MTK_DISP_RDMA }, .data = (void *)MTK_DISP_RDMA },
{ .compatible = "mediatek,mt8183-disp-rdma", { .compatible = "mediatek,mt8183-disp-rdma",
.data = (void *)MTK_DISP_RDMA }, .data = (void *)MTK_DISP_RDMA },
{ .compatible = "mediatek,mt8173-disp-wdma", { .compatible = "mediatek,mt8173-disp-wdma",
.data = (void *)MTK_DISP_WDMA }, .data = (void *)MTK_DISP_WDMA },
{ .compatible = "mediatek,mt8167-disp-ccorr",
.data = (void *)MTK_DISP_CCORR },
{ .compatible = "mediatek,mt8183-disp-ccorr", { .compatible = "mediatek,mt8183-disp-ccorr",
.data = (void *)MTK_DISP_CCORR }, .data = (void *)MTK_DISP_CCORR },
{ .compatible = "mediatek,mt2701-disp-color", { .compatible = "mediatek,mt2701-disp-color",
.data = (void *)MTK_DISP_COLOR }, .data = (void *)MTK_DISP_COLOR },
{ .compatible = "mediatek,mt8167-disp-color",
.data = (void *)MTK_DISP_COLOR },
{ .compatible = "mediatek,mt8173-disp-color", { .compatible = "mediatek,mt8173-disp-color",
.data = (void *)MTK_DISP_COLOR }, .data = (void *)MTK_DISP_COLOR },
{ .compatible = "mediatek,mt8167-disp-aal",
.data = (void *)MTK_DISP_AAL},
{ .compatible = "mediatek,mt8173-disp-aal", { .compatible = "mediatek,mt8173-disp-aal",
.data = (void *)MTK_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", { .compatible = "mediatek,mt8173-disp-gamma",
.data = (void *)MTK_DISP_GAMMA, }, .data = (void *)MTK_DISP_GAMMA, },
{ .compatible = "mediatek,mt8183-disp-gamma", { .compatible = "mediatek,mt8183-disp-gamma",
.data = (void *)MTK_DISP_GAMMA, }, .data = (void *)MTK_DISP_GAMMA, },
{ .compatible = "mediatek,mt8167-disp-dither",
.data = (void *)MTK_DISP_DITHER },
{ .compatible = "mediatek,mt8183-disp-dither", { .compatible = "mediatek,mt8183-disp-dither",
.data = (void *)MTK_DISP_DITHER }, .data = (void *)MTK_DISP_DITHER },
{ .compatible = "mediatek,mt8173-disp-ufoe", { .compatible = "mediatek,mt8173-disp-ufoe",
.data = (void *)MTK_DISP_UFOE }, .data = (void *)MTK_DISP_UFOE },
{ .compatible = "mediatek,mt2701-dsi", { .compatible = "mediatek,mt2701-dsi",
.data = (void *)MTK_DSI }, .data = (void *)MTK_DSI },
{ .compatible = "mediatek,mt8167-dsi",
.data = (void *)MTK_DSI },
{ .compatible = "mediatek,mt8173-dsi", { .compatible = "mediatek,mt8173-dsi",
.data = (void *)MTK_DSI }, .data = (void *)MTK_DSI },
{ .compatible = "mediatek,mt8183-dsi", { .compatible = "mediatek,mt8183-dsi",
...@@ -438,12 +463,16 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = { ...@@ -438,12 +463,16 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
.data = (void *)MTK_DISP_MUTEX }, .data = (void *)MTK_DISP_MUTEX },
{ .compatible = "mediatek,mt2712-disp-mutex", { .compatible = "mediatek,mt2712-disp-mutex",
.data = (void *)MTK_DISP_MUTEX }, .data = (void *)MTK_DISP_MUTEX },
{ .compatible = "mediatek,mt8167-disp-mutex",
.data = (void *)MTK_DISP_MUTEX },
{ .compatible = "mediatek,mt8173-disp-mutex", { .compatible = "mediatek,mt8173-disp-mutex",
.data = (void *)MTK_DISP_MUTEX }, .data = (void *)MTK_DISP_MUTEX },
{ .compatible = "mediatek,mt8183-disp-mutex", { .compatible = "mediatek,mt8183-disp-mutex",
.data = (void *)MTK_DISP_MUTEX }, .data = (void *)MTK_DISP_MUTEX },
{ .compatible = "mediatek,mt2701-disp-pwm", { .compatible = "mediatek,mt2701-disp-pwm",
.data = (void *)MTK_DISP_BLS }, .data = (void *)MTK_DISP_BLS },
{ .compatible = "mediatek,mt8167-disp-pwm",
.data = (void *)MTK_DISP_PWM },
{ .compatible = "mediatek,mt8173-disp-pwm", { .compatible = "mediatek,mt8173-disp-pwm",
.data = (void *)MTK_DISP_PWM }, .data = (void *)MTK_DISP_PWM },
{ .compatible = "mediatek,mt8173-disp-od", { .compatible = "mediatek,mt8173-disp-od",
...@@ -458,6 +487,8 @@ static const struct of_device_id mtk_drm_of_ids[] = { ...@@ -458,6 +487,8 @@ static const struct of_device_id mtk_drm_of_ids[] = {
.data = &mt7623_mmsys_driver_data}, .data = &mt7623_mmsys_driver_data},
{ .compatible = "mediatek,mt2712-mmsys", { .compatible = "mediatek,mt2712-mmsys",
.data = &mt2712_mmsys_driver_data}, .data = &mt2712_mmsys_driver_data},
{ .compatible = "mediatek,mt8167-mmsys",
.data = &mt8167_mmsys_driver_data},
{ .compatible = "mediatek,mt8173-mmsys", { .compatible = "mediatek,mt8173-mmsys",
.data = &mt8173_mmsys_driver_data}, .data = &mt8173_mmsys_driver_data},
{ .compatible = "mediatek,mt8183-mmsys", { .compatible = "mediatek,mt8183-mmsys",
...@@ -526,11 +557,12 @@ static int mtk_drm_probe(struct platform_device *pdev) ...@@ -526,11 +557,12 @@ static int mtk_drm_probe(struct platform_device *pdev)
private->comp_node[comp_id] = of_node_get(node); 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 * blocks have separate component platform drivers and initialize their own
* DDP component structure. The others are initialized here. * 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_COLOR ||
comp_type == MTK_DISP_GAMMA || comp_type == MTK_DISP_GAMMA ||
comp_type == MTK_DISP_OVL || comp_type == MTK_DISP_OVL ||
...@@ -630,6 +662,7 @@ static struct platform_driver mtk_drm_platform_driver = { ...@@ -630,6 +662,7 @@ static struct platform_driver mtk_drm_platform_driver = {
}; };
static struct platform_driver * const mtk_drm_drivers[] = { static struct platform_driver * const mtk_drm_drivers[] = {
&mtk_disp_aal_driver,
&mtk_disp_ccorr_driver, &mtk_disp_ccorr_driver,
&mtk_disp_color_driver, &mtk_disp_color_driver,
&mtk_disp_gamma_driver, &mtk_disp_gamma_driver,
......
...@@ -46,6 +46,7 @@ struct mtk_drm_private { ...@@ -46,6 +46,7 @@ struct mtk_drm_private {
struct drm_atomic_state *suspend_state; 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_ccorr_driver;
extern struct platform_driver mtk_disp_color_driver; extern struct platform_driver mtk_disp_color_driver;
extern struct platform_driver mtk_disp_gamma_driver; extern struct platform_driver mtk_disp_gamma_driver;
......
...@@ -14,11 +14,14 @@ ...@@ -14,11 +14,14 @@
#include "mtk_drm_drv.h" #include "mtk_drm_drv.h"
#include "mtk_drm_gem.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 = { static const struct drm_gem_object_funcs mtk_drm_gem_object_funcs = {
.free = mtk_drm_gem_free_object, .free = mtk_drm_gem_free_object,
.get_sg_table = mtk_gem_prime_get_sg_table, .get_sg_table = mtk_gem_prime_get_sg_table,
.vmap = mtk_drm_gem_prime_vmap, .vmap = mtk_drm_gem_prime_vmap,
.vunmap = mtk_drm_gem_prime_vunmap, .vunmap = mtk_drm_gem_prime_vunmap,
.mmap = mtk_drm_gem_object_mmap,
.vm_ops = &drm_gem_cma_vm_ops, .vm_ops = &drm_gem_cma_vm_ops,
}; };
...@@ -145,11 +148,19 @@ static int mtk_drm_gem_object_mmap(struct drm_gem_object *obj, ...@@ -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_gem_obj *mtk_gem = to_mtk_gem_obj(obj);
struct mtk_drm_private *priv = obj->dev->dev_private; 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 * 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(). * 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, ret = dma_mmap_attrs(priv->dma_dev, vma, mtk_gem->cookie,
mtk_gem->dma_addr, obj->size, mtk_gem->dma_attrs); 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, ...@@ -159,37 +170,6 @@ static int mtk_drm_gem_object_mmap(struct drm_gem_object *obj,
return ret; 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. * Allocate a sg_table for this GEM object.
* Note: Both the table's contents, and the sg_table itself must be freed by * 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, ...@@ -39,9 +39,6 @@ struct mtk_drm_gem_obj *mtk_drm_gem_create(struct drm_device *dev, size_t size,
bool alloc_kmap); bool alloc_kmap);
int mtk_drm_gem_dumb_create(struct drm_file *file_priv, struct drm_device *dev, int mtk_drm_gem_dumb_create(struct drm_file *file_priv, struct drm_device *dev,
struct drm_mode_create_dumb *args); 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 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 drm_gem_object *mtk_gem_prime_import_sg_table(struct drm_device *dev,
struct dma_buf_attachment *attach, struct sg_table *sg); struct dma_buf_attachment *attach, struct sg_table *sg);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment