126bd43a7Sjames qian wang (Arm Technology China) // SPDX-License-Identifier: GPL-2.0
226bd43a7Sjames qian wang (Arm Technology China) /*
326bd43a7Sjames qian wang (Arm Technology China) * (C) COPYRIGHT 2018 ARM Limited. All rights reserved.
426bd43a7Sjames qian wang (Arm Technology China) * Author: James.Qian.Wang <james.qian.wang@arm.com>
526bd43a7Sjames qian wang (Arm Technology China) *
626bd43a7Sjames qian wang (Arm Technology China) */
726bd43a7Sjames qian wang (Arm Technology China) #include <linux/module.h>
826bd43a7Sjames qian wang (Arm Technology China) #include <linux/kernel.h>
9fb28b3f0SThomas Zimmermann #include <linux/of.h>
1026bd43a7Sjames qian wang (Arm Technology China) #include <linux/platform_device.h>
112ebb6701SLowry Li (Arm Technology China) #include <linux/pm_runtime.h>
128ab59da2SThomas Zimmermann #include <drm/drm_fbdev_generic.h>
13e0f8cd23SJavier Martinez Canillas #include <drm/drm_module.h>
1426bd43a7Sjames qian wang (Arm Technology China) #include <drm/drm_of.h>
1526bd43a7Sjames qian wang (Arm Technology China) #include "komeda_dev.h"
1661f1c4a8Sjames qian wang (Arm Technology China) #include "komeda_kms.h"
1726bd43a7Sjames qian wang (Arm Technology China)
1826bd43a7Sjames qian wang (Arm Technology China) struct komeda_drv {
1926bd43a7Sjames qian wang (Arm Technology China) struct komeda_dev *mdev;
2061f1c4a8Sjames qian wang (Arm Technology China) struct komeda_kms_dev *kms;
2126bd43a7Sjames qian wang (Arm Technology China) };
2226bd43a7Sjames qian wang (Arm Technology China)
dev_to_mdev(struct device * dev)2355223394Sjames qian wang (Arm Technology China) struct komeda_dev *dev_to_mdev(struct device *dev)
2455223394Sjames qian wang (Arm Technology China) {
2555223394Sjames qian wang (Arm Technology China) struct komeda_drv *mdrv = dev_get_drvdata(dev);
2655223394Sjames qian wang (Arm Technology China)
2755223394Sjames qian wang (Arm Technology China) return mdrv ? mdrv->mdev : NULL;
2855223394Sjames qian wang (Arm Technology China) }
2955223394Sjames qian wang (Arm Technology China)
komeda_platform_remove(struct platform_device * pdev)30*4cfe5cc0SFaiz Abbas static void komeda_platform_remove(struct platform_device *pdev)
3126bd43a7Sjames qian wang (Arm Technology China) {
32*4cfe5cc0SFaiz Abbas struct device *dev = &pdev->dev;
3326bd43a7Sjames qian wang (Arm Technology China) struct komeda_drv *mdrv = dev_get_drvdata(dev);
3426bd43a7Sjames qian wang (Arm Technology China)
3561f1c4a8Sjames qian wang (Arm Technology China) komeda_kms_detach(mdrv->kms);
36efb46508Sjames qian wang (Arm Technology China)
37efb46508Sjames qian wang (Arm Technology China) if (pm_runtime_enabled(dev))
38efb46508Sjames qian wang (Arm Technology China) pm_runtime_disable(dev);
39efb46508Sjames qian wang (Arm Technology China) else
40efb46508Sjames qian wang (Arm Technology China) komeda_dev_suspend(mdrv->mdev);
41efb46508Sjames qian wang (Arm Technology China)
4226bd43a7Sjames qian wang (Arm Technology China) komeda_dev_destroy(mdrv->mdev);
4326bd43a7Sjames qian wang (Arm Technology China)
4426bd43a7Sjames qian wang (Arm Technology China) dev_set_drvdata(dev, NULL);
4526bd43a7Sjames qian wang (Arm Technology China) devm_kfree(dev, mdrv);
4626bd43a7Sjames qian wang (Arm Technology China) }
4726bd43a7Sjames qian wang (Arm Technology China)
komeda_platform_probe(struct platform_device * pdev)48*4cfe5cc0SFaiz Abbas static int komeda_platform_probe(struct platform_device *pdev)
4926bd43a7Sjames qian wang (Arm Technology China) {
50*4cfe5cc0SFaiz Abbas struct device *dev = &pdev->dev;
5126bd43a7Sjames qian wang (Arm Technology China) struct komeda_drv *mdrv;
5226bd43a7Sjames qian wang (Arm Technology China) int err;
5326bd43a7Sjames qian wang (Arm Technology China)
5426bd43a7Sjames qian wang (Arm Technology China) mdrv = devm_kzalloc(dev, sizeof(*mdrv), GFP_KERNEL);
5526bd43a7Sjames qian wang (Arm Technology China) if (!mdrv)
5626bd43a7Sjames qian wang (Arm Technology China) return -ENOMEM;
5726bd43a7Sjames qian wang (Arm Technology China)
5826bd43a7Sjames qian wang (Arm Technology China) mdrv->mdev = komeda_dev_create(dev);
5926bd43a7Sjames qian wang (Arm Technology China) if (IS_ERR(mdrv->mdev)) {
6026bd43a7Sjames qian wang (Arm Technology China) err = PTR_ERR(mdrv->mdev);
6126bd43a7Sjames qian wang (Arm Technology China) goto free_mdrv;
6226bd43a7Sjames qian wang (Arm Technology China) }
6326bd43a7Sjames qian wang (Arm Technology China)
64efb46508Sjames qian wang (Arm Technology China) pm_runtime_enable(dev);
65efb46508Sjames qian wang (Arm Technology China) if (!pm_runtime_enabled(dev))
66efb46508Sjames qian wang (Arm Technology China) komeda_dev_resume(mdrv->mdev);
67efb46508Sjames qian wang (Arm Technology China)
6861f1c4a8Sjames qian wang (Arm Technology China) mdrv->kms = komeda_kms_attach(mdrv->mdev);
6961f1c4a8Sjames qian wang (Arm Technology China) if (IS_ERR(mdrv->kms)) {
7061f1c4a8Sjames qian wang (Arm Technology China) err = PTR_ERR(mdrv->kms);
7161f1c4a8Sjames qian wang (Arm Technology China) goto destroy_mdev;
7261f1c4a8Sjames qian wang (Arm Technology China) }
7361f1c4a8Sjames qian wang (Arm Technology China)
7426bd43a7Sjames qian wang (Arm Technology China) dev_set_drvdata(dev, mdrv);
75000a2f04SCarsten Haitzler drm_fbdev_generic_setup(&mdrv->kms->base, 32);
7626bd43a7Sjames qian wang (Arm Technology China)
7726bd43a7Sjames qian wang (Arm Technology China) return 0;
7826bd43a7Sjames qian wang (Arm Technology China)
7961f1c4a8Sjames qian wang (Arm Technology China) destroy_mdev:
80efb46508Sjames qian wang (Arm Technology China) if (pm_runtime_enabled(dev))
81efb46508Sjames qian wang (Arm Technology China) pm_runtime_disable(dev);
82efb46508Sjames qian wang (Arm Technology China) else
83efb46508Sjames qian wang (Arm Technology China) komeda_dev_suspend(mdrv->mdev);
84efb46508Sjames qian wang (Arm Technology China)
8561f1c4a8Sjames qian wang (Arm Technology China) komeda_dev_destroy(mdrv->mdev);
8661f1c4a8Sjames qian wang (Arm Technology China)
8726bd43a7Sjames qian wang (Arm Technology China) free_mdrv:
8826bd43a7Sjames qian wang (Arm Technology China) devm_kfree(dev, mdrv);
8926bd43a7Sjames qian wang (Arm Technology China) return err;
9026bd43a7Sjames qian wang (Arm Technology China) }
9126bd43a7Sjames qian wang (Arm Technology China)
9215e9122dSjames qian wang (Arm Technology China) static const struct of_device_id komeda_of_match[] = {
93b25bc78fSjames qian wang (Arm Technology China) { .compatible = "arm,mali-d71", .data = d71_identify, },
9417cfcb68Sjames qian wang (Arm Technology China) { .compatible = "arm,mali-d32", .data = d71_identify, },
9526bd43a7Sjames qian wang (Arm Technology China) {},
9626bd43a7Sjames qian wang (Arm Technology China) };
9726bd43a7Sjames qian wang (Arm Technology China)
9826bd43a7Sjames qian wang (Arm Technology China) MODULE_DEVICE_TABLE(of, komeda_of_match);
9926bd43a7Sjames qian wang (Arm Technology China)
komeda_rt_pm_suspend(struct device * dev)1009803aac7SArnd Bergmann static int __maybe_unused komeda_rt_pm_suspend(struct device *dev)
101efb46508Sjames qian wang (Arm Technology China) {
102efb46508Sjames qian wang (Arm Technology China) struct komeda_drv *mdrv = dev_get_drvdata(dev);
103efb46508Sjames qian wang (Arm Technology China)
104efb46508Sjames qian wang (Arm Technology China) return komeda_dev_suspend(mdrv->mdev);
105efb46508Sjames qian wang (Arm Technology China) }
106efb46508Sjames qian wang (Arm Technology China)
komeda_rt_pm_resume(struct device * dev)1079803aac7SArnd Bergmann static int __maybe_unused komeda_rt_pm_resume(struct device *dev)
108efb46508Sjames qian wang (Arm Technology China) {
109efb46508Sjames qian wang (Arm Technology China) struct komeda_drv *mdrv = dev_get_drvdata(dev);
110efb46508Sjames qian wang (Arm Technology China)
111efb46508Sjames qian wang (Arm Technology China) return komeda_dev_resume(mdrv->mdev);
112efb46508Sjames qian wang (Arm Technology China) }
113efb46508Sjames qian wang (Arm Technology China)
komeda_pm_suspend(struct device * dev)1142ebb6701SLowry Li (Arm Technology China) static int __maybe_unused komeda_pm_suspend(struct device *dev)
1152ebb6701SLowry Li (Arm Technology China) {
1162ebb6701SLowry Li (Arm Technology China) struct komeda_drv *mdrv = dev_get_drvdata(dev);
1172ebb6701SLowry Li (Arm Technology China) int res;
1182ebb6701SLowry Li (Arm Technology China)
119efb46508Sjames qian wang (Arm Technology China) res = drm_mode_config_helper_suspend(&mdrv->kms->base);
1202ebb6701SLowry Li (Arm Technology China)
121efb46508Sjames qian wang (Arm Technology China) if (!pm_runtime_status_suspended(dev))
1222ebb6701SLowry Li (Arm Technology China) komeda_dev_suspend(mdrv->mdev);
1232ebb6701SLowry Li (Arm Technology China)
1242ebb6701SLowry Li (Arm Technology China) return res;
1252ebb6701SLowry Li (Arm Technology China) }
1262ebb6701SLowry Li (Arm Technology China)
komeda_pm_resume(struct device * dev)1272ebb6701SLowry Li (Arm Technology China) static int __maybe_unused komeda_pm_resume(struct device *dev)
1282ebb6701SLowry Li (Arm Technology China) {
1292ebb6701SLowry Li (Arm Technology China) struct komeda_drv *mdrv = dev_get_drvdata(dev);
1302ebb6701SLowry Li (Arm Technology China)
131efb46508Sjames qian wang (Arm Technology China) if (!pm_runtime_status_suspended(dev))
1322ebb6701SLowry Li (Arm Technology China) komeda_dev_resume(mdrv->mdev);
1332ebb6701SLowry Li (Arm Technology China)
134efb46508Sjames qian wang (Arm Technology China) return drm_mode_config_helper_resume(&mdrv->kms->base);
1352ebb6701SLowry Li (Arm Technology China) }
1362ebb6701SLowry Li (Arm Technology China)
1372ebb6701SLowry Li (Arm Technology China) static const struct dev_pm_ops komeda_pm_ops = {
1382ebb6701SLowry Li (Arm Technology China) SET_SYSTEM_SLEEP_PM_OPS(komeda_pm_suspend, komeda_pm_resume)
139efb46508Sjames qian wang (Arm Technology China) SET_RUNTIME_PM_OPS(komeda_rt_pm_suspend, komeda_rt_pm_resume, NULL)
1402ebb6701SLowry Li (Arm Technology China) };
1412ebb6701SLowry Li (Arm Technology China)
14226bd43a7Sjames qian wang (Arm Technology China) static struct platform_driver komeda_platform_driver = {
14326bd43a7Sjames qian wang (Arm Technology China) .probe = komeda_platform_probe,
1441bf3d76aSUwe Kleine-König .remove_new = komeda_platform_remove,
14526bd43a7Sjames qian wang (Arm Technology China) .driver = {
14626bd43a7Sjames qian wang (Arm Technology China) .name = "komeda",
14726bd43a7Sjames qian wang (Arm Technology China) .of_match_table = komeda_of_match,
1482ebb6701SLowry Li (Arm Technology China) .pm = &komeda_pm_ops,
14926bd43a7Sjames qian wang (Arm Technology China) },
15026bd43a7Sjames qian wang (Arm Technology China) };
15126bd43a7Sjames qian wang (Arm Technology China)
152e0f8cd23SJavier Martinez Canillas drm_module_platform_driver(komeda_platform_driver);
15326bd43a7Sjames qian wang (Arm Technology China)
15426bd43a7Sjames qian wang (Arm Technology China) MODULE_AUTHOR("James.Qian.Wang <james.qian.wang@arm.com>");
15526bd43a7Sjames qian wang (Arm Technology China) MODULE_DESCRIPTION("Komeda KMS driver");
15626bd43a7Sjames qian wang (Arm Technology China) MODULE_LICENSE("GPL v2");
157