1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* Hisilicon Hibmc SoC drm driver 3 * 4 * Based on the bochs drm driver. 5 * 6 * Copyright (c) 2016 Huawei Limited. 7 * 8 * Author: 9 * Rongrong Zou <zourongrong@huawei.com> 10 * Rongrong Zou <zourongrong@gmail.com> 11 * Jianhua Li <lijianhua@huawei.com> 12 */ 13 14 #include <linux/module.h> 15 #include <linux/pci.h> 16 17 #include <drm/drm_atomic_helper.h> 18 #include <drm/drm_drv.h> 19 #include <drm/drm_gem_vram_helper.h> 20 #include <drm/drm_irq.h> 21 #include <drm/drm_managed.h> 22 #include <drm/drm_vblank.h> 23 24 #include "hibmc_drm_drv.h" 25 #include "hibmc_drm_regs.h" 26 27 DEFINE_DRM_GEM_FOPS(hibmc_fops); 28 29 static irqreturn_t hibmc_drm_interrupt(int irq, void *arg) 30 { 31 struct drm_device *dev = (struct drm_device *)arg; 32 struct hibmc_drm_private *priv = to_hibmc_drm_private(dev); 33 u32 status; 34 35 status = readl(priv->mmio + HIBMC_RAW_INTERRUPT); 36 37 if (status & HIBMC_RAW_INTERRUPT_VBLANK(1)) { 38 writel(HIBMC_RAW_INTERRUPT_VBLANK(1), 39 priv->mmio + HIBMC_RAW_INTERRUPT); 40 drm_handle_vblank(dev, 0); 41 } 42 43 return IRQ_HANDLED; 44 } 45 46 static struct drm_driver hibmc_driver = { 47 .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC, 48 .fops = &hibmc_fops, 49 .name = "hibmc", 50 .date = "20160828", 51 .desc = "hibmc drm driver", 52 .major = 1, 53 .minor = 0, 54 .debugfs_init = drm_vram_mm_debugfs_init, 55 .dumb_create = hibmc_dumb_create, 56 .dumb_map_offset = drm_gem_vram_driver_dumb_mmap_offset, 57 .gem_prime_mmap = drm_gem_prime_mmap, 58 .irq_handler = hibmc_drm_interrupt, 59 }; 60 61 static int __maybe_unused hibmc_pm_suspend(struct device *dev) 62 { 63 struct drm_device *drm_dev = dev_get_drvdata(dev); 64 65 return drm_mode_config_helper_suspend(drm_dev); 66 } 67 68 static int __maybe_unused hibmc_pm_resume(struct device *dev) 69 { 70 struct drm_device *drm_dev = dev_get_drvdata(dev); 71 72 return drm_mode_config_helper_resume(drm_dev); 73 } 74 75 static const struct dev_pm_ops hibmc_pm_ops = { 76 SET_SYSTEM_SLEEP_PM_OPS(hibmc_pm_suspend, 77 hibmc_pm_resume) 78 }; 79 80 static int hibmc_kms_init(struct hibmc_drm_private *priv) 81 { 82 int ret; 83 84 drm_mode_config_init(priv->dev); 85 priv->mode_config_initialized = true; 86 87 priv->dev->mode_config.min_width = 0; 88 priv->dev->mode_config.min_height = 0; 89 priv->dev->mode_config.max_width = 1920; 90 priv->dev->mode_config.max_height = 1200; 91 92 priv->dev->mode_config.fb_base = priv->fb_base; 93 priv->dev->mode_config.preferred_depth = 32; 94 priv->dev->mode_config.prefer_shadow = 1; 95 96 priv->dev->mode_config.funcs = (void *)&hibmc_mode_funcs; 97 98 ret = hibmc_de_init(priv); 99 if (ret) { 100 drm_err(priv->dev, "failed to init de: %d\n", ret); 101 return ret; 102 } 103 104 ret = hibmc_vdac_init(priv); 105 if (ret) { 106 drm_err(priv->dev, "failed to init vdac: %d\n", ret); 107 return ret; 108 } 109 110 return 0; 111 } 112 113 static void hibmc_kms_fini(struct hibmc_drm_private *priv) 114 { 115 if (priv->mode_config_initialized) { 116 drm_mode_config_cleanup(priv->dev); 117 priv->mode_config_initialized = false; 118 } 119 } 120 121 /* 122 * It can operate in one of three modes: 0, 1 or Sleep. 123 */ 124 void hibmc_set_power_mode(struct hibmc_drm_private *priv, 125 unsigned int power_mode) 126 { 127 unsigned int control_value = 0; 128 void __iomem *mmio = priv->mmio; 129 unsigned int input = 1; 130 131 if (power_mode > HIBMC_PW_MODE_CTL_MODE_SLEEP) 132 return; 133 134 if (power_mode == HIBMC_PW_MODE_CTL_MODE_SLEEP) 135 input = 0; 136 137 control_value = readl(mmio + HIBMC_POWER_MODE_CTRL); 138 control_value &= ~(HIBMC_PW_MODE_CTL_MODE_MASK | 139 HIBMC_PW_MODE_CTL_OSC_INPUT_MASK); 140 control_value |= HIBMC_FIELD(HIBMC_PW_MODE_CTL_MODE, power_mode); 141 control_value |= HIBMC_FIELD(HIBMC_PW_MODE_CTL_OSC_INPUT, input); 142 writel(control_value, mmio + HIBMC_POWER_MODE_CTRL); 143 } 144 145 void hibmc_set_current_gate(struct hibmc_drm_private *priv, unsigned int gate) 146 { 147 unsigned int gate_reg; 148 unsigned int mode; 149 void __iomem *mmio = priv->mmio; 150 151 /* Get current power mode. */ 152 mode = (readl(mmio + HIBMC_POWER_MODE_CTRL) & 153 HIBMC_PW_MODE_CTL_MODE_MASK) >> HIBMC_PW_MODE_CTL_MODE_SHIFT; 154 155 switch (mode) { 156 case HIBMC_PW_MODE_CTL_MODE_MODE0: 157 gate_reg = HIBMC_MODE0_GATE; 158 break; 159 160 case HIBMC_PW_MODE_CTL_MODE_MODE1: 161 gate_reg = HIBMC_MODE1_GATE; 162 break; 163 164 default: 165 gate_reg = HIBMC_MODE0_GATE; 166 break; 167 } 168 writel(gate, mmio + gate_reg); 169 } 170 171 static void hibmc_hw_config(struct hibmc_drm_private *priv) 172 { 173 unsigned int reg; 174 175 /* On hardware reset, power mode 0 is default. */ 176 hibmc_set_power_mode(priv, HIBMC_PW_MODE_CTL_MODE_MODE0); 177 178 /* Enable display power gate & LOCALMEM power gate*/ 179 reg = readl(priv->mmio + HIBMC_CURRENT_GATE); 180 reg &= ~HIBMC_CURR_GATE_DISPLAY_MASK; 181 reg &= ~HIBMC_CURR_GATE_LOCALMEM_MASK; 182 reg |= HIBMC_CURR_GATE_DISPLAY(1); 183 reg |= HIBMC_CURR_GATE_LOCALMEM(1); 184 185 hibmc_set_current_gate(priv, reg); 186 187 /* 188 * Reset the memory controller. If the memory controller 189 * is not reset in chip,the system might hang when sw accesses 190 * the memory.The memory should be resetted after 191 * changing the MXCLK. 192 */ 193 reg = readl(priv->mmio + HIBMC_MISC_CTRL); 194 reg &= ~HIBMC_MSCCTL_LOCALMEM_RESET_MASK; 195 reg |= HIBMC_MSCCTL_LOCALMEM_RESET(0); 196 writel(reg, priv->mmio + HIBMC_MISC_CTRL); 197 198 reg &= ~HIBMC_MSCCTL_LOCALMEM_RESET_MASK; 199 reg |= HIBMC_MSCCTL_LOCALMEM_RESET(1); 200 201 writel(reg, priv->mmio + HIBMC_MISC_CTRL); 202 } 203 204 static int hibmc_hw_map(struct hibmc_drm_private *priv) 205 { 206 struct drm_device *dev = priv->dev; 207 struct pci_dev *pdev = dev->pdev; 208 resource_size_t addr, size, ioaddr, iosize; 209 210 ioaddr = pci_resource_start(pdev, 1); 211 iosize = pci_resource_len(pdev, 1); 212 priv->mmio = devm_ioremap(dev->dev, ioaddr, iosize); 213 if (!priv->mmio) { 214 drm_err(dev, "Cannot map mmio region\n"); 215 return -ENOMEM; 216 } 217 218 addr = pci_resource_start(pdev, 0); 219 size = pci_resource_len(pdev, 0); 220 priv->fb_map = devm_ioremap(dev->dev, addr, size); 221 if (!priv->fb_map) { 222 drm_err(dev, "Cannot map framebuffer\n"); 223 return -ENOMEM; 224 } 225 priv->fb_base = addr; 226 priv->fb_size = size; 227 228 return 0; 229 } 230 231 static int hibmc_hw_init(struct hibmc_drm_private *priv) 232 { 233 int ret; 234 235 ret = hibmc_hw_map(priv); 236 if (ret) 237 return ret; 238 239 hibmc_hw_config(priv); 240 241 return 0; 242 } 243 244 static int hibmc_unload(struct drm_device *dev) 245 { 246 struct hibmc_drm_private *priv = to_hibmc_drm_private(dev); 247 248 drm_atomic_helper_shutdown(dev); 249 250 if (dev->irq_enabled) 251 drm_irq_uninstall(dev); 252 253 pci_disable_msi(dev->pdev); 254 hibmc_kms_fini(priv); 255 hibmc_mm_fini(priv); 256 dev->dev_private = NULL; 257 return 0; 258 } 259 260 static int hibmc_load(struct drm_device *dev) 261 { 262 struct hibmc_drm_private *priv; 263 int ret; 264 265 priv = drmm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 266 if (!priv) { 267 drm_err(dev, "no memory to allocate for hibmc_drm_private\n"); 268 return -ENOMEM; 269 } 270 dev->dev_private = priv; 271 priv->dev = dev; 272 273 ret = hibmc_hw_init(priv); 274 if (ret) 275 goto err; 276 277 ret = hibmc_mm_init(priv); 278 if (ret) 279 goto err; 280 281 ret = hibmc_kms_init(priv); 282 if (ret) 283 goto err; 284 285 ret = drm_vblank_init(dev, dev->mode_config.num_crtc); 286 if (ret) { 287 drm_err(dev, "failed to initialize vblank: %d\n", ret); 288 goto err; 289 } 290 291 ret = pci_enable_msi(dev->pdev); 292 if (ret) { 293 drm_warn(dev, "enabling MSI failed: %d\n", ret); 294 } else { 295 ret = drm_irq_install(dev, dev->pdev->irq); 296 if (ret) 297 drm_warn(dev, "install irq failed: %d\n", ret); 298 } 299 300 /* reset all the states of crtc/plane/encoder/connector */ 301 drm_mode_config_reset(dev); 302 303 return 0; 304 305 err: 306 hibmc_unload(dev); 307 drm_err(dev, "failed to initialize drm driver: %d\n", ret); 308 return ret; 309 } 310 311 static int hibmc_pci_probe(struct pci_dev *pdev, 312 const struct pci_device_id *ent) 313 { 314 struct drm_device *dev; 315 int ret; 316 317 ret = drm_fb_helper_remove_conflicting_pci_framebuffers(pdev, 318 "hibmcdrmfb"); 319 if (ret) 320 return ret; 321 322 dev = drm_dev_alloc(&hibmc_driver, &pdev->dev); 323 if (IS_ERR(dev)) { 324 DRM_ERROR("failed to allocate drm_device\n"); 325 return PTR_ERR(dev); 326 } 327 328 dev->pdev = pdev; 329 pci_set_drvdata(pdev, dev); 330 331 ret = pci_enable_device(pdev); 332 if (ret) { 333 drm_err(dev, "failed to enable pci device: %d\n", ret); 334 goto err_free; 335 } 336 337 ret = hibmc_load(dev); 338 if (ret) { 339 drm_err(dev, "failed to load hibmc: %d\n", ret); 340 goto err_disable; 341 } 342 343 ret = drm_dev_register(dev, 0); 344 if (ret) { 345 drm_err(dev, "failed to register drv for userspace access: %d\n", 346 ret); 347 goto err_unload; 348 } 349 350 drm_fbdev_generic_setup(dev, dev->mode_config.preferred_depth); 351 352 return 0; 353 354 err_unload: 355 hibmc_unload(dev); 356 err_disable: 357 pci_disable_device(pdev); 358 err_free: 359 drm_dev_put(dev); 360 361 return ret; 362 } 363 364 static void hibmc_pci_remove(struct pci_dev *pdev) 365 { 366 struct drm_device *dev = pci_get_drvdata(pdev); 367 368 drm_dev_unregister(dev); 369 hibmc_unload(dev); 370 drm_dev_put(dev); 371 } 372 373 static struct pci_device_id hibmc_pci_table[] = { 374 { PCI_VDEVICE(HUAWEI, 0x1711) }, 375 {0,} 376 }; 377 378 static struct pci_driver hibmc_pci_driver = { 379 .name = "hibmc-drm", 380 .id_table = hibmc_pci_table, 381 .probe = hibmc_pci_probe, 382 .remove = hibmc_pci_remove, 383 .driver.pm = &hibmc_pm_ops, 384 }; 385 386 module_pci_driver(hibmc_pci_driver); 387 388 MODULE_DEVICE_TABLE(pci, hibmc_pci_table); 389 MODULE_AUTHOR("RongrongZou <zourongrong@huawei.com>"); 390 MODULE_DESCRIPTION("DRM Driver for Hisilicon Hibmc"); 391 MODULE_LICENSE("GPL v2"); 392