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); drm_rk_filter_whitelist(&hdmi->edid_data);
if (hdmi->phy.ops->mode_valid) if (hdmi->phy.ops->mode_valid)
hdmi->phy.ops->mode_valid(hdmi, state); 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)) { if (!drm_mode_prune_invalid(&hdmi->edid_data)) {
printf("can't find valid hdmi mode\n"); printf("can't find valid hdmi mode\n");
return -EINVAL; return -EINVAL;

View File

@ -16,6 +16,7 @@ struct rockchip_crtc {
}; };
struct rockchip_crtc_funcs { struct rockchip_crtc_funcs {
int (*preinit)(struct display_state *state);
int (*init)(struct display_state *state); int (*init)(struct display_state *state);
void (*deinit)(struct display_state *state); void (*deinit)(struct display_state *state);
int (*set_plane)(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; 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 * drm_mode_set_crtcinfo - set CRTC modesetting timing parameters
* @p: mode * @p: mode
@ -552,6 +569,12 @@ static int display_init(struct display_state *state)
return -ENODEV; return -ENODEV;
} }
if (crtc_funcs->preinit) {
ret = crtc_funcs->preinit(state);
if (ret)
return ret;
}
if (panel_state->panel) if (panel_state->panel)
rockchip_panel_init(panel_state->panel); rockchip_panel_init(panel_state->panel);

View File

@ -62,6 +62,11 @@ struct rockchip_mcu_timing {
int mcu_hold_mode; int mcu_hold_mode;
}; };
struct vop_rect {
int width;
int height;
};
struct crtc_state { struct crtc_state {
struct udevice *dev; struct udevice *dev;
struct rockchip_crtc *crtc; struct rockchip_crtc *crtc;
@ -85,6 +90,7 @@ struct crtc_state {
bool yuv_overlay; bool yuv_overlay;
struct rockchip_mcu_timing mcu_timing; struct rockchip_mcu_timing mcu_timing;
u32 dual_channel_swap; u32 dual_channel_swap;
struct vop_rect max_output;
}; };
struct panel_state { 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, bool drm_mode_is_420(const struct drm_display_info *display,
struct drm_display_mode *mode); struct drm_display_mode *mode);
void drm_mode_max_resolution_filter(struct hdmi_edid_data *edid_data,
struct vop_rect *max_output);
#endif #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); 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) static int rockchip_vop_init(struct display_state *state)
{ {
struct crtc_state *crtc_state = &state->crtc_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->csc_table = vop_data->csc_table;
vop->win_csc = vop_data->win_csc; vop->win_csc = vop_data->win_csc;
vop->version = vop_data->version; vop->version = vop_data->version;
vop->max_output = vop_data->max_output;
/* Process 'assigned-{clocks/clock-parents/clock-rates}' properties */ /* Process 'assigned-{clocks/clock-parents/clock-rates}' properties */
ret = clk_set_defaults(crtc_state->dev); 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) if (!vop->win->scl)
return; 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) { if (!vop->win->scl->ext) {
VOP_SCL_SET(vop, scale_yrgb_x, VOP_SCL_SET(vop, scale_yrgb_x,
scl_cal_scale2(src_w, dst_w)); 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 xvir = crtc_state->xvir;
int x_mirror = 0, y_mirror = 0; 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_h - 1) << 16;
act_info |= (src_w - 1) & 0xffff; 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 = { const struct rockchip_crtc_funcs rockchip_vop_funcs = {
.preinit = rockchip_vop_preinit,
.init = rockchip_vop_init, .init = rockchip_vop_init,
.set_plane = rockchip_vop_set_plane, .set_plane = rockchip_vop_set_plane,
.prepare = rockchip_vop_prepare, .prepare = rockchip_vop_prepare,

View File

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