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 const 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 struct drm_device *dev = &priv->dev; 83 int ret; 84 85 drm_mode_config_init(dev); 86 priv->mode_config_initialized = true; 87 88 dev->mode_config.min_width = 0; 89 dev->mode_config.min_height = 0; 90 dev->mode_config.max_width = 1920; 91 dev->mode_config.max_height = 1200; 92 93 dev->mode_config.fb_base = priv->fb_base; 94 dev->mode_config.preferred_depth = 32; 95 dev->mode_config.prefer_shadow = 1; 96 97 dev->mode_config.funcs = (void *)&hibmc_mode_funcs; 98 99 ret = hibmc_de_init(priv); 100 if (ret) { 101 drm_err(dev, "failed to init de: %d\n", ret); 102 return ret; 103 } 104 105 ret = hibmc_vdac_init(priv); 106 if (ret) { 107 drm_err(dev, "failed to init vdac: %d\n", ret); 108 return ret; 109 } 110 111 return 0; 112 } 113 114 static void hibmc_kms_fini(struct hibmc_drm_private *priv) 115 { 116 if (priv->mode_config_initialized) { 117 drm_mode_config_cleanup(&priv->dev); 118 priv->mode_config_initialized = false; 119 } 120 } 121 122 /* 123 * It can operate in one of three modes: 0, 1 or Sleep. 124 */ 125 void hibmc_set_power_mode(struct hibmc_drm_private *priv, u32 power_mode) 126 { 127 u32 control_value = 0; 128 void __iomem *mmio = priv->mmio; 129 u32 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 u32 gate_reg; 148 u32 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 u32 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 pci_disable_msi(dev->pdev); 251 hibmc_kms_fini(priv); 252 hibmc_mm_fini(priv); 253 dev->dev_private = NULL; 254 return 0; 255 } 256 257 static int hibmc_load(struct drm_device *dev) 258 { 259 struct hibmc_drm_private *priv = to_hibmc_drm_private(dev); 260 int ret; 261 262 ret = hibmc_hw_init(priv); 263 if (ret) 264 goto err; 265 266 ret = hibmc_mm_init(priv); 267 if (ret) 268 goto err; 269 270 ret = hibmc_kms_init(priv); 271 if (ret) 272 goto err; 273 274 ret = drm_vblank_init(dev, dev->mode_config.num_crtc); 275 if (ret) { 276 drm_err(dev, "failed to initialize vblank: %d\n", ret); 277 goto err; 278 } 279 280 ret = pci_enable_msi(dev->pdev); 281 if (ret) { 282 drm_warn(dev, "enabling MSI failed: %d\n", ret); 283 } else { 284 ret = devm_drm_irq_install(dev, dev->pdev->irq); 285 if (ret) 286 drm_warn(dev, "install irq failed: %d\n", ret); 287 } 288 289 /* reset all the states of crtc/plane/encoder/connector */ 290 drm_mode_config_reset(dev); 291 292 return 0; 293 294 err: 295 hibmc_unload(dev); 296 drm_err(dev, "failed to initialize drm driver: %d\n", ret); 297 return ret; 298 } 299 300 static int hibmc_pci_probe(struct pci_dev *pdev, 301 const struct pci_device_id *ent) 302 { 303 struct hibmc_drm_private *priv; 304 struct drm_device *dev; 305 int ret; 306 307 ret = drm_fb_helper_remove_conflicting_pci_framebuffers(pdev, 308 "hibmcdrmfb"); 309 if (ret) 310 return ret; 311 312 priv = devm_drm_dev_alloc(&pdev->dev, &hibmc_driver, 313 struct hibmc_drm_private, dev); 314 if (IS_ERR(priv)) { 315 DRM_ERROR("failed to allocate drm_device\n"); 316 return PTR_ERR(priv); 317 } 318 319 dev = &priv->dev; 320 dev->pdev = pdev; 321 pci_set_drvdata(pdev, dev); 322 323 ret = pci_enable_device(pdev); 324 if (ret) { 325 drm_err(dev, "failed to enable pci device: %d\n", ret); 326 goto err_free; 327 } 328 329 ret = hibmc_load(dev); 330 if (ret) { 331 drm_err(dev, "failed to load hibmc: %d\n", ret); 332 goto err_disable; 333 } 334 335 ret = drm_dev_register(dev, 0); 336 if (ret) { 337 drm_err(dev, "failed to register drv for userspace access: %d\n", 338 ret); 339 goto err_unload; 340 } 341 342 drm_fbdev_generic_setup(dev, dev->mode_config.preferred_depth); 343 344 return 0; 345 346 err_unload: 347 hibmc_unload(dev); 348 err_disable: 349 pci_disable_device(pdev); 350 err_free: 351 drm_dev_put(dev); 352 353 return ret; 354 } 355 356 static void hibmc_pci_remove(struct pci_dev *pdev) 357 { 358 struct drm_device *dev = pci_get_drvdata(pdev); 359 360 drm_dev_unregister(dev); 361 hibmc_unload(dev); 362 drm_dev_put(dev); 363 } 364 365 static const struct pci_device_id hibmc_pci_table[] = { 366 { PCI_VDEVICE(HUAWEI, 0x1711) }, 367 {0,} 368 }; 369 370 static struct pci_driver hibmc_pci_driver = { 371 .name = "hibmc-drm", 372 .id_table = hibmc_pci_table, 373 .probe = hibmc_pci_probe, 374 .remove = hibmc_pci_remove, 375 .driver.pm = &hibmc_pm_ops, 376 }; 377 378 module_pci_driver(hibmc_pci_driver); 379 380 MODULE_DEVICE_TABLE(pci, hibmc_pci_table); 381 MODULE_AUTHOR("RongrongZou <zourongrong@huawei.com>"); 382 MODULE_DESCRIPTION("DRM Driver for Hisilicon Hibmc"); 383 MODULE_LICENSE("GPL v2"); 384