drm/msm/mdp5: Basic support for MDP5 v1.7 (MSM8996)
authorStephane Viau <sviau@codeaurora.org>
Tue, 15 Sep 2015 12:41:53 +0000 (08:41 -0400)
committerRob Clark <robdclark@gmail.com>
Thu, 22 Oct 2015 19:39:57 +0000 (15:39 -0400)
This change adds the basic MDP5 support for MSM8996.

Signed-off-by: Stephane Viau <sviau@codeaurora.org>
Signed-off-by: Rob Clark <robdclark@gmail.com>
drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c
drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h
drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h
drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c
drivers/gpu/drm/msm/mdp/mdp_kms.h

index a1e26f23c7cca53a19f2ad557a1cdb01b4c4a646..bb1225aa2f75b8ef9f7ee7deb96a47903406fd63 100644 (file)
@@ -27,6 +27,8 @@ const struct mdp5_cfg_hw msm8x74v1_config = {
        .mdp = {
                .count = 1,
                .base = { 0x00100 },
+               .caps = MDP_CAP_SMP |
+                       0,
        },
        .smp = {
                .mmb_count = 22,
@@ -96,6 +98,8 @@ const struct mdp5_cfg_hw msm8x74v2_config = {
        .mdp = {
                .count = 1,
                .base = { 0x00100 },
+               .caps = MDP_CAP_SMP |
+                       0,
        },
        .smp = {
                .mmb_count = 22,
@@ -165,6 +169,8 @@ const struct mdp5_cfg_hw apq8084_config = {
        .mdp = {
                .count = 1,
                .base = { 0x00100 },
+               .caps = MDP_CAP_SMP |
+                       0,
        },
        .smp = {
                .mmb_count = 44,
@@ -242,6 +248,8 @@ const struct mdp5_cfg_hw msm8x16_config = {
        .mdp = {
                .count = 1,
                .base = { 0x01000 },
+               .caps = MDP_CAP_SMP |
+                       0,
        },
        .smp = {
                .mmb_count = 8,
@@ -301,6 +309,8 @@ const struct mdp5_cfg_hw msm8x94_config = {
        .mdp = {
                .count = 1,
                .base = { 0x01000 },
+               .caps = MDP_CAP_SMP |
+                       0,
        },
        .smp = {
                .mmb_count = 44,
@@ -370,7 +380,89 @@ const struct mdp5_cfg_hw msm8x94_config = {
                        [3] = INTF_HDMI,
                },
        },
-       .max_clk = 320000000,
+       .max_clk = 400000000,
+};
+
+const struct mdp5_cfg_hw msm8x96_config = {
+       .name = "msm8x96",
+       .mdp = {
+               .count = 1,
+               .base = { 0x01000 },
+               .caps = MDP_CAP_DSC |
+                       MDP_CAP_CDM |
+                       0,
+       },
+       .ctl = {
+               .count = 5,
+               .base = { 0x02000, 0x02200, 0x02400, 0x02600, 0x02800 },
+               .flush_hw_mask = 0xf4ffffff,
+       },
+       .pipe_vig = {
+               .count = 4,
+               .base = { 0x05000, 0x07000, 0x09000, 0x0b000 },
+               .caps = MDP_PIPE_CAP_HFLIP      |
+                       MDP_PIPE_CAP_VFLIP      |
+                       MDP_PIPE_CAP_SCALE      |
+                       MDP_PIPE_CAP_CSC        |
+                       MDP_PIPE_CAP_DECIMATION |
+                       MDP_PIPE_CAP_SW_PIX_EXT |
+                       0,
+       },
+       .pipe_rgb = {
+               .count = 4,
+               .base = { 0x15000, 0x17000, 0x19000, 0x1b000 },
+               .caps = MDP_PIPE_CAP_HFLIP      |
+                       MDP_PIPE_CAP_VFLIP      |
+                       MDP_PIPE_CAP_SCALE      |
+                       MDP_PIPE_CAP_DECIMATION |
+                       MDP_PIPE_CAP_SW_PIX_EXT |
+                       0,
+       },
+       .pipe_dma = {
+               .count = 2,
+               .base = { 0x25000, 0x27000 },
+               .caps = MDP_PIPE_CAP_HFLIP      |
+                       MDP_PIPE_CAP_VFLIP      |
+                       MDP_PIPE_CAP_SW_PIX_EXT |
+                       0,
+       },
+       .lm = {
+               .count = 6,
+               .base = { 0x45000, 0x46000, 0x47000, 0x48000, 0x49000, 0x4a000 },
+               .nb_stages = 8,
+               .max_width = 2560,
+               .max_height = 0xFFFF,
+       },
+       .dspp = {
+               .count = 2,
+               .base = { 0x55000, 0x57000 },
+       },
+       .ad = {
+               .count = 3,
+               .base = { 0x79000, 0x79800, 0x7a000 },
+       },
+       .pp = {
+               .count = 4,
+               .base = { 0x71000, 0x71800, 0x72000, 0x72800 },
+       },
+       .cdm = {
+               .count = 1,
+               .base = { 0x7a200 },
+       },
+       .dsc = {
+               .count = 2,
+               .base = { 0x81000, 0x81400 },
+       },
+       .intf = {
+               .base = { 0x6b000, 0x6b800, 0x6c000, 0x6c800, 0x6d000 },
+               .connect = {
+                       [0] = INTF_DISABLED,
+                       [1] = INTF_DSI,
+                       [2] = INTF_DSI,
+                       [3] = INTF_HDMI,
+               },
+       },
+       .max_clk = 412500000,
 };
 
 static const struct mdp5_cfg_handler cfg_handlers[] = {
@@ -379,6 +471,7 @@ static const struct mdp5_cfg_handler cfg_handlers[] = {
        { .revision = 3, .config = { .hw = &apq8084_config } },
        { .revision = 6, .config = { .hw = &msm8x16_config } },
        { .revision = 9, .config = { .hw = &msm8x94_config } },
+       { .revision = 7, .config = { .hw = &msm8x96_config } },
 };
 
 static struct mdp5_cfg_platform *mdp5_get_config(struct platform_device *dev);
index a6facafed3bbd43560e02e3be7e4fdf140964187..050e1618c836e6eed5515bae1e479ab92c7e42d0 100644 (file)
@@ -64,6 +64,11 @@ struct mdp5_smp_block {
        uint8_t reserved[MAX_CLIENTS];  /* # of MMBs allocated per client */
 };
 
+struct mdp5_mdp_block {
+       MDP5_SUB_BLOCK_DEFINITION;
+       uint32_t caps;                  /* MDP capabilities: MDP_CAP_xxx bits */
+};
+
 #define MDP5_INTF_NUM_MAX      5
 
 struct mdp5_intf_block {
@@ -74,7 +79,7 @@ struct mdp5_intf_block {
 struct mdp5_cfg_hw {
        char  *name;
 
-       struct mdp5_sub_block mdp;
+       struct mdp5_mdp_block mdp;
        struct mdp5_smp_block smp;
        struct mdp5_ctl_block ctl;
        struct mdp5_pipe_block pipe_vig;
@@ -84,6 +89,8 @@ struct mdp5_cfg_hw {
        struct mdp5_sub_block dspp;
        struct mdp5_sub_block ad;
        struct mdp5_sub_block pp;
+       struct mdp5_sub_block dsc;
+       struct mdp5_sub_block cdm;
        struct mdp5_intf_block intf;
 
        uint32_t max_clk;
index 34c4ad54c269a60949bb769dd1c12c877a14b1a8..b532faa8026d95079dc2cf19ad0aef0f97782849 100644 (file)
@@ -554,15 +554,23 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev)
        }
 
        config = mdp5_cfg_get_config(mdp5_kms->cfg);
+       mdp5_kms->caps = config->hw->mdp.caps;
 
        /* TODO: compute core clock rate at runtime */
        clk_set_rate(mdp5_kms->src_clk, config->hw->max_clk);
 
-       mdp5_kms->smp = mdp5_smp_init(mdp5_kms->dev, &config->hw->smp);
-       if (IS_ERR(mdp5_kms->smp)) {
-               ret = PTR_ERR(mdp5_kms->smp);
-               mdp5_kms->smp = NULL;
-               goto fail;
+       /*
+        * Some chipsets have a Shared Memory Pool (SMP), while others
+        * have dedicated latency buffering per source pipe instead;
+        * this section initializes the SMP:
+        */
+       if (mdp5_kms->caps & MDP_CAP_SMP) {
+               mdp5_kms->smp = mdp5_smp_init(mdp5_kms->dev, &config->hw->smp);
+               if (IS_ERR(mdp5_kms->smp)) {
+                       ret = PTR_ERR(mdp5_kms->smp);
+                       mdp5_kms->smp = NULL;
+                       goto fail;
+               }
        }
 
        mdp5_kms->ctlm = mdp5_ctlm_init(dev, mdp5_kms->mmio, mdp5_kms->cfg);
index 0bb62423586e2e2126efa6acfe618ed41b90d982..84f65d415598ea4b6c7d85bc8e17d83be3fa1e6e 100644 (file)
@@ -32,6 +32,8 @@ struct mdp5_kms {
        struct drm_device *dev;
 
        struct mdp5_cfg_handler *cfg;
+       uint32_t caps;  /* MDP capabilities (MDP_CAP_XXX bits) */
+
 
        /* mapper-id used to request GEM buffer mapped for scanout: */
        int id;
index d93185e6f18aa50c01b2f26a0a9ccd4e62e05824..81cd49045ffcba70e5a47bdb4a9493a94cd71ba0 100644 (file)
@@ -705,10 +705,12 @@ static int mdp5_plane_mode_set(struct drm_plane *plane,
                        crtc->base.id, crtc_x, crtc_y, crtc_w, crtc_h);
 
        /* Request some memory from the SMP: */
-       ret = mdp5_smp_request(mdp5_kms->smp,
-                       mdp5_plane->pipe, format, src_w, false);
-       if (ret)
-               return ret;
+       if (mdp5_kms->smp) {
+               ret = mdp5_smp_request(mdp5_kms->smp,
+                               mdp5_plane->pipe, format, src_w, false);
+               if (ret)
+                       return ret;
+       }
 
        /*
         * Currently we update the hw for allocations/requests immediately,
@@ -716,7 +718,8 @@ static int mdp5_plane_mode_set(struct drm_plane *plane,
         * would move into atomic->check_plane_state(), while updating the
         * hw would remain here:
         */
-       mdp5_smp_configure(mdp5_kms->smp, pipe);
+       if (mdp5_kms->smp)
+               mdp5_smp_configure(mdp5_kms->smp, pipe);
 
        ret = calc_scalex_steps(plane, pix_format, src_w, crtc_w, phasex_step);
        if (ret)
@@ -835,7 +838,8 @@ void mdp5_plane_complete_flip(struct drm_plane *plane)
 
        DBG("%s: complete flip", mdp5_plane->name);
 
-       mdp5_smp_commit(mdp5_kms->smp, pipe);
+       if (mdp5_kms->smp)
+               mdp5_smp_commit(mdp5_kms->smp, pipe);
 
        to_mdp5_plane_state(plane->state)->pending = false;
 }
@@ -861,7 +865,7 @@ void mdp5_plane_complete_commit(struct drm_plane *plane,
        struct mdp5_plane *mdp5_plane = to_mdp5_plane(plane);
        enum mdp5_pipe pipe = mdp5_plane->pipe;
 
-       if (!plane_enabled(plane->state)) {
+       if (!plane_enabled(plane->state) && mdp5_kms->smp) {
                DBG("%s: free SMP", mdp5_plane->name);
                mdp5_smp_release(mdp5_kms->smp, pipe);
        }
index 0af2a541171d207eeebb562ec91afb243efab99a..30313032074845c4602a9feae9c8a3d5f76c2b07 100644 (file)
@@ -100,6 +100,11 @@ struct mdp_format {
 uint32_t mdp_get_formats(uint32_t *formats, uint32_t max_formats, bool rgb_only);
 const struct msm_format *mdp_get_format(struct msm_kms *kms, uint32_t format);
 
+/* MDP capabilities */
+#define MDP_CAP_SMP            BIT(0)  /* Shared Memory Pool                 */
+#define MDP_CAP_DSC            BIT(1)  /* VESA Display Stream Compression    */
+#define MDP_CAP_CDM            BIT(2)  /* Chroma Down Module (HDMI 2.0 YUV)  */
+
 /* MDP pipe capabilities */
 #define MDP_PIPE_CAP_HFLIP                     BIT(0)
 #define MDP_PIPE_CAP_VFLIP                     BIT(1)