diff options
Diffstat (limited to 'samsung')
-rw-r--r-- | samsung/exynos_drm_crtc.c | 83 | ||||
-rw-r--r-- | samsung/exynos_drm_crtc.h | 6 | ||||
-rw-r--r-- | samsung/exynos_drm_decon.c | 7 | ||||
-rw-r--r-- | samsung/exynos_drm_fb.c | 161 | ||||
-rw-r--r-- | samsung/exynos_drm_writeback.c | 19 |
5 files changed, 16 insertions, 260 deletions
diff --git a/samsung/exynos_drm_crtc.c b/samsung/exynos_drm_crtc.c index 1e25145..e8ad5dc 100644 --- a/samsung/exynos_drm_crtc.c +++ b/samsung/exynos_drm_crtc.c @@ -15,7 +15,6 @@ #include <drm/drm_atomic.h> #include <drm/drm_atomic_helper.h> -#include <drm/drm_bridge.h> #include <drm/drm_encoder.h> #include <drm/drm_color_mgmt.h> #include <drm/drm_crtc_helper.h> @@ -1051,85 +1050,3 @@ void exynos_crtc_wait_for_flip_done(struct drm_atomic_state *old_state) old_crtc_state, new_crtc_state); } } - -bool exynos_crtc_needs_disable(struct drm_crtc_state *old_state, - struct drm_crtc_state *new_state) -{ - /* - * No new_state means the CRTC is off, so the only criteria is whether - * it's currently active or in self refresh mode. - */ - if (!new_state) - return drm_atomic_crtc_effectively_active(old_state); - - /* - * We need to run through the crtc_funcs->disable() function if the CRTC - * is currently on, if it's transitioning to self refresh mode, or if - * it's in self refresh mode and needs to be fully disabled. - */ - return old_state->active || - (old_state->self_refresh_active && !new_state->enable) || - new_state->self_refresh_active; -} - -void exynos_crtc_set_mode(struct drm_device *dev, - struct drm_atomic_state *old_state) -{ - struct drm_crtc *crtc; - struct drm_crtc_state *new_crtc_state; - struct drm_connector *connector; - struct drm_connector_state *new_conn_state; - int i; - - for_each_new_crtc_in_state(old_state, crtc, new_crtc_state, i) { - const struct drm_crtc_helper_funcs *funcs; - - if (!new_crtc_state->mode_changed) - continue; - - funcs = crtc->helper_private; - - if (new_crtc_state->enable && funcs->mode_set_nofb) { - DRM_DEBUG_ATOMIC("modeset on [CRTC:%d:%s]\n", - crtc->base.id, crtc->name); - - funcs->mode_set_nofb(crtc); - } - } - - for_each_new_connector_in_state(old_state, connector, new_conn_state, i) { - const struct drm_encoder_helper_funcs *funcs; - struct drm_encoder *encoder; - struct drm_display_mode *mode, *adjusted_mode; - struct drm_bridge *bridge; - - if (!new_conn_state->best_encoder) - continue; - - encoder = new_conn_state->best_encoder; - funcs = encoder->helper_private; - new_crtc_state = new_conn_state->crtc->state; - mode = &new_crtc_state->mode; - adjusted_mode = &new_crtc_state->adjusted_mode; - - if (!new_crtc_state->mode_changed) - continue; - - DRM_DEBUG_ATOMIC("modeset on [ENCODER:%d:%s]\n", - encoder->base.id, encoder->name); - - /* - * Each encoder has at most one connector (since we always steal - * it away), so we won't call mode_set hooks twice. - */ - if (funcs && funcs->atomic_mode_set) { - funcs->atomic_mode_set(encoder, new_crtc_state, - new_conn_state); - } else if (funcs && funcs->mode_set) { - funcs->mode_set(encoder, mode, adjusted_mode); - } - - bridge = drm_bridge_chain_get_first_bridge(encoder); - drm_bridge_chain_mode_set(bridge, mode, adjusted_mode); - } -} diff --git a/samsung/exynos_drm_crtc.h b/samsung/exynos_drm_crtc.h index 42d4100..7d13e92 100644 --- a/samsung/exynos_drm_crtc.h +++ b/samsung/exynos_drm_crtc.h @@ -59,10 +59,4 @@ void exynos_drm_crtc_te_handler(struct drm_crtc *crtc); void exynos_crtc_handle_event(struct exynos_drm_crtc *exynos_crtc); void exynos_crtc_wait_for_flip_done(struct drm_atomic_state *old_state); - -bool exynos_crtc_needs_disable(struct drm_crtc_state *old_state, - struct drm_crtc_state *new_state); - -void exynos_crtc_set_mode(struct drm_device *dev, - struct drm_atomic_state *old_state); #endif diff --git a/samsung/exynos_drm_decon.c b/samsung/exynos_drm_decon.c index 8671018..dd41789 100644 --- a/samsung/exynos_drm_decon.c +++ b/samsung/exynos_drm_decon.c @@ -847,8 +847,6 @@ static void decon_atomic_flush(struct exynos_drm_crtc *exynos_crtc, if (new_exynos_crtc_state->wb_type == EXYNOS_WB_CWB) decon_reg_set_cwb_enable(decon->id, true); - else if (old_exynos_crtc_state->wb_type == EXYNOS_WB_CWB) - decon_reg_set_cwb_enable(decon->id, false); /* if there are no dpp planes attached, enable colormap as fallback */ if ((new_crtc_state->plane_mask & ~exynos_crtc->rcd_plane_mask) == 0) { @@ -1450,6 +1448,8 @@ static void decon_wait_for_flip_done(struct exynos_drm_crtc *crtc, struct decon_device *decon = crtc->ctx; struct drm_crtc_commit *commit = new_crtc_state->commit; struct decon_mode *mode; + struct exynos_drm_crtc_state *new_exynos_crtc_state = + to_exynos_crtc_state(new_crtc_state); int fps, recovering; if (!new_crtc_state->active) @@ -1495,6 +1495,9 @@ static void decon_wait_for_flip_done(struct exynos_drm_crtc *crtc, DPU_EVENT_LOG(DPU_EVT_DECON_TRIG_MASK, decon->id, NULL); decon_reg_set_trigger(decon->id, mode, DECON_TRIG_MASK); } + + if (new_exynos_crtc_state->wb_type == EXYNOS_WB_CWB) + decon_reg_set_cwb_enable(decon->id, false); } static const struct exynos_drm_crtc_ops decon_crtc_ops = { diff --git a/samsung/exynos_drm_fb.c b/samsung/exynos_drm_fb.c index 027fbdf..97d4dda 100644 --- a/samsung/exynos_drm_fb.c +++ b/samsung/exynos_drm_fb.c @@ -15,7 +15,6 @@ #include <drm/drm_atomic.h> #include <drm/drm_atomic_helper.h> -#include <drm/drm_bridge.h> #include <drm/drm_crtc.h> #include <drm/drm_crtc_helper.h> #include <drm/drm_fb_helper.h> @@ -544,59 +543,20 @@ static void exynos_rmem_free(struct decon_device *decon) decon->fb_handover.phys_size = 0; } -static void -exynos_disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state, - unsigned int *disabling_crtc_mask) + +static void exynos_atomic_commit_tail(struct drm_atomic_state *old_state) { + int i; + struct drm_device *dev = old_state->dev; struct decon_device *decon; - struct drm_connector *connector; - struct drm_connector_state *old_conn_state, *new_conn_state; struct drm_crtc *crtc; struct drm_crtc_state *old_crtc_state, *new_crtc_state; - int i; - - for_each_oldnew_connector_in_state(old_state, connector, old_conn_state, - new_conn_state, i) { - struct drm_encoder *encoder; - struct drm_bridge *bridge; - - /* Shut down everything that's in the changeset and currently - * still on. So need to check the old, saved state. - */ - if (!old_conn_state->crtc) - continue; - - old_crtc_state = drm_atomic_get_old_crtc_state(old_state, old_conn_state->crtc); - - if (new_conn_state->crtc) - new_crtc_state = drm_atomic_get_new_crtc_state( - old_state, - new_conn_state->crtc); - else - new_crtc_state = NULL; - - if (!exynos_crtc_needs_disable(old_crtc_state, new_crtc_state) || - !drm_atomic_crtc_needs_modeset(old_conn_state->crtc->state)) - continue; - - encoder = old_conn_state->best_encoder; - - /* We shouldn't get this far if we didn't previously have - * an encoder.. but WARN_ON() rather than explode. - */ - if (WARN_ON(!encoder)) - continue; - - DRM_DEBUG_ATOMIC("disabling bridge chain [ENCODER:%d:%s]\n", - encoder->base.id, encoder->name); + struct drm_connector *connector; + struct drm_connector_state *old_conn_state; + struct drm_connector_state *new_conn_state; + unsigned int disabling_crtc_mask = 0; - /* - * Each encoder has at most one connector (since we always steal - * it away), so we won't call disable hooks twice. - */ - bridge = drm_bridge_chain_get_first_bridge(encoder); - drm_atomic_bridge_chain_disable(bridge, old_state); - } + DPU_ATRACE_BEGIN("exynos_atomic_commit_tail"); for_each_oldnew_crtc_in_state(old_state, crtc, old_crtc_state, new_crtc_state, i) { @@ -626,7 +586,7 @@ exynos_disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_stat if (drm_atomic_crtc_effectively_active(old_crtc_state) && !new_crtc_state->active) { /* keep runtime vote while disabling is taking place */ pm_runtime_get_sync(decon->dev); - *disabling_crtc_mask |= drm_crtc_mask(crtc); + disabling_crtc_mask |= drm_crtc_mask(crtc); } if (old_crtc_state->active && drm_atomic_crtc_needs_modeset(new_crtc_state)) { @@ -649,107 +609,8 @@ exynos_disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_stat old_crtc_state->active = true; } - for_each_oldnew_connector_in_state(old_state, connector, old_conn_state, - new_conn_state, i) { - const struct drm_encoder_helper_funcs *funcs; - struct drm_encoder *encoder; - struct drm_bridge *bridge; - - /* Shut down everything that's in the changeset and currently - * still on. So need to check the old, saved state. - */ - if (!old_conn_state->crtc) - continue; - - old_crtc_state = drm_atomic_get_old_crtc_state(old_state, old_conn_state->crtc); - - if (new_conn_state->crtc) - new_crtc_state = drm_atomic_get_new_crtc_state( - old_state, - new_conn_state->crtc); - else - new_crtc_state = NULL; - - if (!exynos_crtc_needs_disable(old_crtc_state, new_crtc_state) || - !drm_atomic_crtc_needs_modeset(old_conn_state->crtc->state)) - continue; - - encoder = old_conn_state->best_encoder; - - /* We shouldn't get this far if we didn't previously have - * an encoder.. but WARN_ON() rather than explode. - */ - if (WARN_ON(!encoder)) - continue; - - funcs = encoder->helper_private; - - DRM_DEBUG_ATOMIC("disabling [ENCODER:%d:%s]\n", - encoder->base.id, encoder->name); - - /* - * Each encoder has at most one connector (since we always steal - * it away), so we won't call disable hooks twice. - */ - bridge = drm_bridge_chain_get_first_bridge(encoder); - - /* Right function depends upon target state. */ - if (funcs) { - if (funcs->atomic_disable) - funcs->atomic_disable(encoder, old_state); - else if (new_conn_state->crtc && funcs->prepare) - funcs->prepare(encoder); - else if (funcs->disable) - funcs->disable(encoder); - else if (funcs->dpms) - funcs->dpms(encoder, DRM_MODE_DPMS_OFF); - } - - drm_atomic_bridge_chain_post_disable(bridge, old_state); - } -} - -/** - * exynos_drm_atomic_helper_commit_modeset_disables - modeset commit to disable outputs - * @dev: DRM device - * @old_state: atomic state object with old state structures - * @disabling_crtc_mask: the disabling crtc mask - * - * This function shuts down all the outputs that need to be shut down and - * prepares them (if required) with the new mode. - * - * For compatibility with legacy CRTC helpers this should be called before - * drm_atomic_helper_commit_planes(), which is what the default commit function - * does. But drivers with different needs can group the modeset commits together - * and do the plane commits at the end. This is useful for drivers doing runtime - * PM since planes updates then only happen when the CRTC is actually enabled. - */ -static void exynos_drm_atomic_helper_commit_modeset_disables(struct drm_device *dev, - struct drm_atomic_state *old_state, unsigned int *disabling_crtc_mask) -{ - exynos_disable_outputs(dev, old_state, disabling_crtc_mask); - - drm_atomic_helper_update_legacy_modeset_state(dev, old_state); - drm_atomic_helper_calc_timestamping_constants(old_state); - - exynos_crtc_set_mode(dev, old_state); -} - -static void exynos_atomic_commit_tail(struct drm_atomic_state *old_state) -{ - int i; - struct drm_device *dev = old_state->dev; - struct decon_device *decon; - struct drm_crtc *crtc; - struct drm_crtc_state *new_crtc_state; - struct drm_connector *connector; - struct drm_connector_state *old_conn_state; - struct drm_connector_state *new_conn_state; - unsigned int disabling_crtc_mask = 0; - - DPU_ATRACE_BEGIN("exynos_atomic_commit_tail"); DPU_ATRACE_BEGIN("modeset"); - exynos_drm_atomic_helper_commit_modeset_disables(dev, old_state, &disabling_crtc_mask); + drm_atomic_helper_commit_modeset_disables(dev, old_state); exynos_atomic_bts_pre_update(dev, old_state); diff --git a/samsung/exynos_drm_writeback.c b/samsung/exynos_drm_writeback.c index b3c92e4..dab5949 100644 --- a/samsung/exynos_drm_writeback.c +++ b/samsung/exynos_drm_writeback.c @@ -39,20 +39,6 @@ #include "exynos_drm_format.h" #include "exynos_drm_writeback.h" -static inline int wb_check_type(const struct writeback_device *wb, bool *is_cwb) -{ - const struct decon_device *decon = wb_get_decon(wb); - - if (unlikely(!decon)) { - pr_err("%s: unable to get decon\n", __func__); - return -EINVAL; - } - - *is_cwb = decon->config.out_type != DECON_OUT_WB; - - return 0; -} - void wb_dump(struct drm_printer *p, struct writeback_device *wb) { if (wb->state != WB_STATE_ON) { @@ -581,16 +567,11 @@ static irqreturn_t odma_irq_handler(int irq, void *priv) irqs = odma_reg_get_irq_and_clear(wb->id); if (irqs & ODMA_STATUS_FRAMEDONE_IRQ || irqs & ODMA_INST_OFF_DONE_IRQ) { - bool is_cwb; - if (irqs & ODMA_STATUS_FRAMEDONE_IRQ) pr_debug("wb(%d) framedone irq occurs\n", wb->id); else pr_warn("wb(%d) instant off irq occurs\n", wb->id); - if (wb_check_type(wb, &is_cwb) || is_cwb) - decon_reg_set_cwb_enable(wb->decon_id, false); - drm_writeback_signal_completion(&wb->writeback, 0); DPU_EVENT_LOG(DPU_EVT_WB_FRAMEDONE, wb->decon_id, wb); } |