Skip to content

Commit

Permalink
Merge tag 'mediatek-drm-next-5.5-2' of https://github.com/ckhu-mediat…
Browse files Browse the repository at this point in the history
…ek/linux.git-tags into drm-next

Mediatek DRM next for Linux 5.5 - 2

Signed-off-by: Dave Airlie <airlied@redhat.com>

From: CK Hu <ck.hu@mediatek.com>
Link: https://patchwork.freedesktop.org/patch/msgid/1573093419.13645.5.camel@mtksdaap41
  • Loading branch information
Dave Airlie committed Nov 8, 2019
2 parents cea35f5 + df44445 commit 393fdfd
Show file tree
Hide file tree
Showing 6 changed files with 205 additions and 42 deletions.
50 changes: 50 additions & 0 deletions drivers/gpu/drm/mediatek/mtk_disp_ovl.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
* Copyright (c) 2015 MediaTek Inc.
*/

#include <drm/drm_fourcc.h>

#include <linux/clk.h>
#include <linux/component.h>
#include <linux/module.h>
Expand Down Expand Up @@ -50,6 +52,8 @@
OVL_CON_CLRFMT_RGB : 0)
#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)

struct mtk_disp_ovl_data {
unsigned int addr;
Expand Down Expand Up @@ -137,6 +141,40 @@ static unsigned int mtk_ovl_layer_nr(struct mtk_ddp_comp *comp)
return ovl->data->layer_nr;
}

static unsigned int mtk_ovl_supported_rotations(struct mtk_ddp_comp *comp)
{
return DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180 |
DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y;
}

static int mtk_ovl_layer_check(struct mtk_ddp_comp *comp, unsigned int idx,
struct mtk_plane_state *mtk_state)
{
struct drm_plane_state *state = &mtk_state->base;
unsigned int rotation = 0;

rotation = drm_rotation_simplify(state->rotation,
DRM_MODE_ROTATE_0 |
DRM_MODE_REFLECT_X |
DRM_MODE_REFLECT_Y);
rotation &= ~DRM_MODE_ROTATE_0;

/* We can only do reflection, not rotation */
if ((rotation & DRM_MODE_ROTATE_MASK) != 0)
return -EINVAL;

/*
* TODO: Rotating/reflecting YUV buffers is not supported at this time.
* Only RGB[AX] variants are supported.
*/
if (state->fb->format->is_yuv && rotation != 0)
return -EINVAL;

state->rotation = rotation;

return 0;
}

static void mtk_ovl_layer_on(struct mtk_ddp_comp *comp, unsigned int idx)
{
unsigned int reg;
Expand Down Expand Up @@ -229,6 +267,16 @@ static void mtk_ovl_layer_config(struct mtk_ddp_comp *comp, unsigned int idx,
if (idx != 0)
con |= OVL_CON_AEN | OVL_CON_ALPHA;

if (pending->rotation & DRM_MODE_REFLECT_Y) {
con |= OVL_CON_VIRT_FLIP;
addr += (pending->height - 1) * pending->pitch;
}

if (pending->rotation & DRM_MODE_REFLECT_X) {
con |= OVL_CON_HORZ_FLIP;
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));
Expand Down Expand Up @@ -263,9 +311,11 @@ static const struct mtk_ddp_comp_funcs mtk_disp_ovl_funcs = {
.stop = mtk_ovl_stop,
.enable_vblank = mtk_ovl_enable_vblank,
.disable_vblank = mtk_ovl_disable_vblank,
.supported_rotations = mtk_ovl_supported_rotations,
.layer_nr = mtk_ovl_layer_nr,
.layer_on = mtk_ovl_layer_on,
.layer_off = mtk_ovl_layer_off,
.layer_check = mtk_ovl_layer_check,
.layer_config = mtk_ovl_layer_config,
.bgclr_in_on = mtk_ovl_bgclr_in_on,
.bgclr_in_off = mtk_ovl_bgclr_in_off,
Expand Down
145 changes: 105 additions & 40 deletions drivers/gpu/drm/mediatek/mtk_drm_crtc.c
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,28 @@ static void mtk_crtc_ddp_clk_disable(struct mtk_drm_crtc *mtk_crtc)
clk_disable_unprepare(mtk_crtc->ddp_comp[i]->clk);
}

static
struct mtk_ddp_comp *mtk_drm_ddp_comp_for_plane(struct drm_crtc *crtc,
struct drm_plane *plane,
unsigned int *local_layer)
{
struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
struct mtk_ddp_comp *comp;
int i, count = 0;

for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {
comp = mtk_crtc->ddp_comp[i];
if (plane->index < (count + mtk_ddp_comp_layer_nr(comp))) {
*local_layer = plane->index - count;
return comp;
}
count += mtk_ddp_comp_layer_nr(comp);
}

WARN(1, "Failed to find component for plane %d\n", plane->index);
return NULL;
}

static int mtk_crtc_ddp_hw_init(struct mtk_drm_crtc *mtk_crtc)
{
struct drm_crtc *crtc = &mtk_crtc->base;
Expand Down Expand Up @@ -283,19 +305,12 @@ static int mtk_crtc_ddp_hw_init(struct mtk_drm_crtc *mtk_crtc)
for (i = 0; i < mtk_crtc->layer_nr; i++) {
struct drm_plane *plane = &mtk_crtc->planes[i];
struct mtk_plane_state *plane_state;
struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[0];
unsigned int comp_layer_nr = mtk_ddp_comp_layer_nr(comp);
struct mtk_ddp_comp *comp;
unsigned int local_layer;

plane_state = to_mtk_plane_state(plane->state);

if (i >= comp_layer_nr) {
comp = mtk_crtc->ddp_comp[1];
local_layer = i - comp_layer_nr;
} else
local_layer = i;
mtk_ddp_comp_layer_config(comp, local_layer,
plane_state);
comp = mtk_drm_ddp_comp_for_plane(crtc, plane, &local_layer);
mtk_ddp_comp_layer_config(comp, local_layer, plane_state);
}

return 0;
Expand Down Expand Up @@ -343,7 +358,6 @@ static void mtk_crtc_ddp_config(struct drm_crtc *crtc)
struct mtk_crtc_state *state = to_mtk_crtc_state(mtk_crtc->base.state);
struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[0];
unsigned int i;
unsigned int comp_layer_nr = mtk_ddp_comp_layer_nr(comp);
unsigned int local_layer;

/*
Expand All @@ -366,22 +380,30 @@ static void mtk_crtc_ddp_config(struct drm_crtc *crtc)

plane_state = to_mtk_plane_state(plane->state);

if (plane_state->pending.config) {
if (i >= comp_layer_nr) {
comp = mtk_crtc->ddp_comp[1];
local_layer = i - comp_layer_nr;
} else
local_layer = i;

mtk_ddp_comp_layer_config(comp, local_layer,
plane_state);
plane_state->pending.config = false;
}
if (!plane_state->pending.config)
continue;

comp = mtk_drm_ddp_comp_for_plane(crtc, plane,
&local_layer);

mtk_ddp_comp_layer_config(comp, local_layer,
plane_state);
plane_state->pending.config = false;
}
mtk_crtc->pending_planes = false;
}
}

int mtk_drm_crtc_plane_check(struct drm_crtc *crtc, struct drm_plane *plane,
struct mtk_plane_state *state)
{
unsigned int local_layer;
struct mtk_ddp_comp *comp;

comp = mtk_drm_ddp_comp_for_plane(crtc, plane, &local_layer);
return mtk_ddp_comp_layer_check(comp, local_layer, state);
}

static void mtk_drm_crtc_atomic_enable(struct drm_crtc *crtc,
struct drm_crtc_state *old_state)
{
Expand Down Expand Up @@ -543,14 +565,65 @@ void mtk_crtc_ddp_irq(struct drm_crtc *crtc, struct mtk_ddp_comp *comp)
mtk_drm_finish_page_flip(mtk_crtc);
}

static int mtk_drm_crtc_num_comp_planes(struct mtk_drm_crtc *mtk_crtc,
int comp_idx)
{
struct mtk_ddp_comp *comp;

if (comp_idx > 1)
return 0;

comp = mtk_crtc->ddp_comp[comp_idx];
if (!comp->funcs)
return 0;

if (comp_idx == 1 && !comp->funcs->bgclr_in_on)
return 0;

return mtk_ddp_comp_layer_nr(comp);
}

static inline
enum drm_plane_type mtk_drm_crtc_plane_type(unsigned int plane_idx)
{
if (plane_idx == 0)
return DRM_PLANE_TYPE_PRIMARY;
else if (plane_idx == 1)
return DRM_PLANE_TYPE_CURSOR;
else
return DRM_PLANE_TYPE_OVERLAY;

}

static int mtk_drm_crtc_init_comp_planes(struct drm_device *drm_dev,
struct mtk_drm_crtc *mtk_crtc,
int comp_idx, int pipe)
{
int num_planes = mtk_drm_crtc_num_comp_planes(mtk_crtc, comp_idx);
struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[comp_idx];
int i, ret;

for (i = 0; i < num_planes; i++) {
ret = mtk_plane_init(drm_dev,
&mtk_crtc->planes[mtk_crtc->layer_nr],
BIT(pipe),
mtk_drm_crtc_plane_type(mtk_crtc->layer_nr),
mtk_ddp_comp_supported_rotations(comp));
if (ret)
return ret;

mtk_crtc->layer_nr++;
}
return 0;
}

int mtk_drm_crtc_create(struct drm_device *drm_dev,
const enum mtk_ddp_comp_id *path, unsigned int path_len)
{
struct mtk_drm_private *priv = drm_dev->dev_private;
struct device *dev = drm_dev->dev;
struct mtk_drm_crtc *mtk_crtc;
enum drm_plane_type type;
unsigned int zpos;
unsigned int num_comp_planes = 0;
int pipe = priv->num_pipes;
int ret;
int i;
Expand Down Expand Up @@ -606,23 +679,15 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
mtk_crtc->ddp_comp[i] = comp;
}

mtk_crtc->layer_nr = mtk_ddp_comp_layer_nr(mtk_crtc->ddp_comp[0]);
if (mtk_crtc->ddp_comp_nr > 1) {
struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[1];
for (i = 0; i < mtk_crtc->ddp_comp_nr; i++)
num_comp_planes += mtk_drm_crtc_num_comp_planes(mtk_crtc, i);

if (comp->funcs->bgclr_in_on)
mtk_crtc->layer_nr += mtk_ddp_comp_layer_nr(comp);
}
mtk_crtc->planes = devm_kcalloc(dev, mtk_crtc->layer_nr,
sizeof(struct drm_plane),
GFP_KERNEL);

for (zpos = 0; zpos < mtk_crtc->layer_nr; zpos++) {
type = (zpos == 0) ? DRM_PLANE_TYPE_PRIMARY :
(zpos == 1) ? DRM_PLANE_TYPE_CURSOR :
DRM_PLANE_TYPE_OVERLAY;
ret = mtk_plane_init(drm_dev, &mtk_crtc->planes[zpos],
BIT(pipe), type);
mtk_crtc->planes = devm_kcalloc(dev, num_comp_planes,
sizeof(struct drm_plane), GFP_KERNEL);

for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {
ret = mtk_drm_crtc_init_comp_planes(drm_dev, mtk_crtc, i,
pipe);
if (ret)
return ret;
}
Expand Down
2 changes: 2 additions & 0 deletions drivers/gpu/drm/mediatek/mtk_drm_crtc.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,7 @@ void mtk_crtc_ddp_irq(struct drm_crtc *crtc, struct mtk_ddp_comp *comp);
int mtk_drm_crtc_create(struct drm_device *drm_dev,
const enum mtk_ddp_comp_id *path,
unsigned int path_len);
int mtk_drm_crtc_plane_check(struct drm_crtc *crtc, struct drm_plane *plane,
struct mtk_plane_state *state);

#endif /* MTK_DRM_CRTC_H */
22 changes: 22 additions & 0 deletions drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,13 @@ struct mtk_ddp_comp_funcs {
void (*stop)(struct mtk_ddp_comp *comp);
void (*enable_vblank)(struct mtk_ddp_comp *comp, struct drm_crtc *crtc);
void (*disable_vblank)(struct mtk_ddp_comp *comp);
unsigned int (*supported_rotations)(struct mtk_ddp_comp *comp);
unsigned int (*layer_nr)(struct mtk_ddp_comp *comp);
void (*layer_on)(struct mtk_ddp_comp *comp, unsigned int idx);
void (*layer_off)(struct mtk_ddp_comp *comp, unsigned int idx);
int (*layer_check)(struct mtk_ddp_comp *comp,
unsigned int idx,
struct mtk_plane_state *state);
void (*layer_config)(struct mtk_ddp_comp *comp, unsigned int idx,
struct mtk_plane_state *state);
void (*gamma_set)(struct mtk_ddp_comp *comp,
Expand Down Expand Up @@ -130,6 +134,15 @@ static inline void mtk_ddp_comp_disable_vblank(struct mtk_ddp_comp *comp)
comp->funcs->disable_vblank(comp);
}

static inline
unsigned int mtk_ddp_comp_supported_rotations(struct mtk_ddp_comp *comp)
{
if (comp->funcs && comp->funcs->supported_rotations)
return comp->funcs->supported_rotations(comp);

return 0;
}

static inline unsigned int mtk_ddp_comp_layer_nr(struct mtk_ddp_comp *comp)
{
if (comp->funcs && comp->funcs->layer_nr)
Expand All @@ -152,6 +165,15 @@ static inline void mtk_ddp_comp_layer_off(struct mtk_ddp_comp *comp,
comp->funcs->layer_off(comp, idx);
}

static inline int mtk_ddp_comp_layer_check(struct mtk_ddp_comp *comp,
unsigned int idx,
struct mtk_plane_state *state)
{
if (comp->funcs && comp->funcs->layer_check)
return comp->funcs->layer_check(comp, idx, state);
return 0;
}

static inline void mtk_ddp_comp_layer_config(struct mtk_ddp_comp *comp,
unsigned int idx,
struct mtk_plane_state *state)
Expand Down
Loading

0 comments on commit 393fdfd

Please sign in to comment.