> On Thu, Mar 12, 2015 at 4:48 PM, Jilai Wang <jilaiw@xxxxxxxxxxxxxx> wrote: >> Introduce msm_drm_sub_dev for each mdp interface component such as >> HDMI/eDP/DSI to contain common information shared with MDP. >> >> Signed-off-by: Jilai Wang <jilaiw@xxxxxxxxxxxxxx> >> --- >> drivers/gpu/drm/msm/edp/edp.c | 18 +++++++++-- >> drivers/gpu/drm/msm/edp/edp.h | 1 + >> drivers/gpu/drm/msm/hdmi/hdmi.c | 22 ++++++++++--- >> drivers/gpu/drm/msm/hdmi/hdmi.h | 1 + >> drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c | 3 +- >> drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | 56 >> ++++++++++++++++----------------- >> drivers/gpu/drm/msm/msm_drv.h | 23 +++++++++----- >> 7 files changed, 80 insertions(+), 44 deletions(-) > > So a couple comments.. > > 1) I kinda prefer having some to_hdmi/to_edp/etc macros rather than > just open coding container_of().. I guess kind of a minor thing, but > it keeps things consistent with how "inheritance" is handled elsewhere > (like to_mdp5_crtc(), etc) > > 2) I'd be a bit more enthused by this when it actually results in a > negative diffstat, rather than a positive one. Not saying it isn't > something we should do at some point, but at this point I'm leaning > towards rebasing the DSI patcheset to not depend on this for now. Actually most of the negative diffstat is in mdp5_kms.c which moves the modeset_init out of construct encoder. And it is required by DSI change. > > BR, > -R > >> >> diff --git a/drivers/gpu/drm/msm/edp/edp.c >> b/drivers/gpu/drm/msm/edp/edp.c >> index 0940e84..8d8b7e9 100644 >> --- a/drivers/gpu/drm/msm/edp/edp.c >> +++ b/drivers/gpu/drm/msm/edp/edp.c >> @@ -14,6 +14,9 @@ >> #include <linux/of_irq.h> >> #include "edp.h" >> >> +static int msm_edp_modeset_init(struct msm_drm_sub_dev *base, >> + struct drm_device *dev); >> + >> static irqreturn_t edp_irq(int irq, void *dev_id) >> { >> struct msm_edp *edp = dev_id; >> @@ -63,6 +66,8 @@ static struct msm_edp *edp_init(struct platform_device >> *pdev) >> if (ret) >> goto fail; >> >> + edp->base.modeset_init = msm_edp_modeset_init; >> + >> return edp; >> >> fail: >> @@ -82,7 +87,8 @@ static int edp_bind(struct device *dev, struct device >> *master, void *data) >> edp = edp_init(to_platform_device(dev)); >> if (IS_ERR(edp)) >> return PTR_ERR(edp); >> - priv->edp = edp; >> + >> + priv->edp = &edp->base; >> >> return 0; >> } >> @@ -144,13 +150,19 @@ void __exit msm_edp_unregister(void) >> } >> >> /* Second part of initialization, the drm/kms level modeset_init */ >> -int msm_edp_modeset_init(struct msm_edp *edp, struct drm_device *dev, >> - struct drm_encoder *encoder) >> +static int msm_edp_modeset_init(struct msm_drm_sub_dev *base, >> + struct drm_device *dev) >> { >> + struct msm_edp *edp = container_of(base, struct msm_edp, base); >> struct platform_device *pdev = edp->pdev; >> struct msm_drm_private *priv = dev->dev_private; >> + struct drm_encoder *encoder; >> int ret; >> >> + if (WARN_ON(base->num_encoders != 1)) >> + return -EINVAL; >> + >> + encoder = base->encoders[0]; >> edp->encoder = encoder; >> edp->dev = dev; >> >> diff --git a/drivers/gpu/drm/msm/edp/edp.h >> b/drivers/gpu/drm/msm/edp/edp.h >> index ba5bedd..00eff68 100644 >> --- a/drivers/gpu/drm/msm/edp/edp.h >> +++ b/drivers/gpu/drm/msm/edp/edp.h >> @@ -31,6 +31,7 @@ struct edp_aux; >> struct edp_phy; >> >> struct msm_edp { >> + struct msm_drm_sub_dev base; >> struct drm_device *dev; >> struct platform_device *pdev; >> >> diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c >> b/drivers/gpu/drm/msm/hdmi/hdmi.c >> index 9a8a825..9e886ec 100644 >> --- a/drivers/gpu/drm/msm/hdmi/hdmi.c >> +++ b/drivers/gpu/drm/msm/hdmi/hdmi.c >> @@ -19,6 +19,9 @@ >> #include <linux/of_irq.h> >> #include "hdmi.h" >> >> +static int hdmi_modeset_init(struct msm_drm_sub_dev *base, >> + struct drm_device *dev); >> + >> void hdmi_set_mode(struct hdmi *hdmi, bool power_on) >> { >> uint32_t ctrl = 0; >> @@ -197,6 +200,8 @@ static struct hdmi *hdmi_init(struct platform_device >> *pdev) >> goto fail; >> } >> >> + hdmi->base.modeset_init = hdmi_modeset_init; >> + >> return hdmi; >> >> fail: >> @@ -214,13 +219,19 @@ fail: >> * should be handled in hdmi_init() so that failure happens from >> * hdmi sub-device's probe. >> */ >> -int hdmi_modeset_init(struct hdmi *hdmi, >> - struct drm_device *dev, struct drm_encoder *encoder) >> +static int hdmi_modeset_init(struct msm_drm_sub_dev *base, >> + struct drm_device *dev) >> { >> + struct hdmi *hdmi = container_of(base, struct hdmi, base); >> struct msm_drm_private *priv = dev->dev_private; >> struct platform_device *pdev = hdmi->pdev; >> + struct drm_encoder *encoder; >> int ret; >> >> + if (WARN_ON(base->num_encoders != 1)) >> + return -EINVAL; >> + >> + encoder = base->encoders[0]; >> hdmi->dev = dev; >> hdmi->encoder = encoder; >> >> @@ -439,7 +450,8 @@ static int hdmi_bind(struct device *dev, struct >> device *master, void *data) >> hdmi = hdmi_init(to_platform_device(dev)); >> if (IS_ERR(hdmi)) >> return PTR_ERR(hdmi); >> - priv->hdmi = hdmi; >> + >> + priv->hdmi = &hdmi->base; >> >> return 0; >> } >> @@ -449,8 +461,10 @@ static void hdmi_unbind(struct device *dev, struct >> device *master, >> { >> struct drm_device *drm = dev_get_drvdata(master); >> struct msm_drm_private *priv = drm->dev_private; >> + >> if (priv->hdmi) { >> - hdmi_destroy(priv->hdmi); >> + struct hdmi *hdmi = container_of(priv->hdmi, struct >> hdmi, base); >> + hdmi_destroy(hdmi); >> priv->hdmi = NULL; >> } >> } >> diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.h >> b/drivers/gpu/drm/msm/hdmi/hdmi.h >> index 68fdfb3..a1d4595 100644 >> --- a/drivers/gpu/drm/msm/hdmi/hdmi.h >> +++ b/drivers/gpu/drm/msm/hdmi/hdmi.h >> @@ -38,6 +38,7 @@ struct hdmi_audio { >> }; >> >> struct hdmi { >> + struct msm_drm_sub_dev base; >> struct drm_device *dev; >> struct platform_device *pdev; >> >> diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c >> b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c >> index 24c38d4..02426ba 100644 >> --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c >> +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c >> @@ -370,7 +370,8 @@ static int modeset_init(struct mdp4_kms *mdp4_kms) >> >> if (priv->hdmi) { >> /* Construct bridge/connector for HDMI: */ >> - ret = hdmi_modeset_init(priv->hdmi, dev, encoder); >> + priv->hdmi->encoders[priv->hdmi->num_encoders++] = >> encoder; >> + ret = priv->hdmi->modeset_init(priv->hdmi, dev); >> if (ret) { >> dev_err(dev->dev, "failed to initialize HDMI: >> %d\n", ret); >> goto fail; >> diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c >> b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c >> index 84168bf..ae336ec 100644 >> --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c >> +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c >> @@ -1,5 +1,5 @@ >> /* >> - * Copyright (c) 2014, The Linux Foundation. All rights reserved. >> + * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. >> * Copyright (C) 2013 Red Hat >> * Author: Rob Clark <robdclark@xxxxxxxxx> >> * >> @@ -166,8 +166,9 @@ int mdp5_enable(struct mdp5_kms *mdp5_kms) >> return 0; >> } >> >> -static int construct_encoder(struct mdp5_kms *mdp5_kms, >> - enum mdp5_intf_type intf_type, int intf_num) >> +static struct drm_encoder *construct_encoder(struct mdp5_kms *mdp5_kms, >> + enum mdp5_intf_type intf_type, int intf_num, >> + enum mdp5_intf_mode intf_mode) >> { >> struct drm_device *dev = mdp5_kms->dev; >> struct msm_drm_private *priv = dev->dev_private; >> @@ -175,33 +176,19 @@ static int construct_encoder(struct mdp5_kms >> *mdp5_kms, >> struct mdp5_interface intf = { >> .num = intf_num, >> .type = intf_type, >> - .mode = MDP5_INTF_MODE_NONE, >> + .mode = intf_mode, >> }; >> - int ret = 0; >> >> encoder = mdp5_encoder_init(dev, &intf); >> if (IS_ERR(encoder)) { >> - ret = PTR_ERR(encoder); >> - dev_err(dev->dev, "failed to construct encoder: %d\n", >> ret); >> - return ret; >> + dev_err(dev->dev, "failed to construct encoder\n"); >> + return encoder; >> } >> >> encoder->possible_crtcs = (1 << priv->num_crtcs) - 1; >> priv->encoders[priv->num_encoders++] = encoder; >> >> - if (intf_type == INTF_HDMI) { >> - ret = hdmi_modeset_init(priv->hdmi, dev, encoder); >> - if (ret) >> - dev_err(dev->dev, "failed to init HDMI: %d\n", >> ret); >> - >> - } else if (intf_type == INTF_eDP) { >> - /* Construct bridge/connector for eDP: */ >> - ret = msm_edp_modeset_init(priv->edp, dev, encoder); >> - if (ret) >> - dev_err(dev->dev, "failed to init eDP: %d\n", >> ret); >> - } >> - >> - return ret; >> + return encoder; >> } >> >> static int modeset_init(struct mdp5_kms *mdp5_kms) >> @@ -267,26 +254,39 @@ static int modeset_init(struct mdp5_kms *mdp5_kms) >> /* Construct external display interfaces' encoders: */ >> for (i = 0; i < ARRAY_SIZE(hw_cfg->intfs); i++) { >> enum mdp5_intf_type intf_type = hw_cfg->intfs[i]; >> + enum mdp5_intf_mode intf_mode = MDP5_INTF_MODE_NONE; >> + struct msm_drm_sub_dev *sub_dev; >> + struct drm_encoder *encoder; >> >> switch (intf_type) { >> case INTF_DISABLED: >> + sub_dev = NULL; >> break; >> case INTF_eDP: >> - if (priv->edp) >> - ret = construct_encoder(mdp5_kms, >> INTF_eDP, i); >> + sub_dev = priv->edp; >> break; >> case INTF_HDMI: >> - if (priv->hdmi) >> - ret = construct_encoder(mdp5_kms, >> INTF_HDMI, i); >> + sub_dev = priv->hdmi; >> break; >> default: >> dev_err(dev->dev, "unknown intf: %d\n", >> intf_type); >> ret = -EINVAL; >> - break; >> + goto fail; >> } >> >> - if (ret) >> - goto fail; >> + if (sub_dev) { >> + encoder = construct_encoder(mdp5_kms, intf_type, >> + i, intf_mode); >> + if (IS_ERR(encoder)) { >> + ret = PTR_ERR(encoder); >> + goto fail; >> + } >> + >> + sub_dev->encoders[sub_dev->num_encoders++] = >> encoder; >> + ret = sub_dev->modeset_init(sub_dev, dev); >> + if (ret) >> + goto fail; >> + } >> } >> >> return 0; >> diff --git a/drivers/gpu/drm/msm/msm_drv.h >> b/drivers/gpu/drm/msm/msm_drv.h >> index 9e8d441..7b464db 100644 >> --- a/drivers/gpu/drm/msm/msm_drv.h >> +++ b/drivers/gpu/drm/msm/msm_drv.h >> @@ -64,6 +64,19 @@ struct msm_file_private { >> int dummy; >> }; >> >> +/* A base data structure for all MDP sub devices */ >> +struct msm_drm_sub_dev { >> + /* >> + * the encoders can be used by sub dev, >> + * must be set before modeset_init >> + */ >> + unsigned int num_encoders; >> + struct drm_encoder *encoders[8]; >> + >> + int (*modeset_init)(struct msm_drm_sub_dev *base, >> + struct drm_device *dev); >> +}; >> + >> struct msm_drm_private { >> >> struct msm_kms *kms; >> @@ -74,13 +87,13 @@ struct msm_drm_private { >> /* possibly this should be in the kms component, but it is >> * shared by both mdp4 and mdp5.. >> */ >> - struct hdmi *hdmi; >> + struct msm_drm_sub_dev *hdmi; >> >> /* eDP is for mdp5 only, but kms has not been created >> * when edp_bind() and edp_init() are called. Here is the only >> * place to keep the edp instance. >> */ >> - struct msm_edp *edp; >> + struct msm_drm_sub_dev *edp; >> >> /* when we have more than one 'msm_gpu' these need to be an >> array: */ >> struct msm_gpu *gpu; >> @@ -224,17 +237,11 @@ struct drm_framebuffer >> *msm_framebuffer_create(struct drm_device *dev, >> >> struct drm_fb_helper *msm_fbdev_init(struct drm_device *dev); >> >> -struct hdmi; >> -int hdmi_modeset_init(struct hdmi *hdmi, struct drm_device *dev, >> - struct drm_encoder *encoder); >> void __init hdmi_register(void); >> void __exit hdmi_unregister(void); >> >> -struct msm_edp; >> void __init msm_edp_register(void); >> void __exit msm_edp_unregister(void); >> -int msm_edp_modeset_init(struct msm_edp *edp, struct drm_device *dev, >> - struct drm_encoder *encoder); >> >> #ifdef CONFIG_DEBUG_FS >> void msm_gem_describe(struct drm_gem_object *obj, struct seq_file *m); >> -- >> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora >> Forum, >> a Linux Foundation Collaborative Project >> > _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel