1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (C) 2023 Loongson Technology Corporation Limited 4 */ 5 6 #include <linux/aperture.h> 7 #include <linux/pci.h> 8 #include <linux/vgaarb.h> 9 10 #include <drm/drm_atomic.h> 11 #include <drm/drm_atomic_helper.h> 12 #include <drm/drm_client_setup.h> 13 #include <drm/drm_drv.h> 14 #include <drm/drm_fbdev_ttm.h> 15 #include <drm/drm_gem_framebuffer_helper.h> 16 #include <drm/drm_ioctl.h> 17 #include <drm/drm_modeset_helper.h> 18 #include <drm/drm_probe_helper.h> 19 #include <drm/drm_vblank.h> 20 21 #include "loongson_module.h" 22 #include "lsdc_drv.h" 23 #include "lsdc_gem.h" 24 #include "lsdc_ttm.h" 25 26 #define DRIVER_AUTHOR "Sui Jingfeng <suijingfeng@loongson.cn>" 27 #define DRIVER_NAME "loongson" 28 #define DRIVER_DESC "drm driver for loongson graphics" 29 #define DRIVER_DATE "20220701" 30 #define DRIVER_MAJOR 1 31 #define DRIVER_MINOR 0 32 #define DRIVER_PATCHLEVEL 0 33 34 DEFINE_DRM_GEM_FOPS(lsdc_gem_fops); 35 36 static const struct drm_driver lsdc_drm_driver = { 37 .driver_features = DRIVER_MODESET | DRIVER_RENDER | DRIVER_GEM | DRIVER_ATOMIC, 38 .fops = &lsdc_gem_fops, 39 40 .name = DRIVER_NAME, 41 .desc = DRIVER_DESC, 42 .date = DRIVER_DATE, 43 .major = DRIVER_MAJOR, 44 .minor = DRIVER_MINOR, 45 .patchlevel = DRIVER_PATCHLEVEL, 46 47 .debugfs_init = lsdc_debugfs_init, 48 .dumb_create = lsdc_dumb_create, 49 .dumb_map_offset = lsdc_dumb_map_offset, 50 .gem_prime_import_sg_table = lsdc_prime_import_sg_table, 51 DRM_FBDEV_TTM_DRIVER_OPS, 52 }; 53 54 static const struct drm_mode_config_funcs lsdc_mode_config_funcs = { 55 .fb_create = drm_gem_fb_create, 56 .atomic_check = drm_atomic_helper_check, 57 .atomic_commit = drm_atomic_helper_commit, 58 }; 59 60 /* Display related */ 61 62 static int lsdc_modeset_init(struct lsdc_device *ldev, 63 unsigned int num_crtc, 64 const struct lsdc_kms_funcs *funcs, 65 bool has_vblank) 66 { 67 struct drm_device *ddev = &ldev->base; 68 struct lsdc_display_pipe *dispipe; 69 unsigned int i; 70 int ret; 71 72 for (i = 0; i < num_crtc; i++) { 73 dispipe = &ldev->dispipe[i]; 74 75 /* We need an index before crtc is initialized */ 76 dispipe->index = i; 77 78 ret = funcs->create_i2c(ddev, dispipe, i); 79 if (ret) 80 return ret; 81 } 82 83 for (i = 0; i < num_crtc; i++) { 84 struct i2c_adapter *ddc = NULL; 85 86 dispipe = &ldev->dispipe[i]; 87 if (dispipe->li2c) 88 ddc = &dispipe->li2c->adapter; 89 90 ret = funcs->output_init(ddev, dispipe, ddc, i); 91 if (ret) 92 return ret; 93 94 ldev->num_output++; 95 } 96 97 for (i = 0; i < num_crtc; i++) { 98 dispipe = &ldev->dispipe[i]; 99 100 ret = funcs->primary_plane_init(ddev, &dispipe->primary.base, i); 101 if (ret) 102 return ret; 103 104 ret = funcs->cursor_plane_init(ddev, &dispipe->cursor.base, i); 105 if (ret) 106 return ret; 107 108 ret = funcs->crtc_init(ddev, &dispipe->crtc.base, 109 &dispipe->primary.base, 110 &dispipe->cursor.base, 111 i, has_vblank); 112 if (ret) 113 return ret; 114 } 115 116 drm_info(ddev, "Total %u outputs\n", ldev->num_output); 117 118 return 0; 119 } 120 121 static const struct drm_mode_config_helper_funcs lsdc_mode_config_helper_funcs = { 122 .atomic_commit_tail = drm_atomic_helper_commit_tail, 123 }; 124 125 static int lsdc_mode_config_init(struct drm_device *ddev, 126 const struct lsdc_desc *descp) 127 { 128 int ret; 129 130 ret = drmm_mode_config_init(ddev); 131 if (ret) 132 return ret; 133 134 ddev->mode_config.funcs = &lsdc_mode_config_funcs; 135 ddev->mode_config.min_width = 1; 136 ddev->mode_config.min_height = 1; 137 ddev->mode_config.max_width = descp->max_width * LSDC_NUM_CRTC; 138 ddev->mode_config.max_height = descp->max_height * LSDC_NUM_CRTC; 139 ddev->mode_config.preferred_depth = 24; 140 ddev->mode_config.prefer_shadow = 1; 141 142 ddev->mode_config.cursor_width = descp->hw_cursor_h; 143 ddev->mode_config.cursor_height = descp->hw_cursor_h; 144 145 ddev->mode_config.helper_private = &lsdc_mode_config_helper_funcs; 146 147 if (descp->has_vblank_counter) 148 ddev->max_vblank_count = 0xffffffff; 149 150 return ret; 151 } 152 153 /* 154 * The GPU and display controller in the LS7A1000/LS7A2000/LS2K2000 are 155 * separated PCIE devices. They are two devices, not one. Bar 2 of the GPU 156 * device contains the base address and size of the VRAM, both the GPU and 157 * the DC could access the on-board VRAM. 158 */ 159 static int lsdc_get_dedicated_vram(struct lsdc_device *ldev, 160 struct pci_dev *pdev_dc, 161 const struct lsdc_desc *descp) 162 { 163 struct drm_device *ddev = &ldev->base; 164 struct pci_dev *pdev_gpu; 165 resource_size_t base, size; 166 167 /* 168 * The GPU has 00:06.0 as its BDF, while the DC has 00:06.1 169 * This is true for the LS7A1000, LS7A2000 and LS2K2000. 170 */ 171 pdev_gpu = pci_get_domain_bus_and_slot(pci_domain_nr(pdev_dc->bus), 172 pdev_dc->bus->number, 173 PCI_DEVFN(6, 0)); 174 if (!pdev_gpu) { 175 drm_err(ddev, "No GPU device, then no VRAM\n"); 176 return -ENODEV; 177 } 178 179 base = pci_resource_start(pdev_gpu, 2); 180 size = pci_resource_len(pdev_gpu, 2); 181 182 ldev->vram_base = base; 183 ldev->vram_size = size; 184 ldev->gpu = pdev_gpu; 185 186 drm_info(ddev, "Dedicated vram start: 0x%llx, size: %uMiB\n", 187 (u64)base, (u32)(size >> 20)); 188 189 return (size > SZ_1M) ? 0 : -ENODEV; 190 } 191 192 static struct lsdc_device * 193 lsdc_create_device(struct pci_dev *pdev, 194 const struct lsdc_desc *descp, 195 const struct drm_driver *driver) 196 { 197 struct lsdc_device *ldev; 198 struct drm_device *ddev; 199 int ret; 200 201 ldev = devm_drm_dev_alloc(&pdev->dev, driver, struct lsdc_device, base); 202 if (IS_ERR(ldev)) 203 return ldev; 204 205 ldev->dc = pdev; 206 ldev->descp = descp; 207 208 ddev = &ldev->base; 209 210 loongson_gfxpll_create(ddev, &ldev->gfxpll); 211 212 ret = lsdc_get_dedicated_vram(ldev, pdev, descp); 213 if (ret) { 214 drm_err(ddev, "Init VRAM failed: %d\n", ret); 215 return ERR_PTR(ret); 216 } 217 218 ret = aperture_remove_conflicting_devices(ldev->vram_base, 219 ldev->vram_size, 220 driver->name); 221 if (ret) { 222 drm_err(ddev, "Remove firmware framebuffers failed: %d\n", ret); 223 return ERR_PTR(ret); 224 } 225 226 ret = lsdc_ttm_init(ldev); 227 if (ret) { 228 drm_err(ddev, "Memory manager init failed: %d\n", ret); 229 return ERR_PTR(ret); 230 } 231 232 lsdc_gem_init(ddev); 233 234 /* Bar 0 of the DC device contains the MMIO register's base address */ 235 ldev->reg_base = pcim_iomap(pdev, 0, 0); 236 if (!ldev->reg_base) 237 return ERR_PTR(-ENODEV); 238 239 spin_lock_init(&ldev->reglock); 240 241 ret = lsdc_mode_config_init(ddev, descp); 242 if (ret) 243 return ERR_PTR(ret); 244 245 ret = lsdc_modeset_init(ldev, descp->num_of_crtc, descp->funcs, 246 loongson_vblank); 247 if (ret) 248 return ERR_PTR(ret); 249 250 drm_mode_config_reset(ddev); 251 252 return ldev; 253 } 254 255 /* For multiple GPU driver instance co-exixt in the system */ 256 257 static unsigned int lsdc_vga_set_decode(struct pci_dev *pdev, bool state) 258 { 259 return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM; 260 } 261 262 static int lsdc_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) 263 { 264 const struct lsdc_desc *descp; 265 struct drm_device *ddev; 266 struct lsdc_device *ldev; 267 int ret; 268 269 descp = lsdc_device_probe(pdev, ent->driver_data); 270 if (IS_ERR_OR_NULL(descp)) 271 return -ENODEV; 272 273 pci_set_master(pdev); 274 275 ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(40)); 276 if (ret) 277 return ret; 278 279 ret = pcim_enable_device(pdev); 280 if (ret) 281 return ret; 282 283 dev_info(&pdev->dev, "Found %s, revision: %u", 284 to_loongson_gfx(descp)->model, pdev->revision); 285 286 ldev = lsdc_create_device(pdev, descp, &lsdc_drm_driver); 287 if (IS_ERR(ldev)) 288 return PTR_ERR(ldev); 289 290 ddev = &ldev->base; 291 292 pci_set_drvdata(pdev, ddev); 293 294 vga_client_register(pdev, lsdc_vga_set_decode); 295 296 drm_kms_helper_poll_init(ddev); 297 298 if (loongson_vblank) { 299 ret = drm_vblank_init(ddev, descp->num_of_crtc); 300 if (ret) 301 return ret; 302 303 ret = devm_request_irq(&pdev->dev, pdev->irq, 304 descp->funcs->irq_handler, 305 IRQF_SHARED, 306 dev_name(&pdev->dev), ddev); 307 if (ret) { 308 drm_err(ddev, "Failed to register interrupt: %d\n", ret); 309 return ret; 310 } 311 312 drm_info(ddev, "registered irq: %u\n", pdev->irq); 313 } 314 315 ret = drm_dev_register(ddev, 0); 316 if (ret) 317 return ret; 318 319 drm_client_setup(ddev, NULL); 320 321 return 0; 322 } 323 324 static void lsdc_pci_remove(struct pci_dev *pdev) 325 { 326 struct drm_device *ddev = pci_get_drvdata(pdev); 327 328 drm_dev_unregister(ddev); 329 drm_atomic_helper_shutdown(ddev); 330 } 331 332 static void lsdc_pci_shutdown(struct pci_dev *pdev) 333 { 334 drm_atomic_helper_shutdown(pci_get_drvdata(pdev)); 335 } 336 337 static int lsdc_drm_freeze(struct drm_device *ddev) 338 { 339 struct lsdc_device *ldev = to_lsdc(ddev); 340 struct lsdc_bo *lbo; 341 int ret; 342 343 /* unpin all of buffers in the VRAM */ 344 mutex_lock(&ldev->gem.mutex); 345 list_for_each_entry(lbo, &ldev->gem.objects, list) { 346 struct ttm_buffer_object *tbo = &lbo->tbo; 347 struct ttm_resource *resource = tbo->resource; 348 unsigned int pin_count = tbo->pin_count; 349 350 drm_dbg(ddev, "bo[%p], size: %zuKiB, type: %s, pin count: %u\n", 351 lbo, lsdc_bo_size(lbo) >> 10, 352 lsdc_mem_type_to_str(resource->mem_type), pin_count); 353 354 if (!pin_count) 355 continue; 356 357 if (resource->mem_type == TTM_PL_VRAM) { 358 ret = lsdc_bo_reserve(lbo); 359 if (unlikely(ret)) { 360 drm_err(ddev, "bo reserve failed: %d\n", ret); 361 continue; 362 } 363 364 do { 365 lsdc_bo_unpin(lbo); 366 --pin_count; 367 } while (pin_count); 368 369 lsdc_bo_unreserve(lbo); 370 } 371 } 372 mutex_unlock(&ldev->gem.mutex); 373 374 lsdc_bo_evict_vram(ddev); 375 376 ret = drm_mode_config_helper_suspend(ddev); 377 if (unlikely(ret)) { 378 drm_err(ddev, "Freeze error: %d", ret); 379 return ret; 380 } 381 382 return 0; 383 } 384 385 static int lsdc_drm_resume(struct device *dev) 386 { 387 struct pci_dev *pdev = to_pci_dev(dev); 388 struct drm_device *ddev = pci_get_drvdata(pdev); 389 390 return drm_mode_config_helper_resume(ddev); 391 } 392 393 static int lsdc_pm_freeze(struct device *dev) 394 { 395 struct pci_dev *pdev = to_pci_dev(dev); 396 struct drm_device *ddev = pci_get_drvdata(pdev); 397 398 return lsdc_drm_freeze(ddev); 399 } 400 401 static int lsdc_pm_thaw(struct device *dev) 402 { 403 return lsdc_drm_resume(dev); 404 } 405 406 static int lsdc_pm_suspend(struct device *dev) 407 { 408 struct pci_dev *pdev = to_pci_dev(dev); 409 int error; 410 411 error = lsdc_pm_freeze(dev); 412 if (error) 413 return error; 414 415 pci_save_state(pdev); 416 /* Shut down the device */ 417 pci_disable_device(pdev); 418 pci_set_power_state(pdev, PCI_D3hot); 419 420 return 0; 421 } 422 423 static int lsdc_pm_resume(struct device *dev) 424 { 425 struct pci_dev *pdev = to_pci_dev(dev); 426 427 pci_set_power_state(pdev, PCI_D0); 428 429 pci_restore_state(pdev); 430 431 if (pcim_enable_device(pdev)) 432 return -EIO; 433 434 return lsdc_pm_thaw(dev); 435 } 436 437 static const struct dev_pm_ops lsdc_pm_ops = { 438 .suspend = lsdc_pm_suspend, 439 .resume = lsdc_pm_resume, 440 .freeze = lsdc_pm_freeze, 441 .thaw = lsdc_pm_thaw, 442 .poweroff = lsdc_pm_freeze, 443 .restore = lsdc_pm_resume, 444 }; 445 446 static const struct pci_device_id lsdc_pciid_list[] = { 447 {PCI_VDEVICE(LOONGSON, 0x7a06), CHIP_LS7A1000}, 448 {PCI_VDEVICE(LOONGSON, 0x7a36), CHIP_LS7A2000}, 449 { } 450 }; 451 452 struct pci_driver lsdc_pci_driver = { 453 .name = DRIVER_NAME, 454 .id_table = lsdc_pciid_list, 455 .probe = lsdc_pci_probe, 456 .remove = lsdc_pci_remove, 457 .shutdown = lsdc_pci_shutdown, 458 .driver.pm = &lsdc_pm_ops, 459 }; 460 461 MODULE_DEVICE_TABLE(pci, lsdc_pciid_list); 462 MODULE_AUTHOR(DRIVER_AUTHOR); 463 MODULE_DESCRIPTION(DRIVER_DESC); 464 MODULE_LICENSE("GPL"); 465