diff options
| author | Dhaval Patel <pdhaval@codeaurora.org> | 2014-07-09 15:39:03 -0700 |
|---|---|---|
| committer | David Keitel <dkeitel@codeaurora.org> | 2016-03-23 20:31:56 -0700 |
| commit | d7206c1f545f29666fdde8fbb92ee92c9e7fa178 (patch) | |
| tree | 693c012c58bbdfa7975231a8deb607811030bf84 | |
| parent | 843808743c39c9a5b38a6d478426348dc53c5797 (diff) | |
msm: mdss: update MDSS driver to support latency ram
Different MDSS hardware variants support fixed pixel
latency ram for each pipe vs SMP (Shared Memory Pool).
Software does not have to handle SMP allocation/deallocation
for hardware with fixed pixel latency ram. This change
enables the driver to handle such MDSS hardware.
Change-Id: Ia55f45d65c3eb19350c7195acd83af8ffc0e9a10
Signed-off-by: Dhaval Patel <pdhaval@codeaurora.org>
| -rw-r--r-- | Documentation/devicetree/bindings/fb/mdss-mdp.txt | 11 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss.h | 1 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp.c | 68 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp.h | 7 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_overlay.c | 6 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_pipe.c | 39 | ||||
| -rw-r--r-- | include/uapi/linux/msm_mdp.h | 2 |
7 files changed, 97 insertions, 37 deletions
diff --git a/Documentation/devicetree/bindings/fb/mdss-mdp.txt b/Documentation/devicetree/bindings/fb/mdss-mdp.txt index 55f3c176b055..5882aa043d0b 100644 --- a/Documentation/devicetree/bindings/fb/mdss-mdp.txt +++ b/Documentation/devicetree/bindings/fb/mdss-mdp.txt @@ -81,11 +81,6 @@ Required properties offset within status register. Number of tuples defined should match the number of offsets defined in property: qcom,mdss-pipe-dma-off -- qcom,mdss-smp-data: Array of shared memory pool data. There should - be only two values in this property. The first - value corresponds to the number of smp blocks - and the second is the size of each block - present in the mdss hardware. - qcom,mdss-ctl-off: Array of offset addresses for the available ctl hw blocks within MDP, these offsets are calculated from register "mdp_phys" defined in @@ -229,6 +224,12 @@ Optional properties: settings used to setup MDSS QoS for best performance. The key used should be offset from "mdp_phys" register defined in reg property. +- qcom,mdss-smp-data: Array of shared memory pool data for dynamic SMP. There + should be only two values in this property. The first + value corresponds to the number of smp blocks and the + second is the size of each block present in the mdss + hardware. This property is optional for MDP hardware + with fix pixel latency ram. - qcom,mdss-rot-block-size: The size of a memory block (in pixels) to be used by the rotator. If this property is not specified, then a default value of 128 pixels would be used. diff --git a/drivers/video/fbdev/msm/mdss.h b/drivers/video/fbdev/msm/mdss.h index 65a18a0d284f..338d17278342 100644 --- a/drivers/video/fbdev/msm/mdss.h +++ b/drivers/video/fbdev/msm/mdss.h @@ -139,6 +139,7 @@ struct mdss_data_type { bool has_src_split; bool idle_pc_enabled; bool has_dst_split; + bool has_pixel_ram; u32 rotator_ot_limit; u32 mdp_irq_mask; diff --git a/drivers/video/fbdev/msm/mdss_mdp.c b/drivers/video/fbdev/msm/mdss_mdp.c index dcc7c2f8d8d2..8a200ba41ac2 100644 --- a/drivers/video/fbdev/msm/mdss_mdp.c +++ b/drivers/video/fbdev/msm/mdss_mdp.c @@ -1812,6 +1812,9 @@ static int mdss_mdp_parse_dt_pipe(struct platform_device *pdev) struct mdss_data_type *mdata = platform_get_drvdata(pdev); + mdata->has_pixel_ram = !mdss_mdp_parse_dt_prop_len(pdev, + "qcom,mdss-smp-data"); + mdata->nvig_pipes = mdss_mdp_parse_dt_prop_len(pdev, "qcom,mdss-pipe-vig-off"); mdata->nrgb_pipes = mdss_mdp_parse_dt_prop_len(pdev, @@ -1821,15 +1824,17 @@ static int mdss_mdp_parse_dt_pipe(struct platform_device *pdev) npipes = mdata->nvig_pipes + mdata->nrgb_pipes + mdata->ndma_pipes; - nfids += mdss_mdp_parse_dt_prop_len(pdev, - "qcom,mdss-pipe-vig-fetch-id"); - nfids += mdss_mdp_parse_dt_prop_len(pdev, - "qcom,mdss-pipe-rgb-fetch-id"); - nfids += mdss_mdp_parse_dt_prop_len(pdev, - "qcom,mdss-pipe-dma-fetch-id"); - if (npipes != nfids) { - pr_err("device tree err: unequal number of pipes and smp ids"); - return -EINVAL; + if (!mdata->has_pixel_ram) { + nfids += mdss_mdp_parse_dt_prop_len(pdev, + "qcom,mdss-pipe-vig-fetch-id"); + nfids += mdss_mdp_parse_dt_prop_len(pdev, + "qcom,mdss-pipe-rgb-fetch-id"); + nfids += mdss_mdp_parse_dt_prop_len(pdev, + "qcom,mdss-pipe-dma-fetch-id"); + if (npipes != nfids) { + pr_err("device tree err: unequal number of pipes and smp ids"); + return -EINVAL; + } } nxids += mdss_mdp_parse_dt_prop_len(pdev, "qcom,mdss-pipe-vig-xin-id"); @@ -1846,7 +1851,7 @@ static int mdss_mdp_parse_dt_pipe(struct platform_device *pdev) return -ENOMEM; } - ftch_id = kzalloc(sizeof(u32) * nfids, GFP_KERNEL); + ftch_id = kzalloc(sizeof(u32) * npipes, GFP_KERNEL); if (!ftch_id) { pr_err("no mem assigned for ftch_id: kzalloc fail\n"); rc = -ENOMEM; @@ -1887,10 +1892,13 @@ static int mdss_mdp_parse_dt_pipe(struct platform_device *pdev) } } - rc = mdss_mdp_parse_dt_handler(pdev, "qcom,mdss-pipe-vig-fetch-id", - ftch_id, mdata->nvig_pipes); - if (rc) - goto parse_fail; + if (nfids) { + rc = mdss_mdp_parse_dt_handler(pdev, + "qcom,mdss-pipe-vig-fetch-id", ftch_id, + mdata->nvig_pipes); + if (rc) + goto parse_fail; + } rc = mdss_mdp_parse_dt_handler(pdev, "qcom,mdss-pipe-vig-xin-id", xin_id, mdata->nvig_pipes); @@ -1910,10 +1918,13 @@ static int mdss_mdp_parse_dt_pipe(struct platform_device *pdev) setup_cnt += len; - rc = mdss_mdp_parse_dt_handler(pdev, "qcom,mdss-pipe-rgb-fetch-id", - ftch_id + mdata->nvig_pipes, mdata->nrgb_pipes); - if (rc) - goto parse_fail; + if (nfids) { + rc = mdss_mdp_parse_dt_handler(pdev, + "qcom,mdss-pipe-rgb-fetch-id", + ftch_id + mdata->nvig_pipes, mdata->nrgb_pipes); + if (rc) + goto parse_fail; + } rc = mdss_mdp_parse_dt_handler(pdev, "qcom,mdss-pipe-rgb-xin-id", xin_id + mdata->nvig_pipes, mdata->nrgb_pipes); @@ -1938,11 +1949,13 @@ static int mdss_mdp_parse_dt_pipe(struct platform_device *pdev) if (mdata->ndma_pipes) { dma_off = mdata->nvig_pipes + mdata->nrgb_pipes; - rc = mdss_mdp_parse_dt_handler(pdev, - "qcom,mdss-pipe-dma-fetch-id", - ftch_id + dma_off, mdata->ndma_pipes); - if (rc) - goto parse_fail; + if (nfids) { + rc = mdss_mdp_parse_dt_handler(pdev, + "qcom,mdss-pipe-dma-fetch-id", + ftch_id + dma_off, mdata->ndma_pipes); + if (rc) + goto parse_fail; + } rc = mdss_mdp_parse_dt_handler(pdev, "qcom,mdss-pipe-dma-xin-id", @@ -2300,8 +2313,13 @@ static int mdss_mdp_parse_dt_smp(struct platform_device *pdev) const u32 *arr; num = mdss_mdp_parse_dt_prop_len(pdev, "qcom,mdss-smp-data"); - - if (num != 2) + /* + * This property is optional for targets with fix pixel ram. Rest + * must provide no. of smp and size of each block. + */ + if (!num) + return 0; + else if (num != 2) return -EINVAL; rc = mdss_mdp_parse_dt_handler(pdev, "qcom,mdss-smp-data", data, num); diff --git a/drivers/video/fbdev/msm/mdss_mdp.h b/drivers/video/fbdev/msm/mdss_mdp.h index 87b9a5a6ae16..4cec2d6a324c 100644 --- a/drivers/video/fbdev/msm/mdss_mdp.h +++ b/drivers/video/fbdev/msm/mdss_mdp.h @@ -30,6 +30,7 @@ #define MDSS_MDP_CURSOR_WIDTH 64 #define MDSS_MDP_CURSOR_HEIGHT 64 #define MDSS_MDP_CURSOR_SIZE (MDSS_MDP_CURSOR_WIDTH*MDSS_MDP_CURSOR_WIDTH*4) +#define MDSS_MDP_PIXEL_RAM_SIZE (50 * 1024) #define MDP_CLK_DEFAULT_RATE 200000000 #define PHASE_STEP_SHIFT 21 @@ -634,6 +635,12 @@ static inline int mdss_mdp_get_wb_ctl_support(struct mdss_data_type *mdata, (mdata->nctl - mdata->nwb); } +static inline int mdss_mdp_get_pixel_ram_size(struct mdss_data_type *mdata) +{ + return (mdata->mdp_rev == MDSS_MDP_HW_REV_107) ? + MDSS_MDP_PIXEL_RAM_SIZE : 0; +} + irqreturn_t mdss_mdp_isr(int irq, void *ptr); int mdss_iommu_attach(struct mdss_data_type *mdata); int mdss_iommu_dettach(struct mdss_data_type *mdata); diff --git a/drivers/video/fbdev/msm/mdss_mdp_overlay.c b/drivers/video/fbdev/msm/mdss_mdp_overlay.c index b6f068e83275..4ac3ab0a938d 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_overlay.c +++ b/drivers/video/fbdev/msm/mdss_mdp_overlay.c @@ -2661,8 +2661,10 @@ static int mdss_fb_get_hw_caps(struct msm_fb_data_type *mfd, if (mdata->has_decimation) caps->features |= MDP_DECIMATION_EN; - caps->max_smp_cnt = mdss_res->smp_mb_cnt; - caps->smp_per_pipe = mdata->smp_mb_per_pipe; + if (mdata->smp_mb_cnt) { + caps->max_smp_cnt = mdata->smp_mb_cnt; + caps->smp_per_pipe = mdata->smp_mb_per_pipe; + } return 0; } diff --git a/drivers/video/fbdev/msm/mdss_mdp_pipe.c b/drivers/video/fbdev/msm/mdss_mdp_pipe.c index 8a16e1983e80..0e5ee4f2ae7d 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_pipe.c +++ b/drivers/video/fbdev/msm/mdss_mdp_pipe.c @@ -171,14 +171,23 @@ static void mdss_mdp_smp_mmb_free(unsigned long *smp, bool write) */ u32 mdss_mdp_smp_get_size(struct mdss_mdp_pipe *pipe) { - int i, mb_cnt = 0; + int i, mb_cnt = 0, smp_size; + struct mdss_data_type *mdata = mdss_mdp_get_mdata(); - for (i = 0; i < MAX_PLANES; i++) { - mb_cnt += bitmap_weight(pipe->smp_map[i].allocated, SMP_MB_CNT); - mb_cnt += bitmap_weight(pipe->smp_map[i].fixed, SMP_MB_CNT); + if (mdata->has_pixel_ram) { + smp_size = mdss_mdp_get_pixel_ram_size(mdata); + } else { + for (i = 0; i < MAX_PLANES; i++) { + mb_cnt += bitmap_weight(pipe->smp_map[i].allocated, + SMP_MB_CNT); + mb_cnt += bitmap_weight(pipe->smp_map[i].fixed, + SMP_MB_CNT); + } + + smp_size = mb_cnt * SMP_MB_SIZE; } - return mb_cnt * SMP_MB_SIZE; + return smp_size; } static void mdss_mdp_smp_set_wm_levels(struct mdss_mdp_pipe *pipe, int mb_cnt) @@ -232,6 +241,9 @@ static void mdss_mdp_smp_set_wm_levels(struct mdss_mdp_pipe *pipe, int mb_cnt) static void mdss_mdp_smp_free(struct mdss_mdp_pipe *pipe) { int i; + struct mdss_data_type *mdata = mdss_mdp_get_mdata(); + if (mdata->has_pixel_ram) + return; mutex_lock(&mdss_mdp_smp_lock); for (i = 0; i < MAX_PLANES; i++) { @@ -244,6 +256,9 @@ static void mdss_mdp_smp_free(struct mdss_mdp_pipe *pipe) void mdss_mdp_smp_unreserve(struct mdss_mdp_pipe *pipe) { int i; + struct mdss_data_type *mdata = mdss_mdp_get_mdata(); + if (mdata->has_pixel_ram) + return; mutex_lock(&mdss_mdp_smp_lock); for (i = 0; i < MAX_PLANES; i++) @@ -262,6 +277,9 @@ int mdss_mdp_smp_reserve(struct mdss_mdp_pipe *pipe) u32 nlines, format, seg_w; u16 width; + if (mdata->has_pixel_ram) + return 0; + width = pipe->src.w >> pipe->horz_deci; if (pipe->bwc_mode) { @@ -416,6 +434,10 @@ static int mdss_mdp_smp_alloc(struct mdss_mdp_pipe *pipe) { int i; int cnt = 0; + struct mdss_data_type *mdata = mdss_mdp_get_mdata(); + + if (mdata->has_pixel_ram) + return 0; mutex_lock(&mdss_mdp_smp_lock); for (i = 0; i < MAX_PLANES; i++) { @@ -439,6 +461,10 @@ static int mdss_mdp_smp_alloc(struct mdss_mdp_pipe *pipe) void mdss_mdp_smp_release(struct mdss_mdp_pipe *pipe) { + struct mdss_data_type *mdata = mdss_mdp_get_mdata(); + if (mdata->has_pixel_ram) + return; + mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON); mdss_mdp_smp_free(pipe); mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF); @@ -475,6 +501,9 @@ int mdss_mdp_smp_handoff(struct mdss_data_type *mdata) u32 off, s, data; struct mdss_mdp_pipe *pipe = NULL; + if (mdata->has_pixel_ram) + return 0; + /* * figure out what SMP MMBs are allocated for each of the pipes * that need to be handed off. diff --git a/include/uapi/linux/msm_mdp.h b/include/uapi/linux/msm_mdp.h index beb14559d938..18d085f94570 100644 --- a/include/uapi/linux/msm_mdp.h +++ b/include/uapi/linux/msm_mdp.h @@ -101,6 +101,8 @@ #define MDSS_MDP_HW_REV_103_1 MDSS_MDP_REV(1, 3, 1) /* 8084 v1.1 */ #define MDSS_MDP_HW_REV_105 MDSS_MDP_REV(1, 5, 0) /* 8994 v1.0 */ #define MDSS_MDP_HW_REV_106 MDSS_MDP_REV(1, 6, 0) /* 8916 v1.0 */ +#define MDSS_MDP_HW_REV_107 MDSS_MDP_REV(1, 7, 0) +#define MDSS_MDP_HW_REV_108 MDSS_MDP_REV(1, 8, 0) /* 8939 v1.0 */ #define MDSS_MDP_HW_REV_200 MDSS_MDP_REV(2, 0, 0) /* 8092 v1.0 */ enum { |
