Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /* Hisilicon Hibmc SoC drm driver
0003  *
0004  * Based on the bochs drm driver.
0005  *
0006  * Copyright (c) 2016 Huawei Limited.
0007  *
0008  * Author:
0009  *  Rongrong Zou <zourongrong@huawei.com>
0010  *  Rongrong Zou <zourongrong@gmail.com>
0011  *  Jianhua Li <lijianhua@huawei.com>
0012  */
0013 
0014 #include <linux/module.h>
0015 #include <linux/pci.h>
0016 
0017 #include <drm/drm_aperture.h>
0018 #include <drm/drm_atomic_helper.h>
0019 #include <drm/drm_drv.h>
0020 #include <drm/drm_gem_framebuffer_helper.h>
0021 #include <drm/drm_gem_vram_helper.h>
0022 #include <drm/drm_managed.h>
0023 #include <drm/drm_module.h>
0024 #include <drm/drm_vblank.h>
0025 
0026 #include "hibmc_drm_drv.h"
0027 #include "hibmc_drm_regs.h"
0028 
0029 DEFINE_DRM_GEM_FOPS(hibmc_fops);
0030 
0031 static irqreturn_t hibmc_interrupt(int irq, void *arg)
0032 {
0033     struct drm_device *dev = (struct drm_device *)arg;
0034     struct hibmc_drm_private *priv = to_hibmc_drm_private(dev);
0035     u32 status;
0036 
0037     status = readl(priv->mmio + HIBMC_RAW_INTERRUPT);
0038 
0039     if (status & HIBMC_RAW_INTERRUPT_VBLANK(1)) {
0040         writel(HIBMC_RAW_INTERRUPT_VBLANK(1),
0041                priv->mmio + HIBMC_RAW_INTERRUPT);
0042         drm_handle_vblank(dev, 0);
0043     }
0044 
0045     return IRQ_HANDLED;
0046 }
0047 
0048 static int hibmc_dumb_create(struct drm_file *file, struct drm_device *dev,
0049                  struct drm_mode_create_dumb *args)
0050 {
0051     return drm_gem_vram_fill_create_dumb(file, dev, 0, 128, args);
0052 }
0053 
0054 static const struct drm_driver hibmc_driver = {
0055     .driver_features    = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
0056     .fops           = &hibmc_fops,
0057     .name           = "hibmc",
0058     .date           = "20160828",
0059     .desc           = "hibmc drm driver",
0060     .major          = 1,
0061     .minor          = 0,
0062     .debugfs_init       = drm_vram_mm_debugfs_init,
0063     .dumb_create            = hibmc_dumb_create,
0064     .dumb_map_offset        = drm_gem_ttm_dumb_map_offset,
0065     .gem_prime_mmap     = drm_gem_prime_mmap,
0066 };
0067 
0068 static int __maybe_unused hibmc_pm_suspend(struct device *dev)
0069 {
0070     struct drm_device *drm_dev = dev_get_drvdata(dev);
0071 
0072     return drm_mode_config_helper_suspend(drm_dev);
0073 }
0074 
0075 static int  __maybe_unused hibmc_pm_resume(struct device *dev)
0076 {
0077     struct drm_device *drm_dev = dev_get_drvdata(dev);
0078 
0079     return drm_mode_config_helper_resume(drm_dev);
0080 }
0081 
0082 static const struct dev_pm_ops hibmc_pm_ops = {
0083     SET_SYSTEM_SLEEP_PM_OPS(hibmc_pm_suspend,
0084                 hibmc_pm_resume)
0085 };
0086 
0087 static const struct drm_mode_config_funcs hibmc_mode_funcs = {
0088     .mode_valid = drm_vram_helper_mode_valid,
0089     .atomic_check = drm_atomic_helper_check,
0090     .atomic_commit = drm_atomic_helper_commit,
0091     .fb_create = drm_gem_fb_create,
0092 };
0093 
0094 static int hibmc_kms_init(struct hibmc_drm_private *priv)
0095 {
0096     struct drm_device *dev = &priv->dev;
0097     int ret;
0098 
0099     ret = drmm_mode_config_init(dev);
0100     if (ret)
0101         return ret;
0102 
0103     dev->mode_config.min_width = 0;
0104     dev->mode_config.min_height = 0;
0105     dev->mode_config.max_width = 1920;
0106     dev->mode_config.max_height = 1200;
0107 
0108     dev->mode_config.fb_base = priv->fb_base;
0109     dev->mode_config.preferred_depth = 32;
0110     dev->mode_config.prefer_shadow = 1;
0111 
0112     dev->mode_config.funcs = (void *)&hibmc_mode_funcs;
0113 
0114     ret = hibmc_de_init(priv);
0115     if (ret) {
0116         drm_err(dev, "failed to init de: %d\n", ret);
0117         return ret;
0118     }
0119 
0120     ret = hibmc_vdac_init(priv);
0121     if (ret) {
0122         drm_err(dev, "failed to init vdac: %d\n", ret);
0123         return ret;
0124     }
0125 
0126     return 0;
0127 }
0128 
0129 /*
0130  * It can operate in one of three modes: 0, 1 or Sleep.
0131  */
0132 void hibmc_set_power_mode(struct hibmc_drm_private *priv, u32 power_mode)
0133 {
0134     u32 control_value = 0;
0135     void __iomem   *mmio = priv->mmio;
0136     u32 input = 1;
0137 
0138     if (power_mode > HIBMC_PW_MODE_CTL_MODE_SLEEP)
0139         return;
0140 
0141     if (power_mode == HIBMC_PW_MODE_CTL_MODE_SLEEP)
0142         input = 0;
0143 
0144     control_value = readl(mmio + HIBMC_POWER_MODE_CTRL);
0145     control_value &= ~(HIBMC_PW_MODE_CTL_MODE_MASK |
0146                HIBMC_PW_MODE_CTL_OSC_INPUT_MASK);
0147     control_value |= HIBMC_FIELD(HIBMC_PW_MODE_CTL_MODE, power_mode);
0148     control_value |= HIBMC_FIELD(HIBMC_PW_MODE_CTL_OSC_INPUT, input);
0149     writel(control_value, mmio + HIBMC_POWER_MODE_CTRL);
0150 }
0151 
0152 void hibmc_set_current_gate(struct hibmc_drm_private *priv, unsigned int gate)
0153 {
0154     u32 gate_reg;
0155     u32 mode;
0156     void __iomem   *mmio = priv->mmio;
0157 
0158     /* Get current power mode. */
0159     mode = (readl(mmio + HIBMC_POWER_MODE_CTRL) &
0160         HIBMC_PW_MODE_CTL_MODE_MASK) >> HIBMC_PW_MODE_CTL_MODE_SHIFT;
0161 
0162     switch (mode) {
0163     case HIBMC_PW_MODE_CTL_MODE_MODE0:
0164         gate_reg = HIBMC_MODE0_GATE;
0165         break;
0166 
0167     case HIBMC_PW_MODE_CTL_MODE_MODE1:
0168         gate_reg = HIBMC_MODE1_GATE;
0169         break;
0170 
0171     default:
0172         gate_reg = HIBMC_MODE0_GATE;
0173         break;
0174     }
0175     writel(gate, mmio + gate_reg);
0176 }
0177 
0178 static void hibmc_hw_config(struct hibmc_drm_private *priv)
0179 {
0180     u32 reg;
0181 
0182     /* On hardware reset, power mode 0 is default. */
0183     hibmc_set_power_mode(priv, HIBMC_PW_MODE_CTL_MODE_MODE0);
0184 
0185     /* Enable display power gate & LOCALMEM power gate*/
0186     reg = readl(priv->mmio + HIBMC_CURRENT_GATE);
0187     reg &= ~HIBMC_CURR_GATE_DISPLAY_MASK;
0188     reg &= ~HIBMC_CURR_GATE_LOCALMEM_MASK;
0189     reg |= HIBMC_CURR_GATE_DISPLAY(1);
0190     reg |= HIBMC_CURR_GATE_LOCALMEM(1);
0191 
0192     hibmc_set_current_gate(priv, reg);
0193 
0194     /*
0195      * Reset the memory controller. If the memory controller
0196      * is not reset in chip,the system might hang when sw accesses
0197      * the memory.The memory should be resetted after
0198      * changing the MXCLK.
0199      */
0200     reg = readl(priv->mmio + HIBMC_MISC_CTRL);
0201     reg &= ~HIBMC_MSCCTL_LOCALMEM_RESET_MASK;
0202     reg |= HIBMC_MSCCTL_LOCALMEM_RESET(0);
0203     writel(reg, priv->mmio + HIBMC_MISC_CTRL);
0204 
0205     reg &= ~HIBMC_MSCCTL_LOCALMEM_RESET_MASK;
0206     reg |= HIBMC_MSCCTL_LOCALMEM_RESET(1);
0207 
0208     writel(reg, priv->mmio + HIBMC_MISC_CTRL);
0209 }
0210 
0211 static int hibmc_hw_map(struct hibmc_drm_private *priv)
0212 {
0213     struct drm_device *dev = &priv->dev;
0214     struct pci_dev *pdev = to_pci_dev(dev->dev);
0215     resource_size_t addr, size, ioaddr, iosize;
0216 
0217     ioaddr = pci_resource_start(pdev, 1);
0218     iosize = pci_resource_len(pdev, 1);
0219     priv->mmio = devm_ioremap(dev->dev, ioaddr, iosize);
0220     if (!priv->mmio) {
0221         drm_err(dev, "Cannot map mmio region\n");
0222         return -ENOMEM;
0223     }
0224 
0225     addr = pci_resource_start(pdev, 0);
0226     size = pci_resource_len(pdev, 0);
0227     priv->fb_map = devm_ioremap(dev->dev, addr, size);
0228     if (!priv->fb_map) {
0229         drm_err(dev, "Cannot map framebuffer\n");
0230         return -ENOMEM;
0231     }
0232     priv->fb_base = addr;
0233     priv->fb_size = size;
0234 
0235     return 0;
0236 }
0237 
0238 static int hibmc_hw_init(struct hibmc_drm_private *priv)
0239 {
0240     int ret;
0241 
0242     ret = hibmc_hw_map(priv);
0243     if (ret)
0244         return ret;
0245 
0246     hibmc_hw_config(priv);
0247 
0248     return 0;
0249 }
0250 
0251 static int hibmc_unload(struct drm_device *dev)
0252 {
0253     struct pci_dev *pdev = to_pci_dev(dev->dev);
0254 
0255     drm_atomic_helper_shutdown(dev);
0256 
0257     free_irq(pdev->irq, dev);
0258 
0259     pci_disable_msi(to_pci_dev(dev->dev));
0260 
0261     return 0;
0262 }
0263 
0264 static int hibmc_load(struct drm_device *dev)
0265 {
0266     struct pci_dev *pdev = to_pci_dev(dev->dev);
0267     struct hibmc_drm_private *priv = to_hibmc_drm_private(dev);
0268     int ret;
0269 
0270     ret = hibmc_hw_init(priv);
0271     if (ret)
0272         goto err;
0273 
0274     ret = drmm_vram_helper_init(dev, pci_resource_start(pdev, 0), priv->fb_size);
0275     if (ret) {
0276         drm_err(dev, "Error initializing VRAM MM; %d\n", ret);
0277         goto err;
0278     }
0279 
0280     ret = hibmc_kms_init(priv);
0281     if (ret)
0282         goto err;
0283 
0284     ret = drm_vblank_init(dev, dev->mode_config.num_crtc);
0285     if (ret) {
0286         drm_err(dev, "failed to initialize vblank: %d\n", ret);
0287         goto err;
0288     }
0289 
0290     ret = pci_enable_msi(pdev);
0291     if (ret) {
0292         drm_warn(dev, "enabling MSI failed: %d\n", ret);
0293     } else {
0294         /* PCI devices require shared interrupts. */
0295         ret = request_irq(pdev->irq, hibmc_interrupt, IRQF_SHARED,
0296                   dev->driver->name, dev);
0297         if (ret)
0298             drm_warn(dev, "install irq failed: %d\n", ret);
0299     }
0300 
0301     /* reset all the states of crtc/plane/encoder/connector */
0302     drm_mode_config_reset(dev);
0303 
0304     return 0;
0305 
0306 err:
0307     hibmc_unload(dev);
0308     drm_err(dev, "failed to initialize drm driver: %d\n", ret);
0309     return ret;
0310 }
0311 
0312 static int hibmc_pci_probe(struct pci_dev *pdev,
0313                const struct pci_device_id *ent)
0314 {
0315     struct hibmc_drm_private *priv;
0316     struct drm_device *dev;
0317     int ret;
0318 
0319     ret = drm_aperture_remove_conflicting_pci_framebuffers(pdev, &hibmc_driver);
0320     if (ret)
0321         return ret;
0322 
0323     priv = devm_drm_dev_alloc(&pdev->dev, &hibmc_driver,
0324                   struct hibmc_drm_private, dev);
0325     if (IS_ERR(priv)) {
0326         DRM_ERROR("failed to allocate drm_device\n");
0327         return PTR_ERR(priv);
0328     }
0329 
0330     dev = &priv->dev;
0331     pci_set_drvdata(pdev, dev);
0332 
0333     ret = pcim_enable_device(pdev);
0334     if (ret) {
0335         drm_err(dev, "failed to enable pci device: %d\n", ret);
0336         goto err_return;
0337     }
0338 
0339     ret = hibmc_load(dev);
0340     if (ret) {
0341         drm_err(dev, "failed to load hibmc: %d\n", ret);
0342         goto err_return;
0343     }
0344 
0345     ret = drm_dev_register(dev, 0);
0346     if (ret) {
0347         drm_err(dev, "failed to register drv for userspace access: %d\n",
0348               ret);
0349         goto err_unload;
0350     }
0351 
0352     drm_fbdev_generic_setup(dev, dev->mode_config.preferred_depth);
0353 
0354     return 0;
0355 
0356 err_unload:
0357     hibmc_unload(dev);
0358 err_return:
0359     return ret;
0360 }
0361 
0362 static void hibmc_pci_remove(struct pci_dev *pdev)
0363 {
0364     struct drm_device *dev = pci_get_drvdata(pdev);
0365 
0366     drm_dev_unregister(dev);
0367     hibmc_unload(dev);
0368 }
0369 
0370 static const struct pci_device_id hibmc_pci_table[] = {
0371     { PCI_VDEVICE(HUAWEI, 0x1711) },
0372     {0,}
0373 };
0374 
0375 static struct pci_driver hibmc_pci_driver = {
0376     .name =     "hibmc-drm",
0377     .id_table = hibmc_pci_table,
0378     .probe =    hibmc_pci_probe,
0379     .remove =   hibmc_pci_remove,
0380     .driver.pm =    &hibmc_pm_ops,
0381 };
0382 
0383 drm_module_pci_driver(hibmc_pci_driver);
0384 
0385 MODULE_DEVICE_TABLE(pci, hibmc_pci_table);
0386 MODULE_AUTHOR("RongrongZou <zourongrong@huawei.com>");
0387 MODULE_DESCRIPTION("DRM Driver for Hisilicon Hibmc");
0388 MODULE_LICENSE("GPL v2");