drm/rockchip: filter the edid modes accordinig to vop max output resolution

Signed-off-by: Sandy Huang <hjc@rock-chips.com>
Change-Id: Id338a2b3bc659799c4fb391d36fa814c44e0274d
This commit is contained in:
Sandy Huang 2020-05-09 15:36:23 +08:00 committed by Jianhong Chen
parent af50552e4f
commit cf53642aa6
6 changed files with 54 additions and 13 deletions

View File

@ -2423,6 +2423,8 @@ int rockchip_dw_hdmi_get_timing(struct display_state *state)
drm_rk_filter_whitelist(&hdmi->edid_data);
if (hdmi->phy.ops->mode_valid)
hdmi->phy.ops->mode_valid(hdmi, state);
drm_mode_max_resolution_filter(&hdmi->edid_data,
&state->crtc_state.max_output);
if (!drm_mode_prune_invalid(&hdmi->edid_data)) {
printf("can't find valid hdmi mode\n");
return -EINVAL;

View File

@ -16,6 +16,7 @@ struct rockchip_crtc {
};
struct rockchip_crtc_funcs {
int (*preinit)(struct display_state *state);
int (*init)(struct display_state *state);
void (*deinit)(struct display_state *state);
int (*set_plane)(struct display_state *state);

View File

@ -338,6 +338,23 @@ static int display_get_timing_from_dts(struct panel_state *panel_state,
return 0;
}
/**
* drm_mode_max_resolution_filter - mark modes out of vop max resolution
* @edid_data: structure store mode list
* @max_output: vop max output resolution
*/
void drm_mode_max_resolution_filter(struct hdmi_edid_data *edid_data,
struct vop_rect *max_output)
{
int i;
for (i = 0; i < edid_data->modes; i++) {
if (edid_data->mode_buf[i].hdisplay > max_output->width ||
edid_data->mode_buf[i].vdisplay > max_output->height)
edid_data->mode_buf[i].invalid = true;
}
}
/**
* drm_mode_set_crtcinfo - set CRTC modesetting timing parameters
* @p: mode
@ -552,6 +569,12 @@ static int display_init(struct display_state *state)
return -ENODEV;
}
if (crtc_funcs->preinit) {
ret = crtc_funcs->preinit(state);
if (ret)
return ret;
}
if (panel_state->panel)
rockchip_panel_init(panel_state->panel);

View File

@ -62,6 +62,11 @@ struct rockchip_mcu_timing {
int mcu_hold_mode;
};
struct vop_rect {
int width;
int height;
};
struct crtc_state {
struct udevice *dev;
struct rockchip_crtc *crtc;
@ -85,6 +90,7 @@ struct crtc_state {
bool yuv_overlay;
struct rockchip_mcu_timing mcu_timing;
u32 dual_channel_swap;
struct vop_rect max_output;
};
struct panel_state {
@ -176,4 +182,7 @@ int display_send_mcu_cmd(struct display_state *state, u32 type, u32 val);
bool drm_mode_is_420(const struct drm_display_info *display,
struct drm_display_mode *mode);
void drm_mode_max_resolution_filter(struct hdmi_edid_data *edid_data,
struct vop_rect *max_output);
#endif

View File

@ -193,6 +193,15 @@ static void vop_mcu_mode(struct display_state *state, struct vop *vop)
VOP_CTRL_SET(vop, mcu_rw_pend, crtc_state->mcu_timing.mcu_rw_pend);
}
static int rockchip_vop_preinit(struct display_state *state)
{
const struct vop_data *vop_data = state->crtc_state.crtc->data;
state->crtc_state.max_output = vop_data->max_output;
return 0;
}
static int rockchip_vop_init(struct display_state *state)
{
struct crtc_state *crtc_state = &state->crtc_state;
@ -239,7 +248,6 @@ static int rockchip_vop_init(struct display_state *state)
vop->csc_table = vop_data->csc_table;
vop->win_csc = vop_data->win_csc;
vop->version = vop_data->version;
vop->max_output = vop_data->max_output;
/* Process 'assigned-{clocks/clock-parents/clock-rates}' properties */
ret = clk_set_defaults(crtc_state->dev);
@ -505,12 +513,6 @@ static void scl_vop_cal_scl_fac(struct vop *vop,
if (!vop->win->scl)
return;
if (dst_w > vop->max_output.width) {
printf("Maximum destination width %d exceeded\n",
vop->max_output.width);
return;
}
if (!vop->win->scl->ext) {
VOP_SCL_SET(vop, scale_yrgb_x,
scl_cal_scale2(src_w, dst_w));
@ -658,6 +660,14 @@ static int rockchip_vop_set_plane(struct display_state *state)
int xvir = crtc_state->xvir;
int x_mirror = 0, y_mirror = 0;
if ((crtc_w > crtc_state->max_output.width) ||
(crtc_h > crtc_state->max_output.height)){
printf("Maximum destination %dx%d exceeded\n",
crtc_state->max_output.width,
crtc_state->max_output.height);
return -EINVAL;
}
act_info = (src_h - 1) << 16;
act_info |= (src_w - 1) & 0xffff;
@ -817,6 +827,7 @@ static int rockchip_vop_send_mcu_cmd(struct display_state *state,
}
const struct rockchip_crtc_funcs rockchip_vop_funcs = {
.preinit = rockchip_vop_preinit,
.init = rockchip_vop_init,
.set_plane = rockchip_vop_set_plane,
.prepare = rockchip_vop_prepare,

View File

@ -6,6 +6,7 @@
#ifndef _ROCKCHIP_VOP_H_
#define _ROCKCHIP_VOP_H_
#include "rockchip_display.h"
/*
* major: IP major vertion, used for IP structure
@ -426,11 +427,6 @@ struct vop_grf_ctrl {
struct vop_reg grf_dclk_inv;
};
struct vop_rect {
int width;
int height;
};
struct vop_csc_table {
const uint32_t *r2y_bt601;
const uint32_t *r2y_bt601_12_235;
@ -477,7 +473,6 @@ struct vop {
const struct vop_csc_table *csc_table;
const struct vop_csc *win_csc;
int win_offset;
struct vop_rect max_output;
};
static inline void vop_writel(struct vop *vop, uint32_t offset, uint32_t v)