170 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * (C) COPYRIGHT 2018 ARM Limited. All rights reserved.4 * Author: James.Qian.Wang <james.qian.wang@arm.com>5 *6 */7#include <linux/module.h>8#include <linux/kernel.h>9#include <linux/of.h>10#include <linux/platform_device.h>11#include <linux/pm_runtime.h>12#include <drm/drm_fbdev_dma.h>13#include <drm/drm_module.h>14#include <drm/drm_of.h>15#include "komeda_dev.h"16#include "komeda_kms.h"17 18struct komeda_drv {19 struct komeda_dev *mdev;20 struct komeda_kms_dev *kms;21};22 23struct komeda_dev *dev_to_mdev(struct device *dev)24{25 struct komeda_drv *mdrv = dev_get_drvdata(dev);26 27 return mdrv ? mdrv->mdev : NULL;28}29 30static void komeda_platform_remove(struct platform_device *pdev)31{32 struct device *dev = &pdev->dev;33 struct komeda_drv *mdrv = dev_get_drvdata(dev);34 35 komeda_kms_detach(mdrv->kms);36 37 if (pm_runtime_enabled(dev))38 pm_runtime_disable(dev);39 else40 komeda_dev_suspend(mdrv->mdev);41 42 komeda_dev_destroy(mdrv->mdev);43 44 dev_set_drvdata(dev, NULL);45 devm_kfree(dev, mdrv);46}47 48static void komeda_platform_shutdown(struct platform_device *pdev)49{50 struct device *dev = &pdev->dev;51 struct komeda_drv *mdrv = dev_get_drvdata(dev);52 53 komeda_kms_shutdown(mdrv->kms);54}55 56static int komeda_platform_probe(struct platform_device *pdev)57{58 struct device *dev = &pdev->dev;59 struct komeda_drv *mdrv;60 int err;61 62 err = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(40));63 if (err)64 return dev_err_probe(dev, err, "DMA mask error\n");65 66 mdrv = devm_kzalloc(dev, sizeof(*mdrv), GFP_KERNEL);67 if (!mdrv)68 return -ENOMEM;69 70 mdrv->mdev = komeda_dev_create(dev);71 if (IS_ERR(mdrv->mdev)) {72 err = PTR_ERR(mdrv->mdev);73 goto free_mdrv;74 }75 76 pm_runtime_enable(dev);77 if (!pm_runtime_enabled(dev))78 komeda_dev_resume(mdrv->mdev);79 80 mdrv->kms = komeda_kms_attach(mdrv->mdev);81 if (IS_ERR(mdrv->kms)) {82 err = PTR_ERR(mdrv->kms);83 goto destroy_mdev;84 }85 86 dev_set_drvdata(dev, mdrv);87 drm_fbdev_dma_setup(&mdrv->kms->base, 32);88 89 return 0;90 91destroy_mdev:92 if (pm_runtime_enabled(dev))93 pm_runtime_disable(dev);94 else95 komeda_dev_suspend(mdrv->mdev);96 97 komeda_dev_destroy(mdrv->mdev);98 99free_mdrv:100 devm_kfree(dev, mdrv);101 return err;102}103 104static const struct of_device_id komeda_of_match[] = {105 { .compatible = "arm,mali-d71", .data = d71_identify, },106 { .compatible = "arm,mali-d32", .data = d71_identify, },107 {},108};109 110MODULE_DEVICE_TABLE(of, komeda_of_match);111 112static int __maybe_unused komeda_rt_pm_suspend(struct device *dev)113{114 struct komeda_drv *mdrv = dev_get_drvdata(dev);115 116 return komeda_dev_suspend(mdrv->mdev);117}118 119static int __maybe_unused komeda_rt_pm_resume(struct device *dev)120{121 struct komeda_drv *mdrv = dev_get_drvdata(dev);122 123 return komeda_dev_resume(mdrv->mdev);124}125 126static int __maybe_unused komeda_pm_suspend(struct device *dev)127{128 struct komeda_drv *mdrv = dev_get_drvdata(dev);129 int res;130 131 res = drm_mode_config_helper_suspend(&mdrv->kms->base);132 133 if (!pm_runtime_status_suspended(dev))134 komeda_dev_suspend(mdrv->mdev);135 136 return res;137}138 139static int __maybe_unused komeda_pm_resume(struct device *dev)140{141 struct komeda_drv *mdrv = dev_get_drvdata(dev);142 143 if (!pm_runtime_status_suspended(dev))144 komeda_dev_resume(mdrv->mdev);145 146 return drm_mode_config_helper_resume(&mdrv->kms->base);147}148 149static const struct dev_pm_ops komeda_pm_ops = {150 SET_SYSTEM_SLEEP_PM_OPS(komeda_pm_suspend, komeda_pm_resume)151 SET_RUNTIME_PM_OPS(komeda_rt_pm_suspend, komeda_rt_pm_resume, NULL)152};153 154static struct platform_driver komeda_platform_driver = {155 .probe = komeda_platform_probe,156 .remove_new = komeda_platform_remove,157 .shutdown = komeda_platform_shutdown,158 .driver = {159 .name = "komeda",160 .of_match_table = komeda_of_match,161 .pm = &komeda_pm_ops,162 },163};164 165drm_module_platform_driver(komeda_platform_driver);166 167MODULE_AUTHOR("James.Qian.Wang <james.qian.wang@arm.com>");168MODULE_DESCRIPTION("Komeda KMS driver");169MODULE_LICENSE("GPL v2");170