Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

drm/msm/mdp4: Clean up modeset_init



modeset_init() for mdp4 isn't very flexible. That makes it hard to add
more interfaces.

Split out the encoder/connector creation code in modeset_init into a
separate function. This is similar to what's done in modeset_init for
mdp5.

Signed-off-by: default avatarArchit Taneja <architt@codeaurora.org>
Signed-off-by: default avatarRob Clark <robdclark@gmail.com>
parent 66a42f85
Loading
Loading
Loading
Loading
+109 −83
Original line number Diff line number Diff line
@@ -270,117 +270,143 @@ static struct drm_panel *detect_panel(struct drm_device *dev)
	return panel;
}

static int modeset_init(struct mdp4_kms *mdp4_kms)
static int mdp4_modeset_init_intf(struct mdp4_kms *mdp4_kms,
				  int intf_type)
{
	struct drm_device *dev = mdp4_kms->dev;
	struct msm_drm_private *priv = dev->dev_private;
	struct drm_plane *plane;
	struct drm_crtc *crtc;
	struct drm_encoder *encoder;
	struct drm_connector *connector;
	struct drm_panel *panel;
	int ret;

	/* construct non-private planes: */
	plane = mdp4_plane_init(dev, VG1, false);
	if (IS_ERR(plane)) {
		dev_err(dev->dev, "failed to construct plane for VG1\n");
		ret = PTR_ERR(plane);
		goto fail;
	}
	priv->planes[priv->num_planes++] = plane;

	plane = mdp4_plane_init(dev, VG2, false);
	if (IS_ERR(plane)) {
		dev_err(dev->dev, "failed to construct plane for VG2\n");
		ret = PTR_ERR(plane);
		goto fail;
	}
	priv->planes[priv->num_planes++] = plane;

	/*
	 * Setup the LCDC/LVDS path: RGB2 -> DMA_P -> LCDC -> LVDS:
	 */

	switch (intf_type) {
	case DRM_MODE_ENCODER_LVDS:
		panel = detect_panel(dev);
		if (IS_ERR(panel)) {
		ret = PTR_ERR(panel);
		dev_err(dev->dev, "failed to detect LVDS panel: %d\n", ret);
		goto fail;
			dev_err(dev->dev, "failed to detect LVDS panel\n");
			return PTR_ERR(panel);
		}

	plane = mdp4_plane_init(dev, RGB2, true);
	if (IS_ERR(plane)) {
		dev_err(dev->dev, "failed to construct plane for RGB2\n");
		ret = PTR_ERR(plane);
		goto fail;
		encoder = mdp4_lcdc_encoder_init(dev, panel);
		if (IS_ERR(encoder)) {
			dev_err(dev->dev, "failed to construct LCDC encoder\n");
			return PTR_ERR(encoder);
		}

	crtc  = mdp4_crtc_init(dev, plane, priv->num_crtcs, 0, DMA_P);
	if (IS_ERR(crtc)) {
		dev_err(dev->dev, "failed to construct crtc for DMA_P\n");
		ret = PTR_ERR(crtc);
		goto fail;
		/* LCDC can be hooked to DMA_P (TODO: Add DMA_S later?) */
		encoder->possible_crtcs = 1 << DMA_P;

		connector = mdp4_lvds_connector_init(dev, panel, encoder);
		if (IS_ERR(connector)) {
			dev_err(dev->dev, "failed to initialize LVDS connector\n");
			return PTR_ERR(connector);
		}

	encoder = mdp4_lcdc_encoder_init(dev, panel);
		priv->encoders[priv->num_encoders++] = encoder;
		priv->connectors[priv->num_connectors++] = connector;

		break;
	case DRM_MODE_ENCODER_TMDS:
		encoder = mdp4_dtv_encoder_init(dev);
		if (IS_ERR(encoder)) {
		dev_err(dev->dev, "failed to construct LCDC encoder\n");
		ret = PTR_ERR(encoder);
		goto fail;
			dev_err(dev->dev, "failed to construct DTV encoder\n");
			return PTR_ERR(encoder);
		}

	/* LCDC can be hooked to DMA_P: */
	encoder->possible_crtcs = 1 << priv->num_crtcs;
		/* DTV can be hooked to DMA_E: */
		encoder->possible_crtcs = 1 << 1;

		if (priv->hdmi) {
			/* Construct bridge/connector for HDMI: */
			ret = hdmi_modeset_init(priv->hdmi, dev, encoder);
			if (ret) {
				dev_err(dev->dev, "failed to initialize HDMI: %d\n", ret);
				return ret;
			}
		}

	priv->crtcs[priv->num_crtcs++] = crtc;
		priv->encoders[priv->num_encoders++] = encoder;

	connector = mdp4_lvds_connector_init(dev, panel, encoder);
	if (IS_ERR(connector)) {
		ret = PTR_ERR(connector);
		dev_err(dev->dev, "failed to initialize LVDS connector: %d\n", ret);
		goto fail;
		break;
	default:
		dev_err(dev->dev, "Invalid or unsupported interface\n");
		return -EINVAL;
	}

	priv->connectors[priv->num_connectors++] = connector;

	/*
	 * Setup DTV/HDMI path: RGB1 -> DMA_E -> DTV -> HDMI:
	 */
	return 0;
}

static int modeset_init(struct mdp4_kms *mdp4_kms)
{
	struct drm_device *dev = mdp4_kms->dev;
	struct msm_drm_private *priv = dev->dev_private;
	struct drm_plane *plane;
	struct drm_crtc *crtc;
	int i, ret;
	static const enum mdp4_pipe rgb_planes[] = {
		RGB1, RGB2,
	};
	static const enum mdp4_pipe vg_planes[] = {
		VG1, VG2,
	};
	static const enum mdp4_dma mdp4_crtcs[] = {
		DMA_P, DMA_E,
	};
	static const char * const mdp4_crtc_names[] = {
		"DMA_P", "DMA_E",
	};
	static const int mdp4_intfs[] = {
		DRM_MODE_ENCODER_LVDS,
		DRM_MODE_ENCODER_TMDS,
	};

	/* construct non-private planes: */
	for (i = 0; i < ARRAY_SIZE(vg_planes); i++) {
		plane = mdp4_plane_init(dev, vg_planes[i], false);
		if (IS_ERR(plane)) {
			dev_err(dev->dev,
				"failed to construct plane for VG%d\n", i + 1);
			ret = PTR_ERR(plane);
			goto fail;
		}
		priv->planes[priv->num_planes++] = plane;
	}

	plane = mdp4_plane_init(dev, RGB1, true);
	for (i = 0; i < ARRAY_SIZE(mdp4_crtcs); i++) {
		plane = mdp4_plane_init(dev, rgb_planes[i], true);
		if (IS_ERR(plane)) {
		dev_err(dev->dev, "failed to construct plane for RGB1\n");
			dev_err(dev->dev,
				"failed to construct plane for RGB%d\n", i + 1);
			ret = PTR_ERR(plane);
			goto fail;
		}

	crtc  = mdp4_crtc_init(dev, plane, priv->num_crtcs, 1, DMA_E);
		crtc  = mdp4_crtc_init(dev, plane, priv->num_crtcs, i,
				mdp4_crtcs[i]);
		if (IS_ERR(crtc)) {
		dev_err(dev->dev, "failed to construct crtc for DMA_E\n");
			dev_err(dev->dev, "failed to construct crtc for %s\n",
				mdp4_crtc_names[i]);
			ret = PTR_ERR(crtc);
			goto fail;
		}

	encoder = mdp4_dtv_encoder_init(dev);
	if (IS_ERR(encoder)) {
		dev_err(dev->dev, "failed to construct DTV encoder\n");
		ret = PTR_ERR(encoder);
		goto fail;
		priv->crtcs[priv->num_crtcs++] = crtc;
	}

	/* DTV can be hooked to DMA_E: */
	encoder->possible_crtcs = 1 << priv->num_crtcs;

	priv->crtcs[priv->num_crtcs++] = crtc;
	priv->encoders[priv->num_encoders++] = encoder;
	/*
	 * we currently set up two relatively fixed paths:
	 *
	 * LCDC/LVDS path: RGB1 -> DMA_P -> LCDC -> LVDS
	 * DTV/HDMI path: RGB2 -> DMA_E -> DTV -> HDMI
	 */

	if (priv->hdmi) {
		/* Construct bridge/connector for HDMI: */
		ret = hdmi_modeset_init(priv->hdmi, dev, encoder);
	for (i = 0; i < ARRAY_SIZE(mdp4_intfs); i++) {
		ret = mdp4_modeset_init_intf(mdp4_kms, mdp4_intfs[i]);
		if (ret) {
			dev_err(dev->dev, "failed to initialize HDMI: %d\n", ret);
			dev_err(dev->dev, "failed to initialize intf: %d, %d\n",
				i, ret);
			goto fail;
		}
	}