diff options
| author | Narendra Muppalla <NarendraM@codeaurora.org> | 2017-01-25 11:26:33 -0800 |
|---|---|---|
| committer | Narendra Muppalla <NarendraM@codeaurora.org> | 2017-01-25 17:41:26 -0800 |
| commit | 72e48fcbf8556735aed848f6a7eadb22d5f360df (patch) | |
| tree | 75e4266d9e71c8327e518558c981e5982f7fb5b2 /drivers/gpu | |
| parent | e62b597893e84d3eea750df0ecc98daf86c2b622 (diff) | |
Revert "drm/msm/sde: add basic sde object enumeration"
This reverts 'commit 815cfffb81dd ("drm/msm/sde: add
basic sde object enumeration")'
This is partial change for display drm driver,
that will break drm/sde merge commit.
Change-Id: I5d58276f207485ac8ae80d8619282d2b62c0a695
Signed-off-by: Narendra Muppalla <NarendraM@codeaurora.org>
Diffstat (limited to 'drivers/gpu')
| -rw-r--r-- | drivers/gpu/drm/msm/Makefile | 3 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/sde/sde_crtc.c | 535 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/sde/sde_encoder.c | 552 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/sde/sde_hw_catalog_8996.c | 8 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/sde/sde_hw_intf.c | 22 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/sde/sde_hw_intf.h | 3 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/sde/sde_hw_lm.c | 4 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/sde/sde_hw_mdp_ctl.c | 54 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/sde/sde_hw_mdp_ctl.h | 44 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/sde/sde_hw_mdss.h | 43 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/sde/sde_hw_sspp.c | 56 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/sde/sde_hw_sspp.h | 18 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/sde/sde_kms.c | 243 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/sde/sde_kms.h | 26 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/sde/sde_mdp_formats.c | 134 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/sde/sde_mdp_formats.h | 123 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/sde/sde_plane.c | 709 |
17 files changed, 333 insertions, 2244 deletions
diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile index 549b534a3f4d..7b613a55fdc2 100644 --- a/drivers/gpu/drm/msm/Makefile +++ b/drivers/gpu/drm/msm/Makefile @@ -86,5 +86,4 @@ obj-$(CONFIG_DRM_MSM) += sde/sde_hw_catalog.o \ sde/sde_hw_mdp_util.o \ sde/sde_hw_sspp.o \ sde/sde_hw_wb.o \ - sde/sde_hw_pingpong.o \ - sde/sde_mdp_formats.o + sde/sde_hw_pingpong.o diff --git a/drivers/gpu/drm/msm/sde/sde_crtc.c b/drivers/gpu/drm/msm/sde/sde_crtc.c index 97ffb01f8b70..3ddad6f59180 100644 --- a/drivers/gpu/drm/msm/sde/sde_crtc.c +++ b/drivers/gpu/drm/msm/sde/sde_crtc.c @@ -10,7 +10,6 @@ * GNU General Public License for more details. */ -#include <linux/sort.h> #include <drm/drm_mode.h> #include <drm/drm_crtc.h> #include <drm/drm_crtc_helper.h> @@ -18,433 +17,73 @@ #include "sde_kms.h" #include "sde_hw_lm.h" -#include "sde_hw_mdp_ctl.h" - -#define CRTC_DUAL_MIXERS 2 -#define PENDING_FLIP 2 - -#define CRTC_HW_MIXER_MAXSTAGES(c, idx) ((c)->mixer[idx].sblk->maxblendstages) - -struct sde_crtc_mixer { - struct sde_hw_dspp *hw_dspp; - struct sde_hw_mixer *hw_lm; - struct sde_hw_ctl *hw_ctl; - u32 flush_mask; -}; +#include "sde_hw_mdss.h" struct sde_crtc { struct drm_crtc base; char name[8]; struct drm_plane *plane; struct drm_plane *planes[8]; - struct drm_encoder *encoder; int id; bool enabled; - - spinlock_t lm_lock; /* protect registers */ - - /* HW Resources reserved for the crtc */ - u32 num_ctls; - u32 num_mixers; - struct sde_crtc_mixer mixer[CRTC_DUAL_MIXERS]; - - /*if there is a pending flip, these will be non-null */ - struct drm_pending_vblank_event *event; + enum sde_lm mixer; + enum sde_ctl ctl_path; }; #define to_sde_crtc(x) container_of(x, struct sde_crtc, base) -static struct sde_kms *get_kms(struct drm_crtc *crtc) -{ - struct msm_drm_private *priv = crtc->dev->dev_private; - - return to_sde_kms(to_mdp_kms(priv->kms)); -} - -static inline struct sde_hw_ctl *sde_crtc_rm_get_ctl_path(enum sde_ctl idx, - void __iomem *addr, - struct sde_mdss_cfg *m) -{ - /* - * This module keeps track of the requested hw resources state, - * if the requested resource is being used it returns NULL, - * otherwise it returns the hw driver struct - */ - return sde_hw_ctl_init(idx, addr, m); -} - -static inline struct sde_hw_mixer *sde_crtc_rm_get_mixer(enum sde_lm idx, - void __iomem *addr, - struct sde_mdss_cfg *m) -{ - /* - * This module keeps track of the requested hw resources state, - * if the requested resource is being used it returns NULL, - * otherwise it returns the hw driver struct - */ - return sde_hw_lm_init(idx, addr, m); -} - -static int sde_crtc_reserve_hw_resources(struct drm_crtc *crtc, - struct drm_encoder *encoder) -{ - /* - * Assign CRTC resources - * num_ctls; - * num_mixers; - * sde_lm mixer[CRTC_MAX_PIPES]; - * sde_ctl ctl[CRTC_MAX_PIPES]; - */ - struct sde_crtc *sde_crtc = to_sde_crtc(crtc); - struct sde_kms *kms = get_kms(crtc); - enum sde_lm lm_id[CRTC_DUAL_MIXERS]; - enum sde_ctl ctl_id[CRTC_DUAL_MIXERS]; - int i; - - if (!kms) { - DBG("[%s] invalid kms\n", __func__); - return -EINVAL; - } - - if (!kms->mmio) - return -EINVAL; - - /* - * simple check validate against catalog - */ - sde_crtc->num_ctls = 1; - sde_crtc->num_mixers = 1; - ctl_id[0] = CTL_0; - lm_id[0] = LM_0; - - /* - * need to also enable MDP core clock and AHB CLK - * before touching HW driver - */ - DBG("%s Enable clocks\n", __func__); - sde_enable(kms); - for (i = 0; i < sde_crtc->num_ctls; i++) { - sde_crtc->mixer[i].hw_ctl = sde_crtc_rm_get_ctl_path(ctl_id[i], - kms->mmio, kms->catalog); - if (!sde_crtc->mixer[i].hw_ctl) { - DBG("[%s], Invalid ctl_path", __func__); - return -EACCES; - } - } - - for (i = 0; i < sde_crtc->num_mixers; i++) { - sde_crtc->mixer[i].hw_lm = sde_crtc_rm_get_mixer(lm_id[i], - kms->mmio, kms->catalog); - if (!sde_crtc->mixer[i].hw_lm) { - DBG("[%s], Invalid ctl_path", __func__); - return -EACCES; - } - } - /* - * need to disable MDP core clock and AHB CLK - */ - sde_disable(kms); - return 0; -} - static void sde_crtc_destroy(struct drm_crtc *crtc) { struct sde_crtc *sde_crtc = to_sde_crtc(crtc); - DBG(""); drm_crtc_cleanup(crtc); kfree(sde_crtc); } +static void sde_crtc_dpms(struct drm_crtc *crtc, int mode) +{ +} + static bool sde_crtc_mode_fixup(struct drm_crtc *crtc, const struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { - DBG(""); return true; } -static void sde_crtc_mode_set_nofb(struct drm_crtc *crtc) +static int sde_crtc_mode_set(struct drm_crtc *crtc, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode, + int x, int y, + struct drm_framebuffer *old_fb) { - struct sde_crtc *sde_crtc = to_sde_crtc(crtc); - struct sde_crtc_mixer *mixer = sde_crtc->mixer; - struct drm_device *dev = crtc->dev; - struct sde_hw_mixer *lm; - unsigned long flags; - struct drm_display_mode *mode; - struct sde_hw_mixer_cfg cfg; - u32 mixer_width; - int i; - int rc; - - DBG(""); - if (WARN_ON(!crtc->state)) - return; - - mode = &crtc->state->adjusted_mode; - - DBG("%s: set mode: %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x", - sde_crtc->name, mode->base.id, mode->name, - mode->vrefresh, mode->clock, - mode->hdisplay, mode->hsync_start, - mode->hsync_end, mode->htotal, - mode->vdisplay, mode->vsync_start, - mode->vsync_end, mode->vtotal, - mode->type, mode->flags); - - /* - * reserve mixer(s) if not already avaialable - * if dual mode, mixer_width = half mode width - * program mode configuration on mixer(s) - */ - if ((sde_crtc->num_ctls == 0) || - (sde_crtc->num_mixers == 0)) { - rc = sde_crtc_reserve_hw_resources(crtc, sde_crtc->encoder); - if (rc) { - dev_err(dev->dev, " error reserving HW resource for this CRTC\n"); - return; - } - } - - if (sde_crtc->num_mixers == CRTC_DUAL_MIXERS) - mixer_width = mode->hdisplay >> 1; - else - mixer_width = mode->hdisplay; - - spin_lock_irqsave(&sde_crtc->lm_lock, flags); - - for (i = 0; i < sde_crtc->num_mixers; i++) { - lm = mixer[i].hw_lm; - cfg.out_width = mixer_width; - cfg.out_height = mode->vdisplay; - cfg.right_mixer = (i == 0) ? false : true; - cfg.flags = 0; - lm->ops.setup_mixer_out(lm, &cfg); - } - - spin_unlock_irqrestore(&sde_crtc->lm_lock, flags); + return 0; } -static void sde_crtc_get_blend_cfg(struct sde_hw_blend_cfg *cfg, - struct sde_plane_state *pstate) +static void sde_crtc_prepare(struct drm_crtc *crtc) { - const struct mdp_format *format; - struct drm_plane *plane; - - format = to_mdp_format( - msm_framebuffer_format(pstate->base.fb)); - plane = pstate->base.plane; - - cfg->fg.alpha_sel = ALPHA_FG_CONST; - cfg->bg.alpha_sel = ALPHA_BG_CONST; - cfg->fg.const_alpha = pstate->alpha; - cfg->bg.const_alpha = 0xFF - pstate->alpha; - - if (format->alpha_enable && pstate->premultiplied) { - cfg->fg.alpha_sel = ALPHA_FG_CONST; - cfg->bg.alpha_sel = ALPHA_FG_PIXEL; - if (pstate->alpha != 0xff) { - cfg->bg.const_alpha = pstate->alpha; - cfg->bg.inv_alpha_sel = 1; - cfg->bg.mod_alpha = 1; - } else { - cfg->bg.inv_mode_alpha = 1; - } - } else if (format->alpha_enable) { - cfg->fg.alpha_sel = ALPHA_FG_PIXEL; - cfg->bg.alpha_sel = ALPHA_FG_PIXEL; - if (pstate->alpha != 0xff) { - cfg->bg.const_alpha = pstate->alpha; - cfg->fg.mod_alpha = 1; - cfg->bg.inv_alpha_sel = 1; - cfg->bg.mod_alpha = 1; - cfg->bg.inv_mode_alpha = 1; - } else { - cfg->bg.inv_mode_alpha = 1; - } - } } -static void blend_setup(struct drm_crtc *crtc) +static void sde_crtc_commit(struct drm_crtc *crtc) { - struct sde_crtc *sde_crtc = to_sde_crtc(crtc); - struct sde_crtc_mixer *mixer = sde_crtc->mixer; - struct drm_plane *plane; - struct sde_plane_state *pstate, *pstates[SDE_STAGE_MAX] = {0}; - struct sde_hw_stage_cfg stage_cfg; - struct sde_hw_blend_cfg blend; - struct sde_hw_ctl *ctl; - struct sde_hw_mixer *lm; - u32 flush_mask = 0; - unsigned long flags; - int i, j, plane_cnt = 0; - - spin_lock_irqsave(&sde_crtc->lm_lock, flags); - - /* ctl could be reserved already */ - if (!sde_crtc->num_ctls) - goto out; - - /* initialize stage cfg */ - memset(&stage_cfg, 0, sizeof(stage_cfg)); - memset(&blend, 0, sizeof(blend)); - - /* Collect all plane information */ - drm_atomic_crtc_for_each_plane(plane, crtc) { - pstate = to_sde_plane_state(plane->state); - pstates[pstate->stage] = pstate; - plane_cnt++; - for (i = 0; i < sde_crtc->num_mixers; i++) { - stage_cfg.stage[pstate->stage][i] = - sde_plane_pipe(plane); - - /* Cache the flushmask for this layer - * sourcesplit is always enabled, so this layer will - * be staged on both the mixers - */ - ctl = mixer[i].hw_ctl; - ctl->ops.get_bitmask_sspp(ctl, &flush_mask, - sde_plane_pipe(plane)); - } - } - - /* - * If there is no base layer, enable border color. - * currently border color is always black - */ - if ((stage_cfg.stage[SDE_STAGE_BASE][0] == SSPP_NONE) && - plane_cnt) { - stage_cfg.border_enable = 1; - DBG("Border Color is enabled\n"); - } - - /* Program hw */ - for (i = 0; i < sde_crtc->num_mixers; i++) { - if (!mixer[i].hw_lm) - continue; - - if (!mixer[i].hw_ctl) - continue; - - ctl = mixer[i].hw_ctl; - lm = mixer[i].hw_lm; - - /* stage config */ - ctl->ops.setup_blendstage(ctl, mixer[i].hw_lm->idx, - &stage_cfg); - /* stage config flush mask */ - mixer[i].flush_mask = flush_mask; - /* get the flush mask for mixer */ - ctl->ops.get_bitmask_mixer(ctl, &mixer[i].flush_mask, - mixer[i].hw_lm->idx); - - /* blend config */ - for (j = SDE_STAGE_0; j < SDE_STAGE_MAX; j++) { - if (!pstates[j]) - continue; - sde_crtc_get_blend_cfg(&blend, pstates[j]); - blend.fg.alpha_sel = ALPHA_FG_CONST; - blend.bg.alpha_sel = ALPHA_BG_CONST; - blend.fg.const_alpha = pstate->alpha; - blend.bg.const_alpha = 0xFF - pstate->alpha; - lm->ops.setup_blend_config(lm, j, &blend); - } - } -out: - spin_unlock_irqrestore(&sde_crtc->lm_lock, flags); } -static void request_pending(struct drm_crtc *crtc, u32 pending) -{ - DBG(""); -} -/** - * Flush the CTL PATH - */ -static u32 crtc_flush_all(struct drm_crtc *crtc) +static int sde_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, + struct drm_framebuffer *old_fb) { - struct sde_crtc *sde_crtc = to_sde_crtc(crtc); - struct sde_hw_ctl *ctl; - int i; - - DBG(""); - - for (i = 0; i < sde_crtc->num_ctls; i++) { - /* - * Query flush_mask from encoder - * and append to the ctl_path flush_mask - */ - ctl = sde_crtc->mixer[i].hw_ctl; - ctl->ops.get_bitmask_intf(ctl, - &(sde_crtc->mixer[i].flush_mask), - INTF_1); - ctl->ops.setup_flush(ctl, - sde_crtc->mixer[i].flush_mask); - } - return 0; } -static void sde_crtc_atomic_begin(struct drm_crtc *crtc, - struct drm_crtc_state *old_crtc_state) +static void sde_crtc_load_lut(struct drm_crtc *crtc) { - struct sde_crtc *sde_crtc = to_sde_crtc(crtc); - struct drm_device *dev = crtc->dev; - unsigned long flags; - - DBG(""); - - WARN_ON(sde_crtc->event); - - spin_lock_irqsave(&dev->event_lock, flags); - sde_crtc->event = crtc->state->event; - spin_unlock_irqrestore(&dev->event_lock, flags); - - /* - * If no CTL has been allocated in sde_crtc_atomic_check(), - * it means we are trying to flush a CRTC whose state is disabled: - * nothing else needs to be done. - */ - if (unlikely(!sde_crtc->num_ctls)) - return; - - blend_setup(crtc); - - /* - * PP_DONE irq is only used by command mode for now. - * It is better to request pending before FLUSH and START trigger - * to make sure no pp_done irq missed. - * This is safe because no pp_done will happen before SW trigger - * in command mode. - */ } -static void sde_crtc_atomic_flush(struct drm_crtc *crtc, - struct drm_crtc_state *old_crtc_state) +static int sde_crtc_page_flip(struct drm_crtc *crtc, + struct drm_framebuffer *new_fb, + struct drm_pending_vblank_event *event, + uint32_t page_flip_flags) { - struct sde_crtc *sde_crtc = to_sde_crtc(crtc); - struct drm_device *dev = crtc->dev; - unsigned long flags; - - DBG(""); - - WARN_ON(sde_crtc->event); - - spin_lock_irqsave(&dev->event_lock, flags); - sde_crtc->event = crtc->state->event; - spin_unlock_irqrestore(&dev->event_lock, flags); - - /* - * If no CTL has been allocated in sde_crtc_atomic_check(), - * it means we are trying to flush a CRTC whose state is disabled: - * nothing else needs to be done. - */ - if (unlikely(!sde_crtc->num_ctls)) - return; - - crtc_flush_all(crtc); - - request_pending(crtc, PENDING_FLIP); + return 0; } static int sde_crtc_set_property(struct drm_crtc *crtc, @@ -453,111 +92,21 @@ static int sde_crtc_set_property(struct drm_crtc *crtc, return -EINVAL; } -static int sde_crtc_cursor_set(struct drm_crtc *crtc, - struct drm_file *file, uint32_t handle, - uint32_t width, uint32_t height) -{ - return 0; -} - -static int sde_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) -{ - return 0; -} - -static void sde_crtc_disable(struct drm_crtc *crtc) -{ - DBG(""); -} - -static void sde_crtc_enable(struct drm_crtc *crtc) -{ - DBG(""); -} - -struct plane_state { - struct drm_plane *plane; - struct sde_plane_state *state; -}; - -static int pstate_cmp(const void *a, const void *b) -{ - struct plane_state *pa = (struct plane_state *)a; - struct plane_state *pb = (struct plane_state *)b; - - return pa->state->zpos - pb->state->zpos; -} - -static int sde_crtc_atomic_check(struct drm_crtc *crtc, - struct drm_crtc_state *state) -{ - struct sde_crtc *sde_crtc = to_sde_crtc(crtc); - struct sde_kms *sde_kms = get_kms(crtc); - struct drm_plane *plane; - struct drm_device *dev = crtc->dev; - struct plane_state pstates[SDE_STAGE_MAX]; - int max_stages = CRTC_HW_MIXER_MAXSTAGES(sde_kms->catalog, 0); - int cnt = 0, i; - - DBG("%s: check", sde_crtc->name); - - /* verify that there are not too many planes attached to crtc - * and that we don't have conflicting mixer stages: - */ - drm_atomic_crtc_state_for_each_plane(plane, state) { - struct drm_plane_state *pstate; - - if (cnt >= (max_stages)) { - dev_err(dev->dev, "too many planes!\n"); - return -EINVAL; - } - - pstate = state->state->plane_states[drm_plane_index(plane)]; - - /* plane might not have changed, in which case take - * current state: - */ - if (!pstate) - pstate = plane->state; - pstates[cnt].plane = plane; - pstates[cnt].state = to_sde_plane_state(pstate); - - cnt++; - } - - /* assign a stage based on sorted zpos property */ - sort(pstates, cnt, sizeof(pstates[0]), pstate_cmp, NULL); - - for (i = 0; i < cnt; i++) { - pstates[i].state->stage = SDE_STAGE_0 + i; - DBG("%s: assign pipe %d on stage=%d", sde_crtc->name, - sde_plane_pipe(pstates[i].plane), - pstates[i].state->stage); - } - - return 0; -} - static const struct drm_crtc_funcs sde_crtc_funcs = { - .set_config = drm_atomic_helper_set_config, + .set_config = drm_crtc_helper_set_config, .destroy = sde_crtc_destroy, - .page_flip = drm_atomic_helper_page_flip, + .page_flip = sde_crtc_page_flip, .set_property = sde_crtc_set_property, - .reset = drm_atomic_helper_crtc_reset, - .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state, - .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state, - .cursor_set = sde_crtc_cursor_set, - .cursor_move = sde_crtc_cursor_move, }; static const struct drm_crtc_helper_funcs sde_crtc_helper_funcs = { + .dpms = sde_crtc_dpms, .mode_fixup = sde_crtc_mode_fixup, - .mode_set_nofb = sde_crtc_mode_set_nofb, - .disable = sde_crtc_disable, - .enable = sde_crtc_enable, - .atomic_check = sde_crtc_atomic_check, - .atomic_begin = sde_crtc_atomic_begin, - .atomic_flush = sde_crtc_atomic_flush, + .mode_set = sde_crtc_mode_set, + .prepare = sde_crtc_prepare, + .commit = sde_crtc_commit, + .mode_set_base = sde_crtc_mode_set_base, + .load_lut = sde_crtc_load_lut, }; uint32_t sde_crtc_vblank(struct drm_crtc *crtc) @@ -569,20 +118,20 @@ void sde_crtc_cancel_pending_flip(struct drm_crtc *crtc, struct drm_file *file) { } -static void sde_crtc_install_properties(struct drm_crtc *crtc, - struct drm_mode_object *obj) +void sde_crtc_attach(struct drm_crtc *crtc, struct drm_plane *plane) { } +void sde_crtc_detach(struct drm_crtc *crtc, struct drm_plane *plane) +{ +} -/* initialize crtc */ struct drm_crtc *sde_crtc_init(struct drm_device *dev, struct drm_encoder *encoder, struct drm_plane *plane, int id) { struct drm_crtc *crtc = NULL; struct sde_crtc *sde_crtc; - int rc; sde_crtc = kzalloc(sizeof(*sde_crtc), GFP_KERNEL); if (!sde_crtc) @@ -591,21 +140,9 @@ struct drm_crtc *sde_crtc_init(struct drm_device *dev, crtc = &sde_crtc->base; sde_crtc->id = id; - sde_crtc->encoder = encoder; - sde_crtc_install_properties(crtc, &crtc->base); - - drm_crtc_init_with_planes(dev, crtc, plane, NULL, &sde_crtc_funcs); + /* find out if we need one or two lms */ drm_crtc_helper_add(crtc, &sde_crtc_helper_funcs); - plane->crtc = crtc; - - rc = sde_crtc_reserve_hw_resources(crtc, encoder); - if (rc) { - dev_err(dev->dev, " error reserving HW resource for this CRTC\n"); - return ERR_PTR(-EINVAL); - } - - DBG("%s: Successfully initialized crtc\n", __func__); return crtc; } diff --git a/drivers/gpu/drm/msm/sde/sde_encoder.c b/drivers/gpu/drm/msm/sde/sde_encoder.c index db3c57681675..11e13849d295 100644 --- a/drivers/gpu/drm/msm/sde/sde_encoder.c +++ b/drivers/gpu/drm/msm/sde/sde_encoder.c @@ -14,566 +14,82 @@ #include "drm_crtc.h" #include "drm_crtc_helper.h" -#include "sde_hwio.h" -#include "sde_hw_catalog.h" -#include "sde_hw_intf.h" -#include "sde_hw_mdp_ctl.h" -#include "sde_mdp_formats.h" - -#include "../dsi-staging/dsi_display.h" - -#define DBG(fmt, ...) DRM_DEBUG(fmt"\n", ##__VA_ARGS__) - struct sde_encoder { struct drm_encoder base; - spinlock_t intf_lock; - bool enabled; - uint32_t bus_scaling_client; - struct sde_hw_intf *hw_intf; - struct sde_hw_ctl *hw_ctl; - int drm_mode_enc; - - void (*vblank_callback)(void *); - void *vblank_callback_data; - - struct mdp_irq vblank_irq; + int intf; }; #define to_sde_encoder(x) container_of(x, struct sde_encoder, base) -static struct sde_kms *get_kms(struct drm_encoder *drm_enc) +static void sde_encoder_destroy(struct drm_encoder *encoder) { - struct msm_drm_private *priv = drm_enc->dev->dev_private; + struct sde_encoder *sde_encoder = to_sde_encoder(encoder); - return to_sde_kms(to_mdp_kms(priv->kms)); + drm_encoder_cleanup(encoder); + kfree(sde_encoder); } -#ifdef CONFIG_QCOM_BUS_SCALING -#include <linux/msm-bus.h> -#include <linux/msm-bus-board.h> -#define MDP_BUS_VECTOR_ENTRY(ab_val, ib_val) \ - { \ - .src = MSM_BUS_MASTER_MDP_PORT0, \ - .dst = MSM_BUS_SLAVE_EBI_CH0, \ - .ab = (ab_val), \ - .ib = (ib_val), \ - } - -static struct msm_bus_vectors mdp_bus_vectors[] = { - MDP_BUS_VECTOR_ENTRY(0, 0), - MDP_BUS_VECTOR_ENTRY(2000000000, 2000000000), -}; -static struct msm_bus_paths mdp_bus_usecases[] = { { - .num_paths = 1, - .vectors = - &mdp_bus_vectors[0], - }, { - .num_paths = 1, - .vectors = - &mdp_bus_vectors[1], - } -}; - -static struct msm_bus_scale_pdata mdp_bus_scale_table = { - .usecase = mdp_bus_usecases, - .num_usecases = ARRAY_SIZE(mdp_bus_usecases), - .name = "mdss_mdp", +static const struct drm_encoder_funcs sde_encoder_funcs = { + .destroy = sde_encoder_destroy, }; -static void bs_init(struct sde_encoder *sde_enc) +static void sde_encoder_dpms(struct drm_encoder *encoder, int mode) { - sde_enc->bus_scaling_client = - msm_bus_scale_register_client(&mdp_bus_scale_table); - DBG("bus scale client: %08x", sde_enc->bus_scaling_client); -} - -static void bs_fini(struct sde_encoder *sde_enc) -{ - if (sde_enc->bus_scaling_client) { - msm_bus_scale_unregister_client(sde_enc->bus_scaling_client); - sde_enc->bus_scaling_client = 0; - } } -static void bs_set(struct sde_encoder *sde_enc, int idx) +static bool sde_encoder_mode_fixup(struct drm_encoder *encoder, + const struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) { - if (sde_enc->bus_scaling_client) { - DBG("set bus scaling: %d", idx); - idx = 1; - msm_bus_scale_client_update_request(sde_enc->bus_scaling_client, - idx); - } -} -#else -static void bs_init(struct sde_encoder *sde_enc) -{ -} - -static void bs_fini(struct sde_encoder *sde_enc) -{ -} - -static void bs_set(struct sde_encoder *sde_enc, int idx) -{ -} -#endif - -static bool sde_encoder_mode_fixup(struct drm_encoder *drm_enc, - const struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - DBG(""); return true; } -static void sde_encoder_mode_set(struct drm_encoder *drm_enc, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) +static void sde_encoder_mode_set(struct drm_encoder *encoder, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) { - - struct sde_encoder *sde_enc = to_sde_encoder(drm_enc); - struct intf_timing_params p = {0}; - uint32_t hsync_polarity = 0, vsync_polarity = 0; - struct sde_mdp_format_params *sde_fmt_params = NULL; - u32 fmt_fourcc = DRM_FORMAT_RGB888, fmt_mod = 0; - unsigned long lock_flags; - struct sde_hw_intf_cfg intf_cfg = {0}; - - mode = adjusted_mode; - - DBG("set mode: %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x", - mode->base.id, mode->name, mode->vrefresh, mode->clock, - mode->hdisplay, mode->hsync_start, mode->hsync_end, mode->htotal, - mode->vdisplay, mode->vsync_start, mode->vsync_end, mode->vtotal, - mode->type, mode->flags); - - /* DSI controller cannot handle active-low sync signals. */ - if (sde_enc->hw_intf->cap->type != INTF_DSI) { - if (mode->flags & DRM_MODE_FLAG_NHSYNC) - hsync_polarity = 1; - if (mode->flags & DRM_MODE_FLAG_NVSYNC) - vsync_polarity = 1; - } - - /* - * For edp only: - * DISPLAY_V_START = (VBP * HCYCLE) + HBP - * DISPLAY_V_END = (VBP + VACTIVE) * HCYCLE - 1 - HFP - */ - /* - * if (sde_enc->hw->cap->type == INTF_EDP) { - * display_v_start += mode->htotal - mode->hsync_start; - * display_v_end -= mode->hsync_start - mode->hdisplay; - * } - */ - - /* - * https://www.kernel.org/doc/htmldocs/drm/ch02s05.html - * Active Region Front Porch Sync Back Porch - * <---------------------><----------------><---------><--------------> - * <--- [hv]display -----> - * <----------- [hv]sync_start ------------> - * <------------------- [hv]sync_end -----------------> - * <------------------------------ [hv]total -------------------------> - */ - - sde_fmt_params = sde_mdp_get_format_params(fmt_fourcc, fmt_mod); - - p.width = mode->hdisplay; /* active width */ - p.height = mode->vdisplay; /* active height */ - p.xres = p.width; /* Display panel width */ - p.yres = p.height; /* Display panel height */ - p.h_back_porch = mode->htotal - mode->hsync_end; - p.h_front_porch = mode->hsync_start - mode->hdisplay; - p.v_back_porch = mode->vtotal - mode->vsync_end; - p.v_front_porch = mode->vsync_start - mode->vdisplay; - p.hsync_pulse_width = mode->hsync_end - mode->hsync_start; - p.vsync_pulse_width = mode->vsync_end - mode->vsync_start; - p.hsync_polarity = hsync_polarity; - p.vsync_polarity = vsync_polarity; - p.border_clr = 0; - p.underflow_clr = 0xff; - p.hsync_skew = mode->hskew; - - intf_cfg.intf = sde_enc->hw_intf->idx; - intf_cfg.wb = SDE_NONE; - - spin_lock_irqsave(&sde_enc->intf_lock, lock_flags); - sde_enc->hw_intf->ops.setup_timing_gen(sde_enc->hw_intf, &p, - sde_fmt_params); - sde_enc->hw_ctl->ops.setup_intf_cfg(sde_enc->hw_ctl, &intf_cfg); - spin_unlock_irqrestore(&sde_enc->intf_lock, lock_flags); -} - -static void sde_encoder_wait_for_vblank(struct sde_encoder *sde_enc) -{ - struct sde_kms *sde_kms = get_kms(&sde_enc->base); - struct mdp_kms *mdp_kms = &sde_kms->base; - - DBG(""); - mdp_irq_wait(mdp_kms, sde_enc->vblank_irq.irqmask); -} - -static void sde_encoder_vblank_irq(struct mdp_irq *irq, uint32_t irqstatus) -{ - struct sde_encoder *sde_enc = container_of(irq, struct sde_encoder, - vblank_irq); - struct intf_status status = { 0 }; - unsigned long lock_flags; - - spin_lock_irqsave(&sde_enc->intf_lock, lock_flags); - if (sde_enc->vblank_callback) - sde_enc->vblank_callback(sde_enc->vblank_callback_data); - spin_unlock_irqrestore(&sde_enc->intf_lock, lock_flags); - - sde_enc->hw_intf->ops.get_status(sde_enc->hw_intf, &status); -} - -static void sde_encoder_disable(struct drm_encoder *drm_enc) -{ - struct sde_encoder *sde_enc = to_sde_encoder(drm_enc); - struct sde_kms *sde_kms = get_kms(drm_enc); - struct mdp_kms *mdp_kms = &(sde_kms->base); - unsigned long lock_flags; - - DBG(""); - - if (WARN_ON(!sde_enc->enabled)) - return; - - spin_lock_irqsave(&sde_enc->intf_lock, lock_flags); - sde_enc->hw_intf->ops.enable_timing(sde_enc->hw_intf, 0); - spin_unlock_irqrestore(&sde_enc->intf_lock, lock_flags); - - /* - * Wait for a vsync so we know the ENABLE=0 latched before - * the (connector) source of the vsync's gets disabled, - * otherwise we end up in a funny state if we re-enable - * before the disable latches, which results that some of - * the settings changes for the new modeset (like new - * scanout buffer) don't latch properly.. - */ - sde_encoder_wait_for_vblank(sde_enc); - - mdp_irq_unregister(mdp_kms, &sde_enc->vblank_irq); - bs_set(sde_enc, 0); - sde_enc->enabled = false; } -static void sde_encoder_enable(struct drm_encoder *drm_enc) +static void sde_encoder_prepare(struct drm_encoder *encoder) { - struct sde_encoder *sde_enc = to_sde_encoder(drm_enc); - struct mdp_kms *mdp_kms = &(get_kms(drm_enc)->base); - unsigned long lock_flags; - - DBG(""); - - if (WARN_ON(sde_enc->enabled)) - return; - - bs_set(sde_enc, 1); - spin_lock_irqsave(&sde_enc->intf_lock, lock_flags); - sde_enc->hw_intf->ops.enable_timing(sde_enc->hw_intf, 1); - spin_unlock_irqrestore(&sde_enc->intf_lock, lock_flags); - sde_enc->enabled = true; - - mdp_irq_register(mdp_kms, &sde_enc->vblank_irq); - DBG("Registered IRQ for intf %d mask 0x%X", sde_enc->hw_intf->idx, - sde_enc->vblank_irq.irqmask); } -void sde_encoder_get_hw_resources(struct drm_encoder *drm_enc, - struct sde_encoder_hw_resources *hw_res) +static void sde_encoder_commit(struct drm_encoder *encoder) { - struct sde_encoder *sde_enc = to_sde_encoder(drm_enc); - - DBG(""); - - if (WARN_ON(!hw_res)) - return; - - memset(hw_res, 0, sizeof(*hw_res)); - hw_res->intfs[sde_enc->hw_intf->idx] = true; -} - -static void sde_encoder_destroy(struct drm_encoder *drm_enc) -{ - struct sde_encoder *sde_enc = to_sde_encoder(drm_enc); - - DBG(""); - drm_encoder_cleanup(drm_enc); - bs_fini(sde_enc); - kfree(sde_enc->hw_intf); - kfree(sde_enc); } static const struct drm_encoder_helper_funcs sde_encoder_helper_funcs = { + .dpms = sde_encoder_dpms, .mode_fixup = sde_encoder_mode_fixup, .mode_set = sde_encoder_mode_set, - .disable = sde_encoder_disable, - .enable = sde_encoder_enable, -}; - -static const struct drm_encoder_funcs sde_encoder_funcs = {.destroy = - sde_encoder_destroy, -}; - -static int sde_encoder_setup_hw(struct sde_encoder *sde_enc, - struct sde_kms *sde_kms, - enum sde_intf intf_idx, - enum sde_ctl ctl_idx) -{ - int ret = 0; - - DBG(""); - - sde_enc->hw_intf = sde_hw_intf_init(intf_idx, sde_kms->mmio, - sde_kms->catalog); - if (!sde_enc->hw_intf) - return -EINVAL; - - sde_enc->hw_ctl = sde_hw_ctl_init(ctl_idx, sde_kms->mmio, - sde_kms->catalog); - if (!sde_enc->hw_ctl) - return -EINVAL; - - return ret; -} - -static int sde_encoder_virt_add_phys_vid_enc(struct sde_encoder *sde_enc, - struct sde_kms *sde_kms, - enum sde_intf intf_idx, - enum sde_ctl ctl_idx) -{ - int ret = 0; - - DBG(""); - - ret = sde_encoder_setup_hw(sde_enc, sde_kms, intf_idx, ctl_idx); - if (!ret) { - sde_enc->vblank_irq.irq = sde_encoder_vblank_irq; - sde_enc->vblank_irq.irqmask = 0x8000000; - } - return ret; -} - -static int sde_encoder_setup_hdmi(struct sde_encoder *sde_enc, - struct sde_kms *sde_kms, int *hdmi_info) -{ - int ret = 0; - enum sde_intf intf_idx = INTF_MAX; - - DBG(""); - - sde_enc->drm_mode_enc = DRM_MODE_ENCODER_TMDS; - - intf_idx = INTF_3; - if (intf_idx == INTF_MAX) - ret = -EINVAL; - - if (!ret) - ret = - sde_encoder_virt_add_phys_vid_enc(sde_enc, sde_kms, - intf_idx, - CTL_2); - - return ret; -} - -static int sde_encoder_setup_dsi(struct sde_encoder *sde_enc, - struct sde_kms *sde_kms, - struct dsi_display_info *dsi_info) -{ - int ret = 0; - int i = 0; - - DBG(""); - - sde_enc->drm_mode_enc = DRM_MODE_ENCODER_DSI; - - if (WARN_ON(dsi_info->num_of_h_tiles > 1)) { - DBG("Dual DSI mode not yet supported"); - ret = -EINVAL; - } - - WARN_ON(dsi_info->num_of_h_tiles != 1); - dsi_info->num_of_h_tiles = 1; - - DBG("dsi_info->num_of_h_tiles %d h_tiled %d dsi_info->h_tile_ids %d ", - dsi_info->num_of_h_tiles, dsi_info->h_tiled, - dsi_info->h_tile_ids[0]); - - for (i = 0; i < !ret && dsi_info->num_of_h_tiles; i++) { - enum sde_intf intf_idx = INTF_1; - enum sde_ctl ctl_idx = CTL_0; - - if (intf_idx == INTF_MAX) { - DBG("Error: could not get the interface id"); - ret = -EINVAL; - } - - /* Get DSI modes, create both VID & CMD Phys Encoders */ - if (!ret) - ret = - sde_encoder_virt_add_phys_vid_enc(sde_enc, sde_kms, - intf_idx, - ctl_idx); - } - - return ret; -} - -struct display_probe_info { - enum sde_intf_type type; - struct dsi_display_info dsi_info; - int hdmi_info; + .prepare = sde_encoder_prepare, + .commit = sde_encoder_commit, }; -static struct drm_encoder *sde_encoder_virt_init(struct drm_device *dev, - struct display_probe_info - *display) +/* initialize encoder */ +struct drm_encoder *sde_encoder_init(struct drm_device *dev, int intf) { - struct msm_drm_private *priv = dev->dev_private; - struct sde_kms *sde_kms = to_sde_kms(to_mdp_kms(priv->kms)); - struct drm_encoder *drm_enc = NULL; - struct sde_encoder *sde_enc = NULL; - int ret = 0; + struct drm_encoder *encoder = NULL; + struct sde_encoder *sde_encoder; + int ret; - DBG(""); - - sde_enc = kzalloc(sizeof(*sde_enc), GFP_KERNEL); - if (!sde_enc) { + sde_encoder = kzalloc(sizeof(*sde_encoder), GFP_KERNEL); + if (!sde_encoder) { ret = -ENOMEM; goto fail; } - if (display->type == INTF_DSI) { - ret = - sde_encoder_setup_dsi(sde_enc, sde_kms, &display->dsi_info); - } else if (display->type == INTF_HDMI) { - ret = - sde_encoder_setup_hdmi(sde_enc, sde_kms, - &display->hdmi_info); - } else { - DBG("No valid displays found"); - ret = -EINVAL; - } - if (ret) - goto fail; + sde_encoder->intf = intf; + encoder = &sde_encoder->base; - spin_lock_init(&sde_enc->intf_lock); - drm_enc = &sde_enc->base; - drm_encoder_init(dev, drm_enc, &sde_encoder_funcs, - sde_enc->drm_mode_enc); - drm_encoder_helper_add(drm_enc, &sde_encoder_helper_funcs); - bs_init(sde_enc); + drm_encoder_init(dev, encoder, &sde_encoder_funcs, + DRM_MODE_ENCODER_TMDS); + drm_encoder_helper_add(encoder, &sde_encoder_helper_funcs); - DBG("Created sde_encoder for intf %d", sde_enc->hw_intf->idx); - - return drm_enc; + return encoder; fail: - if (drm_enc) - sde_encoder_destroy(drm_enc); + if (encoder) + sde_encoder_destroy(encoder); return ERR_PTR(ret); } - -static int sde_encoder_probe_hdmi(struct drm_device *dev) -{ - struct msm_drm_private *priv = dev->dev_private; - struct drm_encoder *enc = NULL; - struct display_probe_info probe_info = { 0 }; - int ret = 0; - - DBG(""); - - probe_info.type = INTF_HDMI; - - enc = sde_encoder_virt_init(dev, &probe_info); - if (IS_ERR(enc)) - ret = PTR_ERR(enc); - else { - /* Register new encoder with the upper layer */ - priv->encoders[priv->num_encoders++] = enc; - } - return ret; -} - -static int sde_encoder_probe_dsi(struct drm_device *dev) -{ - struct msm_drm_private *priv = dev->dev_private; - u32 ret = 0; - u32 i = 0; - u32 num_displays = 0; - - DBG(""); - - num_displays = dsi_display_get_num_of_displays(); - DBG("num_displays %d", num_displays); - for (i = 0; i < num_displays; i++) { - struct dsi_display *dsi = dsi_display_get_display_by_index(i); - - if (dsi_display_is_active(dsi)) { - struct display_probe_info probe_info = { 0 }; - - DBG("display %d/%d is active", i, num_displays); - probe_info.type = INTF_DSI; - - ret = dsi_display_get_info(dsi, &probe_info.dsi_info); - if (WARN_ON(ret)) - DBG("Failed to retrieve dsi panel info"); - else { - struct drm_encoder *enc = - sde_encoder_virt_init(dev, - &probe_info); - if (IS_ERR(enc)) - return PTR_ERR(enc); - - ret = dsi_display_drm_init(dsi, enc); - if (ret) - return ret; - - /* Register new encoder with the upper layer */ - priv->encoders[priv->num_encoders++] = enc; - } - } else - DBG("display %d/%d is not active", i, num_displays); - } - - return ret; -} - -void sde_encoder_register_vblank_callback(struct drm_encoder *drm_enc, - void (*cb)(void *), void *data) { - struct sde_encoder *sde_enc = to_sde_encoder(drm_enc); - unsigned long lock_flags; - - DBG(""); - - spin_lock_irqsave(&sde_enc->intf_lock, lock_flags); - sde_enc->vblank_callback = cb; - sde_enc->vblank_callback_data = data; - spin_unlock_irqrestore(&sde_enc->intf_lock, lock_flags); -} - -/* encoders init, - * initialize encoder based on displays - */ -void sde_encoders_init(struct drm_device *dev) -{ - struct msm_drm_private *priv = dev->dev_private; - int ret = 0; - - DBG(""); - - /* Start num_encoders at 0, probe functions will increment */ - priv->num_encoders = 0; - ret = sde_encoder_probe_dsi(dev); - if (ret) - DBG("Error probing DSI, %d", ret); - else { - ret = sde_encoder_probe_hdmi(dev); - if (ret) - DBG("Error probing HDMI, %d", ret); - } -} diff --git a/drivers/gpu/drm/msm/sde/sde_hw_catalog_8996.c b/drivers/gpu/drm/msm/sde/sde_hw_catalog_8996.c index 5390742745e6..a9a1f05a00eb 100644 --- a/drivers/gpu/drm/msm/sde/sde_hw_catalog_8996.c +++ b/drivers/gpu/drm/msm/sde/sde_hw_catalog_8996.c @@ -171,13 +171,13 @@ static inline int set_cfg_1xx_init(struct sde_mdss_cfg *cfg) {.id = SSPP_VIG3, .base = 0x0000b000, .features = VIG_17X_MASK, .sblk = &layer}, - {.id = SSPP_RGB0, .base = 0x00015000, + {.id = SSPP_RGB0, .base = 0x00001500, .features = RGB_17X_MASK, .sblk = &layer}, - {.id = SSPP_RGB1, .base = 0x00017000, + {.id = SSPP_RGB1, .base = 0x00001700, .features = RGB_17X_MASK, .sblk = &layer}, - {.id = SSPP_RGB2, .base = 0x00019000, + {.id = SSPP_RGB2, .base = 0x00001900, .features = RGB_17X_MASK, .sblk = &layer}, - {.id = SSPP_RGB3, .base = 0x0001B000, + {.id = SSPP_RGB3, .base = 0x00001B00, .features = RGB_17X_MASK, .sblk = &layer}, {.id = SSPP_DMA0, .base = 0x00025000, diff --git a/drivers/gpu/drm/msm/sde/sde_hw_intf.c b/drivers/gpu/drm/msm/sde/sde_hw_intf.c index 072cb6770bc8..b108e34de24f 100644 --- a/drivers/gpu/drm/msm/sde/sde_hw_intf.c +++ b/drivers/gpu/drm/msm/sde/sde_hw_intf.c @@ -70,8 +70,7 @@ static struct sde_intf_cfg *_intf_offset(enum sde_intf intf, int i; for (i = 0; i < m->intf_count; i++) { - if ((intf == m->intf[i].id) && - (m->intf[i].type != INTF_NONE)) { + if (intf == m->intf[i].id) { b->base_off = addr; b->blk_off = m->intf[i].base; b->hwversion = m->hwversion; @@ -159,13 +158,13 @@ static void sde_hw_intf_setup_timing_engine(struct sde_hw_intf *ctx, (hsync_polarity << 0); /* HSYNC Polarity */ if (!fmt->is_yuv) - panel_format = (fmt->bits[C0_G_Y] | - (fmt->bits[C1_B_Cb] << 2) | - (fmt->bits[C2_R_Cr] << 4) | + panel_format = (fmt->bits[0] | + (fmt->bits[1] << 2) | + (fmt->bits[2] << 4) | (0x21 << 8)); else - /* Interface treats all the pixel data in RGB888 format */ - panel_format = (COLOR_8BIT | + /* Interface treats all the pixel data in RGB888 format */ + panel_format |= (COLOR_8BIT | (COLOR_8BIT << 2) | (COLOR_8BIT << 4) | (0x21 << 8)); @@ -355,9 +354,8 @@ struct sde_hw_intf *sde_hw_intf_init(enum sde_intf idx, return ERR_PTR(-ENOMEM); cfg = _intf_offset(idx, m, addr, &c->hw); - if (IS_ERR_OR_NULL(cfg)) { + if (!cfg) { kfree(c); - pr_err("Error Panic\n"); return ERR_PTR(-EINVAL); } @@ -373,9 +371,3 @@ struct sde_hw_intf *sde_hw_intf_init(enum sde_intf idx, */ return c; } - -void sde_hw_intf_deinit(struct sde_hw_intf *intf) -{ - kfree(intf); -} - diff --git a/drivers/gpu/drm/msm/sde/sde_hw_intf.h b/drivers/gpu/drm/msm/sde/sde_hw_intf.h index 2dc8c52209f0..f0d8a32dc802 100644 --- a/drivers/gpu/drm/msm/sde/sde_hw_intf.h +++ b/drivers/gpu/drm/msm/sde/sde_hw_intf.h @@ -15,7 +15,6 @@ #include "sde_hw_catalog.h" #include "sde_hw_mdss.h" -#include "sde_hw_mdp_util.h" struct sde_hw_intf; @@ -101,6 +100,4 @@ struct sde_hw_intf *sde_hw_intf_init(enum sde_intf idx, void __iomem *addr, struct sde_mdss_cfg *m); -void sde_hw_intf_deinit(struct sde_hw_intf *intf); - #endif /*_SDE_HW_INTF_H */ diff --git a/drivers/gpu/drm/msm/sde/sde_hw_lm.c b/drivers/gpu/drm/msm/sde/sde_hw_lm.c index 03704ddf4980..0a20821f3a32 100644 --- a/drivers/gpu/drm/msm/sde/sde_hw_lm.c +++ b/drivers/gpu/drm/msm/sde/sde_hw_lm.c @@ -58,7 +58,7 @@ static inline int _stage_offset(struct sde_hw_mixer *ctx, enum sde_stage stage) return -EINVAL; if ((stage - SDE_STAGE_0) <= sblk->maxblendstages) - return sblk->blendstage_base[stage - 1]; + return sblk->blendstage_base[stage]; else return -EINVAL; } @@ -126,7 +126,7 @@ static void sde_hw_lm_setup_blendcfg(struct sde_hw_mixer *ctx, SDE_REG_WRITE(c, LM_BLEND0_FG_ALPHA + stage_off, fg->const_alpha); - SDE_REG_WRITE(c, LM_BLEND0_BG_ALPHA + stage_off, + SDE_REG_WRITE(c, LM_BLEND0_FG_ALPHA + stage_off, bg->const_alpha); SDE_REG_WRITE(c, LM_OP_MODE, blend_op); } diff --git a/drivers/gpu/drm/msm/sde/sde_hw_mdp_ctl.c b/drivers/gpu/drm/msm/sde/sde_hw_mdp_ctl.c index f7181ab9ed3d..4886cdf87c9f 100644 --- a/drivers/gpu/drm/msm/sde/sde_hw_mdp_ctl.c +++ b/drivers/gpu/drm/msm/sde/sde_hw_mdp_ctl.c @@ -15,9 +15,9 @@ #include "sde_hw_mdp_ctl.h" #define CTL_LAYER(lm) \ - (((lm) == LM_5) ? (0x024) : (((lm) - LM_0) * 0x004)) + (((lm) == 5) ? (0x024) : ((lm) * 0x004)) #define CTL_LAYER_EXT(lm) \ - (0x40 + (((lm) - LM_0) * 0x004)) + (0x40 + ((lm) * 0x004)) #define CTL_TOP 0x014 #define CTL_FLUSH 0x018 #define CTL_START 0x01C @@ -61,14 +61,15 @@ static int _mixer_stages(const struct sde_lm_cfg *mixer, int count, return stages; } -static inline void sde_hw_ctl_force_start(struct sde_hw_ctl *ctx) +static inline void sde_hw_ctl_setup_flush(struct sde_hw_ctl *ctx, u32 flushbits, + u8 force_start) { - SDE_REG_WRITE(&ctx->hw, CTL_START, 0x1); -} + struct sde_hw_blk_reg_map *c = &ctx->hw; -static inline void sde_hw_ctl_setup_flush(struct sde_hw_ctl *ctx, u32 flushbits) -{ - SDE_REG_WRITE(&ctx->hw, CTL_FLUSH, flushbits); + SDE_REG_WRITE(c, CTL_FLUSH, flushbits); + + if (force_start) + SDE_REG_WRITE(c, CTL_START, 0x1); } static inline int sde_hw_ctl_get_bitmask_sspp(struct sde_hw_ctl *ctx, @@ -221,7 +222,7 @@ static void sde_hw_ctl_setup_blendstage(struct sde_hw_ctl *ctx, struct sde_hw_stage_cfg *cfg) { struct sde_hw_blk_reg_map *c = &ctx->hw; - u32 mixercfg, mixercfg_ext = 0; + u32 mixercfg, mixercfg_ext; int i, j; u8 stages; int pipes_per_stage; @@ -236,8 +237,8 @@ static void sde_hw_ctl_setup_blendstage(struct sde_hw_ctl *ctx, else pipes_per_stage = 1; - mixercfg = cfg->border_enable << 24; /* BORDER_OUT */ - + mixercfg = cfg->border_enable >> 24; /* BORDER_OUT */ +; for (i = 0; i <= stages; i++) { for (j = 0; j < pipes_per_stage; j++) { switch (cfg->stage[i][j]) { @@ -297,38 +298,17 @@ static void sde_hw_ctl_setup_blendstage(struct sde_hw_ctl *ctx, SDE_REG_WRITE(c, CTL_LAYER_EXT(lm), mixercfg_ext); } -static void sde_hw_ctl_intf_cfg(struct sde_hw_ctl *ctx, - struct sde_hw_intf_cfg *cfg) -{ - struct sde_hw_blk_reg_map *c = &ctx->hw; - u32 intf_cfg = 0; - - intf_cfg |= (cfg->intf & 0xF) << 4; - - if (cfg->wb) - intf_cfg |= (cfg->wb & 0x3) + 2; - - if (cfg->mode_3d) { - intf_cfg |= BIT(19); - intf_cfg |= (cfg->mode_3d - 1) << 20; - } - - SDE_REG_WRITE(c, CTL_TOP, intf_cfg); -} - static void _setup_ctl_ops(struct sde_hw_ctl_ops *ops, unsigned long cap) { ops->setup_flush = sde_hw_ctl_setup_flush; - ops->setup_start = sde_hw_ctl_force_start; - ops->setup_intf_cfg = sde_hw_ctl_intf_cfg; ops->reset = sde_hw_ctl_reset_control; - ops->setup_blendstage = sde_hw_ctl_setup_blendstage; ops->get_bitmask_sspp = sde_hw_ctl_get_bitmask_sspp; ops->get_bitmask_mixer = sde_hw_ctl_get_bitmask_mixer; ops->get_bitmask_dspp = sde_hw_ctl_get_bitmask_dspp; ops->get_bitmask_intf = sde_hw_ctl_get_bitmask_intf; ops->get_bitmask_cdm = sde_hw_ctl_get_bitmask_cdm; + ops->setup_blendstage = sde_hw_ctl_setup_blendstage; }; struct sde_hw_ctl *sde_hw_ctl_init(enum sde_ctl idx, @@ -343,9 +323,8 @@ struct sde_hw_ctl *sde_hw_ctl_init(enum sde_ctl idx, return ERR_PTR(-ENOMEM); cfg = _ctl_offset(idx, m, addr, &c->hw); - if (IS_ERR_OR_NULL(cfg)) { + if (cfg) { kfree(c); - pr_err("Error Panic\n"); return ERR_PTR(-EINVAL); } @@ -357,8 +336,3 @@ struct sde_hw_ctl *sde_hw_ctl_init(enum sde_ctl idx, return c; } - -void sde_hw_ctl_destroy(struct sde_hw_ctl *ctx) -{ - kfree(ctx); -} diff --git a/drivers/gpu/drm/msm/sde/sde_hw_mdp_ctl.h b/drivers/gpu/drm/msm/sde/sde_hw_mdp_ctl.h index d46064c57ba4..5782b356bcf6 100644 --- a/drivers/gpu/drm/msm/sde/sde_hw_mdp_ctl.h +++ b/drivers/gpu/drm/msm/sde/sde_hw_mdp_ctl.h @@ -28,45 +28,13 @@ struct sde_hw_stage_cfg { }; /** - * struct sde_hw_intf_cfg :Desbribes how the mdp writes data to - * output interface - * @intf : Interface id - * @wb: writeback id - * @mode_3d: 3d mux configuration - */ -struct sde_hw_intf_cfg { - enum sde_intf intf; - enum sde_wb wb; - enum sde_3d_blend_mode mode_3d; -}; - -/** * struct sde_hw_ctl_ops - Interface to the wb Hw driver functions * Assumption is these functions will be called after clocks are enabled */ struct sde_hw_ctl_ops { - /** - * kickoff hw operation for Sw controlled interfaces - * DSI cmd mode and WB interface are SW controlled - * @ctx : ctl path ctx pointer - */ - void (*setup_start)(struct sde_hw_ctl *ctx); - - /** - * FLUSH the modules for this control path - * @ctx : ctl path ctx pointer - * @flushbits : module flushmask - */ void (*setup_flush)(struct sde_hw_ctl *ctx, - u32 flushbits); - - /** - * Setup ctl_path interface config - * @ctx - * @cfg : interface config structure pointer - */ - void (*setup_intf_cfg)(struct sde_hw_ctl *ctx, - struct sde_hw_intf_cfg *cfg); + u32 flushbits, + u8 force_start); int (*reset)(struct sde_hw_ctl *c); @@ -119,7 +87,7 @@ struct sde_hw_ctl { /** * sde_hw_ctl_init(): Initializes the ctl_path hw driver object. - * should be called before accessing every ctl path registers. + * should be called before accessing every mixer. * @idx: ctl_path index for which driver object is required * @addr: mapped register io address of MDP * @m : pointer to mdss catalog data @@ -128,10 +96,4 @@ struct sde_hw_ctl *sde_hw_ctl_init(enum sde_ctl idx, void __iomem *addr, struct sde_mdss_cfg *m); -/** - * sde_hw_ctl_destroy(): Destroys ctl driver context - * should be called to free the context - */ -void sde_hw_ctl_destroy(struct sde_hw_ctl *ctx); - #endif /*_SDE_HW_MDP_CTL_H */ diff --git a/drivers/gpu/drm/msm/sde/sde_hw_mdss.h b/drivers/gpu/drm/msm/sde/sde_hw_mdss.h index ed5bdf5e5327..ce7ecbf4c8c1 100644 --- a/drivers/gpu/drm/msm/sde/sde_hw_mdss.h +++ b/drivers/gpu/drm/msm/sde/sde_hw_mdss.h @@ -16,7 +16,6 @@ #include <linux/kernel.h> #include <linux/err.h> -#define SDE_NONE 0 #define SDE_CSC_MATRIX_COEFF_SIZE 9 #define SDE_CSC_CLAMP_SIZE 6 #define SDE_CSC_BIAS_SIZE 3 @@ -58,7 +57,7 @@ enum sde_sspp_type { }; enum sde_lm { - LM_0 = 1, + LM_0 = 0, LM_1, LM_2, LM_3, @@ -80,7 +79,7 @@ enum sde_stage { SDE_STAGE_MAX }; enum sde_dspp { - DSPP_0 = 1, + DSPP_0 = 0, DSPP_1, DSPP_2, DSPP_3, @@ -88,7 +87,7 @@ enum sde_dspp { }; enum sde_ctl { - CTL_0 = 1, + CTL_0 = 0, CTL_1, CTL_2, CTL_3, @@ -97,13 +96,13 @@ enum sde_ctl { }; enum sde_cdm { - CDM_0 = 1, + CDM_0 = 0, CDM_1, CDM_MAX }; enum sde_pingpong { - PINGPONG_0 = 1, + PINGPONG_0 = 0, PINGPONG_1, PINGPONG_2, PINGPONG_3, @@ -112,7 +111,7 @@ enum sde_pingpong { }; enum sde_intf { - INTF_0 = 1, + INTF_0 = 0, INTF_1, INTF_2, INTF_3, @@ -209,10 +208,12 @@ enum sde_mdp_fetch_type { * expected by the HW programming. */ enum { - COLOR_1BIT = 0, - COLOR_5BIT = 1, - COLOR_6BIT = 2, - COLOR_8BIT = 3, + COLOR_4BIT, + COLOR_5BIT, + COLOR_6BIT, + COLOR_8BIT, + COLOR_ALPHA_1BIT = 0, + COLOR_ALPHA_4BIT = 1, }; enum sde_alpha_blend_type { @@ -223,26 +224,6 @@ enum sde_alpha_blend_type { ALPHA_MAX }; - -/** - * enum sde_3d_blend_mode - * Desribes how the 3d data is blended - * @BLEND_3D_NONE : 3d blending not enabled - * @BLEND_3D_FRAME_INT : Frame interleaving - * @BLEND_3D_H_ROW_INT : Horizontal row interleaving - * @BLEND_3D_V_ROW_INT : vertical row interleaving - * @BLEND_3D_COL_INT : column interleaving - * @BLEND_3D_MAX : - */ -enum sde_3d_blend_mode { - BLEND_3D_NONE = 0, - BLEND_3D_FRAME_INT, - BLEND_3D_H_ROW_INT, - BLEND_3D_V_ROW_INT, - BLEND_3D_COL_INT, - BLEND_3D_MAX -}; - struct addr_info { u32 plane[SDE_MAX_PLANES]; }; diff --git a/drivers/gpu/drm/msm/sde/sde_hw_sspp.c b/drivers/gpu/drm/msm/sde/sde_hw_sspp.c index 9a3d25423b8a..e179220daab9 100644 --- a/drivers/gpu/drm/msm/sde/sde_hw_sspp.c +++ b/drivers/gpu/drm/msm/sde/sde_hw_sspp.c @@ -182,7 +182,7 @@ static void sde_hw_sspp_setup_format(struct sde_hw_pipe *ctx, u32 opmode = 0; u32 idx; - if (_sspp_subblk_offset(ctx, SDE_SSPP_SRC, &idx)) + if (!_sspp_subblk_offset(ctx, SDE_SSPP_SRC, &idx)) return; opmode = SDE_REG_READ(c, SSPP_SRC_OP_MODE + idx); @@ -210,7 +210,7 @@ static void sde_hw_sspp_setup_format(struct sde_hw_pipe *ctx, src_format = (chroma_samp << 23) | (fmt->fetch_planes << 19) | (fmt->bits[C3_ALPHA] << 6) | (fmt->bits[C2_R_Cr] << 4) | - (fmt->bits[C1_B_Cb] << 2) | (fmt->bits[C0_G_Y] << 0); + (fmt->bits[C0_G_Y] << 0); if (flags & SDE_SSPP_ROT_90) src_format |= BIT(11); /* ROT90 */ @@ -235,9 +235,12 @@ static void sde_hw_sspp_setup_format(struct sde_hw_pipe *ctx, } /* if this is YUV pixel format, enable CSC */ - if (fmt->is_yuv) + if (fmt->is_yuv) { + _sspp_setup_opmode(ctx, CSC, 0x0); + } else { src_format |= BIT(15); - _sspp_setup_opmode(ctx, CSC, fmt->is_yuv); + _sspp_setup_opmode(ctx, CSC, 0x1); + } opmode |= MDSS_MDP_OP_PE_OVERRIDE; @@ -257,8 +260,8 @@ static void sde_hw_sspp_setup_pe_config(struct sde_hw_pipe *ctx, struct sde_hw_blk_reg_map *c = &ctx->hw; u8 color; u32 lr_pe[4], tb_pe[4], tot_req_pixels[4]; - const u32 bytemask = 0xff; - const u32 shortmask = 0xffff; + const u32 bytemask = 0xffff; + const u8 shortmask = 0xff; u32 idx; if (_sspp_subblk_offset(ctx, SDE_SSPP_SRC, &idx)) @@ -280,7 +283,7 @@ static void sde_hw_sspp_setup_pe_config(struct sde_hw_pipe *ctx, ((pe_ext->top_ftch[color] & bytemask) << 8)| (pe_ext->top_rpt[color] & bytemask); - tot_req_pixels[color] = (((pe_ext->roi_h[color] + + tot_req_pixels[color] = (((cfg->src.height + pe_ext->num_ext_pxls_top[color] + pe_ext->num_ext_pxls_btm[color]) & shortmask) << 16) | ((pe_ext->roi_w[color] + @@ -320,30 +323,30 @@ static void sde_hw_sspp_setup_scalar(struct sde_hw_pipe *ctx, scale_config = BIT(0) | BIT(1); /* RGB/YUV config */ - scale_config |= (pe_ext->horz_filter[SDE_SSPP_COMP_LUMA] & mask) << 8; - scale_config |= (pe_ext->vert_filter[SDE_SSPP_COMP_LUMA] & mask) << 10; + scale_config |= (pe_ext->horz_filter[0] & mask) << 8; + scale_config |= (pe_ext->vert_filter[0] & mask) << 10; /* Aplha config*/ - scale_config |= (pe_ext->horz_filter[SDE_SSPP_COMP_ALPHA] & mask) << 16; - scale_config |= (pe_ext->vert_filter[SDE_SSPP_COMP_ALPHA] & mask) << 18; + scale_config |= (pe_ext->horz_filter[3] & mask) << 16; + scale_config |= (pe_ext->vert_filter[3] & mask) << 18; SDE_REG_WRITE(c, SCALE_CONFIG + idx, scale_config); SDE_REG_WRITE(c, COMP0_3_INIT_PHASE_X + idx, - pe_ext->init_phase_x[SDE_SSPP_COMP_LUMA]); + pe_ext->init_phase_x[0]); SDE_REG_WRITE(c, COMP0_3_INIT_PHASE_Y + idx, - pe_ext->init_phase_y[SDE_SSPP_COMP_LUMA]); + pe_ext->init_phase_y[0]); SDE_REG_WRITE(c, COMP0_3_PHASE_STEP_X + idx, - pe_ext->phase_step_x[SDE_SSPP_COMP_LUMA]); + pe_ext->phase_step_x[0]); SDE_REG_WRITE(c, COMP0_3_PHASE_STEP_Y + idx, - pe_ext->phase_step_y[SDE_SSPP_COMP_LUMA]); + pe_ext->phase_step_y[0]); SDE_REG_WRITE(c, COMP1_2_INIT_PHASE_X + idx, - pe_ext->init_phase_x[SDE_SSPP_COMP_CHROMA]); + pe_ext->init_phase_x[1]); SDE_REG_WRITE(c, COMP1_2_INIT_PHASE_Y + idx, - pe_ext->init_phase_y[SDE_SSPP_COMP_CHROMA]); + pe_ext->init_phase_y[1]); SDE_REG_WRITE(c, COMP1_2_PHASE_STEP_X + idx, - pe_ext->phase_step_x[SDE_SSPP_COMP_CHROMA]); + pe_ext->phase_step_x[1]); SDE_REG_WRITE(c, COMP1_2_PHASE_STEP_Y + idx, - pe_ext->phase_step_y[SDE_SSPP_COMP_CHROMA]); + pe_ext->phase_step_y[0]); } /** @@ -362,7 +365,7 @@ static void sde_hw_sspp_setup_rects(struct sde_hw_pipe *ctx, return; /* program pixel extension override */ - if (pe_ext) + if (!pe_ext) sde_hw_sspp_setup_pe_config(ctx, cfg, pe_ext); /* src and dest rect programming */ @@ -385,8 +388,10 @@ static void sde_hw_sspp_setup_rects(struct sde_hw_pipe *ctx, if (test_bit(SDE_SSPP_SCALAR_RGB, &ctx->cap->features) || test_bit(SDE_SSPP_SCALAR_QSEED2, &ctx->cap->features)) { /* program decimation */ - decimation = ((1 << cfg->horz_decimation) - 1) << 8; - decimation |= ((1 << cfg->vert_decimation) - 1); + if (!cfg->horz_decimation) + decimation = (cfg->horz_decimation - 1) << 8; + if (!cfg->vert_decimation) + decimation |= (cfg->vert_decimation - 1); sde_hw_sspp_setup_scalar(ctx, pe_ext); } @@ -416,6 +421,7 @@ static void sde_hw_sspp_setup_sourceaddress(struct sde_hw_pipe *ctx, for (i = 0; i < cfg->src.num_planes; i++) SDE_REG_WRITE(c, SSPP_SRC0_ADDR + idx + i*0x4, cfg->addr.plane[i]); + } static void sde_hw_sspp_setup_csc_8bit(struct sde_hw_pipe *ctx, @@ -470,6 +476,7 @@ static void sde_hw_sspp_setup_solidfill(struct sde_hw_pipe *ctx, static void sde_hw_sspp_setup_histogram_v1(struct sde_hw_pipe *ctx, void *cfg) { + } static void sde_hw_sspp_setup_memcolor(struct sde_hw_pipe *ctx, @@ -582,8 +589,3 @@ struct sde_hw_pipe *sde_hw_sspp_init(enum sde_sspp idx, return c; } -void sde_hw_sspp_destroy(struct sde_hw_pipe *ctx) -{ - kfree(ctx); -} - diff --git a/drivers/gpu/drm/msm/sde/sde_hw_sspp.h b/drivers/gpu/drm/msm/sde/sde_hw_sspp.h index 0e78c52cde56..733837286241 100644 --- a/drivers/gpu/drm/msm/sde/sde_hw_sspp.h +++ b/drivers/gpu/drm/msm/sde/sde_hw_sspp.h @@ -15,6 +15,7 @@ #include "sde_hw_catalog.h" #include "sde_hw_mdss.h" +#include "sde_mdp_formats.h" #include "sde_hw_mdp_util.h" struct sde_hw_pipe; @@ -28,15 +29,6 @@ struct sde_hw_pipe; #define SDE_SSPP_SOURCE_ROTATED_90 0x8 #define SDE_SSPP_ROT_90 0x10 -/** - * Component indices - */ -enum { - SDE_SSPP_COMP_LUMA = 0, - SDE_SSPP_COMP_CHROMA = 1, - SDE_SSPP_COMP_ALPHA = 3 -}; - enum { SDE_MDP_FRAME_LINEAR, SDE_MDP_FRAME_TILE_A4X, @@ -96,7 +88,6 @@ struct sde_hw_pixel_ext { int btm_rpt[SDE_MAX_PLANES]; uint32_t roi_w[SDE_MAX_PLANES]; - uint32_t roi_h[SDE_MAX_PLANES]; /* * Filter type to be used for scaling in horizontal and vertical @@ -271,12 +262,5 @@ struct sde_hw_pipe *sde_hw_sspp_init(enum sde_sspp idx, void __iomem *addr, struct sde_mdss_cfg *m); -/** - * sde_hw_sspp_destroy(): Destroys SSPP driver context - * should be called during Hw pipe cleanup. - * @ctx: Pointer to SSPP driver context returned by sde_hw_sspp_init - */ -void sde_hw_sspp_destroy(struct sde_hw_pipe *ctx); - #endif /*_SDE_HW_SSPP_H */ diff --git a/drivers/gpu/drm/msm/sde/sde_kms.c b/drivers/gpu/drm/msm/sde/sde_kms.c index 89deca7c16ee..2cbff04e98cd 100644 --- a/drivers/gpu/drm/msm/sde/sde_kms.c +++ b/drivers/gpu/drm/msm/sde/sde_kms.c @@ -12,63 +12,31 @@ #include <drm/drm_crtc.h> #include "msm_drv.h" -#include "msm_mmu.h" #include "sde_kms.h" #include "sde_hw_mdss.h" -#include "sde_hw_intf.h" -static const char * const iommu_ports[] = { - "mdp_0", -}; - -#define DEFAULT_MDP_SRC_CLK 200000000 - -int sde_disable(struct sde_kms *sde_kms) +static int modeset_init_intf(struct sde_kms *sde_kms, int intf_num) { - DBG(""); - - clk_disable_unprepare(sde_kms->ahb_clk); - clk_disable_unprepare(sde_kms->axi_clk); - clk_disable_unprepare(sde_kms->core_clk); - if (sde_kms->lut_clk) - clk_disable_unprepare(sde_kms->lut_clk); - - return 0; -} - -int sde_enable(struct sde_kms *sde_kms) -{ - DBG(""); - - clk_prepare_enable(sde_kms->ahb_clk); - clk_prepare_enable(sde_kms->axi_clk); - clk_prepare_enable(sde_kms->core_clk); - if (sde_kms->lut_clk) - clk_prepare_enable(sde_kms->lut_clk); + struct sde_mdss_cfg *catalog = sde_kms->catalog; + u32 intf_type = catalog->intf[intf_num].type; + + switch (intf_type) { + case INTF_NONE: + break; + case INTF_DSI: + break; + case INTF_LCDC: + break; + case INTF_HDMI: + break; + case INTF_EDP: + default: + break; + } return 0; } -static void sde_prepare_commit(struct msm_kms *kms, - struct drm_atomic_state *state) -{ - struct sde_kms *sde_kms = to_sde_kms(to_mdp_kms(kms)); - - sde_enable(sde_kms); -} - -static void sde_complete_commit(struct msm_kms *kms, - struct drm_atomic_state *state) -{ - struct sde_kms *sde_kms = to_sde_kms(to_mdp_kms(kms)); - - sde_disable(sde_kms); -} - -static void sde_wait_for_crtc_commit_done(struct msm_kms *kms, - struct drm_crtc *crtc) -{ -} static int modeset_init(struct sde_kms *sde_kms) { struct msm_drm_private *priv = sde_kms->dev->dev_private; @@ -94,9 +62,8 @@ static int modeset_init(struct sde_kms *sde_kms) || !num_private_planes) primary = false; - plane = sde_plane_init(dev, catalog->sspp[i].id, primary); + plane = sde_plane_init(dev, primary); if (IS_ERR(plane)) { - pr_err("%s: sde_plane_init failed", __func__); ret = PTR_ERR(plane); goto fail; } @@ -104,7 +71,7 @@ static int modeset_init(struct sde_kms *sde_kms) if (primary) primary_planes[primary_planes_idx++] = plane; - if (primary && num_private_planes) + if (num_private_planes) num_private_planes--; } @@ -114,21 +81,15 @@ static int modeset_init(struct sde_kms *sde_kms) goto fail; } - /* - * Enumerate displays supported - */ - sde_encoders_init(dev); - - /* Create one CRTC per display */ - for (i = 0; i < priv->num_encoders; i++) { + /* Create one CRTC per mixer */ + for (i = 0; i < catalog->mixer_count; i++) { /* - * Each CRTC receives a private plane. We start + * Each mixer receives a private plane. We start * with first RGB, and then DMA and then VIG. */ struct drm_crtc *crtc; - crtc = sde_crtc_init(dev, priv->encoders[i], - primary_planes[i], i); + crtc = sde_crtc_init(dev, NULL, primary_planes[i], i); if (IS_ERR(crtc)) { ret = PTR_ERR(crtc); goto fail; @@ -136,13 +97,11 @@ static int modeset_init(struct sde_kms *sde_kms) priv->crtcs[priv->num_crtcs++] = crtc; } - /* - * Iterate through the list of encoders and - * set the possible CRTCs - */ - for (i = 0; i < priv->num_encoders; i++) - priv->encoders[i]->possible_crtcs = (1 << priv->num_crtcs) - 1; - + for (i = 0; i < catalog->intf_count; i++) { + ret = modeset_init_intf(sde_kms, i); + if (ret) + goto fail; + } return 0; fail: return ret; @@ -178,9 +137,6 @@ static const struct mdp_kms_funcs kms_funcs = { .irq_postinstall = sde_irq_postinstall, .irq_uninstall = sde_irq_uninstall, .irq = sde_irq, - .prepare_commit = sde_prepare_commit, - .complete_commit = sde_complete_commit, - .wait_for_crtc_commit_done = sde_wait_for_crtc_commit_done, .enable_vblank = sde_enable_vblank, .disable_vblank = sde_disable_vblank, .get_format = mdp_get_format, @@ -228,7 +184,6 @@ struct sde_kms *sde_hw_setup(struct platform_device *pdev) ret = PTR_ERR(sde_kms->mmio); goto fail; } - pr_err("Mapped Mdp address space @%pK", sde_kms->mmio); sde_kms->vbif = msm_ioremap(pdev, "vbif_phys", "VBIF"); if (IS_ERR(sde_kms->vbif)) { @@ -292,27 +247,8 @@ struct sde_kms *sde_hw_setup(struct platform_device *pdev) get_clk(pdev, &sde_kms->mmagic_clk, "mmagic_clk", false); get_clk(pdev, &sde_kms->iommu_clk, "iommu_clk", false); - if (sde_kms->mmagic) { - ret = regulator_enable(sde_kms->mmagic); - if (ret) { - dev_err(sde_kms->dev->dev, - "failed to enable mmagic GDSC: %d\n", ret); - goto fail; - } - } - if (sde_kms->mmagic_clk) { - clk_prepare_enable(sde_kms->mmagic_clk); - if (ret) { - dev_err(sde_kms->dev->dev, "failed to enable mmagic_clk\n"); - goto undo_gdsc; - } - } - return sde_kms; -undo_gdsc: - if (sde_kms->mmagic) - regulator_disable(sde_kms->mmagic); fail: if (kms) sde_destroy(kms); @@ -320,111 +256,6 @@ fail: return ERR_PTR(ret); } -static int sde_translation_ctrl_pwr(struct sde_kms *sde_kms, bool on) -{ - struct device *dev = sde_kms->dev->dev; - int ret; - - if (on) { - if (sde_kms->iommu_clk) { - ret = clk_prepare_enable(sde_kms->iommu_clk); - if (ret) { - dev_err(dev, "failed to enable iommu_clk\n"); - goto undo_mmagic_clk; - } - } - } else { - if (sde_kms->iommu_clk) - clk_disable_unprepare(sde_kms->iommu_clk); - if (sde_kms->mmagic_clk) - clk_disable_unprepare(sde_kms->mmagic_clk); - if (sde_kms->mmagic) - regulator_disable(sde_kms->mmagic); - } - - return 0; - -undo_mmagic_clk: - if (sde_kms->mmagic_clk) - clk_disable_unprepare(sde_kms->mmagic_clk); - - return ret; -} -int sde_mmu_init(struct sde_kms *sde_kms) -{ - struct sde_mdss_cfg *catalog = sde_kms->catalog; - struct sde_hw_intf *intf = NULL; - struct iommu_domain *iommu; - struct msm_mmu *mmu; - int i, ret; - - /* - * Make sure things are off before attaching iommu (bootloader could - * have left things on, in which case we'll start getting faults if - * we don't disable): - */ - sde_enable(sde_kms); - for (i = 0; i < catalog->intf_count; i++) { - intf = sde_hw_intf_init(catalog->intf[i].id, - sde_kms->mmio, - catalog); - if (!IS_ERR_OR_NULL(intf)) { - intf->ops.enable_timing(intf, 0x0); - sde_hw_intf_deinit(intf); - } - } - sde_disable(sde_kms); - msleep(20); - - iommu = iommu_domain_alloc(&platform_bus_type); - - if (!IS_ERR_OR_NULL(iommu)) { - mmu = msm_smmu_new(sde_kms->dev->dev, MSM_SMMU_DOMAIN_UNSECURE); - if (IS_ERR(mmu)) { - ret = PTR_ERR(mmu); - dev_err(sde_kms->dev->dev, - "failed to init iommu: %d\n", ret); - iommu_domain_free(iommu); - goto fail; - } - - ret = sde_translation_ctrl_pwr(sde_kms, true); - if (ret) { - dev_err(sde_kms->dev->dev, - "failed to power iommu: %d\n", ret); - mmu->funcs->destroy(mmu); - goto fail; - } - - ret = mmu->funcs->attach(mmu, (const char **)iommu_ports, - ARRAY_SIZE(iommu_ports)); - if (ret) { - dev_err(sde_kms->dev->dev, - "failed to attach iommu: %d\n", ret); - mmu->funcs->destroy(mmu); - goto fail; - } - } else { - dev_info(sde_kms->dev->dev, - "no iommu, fallback to phys contig buffers for scanout\n"); - mmu = NULL; - } - sde_kms->mmu = mmu; - - sde_kms->mmu_id = msm_register_mmu(sde_kms->dev, mmu); - if (sde_kms->mmu_id < 0) { - ret = sde_kms->mmu_id; - dev_err(sde_kms->dev->dev, - "failed to register sde iommu: %d\n", ret); - goto fail; - } - - return 0; -fail: - return ret; - -} - struct msm_kms *sde_kms_init(struct drm_device *dev) { struct platform_device *pdev = dev->platformdev; @@ -451,20 +282,10 @@ struct msm_kms *sde_kms_init(struct drm_device *dev) sde_kms->catalog = catalog; - /* we need to set a default rate before enabling. - * Set a safe rate first, before initializing catalog - * later set more optimal rate based on bandwdith/clock - * requirements - */ - - clk_set_rate(sde_kms->src_clk, DEFAULT_MDP_SRC_CLK); - sde_enable(sde_kms); - /* * Now we need to read the HW catalog and initialize resources such as * clocks, regulators, GDSC/MMAGIC, ioremap the register ranges etc */ - sde_mmu_init(sde_kms); /* * modeset_init should create the DRM related objects i.e. CRTCs, @@ -475,14 +296,6 @@ struct msm_kms *sde_kms_init(struct drm_device *dev) dev->mode_config.min_width = 0; dev->mode_config.min_height = 0; - /* - * we can assume the max crtc width is equal to the max supported - * by LM_0 - * Also fixing the max height to 4k - */ - dev->mode_config.max_width = catalog->mixer[0].sblk->maxwidth; - dev->mode_config.max_height = 4096; - return msm_kms; fail: diff --git a/drivers/gpu/drm/msm/sde/sde_kms.h b/drivers/gpu/drm/msm/sde/sde_kms.h index 7be7233c2b97..24dabc93583f 100644 --- a/drivers/gpu/drm/msm/sde/sde_kms.h +++ b/drivers/gpu/drm/msm/sde/sde_kms.h @@ -26,7 +26,6 @@ struct sde_kms { struct sde_mdss_cfg *catalog; struct msm_mmu *mmu; - int mmu_id; /* io/register spaces: */ void __iomem *mmio, *vbif; @@ -87,8 +86,18 @@ int sde_enable_vblank(struct msm_kms *kms, struct drm_crtc *crtc); void sde_disable_vblank(struct msm_kms *kms, struct drm_crtc *crtc); enum sde_sspp sde_plane_pipe(struct drm_plane *plane); -struct drm_plane *sde_plane_init(struct drm_device *dev, uint32_t pipe, - bool private_plane); +void sde_plane_install_properties(struct drm_plane *plane, + struct drm_mode_object *obj); +void sde_plane_set_scanout(struct drm_plane *plane, + struct drm_framebuffer *fb); +int sde_plane_mode_set(struct drm_plane *plane, + struct drm_crtc *crtc, struct drm_framebuffer *fb, + int crtc_x, int crtc_y, + unsigned int crtc_w, unsigned int crtc_h, + uint32_t src_x, uint32_t src_y, + uint32_t src_w, uint32_t src_h); +void sde_plane_complete_flip(struct drm_plane *plane); +struct drm_plane *sde_plane_init(struct drm_device *dev, bool private_plane); uint32_t sde_crtc_vblank(struct drm_crtc *crtc); @@ -99,16 +108,7 @@ struct drm_crtc *sde_crtc_init(struct drm_device *dev, struct drm_encoder *encoder, struct drm_plane *plane, int id); -struct sde_encoder_hw_resources { - bool intfs[INTF_MAX]; - bool pingpongs[PINGPONG_MAX]; -}; -void sde_encoder_get_hw_resources(struct drm_encoder *encoder, - struct sde_encoder_hw_resources *hw_res); -void sde_encoder_register_vblank_callback(struct drm_encoder *drm_enc, - void (*cb)(void *), void *data); -void sde_encoders_init(struct drm_device *dev); - +struct drm_encoder *sde_encoder_init(struct drm_device *dev, int intf); int sde_irq_domain_init(struct sde_kms *sde_kms); int sde_irq_domain_fini(struct sde_kms *sde_kms); diff --git a/drivers/gpu/drm/msm/sde/sde_mdp_formats.c b/drivers/gpu/drm/msm/sde/sde_mdp_formats.c deleted file mode 100644 index 56b65d4bd45e..000000000000 --- a/drivers/gpu/drm/msm/sde/sde_mdp_formats.c +++ /dev/null @@ -1,134 +0,0 @@ -/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include <linux/kernel.h> -#include "sde_mdp_formats.h" - -static struct sde_mdp_format_params sde_mdp_format_map[] = { - INTERLEAVED_RGB_FMT(ARGB8888, - COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, - C1_B_Cb, C0_G_Y, C2_R_Cr, C3_ALPHA, - true, 4, 0), - - INTERLEAVED_RGB_FMT(ABGR8888, - COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, - C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, - true, 4, 0), - - INTERLEAVED_RGB_FMT(RGBA8888, - COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, - C3_ALPHA, C1_B_Cb, C0_G_Y, C2_R_Cr, - true, 4, 0), - - INTERLEAVED_RGB_FMT(BGRA8888, - COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, - C3_ALPHA, C2_R_Cr, C0_G_Y, C1_B_Cb, - true, 4, 0), - - INTERLEAVED_RGB_FMT(XRGB8888, - COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, - C1_B_Cb, C0_G_Y, C2_R_Cr, C3_ALPHA, - true, 4, 0), - - INTERLEAVED_RGB_FMT(RGB888, - 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, - C1_B_Cb, C0_G_Y, C2_R_Cr, 0, - false, 3, 0), - - INTERLEAVED_RGB_FMT(BGR888, - 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, - C2_R_Cr, C0_G_Y, C1_B_Cb, 0, - false, 3, 0), - - INTERLEAVED_RGB_FMT(RGB565, - 0, COLOR_5BIT, COLOR_6BIT, COLOR_5BIT, - C1_B_Cb, C0_G_Y, C2_R_Cr, 0, - false, 2, 0), - - INTERLEAVED_RGB_FMT(BGR565, - 0, 5, 6, 5, - C2_R_Cr, C0_G_Y, C1_B_Cb, 0, - false, 2, 0), - - PSEDUO_YUV_FMT(NV12, - 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, - C1_B_Cb, C2_R_Cr, - SDE_MDP_CHROMA_420, 0), - - PSEDUO_YUV_FMT(NV21, - 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, - C2_R_Cr, C1_B_Cb, - SDE_MDP_CHROMA_420, 0), - - PSEDUO_YUV_FMT(NV16, - 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, - C1_B_Cb, C2_R_Cr, - SDE_MDP_CHROMA_H2V1, 0), - - PSEDUO_YUV_FMT(NV61, - 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, - C2_R_Cr, C1_B_Cb, - SDE_MDP_CHROMA_H2V1, 0), - - INTERLEAVED_YUV_FMT(VYUY, - 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, - C2_R_Cr, C0_G_Y, C1_B_Cb, C0_G_Y, - false, SDE_MDP_CHROMA_H2V1, 4, 2, - 0), - - INTERLEAVED_YUV_FMT(UYVY, - 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, - C1_B_Cb, C0_G_Y, C2_R_Cr, C0_G_Y, - false, SDE_MDP_CHROMA_H2V1, 4, 2, - 0), - - INTERLEAVED_YUV_FMT(YUYV, - 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, - C0_G_Y, C1_B_Cb, C0_G_Y, C2_R_Cr, - false, SDE_MDP_CHROMA_H2V1, 4, 2, - 0), - - INTERLEAVED_YUV_FMT(YVYU, - 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, - C0_G_Y, C2_R_Cr, C0_G_Y, C1_B_Cb, - false, SDE_MDP_CHROMA_H2V1, 4, 2, - 0), - - PLANAR_YUV_FMT(YUV420, - 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, - C2_R_Cr, C1_B_Cb, C0_G_Y, - false, SDE_MDP_CHROMA_420, 2, - 0), - - PLANAR_YUV_FMT(YVU420, - 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, - C1_B_Cb, C2_R_Cr, C0_G_Y, - false, SDE_MDP_CHROMA_420, 2, - 0), -}; - -struct sde_mdp_format_params *sde_mdp_get_format_params(u32 format, - u32 fmt_modifier) -{ - u32 i = 0; - struct sde_mdp_format_params *fmt = NULL; - - for (i = 0; i < sizeof(sde_mdp_format_map)/sizeof(*sde_mdp_format_map); - i++) - if (format == sde_mdp_format_map[i].format) { - fmt = &sde_mdp_format_map[i]; - break; - } - - return fmt; -} - diff --git a/drivers/gpu/drm/msm/sde/sde_mdp_formats.h b/drivers/gpu/drm/msm/sde/sde_mdp_formats.h index e6f1c60aad11..dfd5076bb9dc 100644 --- a/drivers/gpu/drm/msm/sde/sde_mdp_formats.h +++ b/drivers/gpu/drm/msm/sde/sde_mdp_formats.h @@ -58,7 +58,6 @@ alpha, chroma, count, bp, flg) \ .is_yuv = true, \ .flag = flg \ } - #define PSEDUO_YUV_FMT(fmt, a, r, g, b, e0, e1, chroma, flg) \ { \ .format = DRM_FORMAT_ ## fmt, \ @@ -93,12 +92,122 @@ alpha, chroma, count, bp, flg) \ .flag = flg \ } -/** - * sde_mdp_get_format_params(): Returns sde format structure pointer. - * @format: DRM format - * @fmt_modifier: DRM format modifier - */ +static struct sde_mdp_format_params sde_mdp_format_map[] = { + INTERLEAVED_RGB_FMT(ARGB8888, + COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, + C1_B_Cb, C0_G_Y, C2_R_Cr, C3_ALPHA, + true, 4, 0), + + INTERLEAVED_RGB_FMT(ABGR8888, + COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, + C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, + true, 4, 0), + + INTERLEAVED_RGB_FMT(RGBA8888, + COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, + C3_ALPHA, C1_B_Cb, C0_G_Y, C2_R_Cr, + true, 4, 0), + + INTERLEAVED_RGB_FMT(BGRA8888, + COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, + C3_ALPHA, C2_R_Cr, C0_G_Y, C1_B_Cb, + true, 4, 0), + + INTERLEAVED_RGB_FMT(XRGB8888, + COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, + C1_B_Cb, C0_G_Y, C2_R_Cr, C3_ALPHA, + true, 4, 0), + + INTERLEAVED_RGB_FMT(RGB888, + 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, + C1_B_Cb, C0_G_Y, C2_R_Cr, 0, + false, 3, 0), + + INTERLEAVED_RGB_FMT(BGR888, + 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, + C2_R_Cr, C0_G_Y, C1_B_Cb, 0, + false, 3, 0), + + INTERLEAVED_RGB_FMT(RGB565, + 0, COLOR_5BIT, COLOR_6BIT, COLOR_5BIT, + C1_B_Cb, C0_G_Y, C2_R_Cr, 0, + false, 2, 0), + + INTERLEAVED_RGB_FMT(BGR565, + 0, 5, 6, 5, + C2_R_Cr, C0_G_Y, C1_B_Cb, 0, + false, 2, 0), + + PSEDUO_YUV_FMT(NV12, + 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, + C1_B_Cb, C2_R_Cr, + SDE_MDP_CHROMA_420, 0), + + PSEDUO_YUV_FMT(NV21, + 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, + C2_R_Cr, C1_B_Cb, + SDE_MDP_CHROMA_420, 0), + + PSEDUO_YUV_FMT(NV16, + 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, + C1_B_Cb, C2_R_Cr, + SDE_MDP_CHROMA_H2V1, 0), + + PSEDUO_YUV_FMT(NV61, + 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, + C2_R_Cr, C1_B_Cb, + SDE_MDP_CHROMA_H2V1, 0), + + INTERLEAVED_YUV_FMT(VYUY, + 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, + C2_R_Cr, C0_G_Y, C1_B_Cb, C0_G_Y, + false, SDE_MDP_CHROMA_H2V1, 4, 2, + 0), + + INTERLEAVED_YUV_FMT(UYVY, + 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, + C1_B_Cb, C0_G_Y, C2_R_Cr, C0_G_Y, + false, SDE_MDP_CHROMA_H2V1, 4, 2, + 0), + + INTERLEAVED_YUV_FMT(YUYV, + 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, + C0_G_Y, C1_B_Cb, C0_G_Y, C2_R_Cr, + false, SDE_MDP_CHROMA_H2V1, 4, 2, + 0), + + INTERLEAVED_YUV_FMT(YVYU, + 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, + C0_G_Y, C2_R_Cr, C0_G_Y, C1_B_Cb, + false, SDE_MDP_CHROMA_H2V1, 4, 2, + 0), + + PLANAR_YUV_FMT(YUV420, + 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, + C2_R_Cr, C1_B_Cb, C0_G_Y, + false, SDE_MDP_CHROMA_420, 2, + 0), + + PLANAR_YUV_FMT(YVU420, + 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, + C1_B_Cb, C2_R_Cr, C0_G_Y, + false, SDE_MDP_CHROMA_420, 2, + 0), +}; + struct sde_mdp_format_params *sde_mdp_get_format_params(u32 format, - u32 fmt_modifier); + u32 fmt_modifier) +{ + u32 i = 0; + struct sde_mdp_format_params *fmt = NULL; + + for (i = 0; i < ARRAY_SIZE(sde_mdp_format_map); i++) + if (format == sde_mdp_format_map[i].format) { + fmt = &sde_mdp_format_map[i]; + break; + } + + return fmt; +} #endif /*_SDE_MDP_FORMATS_H */ diff --git a/drivers/gpu/drm/msm/sde/sde_plane.c b/drivers/gpu/drm/msm/sde/sde_plane.c index d917a807cd17..6f2dd9dee668 100644 --- a/drivers/gpu/drm/msm/sde/sde_plane.c +++ b/drivers/gpu/drm/msm/sde/sde_plane.c @@ -11,746 +11,103 @@ */ #include "sde_kms.h" -#include "sde_hwio.h" -#include "sde_hw_mdp_ctl.h" -#include "sde_mdp_formats.h" -#include "sde_hw_sspp.h" - -#define DECIMATED_DIMENSION(dim, deci) (((dim) + ((1 << (deci)) - 1)) >> (deci)) -#define PHASE_STEP_SHIFT 21 -#define PHASE_STEP_UNIT_SCALE ((int) (1 << PHASE_STEP_SHIFT)) -#define PHASE_RESIDUAL 15 - -#define SDE_PLANE_FEATURE_SCALER \ - (BIT(SDE_SSPP_SCALAR_QSEED2)| \ - BIT(SDE_SSPP_SCALAR_QSEED3)| \ - BIT(SDE_SSPP_SCALAR_RGB)) - -#ifndef SDE_PLANE_DEBUG_START -#define SDE_PLANE_DEBUG_START() -#endif - -#ifndef SDE_PLANE_DEBUG_END -#define SDE_PLANE_DEBUG_END() -#endif struct sde_plane { struct drm_plane base; const char *name; - - int mmu_id; - - enum sde_sspp pipe; - uint32_t features; /* capabilities from catalog */ - uint32_t flush_mask; /* used to commit pipe registers */ uint32_t nformats; uint32_t formats[32]; - - struct sde_hw_pipe *pipe_hw; - struct sde_hw_pipe_cfg pipe_cfg; - struct sde_hw_pixel_ext pixel_ext; }; #define to_sde_plane(x) container_of(x, struct sde_plane, base) -static bool sde_plane_enabled(struct drm_plane_state *state) -{ - return state->fb && state->crtc; -} - -static void sde_plane_set_scanout(struct drm_plane *plane, - struct sde_hw_pipe_cfg *pipe_cfg, struct drm_framebuffer *fb) -{ - struct sde_plane *psde = to_sde_plane(plane); - int i; - - if (pipe_cfg && fb && psde->pipe_hw->ops.setup_sourceaddress) { - /* stride */ - i = min_t(int, ARRAY_SIZE(fb->pitches), SDE_MAX_PLANES); - while (i) { - --i; - pipe_cfg->src.ystride[i] = fb->pitches[i]; - } - - /* address */ - for (i = 0; i < ARRAY_SIZE(pipe_cfg->addr.plane); ++i) - pipe_cfg->addr.plane[i] = msm_framebuffer_iova(fb, - psde->mmu_id, i); - - /* hw driver */ - psde->pipe_hw->ops.setup_sourceaddress(psde->pipe_hw, pipe_cfg); - } -} - -static void sde_plane_scale_helper(struct drm_plane *plane, - uint32_t src, uint32_t dst, uint32_t *phase_steps, - enum sde_hw_filter *filter, struct sde_mdp_format_params *fmt, - uint32_t chroma_subsampling) -{ - /* calcualte phase steps, leave init phase as zero */ - phase_steps[SDE_SSPP_COMP_LUMA] = - mult_frac(1 << PHASE_STEP_SHIFT, src, dst); - phase_steps[SDE_SSPP_COMP_CHROMA] = - phase_steps[SDE_SSPP_COMP_LUMA] / chroma_subsampling; - - /* calculate scaler config, if necessary */ - if (src != dst) { - filter[SDE_SSPP_COMP_ALPHA] = (src < dst) ? - SDE_MDP_SCALE_FILTER_BIL : - SDE_MDP_SCALE_FILTER_PCMN; - - if (fmt->is_yuv) - filter[SDE_SSPP_COMP_LUMA] = SDE_MDP_SCALE_FILTER_CA; - else - filter[SDE_SSPP_COMP_LUMA] = - filter[SDE_SSPP_COMP_ALPHA]; - } -} - -/* CIFIX: clean up fmt/subsampling params once we're using fourcc formats */ -static void _sde_plane_pixel_ext_helper(struct drm_plane *plane, - uint32_t src, uint32_t dst, uint32_t decimated_src, - uint32_t *phase_steps, uint32_t *out_src, int *out_edge1, - int *out_edge2, struct sde_mdp_format_params *fmt, - uint32_t chroma_subsampling, bool post_compare) -{ - /* CIFIX: adapted from mdss_mdp_pipe_calc_pixel_extn() */ - int64_t edge1, edge2, caf; - uint32_t src_work; - int i, tmp; - - if (plane && phase_steps && out_src && out_edge1 && out_edge2 && fmt) { - /* enable CAF for YUV formats */ - if (fmt->is_yuv) - caf = PHASE_STEP_UNIT_SCALE; - else - caf = 0; - - for (i = 0; i < SDE_MAX_PLANES; i++) { - src_work = decimated_src; - if (i == 1 || i == 2) - src_work /= chroma_subsampling; - if (post_compare) - src = src_work; - if (!(fmt->is_yuv) && (src == dst)) { - /* unity */ - edge1 = 0; - edge2 = 0; - } else if (dst >= src) { - /* upscale */ - edge1 = (1 << PHASE_RESIDUAL); - edge1 -= caf; - edge2 = (1 << PHASE_RESIDUAL); - edge2 += (dst - 1) * *(phase_steps + i); - edge2 -= (src_work - 1) * PHASE_STEP_UNIT_SCALE; - edge2 += caf; - edge2 = -(edge2); - } else { - /* downscale */ - edge1 = 0; - edge2 = (dst - 1) * *(phase_steps + i); - edge2 -= (src_work - 1) * PHASE_STEP_UNIT_SCALE; - edge2 += *(phase_steps + i); - edge2 = -(edge2); - } - - /* only enable CAF for luma plane */ - caf = 0; - - /* populate output arrays */ - *(out_src + i) = src_work; - - /* edge updates taken from __pxl_extn_helper */ - /* CIFIX: why are we casting first to uint32_t? */ - if (edge1 >= 0) { - tmp = (uint32_t)edge1; - tmp >>= PHASE_STEP_SHIFT; - *(out_edge1 + i) = -tmp; - } else { - tmp = (uint32_t)(-edge1); - *(out_edge1 + i) = (tmp + PHASE_STEP_UNIT_SCALE - - 1) >> PHASE_STEP_SHIFT; - } - if (edge2 >= 0) { - tmp = (uint32_t)edge2; - tmp >>= PHASE_STEP_SHIFT; - *(out_edge2 + i) = -tmp; - } else { - tmp = (uint32_t)(-edge2); - *(out_edge2 + i) = (tmp + PHASE_STEP_UNIT_SCALE - - 1) >> PHASE_STEP_SHIFT; - } - } - } -} - -static int sde_plane_mode_set(struct drm_plane *plane, +static int sde_plane_update(struct drm_plane *plane, struct drm_crtc *crtc, struct drm_framebuffer *fb, int crtc_x, int crtc_y, unsigned int crtc_w, unsigned int crtc_h, uint32_t src_x, uint32_t src_y, uint32_t src_w, uint32_t src_h) { - struct sde_plane *psde = to_sde_plane(plane); - struct sde_plane_state *pstate; - const struct mdp_format *format; - uint32_t nplanes, pix_format, tmp; - int i; - struct sde_mdp_format_params *fmt; - struct sde_hw_pixel_ext *pe; - int ret = 0; - - SDE_PLANE_DEBUG_START(); - nplanes = drm_format_num_planes(fb->pixel_format); - - pstate = to_sde_plane_state(plane->state); - - format = to_mdp_format(msm_framebuffer_format(fb)); - pix_format = format->base.pixel_format; - - /* src values are in Q16 fixed point, convert to integer */ - src_x = src_x >> 16; - src_y = src_y >> 16; - src_w = src_w >> 16; - src_h = src_h >> 16; - - DBG("%s: FB[%u] %u,%u,%u,%u -> CRTC[%u] %d,%d,%u,%u", psde->name, - fb->base.id, src_x, src_y, src_w, src_h, - crtc->base.id, crtc_x, crtc_y, crtc_w, crtc_h); - - /* update format configuration */ - memset(&(psde->pipe_cfg), 0, sizeof(struct sde_hw_pipe_cfg)); - - psde->pipe_cfg.src.format = sde_mdp_get_format_params(pix_format, - 0/* CIFIX: fmt_modifier */); - psde->pipe_cfg.src.width = fb->width; - psde->pipe_cfg.src.height = fb->height; - psde->pipe_cfg.src.num_planes = nplanes; - - sde_plane_set_scanout(plane, &psde->pipe_cfg, fb); - - psde->pipe_cfg.src_rect.x = src_x; - psde->pipe_cfg.src_rect.y = src_y; - psde->pipe_cfg.src_rect.w = src_w; - psde->pipe_cfg.src_rect.h = src_h; - - psde->pipe_cfg.dst_rect.x = crtc_x; - psde->pipe_cfg.dst_rect.y = crtc_y; - psde->pipe_cfg.dst_rect.w = crtc_w; - psde->pipe_cfg.dst_rect.h = crtc_h; - - psde->pipe_cfg.horz_decimation = 0; - psde->pipe_cfg.vert_decimation = 0; - - /* get sde pixel format definition */ - fmt = psde->pipe_cfg.src.format; - - /* update pixel extensions */ - pe = &(psde->pixel_ext); - if (!pe->enable_pxl_ext) { - uint32_t chroma_subsample_h, chroma_subsample_v; - - chroma_subsample_h = psde->pipe_cfg.horz_decimation ? 1 : - drm_format_horz_chroma_subsampling(pix_format); - chroma_subsample_v = psde->pipe_cfg.vert_decimation ? 1 : - drm_format_vert_chroma_subsampling(pix_format); - - memset(pe, 0, sizeof(struct sde_hw_pixel_ext)); - - /* calculate phase steps */ - sde_plane_scale_helper(plane, src_w, crtc_w, - pe->phase_step_x, - pe->horz_filter, fmt, chroma_subsample_h); - sde_plane_scale_helper(plane, src_h, crtc_h, - pe->phase_step_y, - pe->vert_filter, fmt, chroma_subsample_v); - - /* calculate left/right/top/bottom pixel extentions */ - tmp = DECIMATED_DIMENSION(src_w, - psde->pipe_cfg.horz_decimation); - if (fmt->is_yuv) - tmp &= ~0x1; - _sde_plane_pixel_ext_helper(plane, src_w, crtc_w, tmp, - pe->phase_step_x, - pe->roi_w, - pe->num_ext_pxls_left, - pe->num_ext_pxls_right, fmt, - chroma_subsample_h, 0); - - tmp = DECIMATED_DIMENSION(src_h, - psde->pipe_cfg.vert_decimation); - _sde_plane_pixel_ext_helper(plane, src_h, crtc_h, tmp, - pe->phase_step_y, - pe->roi_h, - pe->num_ext_pxls_top, - pe->num_ext_pxls_btm, fmt, - chroma_subsample_v, 1); - - /* CIFIX: port "Single pixel rgb scale adjustment"? */ - - for (i = 0; i < SDE_MAX_PLANES; i++) { - if (pe->num_ext_pxls_left[i] >= 0) - pe->left_rpt[i] = - pe->num_ext_pxls_left[i]; - else - pe->left_ftch[i] = - pe->num_ext_pxls_left[i]; - - if (pe->num_ext_pxls_right[i] >= 0) - pe->right_rpt[i] = - pe->num_ext_pxls_right[i]; - else - pe->right_ftch[i] = - pe->num_ext_pxls_right[i]; - - if (pe->num_ext_pxls_top[i] >= 0) - pe->top_rpt[i] = - pe->num_ext_pxls_top[i]; - else - pe->top_ftch[i] = - pe->num_ext_pxls_top[i]; - - if (pe->num_ext_pxls_btm[i] >= 0) - pe->btm_rpt[i] = - pe->num_ext_pxls_btm[i]; - else - pe->btm_ftch[i] = - pe->num_ext_pxls_btm[i]; - } - } - - if (psde->pipe_hw->ops.setup_sourceformat) - psde->pipe_hw->ops.setup_sourceformat(psde->pipe_hw, - &psde->pipe_cfg, 0 /* CIFIX: flags */); - if (psde->pipe_hw->ops.setup_rects) - psde->pipe_hw->ops.setup_rects(psde->pipe_hw, - &psde->pipe_cfg, &psde->pixel_ext); - - /* update csc */ - - SDE_PLANE_DEBUG_END(); - return ret; -} - -static int sde_plane_prepare_fb(struct drm_plane *plane, - const struct drm_plane_state *new_state) -{ - struct drm_framebuffer *fb = new_state->fb; - struct sde_plane *psde = to_sde_plane(plane); - - if (!new_state->fb) - return 0; - - SDE_PLANE_DEBUG_START(); - SDE_PLANE_DEBUG_END(); - DBG("%s: prepare: FB[%u]", psde->name, fb->base.id); - return msm_framebuffer_prepare(fb, psde->mmu_id); -} - -static void sde_plane_cleanup_fb(struct drm_plane *plane, - const struct drm_plane_state *old_state) -{ - struct drm_framebuffer *fb = old_state->fb; - struct sde_plane *psde = to_sde_plane(plane); - - if (!fb) - return; - - SDE_PLANE_DEBUG_START(); - SDE_PLANE_DEBUG_END(); - DBG("%s: cleanup: FB[%u]", psde->name, fb->base.id); - msm_framebuffer_cleanup(fb, psde->mmu_id); + return 0; } -static int sde_plane_atomic_check(struct drm_plane *plane, - struct drm_plane_state *state) +static int sde_plane_disable(struct drm_plane *plane) { - struct sde_plane *psde = to_sde_plane(plane); - struct drm_plane_state *old_state = plane->state; - const struct mdp_format *format; - - SDE_PLANE_DEBUG_START(); - SDE_PLANE_DEBUG_END(); - DBG("%s: check (%d -> %d)", psde->name, - sde_plane_enabled(old_state), sde_plane_enabled(state)); - - if (sde_plane_enabled(state)) { - /* CIFIX: don't use mdp format? */ - format = to_mdp_format(msm_framebuffer_format(state->fb)); - if (MDP_FORMAT_IS_YUV(format) && - (!(psde->features & SDE_PLANE_FEATURE_SCALER) || - !(psde->features & BIT(SDE_SSPP_CSC)))) { - dev_err(plane->dev->dev, - "Pipe doesn't support YUV\n"); - - return -EINVAL; - } - - if (!(psde->features & SDE_PLANE_FEATURE_SCALER) && - (((state->src_w >> 16) != state->crtc_w) || - ((state->src_h >> 16) != state->crtc_h))) { - dev_err(plane->dev->dev, - "Pipe doesn't support scaling (%dx%d -> %dx%d)\n", - state->src_w >> 16, state->src_h >> 16, - state->crtc_w, state->crtc_h); - - return -EINVAL; - } - } - - if (sde_plane_enabled(state) && sde_plane_enabled(old_state)) { - /* we cannot change SMP block configuration during scanout: */ - bool full_modeset = false; - - if (state->fb->pixel_format != old_state->fb->pixel_format) { - DBG("%s: pixel_format change!", psde->name); - full_modeset = true; - } - if (state->src_w != old_state->src_w) { - DBG("%s: src_w change!", psde->name); - full_modeset = true; - } - if (to_sde_plane_state(old_state)->pending) { - DBG("%s: still pending!", psde->name); - full_modeset = true; - } - if (full_modeset) { - struct drm_crtc_state *crtc_state = - drm_atomic_get_crtc_state(state->state, - state->crtc); - crtc_state->mode_changed = true; - to_sde_plane_state(state)->mode_changed = true; - } - } else { - to_sde_plane_state(state)->mode_changed = true; - } - return 0; } -static void sde_plane_atomic_update(struct drm_plane *plane, - struct drm_plane_state *old_state) +static void sde_plane_destroy(struct drm_plane *plane) { struct sde_plane *sde_plane = to_sde_plane(plane); - struct drm_plane_state *state = plane->state; + struct msm_drm_private *priv = plane->dev->dev_private; - DBG("%s: update", sde_plane->name); + if (priv->kms) + sde_plane_disable(plane); - SDE_PLANE_DEBUG_START(); - if (!sde_plane_enabled(state)) { - to_sde_plane_state(state)->pending = true; - } else if (to_sde_plane_state(state)->mode_changed) { - int ret; + drm_plane_cleanup(plane); - to_sde_plane_state(state)->pending = true; - ret = sde_plane_mode_set(plane, - state->crtc, state->fb, - state->crtc_x, state->crtc_y, - state->crtc_w, state->crtc_h, - state->src_x, state->src_y, - state->src_w, state->src_h); - /* atomic_check should have ensured that this doesn't fail */ - WARN_ON(ret < 0); - } else { - sde_plane_set_scanout(plane, &sde_plane->pipe_cfg, state->fb); - } - SDE_PLANE_DEBUG_END(); + kfree(sde_plane); } /* helper to install properties which are common to planes and crtcs */ -static void sde_plane_install_properties(struct drm_plane *plane, +void sde_plane_install_properties(struct drm_plane *plane, struct drm_mode_object *obj) { - struct drm_device *dev = plane->dev; - struct msm_drm_private *dev_priv = dev->dev_private; - struct drm_property *prop; - - SDE_PLANE_DEBUG_START(); -#define INSTALL_PROPERTY(name, NAME, init_val, fnc, ...) do { \ - prop = dev_priv->plane_property[PLANE_PROP_##NAME]; \ - if (!prop) { \ - prop = drm_property_##fnc(dev, 0, #name, \ - ##__VA_ARGS__); \ - if (!prop) { \ - dev_warn(dev->dev, \ - "Create property %s failed\n", \ - #name); \ - return; \ - } \ - dev_priv->plane_property[PLANE_PROP_##NAME] = prop; \ - } \ - drm_object_attach_property(&plane->base, prop, init_val); \ - } while (0) - -#define INSTALL_RANGE_PROPERTY(name, NAME, min, max, init_val) \ - INSTALL_PROPERTY(name, NAME, init_val, \ - create_range, min, max) - -#define INSTALL_ENUM_PROPERTY(name, NAME, init_val) \ - INSTALL_PROPERTY(name, NAME, init_val, \ - create_enum, name##_prop_enum_list, \ - ARRAY_SIZE(name##_prop_enum_list)) - - INSTALL_RANGE_PROPERTY(zpos, ZPOS, 1, 255, 1); - -#undef INSTALL_RANGE_PROPERTY -#undef INSTALL_ENUM_PROPERTY -#undef INSTALL_PROPERTY - SDE_PLANE_DEBUG_END(); -} - -static int sde_plane_atomic_set_property(struct drm_plane *plane, - struct drm_plane_state *state, struct drm_property *property, - uint64_t val) -{ - struct drm_device *dev = plane->dev; - struct sde_plane_state *pstate; - struct msm_drm_private *dev_priv = dev->dev_private; - int ret = 0; - - SDE_PLANE_DEBUG_START(); - - pstate = to_sde_plane_state(state); - -#define SET_PROPERTY(name, NAME, type) do { \ - if (dev_priv->plane_property[PLANE_PROP_##NAME] == property) { \ - pstate->name = (type)val; \ - DBG("Set property %s %d", #name, (type)val); \ - goto done; \ - } \ - } while (0) - - SET_PROPERTY(zpos, ZPOS, uint8_t); - - dev_err(dev->dev, "Invalid property\n"); - ret = -EINVAL; -done: - SDE_PLANE_DEBUG_END(); - return ret; -#undef SET_PROPERTY } -static int sde_plane_set_property(struct drm_plane *plane, +int sde_plane_set_property(struct drm_plane *plane, struct drm_property *property, uint64_t val) { - int rc; - - SDE_PLANE_DEBUG_START(); - rc = sde_plane_atomic_set_property(plane, plane->state, property, - val); - SDE_PLANE_DEBUG_END(); - return rc; -} - -static int sde_plane_atomic_get_property(struct drm_plane *plane, - const struct drm_plane_state *state, - struct drm_property *property, uint64_t *val) -{ - struct drm_device *dev = plane->dev; - struct sde_plane_state *pstate; - struct msm_drm_private *dev_priv = dev->dev_private; - int ret = 0; - - SDE_PLANE_DEBUG_START(); - pstate = to_sde_plane_state(state); - -#define GET_PROPERTY(name, NAME, type) do { \ - if (dev_priv->plane_property[PLANE_PROP_##NAME] == property) { \ - *val = pstate->name; \ - DBG("Get property %s %lld", #name, *val); \ - goto done; \ - } \ - } while (0) - - GET_PROPERTY(zpos, ZPOS, uint8_t); - - dev_err(dev->dev, "Invalid property\n"); - ret = -EINVAL; -done: - SDE_PLANE_DEBUG_END(); - return ret; -#undef SET_PROPERTY -} - -static void sde_plane_destroy(struct drm_plane *plane) -{ - struct sde_plane *psde = to_sde_plane(plane); - - SDE_PLANE_DEBUG_START(); - - if (psde->pipe_hw) - sde_hw_sspp_destroy(psde->pipe_hw); - - drm_plane_helper_disable(plane); - drm_plane_cleanup(plane); - - kfree(psde); - - SDE_PLANE_DEBUG_END(); -} - -static void sde_plane_destroy_state(struct drm_plane *plane, - struct drm_plane_state *state) -{ - SDE_PLANE_DEBUG_START(); - if (state->fb) - drm_framebuffer_unreference(state->fb); - - kfree(to_sde_plane_state(state)); - SDE_PLANE_DEBUG_END(); -} - -static struct drm_plane_state * -sde_plane_duplicate_state(struct drm_plane *plane) -{ - struct sde_plane_state *pstate; - - if (WARN_ON(!plane->state)) - return NULL; - - SDE_PLANE_DEBUG_START(); - pstate = kmemdup(to_sde_plane_state(plane->state), - sizeof(*pstate), GFP_KERNEL); - - if (pstate && pstate->base.fb) - drm_framebuffer_reference(pstate->base.fb); - - pstate->mode_changed = false; - pstate->pending = false; - SDE_PLANE_DEBUG_END(); - - return &pstate->base; -} - -static void sde_plane_reset(struct drm_plane *plane) -{ - struct sde_plane_state *pstate; - - SDE_PLANE_DEBUG_START(); - if (plane->state && plane->state->fb) - drm_framebuffer_unreference(plane->state->fb); - - kfree(to_sde_plane_state(plane->state)); - pstate = kzalloc(sizeof(*pstate), GFP_KERNEL); - - memset(pstate, 0, sizeof(struct sde_plane_state)); - - /* assign default blend parameters */ - pstate->alpha = 255; - pstate->premultiplied = 0; - - if (plane->type == DRM_PLANE_TYPE_PRIMARY) - pstate->zpos = STAGE_BASE; - else - pstate->zpos = STAGE0 + drm_plane_index(plane); - - pstate->base.plane = plane; - - plane->state = &pstate->base; - SDE_PLANE_DEBUG_END(); + return -EINVAL; } static const struct drm_plane_funcs sde_plane_funcs = { - .update_plane = drm_atomic_helper_update_plane, - .disable_plane = drm_atomic_helper_disable_plane, + .update_plane = sde_plane_update, + .disable_plane = sde_plane_disable, .destroy = sde_plane_destroy, .set_property = sde_plane_set_property, - .atomic_set_property = sde_plane_atomic_set_property, - .atomic_get_property = sde_plane_atomic_get_property, - .reset = sde_plane_reset, - .atomic_duplicate_state = sde_plane_duplicate_state, - .atomic_destroy_state = sde_plane_destroy_state, -}; - -static const struct drm_plane_helper_funcs sde_plane_helper_funcs = { - .prepare_fb = sde_plane_prepare_fb, - .cleanup_fb = sde_plane_cleanup_fb, - .atomic_check = sde_plane_atomic_check, - .atomic_update = sde_plane_atomic_update, }; -enum sde_sspp sde_plane_pipe(struct drm_plane *plane) +void sde_plane_set_scanout(struct drm_plane *plane, + struct drm_framebuffer *fb) { - struct sde_plane *sde_plane = to_sde_plane(plane); +} - return sde_plane->pipe; +int sde_plane_mode_set(struct drm_plane *plane, + struct drm_crtc *crtc, struct drm_framebuffer *fb, + int crtc_x, int crtc_y, + unsigned int crtc_w, unsigned int crtc_h, + uint32_t src_x, uint32_t src_y, + uint32_t src_w, uint32_t src_h) +{ + return 0; } /* initialize plane */ -struct drm_plane *sde_plane_init(struct drm_device *dev, uint32_t pipe, - bool private_plane) +struct drm_plane *sde_plane_init(struct drm_device *dev, bool private_plane) { - static const char tmp_name[] = "---"; struct drm_plane *plane = NULL; - struct sde_plane *psde; - struct sde_hw_ctl *sde_ctl; - struct msm_drm_private *priv; - struct sde_kms *kms; - struct sde_mdss_cfg *sde_cat; + struct sde_plane *sde_plane; int ret; enum drm_plane_type type; - priv = dev->dev_private; - kms = to_sde_kms(to_mdp_kms(priv->kms)); - - psde = kzalloc(sizeof(*psde), GFP_KERNEL); - if (!psde) { + sde_plane = kzalloc(sizeof(*sde_plane), GFP_KERNEL); + if (!sde_plane) { ret = -ENOMEM; goto fail; } - memset(psde, 0, sizeof(*psde)); - - plane = &psde->base; - - psde->pipe = pipe; - psde->name = tmp_name; - - if (kms) { - /* mmu id for buffer mapping */ - psde->mmu_id = kms->mmu_id; - - /* check catalog for features mask */ - sde_cat = kms->catalog; - if (sde_cat) - psde->features = sde_cat->sspp[pipe].features; - } - psde->nformats = mdp_get_formats(psde->formats, - ARRAY_SIZE(psde->formats), - !(psde->features & BIT(SDE_SSPP_CSC)) || - !(psde->features & SDE_PLANE_FEATURE_SCALER)); + plane = &sde_plane->base; type = private_plane ? DRM_PLANE_TYPE_PRIMARY : DRM_PLANE_TYPE_OVERLAY; - ret = drm_universal_plane_init(dev, plane, 0xff, &sde_plane_funcs, - psde->formats, psde->nformats, - type); - if (ret) - goto fail; - - drm_plane_helper_add(plane, &sde_plane_helper_funcs); + drm_universal_plane_init(dev, plane, 0xff, &sde_plane_funcs, + sde_plane->formats, sde_plane->nformats, + type); sde_plane_install_properties(plane, &plane->base); - psde->pipe_hw = sde_hw_sspp_init(pipe, kms->mmio, sde_cat); - if (IS_ERR(psde->pipe_hw)) { - ret = PTR_ERR(psde->pipe_hw); - psde->pipe_hw = NULL; - goto fail; - } - - /* cache flush mask for later */ - sde_ctl = sde_hw_ctl_init(CTL_0, kms->mmio, sde_cat); - if (!IS_ERR(sde_ctl)) { - if (sde_ctl->ops.get_bitmask_sspp) - sde_ctl->ops.get_bitmask_sspp(sde_ctl, - &psde->flush_mask, pipe); - sde_hw_ctl_destroy(sde_ctl); - } - - pr_err("%s: Successfully created plane\n", __func__); return plane; fail: - pr_err("%s: Plane creation failed\n", __func__); if (plane) sde_plane_destroy(plane); |
