Commit d879eb5a authored by Stephane Viau's avatar Stephane Viau Committed by Rob Clark

drm/msm/mdp5: Basic support for MDP5 v1.7 (MSM8996)

This change adds the basic MDP5 support for MSM8996.
Signed-off-by: default avatarStephane Viau <sviau@codeaurora.org>
Signed-off-by: default avatarRob Clark <robdclark@gmail.com>
parent 8e2930c6
...@@ -27,6 +27,8 @@ const struct mdp5_cfg_hw msm8x74v1_config = { ...@@ -27,6 +27,8 @@ const struct mdp5_cfg_hw msm8x74v1_config = {
.mdp = { .mdp = {
.count = 1, .count = 1,
.base = { 0x00100 }, .base = { 0x00100 },
.caps = MDP_CAP_SMP |
0,
}, },
.smp = { .smp = {
.mmb_count = 22, .mmb_count = 22,
...@@ -96,6 +98,8 @@ const struct mdp5_cfg_hw msm8x74v2_config = { ...@@ -96,6 +98,8 @@ const struct mdp5_cfg_hw msm8x74v2_config = {
.mdp = { .mdp = {
.count = 1, .count = 1,
.base = { 0x00100 }, .base = { 0x00100 },
.caps = MDP_CAP_SMP |
0,
}, },
.smp = { .smp = {
.mmb_count = 22, .mmb_count = 22,
...@@ -165,6 +169,8 @@ const struct mdp5_cfg_hw apq8084_config = { ...@@ -165,6 +169,8 @@ const struct mdp5_cfg_hw apq8084_config = {
.mdp = { .mdp = {
.count = 1, .count = 1,
.base = { 0x00100 }, .base = { 0x00100 },
.caps = MDP_CAP_SMP |
0,
}, },
.smp = { .smp = {
.mmb_count = 44, .mmb_count = 44,
...@@ -242,6 +248,8 @@ const struct mdp5_cfg_hw msm8x16_config = { ...@@ -242,6 +248,8 @@ const struct mdp5_cfg_hw msm8x16_config = {
.mdp = { .mdp = {
.count = 1, .count = 1,
.base = { 0x01000 }, .base = { 0x01000 },
.caps = MDP_CAP_SMP |
0,
}, },
.smp = { .smp = {
.mmb_count = 8, .mmb_count = 8,
...@@ -301,6 +309,8 @@ const struct mdp5_cfg_hw msm8x94_config = { ...@@ -301,6 +309,8 @@ const struct mdp5_cfg_hw msm8x94_config = {
.mdp = { .mdp = {
.count = 1, .count = 1,
.base = { 0x01000 }, .base = { 0x01000 },
.caps = MDP_CAP_SMP |
0,
}, },
.smp = { .smp = {
.mmb_count = 44, .mmb_count = 44,
...@@ -370,7 +380,89 @@ const struct mdp5_cfg_hw msm8x94_config = { ...@@ -370,7 +380,89 @@ const struct mdp5_cfg_hw msm8x94_config = {
[3] = INTF_HDMI, [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[] = { static const struct mdp5_cfg_handler cfg_handlers[] = {
...@@ -379,6 +471,7 @@ 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 = 3, .config = { .hw = &apq8084_config } },
{ .revision = 6, .config = { .hw = &msm8x16_config } }, { .revision = 6, .config = { .hw = &msm8x16_config } },
{ .revision = 9, .config = { .hw = &msm8x94_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); static struct mdp5_cfg_platform *mdp5_get_config(struct platform_device *dev);
......
...@@ -64,6 +64,11 @@ struct mdp5_smp_block { ...@@ -64,6 +64,11 @@ struct mdp5_smp_block {
uint8_t reserved[MAX_CLIENTS]; /* # of MMBs allocated per client */ 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 #define MDP5_INTF_NUM_MAX 5
struct mdp5_intf_block { struct mdp5_intf_block {
...@@ -74,7 +79,7 @@ struct mdp5_intf_block { ...@@ -74,7 +79,7 @@ struct mdp5_intf_block {
struct mdp5_cfg_hw { struct mdp5_cfg_hw {
char *name; char *name;
struct mdp5_sub_block mdp; struct mdp5_mdp_block mdp;
struct mdp5_smp_block smp; struct mdp5_smp_block smp;
struct mdp5_ctl_block ctl; struct mdp5_ctl_block ctl;
struct mdp5_pipe_block pipe_vig; struct mdp5_pipe_block pipe_vig;
...@@ -84,6 +89,8 @@ struct mdp5_cfg_hw { ...@@ -84,6 +89,8 @@ struct mdp5_cfg_hw {
struct mdp5_sub_block dspp; struct mdp5_sub_block dspp;
struct mdp5_sub_block ad; struct mdp5_sub_block ad;
struct mdp5_sub_block pp; struct mdp5_sub_block pp;
struct mdp5_sub_block dsc;
struct mdp5_sub_block cdm;
struct mdp5_intf_block intf; struct mdp5_intf_block intf;
uint32_t max_clk; uint32_t max_clk;
......
...@@ -554,16 +554,24 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev) ...@@ -554,16 +554,24 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev)
} }
config = mdp5_cfg_get_config(mdp5_kms->cfg); config = mdp5_cfg_get_config(mdp5_kms->cfg);
mdp5_kms->caps = config->hw->mdp.caps;
/* TODO: compute core clock rate at runtime */ /* TODO: compute core clock rate at runtime */
clk_set_rate(mdp5_kms->src_clk, config->hw->max_clk); clk_set_rate(mdp5_kms->src_clk, config->hw->max_clk);
/*
* 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); mdp5_kms->smp = mdp5_smp_init(mdp5_kms->dev, &config->hw->smp);
if (IS_ERR(mdp5_kms->smp)) { if (IS_ERR(mdp5_kms->smp)) {
ret = PTR_ERR(mdp5_kms->smp); ret = PTR_ERR(mdp5_kms->smp);
mdp5_kms->smp = NULL; mdp5_kms->smp = NULL;
goto fail; goto fail;
} }
}
mdp5_kms->ctlm = mdp5_ctlm_init(dev, mdp5_kms->mmio, mdp5_kms->cfg); mdp5_kms->ctlm = mdp5_ctlm_init(dev, mdp5_kms->mmio, mdp5_kms->cfg);
if (IS_ERR(mdp5_kms->ctlm)) { if (IS_ERR(mdp5_kms->ctlm)) {
......
...@@ -32,6 +32,8 @@ struct mdp5_kms { ...@@ -32,6 +32,8 @@ struct mdp5_kms {
struct drm_device *dev; struct drm_device *dev;
struct mdp5_cfg_handler *cfg; struct mdp5_cfg_handler *cfg;
uint32_t caps; /* MDP capabilities (MDP_CAP_XXX bits) */
/* mapper-id used to request GEM buffer mapped for scanout: */ /* mapper-id used to request GEM buffer mapped for scanout: */
int id; int id;
......
...@@ -705,10 +705,12 @@ static int mdp5_plane_mode_set(struct drm_plane *plane, ...@@ -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); crtc->base.id, crtc_x, crtc_y, crtc_w, crtc_h);
/* Request some memory from the SMP: */ /* Request some memory from the SMP: */
if (mdp5_kms->smp) {
ret = mdp5_smp_request(mdp5_kms->smp, ret = mdp5_smp_request(mdp5_kms->smp,
mdp5_plane->pipe, format, src_w, false); mdp5_plane->pipe, format, src_w, false);
if (ret) if (ret)
return ret; return ret;
}
/* /*
* Currently we update the hw for allocations/requests immediately, * Currently we update the hw for allocations/requests immediately,
...@@ -716,6 +718,7 @@ static int mdp5_plane_mode_set(struct drm_plane *plane, ...@@ -716,6 +718,7 @@ static int mdp5_plane_mode_set(struct drm_plane *plane,
* would move into atomic->check_plane_state(), while updating the * would move into atomic->check_plane_state(), while updating the
* hw would remain here: * hw would remain here:
*/ */
if (mdp5_kms->smp)
mdp5_smp_configure(mdp5_kms->smp, pipe); mdp5_smp_configure(mdp5_kms->smp, pipe);
ret = calc_scalex_steps(plane, pix_format, src_w, crtc_w, phasex_step); ret = calc_scalex_steps(plane, pix_format, src_w, crtc_w, phasex_step);
...@@ -835,6 +838,7 @@ void mdp5_plane_complete_flip(struct drm_plane *plane) ...@@ -835,6 +838,7 @@ void mdp5_plane_complete_flip(struct drm_plane *plane)
DBG("%s: complete flip", mdp5_plane->name); DBG("%s: complete flip", mdp5_plane->name);
if (mdp5_kms->smp)
mdp5_smp_commit(mdp5_kms->smp, pipe); mdp5_smp_commit(mdp5_kms->smp, pipe);
to_mdp5_plane_state(plane->state)->pending = false; to_mdp5_plane_state(plane->state)->pending = false;
...@@ -861,7 +865,7 @@ void mdp5_plane_complete_commit(struct drm_plane *plane, ...@@ -861,7 +865,7 @@ void mdp5_plane_complete_commit(struct drm_plane *plane,
struct mdp5_plane *mdp5_plane = to_mdp5_plane(plane); struct mdp5_plane *mdp5_plane = to_mdp5_plane(plane);
enum mdp5_pipe pipe = mdp5_plane->pipe; 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); DBG("%s: free SMP", mdp5_plane->name);
mdp5_smp_release(mdp5_kms->smp, pipe); mdp5_smp_release(mdp5_kms->smp, pipe);
} }
......
...@@ -100,6 +100,11 @@ struct mdp_format { ...@@ -100,6 +100,11 @@ struct mdp_format {
uint32_t mdp_get_formats(uint32_t *formats, uint32_t max_formats, bool rgb_only); 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); 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 */ /* MDP pipe capabilities */
#define MDP_PIPE_CAP_HFLIP BIT(0) #define MDP_PIPE_CAP_HFLIP BIT(0)
#define MDP_PIPE_CAP_VFLIP BIT(1) #define MDP_PIPE_CAP_VFLIP BIT(1)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment