Commit 393fdfdb authored by Dave Airlie's avatar Dave Airlie

Merge tag 'mediatek-drm-next-5.5-2' of...

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: default avatarDave Airlie <airlied@redhat.com>

From: CK Hu <ck.hu@mediatek.com>
Link: https://patchwork.freedesktop.org/patch/msgid/1573093419.13645.5.camel@mtksdaap41
parents cea35f5a df444457
...@@ -3,6 +3,8 @@ ...@@ -3,6 +3,8 @@
* Copyright (c) 2015 MediaTek Inc. * Copyright (c) 2015 MediaTek Inc.
*/ */
#include <drm/drm_fourcc.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/component.h> #include <linux/component.h>
#include <linux/module.h> #include <linux/module.h>
...@@ -50,6 +52,8 @@ ...@@ -50,6 +52,8 @@
OVL_CON_CLRFMT_RGB : 0) OVL_CON_CLRFMT_RGB : 0)
#define OVL_CON_AEN BIT(8) #define OVL_CON_AEN BIT(8)
#define OVL_CON_ALPHA 0xff #define OVL_CON_ALPHA 0xff
#define OVL_CON_VIRT_FLIP BIT(9)
#define OVL_CON_HORZ_FLIP BIT(10)
struct mtk_disp_ovl_data { struct mtk_disp_ovl_data {
unsigned int addr; unsigned int addr;
...@@ -137,6 +141,40 @@ static unsigned int mtk_ovl_layer_nr(struct mtk_ddp_comp *comp) ...@@ -137,6 +141,40 @@ static unsigned int mtk_ovl_layer_nr(struct mtk_ddp_comp *comp)
return ovl->data->layer_nr; 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) static void mtk_ovl_layer_on(struct mtk_ddp_comp *comp, unsigned int idx)
{ {
unsigned int reg; unsigned int reg;
...@@ -229,6 +267,16 @@ static void mtk_ovl_layer_config(struct mtk_ddp_comp *comp, unsigned int idx, ...@@ -229,6 +267,16 @@ static void mtk_ovl_layer_config(struct mtk_ddp_comp *comp, unsigned int idx,
if (idx != 0) if (idx != 0)
con |= OVL_CON_AEN | OVL_CON_ALPHA; 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(con, comp->regs + DISP_REG_OVL_CON(idx));
writel_relaxed(pitch, comp->regs + DISP_REG_OVL_PITCH(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(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 = { ...@@ -263,9 +311,11 @@ static const struct mtk_ddp_comp_funcs mtk_disp_ovl_funcs = {
.stop = mtk_ovl_stop, .stop = mtk_ovl_stop,
.enable_vblank = mtk_ovl_enable_vblank, .enable_vblank = mtk_ovl_enable_vblank,
.disable_vblank = mtk_ovl_disable_vblank, .disable_vblank = mtk_ovl_disable_vblank,
.supported_rotations = mtk_ovl_supported_rotations,
.layer_nr = mtk_ovl_layer_nr, .layer_nr = mtk_ovl_layer_nr,
.layer_on = mtk_ovl_layer_on, .layer_on = mtk_ovl_layer_on,
.layer_off = mtk_ovl_layer_off, .layer_off = mtk_ovl_layer_off,
.layer_check = mtk_ovl_layer_check,
.layer_config = mtk_ovl_layer_config, .layer_config = mtk_ovl_layer_config,
.bgclr_in_on = mtk_ovl_bgclr_in_on, .bgclr_in_on = mtk_ovl_bgclr_in_on,
.bgclr_in_off = mtk_ovl_bgclr_in_off, .bgclr_in_off = mtk_ovl_bgclr_in_off,
......
...@@ -207,6 +207,28 @@ static void mtk_crtc_ddp_clk_disable(struct mtk_drm_crtc *mtk_crtc) ...@@ -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); 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) static int mtk_crtc_ddp_hw_init(struct mtk_drm_crtc *mtk_crtc)
{ {
struct drm_crtc *crtc = &mtk_crtc->base; struct drm_crtc *crtc = &mtk_crtc->base;
...@@ -283,19 +305,12 @@ static int mtk_crtc_ddp_hw_init(struct mtk_drm_crtc *mtk_crtc) ...@@ -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++) { for (i = 0; i < mtk_crtc->layer_nr; i++) {
struct drm_plane *plane = &mtk_crtc->planes[i]; struct drm_plane *plane = &mtk_crtc->planes[i];
struct mtk_plane_state *plane_state; struct mtk_plane_state *plane_state;
struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[0]; struct mtk_ddp_comp *comp;
unsigned int comp_layer_nr = mtk_ddp_comp_layer_nr(comp);
unsigned int local_layer; unsigned int local_layer;
plane_state = to_mtk_plane_state(plane->state); plane_state = to_mtk_plane_state(plane->state);
comp = mtk_drm_ddp_comp_for_plane(crtc, plane, &local_layer);
if (i >= comp_layer_nr) { mtk_ddp_comp_layer_config(comp, local_layer, plane_state);
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);
} }
return 0; return 0;
...@@ -343,7 +358,6 @@ static void mtk_crtc_ddp_config(struct drm_crtc *crtc) ...@@ -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_crtc_state *state = to_mtk_crtc_state(mtk_crtc->base.state);
struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[0]; struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[0];
unsigned int i; unsigned int i;
unsigned int comp_layer_nr = mtk_ddp_comp_layer_nr(comp);
unsigned int local_layer; unsigned int local_layer;
/* /*
...@@ -366,22 +380,30 @@ static void mtk_crtc_ddp_config(struct drm_crtc *crtc) ...@@ -366,22 +380,30 @@ static void mtk_crtc_ddp_config(struct drm_crtc *crtc)
plane_state = to_mtk_plane_state(plane->state); plane_state = to_mtk_plane_state(plane->state);
if (plane_state->pending.config) { if (!plane_state->pending.config)
if (i >= comp_layer_nr) { continue;
comp = mtk_crtc->ddp_comp[1];
local_layer = i - comp_layer_nr; comp = mtk_drm_ddp_comp_for_plane(crtc, plane,
} else &local_layer);
local_layer = i;
mtk_ddp_comp_layer_config(comp, local_layer,
mtk_ddp_comp_layer_config(comp, local_layer, plane_state);
plane_state); plane_state->pending.config = false;
plane_state->pending.config = false;
}
} }
mtk_crtc->pending_planes = 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, static void mtk_drm_crtc_atomic_enable(struct drm_crtc *crtc,
struct drm_crtc_state *old_state) struct drm_crtc_state *old_state)
{ {
...@@ -543,14 +565,65 @@ void mtk_crtc_ddp_irq(struct drm_crtc *crtc, struct mtk_ddp_comp *comp) ...@@ -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); 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, int mtk_drm_crtc_create(struct drm_device *drm_dev,
const enum mtk_ddp_comp_id *path, unsigned int path_len) const enum mtk_ddp_comp_id *path, unsigned int path_len)
{ {
struct mtk_drm_private *priv = drm_dev->dev_private; struct mtk_drm_private *priv = drm_dev->dev_private;
struct device *dev = drm_dev->dev; struct device *dev = drm_dev->dev;
struct mtk_drm_crtc *mtk_crtc; struct mtk_drm_crtc *mtk_crtc;
enum drm_plane_type type; unsigned int num_comp_planes = 0;
unsigned int zpos;
int pipe = priv->num_pipes; int pipe = priv->num_pipes;
int ret; int ret;
int i; int i;
...@@ -606,23 +679,15 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev, ...@@ -606,23 +679,15 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
mtk_crtc->ddp_comp[i] = comp; mtk_crtc->ddp_comp[i] = comp;
} }
mtk_crtc->layer_nr = mtk_ddp_comp_layer_nr(mtk_crtc->ddp_comp[0]); for (i = 0; i < mtk_crtc->ddp_comp_nr; i++)
if (mtk_crtc->ddp_comp_nr > 1) { num_comp_planes += mtk_drm_crtc_num_comp_planes(mtk_crtc, i);
struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[1];
if (comp->funcs->bgclr_in_on) mtk_crtc->planes = devm_kcalloc(dev, num_comp_planes,
mtk_crtc->layer_nr += mtk_ddp_comp_layer_nr(comp); sizeof(struct drm_plane), GFP_KERNEL);
}
mtk_crtc->planes = devm_kcalloc(dev, mtk_crtc->layer_nr, for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {
sizeof(struct drm_plane), ret = mtk_drm_crtc_init_comp_planes(drm_dev, mtk_crtc, i,
GFP_KERNEL); pipe);
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);
if (ret) if (ret)
return ret; return ret;
} }
......
...@@ -19,5 +19,7 @@ void mtk_crtc_ddp_irq(struct drm_crtc *crtc, struct mtk_ddp_comp *comp); ...@@ -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, int mtk_drm_crtc_create(struct drm_device *drm_dev,
const enum mtk_ddp_comp_id *path, const enum mtk_ddp_comp_id *path,
unsigned int path_len); 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 */ #endif /* MTK_DRM_CRTC_H */
...@@ -77,9 +77,13 @@ struct mtk_ddp_comp_funcs { ...@@ -77,9 +77,13 @@ struct mtk_ddp_comp_funcs {
void (*stop)(struct mtk_ddp_comp *comp); void (*stop)(struct mtk_ddp_comp *comp);
void (*enable_vblank)(struct mtk_ddp_comp *comp, struct drm_crtc *crtc); void (*enable_vblank)(struct mtk_ddp_comp *comp, struct drm_crtc *crtc);
void (*disable_vblank)(struct mtk_ddp_comp *comp); 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); unsigned int (*layer_nr)(struct mtk_ddp_comp *comp);
void (*layer_on)(struct mtk_ddp_comp *comp, unsigned int idx); void (*layer_on)(struct mtk_ddp_comp *comp, unsigned int idx);
void (*layer_off)(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, void (*layer_config)(struct mtk_ddp_comp *comp, unsigned int idx,
struct mtk_plane_state *state); struct mtk_plane_state *state);
void (*gamma_set)(struct mtk_ddp_comp *comp, 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) ...@@ -130,6 +134,15 @@ static inline void mtk_ddp_comp_disable_vblank(struct mtk_ddp_comp *comp)
comp->funcs->disable_vblank(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) static inline unsigned int mtk_ddp_comp_layer_nr(struct mtk_ddp_comp *comp)
{ {
if (comp->funcs && comp->funcs->layer_nr) if (comp->funcs && comp->funcs->layer_nr)
...@@ -152,6 +165,15 @@ static inline void mtk_ddp_comp_layer_off(struct mtk_ddp_comp *comp, ...@@ -152,6 +165,15 @@ static inline void mtk_ddp_comp_layer_off(struct mtk_ddp_comp *comp,
comp->funcs->layer_off(comp, idx); 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, static inline void mtk_ddp_comp_layer_config(struct mtk_ddp_comp *comp,
unsigned int idx, unsigned int idx,
struct mtk_plane_state *state) struct mtk_plane_state *state)
......
...@@ -20,6 +20,12 @@ ...@@ -20,6 +20,12 @@
static const u32 formats[] = { static const u32 formats[] = {
DRM_FORMAT_XRGB8888, DRM_FORMAT_XRGB8888,
DRM_FORMAT_ARGB8888, DRM_FORMAT_ARGB8888,
DRM_FORMAT_BGRX8888,
DRM_FORMAT_BGRA8888,
DRM_FORMAT_ABGR8888,
DRM_FORMAT_XBGR8888,
DRM_FORMAT_RGB888,
DRM_FORMAT_BGR888,
DRM_FORMAT_RGB565, DRM_FORMAT_RGB565,
DRM_FORMAT_UYVY, DRM_FORMAT_UYVY,
DRM_FORMAT_YUYV, DRM_FORMAT_YUYV,
...@@ -84,6 +90,7 @@ static int mtk_plane_atomic_check(struct drm_plane *plane, ...@@ -84,6 +90,7 @@ static int mtk_plane_atomic_check(struct drm_plane *plane,
{ {
struct drm_framebuffer *fb = state->fb; struct drm_framebuffer *fb = state->fb;
struct drm_crtc_state *crtc_state; struct drm_crtc_state *crtc_state;
int ret;
if (!fb) if (!fb)
return 0; return 0;
...@@ -91,6 +98,11 @@ static int mtk_plane_atomic_check(struct drm_plane *plane, ...@@ -91,6 +98,11 @@ static int mtk_plane_atomic_check(struct drm_plane *plane,
if (!state->crtc) if (!state->crtc)
return 0; return 0;
ret = mtk_drm_crtc_plane_check(state->crtc, plane,
to_mtk_plane_state(state));
if (ret)
return ret;
crtc_state = drm_atomic_get_crtc_state(state->state, state->crtc); crtc_state = drm_atomic_get_crtc_state(state->state, state->crtc);
if (IS_ERR(crtc_state)) if (IS_ERR(crtc_state))
return PTR_ERR(crtc_state); return PTR_ERR(crtc_state);
...@@ -132,6 +144,7 @@ static void mtk_plane_atomic_update(struct drm_plane *plane, ...@@ -132,6 +144,7 @@ static void mtk_plane_atomic_update(struct drm_plane *plane,
state->pending.y = plane->state->dst.y1; state->pending.y = plane->state->dst.y1;
state->pending.width = drm_rect_width(&plane->state->dst); state->pending.width = drm_rect_width(&plane->state->dst);
state->pending.height = drm_rect_height(&plane->state->dst); state->pending.height = drm_rect_height(&plane->state->dst);
state->pending.rotation = plane->state->rotation;
wmb(); /* Make sure the above parameters are set before update */ wmb(); /* Make sure the above parameters are set before update */
state->pending.dirty = true; state->pending.dirty = true;
} }
...@@ -154,7 +167,8 @@ static const struct drm_plane_helper_funcs mtk_plane_helper_funcs = { ...@@ -154,7 +167,8 @@ static const struct drm_plane_helper_funcs mtk_plane_helper_funcs = {
}; };
int mtk_plane_init(struct drm_device *dev, struct drm_plane *plane, int mtk_plane_init(struct drm_device *dev, struct drm_plane *plane,
unsigned long possible_crtcs, enum drm_plane_type type) unsigned long possible_crtcs, enum drm_plane_type type,
unsigned int supported_rotations)
{ {
int err; int err;
...@@ -166,6 +180,14 @@ int mtk_plane_init(struct drm_device *dev, struct drm_plane *plane, ...@@ -166,6 +180,14 @@ int mtk_plane_init(struct drm_device *dev, struct drm_plane *plane,
return err; return err;
} }
if (supported_rotations & ~DRM_MODE_ROTATE_0) {
err = drm_plane_create_rotation_property(plane,
DRM_MODE_ROTATE_0,
supported_rotations);
if (err)
DRM_INFO("Create rotation property failed\n");
}
drm_plane_helper_add(plane, &mtk_plane_helper_funcs); drm_plane_helper_add(plane, &mtk_plane_helper_funcs);
return 0; return 0;
......
...@@ -20,6 +20,7 @@ struct mtk_plane_pending_state { ...@@ -20,6 +20,7 @@ struct mtk_plane_pending_state {
unsigned int y; unsigned int y;
unsigned int width; unsigned int width;
unsigned int height; unsigned int height;
unsigned int rotation;
bool dirty; bool dirty;
}; };
...@@ -35,6 +36,7 @@ to_mtk_plane_state(struct drm_plane_state *state) ...@@ -35,6 +36,7 @@ to_mtk_plane_state(struct drm_plane_state *state)
} }
int mtk_plane_init(struct drm_device *dev, struct drm_plane *plane, int mtk_plane_init(struct drm_device *dev, struct drm_plane *plane,
unsigned long possible_crtcs, enum drm_plane_type type); unsigned long possible_crtcs, enum drm_plane_type type,
unsigned int supported_rotations);
#endif #endif
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