drm/msm/mdp5: Clean up interface assignment
authorArchit Taneja <architt@codeaurora.org>
Thu, 23 Mar 2017 10:27:59 +0000 (15:57 +0530)
committerRob Clark <robdclark@gmail.com>
Sat, 8 Apr 2017 10:59:33 +0000 (06:59 -0400)
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: Archit Taneja <architt@codeaurora.org>
Signed-off-by: Rob Clark <robdclark@gmail.com>
drivers/gpu/drm/msm/mdp/mdp5/mdp5_cmd_encoder.c
drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.c
drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c
drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h

index fd3cb45976f3492a8c90dd48e9914ebfa7bc169d..18c967107bc4524d9540358c37528ef25bdbe8ec 100644 (file)
@@ -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
index fa4f27a1a55145a11cfd5960aab57f879acc96f3..ed184e5491b441f2ab3bc0e4c33bcefb5a97e564 100644 (file)
@@ -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;
index c2c204e6ea3bc5f7d59a23a1f21af38900a37c99..2994841eb00c78e1ced15476155f988689d855bb 100644 (file)
@@ -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,8 +206,8 @@ 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_encoder->ctl);
+       mdp5_crtc_set_pipeline(encoder->crtc, mdp5_encoder->intf,
+                              mdp5_encoder->ctl);
 }
 
 static void mdp5_vid_encoder_disable(struct drm_encoder *encoder)
@@ -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);
 
index e8174d4847b0d9e062b8bfa4775450d4d9e23ee4..9d855ee0c0a4270c362c22902bb56d13cadd9a5b 100644 (file)
@@ -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_ctl *ctl)
+                                            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;
 
index 5a1ce871f5eb144a05dc03ad8e46e78deff56271..cf821971793df073a5be6b276837f0b2f2f64fa7 100644 (file)
@@ -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)