cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

dcss-drv.c (2803B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Copyright 2019 NXP.
      4 */
      5
      6#include <linux/module.h>
      7#include <linux/kernel.h>
      8#include <linux/platform_device.h>
      9#include <drm/drm_module.h>
     10#include <drm/drm_of.h>
     11
     12#include "dcss-dev.h"
     13#include "dcss-kms.h"
     14
     15struct dcss_drv {
     16	struct dcss_dev *dcss;
     17	struct dcss_kms_dev *kms;
     18};
     19
     20struct dcss_dev *dcss_drv_dev_to_dcss(struct device *dev)
     21{
     22	struct dcss_drv *mdrv = dev_get_drvdata(dev);
     23
     24	return mdrv ? mdrv->dcss : NULL;
     25}
     26
     27struct drm_device *dcss_drv_dev_to_drm(struct device *dev)
     28{
     29	struct dcss_drv *mdrv = dev_get_drvdata(dev);
     30
     31	return mdrv ? &mdrv->kms->base : NULL;
     32}
     33
     34static int dcss_drv_platform_probe(struct platform_device *pdev)
     35{
     36	struct device *dev = &pdev->dev;
     37	struct device_node *remote;
     38	struct dcss_drv *mdrv;
     39	int err = 0;
     40	bool hdmi_output = true;
     41
     42	if (!dev->of_node)
     43		return -ENODEV;
     44
     45	remote = of_graph_get_remote_node(dev->of_node, 0, 0);
     46	if (!remote)
     47		return -ENODEV;
     48
     49	hdmi_output = !of_device_is_compatible(remote, "fsl,imx8mq-nwl-dsi");
     50
     51	of_node_put(remote);
     52
     53	mdrv = kzalloc(sizeof(*mdrv), GFP_KERNEL);
     54	if (!mdrv)
     55		return -ENOMEM;
     56
     57	mdrv->dcss = dcss_dev_create(dev, hdmi_output);
     58	if (IS_ERR(mdrv->dcss)) {
     59		err = PTR_ERR(mdrv->dcss);
     60		goto err;
     61	}
     62
     63	dev_set_drvdata(dev, mdrv);
     64
     65	mdrv->kms = dcss_kms_attach(mdrv->dcss);
     66	if (IS_ERR(mdrv->kms)) {
     67		err = PTR_ERR(mdrv->kms);
     68		goto dcss_shutoff;
     69	}
     70
     71	return 0;
     72
     73dcss_shutoff:
     74	dcss_dev_destroy(mdrv->dcss);
     75
     76	dev_set_drvdata(dev, NULL);
     77
     78err:
     79	kfree(mdrv);
     80	return err;
     81}
     82
     83static int dcss_drv_platform_remove(struct platform_device *pdev)
     84{
     85	struct dcss_drv *mdrv = dev_get_drvdata(&pdev->dev);
     86
     87	if (!mdrv)
     88		return 0;
     89
     90	dcss_kms_detach(mdrv->kms);
     91	dcss_dev_destroy(mdrv->dcss);
     92
     93	dev_set_drvdata(&pdev->dev, NULL);
     94
     95	kfree(mdrv);
     96
     97	return 0;
     98}
     99
    100static struct dcss_type_data dcss_types[] = {
    101	[DCSS_IMX8MQ] = {
    102		.name = "DCSS_IMX8MQ",
    103		.blkctl_ofs = 0x2F000,
    104		.ctxld_ofs = 0x23000,
    105		.dtg_ofs = 0x20000,
    106		.scaler_ofs = 0x1C000,
    107		.ss_ofs = 0x1B000,
    108		.dpr_ofs = 0x18000,
    109	},
    110};
    111
    112static const struct of_device_id dcss_of_match[] = {
    113	{ .compatible = "nxp,imx8mq-dcss", .data = &dcss_types[DCSS_IMX8MQ], },
    114	{},
    115};
    116
    117MODULE_DEVICE_TABLE(of, dcss_of_match);
    118
    119static const struct dev_pm_ops dcss_dev_pm = {
    120	SET_SYSTEM_SLEEP_PM_OPS(dcss_dev_suspend, dcss_dev_resume)
    121	SET_RUNTIME_PM_OPS(dcss_dev_runtime_suspend,
    122			   dcss_dev_runtime_resume, NULL)
    123};
    124
    125static struct platform_driver dcss_platform_driver = {
    126	.probe	= dcss_drv_platform_probe,
    127	.remove	= dcss_drv_platform_remove,
    128	.driver	= {
    129		.name = "imx-dcss",
    130		.of_match_table	= dcss_of_match,
    131		.pm = &dcss_dev_pm,
    132	},
    133};
    134
    135drm_module_platform_driver(dcss_platform_driver);
    136
    137MODULE_AUTHOR("Laurentiu Palcu <laurentiu.palcu@nxp.com>");
    138MODULE_DESCRIPTION("DCSS driver for i.MX8MQ");
    139MODULE_LICENSE("GPL v2");