Skip to content

Commit

Permalink
drm/mediatek: support CMDQ interface in ddp component
Browse files Browse the repository at this point in the history
The CMDQ (Command Queue) in some Mediatek SoC is used
to help update all relevant display controller registers
with critical time limation.
This patch add cmdq interface in ddp_comp interface,
let all ddp_comp interface can support cpu/cmdq function
at the same time.

Signed-off-by: YT Shen <yt.shen@mediatek.com>
Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
Signed-off-by: Bibby Hsieh <bibby.hsieh@mediatek.com>
Signed-off-by: Yongqiang Niu <yongqiang.niu@mediatek.com>
Signed-off-by: CK Hu <ck.hu@mediatek.com>
  • Loading branch information
Bibby Hsieh authored and CK Hu committed Jan 9, 2020
1 parent 17aab65 commit d0afe37
Show file tree
Hide file tree
Showing 6 changed files with 186 additions and 94 deletions.
7 changes: 4 additions & 3 deletions drivers/gpu/drm/mediatek/mtk_disp_color.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <linux/of_device.h>
#include <linux/of_irq.h>
#include <linux/platform_device.h>
#include <linux/soc/mediatek/mtk-cmdq.h>

#include "mtk_drm_crtc.h"
#include "mtk_drm_ddp_comp.h"
Expand Down Expand Up @@ -45,12 +46,12 @@ static inline struct mtk_disp_color *comp_to_color(struct mtk_ddp_comp *comp)

static void mtk_color_config(struct mtk_ddp_comp *comp, unsigned int w,
unsigned int h, unsigned int vrefresh,
unsigned int bpc)
unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
{
struct mtk_disp_color *color = comp_to_color(comp);

writel(w, comp->regs + DISP_COLOR_WIDTH(color));
writel(h, comp->regs + DISP_COLOR_HEIGHT(color));
mtk_ddp_write(cmdq_pkt, w, comp, DISP_COLOR_WIDTH(color));
mtk_ddp_write(cmdq_pkt, h, comp, DISP_COLOR_HEIGHT(color));
}

static void mtk_color_start(struct mtk_ddp_comp *comp)
Expand Down
65 changes: 35 additions & 30 deletions drivers/gpu/drm/mediatek/mtk_disp_ovl.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <linux/of_device.h>
#include <linux/of_irq.h>
#include <linux/platform_device.h>
#include <linux/soc/mediatek/mtk-cmdq.h>

#include "mtk_drm_crtc.h"
#include "mtk_drm_ddp_comp.h"
Expand Down Expand Up @@ -124,14 +125,15 @@ static void mtk_ovl_stop(struct mtk_ddp_comp *comp)

static void mtk_ovl_config(struct mtk_ddp_comp *comp, unsigned int w,
unsigned int h, unsigned int vrefresh,
unsigned int bpc)
unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
{
if (w != 0 && h != 0)
writel_relaxed(h << 16 | w, comp->regs + DISP_REG_OVL_ROI_SIZE);
writel_relaxed(0x0, comp->regs + DISP_REG_OVL_ROI_BGCLR);
mtk_ddp_write_relaxed(cmdq_pkt, h << 16 | w, comp,
DISP_REG_OVL_ROI_SIZE);
mtk_ddp_write_relaxed(cmdq_pkt, 0x0, comp, DISP_REG_OVL_ROI_BGCLR);

writel(0x1, comp->regs + DISP_REG_OVL_RST);
writel(0x0, comp->regs + DISP_REG_OVL_RST);
mtk_ddp_write(cmdq_pkt, 0x1, comp, DISP_REG_OVL_RST);
mtk_ddp_write(cmdq_pkt, 0x0, comp, DISP_REG_OVL_RST);
}

static unsigned int mtk_ovl_layer_nr(struct mtk_ddp_comp *comp)
Expand Down Expand Up @@ -175,16 +177,16 @@ static int mtk_ovl_layer_check(struct mtk_ddp_comp *comp, unsigned int idx,
return 0;
}

static void mtk_ovl_layer_on(struct mtk_ddp_comp *comp, unsigned int idx)
static void mtk_ovl_layer_on(struct mtk_ddp_comp *comp, unsigned int idx,
struct cmdq_pkt *cmdq_pkt)
{
unsigned int reg;
unsigned int gmc_thrshd_l;
unsigned int gmc_thrshd_h;
unsigned int gmc_value;
struct mtk_disp_ovl *ovl = comp_to_ovl(comp);

writel(0x1, comp->regs + DISP_REG_OVL_RDMA_CTRL(idx));

mtk_ddp_write(cmdq_pkt, 0x1, comp,
DISP_REG_OVL_RDMA_CTRL(idx));
gmc_thrshd_l = GMC_THRESHOLD_LOW >>
(GMC_THRESHOLD_BITS - ovl->data->gmc_bits);
gmc_thrshd_h = GMC_THRESHOLD_HIGH >>
Expand All @@ -194,22 +196,19 @@ static void mtk_ovl_layer_on(struct mtk_ddp_comp *comp, unsigned int idx)
else
gmc_value = gmc_thrshd_l | gmc_thrshd_l << 8 |
gmc_thrshd_h << 16 | gmc_thrshd_h << 24;
writel(gmc_value, comp->regs + DISP_REG_OVL_RDMA_GMC(idx));

reg = readl(comp->regs + DISP_REG_OVL_SRC_CON);
reg = reg | BIT(idx);
writel(reg, comp->regs + DISP_REG_OVL_SRC_CON);
mtk_ddp_write(cmdq_pkt, gmc_value,
comp, DISP_REG_OVL_RDMA_GMC(idx));
mtk_ddp_write_mask(cmdq_pkt, BIT(idx), comp,
DISP_REG_OVL_SRC_CON, BIT(idx));
}

static void mtk_ovl_layer_off(struct mtk_ddp_comp *comp, unsigned int idx)
static void mtk_ovl_layer_off(struct mtk_ddp_comp *comp, unsigned int idx,
struct cmdq_pkt *cmdq_pkt)
{
unsigned int reg;

reg = readl(comp->regs + DISP_REG_OVL_SRC_CON);
reg = reg & ~BIT(idx);
writel(reg, comp->regs + DISP_REG_OVL_SRC_CON);

writel(0x0, comp->regs + DISP_REG_OVL_RDMA_CTRL(idx));
mtk_ddp_write_mask(cmdq_pkt, 0, comp,
DISP_REG_OVL_SRC_CON, BIT(idx));
mtk_ddp_write(cmdq_pkt, 0, comp,
DISP_REG_OVL_RDMA_CTRL(idx));
}

static unsigned int ovl_fmt_convert(struct mtk_disp_ovl *ovl, unsigned int fmt)
Expand Down Expand Up @@ -249,7 +248,8 @@ static unsigned int ovl_fmt_convert(struct mtk_disp_ovl *ovl, unsigned int fmt)
}

static void mtk_ovl_layer_config(struct mtk_ddp_comp *comp, unsigned int idx,
struct mtk_plane_state *state)
struct mtk_plane_state *state,
struct cmdq_pkt *cmdq_pkt)
{
struct mtk_disp_ovl *ovl = comp_to_ovl(comp);
struct mtk_plane_pending_state *pending = &state->pending;
Expand All @@ -261,7 +261,7 @@ static void mtk_ovl_layer_config(struct mtk_ddp_comp *comp, unsigned int idx,
unsigned int con;

if (!pending->enable)
mtk_ovl_layer_off(comp, idx);
mtk_ovl_layer_off(comp, idx, cmdq_pkt);

con = ovl_fmt_convert(ovl, fmt);
if (idx != 0)
Expand All @@ -277,14 +277,19 @@ static void mtk_ovl_layer_config(struct mtk_ddp_comp *comp, unsigned int idx,
addr += pending->pitch - 1;
}

writel_relaxed(con, comp->regs + DISP_REG_OVL_CON(idx));
writel_relaxed(pitch, comp->regs + DISP_REG_OVL_PITCH(idx));
writel_relaxed(src_size, comp->regs + DISP_REG_OVL_SRC_SIZE(idx));
writel_relaxed(offset, comp->regs + DISP_REG_OVL_OFFSET(idx));
writel_relaxed(addr, comp->regs + DISP_REG_OVL_ADDR(ovl, idx));
mtk_ddp_write_relaxed(cmdq_pkt, con, comp,
DISP_REG_OVL_CON(idx));
mtk_ddp_write_relaxed(cmdq_pkt, pitch, comp,
DISP_REG_OVL_PITCH(idx));
mtk_ddp_write_relaxed(cmdq_pkt, src_size, comp,
DISP_REG_OVL_SRC_SIZE(idx));
mtk_ddp_write_relaxed(cmdq_pkt, offset, comp,
DISP_REG_OVL_OFFSET(idx));
mtk_ddp_write_relaxed(cmdq_pkt, addr, comp,
DISP_REG_OVL_ADDR(ovl, idx));

if (pending->enable)
mtk_ovl_layer_on(comp, idx);
mtk_ovl_layer_on(comp, idx, cmdq_pkt);
}

static void mtk_ovl_bgclr_in_on(struct mtk_ddp_comp *comp)
Expand Down
43 changes: 25 additions & 18 deletions drivers/gpu/drm/mediatek/mtk_disp_rdma.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <linux/of_device.h>
#include <linux/of_irq.h>
#include <linux/platform_device.h>
#include <linux/soc/mediatek/mtk-cmdq.h>

#include "mtk_drm_crtc.h"
#include "mtk_drm_ddp_comp.h"
Expand Down Expand Up @@ -125,14 +126,16 @@ static void mtk_rdma_stop(struct mtk_ddp_comp *comp)

static void mtk_rdma_config(struct mtk_ddp_comp *comp, unsigned int width,
unsigned int height, unsigned int vrefresh,
unsigned int bpc)
unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
{
unsigned int threshold;
unsigned int reg;
struct mtk_disp_rdma *rdma = comp_to_rdma(comp);

rdma_update_bits(comp, DISP_REG_RDMA_SIZE_CON_0, 0xfff, width);
rdma_update_bits(comp, DISP_REG_RDMA_SIZE_CON_1, 0xfffff, height);
mtk_ddp_write_mask(cmdq_pkt, width, comp,
DISP_REG_RDMA_SIZE_CON_0, 0xfff);
mtk_ddp_write_mask(cmdq_pkt, height, comp,
DISP_REG_RDMA_SIZE_CON_1, 0xfffff);

/*
* Enable FIFO underflow since DSI and DPI can't be blocked.
Expand All @@ -144,7 +147,7 @@ static void mtk_rdma_config(struct mtk_ddp_comp *comp, unsigned int width,
reg = RDMA_FIFO_UNDERFLOW_EN |
RDMA_FIFO_PSEUDO_SIZE(RDMA_FIFO_SIZE(rdma)) |
RDMA_OUTPUT_VALID_FIFO_THRESHOLD(threshold);
writel(reg, comp->regs + DISP_REG_RDMA_FIFO_CON);
mtk_ddp_write(cmdq_pkt, reg, comp, DISP_REG_RDMA_FIFO_CON);
}

static unsigned int rdma_fmt_convert(struct mtk_disp_rdma *rdma,
Expand Down Expand Up @@ -190,7 +193,8 @@ static unsigned int mtk_rdma_layer_nr(struct mtk_ddp_comp *comp)
}

static void mtk_rdma_layer_config(struct mtk_ddp_comp *comp, unsigned int idx,
struct mtk_plane_state *state)
struct mtk_plane_state *state,
struct cmdq_pkt *cmdq_pkt)
{
struct mtk_disp_rdma *rdma = comp_to_rdma(comp);
struct mtk_plane_pending_state *pending = &state->pending;
Expand All @@ -200,24 +204,27 @@ static void mtk_rdma_layer_config(struct mtk_ddp_comp *comp, unsigned int idx,
unsigned int con;

con = rdma_fmt_convert(rdma, fmt);
writel_relaxed(con, comp->regs + DISP_RDMA_MEM_CON);
mtk_ddp_write_relaxed(cmdq_pkt, con, comp, DISP_RDMA_MEM_CON);

if (fmt == DRM_FORMAT_UYVY || fmt == DRM_FORMAT_YUYV) {
rdma_update_bits(comp, DISP_REG_RDMA_SIZE_CON_0,
RDMA_MATRIX_ENABLE, RDMA_MATRIX_ENABLE);
rdma_update_bits(comp, DISP_REG_RDMA_SIZE_CON_0,
RDMA_MATRIX_INT_MTX_SEL,
RDMA_MATRIX_INT_MTX_BT601_to_RGB);
mtk_ddp_write_mask(cmdq_pkt, RDMA_MATRIX_ENABLE, comp,
DISP_REG_RDMA_SIZE_CON_0,
RDMA_MATRIX_ENABLE);
mtk_ddp_write_mask(cmdq_pkt, RDMA_MATRIX_INT_MTX_BT601_to_RGB,
comp, DISP_REG_RDMA_SIZE_CON_0,
RDMA_MATRIX_INT_MTX_SEL);
} else {
rdma_update_bits(comp, DISP_REG_RDMA_SIZE_CON_0,
RDMA_MATRIX_ENABLE, 0);
mtk_ddp_write_mask(cmdq_pkt, 0, comp,
DISP_REG_RDMA_SIZE_CON_0,
RDMA_MATRIX_ENABLE);
}
mtk_ddp_write_relaxed(cmdq_pkt, addr, comp, DISP_RDMA_MEM_START_ADDR);
mtk_ddp_write_relaxed(cmdq_pkt, pitch, comp, DISP_RDMA_MEM_SRC_PITCH);
mtk_ddp_write(cmdq_pkt, RDMA_MEM_GMC, comp,
DISP_RDMA_MEM_GMC_SETTING_0);
mtk_ddp_write_mask(cmdq_pkt, RDMA_MODE_MEMORY, comp,
DISP_REG_RDMA_GLOBAL_CON, RDMA_MODE_MEMORY);

writel_relaxed(addr, comp->regs + DISP_RDMA_MEM_START_ADDR);
writel_relaxed(pitch, comp->regs + DISP_RDMA_MEM_SRC_PITCH);
writel(RDMA_MEM_GMC, comp->regs + DISP_RDMA_MEM_GMC_SETTING_0);
rdma_update_bits(comp, DISP_REG_RDMA_GLOBAL_CON,
RDMA_MODE_MEMORY, RDMA_MODE_MEMORY);
}

static const struct mtk_ddp_comp_funcs mtk_disp_rdma_funcs = {
Expand Down
10 changes: 5 additions & 5 deletions drivers/gpu/drm/mediatek/mtk_drm_crtc.c
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ static int mtk_crtc_ddp_hw_init(struct mtk_drm_crtc *mtk_crtc)
if (i == 1)
mtk_ddp_comp_bgclr_in_on(comp);

mtk_ddp_comp_config(comp, width, height, vrefresh, bpc);
mtk_ddp_comp_config(comp, width, height, vrefresh, bpc, NULL);
mtk_ddp_comp_start(comp);
}

Expand All @@ -317,7 +317,7 @@ static int mtk_crtc_ddp_hw_init(struct mtk_drm_crtc *mtk_crtc)
comp = mtk_drm_ddp_comp_for_plane(crtc, plane, &local_layer);
if (comp)
mtk_ddp_comp_layer_config(comp, local_layer,
plane_state);
plane_state, NULL);
}

return 0;
Expand Down Expand Up @@ -383,7 +383,7 @@ static void mtk_crtc_ddp_config(struct drm_crtc *crtc)
if (state->pending_config) {
mtk_ddp_comp_config(comp, state->pending_width,
state->pending_height,
state->pending_vrefresh, 0);
state->pending_vrefresh, 0, NULL);

state->pending_config = false;
}
Expand All @@ -403,7 +403,7 @@ static void mtk_crtc_ddp_config(struct drm_crtc *crtc)

if (comp)
mtk_ddp_comp_layer_config(comp, local_layer,
plane_state);
plane_state, NULL);
plane_state->pending.config = false;
}
mtk_crtc->pending_planes = false;
Expand All @@ -424,7 +424,7 @@ static void mtk_crtc_ddp_config(struct drm_crtc *crtc)

if (comp)
mtk_ddp_comp_layer_config(comp, local_layer,
plane_state);
plane_state, NULL);
plane_state->pending.async_config = false;
}
mtk_crtc->pending_async_planes = false;
Expand Down
Loading

0 comments on commit d0afe37

Please sign in to comment.