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

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
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -145,7 +145,7 @@ void mdp5_cmd_encoder_mode_set(struct drm_encoder *encoder,
			mode->vsync_end, mode->vtotal,
			mode->type, mode->flags);
	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);
}

@@ -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_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))
		return;
@@ -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_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))
		return;
@@ -200,7 +200,7 @@ int mdp5_cmd_encoder_set_split_display(struct drm_encoder *encoder,
		return -EINVAL;

	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
	 * start signal for the slave encoder
+6 −15
Original line number Diff line number Diff line
@@ -33,7 +33,7 @@
#define CTL_STAT_BOOKED	0x2

struct op_mode {
	struct mdp5_interface intf;
	struct mdp5_interface *intf;

	bool encoder_enabled;
	uint32_t start_mask;
@@ -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_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;

	memcpy(&ctl->pipeline.intf, intf, sizeof(*intf));
	ctl->pipeline.intf = intf;

	ctl->pipeline.start_mask = mdp_ctl_flush_mask_lm(mixer->lm) |
				   mdp_ctl_flush_mask_encoder(intf);
@@ -210,11 +202,11 @@ static bool start_signal_needed(struct mdp5_ctl *ctl)
	if (!pipeline->encoder_enabled || pipeline->start_mask != 0)
		return false;

	switch (pipeline->intf.type) {
	switch (pipeline->intf->type) {
	case INTF_WB:
		return true;
	case INTF_DSI:
		return pipeline->intf.mode == MDP5_INTF_DSI_MODE_COMMAND;
		return pipeline->intf->mode == MDP5_INTF_DSI_MODE_COMMAND;
	default:
		return false;
	}
@@ -239,7 +231,7 @@ static void send_start_signal(struct mdp5_ctl *ctl)
static void refill_start_mask(struct mdp5_ctl *ctl)
{
	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);

@@ -265,7 +257,7 @@ int mdp5_ctl_set_encoder_state(struct mdp5_ctl *ctl, bool enabled)
		return -EINVAL;

	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)) {
		send_start_signal(ctl);
@@ -621,7 +613,6 @@ struct mdp5_ctl *mdp5_ctlm_request(struct mdp5_ctl_manager *ctl_mgr,

found:
	ctl = &ctl_mgr->ctls[c];
	ctl->pipeline.intf.num = intf_num;
	ctl->mixer = NULL;
	ctl->status |= CTL_STAT_BUSY;
	ctl->pending_ctl_trigger = 0;
+19 −18
Original line number Diff line number Diff line
@@ -109,7 +109,7 @@ static void mdp5_vid_encoder_mode_set(struct drm_encoder *encoder,
	struct mdp5_kms *mdp5_kms = get_kms(encoder);
	struct drm_device *dev = encoder->dev;
	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 display_v_start, display_v_end;
	uint32_t hsync_start_x, hsync_end_x;
@@ -130,7 +130,7 @@ static void mdp5_vid_encoder_mode_set(struct drm_encoder *encoder,
	ctrl_pol = 0;

	/* 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)
			ctrl_pol |= MDP5_INTF_POLARITY_CTL_HSYNC_LOW;
		if (mode->flags & DRM_MODE_FLAG_NVSYNC)
@@ -175,7 +175,7 @@ static void mdp5_vid_encoder_mode_set(struct drm_encoder *encoder,
	 * DISPLAY_V_START = (VBP * HCYCLE) + HBP
	 * 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_end -= mode->hsync_start - mode->hdisplay;
	}
@@ -206,7 +206,7 @@ static void mdp5_vid_encoder_mode_set(struct drm_encoder *encoder,

	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);
}

@@ -216,8 +216,8 @@ static void mdp5_vid_encoder_disable(struct drm_encoder *encoder)
	struct mdp5_kms *mdp5_kms = get_kms(encoder);
	struct mdp5_ctl *ctl = mdp5_encoder->ctl;
	struct mdp5_hw_mixer *mixer = mdp5_crtc_get_mixer(encoder->crtc);
	struct mdp5_interface *intf = &mdp5_encoder->intf;
	int intfn = mdp5_encoder->intf.num;
	struct mdp5_interface *intf = mdp5_encoder->intf;
	int intfn = mdp5_encoder->intf->num;
	unsigned long flags;

	if (WARN_ON(!mdp5_encoder->enabled))
@@ -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_kms *mdp5_kms = get_kms(encoder);
	struct mdp5_ctl *ctl = mdp5_encoder->ctl;
	struct mdp5_interface *intf = &mdp5_encoder->intf;
	int intfn = mdp5_encoder->intf.num;
	struct mdp5_interface *intf = mdp5_encoder->intf;
	int intfn = intf->num;
	unsigned long flags;

	if (WARN_ON(mdp5_encoder->enabled))
@@ -273,7 +273,7 @@ static void mdp5_encoder_mode_set(struct drm_encoder *encoder,
				  struct drm_display_mode *adjusted_mode)
{
	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)
		mdp5_cmd_encoder_mode_set(encoder, mode, adjusted_mode);
@@ -284,7 +284,7 @@ static void mdp5_encoder_mode_set(struct drm_encoder *encoder,
static void mdp5_encoder_disable(struct drm_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)
		mdp5_cmd_encoder_disable(encoder);
@@ -295,7 +295,7 @@ static void mdp5_encoder_disable(struct drm_encoder *encoder)
static void mdp5_encoder_enable(struct drm_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)
		mdp5_cmd_encoder_disable(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_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));
}
@@ -322,7 +322,7 @@ u32 mdp5_encoder_get_framecount(struct drm_encoder *encoder)
{
	struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(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));
}
@@ -340,7 +340,7 @@ int mdp5_vid_encoder_set_split_display(struct drm_encoder *encoder,
		return -EINVAL;

	mdp5_kms = get_kms(encoder);
	intf_num = mdp5_encoder->intf.num;
	intf_num = mdp5_encoder->intf->num;

	/* Switch slave encoder's TimingGen Sync mode,
	 * 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,
void mdp5_encoder_set_intf_mode(struct drm_encoder *encoder, bool cmd_mode)
{
	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 */
	if (cmd_mode) {
@@ -385,7 +385,8 @@ void mdp5_encoder_set_intf_mode(struct drm_encoder *encoder, bool cmd_mode)

/* initialize encoder */
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 mdp5_encoder *mdp5_encoder;
@@ -399,9 +400,9 @@ struct drm_encoder *mdp5_encoder_init(struct drm_device *dev,
		goto fail;
	}

	memcpy(&mdp5_encoder->intf, intf, sizeof(mdp5_encoder->intf));
	encoder = &mdp5_encoder->base;
	mdp5_encoder->ctl = ctl;
	mdp5_encoder->intf = intf;

	spin_lock_init(&mdp5_encoder->intf_lock);

+59 −26
Original line number Diff line number Diff line
@@ -271,19 +271,14 @@ int mdp5_enable(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 drm_device *dev = mdp5_kms->dev;
	struct msm_drm_private *priv = dev->dev_private;
	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)) {
		dev_err(dev->dev, "failed to construct encoder\n");
		return encoder;
@@ -312,32 +307,28 @@ static int get_dsi_id_from_intf(const struct mdp5_cfg_hw *hw_cfg, int intf_num)
	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 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 *ctl;
	struct drm_encoder *encoder;
	int ret = 0;

	switch (intf_type) {
	case INTF_DISABLED:
		break;
	switch (intf->type) {
	case INTF_eDP:
		if (!priv->edp)
			break;

		ctl = mdp5_ctlm_request(ctlm, intf_num);
		ctl = mdp5_ctlm_request(ctlm, intf->num);
		if (!ctl) {
			ret = -EINVAL;
			break;
		}

		encoder = construct_encoder(mdp5_kms, INTF_eDP, intf_num, ctl);
		encoder = construct_encoder(mdp5_kms, intf, ctl);
		if (IS_ERR(encoder)) {
			ret = PTR_ERR(encoder);
			break;
@@ -349,13 +340,13 @@ static int modeset_init_intf(struct mdp5_kms *mdp5_kms, int intf_num)
		if (!priv->hdmi)
			break;

		ctl = mdp5_ctlm_request(ctlm, intf_num);
		ctl = mdp5_ctlm_request(ctlm, intf->num);
		if (!ctl) {
			ret = -EINVAL;
			break;
		}

		encoder = construct_encoder(mdp5_kms, INTF_HDMI, intf_num, ctl);
		encoder = construct_encoder(mdp5_kms, intf, ctl);
		if (IS_ERR(encoder)) {
			ret = PTR_ERR(encoder);
			break;
@@ -365,11 +356,13 @@ static int modeset_init_intf(struct mdp5_kms *mdp5_kms, int intf_num)
		break;
	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)) {
			dev_err(dev->dev, "failed to find dsi from intf %d\n",
				intf_num);
				intf->num);
			ret = -EINVAL;
			break;
		}
@@ -377,13 +370,13 @@ static int modeset_init_intf(struct mdp5_kms *mdp5_kms, int intf_num)
		if (!priv->dsi[dsi_id])
			break;

		ctl = mdp5_ctlm_request(ctlm, intf_num);
		ctl = mdp5_ctlm_request(ctlm, intf->num);
		if (!ctl) {
			ret = -EINVAL;
			break;
		}

		encoder = construct_encoder(mdp5_kms, INTF_DSI, intf_num, ctl);
		encoder = construct_encoder(mdp5_kms, intf, ctl);
		if (IS_ERR(encoder)) {
			ret = PTR_ERR(encoder);
			break;
@@ -393,7 +386,7 @@ static int modeset_init_intf(struct mdp5_kms *mdp5_kms, int intf_num)
		break;
	}
	default:
		dev_err(dev->dev, "unknown intf: %d\n", intf_type);
		dev_err(dev->dev, "unknown intf: %d\n", intf->type);
		ret = -EINVAL;
		break;
	}
@@ -417,8 +410,8 @@ static int modeset_init(struct mdp5_kms *mdp5_kms)
	 * Construct encoders and modeset initialize connector devices
	 * for each external display interface.
	 */
	for (i = 0; i < ARRAY_SIZE(hw_cfg->intf.connect); i++) {
		ret = modeset_init_intf(mdp5_kms, i);
	for (i = 0; i < mdp5_kms->num_intfs; i++) {
		ret = modeset_init_intf(mdp5_kms, mdp5_kms->intfs[i]);
		if (ret)
			goto fail;
	}
@@ -747,6 +740,7 @@ fail:
static void mdp5_destroy(struct platform_device *pdev)
{
	struct mdp5_kms *mdp5_kms = platform_get_drvdata(pdev);
	int i;

	if (mdp5_kms->ctlm)
		mdp5_ctlm_destroy(mdp5_kms->ctlm);
@@ -755,6 +749,9 @@ static void mdp5_destroy(struct platform_device *pdev)
	if (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)
		pm_runtime_disable(&pdev->dev);

@@ -862,6 +859,38 @@ static int hwmixer_init(struct mdp5_kms *mdp5_kms)
	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)
{
	struct msm_drm_private *priv = dev->dev_private;
@@ -966,6 +995,10 @@ static int mdp5_init(struct platform_device *pdev, struct drm_device *dev)
	if (ret)
		goto fail;

	ret = interface_init(mdp5_kms);
	if (ret)
		goto fail;

	/* set uninit-ed kms */
	priv->kms = &mdp5_kms->base.base;

+5 −1
Original line number Diff line number Diff line
@@ -43,6 +43,9 @@ struct mdp5_kms {
	unsigned num_hwmixers;
	struct mdp5_hw_mixer *hwmixers[8];

	unsigned num_intfs;
	struct mdp5_interface *intfs[5];

	struct mdp5_cfg_handler *cfg;
	uint32_t caps;	/* MDP capabilities (MDP_CAP_XXX bits) */

@@ -125,6 +128,7 @@ enum mdp5_intf_mode {
};

struct mdp5_interface {
	int idx;
	int num; /* display interface number */
	enum mdp5_intf_type type;
	enum mdp5_intf_mode mode;
@@ -132,11 +136,11 @@ struct mdp5_interface {

struct mdp5_encoder {
	struct drm_encoder base;
	struct mdp5_interface intf;
	spinlock_t intf_lock;	/* protect REG_MDP5_INTF_* registers */
	bool enabled;
	uint32_t bsc;

	struct mdp5_interface *intf;
	struct mdp5_ctl *ctl;
};
#define to_mdp5_encoder(x) container_of(x, struct mdp5_encoder, base)