mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-09 20:32:04 +09:00
FROMLIST: drm/rockchip: get rid of rockchip_drm_crtc_mode_config
We need to take care of the vop status when use rockchip_drm_crtc_mode_config, if vop is disabled, the function would failed, that is terrible. Save output_type and output_mode into rockchip_crtc_state, it's nice to make them into atomic. Conflicts: drivers/gpu/drm/rockchip/analogix_dp-rockchip.c drivers/gpu/drm/rockchip/dw-mipi-dsi.c drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c drivers/gpu/drm/rockchip/inno_hdmi.c drivers/gpu/drm/rockchip/rockchip_drm_drv.h drivers/gpu/drm/rockchip/rockchip_drm_vop.c Change-Id: I43c49a92b2b9df02ce8a055bd16948b400ab0f47 Signed-off-by: Mark Yao <mark.yao@rock-chips.com> (am from https://patchwork.kernel.org/patch/8844321/)
This commit is contained in:
@@ -125,41 +125,6 @@ rockchip_dp_drm_encoder_mode_fixup(struct drm_encoder *encoder,
|
|||||||
const struct drm_display_mode *mode,
|
const struct drm_display_mode *mode,
|
||||||
struct drm_display_mode *adjusted_mode)
|
struct drm_display_mode *adjusted_mode)
|
||||||
{
|
{
|
||||||
struct rockchip_dp_device *dp = to_dp(encoder);
|
|
||||||
int private_flags;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The hardware IC designed that VOP must output the RGB10 video
|
|
||||||
* format to eDP contoller, and if eDP panel only support RGB8,
|
|
||||||
* then eDP contoller should cut down the video data, not via VOP
|
|
||||||
* contoller, that's why we need to hardcode the VOP output mode
|
|
||||||
* to RGA10 here.
|
|
||||||
*/
|
|
||||||
|
|
||||||
ret = rockchip_drm_encoder_get_mux_id(dp->dev->of_node, encoder);
|
|
||||||
if (ret < 0)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
switch (dp->data->chip_type) {
|
|
||||||
case RK3399_EDP:
|
|
||||||
/*
|
|
||||||
* For RK3399, VOP Lit must code the out mode to RGB888,
|
|
||||||
* VOP Big must code the out mode to RGB10.
|
|
||||||
*/
|
|
||||||
if (ret)
|
|
||||||
private_flags = ROCKCHIP_DSP_MODE(eDP, P888);
|
|
||||||
else
|
|
||||||
private_flags = ROCKCHIP_DSP_MODE(eDP, AAAA);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
private_flags = ROCKCHIP_DSP_MODE(eDP, AAAA);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
adjusted_mode->private_flags = private_flags;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -199,11 +164,54 @@ static void rockchip_dp_drm_encoder_nop(struct drm_encoder *encoder)
|
|||||||
/* do nothing */
|
/* do nothing */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
rockchip_dp_drm_encoder_atomic_check(struct drm_encoder *encoder,
|
||||||
|
struct drm_crtc_state *crtc_state,
|
||||||
|
struct drm_connector_state *conn_state)
|
||||||
|
{
|
||||||
|
struct rockchip_dp_device *dp = to_dp(encoder);
|
||||||
|
struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state);
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The hardware IC designed that VOP must output the RGB10 video
|
||||||
|
* format to eDP contoller, and if eDP panel only support RGB8,
|
||||||
|
* then eDP contoller should cut down the video data, not via VOP
|
||||||
|
* contoller, that's why we need to hardcode the VOP output mode
|
||||||
|
* to RGA10 here.
|
||||||
|
*/
|
||||||
|
|
||||||
|
ret = rockchip_drm_encoder_get_mux_id(dp->dev->of_node, encoder);
|
||||||
|
if (ret < 0)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
switch (dp->data->chip_type) {
|
||||||
|
case RK3399_EDP:
|
||||||
|
/*
|
||||||
|
* For RK3399, VOP Lit must code the out mode to RGB888,
|
||||||
|
* VOP Big must code the out mode to RGB10.
|
||||||
|
*/
|
||||||
|
if (ret)
|
||||||
|
s->output_mode = ROCKCHIP_OUT_MODE_P888;
|
||||||
|
else
|
||||||
|
s->output_mode = ROCKCHIP_OUT_MODE_AAAA;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
s->output_mode = ROCKCHIP_OUT_MODE_AAAA;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
s->output_type = DRM_MODE_CONNECTOR_eDP;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static struct drm_encoder_helper_funcs rockchip_dp_encoder_helper_funcs = {
|
static struct drm_encoder_helper_funcs rockchip_dp_encoder_helper_funcs = {
|
||||||
.mode_fixup = rockchip_dp_drm_encoder_mode_fixup,
|
.mode_fixup = rockchip_dp_drm_encoder_mode_fixup,
|
||||||
.mode_set = rockchip_dp_drm_encoder_mode_set,
|
.mode_set = rockchip_dp_drm_encoder_mode_set,
|
||||||
.enable = rockchip_dp_drm_encoder_enable,
|
.enable = rockchip_dp_drm_encoder_enable,
|
||||||
.disable = rockchip_dp_drm_encoder_nop,
|
.disable = rockchip_dp_drm_encoder_nop,
|
||||||
|
.atomic_check = rockchip_dp_drm_encoder_atomic_check,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void rockchip_dp_drm_encoder_destroy(struct drm_encoder *encoder)
|
static void rockchip_dp_drm_encoder_destroy(struct drm_encoder *encoder)
|
||||||
|
|||||||
@@ -902,23 +902,6 @@ static bool dw_mipi_dsi_encoder_mode_fixup(struct drm_encoder *encoder,
|
|||||||
const struct drm_display_mode *mode,
|
const struct drm_display_mode *mode,
|
||||||
struct drm_display_mode *adjusted_mode)
|
struct drm_display_mode *adjusted_mode)
|
||||||
{
|
{
|
||||||
struct dw_mipi_dsi *dsi = encoder_to_dsi(encoder);
|
|
||||||
|
|
||||||
switch (dsi->format) {
|
|
||||||
case MIPI_DSI_FMT_RGB888:
|
|
||||||
adjusted_mode->private_flags = ROCKCHIP_DSP_MODE(DSI, P888);
|
|
||||||
break;
|
|
||||||
case MIPI_DSI_FMT_RGB666:
|
|
||||||
adjusted_mode->private_flags = ROCKCHIP_DSP_MODE(DSI, P666);
|
|
||||||
break;
|
|
||||||
case MIPI_DSI_FMT_RGB565:
|
|
||||||
adjusted_mode->private_flags = ROCKCHIP_DSP_MODE(DSI, P565);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
WARN_ON(1);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -955,12 +938,41 @@ static void dw_mipi_dsi_encoder_commit(struct drm_encoder *encoder)
|
|||||||
dev_dbg(dsi->dev, "vop %s output to dsi0\n", (mux) ? "LIT" : "BIG");
|
dev_dbg(dsi->dev, "vop %s output to dsi0\n", (mux) ? "LIT" : "BIG");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
dw_mipi_dsi_encoder_atomic_check(struct drm_encoder *encoder,
|
||||||
|
struct drm_crtc_state *crtc_state,
|
||||||
|
struct drm_connector_state *conn_state)
|
||||||
|
{
|
||||||
|
struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state);
|
||||||
|
struct dw_mipi_dsi *dsi = encoder_to_dsi(encoder);
|
||||||
|
|
||||||
|
switch (dsi->format) {
|
||||||
|
case MIPI_DSI_FMT_RGB888:
|
||||||
|
s->output_mode = ROCKCHIP_OUT_MODE_P888;
|
||||||
|
break;
|
||||||
|
case MIPI_DSI_FMT_RGB666:
|
||||||
|
s->output_mode = ROCKCHIP_OUT_MODE_P666;
|
||||||
|
break;
|
||||||
|
case MIPI_DSI_FMT_RGB565:
|
||||||
|
s->output_mode = ROCKCHIP_OUT_MODE_P565;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
WARN_ON(1);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
s->output_type = DRM_MODE_CONNECTOR_DSI;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static struct drm_encoder_helper_funcs
|
static struct drm_encoder_helper_funcs
|
||||||
dw_mipi_dsi_encoder_helper_funcs = {
|
dw_mipi_dsi_encoder_helper_funcs = {
|
||||||
.mode_fixup = dw_mipi_dsi_encoder_mode_fixup,
|
.mode_fixup = dw_mipi_dsi_encoder_mode_fixup,
|
||||||
.commit = dw_mipi_dsi_encoder_commit,
|
.commit = dw_mipi_dsi_encoder_commit,
|
||||||
.mode_set = dw_mipi_dsi_encoder_mode_set,
|
.mode_set = dw_mipi_dsi_encoder_mode_set,
|
||||||
.disable = dw_mipi_dsi_encoder_disable,
|
.disable = dw_mipi_dsi_encoder_disable,
|
||||||
|
.atomic_check = dw_mipi_dsi_encoder_atomic_check,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct drm_encoder_funcs dw_mipi_dsi_encoder_funcs = {
|
static struct drm_encoder_funcs dw_mipi_dsi_encoder_funcs = {
|
||||||
|
|||||||
@@ -186,8 +186,6 @@ dw_hdmi_rockchip_encoder_mode_fixup(struct drm_encoder *encoder,
|
|||||||
const struct drm_display_mode *mode,
|
const struct drm_display_mode *mode,
|
||||||
struct drm_display_mode *adj_mode)
|
struct drm_display_mode *adj_mode)
|
||||||
{
|
{
|
||||||
adj_mode->private_flags = ROCKCHIP_DSP_MODE(HDMIA, AAAA);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -214,11 +212,25 @@ static void dw_hdmi_rockchip_encoder_enable(struct drm_encoder *encoder)
|
|||||||
(mux) ? "LIT" : "BIG");
|
(mux) ? "LIT" : "BIG");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
dw_hdmi_rockchip_encoder_atomic_check(struct drm_encoder *encoder,
|
||||||
|
struct drm_crtc_state *crtc_state,
|
||||||
|
struct drm_connector_state *conn_state)
|
||||||
|
{
|
||||||
|
struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state);
|
||||||
|
|
||||||
|
s->output_mode = ROCKCHIP_OUT_MODE_AAAA;
|
||||||
|
s->output_type = DRM_MODE_CONNECTOR_HDMIA;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static const struct drm_encoder_helper_funcs dw_hdmi_rockchip_encoder_helper_funcs = {
|
static const struct drm_encoder_helper_funcs dw_hdmi_rockchip_encoder_helper_funcs = {
|
||||||
.mode_fixup = dw_hdmi_rockchip_encoder_mode_fixup,
|
.mode_fixup = dw_hdmi_rockchip_encoder_mode_fixup,
|
||||||
.mode_set = dw_hdmi_rockchip_encoder_mode_set,
|
.mode_set = dw_hdmi_rockchip_encoder_mode_set,
|
||||||
.enable = dw_hdmi_rockchip_encoder_enable,
|
.enable = dw_hdmi_rockchip_encoder_enable,
|
||||||
.disable = dw_hdmi_rockchip_encoder_disable,
|
.disable = dw_hdmi_rockchip_encoder_disable,
|
||||||
|
.atomic_check = dw_hdmi_rockchip_encoder_atomic_check,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct dw_hdmi_plat_data rockchip_hdmi_drv_data = {
|
static const struct dw_hdmi_plat_data rockchip_hdmi_drv_data = {
|
||||||
|
|||||||
@@ -61,6 +61,15 @@ struct rockchip_atomic_commit {
|
|||||||
struct mutex lock;
|
struct mutex lock;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct rockchip_crtc_state {
|
||||||
|
struct drm_crtc_state base;
|
||||||
|
int output_type;
|
||||||
|
int output_mode;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define to_rockchip_crtc_state(s) \
|
||||||
|
container_of(s, struct rockchip_crtc_state, base)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Rockchip drm_file private structure.
|
* Rockchip drm_file private structure.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -898,6 +898,7 @@ static bool vop_crtc_mode_fixup(struct drm_crtc *crtc,
|
|||||||
static void vop_crtc_enable(struct drm_crtc *crtc)
|
static void vop_crtc_enable(struct drm_crtc *crtc)
|
||||||
{
|
{
|
||||||
struct vop *vop = to_vop(crtc);
|
struct vop *vop = to_vop(crtc);
|
||||||
|
struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc->state);
|
||||||
struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode;
|
struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode;
|
||||||
u16 hsync_len = adjusted_mode->hsync_end - adjusted_mode->hsync_start;
|
u16 hsync_len = adjusted_mode->hsync_end - adjusted_mode->hsync_start;
|
||||||
u16 hdisplay = adjusted_mode->hdisplay;
|
u16 hdisplay = adjusted_mode->hdisplay;
|
||||||
@@ -909,9 +910,7 @@ static void vop_crtc_enable(struct drm_crtc *crtc)
|
|||||||
u16 vsync_len = adjusted_mode->vsync_end - adjusted_mode->vsync_start;
|
u16 vsync_len = adjusted_mode->vsync_end - adjusted_mode->vsync_start;
|
||||||
u16 vact_st = adjusted_mode->vtotal - adjusted_mode->vsync_start;
|
u16 vact_st = adjusted_mode->vtotal - adjusted_mode->vsync_start;
|
||||||
u16 vact_end = vact_st + vdisplay;
|
u16 vact_end = vact_st + vdisplay;
|
||||||
uint32_t pin_pol, val;
|
uint32_t val;
|
||||||
int type = ROCKCHIP_OUT_MODE_TYPE(adjusted_mode->private_flags);
|
|
||||||
int out_mode = ROCKCHIP_OUT_MODE(adjusted_mode->private_flags);
|
|
||||||
|
|
||||||
vop_enable(crtc);
|
vop_enable(crtc);
|
||||||
/*
|
/*
|
||||||
@@ -950,32 +949,27 @@ static void vop_crtc_enable(struct drm_crtc *crtc)
|
|||||||
vop_dsp_hold_valid_irq_disable(vop);
|
vop_dsp_hold_valid_irq_disable(vop);
|
||||||
}
|
}
|
||||||
|
|
||||||
pin_pol = 0x8;
|
val = 0x8;
|
||||||
pin_pol |= (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC) ? 0 : 1;
|
val |= (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC) ? 0 : 1;
|
||||||
pin_pol |= (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC) ? 0 : (1 << 1);
|
val |= (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC) ? 0 : (1 << 1);
|
||||||
VOP_CTRL_SET(vop, pin_pol, pin_pol);
|
VOP_CTRL_SET(vop, pin_pol, val);
|
||||||
|
switch (s->output_type) {
|
||||||
switch(type) {
|
|
||||||
case DRM_MODE_CONNECTOR_LVDS:
|
case DRM_MODE_CONNECTOR_LVDS:
|
||||||
VOP_CTRL_SET(vop, rgb_en, 1);
|
VOP_CTRL_SET(vop, rgb_en, 1);
|
||||||
VOP_CTRL_SET(vop, rgb_pin_pol, pin_pol);
|
|
||||||
break;
|
break;
|
||||||
case DRM_MODE_CONNECTOR_eDP:
|
case DRM_MODE_CONNECTOR_eDP:
|
||||||
VOP_CTRL_SET(vop, edp_pin_pol, pin_pol);
|
|
||||||
VOP_CTRL_SET(vop, edp_en, 1);
|
VOP_CTRL_SET(vop, edp_en, 1);
|
||||||
break;
|
break;
|
||||||
case DRM_MODE_CONNECTOR_HDMIA:
|
case DRM_MODE_CONNECTOR_HDMIA:
|
||||||
VOP_CTRL_SET(vop, hdmi_pin_pol, pin_pol);
|
|
||||||
VOP_CTRL_SET(vop, hdmi_en, 1);
|
VOP_CTRL_SET(vop, hdmi_en, 1);
|
||||||
break;
|
break;
|
||||||
case DRM_MODE_CONNECTOR_DSI:
|
case DRM_MODE_CONNECTOR_DSI:
|
||||||
VOP_CTRL_SET(vop, mipi_pin_pol, pin_pol);
|
|
||||||
VOP_CTRL_SET(vop, mipi_en, 1);
|
VOP_CTRL_SET(vop, mipi_en, 1);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
DRM_ERROR("unsupport connector_type[%d]\n", type);
|
DRM_ERROR("unsupport connector_type[%d]\n", s->output_type);
|
||||||
}
|
}
|
||||||
VOP_CTRL_SET(vop, out_mode, out_mode);
|
VOP_CTRL_SET(vop, out_mode, s->output_mode);
|
||||||
|
|
||||||
VOP_CTRL_SET(vop, htotal_pw, (htotal << 16) | hsync_len);
|
VOP_CTRL_SET(vop, htotal_pw, (htotal << 16) | hsync_len);
|
||||||
val = hact_st << 16;
|
val = hact_st << 16;
|
||||||
@@ -1035,13 +1029,34 @@ static void vop_crtc_destroy(struct drm_crtc *crtc)
|
|||||||
drm_crtc_cleanup(crtc);
|
drm_crtc_cleanup(crtc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct drm_crtc_state *vop_crtc_duplicate_state(struct drm_crtc *crtc)
|
||||||
|
{
|
||||||
|
struct rockchip_crtc_state *rockchip_state;
|
||||||
|
|
||||||
|
rockchip_state = kzalloc(sizeof(*rockchip_state), GFP_KERNEL);
|
||||||
|
if (!rockchip_state)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
__drm_atomic_helper_crtc_duplicate_state(crtc, &rockchip_state->base);
|
||||||
|
return &rockchip_state->base;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void vop_crtc_destroy_state(struct drm_crtc *crtc,
|
||||||
|
struct drm_crtc_state *state)
|
||||||
|
{
|
||||||
|
struct rockchip_crtc_state *s = to_rockchip_crtc_state(state);
|
||||||
|
|
||||||
|
__drm_atomic_helper_crtc_destroy_state(crtc, &s->base);
|
||||||
|
kfree(s);
|
||||||
|
}
|
||||||
|
|
||||||
static const struct drm_crtc_funcs vop_crtc_funcs = {
|
static const struct drm_crtc_funcs vop_crtc_funcs = {
|
||||||
.set_config = drm_atomic_helper_set_config,
|
.set_config = drm_atomic_helper_set_config,
|
||||||
.page_flip = drm_atomic_helper_page_flip,
|
.page_flip = drm_atomic_helper_page_flip,
|
||||||
.destroy = vop_crtc_destroy,
|
.destroy = vop_crtc_destroy,
|
||||||
.reset = drm_atomic_helper_crtc_reset,
|
.reset = drm_atomic_helper_crtc_reset,
|
||||||
.atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
|
.atomic_duplicate_state = vop_crtc_duplicate_state,
|
||||||
.atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
|
.atomic_destroy_state = vop_crtc_destroy_state,
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool vop_win_pending_is_complete(struct vop_win *vop_win)
|
static bool vop_win_pending_is_complete(struct vop_win *vop_win)
|
||||||
|
|||||||
Reference in New Issue
Block a user