diff options
| author | Adrian Salido-Moreno <adrianm@codeaurora.org> | 2012-12-06 14:15:25 -0800 |
|---|---|---|
| committer | David Keitel <dkeitel@codeaurora.org> | 2016-03-23 20:14:18 -0700 |
| commit | fa1b60d13d37d28f16d65ae7aa8fb2f13dc2a251 (patch) | |
| tree | 9df781a1e1135254a6f19ddcb7139b7ddbdd07a0 /drivers/video/fbdev | |
| parent | 5f270e6406a9ad77433c14140defddc6a76ebe63 (diff) | |
msm: mdss: split out framebuffer info from data path controller
Separate framebuffer specific logic from data path controller.
This allows the framebuffer API to be agnostic of the actual
data path configuration and support more complex display use cases
more easily.
Change-Id: I5553552a352dea234c6fb33000a5c56a7d643251
Signed-off-by: Adrian Salido-Moreno <adrianm@codeaurora.org>
Diffstat (limited to 'drivers/video/fbdev')
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_fb.c | 3 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp.h | 7 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_ctl.c | 142 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_overlay.c | 51 |
4 files changed, 107 insertions, 96 deletions
diff --git a/drivers/video/fbdev/msm/mdss_fb.c b/drivers/video/fbdev/msm/mdss_fb.c index e016aab6629f..86df67cef584 100644 --- a/drivers/video/fbdev/msm/mdss_fb.c +++ b/drivers/video/fbdev/msm/mdss_fb.c @@ -1756,9 +1756,6 @@ int mdss_register_panel(struct mdss_panel_data *pdata) if (mfd->key != MFD_KEY) return -EINVAL; - mfd->on_fnc = mdss_mdp_ctl_on; - mfd->off_fnc = mdss_mdp_ctl_off; - rc = mdss_mdp_overlay_init(mfd); if (rc) pr_err("unable to init overlay\n"); diff --git a/drivers/video/fbdev/msm/mdss_mdp.h b/drivers/video/fbdev/msm/mdss_mdp.h index 3ae79af756b9..6bf691483b1e 100644 --- a/drivers/video/fbdev/msm/mdss_mdp.h +++ b/drivers/video/fbdev/msm/mdss_mdp.h @@ -291,8 +291,11 @@ int mdss_mdp_video_start(struct mdss_mdp_ctl *ctl); int mdss_mdp_writeback_start(struct mdss_mdp_ctl *ctl); int mdss_mdp_overlay_kickoff(struct mdss_mdp_ctl *ctl); -int mdss_mdp_ctl_on(struct msm_fb_data_type *mfd); -int mdss_mdp_ctl_off(struct msm_fb_data_type *mfd); +struct mdss_mdp_ctl *mdss_mdp_ctl_init(struct mdss_panel_data *pdata, + struct msm_fb_data_type *mfd); +int mdss_mdp_ctl_destroy(struct mdss_mdp_ctl *ctl); +int mdss_mdp_ctl_start(struct mdss_mdp_ctl *ctl); +int mdss_mdp_ctl_stop(struct mdss_mdp_ctl *ctl); int mdss_mdp_ctl_intf_event(struct mdss_mdp_ctl *ctl, int event, void *arg); struct mdss_mdp_mixer *mdss_mdp_wb_mixer_alloc(int rotator); diff --git a/drivers/video/fbdev/msm/mdss_mdp_ctl.c b/drivers/video/fbdev/msm/mdss_mdp_ctl.c index f4e43a40f570..81bec4d8bb0b 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_ctl.c +++ b/drivers/video/fbdev/msm/mdss_mdp_ctl.c @@ -386,41 +386,22 @@ int mdss_mdp_wb_mixer_destroy(struct mdss_mdp_mixer *mixer) return 0; } -static int mdss_mdp_ctl_init(struct msm_fb_data_type *mfd) +static int mdss_mdp_ctl_setup(struct mdss_mdp_ctl *ctl) { - struct mdss_mdp_ctl *ctl; - struct mdss_panel_data *pdata; u32 width, height; - int ret = 0; - - if (!mfd) - return -ENODEV; + int ret; - pdata = dev_get_platdata(&mfd->pdev->dev); - if (!pdata) { - pr_err("no panel connected for fb%d\n", mfd->index); + if (!ctl || !ctl->panel_data) { + pr_err("invalid ctl handle\n"); return -ENODEV; } - width = pdata->panel_info.xres; - height = pdata->panel_info.yres; + width = ctl->panel_data->panel_info.xres; + height = ctl->panel_data->panel_info.yres; if (width > (2 * MAX_MIXER_WIDTH)) { - pr_err("unsupported resolution\n"); - return -EINVAL; - } - - if (!mfd->ctl) { - ctl = mdss_mdp_ctl_alloc(); - if (!ctl) { - pr_err("unable to allocate ctl\n"); - return -ENOMEM; - } - ctl->mfd = mfd; - mfd->ctl = ctl; - ctl->panel_data = pdata; - } else { - ctl = mfd->ctl; + pr_err("Unsupported panel resolution: %dx%d\n", width, height); + return -ENOTSUPP; } ctl->width = width; @@ -432,7 +413,7 @@ static int mdss_mdp_ctl_init(struct msm_fb_data_type *mfd) if (!ctl->mixer_left) { pr_err("unable to allocate layer mixer\n"); ret = -ENOMEM; - goto ctl_init_fail; + goto setup_fail; } } @@ -450,7 +431,7 @@ static int mdss_mdp_ctl_init(struct msm_fb_data_type *mfd) if (!ctl->mixer_right) { pr_err("unable to allocate right mixer\n"); ret = -ENOMEM; - goto ctl_init_fail; + goto setup_fail; } } ctl->mixer_right->width = width; @@ -460,6 +441,38 @@ static int mdss_mdp_ctl_init(struct msm_fb_data_type *mfd) mdss_mdp_mixer_free(ctl->mixer_right); } + + if (ctl->mixer_right) { + ctl->opmode |= MDSS_MDP_CTL_OP_PACK_3D_ENABLE | + MDSS_MDP_CTL_OP_PACK_3D_H_ROW_INT; + } else { + ctl->opmode &= ~(MDSS_MDP_CTL_OP_PACK_3D_ENABLE | + MDSS_MDP_CTL_OP_PACK_3D_H_ROW_INT); + } + + return 0; +setup_fail: + if (ctl->mixer_left) + mdss_mdp_mixer_free(ctl->mixer_left); + if (ctl->mixer_right) + mdss_mdp_mixer_free(ctl->mixer_right); + return ret; +} + +struct mdss_mdp_ctl *mdss_mdp_ctl_init(struct mdss_panel_data *pdata, + struct msm_fb_data_type *mfd) +{ + struct mdss_mdp_ctl *ctl; + int ret = 0; + + ctl = mdss_mdp_ctl_alloc(); + if (!ctl) { + pr_err("unable to allocate ctl\n"); + return ERR_PTR(-ENOMEM); + } + ctl->mfd = mfd; + ctl->panel_data = pdata; + switch (pdata->panel_info.type) { case EDP_PANEL: ctl->intf_num = MDSS_MDP_INTF0; @@ -519,32 +532,19 @@ static int mdss_mdp_ctl_init(struct msm_fb_data_type *mfd) mdss_mdp_dither_config(&dither, NULL); } - if (ctl->mixer_right) { - ctl->opmode |= MDSS_MDP_CTL_OP_PACK_3D_ENABLE | - MDSS_MDP_CTL_OP_PACK_3D_H_ROW_INT; - } - + return ctl; ctl_init_fail: - if (IS_ERR_VALUE(ret)) { - if (ctl->mixer_left) - mdss_mdp_mixer_free(ctl->mixer_left); - if (ctl->mixer_right) - mdss_mdp_mixer_free(ctl->mixer_right); - mdss_mdp_ctl_free(ctl); - mfd->ctl = NULL; - } + mdss_mdp_ctl_free(ctl); - return ret; + return ERR_PTR(ret); } -static int mdss_mdp_ctl_destroy(struct msm_fb_data_type *mfd) +int mdss_mdp_ctl_destroy(struct mdss_mdp_ctl *ctl) { - struct mdss_mdp_ctl *ctl; - if (!mfd || !mfd->ctl) - return -ENODEV; + int rc; - ctl = mfd->ctl; - mfd->ctl = NULL; + rc = mdss_mdp_ctl_intf_event(ctl, MDSS_EVENT_CLOSE, NULL); + WARN(rc, "unable to close panel for intf=%d\n", ctl->intf_num); if (ctl->mixer_left) mdss_mdp_mixer_free(ctl->mixer_left); @@ -571,25 +571,15 @@ int mdss_mdp_ctl_intf_event(struct mdss_mdp_ctl *ctl, int event, void *arg) return 0; } -int mdss_mdp_ctl_on(struct msm_fb_data_type *mfd) +int mdss_mdp_ctl_start(struct mdss_mdp_ctl *ctl) { - struct mdss_mdp_ctl *ctl; struct mdss_mdp_mixer *mixer; u32 outsize, temp, off; int ret = 0; - if (!mfd) - return -ENODEV; - - if (mfd->key != MFD_KEY) - return -EINVAL; - - if (mdss_mdp_ctl_init(mfd)) { - pr_err("unable to initialize ctl\n"); - return -ENODEV; - } - - ctl = mfd->ctl; + ret = mdss_mdp_ctl_setup(ctl); + if (ret) + return ret; if (ctl->power_on) { WARN(1, "already on!\n"); @@ -654,36 +644,20 @@ int mdss_mdp_ctl_on(struct msm_fb_data_type *mfd) start_fail: mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false); mutex_unlock(&ctl->lock); - if (ret) - mdss_mdp_ctl_destroy(mfd); return ret; } -int mdss_mdp_ctl_off(struct msm_fb_data_type *mfd) +int mdss_mdp_ctl_stop(struct mdss_mdp_ctl *ctl) { - struct mdss_mdp_ctl *ctl; int ret = 0; - if (!mfd) - return -ENODEV; - - if (mfd->key != MFD_KEY) - return -EINVAL; - - if (!mfd->ctl) { - pr_err("ctl not initialized\n"); - return -ENODEV; - } - - ctl = mfd->ctl; - if (!ctl->power_on) { WARN(1, "already off!\n"); return 0; } - pr_debug("ctl_num=%d\n", mfd->ctl->num); + pr_debug("ctl_num=%d\n", ctl->num); mutex_lock(&ctl->lock); @@ -715,12 +689,6 @@ int mdss_mdp_ctl_off(struct msm_fb_data_type *mfd) mutex_unlock(&ctl->lock); - if (!ret && !mfd->ref_cnt) { - ret = mdss_mdp_ctl_intf_event(ctl, MDSS_EVENT_CLOSE, NULL); - WARN(ret, "unable to close intf %d\n", ctl->intf_num); - mdss_mdp_ctl_destroy(mfd); - } - return ret; } diff --git a/drivers/video/fbdev/msm/mdss_mdp_overlay.c b/drivers/video/fbdev/msm/mdss_mdp_overlay.c index 3956228c8d0a..ad905c5da9fc 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_overlay.c +++ b/drivers/video/fbdev/msm/mdss_mdp_overlay.c @@ -1244,9 +1244,38 @@ static int mdss_mdp_overlay_on(struct msm_fb_data_type *mfd) { int rc; - rc = mdss_mdp_ctl_on(mfd); - if (rc == 0) + if (!mfd) + return -ENODEV; + + if (mfd->key != MFD_KEY) + return -EINVAL; + + if (!mfd->ctl) { + struct mdss_mdp_ctl *ctl; + struct mdss_panel_data *pdata; + + pdata = dev_get_platdata(&mfd->pdev->dev); + if (!pdata) { + pr_err("no panel connected for fb%d\n", mfd->index); + return -ENODEV; + } + + ctl = mdss_mdp_ctl_init(pdata, mfd); + if (IS_ERR_OR_NULL(ctl)) { + pr_err("Unable to initialize ctl for fb%d\n", + mfd->index); + return PTR_ERR(ctl); + } + mfd->ctl = ctl; + } + + rc = mdss_mdp_ctl_start(mfd->ctl); + if (rc == 0) { atomic_inc(&ov_active_panels); + } else { + mdss_mdp_ctl_destroy(mfd->ctl); + mfd->ctl = NULL; + } return rc; } @@ -1255,12 +1284,26 @@ static int mdss_mdp_overlay_off(struct msm_fb_data_type *mfd) { int rc; + if (!mfd) + return -ENODEV; + + if (mfd->key != MFD_KEY) + return -EINVAL; + + if (!mfd->ctl) { + pr_err("ctl not initialized\n"); + return -ENODEV; + } + mdss_mdp_overlay_release_all(mfd); - rc = mdss_mdp_ctl_off(mfd); + rc = mdss_mdp_ctl_stop(mfd->ctl); if (rc == 0) { - if (!mfd->ref_cnt) + if (!mfd->ref_cnt) { mfd->borderfill_enable = false; + mdss_mdp_ctl_destroy(mfd->ctl); + mfd->ctl = NULL; + } if (atomic_dec_return(&ov_active_panels) == 0) mdss_mdp_rotator_release_all(); |
