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:
Mark Yao
2016-04-20 10:13:30 +08:00
committed by Huang, Tao
parent 629b58a49a
commit e5683dd6c1
5 changed files with 127 additions and 71 deletions

View File

@@ -125,41 +125,6 @@ rockchip_dp_drm_encoder_mode_fixup(struct drm_encoder *encoder,
const struct drm_display_mode *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;
}
@@ -199,11 +164,54 @@ static void rockchip_dp_drm_encoder_nop(struct drm_encoder *encoder)
/* 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 = {
.mode_fixup = rockchip_dp_drm_encoder_mode_fixup,
.mode_set = rockchip_dp_drm_encoder_mode_set,
.enable = rockchip_dp_drm_encoder_enable,
.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)

View File

@@ -902,23 +902,6 @@ static bool dw_mipi_dsi_encoder_mode_fixup(struct drm_encoder *encoder,
const struct drm_display_mode *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;
}
@@ -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");
}
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
dw_mipi_dsi_encoder_helper_funcs = {
.mode_fixup = dw_mipi_dsi_encoder_mode_fixup,
.commit = dw_mipi_dsi_encoder_commit,
.mode_set = dw_mipi_dsi_encoder_mode_set,
.disable = dw_mipi_dsi_encoder_disable,
.atomic_check = dw_mipi_dsi_encoder_atomic_check,
};
static struct drm_encoder_funcs dw_mipi_dsi_encoder_funcs = {

View File

@@ -186,8 +186,6 @@ dw_hdmi_rockchip_encoder_mode_fixup(struct drm_encoder *encoder,
const struct drm_display_mode *mode,
struct drm_display_mode *adj_mode)
{
adj_mode->private_flags = ROCKCHIP_DSP_MODE(HDMIA, AAAA);
return true;
}
@@ -214,11 +212,25 @@ static void dw_hdmi_rockchip_encoder_enable(struct drm_encoder *encoder)
(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 = {
.mode_fixup = dw_hdmi_rockchip_encoder_mode_fixup,
.mode_set = dw_hdmi_rockchip_encoder_mode_set,
.enable = dw_hdmi_rockchip_encoder_enable,
.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 = {

View File

@@ -61,6 +61,15 @@ struct rockchip_atomic_commit {
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.
*

View File

@@ -898,6 +898,7 @@ static bool vop_crtc_mode_fixup(struct drm_crtc *crtc,
static void vop_crtc_enable(struct drm_crtc *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;
u16 hsync_len = adjusted_mode->hsync_end - adjusted_mode->hsync_start;
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 vact_st = adjusted_mode->vtotal - adjusted_mode->vsync_start;
u16 vact_end = vact_st + vdisplay;
uint32_t pin_pol, val;
int type = ROCKCHIP_OUT_MODE_TYPE(adjusted_mode->private_flags);
int out_mode = ROCKCHIP_OUT_MODE(adjusted_mode->private_flags);
uint32_t val;
vop_enable(crtc);
/*
@@ -950,32 +949,27 @@ static void vop_crtc_enable(struct drm_crtc *crtc)
vop_dsp_hold_valid_irq_disable(vop);
}
pin_pol = 0x8;
pin_pol |= (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC) ? 0 : 1;
pin_pol |= (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC) ? 0 : (1 << 1);
VOP_CTRL_SET(vop, pin_pol, pin_pol);
switch(type) {
val = 0x8;
val |= (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC) ? 0 : 1;
val |= (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC) ? 0 : (1 << 1);
VOP_CTRL_SET(vop, pin_pol, val);
switch (s->output_type) {
case DRM_MODE_CONNECTOR_LVDS:
VOP_CTRL_SET(vop, rgb_en, 1);
VOP_CTRL_SET(vop, rgb_pin_pol, pin_pol);
break;
case DRM_MODE_CONNECTOR_eDP:
VOP_CTRL_SET(vop, edp_pin_pol, pin_pol);
VOP_CTRL_SET(vop, edp_en, 1);
break;
case DRM_MODE_CONNECTOR_HDMIA:
VOP_CTRL_SET(vop, hdmi_pin_pol, pin_pol);
VOP_CTRL_SET(vop, hdmi_en, 1);
break;
case DRM_MODE_CONNECTOR_DSI:
VOP_CTRL_SET(vop, mipi_pin_pol, pin_pol);
VOP_CTRL_SET(vop, mipi_en, 1);
break;
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);
val = hact_st << 16;
@@ -1035,13 +1029,34 @@ static void vop_crtc_destroy(struct drm_crtc *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 = {
.set_config = drm_atomic_helper_set_config,
.page_flip = drm_atomic_helper_page_flip,
.destroy = vop_crtc_destroy,
.reset = drm_atomic_helper_crtc_reset,
.atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
.atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
.atomic_duplicate_state = vop_crtc_duplicate_state,
.atomic_destroy_state = vop_crtc_destroy_state,
};
static bool vop_win_pending_is_complete(struct vop_win *vop_win)