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