xref: /linux/drivers/gpu/drm/arm/display/komeda/komeda_drv.c (revision a1ff5a7d78a036d6c2178ee5acd6ba4946243800)
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>
12386030e5SThomas Zimmermann #include <drm/drm_fbdev_dma.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)304cfe5cc0SFaiz Abbas static void komeda_platform_remove(struct platform_device *pdev)
3126bd43a7Sjames qian wang (Arm Technology China) {
324cfe5cc0SFaiz 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_shutdown(struct platform_device * pdev)48ce3d99c8SDouglas Anderson static void komeda_platform_shutdown(struct platform_device *pdev)
49ce3d99c8SDouglas Anderson {
50ce3d99c8SDouglas Anderson 	struct device *dev = &pdev->dev;
51ce3d99c8SDouglas Anderson 	struct komeda_drv *mdrv = dev_get_drvdata(dev);
52ce3d99c8SDouglas Anderson 
53ce3d99c8SDouglas Anderson 	komeda_kms_shutdown(mdrv->kms);
54ce3d99c8SDouglas Anderson }
55ce3d99c8SDouglas Anderson 
komeda_platform_probe(struct platform_device * pdev)564cfe5cc0SFaiz Abbas static int komeda_platform_probe(struct platform_device *pdev)
5726bd43a7Sjames qian wang (Arm Technology China) {
584cfe5cc0SFaiz Abbas 	struct device *dev = &pdev->dev;
5926bd43a7Sjames qian wang (Arm Technology China) 	struct komeda_drv *mdrv;
6026bd43a7Sjames qian wang (Arm Technology China) 	int err;
6126bd43a7Sjames qian wang (Arm Technology China) 
62*a918dcfeSAmjad Ouled-Ameur 	err = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(40));
63*a918dcfeSAmjad Ouled-Ameur 	if (err)
64*a918dcfeSAmjad Ouled-Ameur 		return dev_err_probe(dev, err, "DMA mask error\n");
65*a918dcfeSAmjad Ouled-Ameur 
6626bd43a7Sjames qian wang (Arm Technology China) 	mdrv = devm_kzalloc(dev, sizeof(*mdrv), GFP_KERNEL);
6726bd43a7Sjames qian wang (Arm Technology China) 	if (!mdrv)
6826bd43a7Sjames qian wang (Arm Technology China) 		return -ENOMEM;
6926bd43a7Sjames qian wang (Arm Technology China) 
7026bd43a7Sjames qian wang (Arm Technology China) 	mdrv->mdev = komeda_dev_create(dev);
7126bd43a7Sjames qian wang (Arm Technology China) 	if (IS_ERR(mdrv->mdev)) {
7226bd43a7Sjames qian wang (Arm Technology China) 		err = PTR_ERR(mdrv->mdev);
7326bd43a7Sjames qian wang (Arm Technology China) 		goto free_mdrv;
7426bd43a7Sjames qian wang (Arm Technology China) 	}
7526bd43a7Sjames qian wang (Arm Technology China) 
76efb46508Sjames qian wang (Arm Technology China) 	pm_runtime_enable(dev);
77efb46508Sjames qian wang (Arm Technology China) 	if (!pm_runtime_enabled(dev))
78efb46508Sjames qian wang (Arm Technology China) 		komeda_dev_resume(mdrv->mdev);
79efb46508Sjames qian wang (Arm Technology China) 
8061f1c4a8Sjames qian wang (Arm Technology China) 	mdrv->kms = komeda_kms_attach(mdrv->mdev);
8161f1c4a8Sjames qian wang (Arm Technology China) 	if (IS_ERR(mdrv->kms)) {
8261f1c4a8Sjames qian wang (Arm Technology China) 		err = PTR_ERR(mdrv->kms);
8361f1c4a8Sjames qian wang (Arm Technology China) 		goto destroy_mdev;
8461f1c4a8Sjames qian wang (Arm Technology China) 	}
8561f1c4a8Sjames qian wang (Arm Technology China) 
8626bd43a7Sjames qian wang (Arm Technology China) 	dev_set_drvdata(dev, mdrv);
87386030e5SThomas Zimmermann 	drm_fbdev_dma_setup(&mdrv->kms->base, 32);
8826bd43a7Sjames qian wang (Arm Technology China) 
8926bd43a7Sjames qian wang (Arm Technology China) 	return 0;
9026bd43a7Sjames qian wang (Arm Technology China) 
9161f1c4a8Sjames qian wang (Arm Technology China) destroy_mdev:
92efb46508Sjames qian wang (Arm Technology China) 	if (pm_runtime_enabled(dev))
93efb46508Sjames qian wang (Arm Technology China) 		pm_runtime_disable(dev);
94efb46508Sjames qian wang (Arm Technology China) 	else
95efb46508Sjames qian wang (Arm Technology China) 		komeda_dev_suspend(mdrv->mdev);
96efb46508Sjames qian wang (Arm Technology China) 
9761f1c4a8Sjames qian wang (Arm Technology China) 	komeda_dev_destroy(mdrv->mdev);
9861f1c4a8Sjames qian wang (Arm Technology China) 
9926bd43a7Sjames qian wang (Arm Technology China) free_mdrv:
10026bd43a7Sjames qian wang (Arm Technology China) 	devm_kfree(dev, mdrv);
10126bd43a7Sjames qian wang (Arm Technology China) 	return err;
10226bd43a7Sjames qian wang (Arm Technology China) }
10326bd43a7Sjames qian wang (Arm Technology China) 
10415e9122dSjames qian wang (Arm Technology China) static const struct of_device_id komeda_of_match[] = {
105b25bc78fSjames qian wang (Arm Technology China) 	{ .compatible = "arm,mali-d71", .data = d71_identify, },
10617cfcb68Sjames qian wang (Arm Technology China) 	{ .compatible = "arm,mali-d32", .data = d71_identify, },
10726bd43a7Sjames qian wang (Arm Technology China) 	{},
10826bd43a7Sjames qian wang (Arm Technology China) };
10926bd43a7Sjames qian wang (Arm Technology China) 
11026bd43a7Sjames qian wang (Arm Technology China) MODULE_DEVICE_TABLE(of, komeda_of_match);
11126bd43a7Sjames qian wang (Arm Technology China) 
komeda_rt_pm_suspend(struct device * dev)1129803aac7SArnd Bergmann static int __maybe_unused komeda_rt_pm_suspend(struct device *dev)
113efb46508Sjames qian wang (Arm Technology China) {
114efb46508Sjames qian wang (Arm Technology China) 	struct komeda_drv *mdrv = dev_get_drvdata(dev);
115efb46508Sjames qian wang (Arm Technology China) 
116efb46508Sjames qian wang (Arm Technology China) 	return komeda_dev_suspend(mdrv->mdev);
117efb46508Sjames qian wang (Arm Technology China) }
118efb46508Sjames qian wang (Arm Technology China) 
komeda_rt_pm_resume(struct device * dev)1199803aac7SArnd Bergmann static int __maybe_unused komeda_rt_pm_resume(struct device *dev)
120efb46508Sjames qian wang (Arm Technology China) {
121efb46508Sjames qian wang (Arm Technology China) 	struct komeda_drv *mdrv = dev_get_drvdata(dev);
122efb46508Sjames qian wang (Arm Technology China) 
123efb46508Sjames qian wang (Arm Technology China) 	return komeda_dev_resume(mdrv->mdev);
124efb46508Sjames qian wang (Arm Technology China) }
125efb46508Sjames qian wang (Arm Technology China) 
komeda_pm_suspend(struct device * dev)1262ebb6701SLowry Li (Arm Technology China) static int __maybe_unused komeda_pm_suspend(struct device *dev)
1272ebb6701SLowry Li (Arm Technology China) {
1282ebb6701SLowry Li (Arm Technology China) 	struct komeda_drv *mdrv = dev_get_drvdata(dev);
1292ebb6701SLowry Li (Arm Technology China) 	int res;
1302ebb6701SLowry Li (Arm Technology China) 
131efb46508Sjames qian wang (Arm Technology China) 	res = drm_mode_config_helper_suspend(&mdrv->kms->base);
1322ebb6701SLowry Li (Arm Technology China) 
133efb46508Sjames qian wang (Arm Technology China) 	if (!pm_runtime_status_suspended(dev))
1342ebb6701SLowry Li (Arm Technology China) 		komeda_dev_suspend(mdrv->mdev);
1352ebb6701SLowry Li (Arm Technology China) 
1362ebb6701SLowry Li (Arm Technology China) 	return res;
1372ebb6701SLowry Li (Arm Technology China) }
1382ebb6701SLowry Li (Arm Technology China) 
komeda_pm_resume(struct device * dev)1392ebb6701SLowry Li (Arm Technology China) static int __maybe_unused komeda_pm_resume(struct device *dev)
1402ebb6701SLowry Li (Arm Technology China) {
1412ebb6701SLowry Li (Arm Technology China) 	struct komeda_drv *mdrv = dev_get_drvdata(dev);
1422ebb6701SLowry Li (Arm Technology China) 
143efb46508Sjames qian wang (Arm Technology China) 	if (!pm_runtime_status_suspended(dev))
1442ebb6701SLowry Li (Arm Technology China) 		komeda_dev_resume(mdrv->mdev);
1452ebb6701SLowry Li (Arm Technology China) 
146efb46508Sjames qian wang (Arm Technology China) 	return drm_mode_config_helper_resume(&mdrv->kms->base);
1472ebb6701SLowry Li (Arm Technology China) }
1482ebb6701SLowry Li (Arm Technology China) 
1492ebb6701SLowry Li (Arm Technology China) static const struct dev_pm_ops komeda_pm_ops = {
1502ebb6701SLowry Li (Arm Technology China) 	SET_SYSTEM_SLEEP_PM_OPS(komeda_pm_suspend, komeda_pm_resume)
151efb46508Sjames qian wang (Arm Technology China) 	SET_RUNTIME_PM_OPS(komeda_rt_pm_suspend, komeda_rt_pm_resume, NULL)
1522ebb6701SLowry Li (Arm Technology China) };
1532ebb6701SLowry Li (Arm Technology China) 
15426bd43a7Sjames qian wang (Arm Technology China) static struct platform_driver komeda_platform_driver = {
15526bd43a7Sjames qian wang (Arm Technology China) 	.probe	= komeda_platform_probe,
1561bf3d76aSUwe Kleine-König 	.remove_new = komeda_platform_remove,
157ce3d99c8SDouglas Anderson 	.shutdown = komeda_platform_shutdown,
15826bd43a7Sjames qian wang (Arm Technology China) 	.driver	= {
15926bd43a7Sjames qian wang (Arm Technology China) 		.name = "komeda",
16026bd43a7Sjames qian wang (Arm Technology China) 		.of_match_table	= komeda_of_match,
1612ebb6701SLowry Li (Arm Technology China) 		.pm = &komeda_pm_ops,
16226bd43a7Sjames qian wang (Arm Technology China) 	},
16326bd43a7Sjames qian wang (Arm Technology China) };
16426bd43a7Sjames qian wang (Arm Technology China) 
165e0f8cd23SJavier Martinez Canillas drm_module_platform_driver(komeda_platform_driver);
16626bd43a7Sjames qian wang (Arm Technology China) 
16726bd43a7Sjames qian wang (Arm Technology China) MODULE_AUTHOR("James.Qian.Wang <james.qian.wang@arm.com>");
16826bd43a7Sjames qian wang (Arm Technology China) MODULE_DESCRIPTION("Komeda KMS driver");
16926bd43a7Sjames qian wang (Arm Technology China) MODULE_LICENSE("GPL v2");
170