Skip to content

Commit 393fdfd

Browse files
committed
Merge tag 'mediatek-drm-next-5.5-2' of https://github.com/ckhu-mediatek/linux.git-tags into drm-next
Mediatek DRM next for Linux 5.5 - 2 Signed-off-by: Dave Airlie <[email protected]> From: CK Hu <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/1573093419.13645.5.camel@mtksdaap41
2 parents cea35f5 + df44445 commit 393fdfd

File tree

6 files changed

+205
-42
lines changed

6 files changed

+205
-42
lines changed

drivers/gpu/drm/mediatek/mtk_disp_ovl.c

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
* Copyright (c) 2015 MediaTek Inc.
44
*/
55

6+
#include <drm/drm_fourcc.h>
7+
68
#include <linux/clk.h>
79
#include <linux/component.h>
810
#include <linux/module.h>
@@ -50,6 +52,8 @@
5052
OVL_CON_CLRFMT_RGB : 0)
5153
#define OVL_CON_AEN BIT(8)
5254
#define OVL_CON_ALPHA 0xff
55+
#define OVL_CON_VIRT_FLIP BIT(9)
56+
#define OVL_CON_HORZ_FLIP BIT(10)
5357

5458
struct mtk_disp_ovl_data {
5559
unsigned int addr;
@@ -137,6 +141,40 @@ static unsigned int mtk_ovl_layer_nr(struct mtk_ddp_comp *comp)
137141
return ovl->data->layer_nr;
138142
}
139143

144+
static unsigned int mtk_ovl_supported_rotations(struct mtk_ddp_comp *comp)
145+
{
146+
return DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180 |
147+
DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y;
148+
}
149+
150+
static int mtk_ovl_layer_check(struct mtk_ddp_comp *comp, unsigned int idx,
151+
struct mtk_plane_state *mtk_state)
152+
{
153+
struct drm_plane_state *state = &mtk_state->base;
154+
unsigned int rotation = 0;
155+
156+
rotation = drm_rotation_simplify(state->rotation,
157+
DRM_MODE_ROTATE_0 |
158+
DRM_MODE_REFLECT_X |
159+
DRM_MODE_REFLECT_Y);
160+
rotation &= ~DRM_MODE_ROTATE_0;
161+
162+
/* We can only do reflection, not rotation */
163+
if ((rotation & DRM_MODE_ROTATE_MASK) != 0)
164+
return -EINVAL;
165+
166+
/*
167+
* TODO: Rotating/reflecting YUV buffers is not supported at this time.
168+
* Only RGB[AX] variants are supported.
169+
*/
170+
if (state->fb->format->is_yuv && rotation != 0)
171+
return -EINVAL;
172+
173+
state->rotation = rotation;
174+
175+
return 0;
176+
}
177+
140178
static void mtk_ovl_layer_on(struct mtk_ddp_comp *comp, unsigned int idx)
141179
{
142180
unsigned int reg;
@@ -229,6 +267,16 @@ static void mtk_ovl_layer_config(struct mtk_ddp_comp *comp, unsigned int idx,
229267
if (idx != 0)
230268
con |= OVL_CON_AEN | OVL_CON_ALPHA;
231269

270+
if (pending->rotation & DRM_MODE_REFLECT_Y) {
271+
con |= OVL_CON_VIRT_FLIP;
272+
addr += (pending->height - 1) * pending->pitch;
273+
}
274+
275+
if (pending->rotation & DRM_MODE_REFLECT_X) {
276+
con |= OVL_CON_HORZ_FLIP;
277+
addr += pending->pitch - 1;
278+
}
279+
232280
writel_relaxed(con, comp->regs + DISP_REG_OVL_CON(idx));
233281
writel_relaxed(pitch, comp->regs + DISP_REG_OVL_PITCH(idx));
234282
writel_relaxed(src_size, comp->regs + DISP_REG_OVL_SRC_SIZE(idx));
@@ -263,9 +311,11 @@ static const struct mtk_ddp_comp_funcs mtk_disp_ovl_funcs = {
263311
.stop = mtk_ovl_stop,
264312
.enable_vblank = mtk_ovl_enable_vblank,
265313
.disable_vblank = mtk_ovl_disable_vblank,
314+
.supported_rotations = mtk_ovl_supported_rotations,
266315
.layer_nr = mtk_ovl_layer_nr,
267316
.layer_on = mtk_ovl_layer_on,
268317
.layer_off = mtk_ovl_layer_off,
318+
.layer_check = mtk_ovl_layer_check,
269319
.layer_config = mtk_ovl_layer_config,
270320
.bgclr_in_on = mtk_ovl_bgclr_in_on,
271321
.bgclr_in_off = mtk_ovl_bgclr_in_off,

drivers/gpu/drm/mediatek/mtk_drm_crtc.c

Lines changed: 105 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,28 @@ static void mtk_crtc_ddp_clk_disable(struct mtk_drm_crtc *mtk_crtc)
207207
clk_disable_unprepare(mtk_crtc->ddp_comp[i]->clk);
208208
}
209209

210+
static
211+
struct mtk_ddp_comp *mtk_drm_ddp_comp_for_plane(struct drm_crtc *crtc,
212+
struct drm_plane *plane,
213+
unsigned int *local_layer)
214+
{
215+
struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
216+
struct mtk_ddp_comp *comp;
217+
int i, count = 0;
218+
219+
for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {
220+
comp = mtk_crtc->ddp_comp[i];
221+
if (plane->index < (count + mtk_ddp_comp_layer_nr(comp))) {
222+
*local_layer = plane->index - count;
223+
return comp;
224+
}
225+
count += mtk_ddp_comp_layer_nr(comp);
226+
}
227+
228+
WARN(1, "Failed to find component for plane %d\n", plane->index);
229+
return NULL;
230+
}
231+
210232
static int mtk_crtc_ddp_hw_init(struct mtk_drm_crtc *mtk_crtc)
211233
{
212234
struct drm_crtc *crtc = &mtk_crtc->base;
@@ -283,19 +305,12 @@ static int mtk_crtc_ddp_hw_init(struct mtk_drm_crtc *mtk_crtc)
283305
for (i = 0; i < mtk_crtc->layer_nr; i++) {
284306
struct drm_plane *plane = &mtk_crtc->planes[i];
285307
struct mtk_plane_state *plane_state;
286-
struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[0];
287-
unsigned int comp_layer_nr = mtk_ddp_comp_layer_nr(comp);
308+
struct mtk_ddp_comp *comp;
288309
unsigned int local_layer;
289310

290311
plane_state = to_mtk_plane_state(plane->state);
291-
292-
if (i >= comp_layer_nr) {
293-
comp = mtk_crtc->ddp_comp[1];
294-
local_layer = i - comp_layer_nr;
295-
} else
296-
local_layer = i;
297-
mtk_ddp_comp_layer_config(comp, local_layer,
298-
plane_state);
312+
comp = mtk_drm_ddp_comp_for_plane(crtc, plane, &local_layer);
313+
mtk_ddp_comp_layer_config(comp, local_layer, plane_state);
299314
}
300315

301316
return 0;
@@ -343,7 +358,6 @@ static void mtk_crtc_ddp_config(struct drm_crtc *crtc)
343358
struct mtk_crtc_state *state = to_mtk_crtc_state(mtk_crtc->base.state);
344359
struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[0];
345360
unsigned int i;
346-
unsigned int comp_layer_nr = mtk_ddp_comp_layer_nr(comp);
347361
unsigned int local_layer;
348362

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

367381
plane_state = to_mtk_plane_state(plane->state);
368382

369-
if (plane_state->pending.config) {
370-
if (i >= comp_layer_nr) {
371-
comp = mtk_crtc->ddp_comp[1];
372-
local_layer = i - comp_layer_nr;
373-
} else
374-
local_layer = i;
375-
376-
mtk_ddp_comp_layer_config(comp, local_layer,
377-
plane_state);
378-
plane_state->pending.config = false;
379-
}
383+
if (!plane_state->pending.config)
384+
continue;
385+
386+
comp = mtk_drm_ddp_comp_for_plane(crtc, plane,
387+
&local_layer);
388+
389+
mtk_ddp_comp_layer_config(comp, local_layer,
390+
plane_state);
391+
plane_state->pending.config = false;
380392
}
381393
mtk_crtc->pending_planes = false;
382394
}
383395
}
384396

397+
int mtk_drm_crtc_plane_check(struct drm_crtc *crtc, struct drm_plane *plane,
398+
struct mtk_plane_state *state)
399+
{
400+
unsigned int local_layer;
401+
struct mtk_ddp_comp *comp;
402+
403+
comp = mtk_drm_ddp_comp_for_plane(crtc, plane, &local_layer);
404+
return mtk_ddp_comp_layer_check(comp, local_layer, state);
405+
}
406+
385407
static void mtk_drm_crtc_atomic_enable(struct drm_crtc *crtc,
386408
struct drm_crtc_state *old_state)
387409
{
@@ -543,14 +565,65 @@ void mtk_crtc_ddp_irq(struct drm_crtc *crtc, struct mtk_ddp_comp *comp)
543565
mtk_drm_finish_page_flip(mtk_crtc);
544566
}
545567

568+
static int mtk_drm_crtc_num_comp_planes(struct mtk_drm_crtc *mtk_crtc,
569+
int comp_idx)
570+
{
571+
struct mtk_ddp_comp *comp;
572+
573+
if (comp_idx > 1)
574+
return 0;
575+
576+
comp = mtk_crtc->ddp_comp[comp_idx];
577+
if (!comp->funcs)
578+
return 0;
579+
580+
if (comp_idx == 1 && !comp->funcs->bgclr_in_on)
581+
return 0;
582+
583+
return mtk_ddp_comp_layer_nr(comp);
584+
}
585+
586+
static inline
587+
enum drm_plane_type mtk_drm_crtc_plane_type(unsigned int plane_idx)
588+
{
589+
if (plane_idx == 0)
590+
return DRM_PLANE_TYPE_PRIMARY;
591+
else if (plane_idx == 1)
592+
return DRM_PLANE_TYPE_CURSOR;
593+
else
594+
return DRM_PLANE_TYPE_OVERLAY;
595+
596+
}
597+
598+
static int mtk_drm_crtc_init_comp_planes(struct drm_device *drm_dev,
599+
struct mtk_drm_crtc *mtk_crtc,
600+
int comp_idx, int pipe)
601+
{
602+
int num_planes = mtk_drm_crtc_num_comp_planes(mtk_crtc, comp_idx);
603+
struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[comp_idx];
604+
int i, ret;
605+
606+
for (i = 0; i < num_planes; i++) {
607+
ret = mtk_plane_init(drm_dev,
608+
&mtk_crtc->planes[mtk_crtc->layer_nr],
609+
BIT(pipe),
610+
mtk_drm_crtc_plane_type(mtk_crtc->layer_nr),
611+
mtk_ddp_comp_supported_rotations(comp));
612+
if (ret)
613+
return ret;
614+
615+
mtk_crtc->layer_nr++;
616+
}
617+
return 0;
618+
}
619+
546620
int mtk_drm_crtc_create(struct drm_device *drm_dev,
547621
const enum mtk_ddp_comp_id *path, unsigned int path_len)
548622
{
549623
struct mtk_drm_private *priv = drm_dev->dev_private;
550624
struct device *dev = drm_dev->dev;
551625
struct mtk_drm_crtc *mtk_crtc;
552-
enum drm_plane_type type;
553-
unsigned int zpos;
626+
unsigned int num_comp_planes = 0;
554627
int pipe = priv->num_pipes;
555628
int ret;
556629
int i;
@@ -606,23 +679,15 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
606679
mtk_crtc->ddp_comp[i] = comp;
607680
}
608681

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

613-
if (comp->funcs->bgclr_in_on)
614-
mtk_crtc->layer_nr += mtk_ddp_comp_layer_nr(comp);
615-
}
616-
mtk_crtc->planes = devm_kcalloc(dev, mtk_crtc->layer_nr,
617-
sizeof(struct drm_plane),
618-
GFP_KERNEL);
619-
620-
for (zpos = 0; zpos < mtk_crtc->layer_nr; zpos++) {
621-
type = (zpos == 0) ? DRM_PLANE_TYPE_PRIMARY :
622-
(zpos == 1) ? DRM_PLANE_TYPE_CURSOR :
623-
DRM_PLANE_TYPE_OVERLAY;
624-
ret = mtk_plane_init(drm_dev, &mtk_crtc->planes[zpos],
625-
BIT(pipe), type);
685+
mtk_crtc->planes = devm_kcalloc(dev, num_comp_planes,
686+
sizeof(struct drm_plane), GFP_KERNEL);
687+
688+
for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {
689+
ret = mtk_drm_crtc_init_comp_planes(drm_dev, mtk_crtc, i,
690+
pipe);
626691
if (ret)
627692
return ret;
628693
}

drivers/gpu/drm/mediatek/mtk_drm_crtc.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,7 @@ void mtk_crtc_ddp_irq(struct drm_crtc *crtc, struct mtk_ddp_comp *comp);
1919
int mtk_drm_crtc_create(struct drm_device *drm_dev,
2020
const enum mtk_ddp_comp_id *path,
2121
unsigned int path_len);
22+
int mtk_drm_crtc_plane_check(struct drm_crtc *crtc, struct drm_plane *plane,
23+
struct mtk_plane_state *state);
2224

2325
#endif /* MTK_DRM_CRTC_H */

drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,13 @@ struct mtk_ddp_comp_funcs {
7777
void (*stop)(struct mtk_ddp_comp *comp);
7878
void (*enable_vblank)(struct mtk_ddp_comp *comp, struct drm_crtc *crtc);
7979
void (*disable_vblank)(struct mtk_ddp_comp *comp);
80+
unsigned int (*supported_rotations)(struct mtk_ddp_comp *comp);
8081
unsigned int (*layer_nr)(struct mtk_ddp_comp *comp);
8182
void (*layer_on)(struct mtk_ddp_comp *comp, unsigned int idx);
8283
void (*layer_off)(struct mtk_ddp_comp *comp, unsigned int idx);
84+
int (*layer_check)(struct mtk_ddp_comp *comp,
85+
unsigned int idx,
86+
struct mtk_plane_state *state);
8387
void (*layer_config)(struct mtk_ddp_comp *comp, unsigned int idx,
8488
struct mtk_plane_state *state);
8589
void (*gamma_set)(struct mtk_ddp_comp *comp,
@@ -130,6 +134,15 @@ static inline void mtk_ddp_comp_disable_vblank(struct mtk_ddp_comp *comp)
130134
comp->funcs->disable_vblank(comp);
131135
}
132136

137+
static inline
138+
unsigned int mtk_ddp_comp_supported_rotations(struct mtk_ddp_comp *comp)
139+
{
140+
if (comp->funcs && comp->funcs->supported_rotations)
141+
return comp->funcs->supported_rotations(comp);
142+
143+
return 0;
144+
}
145+
133146
static inline unsigned int mtk_ddp_comp_layer_nr(struct mtk_ddp_comp *comp)
134147
{
135148
if (comp->funcs && comp->funcs->layer_nr)
@@ -152,6 +165,15 @@ static inline void mtk_ddp_comp_layer_off(struct mtk_ddp_comp *comp,
152165
comp->funcs->layer_off(comp, idx);
153166
}
154167

168+
static inline int mtk_ddp_comp_layer_check(struct mtk_ddp_comp *comp,
169+
unsigned int idx,
170+
struct mtk_plane_state *state)
171+
{
172+
if (comp->funcs && comp->funcs->layer_check)
173+
return comp->funcs->layer_check(comp, idx, state);
174+
return 0;
175+
}
176+
155177
static inline void mtk_ddp_comp_layer_config(struct mtk_ddp_comp *comp,
156178
unsigned int idx,
157179
struct mtk_plane_state *state)

0 commit comments

Comments
 (0)