diff options
Diffstat (limited to 'drivers/gpu/drm/omapdrm/omap_crtc.c')
-rw-r--r-- | drivers/gpu/drm/omapdrm/omap_crtc.c | 111 |
1 files changed, 19 insertions, 92 deletions
diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c index 6c4d40b824e4..62928ec0e7db 100644 --- a/drivers/gpu/drm/omapdrm/omap_crtc.c +++ b/drivers/gpu/drm/omapdrm/omap_crtc.c @@ -41,6 +41,7 @@ struct omap_crtc { struct drm_crtc base; const char *name; + struct omap_drm_pipeline *pipe; enum omap_channel channel; struct videomode vm; @@ -108,38 +109,7 @@ int omap_crtc_wait_pending(struct drm_crtc *crtc) * job of sequencing the setup of the video pipe in the proper order */ -/* 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_drm_private *priv, - enum omap_channel channel, - struct omap_dss_device *dst) -{ - const struct dispc_ops *dispc_ops = priv->dispc_ops; - struct dispc_device *dispc = priv->dispc; - - if (omap_crtc_output[channel]) - return -EINVAL; - - if (!(dispc_ops->mgr_get_supported_outputs(dispc, channel) & dst->id)) - return -EINVAL; - - omap_crtc_output[channel] = dst; - dst->dispc_channel_connected = true; - - return 0; -} - -static void omap_crtc_dss_disconnect(struct omap_drm_private *priv, - enum omap_channel channel, - struct omap_dss_device *dst) -{ - omap_crtc_output[channel] = NULL; - dst->dispc_channel_connected = false; -} - static void omap_crtc_dss_start_update(struct omap_drm_private *priv, enum omap_channel channel) { @@ -159,7 +129,7 @@ static void omap_crtc_set_enabled(struct drm_crtc *crtc, bool enable) if (WARN_ON(omap_crtc->enabled == enable)) return; - if (omap_crtc_output[channel]->output_type == OMAP_DISPLAY_TYPE_HDMI) { + if (omap_crtc->pipe->output->output_type == OMAP_DISPLAY_TYPE_HDMI) { priv->dispc_ops->mgr_enable(priv->dispc, channel, enable); omap_crtc->enabled = enable; return; @@ -215,7 +185,8 @@ static void omap_crtc_set_enabled(struct drm_crtc *crtc, bool enable) static int omap_crtc_dss_enable(struct omap_drm_private *priv, enum omap_channel channel) { - struct omap_crtc *omap_crtc = omap_crtcs[channel]; + struct drm_crtc *crtc = priv->channels[channel]->crtc; + struct omap_crtc *omap_crtc = to_omap_crtc(crtc); priv->dispc_ops->mgr_set_timings(priv->dispc, omap_crtc->channel, &omap_crtc->vm); @@ -227,7 +198,8 @@ static int omap_crtc_dss_enable(struct omap_drm_private *priv, static void omap_crtc_dss_disable(struct omap_drm_private *priv, enum omap_channel channel) { - struct omap_crtc *omap_crtc = omap_crtcs[channel]; + struct drm_crtc *crtc = priv->channels[channel]->crtc; + struct omap_crtc *omap_crtc = to_omap_crtc(crtc); omap_crtc_set_enabled(&omap_crtc->base, false); } @@ -236,7 +208,9 @@ static void omap_crtc_dss_set_timings(struct omap_drm_private *priv, enum omap_channel channel, const struct videomode *vm) { - struct omap_crtc *omap_crtc = omap_crtcs[channel]; + struct drm_crtc *crtc = priv->channels[channel]->crtc; + struct omap_crtc *omap_crtc = to_omap_crtc(crtc); + DBG("%s", omap_crtc->name); omap_crtc->vm = *vm; } @@ -245,7 +219,8 @@ static void omap_crtc_dss_set_lcd_config(struct omap_drm_private *priv, enum omap_channel channel, const struct dss_lcd_mgr_config *config) { - struct omap_crtc *omap_crtc = omap_crtcs[channel]; + struct drm_crtc *crtc = priv->channels[channel]->crtc; + struct omap_crtc *omap_crtc = to_omap_crtc(crtc); DBG("%s", omap_crtc->name); priv->dispc_ops->mgr_set_lcd_config(priv->dispc, omap_crtc->channel, @@ -266,8 +241,6 @@ static void omap_crtc_dss_unregister_framedone( } static const struct dss_mgr_ops mgr_ops = { - .connect = omap_crtc_dss_connect, - .disconnect = omap_crtc_dss_disconnect, .start_update = omap_crtc_dss_start_update, .enable = omap_crtc_dss_enable, .disable = omap_crtc_dss_disable, @@ -447,11 +420,6 @@ static void omap_crtc_mode_set_nofb(struct drm_crtc *crtc) { struct omap_crtc *omap_crtc = to_omap_crtc(crtc); struct drm_display_mode *mode = &crtc->state->adjusted_mode; - struct omap_drm_private *priv = crtc->dev->dev_private; - const u32 flags_mask = DISPLAY_FLAGS_DE_HIGH | DISPLAY_FLAGS_DE_LOW | - DISPLAY_FLAGS_PIXDATA_POSEDGE | DISPLAY_FLAGS_PIXDATA_NEGEDGE | - DISPLAY_FLAGS_SYNC_POSEDGE | DISPLAY_FLAGS_SYNC_NEGEDGE; - unsigned int i; DBG("%s: set mode: %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x", omap_crtc->name, mode->base.id, mode->name, @@ -461,38 +429,6 @@ static void omap_crtc_mode_set_nofb(struct drm_crtc *crtc) mode->type, mode->flags); drm_display_mode_to_videomode(mode, &omap_crtc->vm); - - /* - * HACK: This fixes the vm flags. - * struct drm_display_mode does not contain the VSYNC/HSYNC/DE flags - * and they get lost when converting back and forth between - * struct drm_display_mode and struct videomode. The hack below - * goes and fetches the missing flags from the panel drivers. - * - * Correct solution would be to use DRM's bus-flags, but that's not - * easily possible before the omapdrm's panel/encoder driver model - * has been changed to the DRM model. - */ - - for (i = 0; i < priv->num_encoders; ++i) { - struct drm_encoder *encoder = priv->encoders[i]; - - if (encoder->crtc == crtc) { - struct omap_dss_device *dssdev; - - dssdev = omap_encoder_get_dssdev(encoder); - - if (dssdev) { - struct videomode vm = {0}; - - dssdev->driver->get_timings(dssdev, &vm); - - omap_crtc->vm.flags |= vm.flags & flags_mask; - } - - break; - } - } } static int omap_crtc_atomic_check(struct drm_crtc *crtc, @@ -681,37 +617,29 @@ static const char *channel_names[] = { void omap_crtc_pre_init(struct omap_drm_private *priv) { - memset(omap_crtcs, 0, sizeof(omap_crtcs)); - - dss_install_mgr_ops(&mgr_ops, priv); + dss_install_mgr_ops(priv->dss, &mgr_ops, priv); } -void omap_crtc_pre_uninit(void) +void omap_crtc_pre_uninit(struct omap_drm_private *priv) { - dss_uninstall_mgr_ops(); + dss_uninstall_mgr_ops(priv->dss); } /* initialize crtc */ struct drm_crtc *omap_crtc_init(struct drm_device *dev, - struct drm_plane *plane, struct omap_dss_device *dssdev) + struct omap_drm_pipeline *pipe, + struct drm_plane *plane) { struct omap_drm_private *priv = dev->dev_private; struct drm_crtc *crtc = NULL; struct omap_crtc *omap_crtc; enum omap_channel channel; - struct omap_dss_device *out; int ret; - out = omapdss_find_output_from_display(dssdev); - channel = out->dispc_channel; - omap_dss_put_device(out); + channel = pipe->output->dispc_channel; DBG("%s", channel_names[channel]); - /* Multiple displays on same channel is not allowed */ - if (WARN_ON(omap_crtcs[channel] != NULL)) - return ERR_PTR(-EINVAL); - omap_crtc = kzalloc(sizeof(*omap_crtc), GFP_KERNEL); if (!omap_crtc) return ERR_PTR(-ENOMEM); @@ -720,6 +648,7 @@ struct drm_crtc *omap_crtc_init(struct drm_device *dev, init_waitqueue_head(&omap_crtc->pending_wait); + omap_crtc->pipe = pipe; omap_crtc->channel = channel; omap_crtc->name = channel_names[channel]; @@ -727,7 +656,7 @@ struct drm_crtc *omap_crtc_init(struct drm_device *dev, &omap_crtc_funcs, NULL); if (ret < 0) { dev_err(dev->dev, "%s(): could not init crtc for: %s\n", - __func__, dssdev->name); + __func__, pipe->display->name); kfree(omap_crtc); return ERR_PTR(ret); } @@ -750,7 +679,5 @@ struct drm_crtc *omap_crtc_init(struct drm_device *dev, omap_plane_install_properties(crtc->primary, &crtc->base); - omap_crtcs[channel] = omap_crtc; - return crtc; } |