diff options
author | Dave Airlie <airlied@redhat.com> | 2016-03-05 08:07:58 +1000 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2016-03-05 08:07:58 +1000 |
commit | a90cc3f25065e5e8d5e336c75b04d5882912871f (patch) | |
tree | 659048d3ce70a20d2c2391ed45e269bdb1e3b2c0 /drivers/gpu/drm/omapdrm/omap_crtc.c | |
parent | 912b330c20096a9b579ec151ec1d2225eb93b38f (diff) | |
parent | 1c278e5e3718d15475ec08ee2135f37a6b13361c (diff) |
Merge tag 'omapdrm-4.6' of git://git.kernel.org/pub/scm/linux/kernel/git/tomba/linux into drm-next
omapdrm changes for v4.6
* HDMI interlace output support
* DMAbuf import support
* Big refactoring leading to removal of legacy code
* Various non-critical fixes
* tag 'omapdrm-4.6' of git://git.kernel.org/pub/scm/linux/kernel/git/tomba/linux: (76 commits)
drm/omap: no need to select OMAP2_DSS
drm/omap: gem: Fix omap_gem_new() error path
drm/omap: remove -Werror from Makefile
drm/omap: remove dispc_ovl_check()
drm/omap: remove dss compat code
drm/omap: remove last uses of omap_overlay_manager
drm/omap: DSI: remove uses of omap_overlay_manager
drm/omap: VENC: remove uses of omap_overlay_manager
drm/omap: SDI: remove uses of omap_overlay_manager
drm/omap: HDMI4: remove uses of omap_overlay_manager
drm/omap: HDMI5: remove uses of omap_overlay_manager
drm/omap: DPI: remove uses of omap_overlay_manager
drm/omap: remove extra manager checks on disconnect
drm/omap: remove extra check in dpi and sdi
drm/omap: convert dss_mgr_unregister_framedone_handler to accept omap_channel
drm/omap: convert dss_mgr_register_framedone_handler to accept omap_channel
drm/omap: convert dss_mgr_start_update to accept omap_channel
drm/omap: convert dss_mgr_disable to accept omap_channel
drm/omap: convert dss_mgr_enable to accept omap_channel
drm/omap: convert dss_mgr_set_lcd_config to accept omap_channel
...
Diffstat (limited to 'drivers/gpu/drm/omapdrm/omap_crtc.c')
-rw-r--r-- | drivers/gpu/drm/omapdrm/omap_crtc.c | 119 |
1 files changed, 70 insertions, 49 deletions
diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c index d38fcbcc43a8..04097dab8589 100644 --- a/drivers/gpu/drm/omapdrm/omap_crtc.c +++ b/drivers/gpu/drm/omapdrm/omap_crtc.c @@ -34,14 +34,6 @@ struct omap_crtc { const char *name; enum omap_channel channel; - /* - * Temporary: eventually this will go away, but it is needed - * for now to keep the output's happy. (They only need - * mgr->id.) Eventually this will be replaced w/ something - * more common-panel-framework-y - */ - struct omap_overlay_manager *mgr; - struct omap_video_timings timings; struct omap_drm_irq vblank_irq; @@ -80,9 +72,13 @@ int omap_crtc_wait_pending(struct drm_crtc *crtc) { struct omap_crtc *omap_crtc = to_omap_crtc(crtc); + /* + * Timeout is set to a "sufficiently" high value, which should cover + * a single frame refresh even on slower displays. + */ return wait_event_timeout(omap_crtc->pending_wait, !omap_crtc->pending, - msecs_to_jiffies(50)); + msecs_to_jiffies(250)); } /* ----------------------------------------------------------------------------- @@ -100,31 +96,32 @@ int omap_crtc_wait_pending(struct drm_crtc *crtc) /* ovl-mgr-id -> crtc */ static struct omap_crtc *omap_crtcs[8]; +static struct omap_dss_device *omap_crtc_output[8]; /* we can probably ignore these until we support command-mode panels: */ -static int omap_crtc_dss_connect(struct omap_overlay_manager *mgr, +static int omap_crtc_dss_connect(enum omap_channel channel, struct omap_dss_device *dst) { - if (mgr->output) + if (omap_crtc_output[channel]) return -EINVAL; - if ((mgr->supported_outputs & dst->id) == 0) + if ((dispc_mgr_get_supported_outputs(channel) & dst->id) == 0) return -EINVAL; - dst->manager = mgr; - mgr->output = dst; + omap_crtc_output[channel] = dst; + dst->dispc_channel_connected = true; return 0; } -static void omap_crtc_dss_disconnect(struct omap_overlay_manager *mgr, +static void omap_crtc_dss_disconnect(enum omap_channel channel, struct omap_dss_device *dst) { - mgr->output->manager = NULL; - mgr->output = NULL; + omap_crtc_output[channel] = NULL; + dst->dispc_channel_connected = false; } -static void omap_crtc_dss_start_update(struct omap_overlay_manager *mgr) +static void omap_crtc_dss_start_update(enum omap_channel channel) { } @@ -138,6 +135,11 @@ static void omap_crtc_set_enabled(struct drm_crtc *crtc, bool enable) u32 framedone_irq, vsync_irq; int ret; + if (omap_crtc_output[channel]->output_type == OMAP_DISPLAY_TYPE_HDMI) { + dispc_mgr_enable(channel, enable); + return; + } + if (dispc_mgr_is_enabled(channel) == enable) return; @@ -186,9 +188,9 @@ static void omap_crtc_set_enabled(struct drm_crtc *crtc, bool enable) } -static int omap_crtc_dss_enable(struct omap_overlay_manager *mgr) +static int omap_crtc_dss_enable(enum omap_channel channel) { - struct omap_crtc *omap_crtc = omap_crtcs[mgr->id]; + struct omap_crtc *omap_crtc = omap_crtcs[channel]; struct omap_overlay_manager_info info; memset(&info, 0, sizeof(info)); @@ -205,38 +207,38 @@ static int omap_crtc_dss_enable(struct omap_overlay_manager *mgr) return 0; } -static void omap_crtc_dss_disable(struct omap_overlay_manager *mgr) +static void omap_crtc_dss_disable(enum omap_channel channel) { - struct omap_crtc *omap_crtc = omap_crtcs[mgr->id]; + struct omap_crtc *omap_crtc = omap_crtcs[channel]; omap_crtc_set_enabled(&omap_crtc->base, false); } -static void omap_crtc_dss_set_timings(struct omap_overlay_manager *mgr, +static void omap_crtc_dss_set_timings(enum omap_channel channel, const struct omap_video_timings *timings) { - struct omap_crtc *omap_crtc = omap_crtcs[mgr->id]; + struct omap_crtc *omap_crtc = omap_crtcs[channel]; DBG("%s", omap_crtc->name); omap_crtc->timings = *timings; } -static void omap_crtc_dss_set_lcd_config(struct omap_overlay_manager *mgr, +static void omap_crtc_dss_set_lcd_config(enum omap_channel channel, const struct dss_lcd_mgr_config *config) { - struct omap_crtc *omap_crtc = omap_crtcs[mgr->id]; + struct omap_crtc *omap_crtc = omap_crtcs[channel]; DBG("%s", omap_crtc->name); dispc_mgr_set_lcd_config(omap_crtc->channel, config); } static int omap_crtc_dss_register_framedone( - struct omap_overlay_manager *mgr, + enum omap_channel channel, void (*handler)(void *), void *data) { return 0; } static void omap_crtc_dss_unregister_framedone( - struct omap_overlay_manager *mgr, + enum omap_channel channel, void (*handler)(void *), void *data) { } @@ -403,24 +405,40 @@ static void omap_crtc_atomic_flush(struct drm_crtc *crtc, } } +static bool omap_crtc_is_plane_prop(struct drm_device *dev, + struct drm_property *property) +{ + struct omap_drm_private *priv = dev->dev_private; + + return property == priv->zorder_prop || + property == dev->mode_config.rotation_property; +} + static int omap_crtc_atomic_set_property(struct drm_crtc *crtc, struct drm_crtc_state *state, struct drm_property *property, uint64_t val) { - struct drm_plane_state *plane_state; - struct drm_plane *plane = crtc->primary; + struct drm_device *dev = crtc->dev; - /* - * Delegate property set to the primary plane. Get the plane state and - * set the property directly. - */ + if (omap_crtc_is_plane_prop(dev, property)) { + struct drm_plane_state *plane_state; + struct drm_plane *plane = crtc->primary; - plane_state = drm_atomic_get_plane_state(state->state, plane); - if (!plane_state) - return -EINVAL; + /* + * Delegate property set to the primary plane. Get the plane + * state and set the property directly. + */ + + plane_state = drm_atomic_get_plane_state(state->state, plane); + if (IS_ERR(plane_state)) + return PTR_ERR(plane_state); - return drm_atomic_plane_set_property(plane, plane_state, property, val); + return drm_atomic_plane_set_property(plane, plane_state, + property, val); + } + + return -EINVAL; } static int omap_crtc_atomic_get_property(struct drm_crtc *crtc, @@ -428,14 +446,20 @@ static int omap_crtc_atomic_get_property(struct drm_crtc *crtc, struct drm_property *property, uint64_t *val) { - /* - * Delegate property get to the primary plane. The - * drm_atomic_plane_get_property() function isn't exported, but can be - * called through drm_object_property_get_value() as that will call - * drm_atomic_get_property() for atomic drivers. - */ - return drm_object_property_get_value(&crtc->primary->base, property, - val); + struct drm_device *dev = crtc->dev; + + if (omap_crtc_is_plane_prop(dev, property)) { + /* + * Delegate property get to the primary plane. The + * drm_atomic_plane_get_property() function isn't exported, but + * can be called through drm_object_property_get_value() as that + * will call drm_atomic_get_property() for atomic drivers. + */ + return drm_object_property_get_value(&crtc->primary->base, + property, val); + } + + return -EINVAL; } static const struct drm_crtc_funcs omap_crtc_funcs = { @@ -509,9 +533,6 @@ struct drm_crtc *omap_crtc_init(struct drm_device *dev, omap_crtc->error_irq.irq = omap_crtc_error_irq; omap_irq_register(dev, &omap_crtc->error_irq); - /* temporary: */ - omap_crtc->mgr = omap_dss_get_overlay_manager(channel); - ret = drm_crtc_init_with_planes(dev, crtc, plane, NULL, &omap_crtc_funcs, NULL); if (ret < 0) { |