From a82f034765fa3e9db73b8ca99e8830f3bb31ac90 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 13 Feb 2018 14:00:19 +0200 Subject: drm: omapdrm: Split init and cleanup from probe and remove functions When merging the omapdrm and omapdss drivers there will be not omapdrm platform device anymore, and thus no associated probe and remove functions. To prepare for that, split all the initialization code from the probe function to make it usable without a platform device. Similarly, split the cleanup code from the remove function. Signed-off-by: Laurent Pinchart Reviewed-by: Sebastian Reichel --- drivers/gpu/drm/omapdrm/omap_drv.c | 83 +++++++++++++++++++++++--------------- 1 file changed, 51 insertions(+), 32 deletions(-) (limited to 'drivers/gpu/drm/omapdrm/omap_drv.c') diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c index dd68b2556f5b..b571cc04e08d 100644 --- a/drivers/gpu/drm/omapdrm/omap_drv.c +++ b/drivers/gpu/drm/omapdrm/omap_drv.c @@ -510,24 +510,16 @@ static const struct soc_device_attribute omapdrm_soc_devices[] = { { /* sentinel */ } }; -static int pdev_probe(struct platform_device *pdev) +static int omapdrm_init(struct omap_drm_private *priv, struct device *dev) { const struct soc_device_attribute *soc; - struct omap_drm_private *priv; struct drm_device *ddev; unsigned int i; int ret; - DBG("%s", pdev->name); - - if (omapdss_is_initialized() == false) - return -EPROBE_DEFER; + DBG("%s", dev_name(dev)); - ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)); - if (ret) { - dev_err(&pdev->dev, "Failed to set the DMA mask\n"); - return ret; - } + priv->dev = dev; omap_crtc_pre_init(); @@ -535,13 +527,6 @@ static int pdev_probe(struct platform_device *pdev) if (ret) goto err_crtc_uninit; - /* Allocate and initialize the driver private structure. */ - priv = kzalloc(sizeof(*priv), GFP_KERNEL); - if (!priv) { - ret = -ENOMEM; - goto err_disconnect_dssdevs; - } - priv->dispc_ops = dispc_get_ops(); soc = soc_device_match(omapdrm_soc_devices); @@ -552,14 +537,14 @@ static int pdev_probe(struct platform_device *pdev) INIT_LIST_HEAD(&priv->obj_list); /* Allocate and initialize the DRM device. */ - ddev = drm_dev_alloc(&omap_drm_driver, &pdev->dev); + ddev = drm_dev_alloc(&omap_drm_driver, priv->dev); if (IS_ERR(ddev)) { ret = PTR_ERR(ddev); - goto err_free_priv; + goto err_destroy_wq; } + priv->ddev = ddev; ddev->dev_private = priv; - platform_set_drvdata(pdev, ddev); /* Get memory bandwidth limits */ if (priv->dispc_ops->get_memory_bandwidth_limit) @@ -570,14 +555,14 @@ static int pdev_probe(struct platform_device *pdev) ret = omap_modeset_init(ddev); if (ret) { - dev_err(&pdev->dev, "omap_modeset_init failed: ret=%d\n", ret); + dev_err(priv->dev, "omap_modeset_init failed: ret=%d\n", ret); goto err_free_drm_dev; } /* Initialize vblank handling, start with all CRTCs disabled. */ ret = drm_vblank_init(ddev, priv->num_crtcs); if (ret) { - dev_err(&pdev->dev, "could not init vblank\n"); + dev_err(priv->dev, "could not init vblank\n"); goto err_cleanup_modeset; } @@ -610,20 +595,17 @@ err_cleanup_modeset: err_free_drm_dev: omap_gem_deinit(ddev); drm_dev_unref(ddev); -err_free_priv: +err_destroy_wq: destroy_workqueue(priv->wq); - kfree(priv); -err_disconnect_dssdevs: omap_disconnect_dssdevs(); err_crtc_uninit: omap_crtc_pre_uninit(); return ret; } -static int pdev_remove(struct platform_device *pdev) +static void omapdrm_cleanup(struct omap_drm_private *priv) { - struct drm_device *ddev = platform_get_drvdata(pdev); - struct omap_drm_private *priv = ddev->dev_private; + struct drm_device *ddev = priv->ddev; DBG(""); @@ -645,10 +627,45 @@ static int pdev_remove(struct platform_device *pdev) drm_dev_unref(ddev); destroy_workqueue(priv->wq); - kfree(priv); omap_disconnect_dssdevs(); omap_crtc_pre_uninit(); +} + +static int pdev_probe(struct platform_device *pdev) +{ + struct omap_drm_private *priv; + int ret; + + if (omapdss_is_initialized() == false) + return -EPROBE_DEFER; + + ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)); + if (ret) { + dev_err(&pdev->dev, "Failed to set the DMA mask\n"); + return ret; + } + + /* Allocate and initialize the driver private structure. */ + priv = kzalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + platform_set_drvdata(pdev, priv); + + ret = omapdrm_init(priv, &pdev->dev); + if (ret < 0) + kfree(priv); + + return ret; +} + +static int pdev_remove(struct platform_device *pdev) +{ + struct omap_drm_private *priv = platform_get_drvdata(pdev); + + omapdrm_cleanup(priv); + kfree(priv); return 0; } @@ -692,7 +709,8 @@ static int omap_drm_resume_all_displays(void) static int omap_drm_suspend(struct device *dev) { - struct drm_device *drm_dev = dev_get_drvdata(dev); + struct omap_drm_private *priv = dev_get_drvdata(dev); + struct drm_device *drm_dev = priv->ddev; drm_kms_helper_poll_disable(drm_dev); @@ -705,7 +723,8 @@ static int omap_drm_suspend(struct device *dev) static int omap_drm_resume(struct device *dev) { - struct drm_device *drm_dev = dev_get_drvdata(dev); + struct omap_drm_private *priv = dev_get_drvdata(dev); + struct drm_device *drm_dev = priv->ddev; drm_modeset_lock_all(drm_dev); omap_drm_resume_all_displays(); -- cgit v1.2.3 From 64cb81797f8b56e1806d67024de561b60944d1a5 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 13 Feb 2018 14:00:39 +0200 Subject: drm: omapdrm: dss: Pass omap_drm_private pointer to dss_mgr_ops The dss_mgr_ops operations implemented by the omapdrm side have to look up the omap_crtc objects from global variables as they are only passed a channel number. In order to remove global variables in the omapdrm driver pass the omap_drm_private pointer to the dss_mgr_ops. This requires storing a pointer to the omap_drm_private in a global variable on the DSS side as a temporary measure until the omapdrm and omapdss drivers get merged. Signed-off-by: Laurent Pinchart Reviewed-by: Sebastian Reichel --- drivers/gpu/drm/omapdrm/dss/omapdss.h | 41 ++++++++++++++++++++++------------- drivers/gpu/drm/omapdrm/dss/output.c | 28 +++++++++++++++--------- drivers/gpu/drm/omapdrm/omap_crtc.c | 31 +++++++++++++++----------- drivers/gpu/drm/omapdrm/omap_crtc.h | 2 +- drivers/gpu/drm/omapdrm/omap_drv.c | 2 +- 5 files changed, 64 insertions(+), 40 deletions(-) (limited to 'drivers/gpu/drm/omapdrm/omap_drv.c') diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h b/drivers/gpu/drm/omapdrm/dss/omapdss.h index aeaa337b29c7..318641f5bc24 100644 --- a/drivers/gpu/drm/omapdrm/dss/omapdss.h +++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h @@ -59,6 +59,7 @@ #define DISPC_IRQ_ACBIAS_COUNT_STAT3 (1 << 29) #define DISPC_IRQ_FRAMEDONE3 (1 << 30) +struct omap_drm_private; struct omap_dss_device; struct dss_lcd_mgr_config; struct snd_aes_iec958; @@ -635,25 +636,35 @@ struct device_node *dss_of_port_get_parent_device(struct device_node *port); u32 dss_of_port_get_port_number(struct device_node *port); struct dss_mgr_ops { - int (*connect)(enum omap_channel channel, - struct omap_dss_device *dst); - void (*disconnect)(enum omap_channel channel, - struct omap_dss_device *dst); - - void (*start_update)(enum omap_channel channel); - int (*enable)(enum omap_channel channel); - void (*disable)(enum omap_channel channel); - void (*set_timings)(enum omap_channel channel, - const struct videomode *vm); - void (*set_lcd_config)(enum omap_channel channel, - const struct dss_lcd_mgr_config *config); - int (*register_framedone_handler)(enum omap_channel channel, + int (*connect)(struct omap_drm_private *priv, + enum omap_channel channel, + struct omap_dss_device *dst); + void (*disconnect)(struct omap_drm_private *priv, + enum omap_channel channel, + struct omap_dss_device *dst); + + void (*start_update)(struct omap_drm_private *priv, + enum omap_channel channel); + int (*enable)(struct omap_drm_private *priv, + enum omap_channel channel); + void (*disable)(struct omap_drm_private *priv, + enum omap_channel channel); + void (*set_timings)(struct omap_drm_private *priv, + enum omap_channel channel, + const struct videomode *vm); + void (*set_lcd_config)(struct omap_drm_private *priv, + enum omap_channel channel, + const struct dss_lcd_mgr_config *config); + int (*register_framedone_handler)(struct omap_drm_private *priv, + enum omap_channel channel, void (*handler)(void *), void *data); - void (*unregister_framedone_handler)(enum omap_channel channel, + void (*unregister_framedone_handler)(struct omap_drm_private *priv, + enum omap_channel channel, void (*handler)(void *), void *data); }; -int dss_install_mgr_ops(const struct dss_mgr_ops *mgr_ops); +int dss_install_mgr_ops(const struct dss_mgr_ops *mgr_ops, + struct omap_drm_private *priv); void dss_uninstall_mgr_ops(void); int dss_mgr_connect(struct omap_dss_device *dssdev, diff --git a/drivers/gpu/drm/omapdrm/dss/output.c b/drivers/gpu/drm/omapdrm/dss/output.c index 9ff29dea28ce..96b9d4cd505f 100644 --- a/drivers/gpu/drm/omapdrm/dss/output.c +++ b/drivers/gpu/drm/omapdrm/dss/output.c @@ -170,13 +170,16 @@ struct omap_dss_device *omapdss_find_output_from_display(struct omap_dss_device EXPORT_SYMBOL(omapdss_find_output_from_display); static const struct dss_mgr_ops *dss_mgr_ops; +static struct omap_drm_private *dss_mgr_ops_priv; -int dss_install_mgr_ops(const struct dss_mgr_ops *mgr_ops) +int dss_install_mgr_ops(const struct dss_mgr_ops *mgr_ops, + struct omap_drm_private *priv) { if (dss_mgr_ops) return -EBUSY; dss_mgr_ops = mgr_ops; + dss_mgr_ops_priv = priv; return 0; } @@ -185,58 +188,62 @@ EXPORT_SYMBOL(dss_install_mgr_ops); void dss_uninstall_mgr_ops(void) { dss_mgr_ops = NULL; + dss_mgr_ops_priv = NULL; } EXPORT_SYMBOL(dss_uninstall_mgr_ops); int dss_mgr_connect(struct omap_dss_device *dssdev, struct omap_dss_device *dst) { - return dss_mgr_ops->connect(dssdev->dispc_channel, dst); + return dss_mgr_ops->connect(dss_mgr_ops_priv, + dssdev->dispc_channel, dst); } EXPORT_SYMBOL(dss_mgr_connect); void dss_mgr_disconnect(struct omap_dss_device *dssdev, struct omap_dss_device *dst) { - dss_mgr_ops->disconnect(dssdev->dispc_channel, dst); + dss_mgr_ops->disconnect(dss_mgr_ops_priv, dssdev->dispc_channel, dst); } EXPORT_SYMBOL(dss_mgr_disconnect); void dss_mgr_set_timings(struct omap_dss_device *dssdev, const struct videomode *vm) { - dss_mgr_ops->set_timings(dssdev->dispc_channel, vm); + dss_mgr_ops->set_timings(dss_mgr_ops_priv, dssdev->dispc_channel, vm); } EXPORT_SYMBOL(dss_mgr_set_timings); void dss_mgr_set_lcd_config(struct omap_dss_device *dssdev, const struct dss_lcd_mgr_config *config) { - dss_mgr_ops->set_lcd_config(dssdev->dispc_channel, config); + dss_mgr_ops->set_lcd_config(dss_mgr_ops_priv, + dssdev->dispc_channel, config); } EXPORT_SYMBOL(dss_mgr_set_lcd_config); int dss_mgr_enable(struct omap_dss_device *dssdev) { - return dss_mgr_ops->enable(dssdev->dispc_channel); + return dss_mgr_ops->enable(dss_mgr_ops_priv, dssdev->dispc_channel); } EXPORT_SYMBOL(dss_mgr_enable); void dss_mgr_disable(struct omap_dss_device *dssdev) { - dss_mgr_ops->disable(dssdev->dispc_channel); + dss_mgr_ops->disable(dss_mgr_ops_priv, dssdev->dispc_channel); } EXPORT_SYMBOL(dss_mgr_disable); void dss_mgr_start_update(struct omap_dss_device *dssdev) { - dss_mgr_ops->start_update(dssdev->dispc_channel); + dss_mgr_ops->start_update(dss_mgr_ops_priv, dssdev->dispc_channel); } EXPORT_SYMBOL(dss_mgr_start_update); int dss_mgr_register_framedone_handler(struct omap_dss_device *dssdev, void (*handler)(void *), void *data) { - return dss_mgr_ops->register_framedone_handler(dssdev->dispc_channel, + return dss_mgr_ops->register_framedone_handler(dss_mgr_ops_priv, + dssdev->dispc_channel, handler, data); } EXPORT_SYMBOL(dss_mgr_register_framedone_handler); @@ -244,7 +251,8 @@ EXPORT_SYMBOL(dss_mgr_register_framedone_handler); void dss_mgr_unregister_framedone_handler(struct omap_dss_device *dssdev, void (*handler)(void *), void *data) { - dss_mgr_ops->unregister_framedone_handler(dssdev->dispc_channel, + dss_mgr_ops->unregister_framedone_handler(dss_mgr_ops_priv, + dssdev->dispc_channel, handler, data); } EXPORT_SYMBOL(dss_mgr_unregister_framedone_handler); diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c index 95615a86e9f7..61d8d17a4243 100644 --- a/drivers/gpu/drm/omapdrm/omap_crtc.c +++ b/drivers/gpu/drm/omapdrm/omap_crtc.c @@ -113,7 +113,8 @@ 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(enum omap_channel channel, +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 = dispc_get_ops(); @@ -130,14 +131,16 @@ static int omap_crtc_dss_connect(enum omap_channel channel, return 0; } -static void omap_crtc_dss_disconnect(enum omap_channel channel, +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(enum omap_channel channel) +static void omap_crtc_dss_start_update(struct omap_drm_private *priv, + enum omap_channel channel) { } @@ -207,10 +210,10 @@ static void omap_crtc_set_enabled(struct drm_crtc *crtc, bool enable) } -static int omap_crtc_dss_enable(enum omap_channel channel) +static int omap_crtc_dss_enable(struct omap_drm_private *priv, + enum omap_channel channel) { struct omap_crtc *omap_crtc = omap_crtcs[channel]; - struct omap_drm_private *priv = omap_crtc->base.dev->dev_private; priv->dispc_ops->mgr_set_timings(omap_crtc->channel, &omap_crtc->vm); omap_crtc_set_enabled(&omap_crtc->base, true); @@ -218,14 +221,16 @@ static int omap_crtc_dss_enable(enum omap_channel channel) return 0; } -static void omap_crtc_dss_disable(enum omap_channel channel) +static void omap_crtc_dss_disable(struct omap_drm_private *priv, + enum omap_channel channel) { struct omap_crtc *omap_crtc = omap_crtcs[channel]; omap_crtc_set_enabled(&omap_crtc->base, false); } -static void omap_crtc_dss_set_timings(enum omap_channel channel, +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]; @@ -233,25 +238,25 @@ static void omap_crtc_dss_set_timings(enum omap_channel channel, omap_crtc->vm = *vm; } -static void omap_crtc_dss_set_lcd_config(enum omap_channel channel, +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 omap_drm_private *priv = omap_crtc->base.dev->dev_private; DBG("%s", omap_crtc->name); priv->dispc_ops->mgr_set_lcd_config(omap_crtc->channel, config); } static int omap_crtc_dss_register_framedone( - enum omap_channel channel, + struct omap_drm_private *priv, enum omap_channel channel, void (*handler)(void *), void *data) { return 0; } static void omap_crtc_dss_unregister_framedone( - enum omap_channel channel, + struct omap_drm_private *priv, enum omap_channel channel, void (*handler)(void *), void *data) { } @@ -669,11 +674,11 @@ static const char *channel_names[] = { [OMAP_DSS_CHANNEL_LCD3] = "lcd3", }; -void omap_crtc_pre_init(void) +void omap_crtc_pre_init(struct omap_drm_private *priv) { memset(omap_crtcs, 0, sizeof(omap_crtcs)); - dss_install_mgr_ops(&mgr_ops); + dss_install_mgr_ops(&mgr_ops, priv); } void omap_crtc_pre_uninit(void) diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.h b/drivers/gpu/drm/omapdrm/omap_crtc.h index 7f01e730a050..eaab2d7f0324 100644 --- a/drivers/gpu/drm/omapdrm/omap_crtc.h +++ b/drivers/gpu/drm/omapdrm/omap_crtc.h @@ -32,7 +32,7 @@ struct videomode; struct videomode *omap_crtc_timings(struct drm_crtc *crtc); enum omap_channel omap_crtc_channel(struct drm_crtc *crtc); -void omap_crtc_pre_init(void); +void omap_crtc_pre_init(struct omap_drm_private *priv); void omap_crtc_pre_uninit(void); struct drm_crtc *omap_crtc_init(struct drm_device *dev, struct drm_plane *plane, struct omap_dss_device *dssdev); diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c index b571cc04e08d..39e78f765f7e 100644 --- a/drivers/gpu/drm/omapdrm/omap_drv.c +++ b/drivers/gpu/drm/omapdrm/omap_drv.c @@ -521,7 +521,7 @@ static int omapdrm_init(struct omap_drm_private *priv, struct device *dev) priv->dev = dev; - omap_crtc_pre_init(); + omap_crtc_pre_init(priv); ret = omap_connect_dssdevs(); if (ret) -- cgit v1.2.3 From 72877cf38b4b78fbb3a852f2288d7f2a7af0db22 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 13 Feb 2018 14:00:40 +0200 Subject: drm: omapdrm: dss: Store DSS device pointer in the omapdrm private data The dss_device is the top-level component in the omapdss driver. Give the omapdrm driver access to the dss_device pointer in order to obtain pointers to all other components from it. This requires a new global variable in the omapdss driver that will be removed when merging the omapdrm and omapdss drivers, but will already allow removal of several other global variables. As this partly duplicates the omapdss_is_initialized() API, reimplement it as an inline function wrapping omapdss_get_dss(). Signed-off-by: Laurent Pinchart Reviewed-by: Sebastian Reichel --- drivers/gpu/drm/omapdrm/dss/base.c | 14 +++++++------- drivers/gpu/drm/omapdrm/dss/dss.c | 5 +++-- drivers/gpu/drm/omapdrm/dss/omapdss.h | 10 +++++++--- drivers/gpu/drm/omapdrm/omap_drv.c | 1 + drivers/gpu/drm/omapdrm/omap_drv.h | 1 + 5 files changed, 19 insertions(+), 12 deletions(-) (limited to 'drivers/gpu/drm/omapdrm/omap_drv.c') diff --git a/drivers/gpu/drm/omapdrm/dss/base.c b/drivers/gpu/drm/omapdrm/dss/base.c index 67cc87a4f1f6..6346bc967a77 100644 --- a/drivers/gpu/drm/omapdrm/dss/base.c +++ b/drivers/gpu/drm/omapdrm/dss/base.c @@ -20,7 +20,7 @@ #include #include "omapdss.h" -static bool dss_initialized; +static struct dss_device *dss_device; static const struct dispc_ops *ops; static struct list_head omapdss_comp_list; @@ -31,17 +31,17 @@ struct omapdss_comp_node { bool dss_core_component; }; -void omapdss_set_is_initialized(bool set) +struct dss_device *omapdss_get_dss(void) { - dss_initialized = set; + return dss_device; } -EXPORT_SYMBOL(omapdss_set_is_initialized); +EXPORT_SYMBOL(omapdss_get_dss); -bool omapdss_is_initialized(void) +void omapdss_set_dss(struct dss_device *dss) { - return dss_initialized; + dss_device = dss; } -EXPORT_SYMBOL(omapdss_is_initialized); +EXPORT_SYMBOL(omapdss_set_dss); void dispc_set_ops(const struct dispc_ops *o) { diff --git a/drivers/gpu/drm/omapdrm/dss/dss.c b/drivers/gpu/drm/omapdrm/dss/dss.c index 14d2f024eb70..ca2efb937d42 100644 --- a/drivers/gpu/drm/omapdrm/dss/dss.c +++ b/drivers/gpu/drm/omapdrm/dss/dss.c @@ -1316,6 +1316,7 @@ static const struct soc_device_attribute dss_soc_devices[] = { static int dss_bind(struct device *dev) { + struct dss_device *dss = dev_get_drvdata(dev); int r; r = component_bind_all(dev, NULL); @@ -1325,14 +1326,14 @@ static int dss_bind(struct device *dev) pm_set_vt_switch(0); omapdss_gather_components(dev); - omapdss_set_is_initialized(true); + omapdss_set_dss(dss); return 0; } static void dss_unbind(struct device *dev) { - omapdss_set_is_initialized(false); + omapdss_set_dss(NULL); component_unbind_all(dev, NULL); } diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h b/drivers/gpu/drm/omapdrm/dss/omapdss.h index 318641f5bc24..312485714703 100644 --- a/drivers/gpu/drm/omapdrm/dss/omapdss.h +++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h @@ -59,6 +59,7 @@ #define DISPC_IRQ_ACBIAS_COUNT_STAT3 (1 << 29) #define DISPC_IRQ_FRAMEDONE3 (1 << 30) +struct dss_device; struct omap_drm_private; struct omap_dss_device; struct dss_lcd_mgr_config; @@ -586,7 +587,12 @@ struct omap_dss_driver { const struct hdmi_avi_infoframe *avi); }; -bool omapdss_is_initialized(void); +struct dss_device *omapdss_get_dss(void); +void omapdss_set_dss(struct dss_device *dss); +static inline bool omapdss_is_initialized(void) +{ + return !!omapdss_get_dss(); +} int omapdss_register_display(struct omap_dss_device *dssdev); void omapdss_unregister_display(struct omap_dss_device *dssdev); @@ -630,8 +636,6 @@ static inline bool omapdss_device_is_enabled(struct omap_dss_device *dssdev) struct omap_dss_device * omapdss_of_find_source_for_first_ep(struct device_node *node); -void omapdss_set_is_initialized(bool set); - struct device_node *dss_of_port_get_parent_device(struct device_node *port); u32 dss_of_port_get_port_number(struct device_node *port); diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c index 39e78f765f7e..003445b70ee7 100644 --- a/drivers/gpu/drm/omapdrm/omap_drv.c +++ b/drivers/gpu/drm/omapdrm/omap_drv.c @@ -527,6 +527,7 @@ static int omapdrm_init(struct omap_drm_private *priv, struct device *dev) if (ret) goto err_crtc_uninit; + priv->dss = omapdss_get_dss(); priv->dispc_ops = dispc_get_ops(); soc = soc_device_match(omapdrm_soc_devices); diff --git a/drivers/gpu/drm/omapdrm/omap_drv.h b/drivers/gpu/drm/omapdrm/omap_drv.h index 49351bb3731e..a7962c14fc7c 100644 --- a/drivers/gpu/drm/omapdrm/omap_drv.h +++ b/drivers/gpu/drm/omapdrm/omap_drv.h @@ -50,6 +50,7 @@ struct omap_drm_private { struct device *dev; u32 omaprev; + struct dss_device *dss; const struct dispc_ops *dispc_ops; unsigned int num_crtcs; -- cgit v1.2.3 From d3541ca81dbddeefa0c42df448211a9dbaef0843 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 13 Feb 2018 14:00:41 +0200 Subject: drm: omapdrm: dss: Store dispc ops in dss_device structure Remove the global dispc ops variable by storing it in the dss_device structure. Signed-off-by: Laurent Pinchart Reviewed-by: Sebastian Reichel --- drivers/gpu/drm/omapdrm/dss/base.c | 13 ++++--------- drivers/gpu/drm/omapdrm/dss/dispc.c | 6 ++++-- drivers/gpu/drm/omapdrm/dss/dss.h | 2 ++ drivers/gpu/drm/omapdrm/dss/omapdss.h | 3 +-- drivers/gpu/drm/omapdrm/omap_crtc.c | 4 +--- drivers/gpu/drm/omapdrm/omap_drv.c | 5 ++--- 6 files changed, 14 insertions(+), 19 deletions(-) (limited to 'drivers/gpu/drm/omapdrm/omap_drv.c') diff --git a/drivers/gpu/drm/omapdrm/dss/base.c b/drivers/gpu/drm/omapdrm/dss/base.c index 6346bc967a77..c248c3c31904 100644 --- a/drivers/gpu/drm/omapdrm/dss/base.c +++ b/drivers/gpu/drm/omapdrm/dss/base.c @@ -18,10 +18,11 @@ #include #include #include + +#include "dss.h" #include "omapdss.h" static struct dss_device *dss_device; -static const struct dispc_ops *ops; static struct list_head omapdss_comp_list; @@ -43,15 +44,9 @@ void omapdss_set_dss(struct dss_device *dss) } EXPORT_SYMBOL(omapdss_set_dss); -void dispc_set_ops(const struct dispc_ops *o) -{ - ops = o; -} -EXPORT_SYMBOL(dispc_set_ops); - -const struct dispc_ops *dispc_get_ops(void) +const struct dispc_ops *dispc_get_ops(struct dss_device *dss) { - return ops; + return dss->dispc_ops; } EXPORT_SYMBOL(dispc_get_ops); diff --git a/drivers/gpu/drm/omapdrm/dss/dispc.c b/drivers/gpu/drm/omapdrm/dss/dispc.c index 8019cc9f4f97..aae6037f499f 100644 --- a/drivers/gpu/drm/omapdrm/dss/dispc.c +++ b/drivers/gpu/drm/omapdrm/dss/dispc.c @@ -4622,7 +4622,7 @@ static int dispc_bind(struct device *dev, struct device *master, void *data) dispc_runtime_put(); - dispc_set_ops(&dispc_ops); + dss->dispc_ops = &dispc_ops; dispc.debugfs = dss_debugfs_create_file(dss, "dispc", dispc_dump_regs, &dispc); @@ -4637,9 +4637,11 @@ err_runtime_get: static void dispc_unbind(struct device *dev, struct device *master, void *data) { + struct dss_device *dss = dispc.dss; + dss_debugfs_remove_file(dispc.debugfs); - dispc_set_ops(NULL); + dss->dispc_ops = NULL; pm_runtime_disable(dev); diff --git a/drivers/gpu/drm/omapdrm/dss/dss.h b/drivers/gpu/drm/omapdrm/dss/dss.h index 764c52025a27..348378f1b5a5 100644 --- a/drivers/gpu/drm/omapdrm/dss/dss.h +++ b/drivers/gpu/drm/omapdrm/dss/dss.h @@ -271,6 +271,8 @@ struct dss_device { struct dss_pll *plls[4]; struct dss_pll *video1_pll; struct dss_pll *video2_pll; + + const struct dispc_ops *dispc_ops; }; /* core */ diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h b/drivers/gpu/drm/omapdrm/dss/omapdss.h index 312485714703..4bf7843b4aec 100644 --- a/drivers/gpu/drm/omapdrm/dss/omapdss.h +++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h @@ -733,8 +733,7 @@ struct dispc_ops { const u32 *(*ovl_get_color_modes)(enum omap_plane_id plane); }; -void dispc_set_ops(const struct dispc_ops *o); -const struct dispc_ops *dispc_get_ops(void); +const struct dispc_ops *dispc_get_ops(struct dss_device *dss); bool omapdss_component_is_display(struct device_node *node); bool omapdss_component_is_output(struct device_node *node); diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c index 61d8d17a4243..ffe4f698d291 100644 --- a/drivers/gpu/drm/omapdrm/omap_crtc.c +++ b/drivers/gpu/drm/omapdrm/omap_crtc.c @@ -117,12 +117,10 @@ 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 = dispc_get_ops(); - if (omap_crtc_output[channel]) return -EINVAL; - if ((dispc_ops->mgr_get_supported_outputs(channel) & dst->id) == 0) + if (!(priv->dispc_ops->mgr_get_supported_outputs(channel) & dst->id)) return -EINVAL; omap_crtc_output[channel] = dst; diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c index 003445b70ee7..a93916cd0258 100644 --- a/drivers/gpu/drm/omapdrm/omap_drv.c +++ b/drivers/gpu/drm/omapdrm/omap_drv.c @@ -520,6 +520,8 @@ static int omapdrm_init(struct omap_drm_private *priv, struct device *dev) DBG("%s", dev_name(dev)); priv->dev = dev; + priv->dss = omapdss_get_dss(); + priv->dispc_ops = dispc_get_ops(priv->dss); omap_crtc_pre_init(priv); @@ -527,9 +529,6 @@ static int omapdrm_init(struct omap_drm_private *priv, struct device *dev) if (ret) goto err_crtc_uninit; - priv->dss = omapdss_get_dss(); - priv->dispc_ops = dispc_get_ops(); - soc = soc_device_match(omapdrm_soc_devices); priv->omaprev = soc ? (unsigned int)soc->data : 0; priv->wq = alloc_ordered_workqueue("omapdrm", 0); -- cgit v1.2.3 From 50638ae569dc097a95218eb70140e68aa213b07c Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 13 Feb 2018 14:00:42 +0200 Subject: drm: omapdrm: dispc: Pass DISPC pointer to dispc_ops operations This removes the need to access the global DISPC private data in those functions (both for the current accesses and the future ones that will be introduced when allocating the DISPC private data dynamically). In order to allow the omapdrm side to call the dispc_ops with a DISPC pointer, we also introduce a new function dss_get_dispc() to retrieve the DISPC corresponding to the DSS. Signed-off-by: Laurent Pinchart Reviewed-by: Sebastian Reichel --- drivers/gpu/drm/omapdrm/dss/base.c | 6 + drivers/gpu/drm/omapdrm/dss/dispc.c | 223 ++++++++++++++++++---------------- drivers/gpu/drm/omapdrm/dss/dpi.c | 6 +- drivers/gpu/drm/omapdrm/dss/dsi.c | 4 +- drivers/gpu/drm/omapdrm/dss/dss.h | 6 +- drivers/gpu/drm/omapdrm/dss/hdmi4.c | 7 +- drivers/gpu/drm/omapdrm/dss/hdmi5.c | 7 +- drivers/gpu/drm/omapdrm/dss/omapdss.h | 95 +++++++++------ drivers/gpu/drm/omapdrm/dss/sdi.c | 6 +- drivers/gpu/drm/omapdrm/dss/venc.c | 4 +- drivers/gpu/drm/omapdrm/omap_crtc.c | 31 +++-- drivers/gpu/drm/omapdrm/omap_drv.c | 13 +- drivers/gpu/drm/omapdrm/omap_drv.h | 1 + drivers/gpu/drm/omapdrm/omap_irq.c | 32 ++--- drivers/gpu/drm/omapdrm/omap_plane.c | 12 +- 15 files changed, 257 insertions(+), 196 deletions(-) (limited to 'drivers/gpu/drm/omapdrm/omap_drv.c') diff --git a/drivers/gpu/drm/omapdrm/dss/base.c b/drivers/gpu/drm/omapdrm/dss/base.c index c248c3c31904..99e8cb8dc65b 100644 --- a/drivers/gpu/drm/omapdrm/dss/base.c +++ b/drivers/gpu/drm/omapdrm/dss/base.c @@ -44,6 +44,12 @@ void omapdss_set_dss(struct dss_device *dss) } EXPORT_SYMBOL(omapdss_set_dss); +struct dispc_device *dispc_get_dispc(struct dss_device *dss) +{ + return dss->dispc; +} +EXPORT_SYMBOL(dispc_get_dispc); + const struct dispc_ops *dispc_get_ops(struct dss_device *dss) { return dss->dispc_ops; diff --git a/drivers/gpu/drm/omapdrm/dss/dispc.c b/drivers/gpu/drm/omapdrm/dss/dispc.c index aae6037f499f..6d8228f976f9 100644 --- a/drivers/gpu/drm/omapdrm/dss/dispc.c +++ b/drivers/gpu/drm/omapdrm/dss/dispc.c @@ -162,7 +162,7 @@ struct dispc_features { #define DISPC_MAX_NR_FIFOS 5 #define DISPC_MAX_CHANNEL_GAMMA 4 -static struct { +struct dispc_device { struct platform_device *pdev; void __iomem *base; struct dss_device *dss; @@ -194,7 +194,9 @@ static struct { /* DISPC_CONTROL & DISPC_CONFIG lock*/ spinlock_t control_lock; -} dispc; +}; + +static struct dispc_device dispc; enum omap_color_component { /* used for all color formats for OMAP3 and earlier @@ -361,9 +363,7 @@ static unsigned long dispc_mgr_pclk_rate(enum omap_channel channel); static unsigned long dispc_plane_pclk_rate(enum omap_plane_id plane); static unsigned long dispc_plane_lclk_rate(enum omap_plane_id plane); -static void dispc_clear_irqstatus(u32 mask); -static bool dispc_mgr_is_enabled(enum omap_channel channel); -static void dispc_clear_irqstatus(u32 mask); +static void dispc_clear_irqstatus(struct dispc_device *dispc, u32 mask); static inline void dispc_write_reg(const u16 idx, u32 val) { @@ -396,14 +396,14 @@ static void mgr_fld_write(enum omap_channel channel, spin_unlock_irqrestore(&dispc.control_lock, flags); } -static int dispc_get_num_ovls(void) +static int dispc_get_num_ovls(struct dispc_device *dispc) { - return dispc.feat->num_ovls; + return dispc->feat->num_ovls; } -static int dispc_get_num_mgrs(void) +static int dispc_get_num_mgrs(struct dispc_device *dispc) { - return dispc.feat->num_mgrs; + return dispc->feat->num_mgrs; } static void dispc_get_reg_field(enum dispc_feat_reg_field id, @@ -455,7 +455,7 @@ static void dispc_save_context(void) SR(CONFIG3); } - for (i = 0; i < dispc_get_num_mgrs(); i++) { + for (i = 0; i < dispc_get_num_mgrs(&dispc); i++) { SR(DEFAULT_COLOR(i)); SR(TRANS_COLOR(i)); SR(SIZE_MGR(i)); @@ -477,7 +477,7 @@ static void dispc_save_context(void) } } - for (i = 0; i < dispc_get_num_ovls(); i++) { + for (i = 0; i < dispc_get_num_ovls(&dispc); i++) { SR(OVL_BA0(i)); SR(OVL_BA1(i)); SR(OVL_POSITION(i)); @@ -561,7 +561,7 @@ static void dispc_restore_context(void) if (dispc_has_feature(FEAT_MGR_LCD3)) RR(CONFIG3); - for (i = 0; i < dispc_get_num_mgrs(); i++) { + for (i = 0; i < dispc_get_num_mgrs(&dispc); i++) { RR(DEFAULT_COLOR(i)); RR(TRANS_COLOR(i)); RR(SIZE_MGR(i)); @@ -583,7 +583,7 @@ static void dispc_restore_context(void) } } - for (i = 0; i < dispc_get_num_ovls(); i++) { + for (i = 0; i < dispc_get_num_ovls(&dispc); i++) { RR(OVL_BA0(i)); RR(OVL_BA1(i)); RR(OVL_POSITION(i)); @@ -648,7 +648,7 @@ static void dispc_restore_context(void) if (dispc_has_feature(FEAT_MGR_LCD3)) RR(CONTROL3); /* clear spurious SYNC_LOST_DIGIT interrupts */ - dispc_clear_irqstatus(DISPC_IRQ_SYNC_LOST_DIGIT); + dispc_clear_irqstatus(&dispc, DISPC_IRQ_SYNC_LOST_DIGIT); /* * enable last so IRQs won't trigger before @@ -662,41 +662,44 @@ static void dispc_restore_context(void) #undef SR #undef RR -int dispc_runtime_get(void) +int dispc_runtime_get(struct dispc_device *dispc) { int r; DSSDBG("dispc_runtime_get\n"); - r = pm_runtime_get_sync(&dispc.pdev->dev); + r = pm_runtime_get_sync(&dispc->pdev->dev); WARN_ON(r < 0); return r < 0 ? r : 0; } -void dispc_runtime_put(void) +void dispc_runtime_put(struct dispc_device *dispc) { int r; DSSDBG("dispc_runtime_put\n"); - r = pm_runtime_put_sync(&dispc.pdev->dev); + r = pm_runtime_put_sync(&dispc->pdev->dev); WARN_ON(r < 0 && r != -ENOSYS); } -static u32 dispc_mgr_get_vsync_irq(enum omap_channel channel) +static u32 dispc_mgr_get_vsync_irq(struct dispc_device *dispc, + enum omap_channel channel) { return mgr_desc[channel].vsync_irq; } -static u32 dispc_mgr_get_framedone_irq(enum omap_channel channel) +static u32 dispc_mgr_get_framedone_irq(struct dispc_device *dispc, + enum omap_channel channel) { - if (channel == OMAP_DSS_CHANNEL_DIGIT && dispc.feat->no_framedone_tv) + if (channel == OMAP_DSS_CHANNEL_DIGIT && dispc->feat->no_framedone_tv) return 0; return mgr_desc[channel].framedone_irq; } -static u32 dispc_mgr_get_sync_lost_irq(enum omap_channel channel) +static u32 dispc_mgr_get_sync_lost_irq(struct dispc_device *dispc, + enum omap_channel channel) { return mgr_desc[channel].sync_lost_irq; } @@ -706,27 +709,30 @@ u32 dispc_wb_get_framedone_irq(void) return DISPC_IRQ_FRAMEDONEWB; } -static void dispc_mgr_enable(enum omap_channel channel, bool enable) +static void dispc_mgr_enable(struct dispc_device *dispc, + enum omap_channel channel, bool enable) { mgr_fld_write(channel, DISPC_MGR_FLD_ENABLE, enable); /* flush posted write */ mgr_fld_read(channel, DISPC_MGR_FLD_ENABLE); } -static bool dispc_mgr_is_enabled(enum omap_channel channel) +static bool dispc_mgr_is_enabled(struct dispc_device *dispc, + enum omap_channel channel) { return !!mgr_fld_read(channel, DISPC_MGR_FLD_ENABLE); } -static bool dispc_mgr_go_busy(enum omap_channel channel) +static bool dispc_mgr_go_busy(struct dispc_device *dispc, + enum omap_channel channel) { return mgr_fld_read(channel, DISPC_MGR_FLD_GO) == 1; } -static void dispc_mgr_go(enum omap_channel channel) +static void dispc_mgr_go(struct dispc_device *dispc, enum omap_channel channel) { - WARN_ON(!dispc_mgr_is_enabled(channel)); - WARN_ON(dispc_mgr_go_busy(channel)); + WARN_ON(!dispc_mgr_is_enabled(dispc, channel)); + WARN_ON(dispc_mgr_go_busy(dispc, channel)); DSSDBG("GO %s\n", mgr_desc[channel].name); @@ -864,7 +870,7 @@ static void dispc_ovl_write_color_conv_coef(enum omap_plane_id plane, static void dispc_setup_color_conv_coef(void) { int i; - int num_ovl = dispc_get_num_ovls(); + int num_ovl = dispc_get_num_ovls(&dispc); const struct color_conv_coef ctbl_bt601_5_ovl = { /* YUV -> RGB */ 298, 409, 0, 298, -208, -100, 298, 0, 517, 0, @@ -956,7 +962,7 @@ static void dispc_ovl_enable_zorder_planes(void) if (!dispc_has_feature(FEAT_ALPHA_FREE_ZORDER)) return; - for (i = 0; i < dispc_get_num_ovls(); i++) + for (i = 0; i < dispc_get_num_ovls(&dispc); i++) REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(i), 1, 25, 25); } @@ -1213,7 +1219,7 @@ static void dispc_configure_burst_sizes(void) const int burst_size = BURST_SIZE_X8; /* Configure burst size always to maximum size */ - for (i = 0; i < dispc_get_num_ovls(); ++i) + for (i = 0; i < dispc_get_num_ovls(&dispc); ++i) dispc_ovl_set_burst_size(i, burst_size); if (dispc.feat->has_writeback) dispc_ovl_set_burst_size(OMAP_DSS_WB, burst_size); @@ -1240,9 +1246,10 @@ static bool dispc_ovl_color_mode_supported(enum omap_plane_id plane, u32 fourcc) return false; } -static const u32 *dispc_ovl_get_color_modes(enum omap_plane_id plane) +static const u32 *dispc_ovl_get_color_modes(struct dispc_device *dispc, + enum omap_plane_id plane) { - return dispc.feat->supported_color_modes[plane]; + return dispc->feat->supported_color_modes[plane]; } static void dispc_mgr_enable_cpr(enum omap_channel channel, bool enable) @@ -1359,7 +1366,7 @@ static void dispc_init_fifos(void) /* * Setup default fifo thresholds. */ - for (i = 0; i < dispc_get_num_ovls(); ++i) { + for (i = 0; i < dispc_get_num_ovls(&dispc); ++i) { u32 low, high; const bool use_fifomerge = false; const bool manual_update = false; @@ -1462,7 +1469,7 @@ void dispc_ovl_compute_fifo_thresholds(enum omap_plane_id plane, if (use_fifomerge) { total_fifo_size = 0; - for (i = 0; i < dispc_get_num_ovls(); ++i) + for (i = 0; i < dispc_get_num_ovls(&dispc); ++i) total_fifo_size += dispc_ovl_get_fifo_size(i); } else { total_fifo_size = ovl_fifo_size; @@ -1528,7 +1535,7 @@ static void dispc_init_mflag(void) (1 << 0) | /* MFLAG_CTRL = force always on */ (0 << 2)); /* MFLAG_START = disable */ - for (i = 0; i < dispc_get_num_ovls(); ++i) { + for (i = 0; i < dispc_get_num_ovls(&dispc); ++i) { u32 size = dispc_ovl_get_fifo_size(i); u32 unit = dispc.feat->buffer_size_unit; u32 low, high; @@ -2631,13 +2638,14 @@ static int dispc_ovl_setup_common(enum omap_plane_id plane, return 0; } -static int dispc_ovl_setup(enum omap_plane_id plane, - const struct omap_overlay_info *oi, - const struct videomode *vm, bool mem_to_mem, - enum omap_channel channel) +static int dispc_ovl_setup(struct dispc_device *dispc, + enum omap_plane_id plane, + const struct omap_overlay_info *oi, + const struct videomode *vm, bool mem_to_mem, + enum omap_channel channel) { int r; - enum omap_overlay_caps caps = dispc.feat->overlay_caps[plane]; + enum omap_overlay_caps caps = dispc->feat->overlay_caps[plane]; const bool replication = true; DSSDBG("dispc_ovl_setup %d, pa %pad, pa_uv %pad, sw %d, %d,%d, %dx%d ->" @@ -2724,7 +2732,8 @@ int dispc_wb_setup(const struct omap_dss_writeback_info *wi, return r; } -static int dispc_ovl_enable(enum omap_plane_id plane, bool enable) +static int dispc_ovl_enable(struct dispc_device *dispc, + enum omap_plane_id plane, bool enable) { DSSDBG("dispc_enable_plane %d, %d\n", plane, enable); @@ -2733,9 +2742,11 @@ static int dispc_ovl_enable(enum omap_plane_id plane, bool enable) return 0; } -static enum omap_dss_output_id dispc_mgr_get_supported_outputs(enum omap_channel channel) +static enum omap_dss_output_id +dispc_mgr_get_supported_outputs(struct dispc_device *dispc, + enum omap_channel channel) { - return dss_get_supported_outputs(dispc.dss, channel); + return dss_get_supported_outputs(dispc->dss, channel); } static void dispc_lcd_enable_signal_polarity(bool act_high) @@ -2810,8 +2821,9 @@ static void dispc_mgr_enable_alpha_fixed_zorder(enum omap_channel ch, REG_FLD_MOD(DISPC_CONFIG, enable, 19, 19); } -static void dispc_mgr_setup(enum omap_channel channel, - const struct omap_overlay_manager_info *info) +static void dispc_mgr_setup(struct dispc_device *dispc, + enum omap_channel channel, + const struct omap_overlay_manager_info *info) { dispc_mgr_set_default_color(channel, info->default_color); dispc_mgr_set_trans_key(channel, info->trans_key_type, info->trans_key); @@ -2883,8 +2895,9 @@ static void dispc_mgr_enable_stallmode(enum omap_channel channel, bool enable) mgr_fld_write(channel, DISPC_MGR_FLD_STALLMODE, enable); } -static void dispc_mgr_set_lcd_config(enum omap_channel channel, - const struct dss_lcd_mgr_config *config) +static void dispc_mgr_set_lcd_config(struct dispc_device *dispc, + enum omap_channel channel, + const struct dss_lcd_mgr_config *config) { dispc_mgr_set_io_pad_mode(config->io_pad_mode); @@ -3039,8 +3052,9 @@ static int vm_flag_to_int(enum display_flags flags, enum display_flags high, } /* change name to mode? */ -static void dispc_mgr_set_timings(enum omap_channel channel, - const struct videomode *vm) +static void dispc_mgr_set_timings(struct dispc_device *dispc, + enum omap_channel channel, + const struct videomode *vm) { unsigned int xtot, ytot; unsigned long ht, vt; @@ -3078,7 +3092,7 @@ static void dispc_mgr_set_timings(enum omap_channel channel, if (t.flags & DISPLAY_FLAGS_INTERLACED) t.vactive /= 2; - if (dispc.feat->supports_double_pixel) + if (dispc->feat->supports_double_pixel) REG_FLD_MOD(DISPC_CONTROL, !!(t.flags & DISPLAY_FLAGS_DOUBLECLK), 19, 17); @@ -3241,7 +3255,7 @@ void dispc_dump_clocks(struct seq_file *s) u32 l; enum dss_clk_source dispc_clk_src = dss_get_dispc_clk_source(dispc.dss); - if (dispc_runtime_get()) + if (dispc_runtime_get(&dispc)) return; seq_printf(s, "- DISPC -\n"); @@ -3267,7 +3281,7 @@ void dispc_dump_clocks(struct seq_file *s) if (dispc_has_feature(FEAT_MGR_LCD3)) dispc_dump_clocks_channel(s, OMAP_DSS_CHANNEL_LCD3); - dispc_runtime_put(); + dispc_runtime_put(&dispc); } static int dispc_dump_regs(struct seq_file *s, void *p) @@ -3290,7 +3304,7 @@ static int dispc_dump_regs(struct seq_file *s, void *p) #define DUMPREG(r) seq_printf(s, "%-50s %08x\n", #r, dispc_read_reg(r)) - if (dispc_runtime_get()) + if (dispc_runtime_get(&dispc)) return 0; /* DISPC common registers */ @@ -3328,7 +3342,7 @@ static int dispc_dump_regs(struct seq_file *s, void *p) p_names = mgr_names; /* DISPC channel specific registers */ - for (i = 0; i < dispc_get_num_mgrs(); i++) { + for (i = 0; i < dispc_get_num_mgrs(&dispc); i++) { DUMPREG(i, DISPC_DEFAULT_COLOR); DUMPREG(i, DISPC_TRANS_COLOR); DUMPREG(i, DISPC_SIZE_MGR); @@ -3354,7 +3368,7 @@ static int dispc_dump_regs(struct seq_file *s, void *p) p_names = ovl_names; - for (i = 0; i < dispc_get_num_ovls(); i++) { + for (i = 0; i < dispc_get_num_ovls(&dispc); i++) { DUMPREG(i, DISPC_OVL_BA0); DUMPREG(i, DISPC_OVL_BA1); DUMPREG(i, DISPC_OVL_POSITION); @@ -3432,7 +3446,7 @@ static int dispc_dump_regs(struct seq_file *s, void *p) /* Video pipeline coefficient registers */ /* start from OMAP_DSS_VIDEO1 */ - for (i = 1; i < dispc_get_num_ovls(); i++) { + for (i = 1; i < dispc_get_num_ovls(&dispc); i++) { for (j = 0; j < 8; j++) DUMPREG(i, DISPC_OVL_FIR_COEF_H, j); @@ -3459,7 +3473,7 @@ static int dispc_dump_regs(struct seq_file *s, void *p) } } - dispc_runtime_put(); + dispc_runtime_put(&dispc); #undef DISPC_REG #undef DUMPREG @@ -3567,22 +3581,22 @@ int dispc_mgr_get_clock_div(enum omap_channel channel, return 0; } -static u32 dispc_read_irqstatus(void) +static u32 dispc_read_irqstatus(struct dispc_device *dispc) { return dispc_read_reg(DISPC_IRQSTATUS); } -static void dispc_clear_irqstatus(u32 mask) +static void dispc_clear_irqstatus(struct dispc_device *dispc, u32 mask) { dispc_write_reg(DISPC_IRQSTATUS, mask); } -static void dispc_write_irqenable(u32 mask) +static void dispc_write_irqenable(struct dispc_device *dispc, u32 mask) { u32 old_mask = dispc_read_reg(DISPC_IRQENABLE); /* clear the irqstatus for newly enabled irqs */ - dispc_clear_irqstatus((mask ^ old_mask) & mask); + dispc_clear_irqstatus(dispc, (mask ^ old_mask) & mask); dispc_write_reg(DISPC_IRQENABLE, mask); @@ -3600,11 +3614,12 @@ void dispc_disable_sidle(void) REG_FLD_MOD(DISPC_SYSCONFIG, 1, 4, 3); /* SIDLEMODE: no idle */ } -static u32 dispc_mgr_gamma_size(enum omap_channel channel) +static u32 dispc_mgr_gamma_size(struct dispc_device *dispc, + enum omap_channel channel) { const struct dispc_gamma_desc *gdesc = &mgr_desc[channel].gamma; - if (!dispc.feat->has_gamma_table) + if (!dispc->feat->has_gamma_table) return 0; return gdesc->len; @@ -3653,18 +3668,19 @@ static const struct drm_color_lut dispc_mgr_gamma_default_lut[] = { { .red = U16_MAX, .green = U16_MAX, .blue = U16_MAX, }, }; -static void dispc_mgr_set_gamma(enum omap_channel channel, - const struct drm_color_lut *lut, - unsigned int length) +static void dispc_mgr_set_gamma(struct dispc_device *dispc, + enum omap_channel channel, + const struct drm_color_lut *lut, + unsigned int length) { const struct dispc_gamma_desc *gdesc = &mgr_desc[channel].gamma; - u32 *table = dispc.gamma_table[channel]; + u32 *table = dispc->gamma_table[channel]; uint i; DSSDBG("%s: channel %d, lut len %u, hw len %u\n", __func__, channel, length, gdesc->len); - if (!dispc.feat->has_gamma_table) + if (!dispc->feat->has_gamma_table) return; if (lut == NULL || length < 2) { @@ -3696,7 +3712,7 @@ static void dispc_mgr_set_gamma(enum omap_channel channel, } } - if (dispc.is_enabled) + if (dispc->is_enabled) dispc_mgr_write_gamma_table(channel); } @@ -3726,7 +3742,7 @@ static int dispc_init_gamma_tables(void) dispc.gamma_table[channel] = gt; - dispc_mgr_set_gamma(channel, NULL, 0); + dispc_mgr_set_gamma(&dispc, channel, NULL, 0); } return 0; } @@ -4296,43 +4312,44 @@ static irqreturn_t dispc_irq_handler(int irq, void *arg) return dispc.user_handler(irq, dispc.user_data); } -static int dispc_request_irq(irq_handler_t handler, void *dev_id) +static int dispc_request_irq(struct dispc_device *dispc, irq_handler_t handler, + void *dev_id) { int r; - if (dispc.user_handler != NULL) + if (dispc->user_handler != NULL) return -EBUSY; - dispc.user_handler = handler; - dispc.user_data = dev_id; + dispc->user_handler = handler; + dispc->user_data = dev_id; /* ensure the dispc_irq_handler sees the values above */ smp_wmb(); - r = devm_request_irq(&dispc.pdev->dev, dispc.irq, dispc_irq_handler, - IRQF_SHARED, "OMAP DISPC", &dispc); + r = devm_request_irq(&dispc->pdev->dev, dispc->irq, dispc_irq_handler, + IRQF_SHARED, "OMAP DISPC", dispc); if (r) { - dispc.user_handler = NULL; - dispc.user_data = NULL; + dispc->user_handler = NULL; + dispc->user_data = NULL; } return r; } -static void dispc_free_irq(void *dev_id) +static void dispc_free_irq(struct dispc_device *dispc, void *dev_id) { - devm_free_irq(&dispc.pdev->dev, dispc.irq, &dispc); + devm_free_irq(&dispc->pdev->dev, dispc->irq, dispc); - dispc.user_handler = NULL; - dispc.user_data = NULL; + dispc->user_handler = NULL; + dispc->user_data = NULL; } -static u32 dispc_get_memory_bandwidth_limit(void) +static u32 dispc_get_memory_bandwidth_limit(struct dispc_device *dispc) { u32 limit = 0; /* Optional maximum memory bandwidth */ - of_property_read_u32(dispc.pdev->dev.of_node, "max-memory-bandwidth", + of_property_read_u32(dispc->pdev->dev.of_node, "max-memory-bandwidth", &limit); return limit; @@ -4439,7 +4456,8 @@ static void dispc_errata_i734_wa_fini(void) static void dispc_errata_i734_wa(void) { - u32 framedone_irq = dispc_mgr_get_framedone_irq(OMAP_DSS_CHANNEL_LCD); + u32 framedone_irq = dispc_mgr_get_framedone_irq(&dispc, + OMAP_DSS_CHANNEL_LCD); struct omap_overlay_info ovli; struct dss_lcd_mgr_config lcd_conf; u32 gatestate; @@ -4458,39 +4476,39 @@ static void dispc_errata_i734_wa(void) REG_FLD_MOD(DISPC_CONFIG, 0x1f, 8, 4); /* Setup and enable GFX plane */ - dispc_ovl_setup(OMAP_DSS_GFX, &ovli, &i734.vm, false, - OMAP_DSS_CHANNEL_LCD); - dispc_ovl_enable(OMAP_DSS_GFX, true); + dispc_ovl_setup(&dispc, OMAP_DSS_GFX, &ovli, &i734.vm, false, + OMAP_DSS_CHANNEL_LCD); + dispc_ovl_enable(&dispc, OMAP_DSS_GFX, true); /* Set up and enable display manager for LCD1 */ - dispc_mgr_setup(OMAP_DSS_CHANNEL_LCD, &i734.mgri); + dispc_mgr_setup(&dispc, OMAP_DSS_CHANNEL_LCD, &i734.mgri); dispc_calc_clock_rates(dss_get_dispc_clk_rate(dispc.dss), &lcd_conf.clock_info); - dispc_mgr_set_lcd_config(OMAP_DSS_CHANNEL_LCD, &lcd_conf); - dispc_mgr_set_timings(OMAP_DSS_CHANNEL_LCD, &i734.vm); + dispc_mgr_set_lcd_config(&dispc, OMAP_DSS_CHANNEL_LCD, &lcd_conf); + dispc_mgr_set_timings(&dispc, OMAP_DSS_CHANNEL_LCD, &i734.vm); - dispc_clear_irqstatus(framedone_irq); + dispc_clear_irqstatus(&dispc, framedone_irq); /* Enable and shut the channel to produce just one frame */ - dispc_mgr_enable(OMAP_DSS_CHANNEL_LCD, true); - dispc_mgr_enable(OMAP_DSS_CHANNEL_LCD, false); + dispc_mgr_enable(&dispc, OMAP_DSS_CHANNEL_LCD, true); + dispc_mgr_enable(&dispc, OMAP_DSS_CHANNEL_LCD, false); /* Busy wait for framedone. We can't fiddle with irq handlers * in PM resume. Typically the loop runs less than 5 times and * waits less than a micro second. */ count = 0; - while (!(dispc_read_irqstatus() & framedone_irq)) { + while (!(dispc_read_irqstatus(&dispc) & framedone_irq)) { if (count++ > 10000) { dev_err(&dispc.pdev->dev, "%s: framedone timeout\n", __func__); break; } } - dispc_ovl_enable(OMAP_DSS_GFX, false); + dispc_ovl_enable(&dispc, OMAP_DSS_GFX, false); /* Clear all irq bits before continuing */ - dispc_clear_irqstatus(0xffffffff); + dispc_clear_irqstatus(&dispc, 0xffffffff); /* Restore the original state to LCD1 output gates */ REG_FLD_MOD(DISPC_CONFIG, gatestate, 8, 4); @@ -4610,7 +4628,7 @@ static int dispc_bind(struct device *dev, struct device *master, void *data) pm_runtime_enable(&pdev->dev); - r = dispc_runtime_get(); + r = dispc_runtime_get(&dispc); if (r) goto err_runtime_get; @@ -4620,8 +4638,9 @@ static int dispc_bind(struct device *dev, struct device *master, void *data) dev_dbg(&pdev->dev, "OMAP DISPC rev %d.%d\n", FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0)); - dispc_runtime_put(); + dispc_runtime_put(&dispc); + dss->dispc = &dispc; dss->dispc_ops = &dispc_ops; dispc.debugfs = dss_debugfs_create_file(dss, "dispc", dispc_dump_regs, @@ -4634,13 +4653,13 @@ err_runtime_get: return r; } -static void dispc_unbind(struct device *dev, struct device *master, - void *data) +static void dispc_unbind(struct device *dev, struct device *master, void *data) { struct dss_device *dss = dispc.dss; dss_debugfs_remove_file(dispc.debugfs); + dss->dispc = NULL; dss->dispc_ops = NULL; pm_runtime_disable(dev); diff --git a/drivers/gpu/drm/omapdrm/dss/dpi.c b/drivers/gpu/drm/omapdrm/dss/dpi.c index e818e7836cbb..d524094b8394 100644 --- a/drivers/gpu/drm/omapdrm/dss/dpi.c +++ b/drivers/gpu/drm/omapdrm/dss/dpi.c @@ -406,7 +406,7 @@ static int dpi_display_enable(struct omap_dss_device *dssdev) goto err_reg_enable; } - r = dispc_runtime_get(); + r = dispc_runtime_get(dpi->dss->dispc); if (r) goto err_get_dispc; @@ -442,7 +442,7 @@ err_set_mode: dss_pll_disable(dpi->pll); err_pll_init: err_src_sel: - dispc_runtime_put(); + dispc_runtime_put(dpi->dss->dispc); err_get_dispc: if (dpi->vdds_dsi_reg) regulator_disable(dpi->vdds_dsi_reg); @@ -466,7 +466,7 @@ static void dpi_display_disable(struct omap_dss_device *dssdev) dss_pll_disable(dpi->pll); } - dispc_runtime_put(); + dispc_runtime_put(dpi->dss->dispc); if (dpi->vdds_dsi_reg) regulator_disable(dpi->vdds_dsi_reg); diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c index 66c4d973e7eb..c07326a46c01 100644 --- a/drivers/gpu/drm/omapdrm/dss/dsi.c +++ b/drivers/gpu/drm/omapdrm/dss/dsi.c @@ -5523,7 +5523,7 @@ static int dsi_runtime_suspend(struct device *dev) /* wait for current handler to finish before turning the DSI off */ synchronize_irq(dsi->irq); - dispc_runtime_put(); + dispc_runtime_put(dsi->dss->dispc); return 0; } @@ -5533,7 +5533,7 @@ static int dsi_runtime_resume(struct device *dev) struct dsi_data *dsi = dev_get_drvdata(dev); int r; - r = dispc_runtime_get(); + r = dispc_runtime_get(dsi->dss->dispc); if (r) return r; diff --git a/drivers/gpu/drm/omapdrm/dss/dss.h b/drivers/gpu/drm/omapdrm/dss/dss.h index 348378f1b5a5..f3acfd62031c 100644 --- a/drivers/gpu/drm/omapdrm/dss/dss.h +++ b/drivers/gpu/drm/omapdrm/dss/dss.h @@ -25,6 +25,7 @@ #include "omapdss.h" +struct dispc_device; struct dss_debugfs_entry; struct platform_device; struct seq_file; @@ -272,6 +273,7 @@ struct dss_device { struct dss_pll *video1_pll; struct dss_pll *video2_pll; + struct dispc_device *dispc; const struct dispc_ops *dispc_ops; }; @@ -407,8 +409,8 @@ static inline void dpi_uninit_port(struct device_node *port) /* DISPC */ void dispc_dump_clocks(struct seq_file *s); -int dispc_runtime_get(void); -void dispc_runtime_put(void); +int dispc_runtime_get(struct dispc_device *dispc); +void dispc_runtime_put(struct dispc_device *dispc); void dispc_enable_sidle(void); void dispc_disable_sidle(void); diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4.c b/drivers/gpu/drm/omapdrm/dss/hdmi4.c index 096542fb75d2..5c55fa3f593a 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi4.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi4.c @@ -819,16 +819,19 @@ static int hdmi4_remove(struct platform_device *pdev) static int hdmi_runtime_suspend(struct device *dev) { - dispc_runtime_put(); + struct omap_hdmi *hdmi = dev_get_drvdata(dev); + + dispc_runtime_put(hdmi->dss->dispc); return 0; } static int hdmi_runtime_resume(struct device *dev) { + struct omap_hdmi *hdmi = dev_get_drvdata(dev); int r; - r = dispc_runtime_get(); + r = dispc_runtime_get(hdmi->dss->dispc); if (r < 0) return r; diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi5.c b/drivers/gpu/drm/omapdrm/dss/hdmi5.c index 597baebd959c..e896f63480f1 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi5.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi5.c @@ -814,16 +814,19 @@ static int hdmi5_remove(struct platform_device *pdev) static int hdmi_runtime_suspend(struct device *dev) { - dispc_runtime_put(); + struct omap_hdmi *hdmi = dev_get_drvdata(dev); + + dispc_runtime_put(hdmi->dss->dispc); return 0; } static int hdmi_runtime_resume(struct device *dev) { + struct omap_hdmi *hdmi = dev_get_drvdata(dev); int r; - r = dispc_runtime_get(); + r = dispc_runtime_get(hdmi->dss->dispc); if (r < 0) return r; diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h b/drivers/gpu/drm/omapdrm/dss/omapdss.h index 4bf7843b4aec..a4f71e082c1c 100644 --- a/drivers/gpu/drm/omapdrm/dss/omapdss.h +++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h @@ -62,6 +62,8 @@ struct dss_device; struct omap_drm_private; struct omap_dss_device; +struct dispc_device; +struct dss_device; struct dss_lcd_mgr_config; struct snd_aes_iec958; struct snd_cea_861_aud_if; @@ -690,49 +692,64 @@ void dss_mgr_unregister_framedone_handler(struct omap_dss_device *dssdev, /* dispc ops */ struct dispc_ops { - u32 (*read_irqstatus)(void); - void (*clear_irqstatus)(u32 mask); - void (*write_irqenable)(u32 mask); - - int (*request_irq)(irq_handler_t handler, void *dev_id); - void (*free_irq)(void *dev_id); - - int (*runtime_get)(void); - void (*runtime_put)(void); - - int (*get_num_ovls)(void); - int (*get_num_mgrs)(void); - - u32 (*get_memory_bandwidth_limit)(void); - - void (*mgr_enable)(enum omap_channel channel, bool enable); - bool (*mgr_is_enabled)(enum omap_channel channel); - u32 (*mgr_get_vsync_irq)(enum omap_channel channel); - u32 (*mgr_get_framedone_irq)(enum omap_channel channel); - u32 (*mgr_get_sync_lost_irq)(enum omap_channel channel); - bool (*mgr_go_busy)(enum omap_channel channel); - void (*mgr_go)(enum omap_channel channel); - void (*mgr_set_lcd_config)(enum omap_channel channel, - const struct dss_lcd_mgr_config *config); - void (*mgr_set_timings)(enum omap_channel channel, - const struct videomode *vm); - void (*mgr_setup)(enum omap_channel channel, - const struct omap_overlay_manager_info *info); - enum omap_dss_output_id (*mgr_get_supported_outputs)(enum omap_channel channel); - u32 (*mgr_gamma_size)(enum omap_channel channel); - void (*mgr_set_gamma)(enum omap_channel channel, - const struct drm_color_lut *lut, - unsigned int length); - - int (*ovl_enable)(enum omap_plane_id plane, bool enable); - int (*ovl_setup)(enum omap_plane_id plane, + u32 (*read_irqstatus)(struct dispc_device *dispc); + void (*clear_irqstatus)(struct dispc_device *dispc, u32 mask); + void (*write_irqenable)(struct dispc_device *dispc, u32 mask); + + int (*request_irq)(struct dispc_device *dispc, irq_handler_t handler, + void *dev_id); + void (*free_irq)(struct dispc_device *dispc, void *dev_id); + + int (*runtime_get)(struct dispc_device *dispc); + void (*runtime_put)(struct dispc_device *dispc); + + int (*get_num_ovls)(struct dispc_device *dispc); + int (*get_num_mgrs)(struct dispc_device *dispc); + + u32 (*get_memory_bandwidth_limit)(struct dispc_device *dispc); + + void (*mgr_enable)(struct dispc_device *dispc, + enum omap_channel channel, bool enable); + bool (*mgr_is_enabled)(struct dispc_device *dispc, + enum omap_channel channel); + u32 (*mgr_get_vsync_irq)(struct dispc_device *dispc, + enum omap_channel channel); + u32 (*mgr_get_framedone_irq)(struct dispc_device *dispc, + enum omap_channel channel); + u32 (*mgr_get_sync_lost_irq)(struct dispc_device *dispc, + enum omap_channel channel); + bool (*mgr_go_busy)(struct dispc_device *dispc, + enum omap_channel channel); + void (*mgr_go)(struct dispc_device *dispc, enum omap_channel channel); + void (*mgr_set_lcd_config)(struct dispc_device *dispc, + enum omap_channel channel, + const struct dss_lcd_mgr_config *config); + void (*mgr_set_timings)(struct dispc_device *dispc, + enum omap_channel channel, + const struct videomode *vm); + void (*mgr_setup)(struct dispc_device *dispc, enum omap_channel channel, + const struct omap_overlay_manager_info *info); + enum omap_dss_output_id (*mgr_get_supported_outputs)( + struct dispc_device *dispc, enum omap_channel channel); + u32 (*mgr_gamma_size)(struct dispc_device *dispc, + enum omap_channel channel); + void (*mgr_set_gamma)(struct dispc_device *dispc, + enum omap_channel channel, + const struct drm_color_lut *lut, + unsigned int length); + + int (*ovl_enable)(struct dispc_device *dispc, enum omap_plane_id plane, + bool enable); + int (*ovl_setup)(struct dispc_device *dispc, enum omap_plane_id plane, const struct omap_overlay_info *oi, - const struct videomode *vm, bool mem_to_mem, - enum omap_channel channel); + const struct videomode *vm, bool mem_to_mem, + enum omap_channel channel); - const u32 *(*ovl_get_color_modes)(enum omap_plane_id plane); + const u32 *(*ovl_get_color_modes)(struct dispc_device *dispc, + enum omap_plane_id plane); }; +struct dispc_device *dispc_get_dispc(struct dss_device *dss); const struct dispc_ops *dispc_get_ops(struct dss_device *dss); bool omapdss_component_is_display(struct device_node *node); diff --git a/drivers/gpu/drm/omapdrm/dss/sdi.c b/drivers/gpu/drm/omapdrm/dss/sdi.c index bf225ae69b06..b1d0e706a1ec 100644 --- a/drivers/gpu/drm/omapdrm/dss/sdi.c +++ b/drivers/gpu/drm/omapdrm/dss/sdi.c @@ -141,7 +141,7 @@ static int sdi_display_enable(struct omap_dss_device *dssdev) if (r) goto err_reg_enable; - r = dispc_runtime_get(); + r = dispc_runtime_get(sdi.dss->dispc); if (r) goto err_get_dispc; @@ -203,7 +203,7 @@ err_mgr_enable: err_sdi_enable: err_set_dss_clock_div: err_calc_clock_div: - dispc_runtime_put(); + dispc_runtime_put(sdi.dss->dispc); err_get_dispc: regulator_disable(sdi.vdds_sdi_reg); err_reg_enable: @@ -216,7 +216,7 @@ static void sdi_display_disable(struct omap_dss_device *dssdev) dss_sdi_disable(sdi.dss); - dispc_runtime_put(); + dispc_runtime_put(sdi.dss->dispc); regulator_disable(sdi.vdds_sdi_reg); } diff --git a/drivers/gpu/drm/omapdrm/dss/venc.c b/drivers/gpu/drm/omapdrm/dss/venc.c index bed3b54b70b2..546271389189 100644 --- a/drivers/gpu/drm/omapdrm/dss/venc.c +++ b/drivers/gpu/drm/omapdrm/dss/venc.c @@ -956,7 +956,7 @@ static int venc_runtime_suspend(struct device *dev) if (venc.tv_dac_clk) clk_disable_unprepare(venc.tv_dac_clk); - dispc_runtime_put(); + dispc_runtime_put(venc.dss->dispc); return 0; } @@ -965,7 +965,7 @@ static int venc_runtime_resume(struct device *dev) { int r; - r = dispc_runtime_get(); + r = dispc_runtime_get(venc.dss->dispc); if (r < 0) return r; diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c index ffe4f698d291..6c4d40b824e4 100644 --- a/drivers/gpu/drm/omapdrm/omap_crtc.c +++ b/drivers/gpu/drm/omapdrm/omap_crtc.c @@ -117,10 +117,13 @@ 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 (!(priv->dispc_ops->mgr_get_supported_outputs(channel) & dst->id)) + if (!(dispc_ops->mgr_get_supported_outputs(dispc, channel) & dst->id)) return -EINVAL; omap_crtc_output[channel] = dst; @@ -157,7 +160,7 @@ static void omap_crtc_set_enabled(struct drm_crtc *crtc, bool enable) return; if (omap_crtc_output[channel]->output_type == OMAP_DISPLAY_TYPE_HDMI) { - priv->dispc_ops->mgr_enable(channel, enable); + priv->dispc_ops->mgr_enable(priv->dispc, channel, enable); omap_crtc->enabled = enable; return; } @@ -170,8 +173,9 @@ static void omap_crtc_set_enabled(struct drm_crtc *crtc, bool enable) omap_crtc->ignore_digit_sync_lost = true; } - framedone_irq = priv->dispc_ops->mgr_get_framedone_irq(channel); - vsync_irq = priv->dispc_ops->mgr_get_vsync_irq(channel); + framedone_irq = priv->dispc_ops->mgr_get_framedone_irq(priv->dispc, + channel); + vsync_irq = priv->dispc_ops->mgr_get_vsync_irq(priv->dispc, channel); if (enable) { wait = omap_irq_wait_init(dev, vsync_irq, 1); @@ -191,7 +195,7 @@ static void omap_crtc_set_enabled(struct drm_crtc *crtc, bool enable) wait = omap_irq_wait_init(dev, vsync_irq, 2); } - priv->dispc_ops->mgr_enable(channel, enable); + priv->dispc_ops->mgr_enable(priv->dispc, channel, enable); omap_crtc->enabled = enable; ret = omap_irq_wait(dev, wait, msecs_to_jiffies(100)); @@ -213,7 +217,8 @@ static int omap_crtc_dss_enable(struct omap_drm_private *priv, { struct omap_crtc *omap_crtc = omap_crtcs[channel]; - priv->dispc_ops->mgr_set_timings(omap_crtc->channel, &omap_crtc->vm); + priv->dispc_ops->mgr_set_timings(priv->dispc, omap_crtc->channel, + &omap_crtc->vm); omap_crtc_set_enabled(&omap_crtc->base, true); return 0; @@ -243,7 +248,8 @@ static void omap_crtc_dss_set_lcd_config(struct omap_drm_private *priv, struct omap_crtc *omap_crtc = omap_crtcs[channel]; DBG("%s", omap_crtc->name); - priv->dispc_ops->mgr_set_lcd_config(omap_crtc->channel, config); + priv->dispc_ops->mgr_set_lcd_config(priv->dispc, omap_crtc->channel, + config); } static int omap_crtc_dss_register_framedone( @@ -300,7 +306,7 @@ void omap_crtc_vblank_irq(struct drm_crtc *crtc) * If the dispc is busy we're racing the flush operation. Try again on * the next vblank interrupt. */ - if (priv->dispc_ops->mgr_go_busy(omap_crtc->channel)) { + if (priv->dispc_ops->mgr_go_busy(priv->dispc, omap_crtc->channel)) { spin_unlock(&crtc->dev->event_lock); return; } @@ -337,7 +343,7 @@ static void omap_crtc_write_crtc_properties(struct drm_crtc *crtc) info.partial_alpha_enabled = false; info.cpr_enable = false; - priv->dispc_ops->mgr_setup(omap_crtc->channel, &info); + priv->dispc_ops->mgr_setup(priv->dispc, omap_crtc->channel, &info); } /* ----------------------------------------------------------------------------- @@ -537,7 +543,8 @@ static void omap_crtc_atomic_flush(struct drm_crtc *crtc, length = crtc->state->gamma_lut->length / sizeof(*lut); } - priv->dispc_ops->mgr_set_gamma(omap_crtc->channel, lut, length); + priv->dispc_ops->mgr_set_gamma(priv->dispc, omap_crtc->channel, + lut, length); } omap_crtc_write_crtc_properties(crtc); @@ -552,7 +559,7 @@ static void omap_crtc_atomic_flush(struct drm_crtc *crtc, WARN_ON(ret != 0); spin_lock_irq(&crtc->dev->event_lock); - priv->dispc_ops->mgr_go(omap_crtc->channel); + priv->dispc_ops->mgr_go(priv->dispc, omap_crtc->channel); omap_crtc_arm_event(crtc); spin_unlock_irq(&crtc->dev->event_lock); } @@ -734,7 +741,7 @@ struct drm_crtc *omap_crtc_init(struct drm_device *dev, * extracted with dispc_mgr_gamma_size(). If it returns 0 * gamma table is not supprted. */ - if (priv->dispc_ops->mgr_gamma_size(channel)) { + if (priv->dispc_ops->mgr_gamma_size(priv->dispc, channel)) { unsigned int gamma_lut_size = 256; drm_crtc_enable_color_mgmt(crtc, 0, false, gamma_lut_size); diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c index a93916cd0258..65a567dcf3ab 100644 --- a/drivers/gpu/drm/omapdrm/omap_drv.c +++ b/drivers/gpu/drm/omapdrm/omap_drv.c @@ -69,7 +69,7 @@ static void omap_atomic_commit_tail(struct drm_atomic_state *old_state) struct drm_device *dev = old_state->dev; struct omap_drm_private *priv = dev->dev_private; - priv->dispc_ops->runtime_get(); + priv->dispc_ops->runtime_get(priv->dispc); /* Apply the atomic update. */ drm_atomic_helper_commit_modeset_disables(dev, old_state); @@ -113,7 +113,7 @@ static void omap_atomic_commit_tail(struct drm_atomic_state *old_state) drm_atomic_helper_cleanup_planes(dev, old_state); - priv->dispc_ops->runtime_put(); + priv->dispc_ops->runtime_put(priv->dispc); } static const struct drm_mode_config_helper_funcs omap_mode_config_helper_funcs = { @@ -191,7 +191,7 @@ cleanup: static int omap_modeset_init_properties(struct drm_device *dev) { struct omap_drm_private *priv = dev->dev_private; - unsigned int num_planes = priv->dispc_ops->get_num_ovls(); + unsigned int num_planes = priv->dispc_ops->get_num_ovls(priv->dispc); priv->zorder_prop = drm_property_create_range(dev, 0, "zorder", 0, num_planes - 1); @@ -205,8 +205,8 @@ static int omap_modeset_init(struct drm_device *dev) { struct omap_drm_private *priv = dev->dev_private; struct omap_dss_device *dssdev = NULL; - int num_ovls = priv->dispc_ops->get_num_ovls(); - int num_mgrs = priv->dispc_ops->get_num_mgrs(); + int num_ovls = priv->dispc_ops->get_num_ovls(priv->dispc); + int num_mgrs = priv->dispc_ops->get_num_mgrs(priv->dispc); int num_crtcs, crtc_idx, plane_idx; int ret; u32 plane_crtc_mask; @@ -521,6 +521,7 @@ static int omapdrm_init(struct omap_drm_private *priv, struct device *dev) priv->dev = dev; priv->dss = omapdss_get_dss(); + priv->dispc = dispc_get_dispc(priv->dss); priv->dispc_ops = dispc_get_ops(priv->dss); omap_crtc_pre_init(priv); @@ -549,7 +550,7 @@ static int omapdrm_init(struct omap_drm_private *priv, struct device *dev) /* Get memory bandwidth limits */ if (priv->dispc_ops->get_memory_bandwidth_limit) priv->max_bandwidth = - priv->dispc_ops->get_memory_bandwidth_limit(); + priv->dispc_ops->get_memory_bandwidth_limit(priv->dispc); omap_gem_init(ddev); diff --git a/drivers/gpu/drm/omapdrm/omap_drv.h b/drivers/gpu/drm/omapdrm/omap_drv.h index a7962c14fc7c..6eaee4df4559 100644 --- a/drivers/gpu/drm/omapdrm/omap_drv.h +++ b/drivers/gpu/drm/omapdrm/omap_drv.h @@ -51,6 +51,7 @@ struct omap_drm_private { u32 omaprev; struct dss_device *dss; + struct dispc_device *dispc; const struct dispc_ops *dispc_ops; unsigned int num_crtcs; diff --git a/drivers/gpu/drm/omapdrm/omap_irq.c b/drivers/gpu/drm/omapdrm/omap_irq.c index 976dc0e44482..c85115049f86 100644 --- a/drivers/gpu/drm/omapdrm/omap_irq.c +++ b/drivers/gpu/drm/omapdrm/omap_irq.c @@ -38,7 +38,7 @@ static void omap_irq_update(struct drm_device *dev) DBG("irqmask=%08x", irqmask); - priv->dispc_ops->write_irqenable(irqmask); + priv->dispc_ops->write_irqenable(priv->dispc, irqmask); } static void omap_irq_wait_handler(struct omap_irq_wait *wait) @@ -108,7 +108,8 @@ int omap_irq_enable_vblank(struct drm_crtc *crtc) DBG("dev=%p, crtc=%u", dev, channel); spin_lock_irqsave(&priv->wait_lock, flags); - priv->irq_mask |= priv->dispc_ops->mgr_get_vsync_irq(channel); + priv->irq_mask |= priv->dispc_ops->mgr_get_vsync_irq(priv->dispc, + channel); omap_irq_update(dev); spin_unlock_irqrestore(&priv->wait_lock, flags); @@ -134,7 +135,8 @@ void omap_irq_disable_vblank(struct drm_crtc *crtc) DBG("dev=%p, crtc=%u", dev, channel); spin_lock_irqsave(&priv->wait_lock, flags); - priv->irq_mask &= ~priv->dispc_ops->mgr_get_vsync_irq(channel); + priv->irq_mask &= ~priv->dispc_ops->mgr_get_vsync_irq(priv->dispc, + channel); omap_irq_update(dev); spin_unlock_irqrestore(&priv->wait_lock, flags); } @@ -198,9 +200,9 @@ static irqreturn_t omap_irq_handler(int irq, void *arg) unsigned int id; u32 irqstatus; - irqstatus = priv->dispc_ops->read_irqstatus(); - priv->dispc_ops->clear_irqstatus(irqstatus); - priv->dispc_ops->read_irqstatus(); /* flush posted write */ + irqstatus = priv->dispc_ops->read_irqstatus(priv->dispc); + priv->dispc_ops->clear_irqstatus(priv->dispc, irqstatus); + priv->dispc_ops->read_irqstatus(priv->dispc); /* flush posted write */ VERB("irqs: %08x", irqstatus); @@ -208,12 +210,12 @@ static irqreturn_t omap_irq_handler(int irq, void *arg) struct drm_crtc *crtc = priv->crtcs[id]; enum omap_channel channel = omap_crtc_channel(crtc); - if (irqstatus & priv->dispc_ops->mgr_get_vsync_irq(channel)) { + if (irqstatus & priv->dispc_ops->mgr_get_vsync_irq(priv->dispc, channel)) { drm_handle_vblank(dev, id); omap_crtc_vblank_irq(crtc); } - if (irqstatus & priv->dispc_ops->mgr_get_sync_lost_irq(channel)) + if (irqstatus & priv->dispc_ops->mgr_get_sync_lost_irq(priv->dispc, channel)) omap_crtc_error_irq(crtc, irqstatus); } @@ -247,7 +249,7 @@ static const u32 omap_underflow_irqs[] = { int omap_drm_irq_install(struct drm_device *dev) { struct omap_drm_private *priv = dev->dev_private; - unsigned int num_mgrs = priv->dispc_ops->get_num_mgrs(); + unsigned int num_mgrs = priv->dispc_ops->get_num_mgrs(priv->dispc); unsigned int max_planes; unsigned int i; int ret; @@ -265,13 +267,13 @@ int omap_drm_irq_install(struct drm_device *dev) } for (i = 0; i < num_mgrs; ++i) - priv->irq_mask |= priv->dispc_ops->mgr_get_sync_lost_irq(i); + priv->irq_mask |= priv->dispc_ops->mgr_get_sync_lost_irq(priv->dispc, i); - priv->dispc_ops->runtime_get(); - priv->dispc_ops->clear_irqstatus(0xffffffff); - priv->dispc_ops->runtime_put(); + priv->dispc_ops->runtime_get(priv->dispc); + priv->dispc_ops->clear_irqstatus(priv->dispc, 0xffffffff); + priv->dispc_ops->runtime_put(priv->dispc); - ret = priv->dispc_ops->request_irq(omap_irq_handler, dev); + ret = priv->dispc_ops->request_irq(priv->dispc, omap_irq_handler, dev); if (ret < 0) return ret; @@ -289,5 +291,5 @@ void omap_drm_irq_uninstall(struct drm_device *dev) dev->irq_enabled = false; - priv->dispc_ops->free_irq(dev); + priv->dispc_ops->free_irq(priv->dispc, dev); } diff --git a/drivers/gpu/drm/omapdrm/omap_plane.c b/drivers/gpu/drm/omapdrm/omap_plane.c index 0665ed9fe395..2899435cad6e 100644 --- a/drivers/gpu/drm/omapdrm/omap_plane.c +++ b/drivers/gpu/drm/omapdrm/omap_plane.c @@ -77,17 +77,17 @@ static void omap_plane_atomic_update(struct drm_plane *plane, &info.paddr, &info.p_uv_addr); /* and finally, update omapdss: */ - ret = priv->dispc_ops->ovl_setup(omap_plane->id, &info, + ret = priv->dispc_ops->ovl_setup(priv->dispc, omap_plane->id, &info, omap_crtc_timings(state->crtc), false, omap_crtc_channel(state->crtc)); if (ret) { dev_err(plane->dev->dev, "Failed to setup plane %s\n", omap_plane->name); - priv->dispc_ops->ovl_enable(omap_plane->id, false); + priv->dispc_ops->ovl_enable(priv->dispc, omap_plane->id, false); return; } - priv->dispc_ops->ovl_enable(omap_plane->id, true); + priv->dispc_ops->ovl_enable(priv->dispc, omap_plane->id, true); } static void omap_plane_atomic_disable(struct drm_plane *plane, @@ -100,7 +100,7 @@ static void omap_plane_atomic_disable(struct drm_plane *plane, plane->state->zpos = plane->type == DRM_PLANE_TYPE_PRIMARY ? 0 : omap_plane->id; - priv->dispc_ops->ovl_enable(omap_plane->id, false); + priv->dispc_ops->ovl_enable(priv->dispc, omap_plane->id, false); } static int omap_plane_atomic_check(struct drm_plane *plane, @@ -259,7 +259,7 @@ struct drm_plane *omap_plane_init(struct drm_device *dev, u32 possible_crtcs) { struct omap_drm_private *priv = dev->dev_private; - unsigned int num_planes = priv->dispc_ops->get_num_ovls(); + unsigned int num_planes = priv->dispc_ops->get_num_ovls(priv->dispc); struct drm_plane *plane; struct omap_plane *omap_plane; enum omap_plane_id id; @@ -278,7 +278,7 @@ struct drm_plane *omap_plane_init(struct drm_device *dev, if (!omap_plane) return ERR_PTR(-ENOMEM); - formats = priv->dispc_ops->ovl_get_color_modes(id); + formats = priv->dispc_ops->ovl_get_color_modes(priv->dispc, id); for (nformats = 0; formats[nformats]; ++nformats) ; omap_plane->id = id; -- cgit v1.2.3 From efd1f06be004a6a384f0482ef76c12bc202e1b8e Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Fri, 9 Feb 2018 09:36:23 +0200 Subject: drm/omap: cleanup fbdev init/free omap_fbdev_init() and omap_fbdev_free() use priv->fbdev directly. However, omap_fbdev_init() returns the fbdev, and omap_drv.c also assigns the return value to priv->fbdev. This is slightly confusing. Clean this up by removing the omap_fbdev_init() return value, as we don't care whether fbdev init succeeded or not. Also change omap_drv.c to call omap_fbdev_free() always, and omap_fbdev_free() does the check if fbdev was initialized. While at it, rename omap_fbdev_free() to omap_fbdev_fini() to better match the "init" counterpart. Signed-off-by: Tomi Valkeinen Reviewed-by: Laurent Pinchart --- drivers/gpu/drm/omapdrm/omap_drv.c | 9 ++++----- drivers/gpu/drm/omapdrm/omap_fbdev.c | 18 ++++++++---------- drivers/gpu/drm/omapdrm/omap_fbdev.h | 9 ++++----- 3 files changed, 16 insertions(+), 20 deletions(-) (limited to 'drivers/gpu/drm/omapdrm/omap_drv.c') diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c index 65a567dcf3ab..4f48b908bdc6 100644 --- a/drivers/gpu/drm/omapdrm/omap_drv.c +++ b/drivers/gpu/drm/omapdrm/omap_drv.c @@ -570,7 +570,7 @@ static int omapdrm_init(struct omap_drm_private *priv, struct device *dev) for (i = 0; i < priv->num_crtcs; i++) drm_crtc_vblank_off(priv->crtcs[i]); - priv->fbdev = omap_fbdev_init(ddev); + omap_fbdev_init(ddev); drm_kms_helper_poll_init(ddev); omap_modeset_enable_external_hpd(); @@ -588,8 +588,8 @@ static int omapdrm_init(struct omap_drm_private *priv, struct device *dev) err_cleanup_helpers: omap_modeset_disable_external_hpd(); drm_kms_helper_poll_fini(ddev); - if (priv->fbdev) - omap_fbdev_free(ddev); + + omap_fbdev_fini(ddev); err_cleanup_modeset: drm_mode_config_cleanup(ddev); omap_drm_irq_uninstall(ddev); @@ -615,8 +615,7 @@ static void omapdrm_cleanup(struct omap_drm_private *priv) omap_modeset_disable_external_hpd(); drm_kms_helper_poll_fini(ddev); - if (priv->fbdev) - omap_fbdev_free(ddev); + omap_fbdev_fini(ddev); drm_atomic_helper_shutdown(ddev); diff --git a/drivers/gpu/drm/omapdrm/omap_fbdev.c b/drivers/gpu/drm/omapdrm/omap_fbdev.c index 632ebcf2165f..be94480326d7 100644 --- a/drivers/gpu/drm/omapdrm/omap_fbdev.c +++ b/drivers/gpu/drm/omapdrm/omap_fbdev.c @@ -242,7 +242,7 @@ static struct drm_fb_helper *get_fb(struct fb_info *fbi) } /* initialize fbdev helper */ -struct drm_fb_helper *omap_fbdev_init(struct drm_device *dev) +void omap_fbdev_init(struct drm_device *dev) { struct omap_drm_private *priv = dev->dev_private; struct omap_fbdev *fbdev = NULL; @@ -260,10 +260,8 @@ struct drm_fb_helper *omap_fbdev_init(struct drm_device *dev) drm_fb_helper_prepare(dev, helper, &omap_fb_helper_funcs); ret = drm_fb_helper_init(dev, helper, priv->num_connectors); - if (ret) { - dev_err(dev->dev, "could not init fbdev: ret=%d\n", ret); + if (ret) goto fail; - } ret = drm_fb_helper_single_add_all_connectors(helper); if (ret) @@ -275,7 +273,7 @@ struct drm_fb_helper *omap_fbdev_init(struct drm_device *dev) priv->fbdev = helper; - return helper; + return; fini: drm_fb_helper_fini(helper); @@ -283,12 +281,9 @@ fail: kfree(fbdev); dev_warn(dev->dev, "omap_fbdev_init failed\n"); - /* well, limp along without an fbdev.. maybe X11 will work? */ - - return NULL; } -void omap_fbdev_free(struct drm_device *dev) +void omap_fbdev_fini(struct drm_device *dev) { struct omap_drm_private *priv = dev->dev_private; struct drm_fb_helper *helper = priv->fbdev; @@ -296,11 +291,14 @@ void omap_fbdev_free(struct drm_device *dev) DBG(); + if (!helper) + return; + drm_fb_helper_unregister_fbi(helper); drm_fb_helper_fini(helper); - fbdev = to_omap_fbdev(priv->fbdev); + fbdev = to_omap_fbdev(helper); /* unpin the GEM object pinned in omap_fbdev_create() */ if (fbdev->bo) diff --git a/drivers/gpu/drm/omapdrm/omap_fbdev.h b/drivers/gpu/drm/omapdrm/omap_fbdev.h index 1f5ba0996a1a..7dfd843f73f1 100644 --- a/drivers/gpu/drm/omapdrm/omap_fbdev.h +++ b/drivers/gpu/drm/omapdrm/omap_fbdev.h @@ -24,14 +24,13 @@ struct drm_device; struct drm_fb_helper; #ifdef CONFIG_DRM_FBDEV_EMULATION -struct drm_fb_helper *omap_fbdev_init(struct drm_device *dev); -void omap_fbdev_free(struct drm_device *dev); +void omap_fbdev_init(struct drm_device *dev); +void omap_fbdev_fini(struct drm_device *dev); #else -static inline struct drm_fb_helper *omap_fbdev_init(struct drm_device *dev) +static inline void omap_fbdev_init(struct drm_device *dev) { - return NULL; } -static inline void omap_fbdev_free(struct drm_device *dev) +static inline void omap_fbdev_fini(struct drm_device *dev) { } #endif -- cgit v1.2.3 From 1915d7fa93397b3dc8bf9c6973d8662c0a661daf Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Wed, 10 Jan 2018 11:31:18 +0200 Subject: drm/omap: fix maximum sizes We define max width and height in mode_config to 2048. These maximums affect many things, which are independent and depend on platform. We need to do more fine grained checks in the code paths for each component, and so the maximum values in mode_config should just be "big enough" to cover all use cases. Change the maximum width & height to 8192. Signed-off-by: Tomi Valkeinen --- drivers/gpu/drm/omapdrm/omap_drv.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'drivers/gpu/drm/omapdrm/omap_drv.c') diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c index 4f48b908bdc6..3632854c2b91 100644 --- a/drivers/gpu/drm/omapdrm/omap_drv.c +++ b/drivers/gpu/drm/omapdrm/omap_drv.c @@ -310,11 +310,14 @@ static int omap_modeset_init(struct drm_device *dev) dev->mode_config.min_width = 8; dev->mode_config.min_height = 2; - /* note: eventually will need some cpu_is_omapXYZ() type stuff here - * to fill in these limits properly on different OMAP generations.. + /* + * Note: these values are used for multiple independent things: + * connector mode filtering, buffer sizes, crtc sizes... + * Use big enough values here to cover all use cases, and do more + * specific checking in the respective code paths. */ - dev->mode_config.max_width = 2048; - dev->mode_config.max_height = 2048; + dev->mode_config.max_width = 8192; + dev->mode_config.max_height = 8192; dev->mode_config.funcs = &omap_mode_config_funcs; dev->mode_config.helper_private = &omap_mode_config_helper_funcs; -- cgit v1.2.3