Home | History | Annotate | Line # | Download | only in ast
      1  1.2  riastrad /*	$NetBSD: ast_drv.c,v 1.4 2021/12/18 23:45:27 riastradh Exp $	*/
      2  1.2  riastrad 
      3  1.1  riastrad /*
      4  1.1  riastrad  * Copyright 2012 Red Hat Inc.
      5  1.1  riastrad  *
      6  1.1  riastrad  * Permission is hereby granted, free of charge, to any person obtaining a
      7  1.1  riastrad  * copy of this software and associated documentation files (the
      8  1.1  riastrad  * "Software"), to deal in the Software without restriction, including
      9  1.1  riastrad  * without limitation the rights to use, copy, modify, merge, publish,
     10  1.1  riastrad  * distribute, sub license, and/or sell copies of the Software, and to
     11  1.1  riastrad  * permit persons to whom the Software is furnished to do so, subject to
     12  1.1  riastrad  * the following conditions:
     13  1.1  riastrad  *
     14  1.1  riastrad  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     15  1.1  riastrad  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     16  1.1  riastrad  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
     17  1.1  riastrad  * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
     18  1.1  riastrad  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
     19  1.1  riastrad  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
     20  1.1  riastrad  * USE OR OTHER DEALINGS IN THE SOFTWARE.
     21  1.1  riastrad  *
     22  1.1  riastrad  * The above copyright notice and this permission notice (including the
     23  1.1  riastrad  * next paragraph) shall be included in all copies or substantial portions
     24  1.1  riastrad  * of the Software.
     25  1.1  riastrad  *
     26  1.1  riastrad  */
     27  1.1  riastrad /*
     28  1.1  riastrad  * Authors: Dave Airlie <airlied (at) redhat.com>
     29  1.1  riastrad  */
     30  1.4  riastrad 
     31  1.2  riastrad #include <sys/cdefs.h>
     32  1.2  riastrad __KERNEL_RCSID(0, "$NetBSD: ast_drv.c,v 1.4 2021/12/18 23:45:27 riastradh Exp $");
     33  1.2  riastrad 
     34  1.4  riastrad #include <linux/console.h>
     35  1.1  riastrad #include <linux/module.h>
     36  1.4  riastrad #include <linux/pci.h>
     37  1.1  riastrad 
     38  1.1  riastrad #include <drm/drm_crtc_helper.h>
     39  1.4  riastrad #include <drm/drm_drv.h>
     40  1.4  riastrad #include <drm/drm_gem_vram_helper.h>
     41  1.4  riastrad #include <drm/drm_probe_helper.h>
     42  1.1  riastrad 
     43  1.1  riastrad #include "ast_drv.h"
     44  1.1  riastrad 
     45  1.1  riastrad int ast_modeset = -1;
     46  1.1  riastrad 
     47  1.1  riastrad MODULE_PARM_DESC(modeset, "Disable/Enable modesetting");
     48  1.1  riastrad module_param_named(modeset, ast_modeset, int, 0400);
     49  1.1  riastrad 
     50  1.1  riastrad #define PCI_VENDOR_ASPEED 0x1a03
     51  1.1  riastrad 
     52  1.1  riastrad static struct drm_driver driver;
     53  1.1  riastrad 
     54  1.1  riastrad #define AST_VGA_DEVICE(id, info) {		\
     55  1.1  riastrad 	.class = PCI_BASE_CLASS_DISPLAY << 16,	\
     56  1.1  riastrad 	.class_mask = 0xff0000,			\
     57  1.1  riastrad 	.vendor = PCI_VENDOR_ASPEED,			\
     58  1.1  riastrad 	.device = id,				\
     59  1.1  riastrad 	.subvendor = PCI_ANY_ID,		\
     60  1.1  riastrad 	.subdevice = PCI_ANY_ID,		\
     61  1.1  riastrad 	.driver_data = (unsigned long) info }
     62  1.1  riastrad 
     63  1.2  riastrad static const struct pci_device_id pciidlist[] = {
     64  1.1  riastrad 	AST_VGA_DEVICE(PCI_CHIP_AST2000, NULL),
     65  1.1  riastrad 	AST_VGA_DEVICE(PCI_CHIP_AST2100, NULL),
     66  1.1  riastrad 	/*	AST_VGA_DEVICE(PCI_CHIP_AST1180, NULL), - don't bind to 1180 for now */
     67  1.1  riastrad 	{0, 0, 0},
     68  1.1  riastrad };
     69  1.1  riastrad 
     70  1.1  riastrad MODULE_DEVICE_TABLE(pci, pciidlist);
     71  1.1  riastrad 
     72  1.4  riastrad static void ast_kick_out_firmware_fb(struct pci_dev *pdev)
     73  1.4  riastrad {
     74  1.4  riastrad 	struct apertures_struct *ap;
     75  1.4  riastrad 	bool primary = false;
     76  1.4  riastrad 
     77  1.4  riastrad 	ap = alloc_apertures(1);
     78  1.4  riastrad 	if (!ap)
     79  1.4  riastrad 		return;
     80  1.4  riastrad 
     81  1.4  riastrad 	ap->ranges[0].base = pci_resource_start(pdev, 0);
     82  1.4  riastrad 	ap->ranges[0].size = pci_resource_len(pdev, 0);
     83  1.4  riastrad 
     84  1.4  riastrad #ifdef CONFIG_X86
     85  1.4  riastrad 	primary = pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW;
     86  1.4  riastrad #endif
     87  1.4  riastrad 	drm_fb_helper_remove_conflicting_framebuffers(ap, "astdrmfb", primary);
     88  1.4  riastrad 	kfree(ap);
     89  1.4  riastrad }
     90  1.4  riastrad 
     91  1.1  riastrad static int ast_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
     92  1.1  riastrad {
     93  1.4  riastrad 	struct drm_device *dev;
     94  1.4  riastrad 	int ret;
     95  1.4  riastrad 
     96  1.4  riastrad 	ast_kick_out_firmware_fb(pdev);
     97  1.4  riastrad 
     98  1.4  riastrad 	ret = pci_enable_device(pdev);
     99  1.4  riastrad 	if (ret)
    100  1.4  riastrad 		return ret;
    101  1.4  riastrad 
    102  1.4  riastrad 	dev = drm_dev_alloc(&driver, &pdev->dev);
    103  1.4  riastrad 	if (IS_ERR(dev)) {
    104  1.4  riastrad 		ret = PTR_ERR(dev);
    105  1.4  riastrad 		goto err_pci_disable_device;
    106  1.4  riastrad 	}
    107  1.4  riastrad 
    108  1.4  riastrad 	dev->pdev = pdev;
    109  1.4  riastrad 	pci_set_drvdata(pdev, dev);
    110  1.4  riastrad 
    111  1.4  riastrad 	ret = ast_driver_load(dev, ent->driver_data);
    112  1.4  riastrad 	if (ret)
    113  1.4  riastrad 		goto err_drm_dev_put;
    114  1.4  riastrad 
    115  1.4  riastrad 	ret = drm_dev_register(dev, ent->driver_data);
    116  1.4  riastrad 	if (ret)
    117  1.4  riastrad 		goto err_ast_driver_unload;
    118  1.4  riastrad 
    119  1.4  riastrad 	return 0;
    120  1.4  riastrad 
    121  1.4  riastrad err_ast_driver_unload:
    122  1.4  riastrad 	ast_driver_unload(dev);
    123  1.4  riastrad err_drm_dev_put:
    124  1.4  riastrad 	drm_dev_put(dev);
    125  1.4  riastrad err_pci_disable_device:
    126  1.4  riastrad 	pci_disable_device(pdev);
    127  1.4  riastrad 	return ret;
    128  1.4  riastrad 
    129  1.1  riastrad }
    130  1.1  riastrad 
    131  1.1  riastrad static void
    132  1.1  riastrad ast_pci_remove(struct pci_dev *pdev)
    133  1.1  riastrad {
    134  1.1  riastrad 	struct drm_device *dev = pci_get_drvdata(pdev);
    135  1.1  riastrad 
    136  1.4  riastrad 	drm_dev_unregister(dev);
    137  1.4  riastrad 	ast_driver_unload(dev);
    138  1.4  riastrad 	drm_dev_put(dev);
    139  1.1  riastrad }
    140  1.1  riastrad 
    141  1.1  riastrad static int ast_drm_freeze(struct drm_device *dev)
    142  1.1  riastrad {
    143  1.4  riastrad 	int error;
    144  1.1  riastrad 
    145  1.4  riastrad 	error = drm_mode_config_helper_suspend(dev);
    146  1.4  riastrad 	if (error)
    147  1.4  riastrad 		return error;
    148  1.1  riastrad 	pci_save_state(dev->pdev);
    149  1.1  riastrad 	return 0;
    150  1.1  riastrad }
    151  1.1  riastrad 
    152  1.1  riastrad static int ast_drm_thaw(struct drm_device *dev)
    153  1.1  riastrad {
    154  1.1  riastrad 	ast_post_gpu(dev);
    155  1.1  riastrad 
    156  1.4  riastrad 	return drm_mode_config_helper_resume(dev);
    157  1.1  riastrad }
    158  1.1  riastrad 
    159  1.1  riastrad static int ast_drm_resume(struct drm_device *dev)
    160  1.1  riastrad {
    161  1.1  riastrad 	int ret;
    162  1.1  riastrad 
    163  1.1  riastrad 	if (pci_enable_device(dev->pdev))
    164  1.1  riastrad 		return -EIO;
    165  1.1  riastrad 
    166  1.1  riastrad 	ret = ast_drm_thaw(dev);
    167  1.1  riastrad 	if (ret)
    168  1.1  riastrad 		return ret;
    169  1.1  riastrad 	return 0;
    170  1.1  riastrad }
    171  1.1  riastrad 
    172  1.1  riastrad static int ast_pm_suspend(struct device *dev)
    173  1.1  riastrad {
    174  1.1  riastrad 	struct pci_dev *pdev = to_pci_dev(dev);
    175  1.1  riastrad 	struct drm_device *ddev = pci_get_drvdata(pdev);
    176  1.1  riastrad 	int error;
    177  1.1  riastrad 
    178  1.1  riastrad 	error = ast_drm_freeze(ddev);
    179  1.1  riastrad 	if (error)
    180  1.1  riastrad 		return error;
    181  1.1  riastrad 
    182  1.1  riastrad 	pci_disable_device(pdev);
    183  1.1  riastrad 	pci_set_power_state(pdev, PCI_D3hot);
    184  1.1  riastrad 	return 0;
    185  1.1  riastrad }
    186  1.4  riastrad 
    187  1.1  riastrad static int ast_pm_resume(struct device *dev)
    188  1.1  riastrad {
    189  1.1  riastrad 	struct pci_dev *pdev = to_pci_dev(dev);
    190  1.1  riastrad 	struct drm_device *ddev = pci_get_drvdata(pdev);
    191  1.1  riastrad 	return ast_drm_resume(ddev);
    192  1.1  riastrad }
    193  1.1  riastrad 
    194  1.1  riastrad static int ast_pm_freeze(struct device *dev)
    195  1.1  riastrad {
    196  1.1  riastrad 	struct pci_dev *pdev = to_pci_dev(dev);
    197  1.1  riastrad 	struct drm_device *ddev = pci_get_drvdata(pdev);
    198  1.1  riastrad 
    199  1.1  riastrad 	if (!ddev || !ddev->dev_private)
    200  1.1  riastrad 		return -ENODEV;
    201  1.1  riastrad 	return ast_drm_freeze(ddev);
    202  1.1  riastrad }
    203  1.1  riastrad 
    204  1.1  riastrad static int ast_pm_thaw(struct device *dev)
    205  1.1  riastrad {
    206  1.1  riastrad 	struct pci_dev *pdev = to_pci_dev(dev);
    207  1.1  riastrad 	struct drm_device *ddev = pci_get_drvdata(pdev);
    208  1.1  riastrad 	return ast_drm_thaw(ddev);
    209  1.1  riastrad }
    210  1.1  riastrad 
    211  1.1  riastrad static int ast_pm_poweroff(struct device *dev)
    212  1.1  riastrad {
    213  1.1  riastrad 	struct pci_dev *pdev = to_pci_dev(dev);
    214  1.1  riastrad 	struct drm_device *ddev = pci_get_drvdata(pdev);
    215  1.1  riastrad 
    216  1.1  riastrad 	return ast_drm_freeze(ddev);
    217  1.1  riastrad }
    218  1.1  riastrad 
    219  1.1  riastrad static const struct dev_pm_ops ast_pm_ops = {
    220  1.1  riastrad 	.suspend = ast_pm_suspend,
    221  1.1  riastrad 	.resume = ast_pm_resume,
    222  1.1  riastrad 	.freeze = ast_pm_freeze,
    223  1.1  riastrad 	.thaw = ast_pm_thaw,
    224  1.1  riastrad 	.poweroff = ast_pm_poweroff,
    225  1.1  riastrad 	.restore = ast_pm_resume,
    226  1.1  riastrad };
    227  1.1  riastrad 
    228  1.1  riastrad static struct pci_driver ast_pci_driver = {
    229  1.1  riastrad 	.name = DRIVER_NAME,
    230  1.1  riastrad 	.id_table = pciidlist,
    231  1.1  riastrad 	.probe = ast_pci_probe,
    232  1.1  riastrad 	.remove = ast_pci_remove,
    233  1.1  riastrad 	.driver.pm = &ast_pm_ops,
    234  1.1  riastrad };
    235  1.1  riastrad 
    236  1.4  riastrad DEFINE_DRM_GEM_FOPS(ast_fops);
    237  1.1  riastrad 
    238  1.1  riastrad static struct drm_driver driver = {
    239  1.4  riastrad 	.driver_features = DRIVER_ATOMIC |
    240  1.4  riastrad 			   DRIVER_GEM |
    241  1.4  riastrad 			   DRIVER_MODESET,
    242  1.1  riastrad 
    243  1.1  riastrad 	.fops = &ast_fops,
    244  1.1  riastrad 	.name = DRIVER_NAME,
    245  1.1  riastrad 	.desc = DRIVER_DESC,
    246  1.1  riastrad 	.date = DRIVER_DATE,
    247  1.1  riastrad 	.major = DRIVER_MAJOR,
    248  1.1  riastrad 	.minor = DRIVER_MINOR,
    249  1.1  riastrad 	.patchlevel = DRIVER_PATCHLEVEL,
    250  1.1  riastrad 
    251  1.4  riastrad 	DRM_GEM_VRAM_DRIVER
    252  1.1  riastrad };
    253  1.1  riastrad 
    254  1.1  riastrad static int __init ast_init(void)
    255  1.1  riastrad {
    256  1.1  riastrad 	if (vgacon_text_force() && ast_modeset == -1)
    257  1.1  riastrad 		return -EINVAL;
    258  1.1  riastrad 
    259  1.1  riastrad 	if (ast_modeset == 0)
    260  1.1  riastrad 		return -EINVAL;
    261  1.4  riastrad 	return pci_register_driver(&ast_pci_driver);
    262  1.1  riastrad }
    263  1.1  riastrad static void __exit ast_exit(void)
    264  1.1  riastrad {
    265  1.4  riastrad 	pci_unregister_driver(&ast_pci_driver);
    266  1.1  riastrad }
    267  1.1  riastrad 
    268  1.1  riastrad module_init(ast_init);
    269  1.1  riastrad module_exit(ast_exit);
    270  1.1  riastrad 
    271  1.1  riastrad MODULE_AUTHOR(DRIVER_AUTHOR);
    272  1.1  riastrad MODULE_DESCRIPTION(DRIVER_DESC);
    273  1.1  riastrad MODULE_LICENSE("GPL and additional rights");
    274  1.1  riastrad 
    275