1
0
Fork 0

MMFMWK-7806: drm: imx: dcss: check up/down scale ratios

When scaling up/down, DCSS has limits that cannot be exceeded. This
patch adds checks before the plane is updated and rejects those planes
that exceed the up/down scale limits.

Currently, the limit is 3:1 for downscaling and 1:3 for upscaling for
both video and graphics channels.

When support for WR_SCL/RD_SRC will be added, these limits will increase
to the following values:
 * video: 7:1 downscale, 1:7 upscale
 * graphics: 5:1 downscale, 1:5 upscale

Signed-off-by: Laurentiu Palcu <laurentiu.palcu@nxp.com>
pull/10/head
Laurentiu Palcu 2017-12-06 11:03:50 +02:00 committed by Jason Liu
parent cd2ce2b7c9
commit 305d4e7232
3 changed files with 53 additions and 0 deletions

View File

@ -119,6 +119,7 @@ static const struct drm_plane_funcs dcss_plane_funcs = {
static int dcss_plane_atomic_check(struct drm_plane *plane,
struct drm_plane_state *state)
{
struct dcss_plane *dcss_plane = to_dcss_plane(plane);
struct drm_framebuffer *fb = state->fb;
struct drm_gem_cma_object *cma_obj;
struct drm_crtc_state *crtc_state;
@ -145,6 +146,13 @@ static int dcss_plane_atomic_check(struct drm_plane *plane,
state->crtc_y + state->crtc_h > vdisplay)
return -EINVAL;
if (!dcss_scaler_can_scale(dcss_plane->dcss, dcss_plane->ch_num,
state->src_w >> 16, state->src_h >> 16,
state->crtc_w, state->crtc_h)) {
DRM_DEBUG_KMS("Invalid upscale/downscale ratio.");
return -EINVAL;
}
return 0;
}

View File

@ -338,6 +338,48 @@ static void dcss_scaler_fractions_set(struct dcss_soc *dcss, int ch_num,
DCSS_SCALER_H_CHR_INC);
}
/*
* The values below are without RD_SRC/WR_SCL support. When support will be
* added, these need to be changed accordingly.
*/
#define DCSS_SCALER_VIDEO_RATIO 3 /* 7 with RD_SRC/WR_SCL */
#define DCSS_SCALER_GRAPHICS_RATIO 3 /* 5 with RD_SRC/WR_SCL */
/* convert to fixed point (###.# #### #### ####), easier to work with */
#define DCSS_SCALER_VIDEO_DOWN_RATIO_FP (DCSS_SCALER_VIDEO_RATIO << 13)
#define DCSS_SCALER_VIDEO_UP_RATIO_FP \
((1 << 13) / DCSS_SCALER_VIDEO_RATIO)
#define DCSS_SCALER_GRAPHICS_DOWN_RATIO_FP (DCSS_SCALER_GRAPHICS_RATIO << 13)
#define DCSS_SCALER_GRAPHICS_UP_RATIO_FP \
((1 << 13) / DCSS_SCALER_GRAPHICS_RATIO)
static const struct dcss_scaler_ratios {
u16 downscale_ratio;
u16 upscale_ratio;
} dcss_scaler_ratios_map[] = {
{DCSS_SCALER_GRAPHICS_DOWN_RATIO_FP, DCSS_SCALER_GRAPHICS_UP_RATIO_FP},
{DCSS_SCALER_VIDEO_DOWN_RATIO_FP, DCSS_SCALER_VIDEO_UP_RATIO_FP},
{DCSS_SCALER_VIDEO_DOWN_RATIO_FP, DCSS_SCALER_VIDEO_UP_RATIO_FP},
};
bool dcss_scaler_can_scale(struct dcss_soc *dcss, int ch_num,
int src_xres, int src_yres,
int dst_xres, int dst_yres)
{
u32 vscale_fp, hscale_fp;
/* Convert to fixed point. Easier to work with. */
vscale_fp = (src_yres << 13) / dst_yres;
hscale_fp = (src_xres << 13) / dst_xres;
return vscale_fp <= dcss_scaler_ratios_map[ch_num].downscale_ratio &&
vscale_fp >= dcss_scaler_ratios_map[ch_num].upscale_ratio &&
hscale_fp <= dcss_scaler_ratios_map[ch_num].downscale_ratio &&
hscale_fp >= dcss_scaler_ratios_map[ch_num].upscale_ratio;
}
EXPORT_SYMBOL(dcss_scaler_can_scale);
static void dcss_scaler_coef_clr(struct dcss_soc *dcss, int ch_num)
{
int i;

View File

@ -77,6 +77,9 @@ void dcss_ss_enable(struct dcss_soc *dcss, bool en);
void dcss_scaler_enable(struct dcss_soc *dcss, int ch_num, bool en);
void dcss_scaler_setup(struct dcss_soc *dcss, int ch_num, u32 pix_format,
int src_xres, int src_yres, int dst_xres, int dst_yres);
bool dcss_scaler_can_scale(struct dcss_soc *dcss, int ch_num,
int src_xres, int src_yres,
int dst_xres, int dst_yres);
/* CTXLD */
int dcss_ctxld_enable(struct dcss_soc *dcss);