|
3 | 3 | * Copyright (c) 2015 MediaTek Inc.
|
4 | 4 | */
|
5 | 5 |
|
| 6 | +#include <drm/drm_fourcc.h> |
| 7 | + |
6 | 8 | #include <linux/clk.h>
|
7 | 9 | #include <linux/component.h>
|
8 | 10 | #include <linux/module.h>
|
|
50 | 52 | OVL_CON_CLRFMT_RGB : 0)
|
51 | 53 | #define OVL_CON_AEN BIT(8)
|
52 | 54 | #define OVL_CON_ALPHA 0xff
|
| 55 | +#define OVL_CON_VIRT_FLIP BIT(9) |
53 | 56 |
|
54 | 57 | struct mtk_disp_ovl_data {
|
55 | 58 | unsigned int addr;
|
@@ -137,6 +140,38 @@ static unsigned int mtk_ovl_layer_nr(struct mtk_ddp_comp *comp)
|
137 | 140 | return ovl->data->layer_nr;
|
138 | 141 | }
|
139 | 142 |
|
| 143 | +static unsigned int mtk_ovl_supported_rotations(struct mtk_ddp_comp *comp) |
| 144 | +{ |
| 145 | + return DRM_MODE_ROTATE_0 | DRM_MODE_REFLECT_Y; |
| 146 | +} |
| 147 | + |
| 148 | +static int mtk_ovl_layer_check(struct mtk_ddp_comp *comp, unsigned int idx, |
| 149 | + struct mtk_plane_state *mtk_state) |
| 150 | +{ |
| 151 | + struct drm_plane_state *state = &mtk_state->base; |
| 152 | + unsigned int rotation = 0; |
| 153 | + |
| 154 | + rotation = drm_rotation_simplify(state->rotation, |
| 155 | + DRM_MODE_ROTATE_0 | |
| 156 | + DRM_MODE_REFLECT_Y); |
| 157 | + rotation &= ~DRM_MODE_ROTATE_0; |
| 158 | + |
| 159 | + /* We can only do reflection, not rotation */ |
| 160 | + if ((rotation & DRM_MODE_ROTATE_MASK) != 0) |
| 161 | + return -EINVAL; |
| 162 | + |
| 163 | + /* |
| 164 | + * TODO: Rotating/reflecting YUV buffers is not supported at this time. |
| 165 | + * Only RGB[AX] variants are supported. |
| 166 | + */ |
| 167 | + if (state->fb->format->is_yuv && rotation != 0) |
| 168 | + return -EINVAL; |
| 169 | + |
| 170 | + state->rotation = rotation; |
| 171 | + |
| 172 | + return 0; |
| 173 | +} |
| 174 | + |
140 | 175 | static void mtk_ovl_layer_on(struct mtk_ddp_comp *comp, unsigned int idx)
|
141 | 176 | {
|
142 | 177 | unsigned int reg;
|
@@ -229,6 +264,11 @@ static void mtk_ovl_layer_config(struct mtk_ddp_comp *comp, unsigned int idx,
|
229 | 264 | if (idx != 0)
|
230 | 265 | con |= OVL_CON_AEN | OVL_CON_ALPHA;
|
231 | 266 |
|
| 267 | + if (pending->rotation & DRM_MODE_REFLECT_Y) { |
| 268 | + con |= OVL_CON_VIRT_FLIP; |
| 269 | + addr += (pending->height - 1) * pending->pitch; |
| 270 | + } |
| 271 | + |
232 | 272 | writel_relaxed(con, comp->regs + DISP_REG_OVL_CON(idx));
|
233 | 273 | writel_relaxed(pitch, comp->regs + DISP_REG_OVL_PITCH(idx));
|
234 | 274 | writel_relaxed(src_size, comp->regs + DISP_REG_OVL_SRC_SIZE(idx));
|
@@ -263,9 +303,11 @@ static const struct mtk_ddp_comp_funcs mtk_disp_ovl_funcs = {
|
263 | 303 | .stop = mtk_ovl_stop,
|
264 | 304 | .enable_vblank = mtk_ovl_enable_vblank,
|
265 | 305 | .disable_vblank = mtk_ovl_disable_vblank,
|
| 306 | + .supported_rotations = mtk_ovl_supported_rotations, |
266 | 307 | .layer_nr = mtk_ovl_layer_nr,
|
267 | 308 | .layer_on = mtk_ovl_layer_on,
|
268 | 309 | .layer_off = mtk_ovl_layer_off,
|
| 310 | + .layer_check = mtk_ovl_layer_check, |
269 | 311 | .layer_config = mtk_ovl_layer_config,
|
270 | 312 | .bgclr_in_on = mtk_ovl_bgclr_in_on,
|
271 | 313 | .bgclr_in_off = mtk_ovl_bgclr_in_off,
|
|
0 commit comments