if (!win->phy->scl)
return;
- if (dst_w > 3840) {
- DRM_ERROR("Maximum destination width (3840) exceeded\n");
- return;
- }
-
if (!win->phy->scl->ext) {
VOP_SCL_SET(vop, win, scale_yrgb_x,
scl_cal_scale2(src_w, dst_w));
struct vop_win *win = to_vop_win(plane);
struct vop_plane_state *vop_plane_state = to_vop_plane_state(state);
struct drm_crtc_state *crtc_state;
+ const struct vop_data *vop_data;
+ struct vop *vop;
bool visible;
int ret;
struct drm_rect *dest = &vop_plane_state->dest;
if (vop_plane_state->format < 0)
return vop_plane_state->format;
+ vop = to_vop(crtc);
+ vop_data = vop->data;
+
+ if (drm_rect_width(src) >> 16 > vop_data->max_input_fb.width ||
+ drm_rect_height(src) >> 16 > vop_data->max_input_fb.height) {
+ DRM_ERROR("Invalid source: %dx%d. max input: %dx%d\n",
+ drm_rect_width(src) >> 16,
+ drm_rect_height(src) >> 16,
+ vop_data->max_input_fb.width,
+ vop_data->max_input_fb.height);
+ return -EINVAL;
+ }
+
+ if (drm_rect_width(dest) >> 16 > vop_data->max_input_fb.width ||
+ drm_rect_height(dest) >> 16 > vop_data->max_input_fb.height) {
+ DRM_ERROR("Invalid destination: %dx%d. max output: %dx%d\n",
+ drm_rect_width(dest),
+ drm_rect_height(dest),
+ vop_data->max_output_fb.width,
+ vop_data->max_output_fb.height);
+ return -EINVAL;
+ }
+
/*
* Src.x1 can be odd when do clip, but yuv plane start point
* need align with 2 pixel.
struct drm_display_mode *adjusted_mode)
{
struct vop *vop = to_vop(crtc);
+ const struct vop_data *vop_data = vop->data;
+
+ if (mode->hdisplay > vop_data->max_disably_output.width ||
+ mode->vdisplay > vop_data->max_disably_output.height)
+ return false;
adjusted_mode->clock =
clk_round_rate(vop->dclk, mode->clock * 1000) / 1000;
static const struct vop_data rk3288_vop = {
.version = VOP_VERSION(3, 1),
.feature = VOP_FEATURE_OUTPUT_10BIT,
+ .max_input_fb = { 4096, 8192},
+ .max_output_fb = { 3840, 2160},
+ /*
+ * TODO: rk3288 have two vop, big one support 3840x2160,
+ * little one only support 2560x1600.
+ * Now force use 3840x2160.
+ */
+ .max_disably_output = { 3840, 2160},
.intr = &rk3288_vop_intr,
.ctrl = &rk3288_ctrl_data,
.win = rk3288_vop_win_data,
static const struct vop_data rk3368_vop = {
.version = VOP_VERSION(3, 2),
.feature = VOP_FEATURE_OUTPUT_10BIT,
+ .max_input_fb = { 4096, 8192},
+ .max_output_fb = { 4096, 2160},
+ .max_disably_output = { 4096, 2160},
.intr = &rk3368_vop_intr,
.ctrl = &rk3288_ctrl_data,
.win = rk3368_vop_win_data,
static const struct vop_data rk3366_vop = {
.version = VOP_VERSION(3, 4),
.feature = VOP_FEATURE_OUTPUT_10BIT,
+ .max_input_fb = { 4096, 8192},
+ .max_output_fb = { 4096, 2160},
+ .max_disably_output = { 4096, 2160},
.intr = &rk3366_vop_intr,
.ctrl = &rk3288_ctrl_data,
.win = rk3368_vop_win_data,
.version = VOP_VERSION(3, 5),
.csc_table = &rk3399_csc_table,
.feature = VOP_FEATURE_OUTPUT_10BIT | VOP_FEATURE_AFBDC,
+ .max_input_fb = { 4096, 8192},
+ .max_output_fb = { 4096, 2160},
+ .max_disably_output = { 4096, 2160},
.intr = &rk3366_vop_intr,
.ctrl = &rk3288_ctrl_data,
.win = rk3399_vop_win_data,
static const struct vop_data rk3399_vop_lit = {
.version = VOP_VERSION(3, 6),
.csc_table = &rk3399_csc_table,
+ .max_input_fb = { 4096, 8192},
+ .max_output_fb = { 2560, 1600},
+ .max_disably_output = { 2560, 1600},
.intr = &rk3366_vop_intr,
.ctrl = &rk3288_ctrl_data,
.win = rk3399_vop_lit_win_data,
static const struct vop_data rk322x_vop = {
.version = VOP_VERSION(3, 7),
.feature = VOP_FEATURE_OUTPUT_10BIT,
+ .max_input_fb = { 4096, 8192},
+ .max_output_fb = { 4096, 2160},
+ .max_disably_output = { 4096, 2160},
.intr = &rk3366_vop_intr,
.ctrl = &rk3288_ctrl_data,
.win = rk3368_vop_win_data,
static const struct vop_data rk3036_vop = {
.version = VOP_VERSION(2, 2),
+ .max_input_fb = { 1920, 1080},
+ .max_output_fb = { 1920, 1080},
+ .max_disably_output = { 1920, 1080},
.ctrl = &rk3036_ctrl_data,
.intr = &rk3036_intr,
.win = rk3036_vop_win_data,