1
0
Fork 0
alistair23-linux/drivers/gpu/drm/imx/dpu/dpu-plane.h

196 lines
4.4 KiB
C

/*
* Copyright 2017-2019 NXP
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#ifndef __DPU_PLANE_H__
#define __DPU_PLANE_H__
#include <video/dpu.h>
#include "../imx-drm.h"
#define MAX_DPU_PLANE_GRP (MAX_CRTC / 2)
enum dpu_plane_src_type {
DPU_PLANE_SRC_FL,
DPU_PLANE_SRC_FW,
DPU_PLANE_SRC_FD,
};
struct dpu_plane {
struct drm_plane base;
struct dpu_plane_grp *grp;
struct list_head head;
unsigned int stream_id;
};
struct dpu_plane_state {
struct drm_plane_state base;
lb_prim_sel_t stage;
lb_sec_sel_t source;
dpu_block_id_t blend;
lb_prim_sel_t aux_stage;
lb_sec_sel_t aux_source;
dpu_block_id_t aux_blend;
bool is_top;
bool use_prefetch;
bool use_aux_prefetch;
bool need_aux_source;
/* used when pixel combiner is needed */
unsigned int left_src_w;
unsigned int left_crtc_w;
unsigned int left_crtc_x;
unsigned int right_src_w;
unsigned int right_crtc_w;
unsigned int right_crtc_x;
bool is_left_top;
bool is_right_top;
};
static const lb_prim_sel_t cf_stages[] = {LB_PRIM_SEL__CONSTFRAME0,
LB_PRIM_SEL__CONSTFRAME1};
static const lb_prim_sel_t stages[] = {LB_PRIM_SEL__LAYERBLEND0,
LB_PRIM_SEL__LAYERBLEND1,
LB_PRIM_SEL__LAYERBLEND2,
LB_PRIM_SEL__LAYERBLEND3};
/* TODO: Add source entries for subsidiary layers. */
static const lb_sec_sel_t sources[] = {LB_SEC_SEL__FETCHLAYER0,
LB_SEC_SEL__FETCHWARP2,
LB_SEC_SEL__FETCHDECODE0,
LB_SEC_SEL__FETCHDECODE1};
static const dpu_block_id_t blends[] = {ID_LAYERBLEND0, ID_LAYERBLEND1,
ID_LAYERBLEND2, ID_LAYERBLEND3};
static inline struct dpu_plane *to_dpu_plane(struct drm_plane *plane)
{
return container_of(plane, struct dpu_plane, base);
}
static inline struct dpu_plane_state *
to_dpu_plane_state(struct drm_plane_state *plane_state)
{
return container_of(plane_state, struct dpu_plane_state, base);
}
static inline int source_to_type(lb_sec_sel_t source)
{
switch (source) {
case LB_SEC_SEL__FETCHLAYER0:
return DPU_PLANE_SRC_FL;
case LB_SEC_SEL__FETCHWARP2:
return DPU_PLANE_SRC_FW;
case LB_SEC_SEL__FETCHDECODE0:
case LB_SEC_SEL__FETCHDECODE1:
return DPU_PLANE_SRC_FD;
default:
break;
}
WARN_ON(1);
return -EINVAL;
}
static inline int source_to_id(lb_sec_sel_t source)
{
int i, offset = 0;
int type = source_to_type(source);
for (i = 0; i < ARRAY_SIZE(sources); i++) {
if (source != sources[i])
continue;
/* FetchLayer */
if (type == DPU_PLANE_SRC_FL)
return i;
/* FetchWarp or FetchDecode */
while (offset < ARRAY_SIZE(sources)) {
if (source_to_type(sources[offset]) == type)
break;
offset++;
}
return i - offset;
}
WARN_ON(1);
return -EINVAL;
}
static inline struct dpu_fetchunit *
source_to_fu(struct dpu_plane_res *res, lb_sec_sel_t source)
{
int fu_type = source_to_type(source);
int fu_id = source_to_id(source);
if (fu_type < 0 || fu_id < 0)
return NULL;
switch (fu_type) {
case DPU_PLANE_SRC_FD:
return res->fd[fu_id];
case DPU_PLANE_SRC_FL:
return res->fl[fu_id];
case DPU_PLANE_SRC_FW:
return res->fw[fu_id];
}
return NULL;
}
static inline struct dpu_fetchunit *
dpstate_to_fu(struct dpu_plane_state *dpstate)
{
struct drm_plane *plane = dpstate->base.plane;
struct dpu_plane *dplane = to_dpu_plane(plane);
struct dpu_plane_res *res = &dplane->grp->res;
return source_to_fu(res, dpstate->source);
}
static inline int blend_to_id(dpu_block_id_t blend)
{
int i;
for (i = 0; i < ARRAY_SIZE(blends); i++) {
if (blend == blends[i])
return i;
}
WARN_ON(1);
return -EINVAL;
}
static inline bool drm_format_is_yuv(uint32_t format)
{
switch (format) {
case DRM_FORMAT_YUYV:
case DRM_FORMAT_UYVY:
case DRM_FORMAT_NV12:
case DRM_FORMAT_NV21:
return true;
default:
break;
}
return false;
}
struct dpu_plane *dpu_plane_create(struct drm_device *drm,
unsigned int possible_crtcs,
unsigned int stream_id,
struct dpu_plane_grp *grp,
enum drm_plane_type type);
#endif