0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
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
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
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
0183 hibmc_set_power_mode(priv, HIBMC_PW_MODE_CTL_MODE_MODE0);
0184
0185
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
0196
0197
0198
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
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
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");