Commit 36d1364a authored by Archit Taneja's avatar Archit Taneja Committed by Rob Clark

drm/msm/mdp5: Clean up interface assignment

mdp5_interface struct contains data corresponding to a INTF
instance in MDP5 hardware. This sturct is memcpy'd to the
mdp5_encoder struct, and then later to the mdp5_ctl struct.

Instead of copying around interface data, create mdp5_interface
instances in mdp5_init, like how it's done currently done for
pipes and layer mixers. Pass around the interface pointers to
mdp5_encoder and mdp5_ctl. This simplifies the code, and allows
us to decouple encoders from INTFs in the future if needed.
Signed-off-by: default avatarArchit Taneja <architt@codeaurora.org>
Signed-off-by: default avatarRob Clark <robdclark@gmail.com>
parent a2380124
...@@ -145,7 +145,7 @@ void mdp5_cmd_encoder_mode_set(struct drm_encoder *encoder, ...@@ -145,7 +145,7 @@ void mdp5_cmd_encoder_mode_set(struct drm_encoder *encoder,
mode->vsync_end, mode->vtotal, mode->vsync_end, mode->vtotal,
mode->type, mode->flags); mode->type, mode->flags);
pingpong_tearcheck_setup(encoder, mode); pingpong_tearcheck_setup(encoder, mode);
mdp5_crtc_set_pipeline(encoder->crtc, &mdp5_cmd_enc->intf, mdp5_crtc_set_pipeline(encoder->crtc, mdp5_cmd_enc->intf,
mdp5_cmd_enc->ctl); mdp5_cmd_enc->ctl);
} }
...@@ -153,7 +153,7 @@ void mdp5_cmd_encoder_disable(struct drm_encoder *encoder) ...@@ -153,7 +153,7 @@ void mdp5_cmd_encoder_disable(struct drm_encoder *encoder)
{ {
struct mdp5_encoder *mdp5_cmd_enc = to_mdp5_encoder(encoder); struct mdp5_encoder *mdp5_cmd_enc = to_mdp5_encoder(encoder);
struct mdp5_ctl *ctl = mdp5_cmd_enc->ctl; struct mdp5_ctl *ctl = mdp5_cmd_enc->ctl;
struct mdp5_interface *intf = &mdp5_cmd_enc->intf; struct mdp5_interface *intf = mdp5_cmd_enc->intf;
if (WARN_ON(!mdp5_cmd_enc->enabled)) if (WARN_ON(!mdp5_cmd_enc->enabled))
return; return;
...@@ -172,7 +172,7 @@ void mdp5_cmd_encoder_enable(struct drm_encoder *encoder) ...@@ -172,7 +172,7 @@ void mdp5_cmd_encoder_enable(struct drm_encoder *encoder)
{ {
struct mdp5_encoder *mdp5_cmd_enc = to_mdp5_encoder(encoder); struct mdp5_encoder *mdp5_cmd_enc = to_mdp5_encoder(encoder);
struct mdp5_ctl *ctl = mdp5_cmd_enc->ctl; struct mdp5_ctl *ctl = mdp5_cmd_enc->ctl;
struct mdp5_interface *intf = &mdp5_cmd_enc->intf; struct mdp5_interface *intf = mdp5_cmd_enc->intf;
if (WARN_ON(mdp5_cmd_enc->enabled)) if (WARN_ON(mdp5_cmd_enc->enabled))
return; return;
...@@ -200,7 +200,7 @@ int mdp5_cmd_encoder_set_split_display(struct drm_encoder *encoder, ...@@ -200,7 +200,7 @@ int mdp5_cmd_encoder_set_split_display(struct drm_encoder *encoder,
return -EINVAL; return -EINVAL;
mdp5_kms = get_kms(encoder); mdp5_kms = get_kms(encoder);
intf_num = mdp5_cmd_enc->intf.num; intf_num = mdp5_cmd_enc->intf->num;
/* Switch slave encoder's trigger MUX, to use the master's /* Switch slave encoder's trigger MUX, to use the master's
* start signal for the slave encoder * start signal for the slave encoder
......
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
#define CTL_STAT_BOOKED 0x2 #define CTL_STAT_BOOKED 0x2
struct op_mode { struct op_mode {
struct mdp5_interface intf; struct mdp5_interface *intf;
bool encoder_enabled; bool encoder_enabled;
uint32_t start_mask; uint32_t start_mask;
...@@ -180,16 +180,8 @@ int mdp5_ctl_set_pipeline(struct mdp5_ctl *ctl, struct mdp5_interface *intf, ...@@ -180,16 +180,8 @@ int mdp5_ctl_set_pipeline(struct mdp5_ctl *ctl, struct mdp5_interface *intf,
struct mdp5_ctl_manager *ctl_mgr = ctl->ctlm; struct mdp5_ctl_manager *ctl_mgr = ctl->ctlm;
struct mdp5_kms *mdp5_kms = get_kms(ctl_mgr); struct mdp5_kms *mdp5_kms = get_kms(ctl_mgr);
if (unlikely(WARN_ON(intf->num != ctl->pipeline.intf.num))) {
dev_err(mdp5_kms->dev->dev,
"CTL %d is allocated by INTF %d, but used by INTF %d\n",
ctl->id, ctl->pipeline.intf.num, intf->num);
return -EINVAL;
}
ctl->mixer = mixer; ctl->mixer = mixer;
ctl->pipeline.intf = intf;
memcpy(&ctl->pipeline.intf, intf, sizeof(*intf));
ctl->pipeline.start_mask = mdp_ctl_flush_mask_lm(mixer->lm) | ctl->pipeline.start_mask = mdp_ctl_flush_mask_lm(mixer->lm) |
mdp_ctl_flush_mask_encoder(intf); mdp_ctl_flush_mask_encoder(intf);
...@@ -210,11 +202,11 @@ static bool start_signal_needed(struct mdp5_ctl *ctl) ...@@ -210,11 +202,11 @@ static bool start_signal_needed(struct mdp5_ctl *ctl)
if (!pipeline->encoder_enabled || pipeline->start_mask != 0) if (!pipeline->encoder_enabled || pipeline->start_mask != 0)
return false; return false;
switch (pipeline->intf.type) { switch (pipeline->intf->type) {
case INTF_WB: case INTF_WB:
return true; return true;
case INTF_DSI: case INTF_DSI:
return pipeline->intf.mode == MDP5_INTF_DSI_MODE_COMMAND; return pipeline->intf->mode == MDP5_INTF_DSI_MODE_COMMAND;
default: default:
return false; return false;
} }
...@@ -239,7 +231,7 @@ static void send_start_signal(struct mdp5_ctl *ctl) ...@@ -239,7 +231,7 @@ static void send_start_signal(struct mdp5_ctl *ctl)
static void refill_start_mask(struct mdp5_ctl *ctl) static void refill_start_mask(struct mdp5_ctl *ctl)
{ {
struct op_mode *pipeline = &ctl->pipeline; struct op_mode *pipeline = &ctl->pipeline;
struct mdp5_interface *intf = &ctl->pipeline.intf; struct mdp5_interface *intf = pipeline->intf;
pipeline->start_mask = mdp_ctl_flush_mask_lm(ctl->mixer->lm); pipeline->start_mask = mdp_ctl_flush_mask_lm(ctl->mixer->lm);
...@@ -265,7 +257,7 @@ int mdp5_ctl_set_encoder_state(struct mdp5_ctl *ctl, bool enabled) ...@@ -265,7 +257,7 @@ int mdp5_ctl_set_encoder_state(struct mdp5_ctl *ctl, bool enabled)
return -EINVAL; return -EINVAL;
ctl->pipeline.encoder_enabled = enabled; ctl->pipeline.encoder_enabled = enabled;
DBG("intf_%d: %s", ctl->pipeline.intf.num, enabled ? "on" : "off"); DBG("intf_%d: %s", ctl->pipeline.intf->num, enabled ? "on" : "off");
if (start_signal_needed(ctl)) { if (start_signal_needed(ctl)) {
send_start_signal(ctl); send_start_signal(ctl);
...@@ -621,7 +613,6 @@ struct mdp5_ctl *mdp5_ctlm_request(struct mdp5_ctl_manager *ctl_mgr, ...@@ -621,7 +613,6 @@ struct mdp5_ctl *mdp5_ctlm_request(struct mdp5_ctl_manager *ctl_mgr,
found: found:
ctl = &ctl_mgr->ctls[c]; ctl = &ctl_mgr->ctls[c];
ctl->pipeline.intf.num = intf_num;
ctl->mixer = NULL; ctl->mixer = NULL;
ctl->status |= CTL_STAT_BUSY; ctl->status |= CTL_STAT_BUSY;
ctl->pending_ctl_trigger = 0; ctl->pending_ctl_trigger = 0;
......
...@@ -109,7 +109,7 @@ static void mdp5_vid_encoder_mode_set(struct drm_encoder *encoder, ...@@ -109,7 +109,7 @@ static void mdp5_vid_encoder_mode_set(struct drm_encoder *encoder,
struct mdp5_kms *mdp5_kms = get_kms(encoder); struct mdp5_kms *mdp5_kms = get_kms(encoder);
struct drm_device *dev = encoder->dev; struct drm_device *dev = encoder->dev;
struct drm_connector *connector; struct drm_connector *connector;
int intf = mdp5_encoder->intf.num; int intf = mdp5_encoder->intf->num;
uint32_t dtv_hsync_skew, vsync_period, vsync_len, ctrl_pol; uint32_t dtv_hsync_skew, vsync_period, vsync_len, ctrl_pol;
uint32_t display_v_start, display_v_end; uint32_t display_v_start, display_v_end;
uint32_t hsync_start_x, hsync_end_x; uint32_t hsync_start_x, hsync_end_x;
...@@ -130,7 +130,7 @@ static void mdp5_vid_encoder_mode_set(struct drm_encoder *encoder, ...@@ -130,7 +130,7 @@ static void mdp5_vid_encoder_mode_set(struct drm_encoder *encoder,
ctrl_pol = 0; ctrl_pol = 0;
/* DSI controller cannot handle active-low sync signals. */ /* DSI controller cannot handle active-low sync signals. */
if (mdp5_encoder->intf.type != INTF_DSI) { if (mdp5_encoder->intf->type != INTF_DSI) {
if (mode->flags & DRM_MODE_FLAG_NHSYNC) if (mode->flags & DRM_MODE_FLAG_NHSYNC)
ctrl_pol |= MDP5_INTF_POLARITY_CTL_HSYNC_LOW; ctrl_pol |= MDP5_INTF_POLARITY_CTL_HSYNC_LOW;
if (mode->flags & DRM_MODE_FLAG_NVSYNC) if (mode->flags & DRM_MODE_FLAG_NVSYNC)
...@@ -175,7 +175,7 @@ static void mdp5_vid_encoder_mode_set(struct drm_encoder *encoder, ...@@ -175,7 +175,7 @@ static void mdp5_vid_encoder_mode_set(struct drm_encoder *encoder,
* DISPLAY_V_START = (VBP * HCYCLE) + HBP * DISPLAY_V_START = (VBP * HCYCLE) + HBP
* DISPLAY_V_END = (VBP + VACTIVE) * HCYCLE - 1 - HFP * DISPLAY_V_END = (VBP + VACTIVE) * HCYCLE - 1 - HFP
*/ */
if (mdp5_encoder->intf.type == INTF_eDP) { if (mdp5_encoder->intf->type == INTF_eDP) {
display_v_start += mode->htotal - mode->hsync_start; display_v_start += mode->htotal - mode->hsync_start;
display_v_end -= mode->hsync_start - mode->hdisplay; display_v_end -= mode->hsync_start - mode->hdisplay;
} }
...@@ -206,8 +206,8 @@ static void mdp5_vid_encoder_mode_set(struct drm_encoder *encoder, ...@@ -206,8 +206,8 @@ static void mdp5_vid_encoder_mode_set(struct drm_encoder *encoder,
spin_unlock_irqrestore(&mdp5_encoder->intf_lock, flags); spin_unlock_irqrestore(&mdp5_encoder->intf_lock, flags);
mdp5_crtc_set_pipeline(encoder->crtc, &mdp5_encoder->intf, mdp5_crtc_set_pipeline(encoder->crtc, mdp5_encoder->intf,
mdp5_encoder->ctl); mdp5_encoder->ctl);
} }
static void mdp5_vid_encoder_disable(struct drm_encoder *encoder) static void mdp5_vid_encoder_disable(struct drm_encoder *encoder)
...@@ -216,8 +216,8 @@ static void mdp5_vid_encoder_disable(struct drm_encoder *encoder) ...@@ -216,8 +216,8 @@ static void mdp5_vid_encoder_disable(struct drm_encoder *encoder)
struct mdp5_kms *mdp5_kms = get_kms(encoder); struct mdp5_kms *mdp5_kms = get_kms(encoder);
struct mdp5_ctl *ctl = mdp5_encoder->ctl; struct mdp5_ctl *ctl = mdp5_encoder->ctl;
struct mdp5_hw_mixer *mixer = mdp5_crtc_get_mixer(encoder->crtc); struct mdp5_hw_mixer *mixer = mdp5_crtc_get_mixer(encoder->crtc);
struct mdp5_interface *intf = &mdp5_encoder->intf; struct mdp5_interface *intf = mdp5_encoder->intf;
int intfn = mdp5_encoder->intf.num; int intfn = mdp5_encoder->intf->num;
unsigned long flags; unsigned long flags;
if (WARN_ON(!mdp5_encoder->enabled)) if (WARN_ON(!mdp5_encoder->enabled))
...@@ -250,8 +250,8 @@ static void mdp5_vid_encoder_enable(struct drm_encoder *encoder) ...@@ -250,8 +250,8 @@ static void mdp5_vid_encoder_enable(struct drm_encoder *encoder)
struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder); struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder);
struct mdp5_kms *mdp5_kms = get_kms(encoder); struct mdp5_kms *mdp5_kms = get_kms(encoder);
struct mdp5_ctl *ctl = mdp5_encoder->ctl; struct mdp5_ctl *ctl = mdp5_encoder->ctl;
struct mdp5_interface *intf = &mdp5_encoder->intf; struct mdp5_interface *intf = mdp5_encoder->intf;
int intfn = mdp5_encoder->intf.num; int intfn = intf->num;
unsigned long flags; unsigned long flags;
if (WARN_ON(mdp5_encoder->enabled)) if (WARN_ON(mdp5_encoder->enabled))
...@@ -273,7 +273,7 @@ static void mdp5_encoder_mode_set(struct drm_encoder *encoder, ...@@ -273,7 +273,7 @@ static void mdp5_encoder_mode_set(struct drm_encoder *encoder,
struct drm_display_mode *adjusted_mode) struct drm_display_mode *adjusted_mode)
{ {
struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder); struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder);
struct mdp5_interface *intf = &mdp5_encoder->intf; struct mdp5_interface *intf = mdp5_encoder->intf;
if (intf->mode == MDP5_INTF_DSI_MODE_COMMAND) if (intf->mode == MDP5_INTF_DSI_MODE_COMMAND)
mdp5_cmd_encoder_mode_set(encoder, mode, adjusted_mode); mdp5_cmd_encoder_mode_set(encoder, mode, adjusted_mode);
...@@ -284,7 +284,7 @@ static void mdp5_encoder_mode_set(struct drm_encoder *encoder, ...@@ -284,7 +284,7 @@ static void mdp5_encoder_mode_set(struct drm_encoder *encoder,
static void mdp5_encoder_disable(struct drm_encoder *encoder) static void mdp5_encoder_disable(struct drm_encoder *encoder)
{ {
struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder); struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder);
struct mdp5_interface *intf = &mdp5_encoder->intf; struct mdp5_interface *intf = mdp5_encoder->intf;
if (intf->mode == MDP5_INTF_DSI_MODE_COMMAND) if (intf->mode == MDP5_INTF_DSI_MODE_COMMAND)
mdp5_cmd_encoder_disable(encoder); mdp5_cmd_encoder_disable(encoder);
...@@ -295,7 +295,7 @@ static void mdp5_encoder_disable(struct drm_encoder *encoder) ...@@ -295,7 +295,7 @@ static void mdp5_encoder_disable(struct drm_encoder *encoder)
static void mdp5_encoder_enable(struct drm_encoder *encoder) static void mdp5_encoder_enable(struct drm_encoder *encoder)
{ {
struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder); struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder);
struct mdp5_interface *intf = &mdp5_encoder->intf; struct mdp5_interface *intf = mdp5_encoder->intf;
if (intf->mode == MDP5_INTF_DSI_MODE_COMMAND) if (intf->mode == MDP5_INTF_DSI_MODE_COMMAND)
mdp5_cmd_encoder_disable(encoder); mdp5_cmd_encoder_disable(encoder);
...@@ -313,7 +313,7 @@ int mdp5_encoder_get_linecount(struct drm_encoder *encoder) ...@@ -313,7 +313,7 @@ int mdp5_encoder_get_linecount(struct drm_encoder *encoder)
{ {
struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder); struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder);
struct mdp5_kms *mdp5_kms = get_kms(encoder); struct mdp5_kms *mdp5_kms = get_kms(encoder);
int intf = mdp5_encoder->intf.num; int intf = mdp5_encoder->intf->num;
return mdp5_read(mdp5_kms, REG_MDP5_INTF_LINE_COUNT(intf)); return mdp5_read(mdp5_kms, REG_MDP5_INTF_LINE_COUNT(intf));
} }
...@@ -322,7 +322,7 @@ u32 mdp5_encoder_get_framecount(struct drm_encoder *encoder) ...@@ -322,7 +322,7 @@ u32 mdp5_encoder_get_framecount(struct drm_encoder *encoder)
{ {
struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder); struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder);
struct mdp5_kms *mdp5_kms = get_kms(encoder); struct mdp5_kms *mdp5_kms = get_kms(encoder);
int intf = mdp5_encoder->intf.num; int intf = mdp5_encoder->intf->num;
return mdp5_read(mdp5_kms, REG_MDP5_INTF_FRAME_COUNT(intf)); return mdp5_read(mdp5_kms, REG_MDP5_INTF_FRAME_COUNT(intf));
} }
...@@ -340,7 +340,7 @@ int mdp5_vid_encoder_set_split_display(struct drm_encoder *encoder, ...@@ -340,7 +340,7 @@ int mdp5_vid_encoder_set_split_display(struct drm_encoder *encoder,
return -EINVAL; return -EINVAL;
mdp5_kms = get_kms(encoder); mdp5_kms = get_kms(encoder);
intf_num = mdp5_encoder->intf.num; intf_num = mdp5_encoder->intf->num;
/* Switch slave encoder's TimingGen Sync mode, /* Switch slave encoder's TimingGen Sync mode,
* to use the master's enable signal for the slave encoder. * to use the master's enable signal for the slave encoder.
...@@ -369,7 +369,7 @@ int mdp5_vid_encoder_set_split_display(struct drm_encoder *encoder, ...@@ -369,7 +369,7 @@ int mdp5_vid_encoder_set_split_display(struct drm_encoder *encoder,
void mdp5_encoder_set_intf_mode(struct drm_encoder *encoder, bool cmd_mode) void mdp5_encoder_set_intf_mode(struct drm_encoder *encoder, bool cmd_mode)
{ {
struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder); struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder);
struct mdp5_interface *intf = &mdp5_encoder->intf; struct mdp5_interface *intf = mdp5_encoder->intf;
/* TODO: Expand this to set writeback modes too */ /* TODO: Expand this to set writeback modes too */
if (cmd_mode) { if (cmd_mode) {
...@@ -385,7 +385,8 @@ void mdp5_encoder_set_intf_mode(struct drm_encoder *encoder, bool cmd_mode) ...@@ -385,7 +385,8 @@ void mdp5_encoder_set_intf_mode(struct drm_encoder *encoder, bool cmd_mode)
/* initialize encoder */ /* initialize encoder */
struct drm_encoder *mdp5_encoder_init(struct drm_device *dev, struct drm_encoder *mdp5_encoder_init(struct drm_device *dev,
struct mdp5_interface *intf, struct mdp5_ctl *ctl) struct mdp5_interface *intf,
struct mdp5_ctl *ctl)
{ {
struct drm_encoder *encoder = NULL; struct drm_encoder *encoder = NULL;
struct mdp5_encoder *mdp5_encoder; struct mdp5_encoder *mdp5_encoder;
...@@ -399,9 +400,9 @@ struct drm_encoder *mdp5_encoder_init(struct drm_device *dev, ...@@ -399,9 +400,9 @@ struct drm_encoder *mdp5_encoder_init(struct drm_device *dev,
goto fail; goto fail;
} }
memcpy(&mdp5_encoder->intf, intf, sizeof(mdp5_encoder->intf));
encoder = &mdp5_encoder->base; encoder = &mdp5_encoder->base;
mdp5_encoder->ctl = ctl; mdp5_encoder->ctl = ctl;
mdp5_encoder->intf = intf;
spin_lock_init(&mdp5_encoder->intf_lock); spin_lock_init(&mdp5_encoder->intf_lock);
......
...@@ -271,19 +271,14 @@ int mdp5_enable(struct mdp5_kms *mdp5_kms) ...@@ -271,19 +271,14 @@ int mdp5_enable(struct mdp5_kms *mdp5_kms)
} }
static struct drm_encoder *construct_encoder(struct mdp5_kms *mdp5_kms, static struct drm_encoder *construct_encoder(struct mdp5_kms *mdp5_kms,
enum mdp5_intf_type intf_type, int intf_num, struct mdp5_interface *intf,
struct mdp5_ctl *ctl) struct mdp5_ctl *ctl)
{ {
struct drm_device *dev = mdp5_kms->dev; struct drm_device *dev = mdp5_kms->dev;
struct msm_drm_private *priv = dev->dev_private; struct msm_drm_private *priv = dev->dev_private;
struct drm_encoder *encoder; struct drm_encoder *encoder;
struct mdp5_interface intf = {
.num = intf_num,
.type = intf_type,
.mode = MDP5_INTF_MODE_NONE,
};
encoder = mdp5_encoder_init(dev, &intf, ctl); encoder = mdp5_encoder_init(dev, intf, ctl);
if (IS_ERR(encoder)) { if (IS_ERR(encoder)) {
dev_err(dev->dev, "failed to construct encoder\n"); dev_err(dev->dev, "failed to construct encoder\n");
return encoder; return encoder;
...@@ -312,32 +307,28 @@ static int get_dsi_id_from_intf(const struct mdp5_cfg_hw *hw_cfg, int intf_num) ...@@ -312,32 +307,28 @@ static int get_dsi_id_from_intf(const struct mdp5_cfg_hw *hw_cfg, int intf_num)
return -EINVAL; return -EINVAL;
} }
static int modeset_init_intf(struct mdp5_kms *mdp5_kms, int intf_num) static int modeset_init_intf(struct mdp5_kms *mdp5_kms,
struct mdp5_interface *intf)
{ {
struct drm_device *dev = mdp5_kms->dev; struct drm_device *dev = mdp5_kms->dev;
struct msm_drm_private *priv = dev->dev_private; struct msm_drm_private *priv = dev->dev_private;
const struct mdp5_cfg_hw *hw_cfg =
mdp5_cfg_get_hw_config(mdp5_kms->cfg);
enum mdp5_intf_type intf_type = hw_cfg->intf.connect[intf_num];
struct mdp5_ctl_manager *ctlm = mdp5_kms->ctlm; struct mdp5_ctl_manager *ctlm = mdp5_kms->ctlm;
struct mdp5_ctl *ctl; struct mdp5_ctl *ctl;
struct drm_encoder *encoder; struct drm_encoder *encoder;
int ret = 0; int ret = 0;
switch (intf_type) { switch (intf->type) {
case INTF_DISABLED:
break;
case INTF_eDP: case INTF_eDP:
if (!priv->edp) if (!priv->edp)
break; break;
ctl = mdp5_ctlm_request(ctlm, intf_num); ctl = mdp5_ctlm_request(ctlm, intf->num);
if (!ctl) { if (!ctl) {
ret = -EINVAL; ret = -EINVAL;
break; break;
} }
encoder = construct_encoder(mdp5_kms, INTF_eDP, intf_num, ctl); encoder = construct_encoder(mdp5_kms, intf, ctl);
if (IS_ERR(encoder)) { if (IS_ERR(encoder)) {
ret = PTR_ERR(encoder); ret = PTR_ERR(encoder);
break; break;
...@@ -349,13 +340,13 @@ static int modeset_init_intf(struct mdp5_kms *mdp5_kms, int intf_num) ...@@ -349,13 +340,13 @@ static int modeset_init_intf(struct mdp5_kms *mdp5_kms, int intf_num)
if (!priv->hdmi) if (!priv->hdmi)
break; break;
ctl = mdp5_ctlm_request(ctlm, intf_num); ctl = mdp5_ctlm_request(ctlm, intf->num);
if (!ctl) { if (!ctl) {
ret = -EINVAL; ret = -EINVAL;
break; break;
} }
encoder = construct_encoder(mdp5_kms, INTF_HDMI, intf_num, ctl); encoder = construct_encoder(mdp5_kms, intf, ctl);
if (IS_ERR(encoder)) { if (IS_ERR(encoder)) {
ret = PTR_ERR(encoder); ret = PTR_ERR(encoder);
break; break;
...@@ -365,11 +356,13 @@ static int modeset_init_intf(struct mdp5_kms *mdp5_kms, int intf_num) ...@@ -365,11 +356,13 @@ static int modeset_init_intf(struct mdp5_kms *mdp5_kms, int intf_num)
break; break;
case INTF_DSI: case INTF_DSI:
{ {
int dsi_id = get_dsi_id_from_intf(hw_cfg, intf_num); const struct mdp5_cfg_hw *hw_cfg =
mdp5_cfg_get_hw_config(mdp5_kms->cfg);
int dsi_id = get_dsi_id_from_intf(hw_cfg, intf->num);
if ((dsi_id >= ARRAY_SIZE(priv->dsi)) || (dsi_id < 0)) { if ((dsi_id >= ARRAY_SIZE(priv->dsi)) || (dsi_id < 0)) {
dev_err(dev->dev, "failed to find dsi from intf %d\n", dev_err(dev->dev, "failed to find dsi from intf %d\n",
intf_num); intf->num);
ret = -EINVAL; ret = -EINVAL;
break; break;
} }
...@@ -377,13 +370,13 @@ static int modeset_init_intf(struct mdp5_kms *mdp5_kms, int intf_num) ...@@ -377,13 +370,13 @@ static int modeset_init_intf(struct mdp5_kms *mdp5_kms, int intf_num)
if (!priv->dsi[dsi_id]) if (!priv->dsi[dsi_id])
break; break;
ctl = mdp5_ctlm_request(ctlm, intf_num); ctl = mdp5_ctlm_request(ctlm, intf->num);
if (!ctl) { if (!ctl) {
ret = -EINVAL; ret = -EINVAL;
break; break;
} }
encoder = construct_encoder(mdp5_kms, INTF_DSI, intf_num, ctl); encoder = construct_encoder(mdp5_kms, intf, ctl);
if (IS_ERR(encoder)) { if (IS_ERR(encoder)) {
ret = PTR_ERR(encoder); ret = PTR_ERR(encoder);
break; break;
...@@ -393,7 +386,7 @@ static int modeset_init_intf(struct mdp5_kms *mdp5_kms, int intf_num) ...@@ -393,7 +386,7 @@ static int modeset_init_intf(struct mdp5_kms *mdp5_kms, int intf_num)
break; break;
} }
default: default:
dev_err(dev->dev, "unknown intf: %d\n", intf_type); dev_err(dev->dev, "unknown intf: %d\n", intf->type);
ret = -EINVAL; ret = -EINVAL;
break; break;
} }
...@@ -417,8 +410,8 @@ static int modeset_init(struct mdp5_kms *mdp5_kms) ...@@ -417,8 +410,8 @@ static int modeset_init(struct mdp5_kms *mdp5_kms)
* Construct encoders and modeset initialize connector devices * Construct encoders and modeset initialize connector devices
* for each external display interface. * for each external display interface.
*/ */
for (i = 0; i < ARRAY_SIZE(hw_cfg->intf.connect); i++) { for (i = 0; i < mdp5_kms->num_intfs; i++) {
ret = modeset_init_intf(mdp5_kms, i); ret = modeset_init_intf(mdp5_kms, mdp5_kms->intfs[i]);
if (ret) if (ret)
goto fail; goto fail;
} }
...@@ -747,6 +740,7 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev) ...@@ -747,6 +740,7 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev)
static void mdp5_destroy(struct platform_device *pdev) static void mdp5_destroy(struct platform_device *pdev)
{ {
struct mdp5_kms *mdp5_kms = platform_get_drvdata(pdev); struct mdp5_kms *mdp5_kms = platform_get_drvdata(pdev);
int i;
if (mdp5_kms->ctlm) if (mdp5_kms->ctlm)
mdp5_ctlm_destroy(mdp5_kms->ctlm); mdp5_ctlm_destroy(mdp5_kms->ctlm);
...@@ -755,6 +749,9 @@ static void mdp5_destroy(struct platform_device *pdev) ...@@ -755,6 +749,9 @@ static void mdp5_destroy(struct platform_device *pdev)
if (mdp5_kms->cfg) if (mdp5_kms->cfg)
mdp5_cfg_destroy(mdp5_kms->cfg); mdp5_cfg_destroy(mdp5_kms->cfg);
for (i = 0; i < mdp5_kms->num_intfs; i++)
kfree(mdp5_kms->intfs[i]);
if (mdp5_kms->rpm_enabled) if (mdp5_kms->rpm_enabled)
pm_runtime_disable(&pdev->dev); pm_runtime_disable(&pdev->dev);
...@@ -862,6 +859,38 @@ static int hwmixer_init(struct mdp5_kms *mdp5_kms) ...@@ -862,6 +859,38 @@ static int hwmixer_init(struct mdp5_kms *mdp5_kms)
return 0; return 0;
} }
static int interface_init(struct mdp5_kms *mdp5_kms)
{
struct drm_device *dev = mdp5_kms->dev;
const struct mdp5_cfg_hw *hw_cfg;
const enum mdp5_intf_type *intf_types;
int i;
hw_cfg = mdp5_cfg_get_hw_config(mdp5_kms->cfg);
intf_types = hw_cfg->intf.connect;
for (i = 0; i < ARRAY_SIZE(hw_cfg->intf.connect); i++) {
struct mdp5_interface *intf;
if (intf_types[i] == INTF_DISABLED)
continue;
intf = kzalloc(sizeof(*intf), GFP_KERNEL);
if (!intf) {
dev_err(dev->dev, "failed to construct INTF%d\n", i);
return -ENOMEM;
}
intf->num = i;
intf->type = intf_types[i];
intf->mode = MDP5_INTF_MODE_NONE;
intf->idx = mdp5_kms->num_intfs;
mdp5_kms->intfs[mdp5_kms->num_intfs++] = intf;
}
return 0;
}
static int mdp5_init(struct platform_device *pdev, struct drm_device *dev) static int mdp5_init(struct platform_device *pdev, struct drm_device *dev)
{ {
struct msm_drm_private *priv = dev->dev_private; struct msm_drm_private *priv = dev->dev_private;
...@@ -966,6 +995,10 @@ static int mdp5_init(struct platform_device *pdev, struct drm_device *dev) ...@@ -966,6 +995,10 @@ static int mdp5_init(struct platform_device *pdev, struct drm_device *dev)
if (ret) if (ret)
goto fail; goto fail;
ret = interface_init(mdp5_kms);
if (ret)
goto fail;
/* set uninit-ed kms */ /* set uninit-ed kms */
priv->kms = &mdp5_kms->base.base; priv->kms = &mdp5_kms->base.base;
......
...@@ -43,6 +43,9 @@ struct mdp5_kms { ...@@ -43,6 +43,9 @@ struct mdp5_kms {
unsigned num_hwmixers; unsigned num_hwmixers;
struct mdp5_hw_mixer *hwmixers[8]; struct mdp5_hw_mixer *hwmixers[8];
unsigned num_intfs;
struct mdp5_interface *intfs[5];
struct mdp5_cfg_handler *cfg; struct mdp5_cfg_handler *cfg;
uint32_t caps; /* MDP capabilities (MDP_CAP_XXX bits) */ uint32_t caps; /* MDP capabilities (MDP_CAP_XXX bits) */
...@@ -125,6 +128,7 @@ enum mdp5_intf_mode { ...@@ -125,6 +128,7 @@ enum mdp5_intf_mode {
}; };
struct mdp5_interface { struct mdp5_interface {
int idx;
int num; /* display interface number */ int num; /* display interface number */
enum mdp5_intf_type type; enum mdp5_intf_type type;
enum mdp5_intf_mode mode; enum mdp5_intf_mode mode;
...@@ -132,11 +136,11 @@ struct mdp5_interface { ...@@ -132,11 +136,11 @@ struct mdp5_interface {
struct mdp5_encoder { struct mdp5_encoder {
struct drm_encoder base; struct drm_encoder base;
struct mdp5_interface intf;
spinlock_t intf_lock; /* protect REG_MDP5_INTF_* registers */ spinlock_t intf_lock; /* protect REG_MDP5_INTF_* registers */
bool enabled; bool enabled;
uint32_t bsc; uint32_t bsc;
struct mdp5_interface *intf;
struct mdp5_ctl *ctl; struct mdp5_ctl *ctl;
}; };
#define to_mdp5_encoder(x) container_of(x, struct mdp5_encoder, base) #define to_mdp5_encoder(x) container_of(x, struct mdp5_encoder, base)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment