diff options
Diffstat (limited to 'drivers/gpu/drm/arm/display/komeda/komeda_drv.c')
-rw-r--r-- | drivers/gpu/drm/arm/display/komeda/komeda_drv.c | 156 |
1 files changed, 156 insertions, 0 deletions
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_drv.c b/drivers/gpu/drm/arm/display/komeda/komeda_drv.c new file mode 100644 index 0000000000..cb2a2be24c --- /dev/null +++ b/drivers/gpu/drm/arm/display/komeda/komeda_drv.c @@ -0,0 +1,156 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * (C) COPYRIGHT 2018 ARM Limited. All rights reserved. + * Author: James.Qian.Wang <james.qian.wang@arm.com> + * + */ +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/of.h> +#include <linux/platform_device.h> +#include <linux/pm_runtime.h> +#include <drm/drm_fbdev_generic.h> +#include <drm/drm_module.h> +#include <drm/drm_of.h> +#include "komeda_dev.h" +#include "komeda_kms.h" + +struct komeda_drv { + struct komeda_dev *mdev; + struct komeda_kms_dev *kms; +}; + +struct komeda_dev *dev_to_mdev(struct device *dev) +{ + struct komeda_drv *mdrv = dev_get_drvdata(dev); + + return mdrv ? mdrv->mdev : NULL; +} + +static void komeda_platform_remove(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct komeda_drv *mdrv = dev_get_drvdata(dev); + + komeda_kms_detach(mdrv->kms); + + if (pm_runtime_enabled(dev)) + pm_runtime_disable(dev); + else + komeda_dev_suspend(mdrv->mdev); + + komeda_dev_destroy(mdrv->mdev); + + dev_set_drvdata(dev, NULL); + devm_kfree(dev, mdrv); +} + +static int komeda_platform_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct komeda_drv *mdrv; + int err; + + mdrv = devm_kzalloc(dev, sizeof(*mdrv), GFP_KERNEL); + if (!mdrv) + return -ENOMEM; + + mdrv->mdev = komeda_dev_create(dev); + if (IS_ERR(mdrv->mdev)) { + err = PTR_ERR(mdrv->mdev); + goto free_mdrv; + } + + pm_runtime_enable(dev); + if (!pm_runtime_enabled(dev)) + komeda_dev_resume(mdrv->mdev); + + mdrv->kms = komeda_kms_attach(mdrv->mdev); + if (IS_ERR(mdrv->kms)) { + err = PTR_ERR(mdrv->kms); + goto destroy_mdev; + } + + dev_set_drvdata(dev, mdrv); + drm_fbdev_generic_setup(&mdrv->kms->base, 32); + + return 0; + +destroy_mdev: + if (pm_runtime_enabled(dev)) + pm_runtime_disable(dev); + else + komeda_dev_suspend(mdrv->mdev); + + komeda_dev_destroy(mdrv->mdev); + +free_mdrv: + devm_kfree(dev, mdrv); + return err; +} + +static const struct of_device_id komeda_of_match[] = { + { .compatible = "arm,mali-d71", .data = d71_identify, }, + { .compatible = "arm,mali-d32", .data = d71_identify, }, + {}, +}; + +MODULE_DEVICE_TABLE(of, komeda_of_match); + +static int __maybe_unused komeda_rt_pm_suspend(struct device *dev) +{ + struct komeda_drv *mdrv = dev_get_drvdata(dev); + + return komeda_dev_suspend(mdrv->mdev); +} + +static int __maybe_unused komeda_rt_pm_resume(struct device *dev) +{ + struct komeda_drv *mdrv = dev_get_drvdata(dev); + + return komeda_dev_resume(mdrv->mdev); +} + +static int __maybe_unused komeda_pm_suspend(struct device *dev) +{ + struct komeda_drv *mdrv = dev_get_drvdata(dev); + int res; + + res = drm_mode_config_helper_suspend(&mdrv->kms->base); + + if (!pm_runtime_status_suspended(dev)) + komeda_dev_suspend(mdrv->mdev); + + return res; +} + +static int __maybe_unused komeda_pm_resume(struct device *dev) +{ + struct komeda_drv *mdrv = dev_get_drvdata(dev); + + if (!pm_runtime_status_suspended(dev)) + komeda_dev_resume(mdrv->mdev); + + return drm_mode_config_helper_resume(&mdrv->kms->base); +} + +static const struct dev_pm_ops komeda_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(komeda_pm_suspend, komeda_pm_resume) + SET_RUNTIME_PM_OPS(komeda_rt_pm_suspend, komeda_rt_pm_resume, NULL) +}; + +static struct platform_driver komeda_platform_driver = { + .probe = komeda_platform_probe, + .remove_new = komeda_platform_remove, + .driver = { + .name = "komeda", + .of_match_table = komeda_of_match, + .pm = &komeda_pm_ops, + }, +}; + +drm_module_platform_driver(komeda_platform_driver); + +MODULE_AUTHOR("James.Qian.Wang <james.qian.wang@arm.com>"); +MODULE_DESCRIPTION("Komeda KMS driver"); +MODULE_LICENSE("GPL v2"); |