diff options
Diffstat (limited to 'drivers/gpu/drm/tidss/tidss_drv.c')
| -rw-r--r-- | drivers/gpu/drm/tidss/tidss_drv.c | 101 |
1 files changed, 51 insertions, 50 deletions
diff --git a/drivers/gpu/drm/tidss/tidss_drv.c b/drivers/gpu/drm/tidss/tidss_drv.c index 66e3c86eb5c7..1c8cc18bc53c 100644 --- a/drivers/gpu/drm/tidss/tidss_drv.c +++ b/drivers/gpu/drm/tidss/tidss_drv.c @@ -5,25 +5,27 @@ */ #include <linux/console.h> -#include <linux/of_device.h> +#include <linux/of.h> #include <linux/module.h> #include <linux/pm_runtime.h> +#include <linux/aperture.h> +#include <drm/clients/drm_client_setup.h> #include <drm/drm_atomic.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_crtc.h> -#include <drm/drm_crtc_helper.h> #include <drm/drm_drv.h> -#include <drm/drm_fb_helper.h> -#include <drm/drm_gem_cma_helper.h> -#include <drm/drm_irq.h> +#include <drm/drm_fbdev_dma.h> +#include <drm/drm_gem_dma_helper.h> #include <drm/drm_managed.h> +#include <drm/drm_module.h> #include <drm/drm_probe_helper.h> #include "tidss_dispc.h" #include "tidss_drv.h" #include "tidss_kms.h" #include "tidss_irq.h" +#include "tidss_oldi.h" /* Power management */ @@ -31,20 +33,18 @@ int tidss_runtime_get(struct tidss_device *tidss) { int r; - dev_dbg(tidss->dev, "%s\n", __func__); - - r = pm_runtime_get_sync(tidss->dev); + r = pm_runtime_resume_and_get(tidss->dev); WARN_ON(r < 0); - return r < 0 ? r : 0; + return r; } void tidss_runtime_put(struct tidss_device *tidss) { int r; - dev_dbg(tidss->dev, "%s\n", __func__); + pm_runtime_mark_last_busy(tidss->dev); - r = pm_runtime_put_sync(tidss->dev); + r = pm_runtime_put_autosuspend(tidss->dev); WARN_ON(r < 0); } @@ -52,8 +52,6 @@ static int __maybe_unused tidss_pm_runtime_suspend(struct device *dev) { struct tidss_device *tidss = dev_get_drvdata(dev); - dev_dbg(dev, "%s\n", __func__); - return dispc_runtime_suspend(tidss->dispc); } @@ -62,8 +60,6 @@ static int __maybe_unused tidss_pm_runtime_resume(struct device *dev) struct tidss_device *tidss = dev_get_drvdata(dev); int r; - dev_dbg(dev, "%s\n", __func__); - r = dispc_runtime_resume(tidss->dispc); if (r) return r; @@ -75,8 +71,6 @@ static int __maybe_unused tidss_suspend(struct device *dev) { struct tidss_device *tidss = dev_get_drvdata(dev); - dev_dbg(dev, "%s\n", __func__); - return drm_mode_config_helper_suspend(&tidss->ddev); } @@ -84,21 +78,14 @@ static int __maybe_unused tidss_resume(struct device *dev) { struct tidss_device *tidss = dev_get_drvdata(dev); - dev_dbg(dev, "%s\n", __func__); - return drm_mode_config_helper_resume(&tidss->ddev); } -#ifdef CONFIG_PM - -static const struct dev_pm_ops tidss_pm_ops = { - .runtime_suspend = tidss_pm_runtime_suspend, - .runtime_resume = tidss_pm_runtime_resume, +static __maybe_unused const struct dev_pm_ops tidss_pm_ops = { SET_SYSTEM_SLEEP_PM_OPS(tidss_suspend, tidss_resume) + SET_RUNTIME_PM_OPS(tidss_pm_runtime_suspend, tidss_pm_runtime_resume, NULL) }; -#endif /* CONFIG_PM */ - /* DRM device Information */ static void tidss_release(struct drm_device *ddev) @@ -106,23 +93,18 @@ static void tidss_release(struct drm_device *ddev) drm_kms_helper_poll_fini(ddev); } -DEFINE_DRM_GEM_CMA_FOPS(tidss_fops); +DEFINE_DRM_GEM_DMA_FOPS(tidss_fops); static const struct drm_driver tidss_driver = { .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC, .fops = &tidss_fops, .release = tidss_release, - DRM_GEM_CMA_DRIVER_OPS_VMAP, + DRM_GEM_DMA_DRIVER_OPS_VMAP, + DRM_FBDEV_DMA_DRIVER_OPS, .name = "tidss", .desc = "TI Keystone DSS", - .date = "20180215", .major = 1, .minor = 0, - - .irq_preinstall = tidss_irq_preinstall, - .irq_postinstall = tidss_irq_postinstall, - .irq_handler = tidss_irq_handler, - .irq_uninstall = tidss_irq_uninstall, }; static int tidss_probe(struct platform_device *pdev) @@ -133,8 +115,6 @@ static int tidss_probe(struct platform_device *pdev) int ret; int irq; - dev_dbg(dev, "%s\n", __func__); - tidss = devm_drm_dev_alloc(&pdev->dev, &tidss_driver, struct tidss_device, ddev); if (IS_ERR(tidss)) @@ -147,14 +127,23 @@ static int tidss_probe(struct platform_device *pdev) platform_set_drvdata(pdev, tidss); + spin_lock_init(&tidss->irq_lock); + ret = dispc_init(tidss); if (ret) { dev_err(dev, "failed to initialize dispc: %d\n", ret); return ret; } + ret = tidss_oldi_init(tidss); + if (ret) + return dev_err_probe(dev, ret, "failed to init OLDI\n"); + pm_runtime_enable(dev); + pm_runtime_set_autosuspend_delay(dev, 1000); + pm_runtime_use_autosuspend(dev); + #ifndef CONFIG_PM /* If we don't have PM, we need to call resume manually */ dispc_runtime_resume(tidss->dispc); @@ -172,10 +161,11 @@ static int tidss_probe(struct platform_device *pdev) ret = irq; goto err_runtime_suspend; } + tidss->irq = irq; - ret = drm_irq_install(ddev, irq); + ret = tidss_irq_install(ddev, irq); if (ret) { - dev_err(dev, "drm_irq_install failed: %d\n", ret); + dev_err(dev, "tidss_irq_install failed: %d\n", ret); goto err_runtime_suspend; } @@ -189,50 +179,60 @@ static int tidss_probe(struct platform_device *pdev) goto err_irq_uninstall; } - drm_fbdev_generic_setup(ddev, 32); + /* Remove possible early fb before setting up the fbdev */ + ret = aperture_remove_all_conflicting_devices(tidss_driver.name); + if (ret) + goto err_drm_dev_unreg; + + drm_client_setup(ddev, NULL); dev_dbg(dev, "%s done\n", __func__); return 0; +err_drm_dev_unreg: + drm_dev_unregister(ddev); + err_irq_uninstall: - drm_irq_uninstall(ddev); + tidss_irq_uninstall(ddev); err_runtime_suspend: #ifndef CONFIG_PM dispc_runtime_suspend(tidss->dispc); #endif + pm_runtime_dont_use_autosuspend(dev); pm_runtime_disable(dev); + tidss_oldi_deinit(tidss); + return ret; } -static int tidss_remove(struct platform_device *pdev) +static void tidss_remove(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct tidss_device *tidss = platform_get_drvdata(pdev); struct drm_device *ddev = &tidss->ddev; - dev_dbg(dev, "%s\n", __func__); - drm_dev_unregister(ddev); drm_atomic_helper_shutdown(ddev); - drm_irq_uninstall(ddev); + tidss_irq_uninstall(ddev); #ifndef CONFIG_PM /* If we don't have PM, we need to call suspend manually */ dispc_runtime_suspend(tidss->dispc); #endif + pm_runtime_dont_use_autosuspend(dev); pm_runtime_disable(dev); + tidss_oldi_deinit(tidss); + /* devm allocated dispc goes away with the dev so mark it NULL */ dispc_remove(tidss); dev_dbg(dev, "%s done\n", __func__); - - return 0; } static void tidss_shutdown(struct platform_device *pdev) @@ -242,6 +242,9 @@ static void tidss_shutdown(struct platform_device *pdev) static const struct of_device_id tidss_of_table[] = { { .compatible = "ti,k2g-dss", .data = &dispc_k2g_feats, }, + { .compatible = "ti,am625-dss", .data = &dispc_am625_feats, }, + { .compatible = "ti,am62a7-dss", .data = &dispc_am62a7_feats, }, + { .compatible = "ti,am62l-dss", .data = &dispc_am62l_feats, }, { .compatible = "ti,am65x-dss", .data = &dispc_am65x_feats, }, { .compatible = "ti,j721e-dss", .data = &dispc_j721e_feats, }, { } @@ -255,15 +258,13 @@ static struct platform_driver tidss_platform_driver = { .shutdown = tidss_shutdown, .driver = { .name = "tidss", -#ifdef CONFIG_PM - .pm = &tidss_pm_ops, -#endif + .pm = pm_ptr(&tidss_pm_ops), .of_match_table = tidss_of_table, .suppress_bind_attrs = true, }, }; -module_platform_driver(tidss_platform_driver); +drm_module_platform_driver(tidss_platform_driver); MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@ti.com>"); MODULE_DESCRIPTION("TI Keystone DSS Driver"); |
