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; struct mdp5_ctl_manager *ctlm = mdp5_kms->ctlm; struct mdp5_ctl *ctl; struct drm_encoder *encoder; int ret = 0; switch (intf->type) { case INTF_eDP: if (!priv->edp) break; ctl = mdp5_ctlm_request(ctlm, intf->num); if (!ctl) { ret = -EINVAL; break; } encoder = construct_encoder(mdp5_kms, intf, ctl); if (IS_ERR(encoder)) { ret = PTR_ERR(encoder); break; } ret = msm_edp_modeset_init(priv->edp, dev, encoder); break; case INTF_HDMI: if (!priv->hdmi) break; ctl = mdp5_ctlm_request(ctlm, intf->num); if (!ctl) { ret = -EINVAL; break; } encoder = construct_encoder(mdp5_kms, intf, ctl); if (IS_ERR(encoder)) { ret = PTR_ERR(encoder); break; } ret = msm_hdmi_modeset_init(priv->hdmi, dev, encoder); break; case INTF_DSI: { 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); ret = -EINVAL; break; } if (!priv->dsi[dsi_id]) break; ctl = mdp5_ctlm_request(ctlm, intf->num); if (!ctl) { ret = -EINVAL; break; } encoder = construct_encoder(mdp5_kms, intf, ctl); if (IS_ERR(encoder)) { ret = PTR_ERR(encoder); break; } ret = msm_dsi_modeset_init(priv->dsi[dsi_id], dev, encoder); break; } default: dev_err(dev->dev, "unknown intf: %d\n", intf->type); ret = -EINVAL; break; } return ret; }
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_encoder *encoder; struct drm_connector *connector; struct device_node *panel_node; int dsi_id; int ret; switch (intf_type) { case DRM_MODE_ENCODER_LVDS: /* * bail out early if there is no panel node (no need to * initialize LCDC encoder and LVDS connector) */ panel_node = of_graph_get_remote_node(dev->dev->of_node, 0, 0); if (!panel_node) return 0; encoder = mdp4_lcdc_encoder_init(dev, panel_node); if (IS_ERR(encoder)) { dev_err(dev->dev, "failed to construct LCDC encoder\n"); return PTR_ERR(encoder); } /* 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_node, encoder); if (IS_ERR(connector)) { dev_err(dev->dev, "failed to initialize LVDS connector\n"); return PTR_ERR(connector); } 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 DTV encoder\n"); return PTR_ERR(encoder); } /* DTV can be hooked to DMA_E: */ encoder->possible_crtcs = 1 << 1; if (priv->hdmi) { /* Construct bridge/connector for HDMI: */ ret = msm_hdmi_modeset_init(priv->hdmi, dev, encoder); if (ret) { dev_err(dev->dev, "failed to initialize HDMI: %d\n", ret); return ret; } } priv->encoders[priv->num_encoders++] = encoder; break; case DRM_MODE_ENCODER_DSI: /* only DSI1 supported for now */ dsi_id = 0; if (!priv->dsi[dsi_id]) break; encoder = mdp4_dsi_encoder_init(dev); if (IS_ERR(encoder)) { ret = PTR_ERR(encoder); dev_err(dev->dev, "failed to construct DSI encoder: %d\n", ret); return ret; } /* TODO: Add DMA_S later? */ encoder->possible_crtcs = 1 << DMA_P; priv->encoders[priv->num_encoders++] = encoder; ret = msm_dsi_modeset_init(priv->dsi[dsi_id], dev, encoder); if (ret) { dev_err(dev->dev, "failed to initialize DSI: %d\n", ret); return ret; } break; default: dev_err(dev->dev, "Invalid or unsupported interface\n"); return -EINVAL; } return 0; }
static int modeset_init_intf(struct mdp5_kms *mdp5_kms, int intf_num) { 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->intfs[intf_num]; struct drm_encoder *encoder; int ret = 0; switch (intf_type) { case INTF_DISABLED: break; case INTF_eDP: if (!priv->edp) break; encoder = construct_encoder(mdp5_kms, INTF_eDP, intf_num, MDP5_INTF_MODE_NONE); if (IS_ERR(encoder)) { ret = PTR_ERR(encoder); break; } ret = msm_edp_modeset_init(priv->edp, dev, encoder); break; case INTF_HDMI: if (!priv->hdmi) break; encoder = construct_encoder(mdp5_kms, INTF_HDMI, intf_num, MDP5_INTF_MODE_NONE); if (IS_ERR(encoder)) { ret = PTR_ERR(encoder); break; } ret = hdmi_modeset_init(priv->hdmi, dev, encoder); break; case INTF_DSI: { int dsi_id = get_dsi_id_from_intf(hw_cfg, intf_num); struct drm_encoder *dsi_encs[MSM_DSI_ENCODER_NUM]; enum mdp5_intf_mode mode; int i; if ((dsi_id >= ARRAY_SIZE(priv->dsi)) || (dsi_id < 0)) { dev_err(dev->dev, "failed to find dsi from intf %d\n", intf_num); ret = -EINVAL; break; } if (!priv->dsi[dsi_id]) break; for (i = 0; i < MSM_DSI_ENCODER_NUM; i++) { mode = (i == MSM_DSI_CMD_ENCODER_ID) ? MDP5_INTF_DSI_MODE_COMMAND : MDP5_INTF_DSI_MODE_VIDEO; dsi_encs[i] = construct_encoder(mdp5_kms, INTF_DSI, intf_num, mode); if (IS_ERR(dsi_encs)) { ret = PTR_ERR(dsi_encs); break; } } ret = msm_dsi_modeset_init(priv->dsi[dsi_id], dev, dsi_encs); break; } default: dev_err(dev->dev, "unknown intf: %d\n", intf_type); ret = -EINVAL; break; } return ret; }