diff options
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/video/fbdev/msm/mdss.h | 16 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp.c | 322 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp.h | 23 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_ctl.c | 161 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_hwio.h | 18 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_intf_writeback.c | 2 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_overlay.c | 8 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_pipe.c | 217 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_pp.c | 8 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_rotator.c | 14 |
10 files changed, 616 insertions, 173 deletions
diff --git a/drivers/video/fbdev/msm/mdss.h b/drivers/video/fbdev/msm/mdss.h index c6029273bbe0..e5e680cfd94b 100644 --- a/drivers/video/fbdev/msm/mdss.h +++ b/drivers/video/fbdev/msm/mdss.h @@ -85,9 +85,21 @@ struct mdss_data_type { u32 smp_mb_cnt; u32 smp_mb_size; - u32 *pipe_type_map; - u32 *mixer_type_map; + struct mdss_mdp_pipe *vig_pipes; + struct mdss_mdp_pipe *rgb_pipes; + struct mdss_mdp_pipe *dma_pipes; + u32 nvig_pipes; + u32 nrgb_pipes; + u32 ndma_pipes; + struct mdss_mdp_mixer *mixer_intf; + struct mdss_mdp_mixer *mixer_wb; + u32 nmixers_intf; + u32 nmixers_wb; + struct mdss_mdp_ctl *ctl_off; + u32 nctl; + struct mdss_mdp_dp_intf *dp_off; + u32 ndp; struct ion_client *iclient; int iommu_attached; struct mdss_iommu_map_type *iommu_map; diff --git a/drivers/video/fbdev/msm/mdss_mdp.c b/drivers/video/fbdev/msm/mdss_mdp.c index d66e4fbe8778..76c754477f36 100644 --- a/drivers/video/fbdev/msm/mdss_mdp.c +++ b/drivers/video/fbdev/msm/mdss_mdp.c @@ -57,25 +57,6 @@ static DEFINE_SPINLOCK(mdp_lock); static DEFINE_MUTEX(mdp_clk_lock); static DEFINE_MUTEX(mdp_suspend_mutex); -u32 mdss_mdp_pipe_type_map[MDSS_MDP_MAX_SSPP] = { - MDSS_MDP_PIPE_TYPE_VIG, - MDSS_MDP_PIPE_TYPE_VIG, - MDSS_MDP_PIPE_TYPE_VIG, - MDSS_MDP_PIPE_TYPE_RGB, - MDSS_MDP_PIPE_TYPE_RGB, - MDSS_MDP_PIPE_TYPE_RGB, - MDSS_MDP_PIPE_TYPE_DMA, - MDSS_MDP_PIPE_TYPE_DMA, -}; - -u32 mdss_mdp_mixer_type_map[MDSS_MDP_MAX_LAYERMIXER] = { - MDSS_MDP_MIXER_TYPE_INTF, - MDSS_MDP_MIXER_TYPE_INTF, - MDSS_MDP_MIXER_TYPE_INTF, - MDSS_MDP_MIXER_TYPE_WRITEBACK, - MDSS_MDP_MIXER_TYPE_WRITEBACK, -}; - #define MDP_BUS_VECTOR_ENTRY(ab_val, ib_val) \ { \ .src = MSM_BUS_MASTER_MDP_PORT0, \ @@ -131,6 +112,14 @@ static DEFINE_SPINLOCK(mdss_lock); struct mdss_hw *mdss_irq_handlers[MDSS_MAX_HW_BLK]; static int mdss_mdp_register_early_suspend(struct mdss_data_type *mdata); +static int mdss_mdp_parse_dt(struct platform_device *pdev); +static int mdss_mdp_parse_dt_pipe(struct platform_device *pdev); +static int mdss_mdp_parse_dt_mixer(struct platform_device *pdev); +static int mdss_mdp_parse_dt_ctl(struct platform_device *pdev); +static int mdss_mdp_parse_dt_handler(struct platform_device *pdev, + char *prop_name, u32 *offsets, int len); +static int mdss_mdp_parse_dt_prop_len(struct platform_device *pdev, + char *prop_name); static inline int mdss_irq_dispatch(u32 hw_ndx, int irq, void *ptr) { @@ -839,8 +828,6 @@ static u32 mdss_mdp_res_init(struct mdss_data_type *mdata) mdata->smp_mb_cnt = MDSS_MDP_SMP_MMB_BLOCKS; mdata->smp_mb_size = MDSS_MDP_SMP_MMB_SIZE; - mdata->pipe_type_map = mdss_mdp_pipe_type_map; - mdata->mixer_type_map = mdss_mdp_mixer_type_map; pr_info("mdss_revision=%x\n", mdata->rev); pr_info("mdp_hw_revision=%x\n", mdata->mdp_rev); @@ -931,6 +918,13 @@ static int mdss_mdp_probe(struct platform_device *pdev) } mdata->irq = res->start; + /*populate hw iomem base info from device tree*/ + rc = mdss_mdp_parse_dt(pdev); + if (rc) { + pr_err("unable to parse device tree\n"); + goto probe_done; + } + rc = mdss_mdp_res_init(mdata); if (rc) { pr_err("unable to initialize mdss mdp resources\n"); @@ -966,6 +960,292 @@ probe_done: return rc; } +static int mdss_mdp_parse_dt(struct platform_device *pdev) +{ + int rc; + + rc = mdss_mdp_parse_dt_pipe(pdev); + if (rc) { + pr_err("Error in device tree : pipes\n"); + return rc; + } + + rc = mdss_mdp_parse_dt_mixer(pdev); + if (rc) { + pr_err("Error in device tree : mixers\n"); + return rc; + } + + rc = mdss_mdp_parse_dt_ctl(pdev); + if (rc) { + pr_err("Error in device tree : ctl\n"); + return rc; + } + + return 0; +} + + +static int mdss_mdp_parse_dt_pipe(struct platform_device *pdev) +{ + u32 npipes, off; + int rc = 0; + u32 nids = 0; + u32 *offsets = NULL, *ftch_id = NULL; + + struct mdss_data_type *mdata = platform_get_drvdata(pdev); + + 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, + "qcom,mdss-pipe-rgb-off"); + mdata->ndma_pipes = mdss_mdp_parse_dt_prop_len(pdev, + "qcom,mdss-pipe-dma-off"); + + nids += mdss_mdp_parse_dt_prop_len(pdev, + "qcom,mdss-pipe-vig-fetch-id"); + nids += mdss_mdp_parse_dt_prop_len(pdev, + "qcom,mdss-pipe-rgb-fetch-id"); + nids += mdss_mdp_parse_dt_prop_len(pdev, + "qcom,mdss-pipe-dma-fetch-id"); + + npipes = mdata->nvig_pipes + mdata->nrgb_pipes + mdata->ndma_pipes; + + if (npipes != nids) { + pr_err("device tree err: unequal number of pipes and smp ids"); + return -EINVAL; + } + + offsets = kzalloc(sizeof(u32) * npipes, GFP_KERNEL); + if (!offsets) { + pr_err("no mem assigned: kzalloc fail\n"); + return -ENOMEM; + } + + ftch_id = kzalloc(sizeof(u32) * nids, GFP_KERNEL); + if (!ftch_id) { + pr_err("no mem assigned: kzalloc fail\n"); + rc = -ENOMEM; + goto ftch_alloc_fail; + } + + rc = mdss_mdp_parse_dt_handler(pdev, "qcom,mdss-pipe-vig-fetch-id", + ftch_id, mdata->nvig_pipes); + if (rc) + goto parse_done; + + rc = mdss_mdp_parse_dt_handler(pdev, "qcom,mdss-pipe-vig-off", + offsets, mdata->nvig_pipes); + if (rc) + goto parse_done; + + rc = mdss_mdp_pipe_addr_setup(mdata, offsets, ftch_id, + MDSS_MDP_PIPE_TYPE_VIG, MDSS_MDP_SSPP_VIG0, mdata->nvig_pipes); + if (rc) + goto parse_done; + + 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_done; + + rc = mdss_mdp_parse_dt_handler(pdev, "qcom,mdss-pipe-rgb-off", + offsets + mdata->nvig_pipes, mdata->nrgb_pipes); + if (rc) + goto parse_done; + + rc = mdss_mdp_pipe_addr_setup(mdata, offsets + mdata->nvig_pipes, + ftch_id + mdata->nvig_pipes, MDSS_MDP_PIPE_TYPE_RGB, + MDSS_MDP_SSPP_RGB0, mdata->nrgb_pipes); + if (rc) + goto parse_done; + + off = mdata->nvig_pipes + mdata->nrgb_pipes; + + rc = mdss_mdp_parse_dt_handler(pdev, "qcom,mdss-pipe-dma-fetch-id", + ftch_id + off, mdata->ndma_pipes); + if (rc) + goto parse_done; + + rc = mdss_mdp_parse_dt_handler(pdev, "qcom,mdss-pipe-dma-off", + offsets + off, mdata->ndma_pipes); + if (rc) + goto parse_done; + + rc = mdss_mdp_pipe_addr_setup(mdata, offsets + off, ftch_id + off, + MDSS_MDP_PIPE_TYPE_DMA, MDSS_MDP_SSPP_DMA0, mdata->ndma_pipes); + if (rc) + goto parse_done; + +parse_done: + kfree(ftch_id); +ftch_alloc_fail: + kfree(offsets); + return rc; +} + +static int mdss_mdp_parse_dt_mixer(struct platform_device *pdev) +{ + + u32 nmixers, ndspp; + int rc = 0; + u32 *mixer_offsets = NULL, *dspp_offsets = NULL; + + struct mdss_data_type *mdata = platform_get_drvdata(pdev); + + mdata->nmixers_intf = mdss_mdp_parse_dt_prop_len(pdev, + "qcom,mdss-mixer-intf-off"); + mdata->nmixers_wb = mdss_mdp_parse_dt_prop_len(pdev, + "qcom,mdss-mixer-wb-off"); + ndspp = mdss_mdp_parse_dt_prop_len(pdev, + "qcom,mdss-dspp-off"); + nmixers = mdata->nmixers_intf + mdata->nmixers_wb; + + if (mdata->nmixers_intf != ndspp) { + pr_err("device tree err: unequal no of dspp and intf mixers\n"); + return -EINVAL; + } + + mixer_offsets = kzalloc(sizeof(u32) * nmixers, GFP_KERNEL); + if (!mixer_offsets) { + pr_err("no mem assigned: kzalloc fail\n"); + return -ENOMEM; + } + + dspp_offsets = kzalloc(sizeof(u32) * ndspp, GFP_KERNEL); + if (!dspp_offsets) { + pr_err("no mem assigned: kzalloc fail\n"); + rc = -ENOMEM; + goto dspp_alloc_fail; + } + + rc = mdss_mdp_parse_dt_handler(pdev, "qcom,mdss-mixer-intf-off", + mixer_offsets, mdata->nmixers_intf); + if (rc) + goto parse_done; + + rc = mdss_mdp_parse_dt_handler(pdev, "qcom,mdss-mixer-wb-off", + mixer_offsets + mdata->nmixers_intf, mdata->nmixers_wb); + if (rc) + goto parse_done; + + rc = mdss_mdp_parse_dt_handler(pdev, "qcom,mdss-dspp-off", + dspp_offsets, ndspp); + if (rc) + goto parse_done; + + rc = mdss_mdp_mixer_addr_setup(mdata, mixer_offsets, + dspp_offsets, MDSS_MDP_MIXER_TYPE_INTF, + mdata->nmixers_intf); + if (rc) + goto parse_done; + + rc = mdss_mdp_mixer_addr_setup(mdata, mixer_offsets + + mdata->nmixers_intf, NULL, + MDSS_MDP_MIXER_TYPE_WRITEBACK, mdata->nmixers_wb); + if (rc) + goto parse_done; + +parse_done: + kfree(dspp_offsets); +dspp_alloc_fail: + kfree(mixer_offsets); + + return rc; +} + +static int mdss_mdp_parse_dt_ctl(struct platform_device *pdev) +{ + u32 nwb; + int rc = 0; + u32 *ctl_offsets = NULL, *wb_offsets = NULL; + + struct mdss_data_type *mdata = platform_get_drvdata(pdev); + + mdata->nctl = mdss_mdp_parse_dt_prop_len(pdev, + "qcom,mdss-ctl-off"); + nwb = mdss_mdp_parse_dt_prop_len(pdev, + "qcom,mdss-wb-off"); + + if (mdata->nctl != nwb) { + pr_err("device tree err: unequal number of ctl and wb\n"); + rc = -EINVAL; + goto parse_done; + } + + ctl_offsets = kzalloc(sizeof(u32) * mdata->nctl, GFP_KERNEL); + if (!ctl_offsets) { + pr_err("no more mem for ctl offsets\n"); + return -ENOMEM; + } + + wb_offsets = kzalloc(sizeof(u32) * nwb, GFP_KERNEL); + if (!wb_offsets) { + pr_err("no more mem for writeback offsets\n"); + rc = -ENOMEM; + goto wb_alloc_fail; + } + + rc = mdss_mdp_parse_dt_handler(pdev, "qcom,mdss-ctl-off", + ctl_offsets, mdata->nctl); + if (rc) + goto parse_done; + + rc = mdss_mdp_parse_dt_handler(pdev, "qcom,mdss-wb-off", + wb_offsets, nwb); + if (rc) + goto parse_done; + + rc = mdss_mdp_ctl_addr_setup(mdata, ctl_offsets, wb_offsets, + mdata->nctl); + if (rc) + goto parse_done; + +parse_done: + kfree(wb_offsets); +wb_alloc_fail: + kfree(ctl_offsets); + + return rc; +} + +static int mdss_mdp_parse_dt_handler(struct platform_device *pdev, + char *prop_name, u32 *offsets, int len) +{ + int rc; + rc = of_property_read_u32_array(pdev->dev.of_node, prop_name, + offsets, len); + if (rc) { + pr_err("Error from prop %s : u32 array read\n", prop_name); + return -EINVAL; + } + + return 0; +} + +static int mdss_mdp_parse_dt_prop_len(struct platform_device *pdev, + char *prop_name) +{ + int len = 0; + + of_find_property(pdev->dev.of_node, prop_name, &len); + + if (len < 1) { + pr_err("Error from prop %s : spec error in device tree\n", + prop_name); + return 0; + } + + len = len/sizeof(u32); + + return len; +} + +struct mdss_data_type *mdss_mdp_get_mdata() +{ + return mdss_res; +} + static void mdss_mdp_footswitch_ctrl(struct mdss_data_type *mdata, int on) { int ret; diff --git a/drivers/video/fbdev/msm/mdss_mdp.h b/drivers/video/fbdev/msm/mdss_mdp.h index acd54af9e451..84482b7bd8b8 100644 --- a/drivers/video/fbdev/msm/mdss_mdp.h +++ b/drivers/video/fbdev/msm/mdss_mdp.h @@ -112,6 +112,8 @@ typedef void (*mdp_vsync_handler_t)(struct mdss_mdp_ctl *, ktime_t); struct mdss_mdp_ctl { u32 num; + char __iomem *base; + char __iomem *wb_base; u32 ref_cnt; int power_on; @@ -131,7 +133,6 @@ struct mdss_mdp_ctl { u32 bus_ib_quota; u32 clk_rate; - char __iomem *base; struct mdss_data_type *mdata; struct msm_fb_data_type *mfd; struct mdss_mdp_mixer *mixer_left; @@ -153,9 +154,9 @@ struct mdss_mdp_mixer { u32 num; u32 ref_cnt; char __iomem *base; + char __iomem *dspp_base; u8 type; u8 params_changed; - u16 width; u16 height; u8 cursor_enabled; @@ -236,6 +237,7 @@ struct mdss_mdp_pipe { u32 type; u32 ndx; char __iomem *base; + u32 ftch_id; atomic_t ref_cnt; u32 play_cnt; @@ -306,6 +308,7 @@ void mdss_mdp_set_clk_rate(unsigned long min_clk_rate); unsigned long mdss_mdp_get_clk_rate(u32 clk_idx); int mdss_mdp_vsync_clk_enable(int enable); void mdss_mdp_clk_ctrl(int enable, int isr); +struct mdss_data_type *mdss_mdp_get_mdata(void); int mdss_mdp_overlay_init(struct msm_fb_data_type *mfd); int mdss_mdp_overlay_vsync_ctrl(struct msm_fb_data_type *mfd, int en); @@ -358,13 +361,19 @@ int mdss_mdp_hist_collect(struct fb_info *info, struct mdp_histogram_data *hist, u32 *hist_data_addr); void mdss_mdp_hist_intr_done(u32 isr); -struct mdss_mdp_pipe *mdss_mdp_pipe_alloc_pnum( - struct mdss_mdp_mixer *mixer, u32 pnum); -struct mdss_mdp_pipe *mdss_mdp_pipe_alloc( - struct mdss_mdp_mixer *mixer, u32 type); -struct mdss_mdp_pipe *mdss_mdp_pipe_get(u32 ndx); +struct mdss_mdp_pipe *mdss_mdp_pipe_alloc(struct mdss_mdp_mixer *mixer, + u32 type); +struct mdss_mdp_pipe *mdss_mdp_pipe_get(struct mdss_data_type *mdata, u32 ndx); int mdss_mdp_pipe_map(struct mdss_mdp_pipe *pipe); void mdss_mdp_pipe_unmap(struct mdss_mdp_pipe *pipe); +struct mdss_mdp_pipe *mdss_mdp_pipe_alloc_dma(struct mdss_mdp_mixer *mixer); + +int mdss_mdp_pipe_addr_setup(struct mdss_data_type *mdata, u32 *offsets, + u32 *ftch_y_id, u32 type, u32 num_base, u32 len); +int mdss_mdp_mixer_addr_setup(struct mdss_data_type *mdata, u32 *mixer_offsets, + u32 *dspp_offsets, u32 type, u32 len); +int mdss_mdp_ctl_addr_setup(struct mdss_data_type *mdata, u32 *ctl_offsets, + u32 *wb_offsets, u32 len); int mdss_mdp_pipe_destroy(struct mdss_mdp_pipe *pipe); int mdss_mdp_pipe_queue_data(struct mdss_mdp_pipe *pipe, diff --git a/drivers/video/fbdev/msm/mdss_mdp_ctl.c b/drivers/video/fbdev/msm/mdss_mdp_ctl.c index 2ecd4b6ffb3d..63a1aa4a7853 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_ctl.c +++ b/drivers/video/fbdev/msm/mdss_mdp_ctl.c @@ -38,8 +38,6 @@ enum { #define MDSS_MDP_PERF_UPDATE_ALL -1 static DEFINE_MUTEX(mdss_mdp_ctl_lock); -static struct mdss_mdp_ctl mdss_mdp_ctl_list[MDSS_MDP_MAX_CTL]; -static struct mdss_mdp_mixer mdss_mdp_mixer_list[MDSS_MDP_MAX_LAYERMIXER]; static inline void mdp_mixer_write(struct mdss_mdp_mixer *mixer, u32 reg, u32 val) @@ -47,7 +45,7 @@ static inline void mdp_mixer_write(struct mdss_mdp_mixer *mixer, writel_relaxed(val, mixer->base + reg); } -static int mdss_mdp_ctl_perf_commit(u32 flags) +static int mdss_mdp_ctl_perf_commit(struct mdss_data_type *mdata, u32 flags) { struct mdss_mdp_ctl *ctl; int cnum; @@ -60,8 +58,8 @@ static int mdss_mdp_ctl_perf_commit(u32 flags) } mutex_lock(&mdss_mdp_ctl_lock); - for (cnum = 0; cnum < MDSS_MDP_MAX_CTL; cnum++) { - ctl = &mdss_mdp_ctl_list[cnum]; + for (cnum = 0; cnum < mdata->nctl; cnum++) { + ctl = mdata->ctl_off + cnum; if (ctl->power_on) { bus_ab_quota += ctl->bus_ab_quota; bus_ib_quota += ctl->bus_ib_quota; @@ -239,19 +237,16 @@ static struct mdss_mdp_ctl *mdss_mdp_ctl_alloc(struct mdss_data_type *mdata) int cnum; mutex_lock(&mdss_mdp_ctl_lock); - for (cnum = 0; cnum < MDSS_MDP_MAX_CTL; cnum++) { - if (mdss_mdp_ctl_list[cnum].ref_cnt == 0) { - ctl = &mdss_mdp_ctl_list[cnum]; - ctl->num = cnum; + for (cnum = 0; cnum < mdata->nctl; cnum++) { + ctl = mdata->ctl_off + cnum; + if (ctl->ref_cnt == 0) { ctl->ref_cnt++; ctl->mdata = mdata; - ctl->base = mdata->mdp_base + - MDSS_MDP_REG_CTL_OFFSET(cnum); mutex_init(&ctl->lock); - pr_debug("alloc ctl_num=%d\n", ctl->num); break; } + ctl = NULL; } mutex_unlock(&mdss_mdp_ctl_lock); @@ -271,8 +266,7 @@ static int mdss_mdp_ctl_free(struct mdss_mdp_ctl *ctl) } mutex_lock(&mdss_mdp_ctl_lock); - if (--ctl->ref_cnt == 0) - memset(ctl, 0, sizeof(*ctl)); + ctl->ref_cnt--; mutex_unlock(&mdss_mdp_ctl_lock); return 0; @@ -282,27 +276,47 @@ static struct mdss_mdp_mixer *mdss_mdp_mixer_alloc( struct mdss_mdp_ctl *ctl, u32 type) { struct mdss_mdp_mixer *mixer = NULL; - int mnum; + u32 nmixers_intf; + u32 nmixers_wb; + u32 i; + u32 nmixers; + struct mdss_mdp_mixer *mixer_pool = NULL; if (!ctl || !ctl->mdata) return NULL; mutex_lock(&mdss_mdp_ctl_lock); - for (mnum = 0; mnum < MDSS_MDP_MAX_LAYERMIXER; mnum++) { - if (type == ctl->mdata->mixer_type_map[mnum] && - mdss_mdp_mixer_list[mnum].ref_cnt == 0) { - mixer = &mdss_mdp_mixer_list[mnum]; - mixer->num = mnum; + nmixers_intf = ctl->mdata->nmixers_intf; + nmixers_wb = ctl->mdata->nmixers_wb; + + switch (type) { + + case MDSS_MDP_MIXER_TYPE_INTF: + mixer_pool = ctl->mdata->mixer_intf; + nmixers = nmixers_intf; + break; + + case MDSS_MDP_MIXER_TYPE_WRITEBACK: + mixer_pool = ctl->mdata->mixer_wb; + nmixers = nmixers_wb; + break; + + default: + nmixers = 0; + pr_err("invalid pipe type %d\n", type); + break; + } + + for (i = 0; i < nmixers; i++) { + mixer = mixer_pool + i; + if (mixer->ref_cnt == 0) { mixer->ref_cnt++; mixer->params_changed++; - mixer->type = type; - mixer->base = ctl->mdata->mdp_base + - MDSS_MDP_REG_LM_OFFSET(mnum); mixer->ctl = ctl; - - pr_debug("mixer_num=%d\n", mixer->num); + pr_debug("alloc mixer num%d\n", mixer->num); break; } + mixer = NULL; } mutex_unlock(&mdss_mdp_ctl_lock); @@ -322,8 +336,7 @@ static int mdss_mdp_mixer_free(struct mdss_mdp_mixer *mixer) } mutex_lock(&mdss_mdp_ctl_lock); - if (--mixer->ref_cnt == 0) - memset(mixer, 0, sizeof(*mixer)); + mixer->ref_cnt--; mutex_unlock(&mdss_mdp_ctl_lock); return 0; @@ -345,11 +358,11 @@ struct mdss_mdp_mixer *mdss_mdp_wb_mixer_alloc(int rotator) mixer->rotator_mode = rotator; switch (mixer->num) { - case MDSS_MDP_LAYERMIXER3: + case MDSS_MDP_WB_LAYERMIXER0: ctl->opmode = (rotator ? MDSS_MDP_CTL_OP_ROT0_MODE : MDSS_MDP_CTL_OP_WB0_MODE); break; - case MDSS_MDP_LAYERMIXER4: + case MDSS_MDP_WB_LAYERMIXER1: ctl->opmode = (rotator ? MDSS_MDP_CTL_OP_ROT1_MODE : MDSS_MDP_CTL_OP_WB1_MODE); break; @@ -390,7 +403,7 @@ int mdss_mdp_wb_mixer_destroy(struct mdss_mdp_mixer *mixer) mdss_mdp_mixer_free(mixer); mdss_mdp_ctl_free(ctl); - mdss_mdp_ctl_perf_commit(MDSS_MDP_PERF_UPDATE_ALL); + mdss_mdp_ctl_perf_commit(ctl->mdata, MDSS_MDP_PERF_UPDATE_ALL); return 0; } @@ -476,6 +489,7 @@ static int mdss_mdp_ctl_setup(struct mdss_mdp_ctl *ctl) ctl->mixer_right->height = height; } else if (ctl->mixer_right) { mdss_mdp_mixer_free(ctl->mixer_right); + ctl->mixer_right = NULL; } if (ctl->mixer_right) { @@ -666,10 +680,13 @@ int mdss_mdp_ctl_destroy(struct mdss_mdp_ctl *ctl) mdss_mdp_ctl_free(sctl); } else if (ctl->mixer_right) { mdss_mdp_mixer_free(ctl->mixer_right); + ctl->mixer_right = NULL; } - if (ctl->mixer_left) + if (ctl->mixer_left) { mdss_mdp_mixer_free(ctl->mixer_left); + ctl->mixer_left = NULL; + } mdss_mdp_ctl_free(ctl); return 0; @@ -828,7 +845,7 @@ int mdss_mdp_ctl_stop(struct mdss_mdp_ctl *ctl) mdss_mdp_ctl_write(ctl, MDSS_MDP_REG_CTL_LAYER( ctl->mixer_right->num), 0); } - mdss_mdp_ctl_perf_commit(MDSS_MDP_PERF_UPDATE_ALL); + mdss_mdp_ctl_perf_commit(ctl->mdata, MDSS_MDP_PERF_UPDATE_ALL); } mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false); @@ -938,6 +955,76 @@ static int mdss_mdp_mixer_setup(struct mdss_mdp_ctl *ctl, return 0; } +int mdss_mdp_mixer_addr_setup(struct mdss_data_type *mdata, + u32 *mixer_offsets, u32 *dspp_offsets, u32 type, u32 len) +{ + struct mdss_mdp_mixer *head; + u32 i; + int rc = 0; + + head = devm_kzalloc(&mdata->pdev->dev, sizeof(struct mdss_mdp_mixer) * + len, GFP_KERNEL); + + if (!head) { + pr_err("unable to setup mixer type=%d :kzalloc fail\n", + type); + return -ENOMEM; + } + + for (i = 0; i < len; i++) { + head[i].type = type; + head[i].base = mdata->mdp_base + mixer_offsets[i]; + head[i].ref_cnt = 0; + head[i].num = i; + if (type == MDSS_MDP_MIXER_TYPE_INTF) + head[i].dspp_base = mdata->mdp_base + dspp_offsets[i]; + } + + switch (type) { + + case MDSS_MDP_MIXER_TYPE_INTF: + mdata->mixer_intf = head; + break; + + case MDSS_MDP_MIXER_TYPE_WRITEBACK: + mdata->mixer_wb = head; + break; + + default: + pr_err("Invalid mixer type=%d\n", type); + rc = -EINVAL; + break; + } + + return rc; +} + +int mdss_mdp_ctl_addr_setup(struct mdss_data_type *mdata, + u32 *ctl_offsets, u32 *wb_offsets, u32 len) +{ + struct mdss_mdp_ctl *head; + u32 i; + + head = devm_kzalloc(&mdata->pdev->dev, sizeof(struct mdss_mdp_ctl) * + len, GFP_KERNEL); + + if (!head) { + pr_err("unable to setup ctl and wb: kzalloc fail\n"); + return -ENOMEM; + } + + for (i = 0; i < len; i++) { + head[i].num = i; + head[i].base = (mdata->mdp_base) + ctl_offsets[i]; + head[i].wb_base = (mdata->mdp_base) + wb_offsets[i]; + head[i].ref_cnt = 0; + } + + mdata->ctl_off = head; + + return 0; +} + struct mdss_mdp_mixer *mdss_mdp_mixer_get(struct mdss_mdp_ctl *ctl, int mux) { struct mdss_mdp_mixer *mixer = NULL; @@ -1096,7 +1183,7 @@ int mdss_mdp_display_commit(struct mdss_mdp_ctl *ctl, void *arg) } if (perf_update == MDSS_MDP_PERF_UPDATE_EARLY) - mdss_mdp_ctl_perf_commit(update_flags); + mdss_mdp_ctl_perf_commit(ctl->mdata, update_flags); if (mixer1_changed) mdss_mdp_mixer_update(ctl->mixer_left); @@ -1132,7 +1219,7 @@ int mdss_mdp_display_commit(struct mdss_mdp_ctl *ctl, void *arg) ctl->play_cnt++; if (perf_update == MDSS_MDP_PERF_UPDATE_LATE) - mdss_mdp_ctl_perf_commit(update_flags); + mdss_mdp_ctl_perf_commit(ctl->mdata, update_flags); done: mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false); @@ -1146,10 +1233,12 @@ int mdss_mdp_get_ctl_mixers(u32 fb_num, u32 *mixer_id) { int i; struct mdss_mdp_ctl *ctl; + struct mdss_data_type *mdata; u32 mixer_cnt = 0; mutex_lock(&mdss_mdp_ctl_lock); - for (i = 0; i < MDSS_MDP_MAX_CTL; i++) { - ctl = &mdss_mdp_ctl_list[i]; + mdata = mdss_mdp_get_mdata(); + for (i = 0; i < mdata->nctl; i++) { + ctl = mdata->ctl_off + i; if ((ctl->power_on) && (ctl->mfd) && (ctl->mfd->index == fb_num)) { if (ctl->mixer_left) { diff --git a/drivers/video/fbdev/msm/mdss_mdp_hwio.h b/drivers/video/fbdev/msm/mdss_mdp_hwio.h index 0d530b50a36d..9b37c4afc79c 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_hwio.h +++ b/drivers/video/fbdev/msm/mdss_mdp_hwio.h @@ -222,13 +222,17 @@ enum mdss_mdp_sspp_chroma_samp_type { #define MDSS_MDP_NUM_REG_MIXERS 3 #define MDSS_MDP_NUM_WB_MIXERS 2 -enum mdss_mdp_mixer_index { - MDSS_MDP_LAYERMIXER0, - MDSS_MDP_LAYERMIXER1, - MDSS_MDP_LAYERMIXER2, - MDSS_MDP_LAYERMIXER3, - MDSS_MDP_LAYERMIXER4, - MDSS_MDP_MAX_LAYERMIXER +enum mdss_mdp_mixer_intf_index { + MDSS_MDP_INTF_LAYERMIXER0, + MDSS_MDP_INTF_LAYERMIXER1, + MDSS_MDP_INTF_LAYERMIXER2, + MDSS_MDP_INTF_MAX_LAYERMIXER, +}; + +enum mdss_mdp_mixer_wb_index { + MDSS_MDP_WB_LAYERMIXER0, + MDSS_MDP_WB_LAYERMIXER1, + MDSS_MDP_WB_MAX_LAYERMIXER, }; enum mdss_mdp_stage_index { diff --git a/drivers/video/fbdev/msm/mdss_mdp_intf_writeback.c b/drivers/video/fbdev/msm/mdss_mdp_intf_writeback.c index ee953969cbae..584392a5fe7c 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_intf_writeback.c +++ b/drivers/video/fbdev/msm/mdss_mdp_intf_writeback.c @@ -356,7 +356,7 @@ int mdss_mdp_writeback_start(struct mdss_mdp_ctl *ctl) } ctl->priv_data = ctx; ctx->wb_num = ctl->num; /* wb num should match ctl num */ - ctx->base = ctl->mdata->mdp_base + MDSS_MDP_REG_WB_OFFSET(ctx->wb_num); + ctx->base = ctl->wb_base; ctx->initialized = false; mdss_mdp_set_intr_callback(ctx->intr_type, ctx->intf_num, diff --git a/drivers/video/fbdev/msm/mdss_mdp_overlay.c b/drivers/video/fbdev/msm/mdss_mdp_overlay.c index c5ccbc945a28..283d3f0fd402 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_overlay.c +++ b/drivers/video/fbdev/msm/mdss_mdp_overlay.c @@ -39,7 +39,7 @@ static int mdss_mdp_overlay_get(struct msm_fb_data_type *mfd, { struct mdss_mdp_pipe *pipe; - pipe = mdss_mdp_pipe_get(req->id); + pipe = mdss_mdp_pipe_get(mfd->mdata, req->id); if (IS_ERR_OR_NULL(pipe)) { pr_err("invalid pipe ndx=%x\n", req->id); return pipe ? PTR_ERR(pipe) : -ENODEV; @@ -306,7 +306,7 @@ static int mdss_mdp_overlay_pipe_setup(struct msm_fb_data_type *mfd, pipe->mfd = mfd; pipe->play_cnt = 0; } else { - pipe = mdss_mdp_pipe_get(req->id); + pipe = mdss_mdp_pipe_get(mfd->mdata, req->id); if (IS_ERR_OR_NULL(pipe)) { pr_err("invalid pipe ndx=%x\n", req->id); return pipe ? PTR_ERR(pipe) : -ENODEV; @@ -518,7 +518,7 @@ static int mdss_mdp_overlay_release(struct msm_fb_data_type *mfd, int ndx) pipe_ndx = BIT(i); if (pipe_ndx & ndx) { unset_ndx |= pipe_ndx; - pipe = mdss_mdp_pipe_get(pipe_ndx); + pipe = mdss_mdp_pipe_get(mfd->mdata, pipe_ndx); if (IS_ERR_OR_NULL(pipe)) { pr_warn("unknown pipe ndx=%x\n", pipe_ndx); continue; @@ -659,7 +659,7 @@ static int mdss_mdp_overlay_queue(struct msm_fb_data_type *mfd, int ret; u32 flags; - pipe = mdss_mdp_pipe_get(req->id); + pipe = mdss_mdp_pipe_get(mfd->mdata, req->id); if (IS_ERR_OR_NULL(pipe)) { pr_err("pipe ndx=%x doesn't exist\n", req->id); return pipe ? PTR_ERR(pipe) : -ENODEV; diff --git a/drivers/video/fbdev/msm/mdss_mdp_pipe.c b/drivers/video/fbdev/msm/mdss_mdp_pipe.c index 7451a8018a1e..0a525615300c 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_pipe.c +++ b/drivers/video/fbdev/msm/mdss_mdp_pipe.c @@ -25,8 +25,8 @@ static DEFINE_MUTEX(mdss_mdp_sspp_lock); static DEFINE_MUTEX(mdss_mdp_smp_lock); static DECLARE_BITMAP(mdss_mdp_smp_mmb_pool, MDSS_MDP_SMP_MMB_BLOCKS); -static struct mdss_mdp_pipe mdss_mdp_pipe_list[MDSS_MDP_MAX_SSPP]; - +static struct mdss_mdp_pipe *mdss_mdp_pipe_search(struct mdss_data_type *mdata, + u32 ndx); static int mdss_mdp_pipe_free(struct mdss_mdp_pipe *pipe); static u32 mdss_mdp_smp_mmb_reserve(unsigned long *smp, size_t n) @@ -119,42 +119,10 @@ static int mdss_mdp_smp_reserve(struct mdss_mdp_pipe *pipe) static int mdss_mdp_smp_alloc(struct mdss_mdp_pipe *pipe) { - u32 client_id; int i; - - switch (pipe->num) { - case MDSS_MDP_SSPP_VIG0: - client_id = MDSS_MDP_SMP_CLIENT_VIG0_FETCH_Y; - break; - case MDSS_MDP_SSPP_VIG1: - client_id = MDSS_MDP_SMP_CLIENT_VIG1_FETCH_Y; - break; - case MDSS_MDP_SSPP_VIG2: - client_id = MDSS_MDP_SMP_CLIENT_VIG2_FETCH_Y; - break; - case MDSS_MDP_SSPP_RGB0: - client_id = MDSS_MDP_SMP_CLIENT_RGB0_FETCH; - break; - case MDSS_MDP_SSPP_RGB1: - client_id = MDSS_MDP_SMP_CLIENT_RGB1_FETCH; - break; - case MDSS_MDP_SSPP_RGB2: - client_id = MDSS_MDP_SMP_CLIENT_RGB2_FETCH; - break; - case MDSS_MDP_SSPP_DMA0: - client_id = MDSS_MDP_SMP_CLIENT_DMA0_FETCH_Y; - break; - case MDSS_MDP_SSPP_DMA1: - client_id = MDSS_MDP_SMP_CLIENT_DMA1_FETCH_Y; - break; - default: - pr_err("no valid smp client for pnum=%d\n", pipe->num); - return -EINVAL; - } - mutex_lock(&mdss_mdp_smp_lock); for (i = 0; i < pipe->src_planes.num_planes; i++) - mdss_mdp_smp_mmb_set(client_id + i, &pipe->smp[i]); + mdss_mdp_smp_mmb_set(pipe->ftch_id + i, &pipe->smp[i]); mutex_unlock(&mdss_mdp_smp_lock); return 0; } @@ -179,88 +147,134 @@ int mdss_mdp_pipe_map(struct mdss_mdp_pipe *pipe) return 0; } -static struct mdss_mdp_pipe *mdss_mdp_pipe_init( - struct mdss_mdp_mixer *mixer, u32 pnum) +static struct mdss_mdp_pipe *mdss_mdp_pipe_init(struct mdss_mdp_mixer *mixer, + u32 type) { - struct mdss_mdp_pipe *pipe = NULL; + struct mdss_mdp_pipe *pipe; struct mdss_data_type *mdata; + struct mdss_mdp_pipe *pipe_pool = NULL; + u32 npipes; + u32 i; if (!mixer || !mixer->ctl || !mixer->ctl->mdata) return NULL; mdata = mixer->ctl->mdata; - pipe = &mdss_mdp_pipe_list[pnum]; - if (atomic_cmpxchg(&pipe->ref_cnt, 0, 1) == 0) { - pipe->num = pnum; - pipe->type = mdss_res->pipe_type_map[pnum]; - pipe->ndx = BIT(pnum); - pipe->base = mdata->mdp_base + MDSS_MDP_REG_SSPP_OFFSET(pnum); - pipe->mixer = mixer; + switch (type) { + case MDSS_MDP_PIPE_TYPE_VIG: + pipe_pool = mdata->vig_pipes; + npipes = mdata->nvig_pipes; + break; + + case MDSS_MDP_PIPE_TYPE_RGB: + pipe_pool = mdata->rgb_pipes; + npipes = mdata->nrgb_pipes; + break; + + case MDSS_MDP_PIPE_TYPE_DMA: + pipe_pool = mdata->dma_pipes; + npipes = mdata->ndma_pipes; + break; - pr_debug("ndx=%x pnum=%d\n", pipe->ndx, pipe->num); + default: + npipes = 0; + pr_err("invalid pipe type %d\n", type); + break; + } - return pipe; + for (i = 0; i < npipes; i++) { + pipe = pipe_pool + i; + if (atomic_cmpxchg(&pipe->ref_cnt, 0, 1) == 0) { + pipe->mixer = mixer; + break; + } + pipe = NULL; } - return NULL; + if (pipe) + pr_debug("type=%x pnum=%d\n", pipe->type, pipe->num); + else + pr_err("no %d type pipes available\n", type); + + return pipe; } -struct mdss_mdp_pipe *mdss_mdp_pipe_alloc_pnum( - struct mdss_mdp_mixer *mixer, u32 pnum) +struct mdss_mdp_pipe *mdss_mdp_pipe_alloc_dma(struct mdss_mdp_mixer *mixer) { struct mdss_mdp_pipe *pipe = NULL; + struct mdss_data_type *mdata; + u32 pnum; + mutex_lock(&mdss_mdp_sspp_lock); - if (mdss_res->pipe_type_map[pnum] != MDSS_MDP_PIPE_TYPE_UNUSED) - pipe = mdss_mdp_pipe_init(mixer, pnum); + mdata = mixer->ctl->mdata; + pnum = mixer->num; + + if (atomic_cmpxchg(&((mdata->dma_pipes[pnum]).ref_cnt), 0, 1) == 0) { + pipe = &mdata->dma_pipes[pnum]; + pipe->mixer = mixer; + + } else { + pr_err("DMA pnum%d\t not available\n", pnum); + } + mutex_unlock(&mdss_mdp_sspp_lock); return pipe; } -struct mdss_mdp_pipe *mdss_mdp_pipe_alloc( - struct mdss_mdp_mixer *mixer, u32 type) +struct mdss_mdp_pipe *mdss_mdp_pipe_alloc(struct mdss_mdp_mixer *mixer, + u32 type) { - struct mdss_mdp_pipe *pipe = NULL; - int pnum; - + struct mdss_mdp_pipe *pipe; mutex_lock(&mdss_mdp_sspp_lock); - for (pnum = 0; pnum < MDSS_MDP_MAX_SSPP; pnum++) { - if (type == mdss_res->pipe_type_map[pnum]) { - pipe = mdss_mdp_pipe_init(mixer, pnum); - if (pipe) - break; - } - } + pipe = mdss_mdp_pipe_init(mixer, type); mutex_unlock(&mdss_mdp_sspp_lock); - return pipe; } -struct mdss_mdp_pipe *mdss_mdp_pipe_get(u32 ndx) +struct mdss_mdp_pipe *mdss_mdp_pipe_get(struct mdss_data_type *mdata, u32 ndx) { struct mdss_mdp_pipe *pipe = NULL; - int i; if (!ndx) return ERR_PTR(-EINVAL); mutex_lock(&mdss_mdp_sspp_lock); - for (i = 0; i < MDSS_MDP_MAX_SSPP; i++) { - pipe = &mdss_mdp_pipe_list[i]; - if (ndx == pipe->ndx) { - if (mdss_mdp_pipe_map(pipe)) - pipe = ERR_PTR(-EACCES); - break; - } - } - mutex_unlock(&mdss_mdp_sspp_lock); - if (i == MDSS_MDP_MAX_SSPP) - return ERR_PTR(-ENODEV); + pipe = mdss_mdp_pipe_search(mdata, ndx); + if (!pipe) + return ERR_PTR(-EINVAL); + + if (mdss_mdp_pipe_map(pipe)) + return ERR_PTR(-EACCES); + + mutex_unlock(&mdss_mdp_sspp_lock); return pipe; } +static struct mdss_mdp_pipe *mdss_mdp_pipe_search(struct mdss_data_type *mdata, + u32 ndx) +{ + u32 i; + for (i = 0; i < mdata->nvig_pipes; i++) { + if (mdata->vig_pipes[i].ndx == ndx) + return &mdata->vig_pipes[i]; + } + + for (i = 0; i < mdata->nrgb_pipes; i++) { + if (mdata->rgb_pipes[i].ndx == ndx) + return &mdata->rgb_pipes[i]; + } + + for (i = 0; i < mdata->ndma_pipes; i++) { + if (mdata->dma_pipes[i].ndx == ndx) + return &mdata->dma_pipes[i]; + } + + return NULL; +} + static int mdss_mdp_pipe_free(struct mdss_mdp_pipe *pipe) { pr_debug("ndx=%x pnum=%d ref_cnt=%d\n", pipe->ndx, pipe->num, @@ -617,6 +631,53 @@ static void mdss_mdp_addr_add_offset(struct mdss_mdp_pipe *pipe, } } +int mdss_mdp_pipe_addr_setup(struct mdss_data_type *mdata, u32 *offsets, + u32 *ftch_id, u32 type, u32 num_base, u32 len) +{ + struct mdss_mdp_pipe *head; + u32 i; + int rc = 0; + + head = devm_kzalloc(&mdata->pdev->dev, sizeof(struct mdss_mdp_pipe) * + len, GFP_KERNEL); + + if (!head) { + pr_err("unable to setup pipe type=%d :devm_kzalloc fail\n", + type); + return -ENOMEM; + } + + for (i = 0; i < len; i++) { + head[i].type = type; + head[i].ftch_id = ftch_id[i]; + head[i].num = i + num_base; + head[i].ndx = BIT(i + num_base); + head[i].base = mdata->mdp_base + offsets[i]; + } + + switch (type) { + + case MDSS_MDP_PIPE_TYPE_VIG: + mdata->vig_pipes = head; + break; + + case MDSS_MDP_PIPE_TYPE_RGB: + mdata->rgb_pipes = head; + break; + + case MDSS_MDP_PIPE_TYPE_DMA: + mdata->dma_pipes = head; + break; + + default: + pr_err("Invalid pipe type=%d\n", type); + rc = -EINVAL; + break; + } + + return rc; +} + static int mdss_mdp_src_addr_setup(struct mdss_mdp_pipe *pipe, struct mdss_mdp_data *data) { diff --git a/drivers/video/fbdev/msm/mdss_mdp_pp.c b/drivers/video/fbdev/msm/mdss_mdp_pp.c index c14b2c21aad2..ee48f3170abf 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_pp.c +++ b/drivers/video/fbdev/msm/mdss_mdp_pp.c @@ -887,7 +887,7 @@ static int pp_get_dspp_num(u32 disp_num, u32 *dspp_num) { int i; u32 mixer_cnt; - u32 mixer_id[MDSS_MDP_MAX_LAYERMIXER]; + u32 mixer_id[MDSS_MDP_INTF_MAX_LAYERMIXER]; mixer_cnt = mdss_mdp_get_ctl_mixers(disp_num, mixer_id); if (!mixer_cnt) @@ -1599,7 +1599,7 @@ int mdss_mdp_histogram_start(struct mdp_histogram_start_req *req) struct pp_hist_col_info *hist_info; int i, ret = 0; u32 disp_num, dspp_num = 0; - u32 mixer_cnt, mixer_id[MDSS_MDP_MAX_LAYERMIXER]; + u32 mixer_cnt, mixer_id[MDSS_MDP_INTF_MAX_LAYERMIXER]; unsigned long flag; if ((req->block < MDP_LOGICAL_BLOCK_DISP_0) || @@ -1667,7 +1667,7 @@ int mdss_mdp_histogram_stop(u32 block) int i, ret = 0; u32 dspp_num, disp_num, ctl_base, done_bit; struct pp_hist_col_info *hist_info; - u32 mixer_cnt, mixer_id[MDSS_MDP_MAX_LAYERMIXER]; + u32 mixer_cnt, mixer_id[MDSS_MDP_INTF_MAX_LAYERMIXER]; unsigned long flag; if ((block < MDP_LOGICAL_BLOCK_DISP_0) || @@ -1726,7 +1726,7 @@ int mdss_mdp_hist_collect(struct fb_info *info, u32 timeout, v_base; struct pp_hist_col_info *hist_info; u32 dspp_num, disp_num, ctl_base; - u32 mixer_cnt, mixer_id[MDSS_MDP_MAX_LAYERMIXER]; + u32 mixer_cnt, mixer_id[MDSS_MDP_INTF_MAX_LAYERMIXER]; unsigned long flag; if ((hist->block < MDP_LOGICAL_BLOCK_DISP_0) || diff --git a/drivers/video/fbdev/msm/mdss_mdp_rotator.c b/drivers/video/fbdev/msm/mdss_mdp_rotator.c index 0ee336a110e7..8bff5cb4e95b 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_rotator.c +++ b/drivers/video/fbdev/msm/mdss_mdp_rotator.c @@ -70,25 +70,13 @@ static struct mdss_mdp_pipe *mdss_mdp_rotator_pipe_alloc(void) { struct mdss_mdp_mixer *mixer; struct mdss_mdp_pipe *pipe = NULL; - int pnum; mixer = mdss_mdp_wb_mixer_alloc(1); if (!mixer) return NULL; - switch (mixer->num) { - case MDSS_MDP_LAYERMIXER3: - pnum = MDSS_MDP_SSPP_DMA0; - break; - case MDSS_MDP_LAYERMIXER4: - pnum = MDSS_MDP_SSPP_DMA1; - break; - default: - goto done; - } + pipe = mdss_mdp_pipe_alloc_dma(mixer); - pipe = mdss_mdp_pipe_alloc_pnum(mixer, pnum); -done: if (!pipe) mdss_mdp_wb_mixer_destroy(mixer); |
