[PATCH] drm/msm: Refactor msm drm driver by introducing msm_drm_sub_dev

jilaiw at codeaurora.org jilaiw at codeaurora.org
Tue Mar 24 09:13:54 PDT 2015


> On Tue, Mar 24, 2015 at 11:18 AM,  <jilaiw at codeaurora.org> wrote:
>>
>>> On Thu, Mar 12, 2015 at 4:48 PM, Jilai Wang <jilaiw at codeaurora.org>
>>> 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 at codeaurora.org>
>>>> ---
>>>>  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.
>
>
> What I meant is that it adds more lines of code than it removes.. for
> refactoring/cleanup type things, I'd generally prefer things that work
> out the other way around (removing more lines than they add)..
> Anyways, if I drop this patch, I'll rebase the DSI patches.. that is
> fine.
>
> By the time I get DSI also working on mdp4, it might get to the point
> where this sort of change actually removes more lines than it adds, so
> that might be the time to revisit.  We may also be able to simplify it
> a bit..  I'm still thinking about it, I haven't completely decided
> yet.
ok.
>
> BR,
> -R
>
>
>>>
>>> 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 at gmail.com>
>>>>   *
>>>> @@ -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
>>>>
>>>
>>
>>
>




More information about the dri-devel mailing list