1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (c) 2015, NVIDIA Corporation. 4 */ 5 6 #include <linux/clk.h> 7 #include <linux/delay.h> 8 #include <linux/dma-mapping.h> 9 #include <linux/host1x.h> 10 #include <linux/iommu.h> 11 #include <linux/iopoll.h> 12 #include <linux/module.h> 13 #include <linux/of.h> 14 #include <linux/platform_device.h> 15 #include <linux/pm_runtime.h> 16 #include <linux/reset.h> 17 18 #include <soc/tegra/pmc.h> 19 20 #include "drm.h" 21 #include "falcon.h" 22 #include "vic.h" 23 24 #define VIC_FALCON_DEBUGINFO 0x1094 25 #define VIC_DEBUGINFO_DUMMY 0xabcd1234 26 #define VIC_DEBUGINFO_CLEAR 0x0 27 28 struct vic_config { 29 const char *firmware; 30 unsigned int version; 31 bool supports_sid; 32 bool has_riscv; 33 unsigned int transcfg_offset; 34 }; 35 36 struct vic { 37 struct falcon falcon; 38 39 void __iomem *regs; 40 struct tegra_drm_client client; 41 struct host1x_channel *channel; 42 struct device *dev; 43 struct clk *clk; 44 struct reset_control *rst; 45 46 bool can_use_context; 47 48 /* Platform configuration */ 49 const struct vic_config *config; 50 }; 51 52 static inline struct vic *to_vic(struct tegra_drm_client *client) 53 { 54 return container_of(client, struct vic, client); 55 } 56 57 static void vic_writel(struct vic *vic, u32 value, unsigned int offset) 58 { 59 writel(value, vic->regs + offset); 60 } 61 62 static int vic_boot(struct vic *vic) 63 { 64 u32 stream_id; 65 u32 val; 66 int err = 0; 67 68 if (vic->config->supports_sid && tegra_dev_iommu_get_stream_id(vic->dev, &stream_id)) { 69 u32 value; 70 71 value = TRANSCFG_ATT(1, TRANSCFG_SID_FALCON) | 72 TRANSCFG_ATT(0, TRANSCFG_SID_HW); 73 vic_writel(vic, value, vic->config->transcfg_offset); 74 75 /* 76 * STREAMID0 is used for input/output buffers. Initialize it to SID_VIC in case 77 * context isolation is not enabled, and SID_VIC is used for both firmware and 78 * data buffers. 79 * 80 * If context isolation is enabled, it will be overridden by the SETSTREAMID 81 * opcode as part of each job. 82 */ 83 vic_writel(vic, stream_id, VIC_THI_STREAMID0); 84 85 /* STREAMID1 is used for firmware loading. */ 86 vic_writel(vic, stream_id, VIC_THI_STREAMID1); 87 } 88 89 /* setup clockgating registers */ 90 vic_writel(vic, CG_IDLE_CG_DLY_CNT(4) | 91 CG_IDLE_CG_EN | 92 CG_WAKEUP_DLY_CNT(4), 93 NV_PVIC_MISC_PRI_VIC_CG); 94 95 if (vic->config->has_riscv) { 96 /* Write a known pattern into DEBUGINFO register */ 97 vic_writel(vic, VIC_DEBUGINFO_DUMMY, VIC_FALCON_DEBUGINFO); 98 } 99 100 err = falcon_boot(&vic->falcon); 101 if (err < 0) 102 return err; 103 104 if (vic->config->has_riscv) { 105 /* Check VIC has reached a proper initialized state */ 106 err = readl_poll_timeout(vic->regs + VIC_FALCON_DEBUGINFO, val, 107 val == VIC_DEBUGINFO_CLEAR, 108 1000, 2000000); 109 if (err) { 110 dev_err(vic->dev, "VIC not initialized, timeout, val=0x%x\n", val); 111 return err; 112 } 113 } else { 114 u32 fce_ucode_size, fce_bin_data_offset; 115 dma_addr_t iova; 116 void *hdr; 117 118 iova = vic->falcon.firmware.iova; 119 hdr = vic->falcon.firmware.virt; 120 fce_bin_data_offset = *(u32 *)(hdr + VIC_UCODE_FCE_DATA_OFFSET); 121 122 /* Old VIC firmware needs kernel help with setting up FCE microcode. */ 123 if (fce_bin_data_offset != 0x0 && fce_bin_data_offset != 0xa5a5a5a5) { 124 hdr = vic->falcon.firmware.virt + 125 *(u32 *)(hdr + VIC_UCODE_FCE_HEADER_OFFSET); 126 fce_ucode_size = *(u32 *)(hdr + FCE_UCODE_SIZE_OFFSET); 127 128 falcon_execute_method(&vic->falcon, VIC_SET_FCE_UCODE_SIZE, 129 fce_ucode_size); 130 falcon_execute_method(&vic->falcon, VIC_SET_FCE_UCODE_OFFSET, 131 (iova + fce_bin_data_offset) >> 8); 132 } 133 134 err = falcon_wait_idle(&vic->falcon); 135 if (err < 0) { 136 dev_err(vic->dev, 137 "failed to set application ID and FCE base\n"); 138 return err; 139 } 140 } 141 142 return 0; 143 } 144 145 static int vic_init(struct host1x_client *client) 146 { 147 struct tegra_drm_client *drm = host1x_to_drm_client(client); 148 struct drm_device *dev = dev_get_drvdata(client->host); 149 struct tegra_drm *tegra = dev->dev_private; 150 struct vic *vic = to_vic(drm); 151 int err; 152 153 err = host1x_client_iommu_attach(client); 154 if (err < 0 && err != -ENODEV) { 155 dev_err(vic->dev, "failed to attach to domain: %d\n", err); 156 return err; 157 } 158 159 vic->channel = host1x_channel_request(client); 160 if (!vic->channel) { 161 err = -ENOMEM; 162 goto detach; 163 } 164 165 client->syncpts[0] = host1x_syncpt_request(client, 0); 166 if (!client->syncpts[0]) { 167 err = -ENOMEM; 168 goto free_channel; 169 } 170 171 err = tegra_drm_register_client(tegra, drm); 172 if (err < 0) 173 goto free_syncpt; 174 175 /* 176 * Inherit the DMA parameters (such as maximum segment size) from the 177 * parent host1x device. 178 */ 179 client->dev->dma_parms = client->host->dma_parms; 180 181 return 0; 182 183 free_syncpt: 184 host1x_syncpt_put(client->syncpts[0]); 185 free_channel: 186 host1x_channel_put(vic->channel); 187 detach: 188 host1x_client_iommu_detach(client); 189 190 return err; 191 } 192 193 static int vic_exit(struct host1x_client *client) 194 { 195 struct tegra_drm_client *drm = host1x_to_drm_client(client); 196 struct drm_device *dev = dev_get_drvdata(client->host); 197 struct tegra_drm *tegra = dev->dev_private; 198 struct vic *vic = to_vic(drm); 199 int err; 200 201 /* avoid a dangling pointer just in case this disappears */ 202 client->dev->dma_parms = NULL; 203 204 err = tegra_drm_unregister_client(tegra, drm); 205 if (err < 0) 206 return err; 207 208 pm_runtime_dont_use_autosuspend(client->dev); 209 pm_runtime_force_suspend(client->dev); 210 211 host1x_syncpt_put(client->syncpts[0]); 212 host1x_channel_put(vic->channel); 213 host1x_client_iommu_detach(client); 214 215 vic->channel = NULL; 216 217 if (client->group) { 218 dma_unmap_single(vic->dev, vic->falcon.firmware.phys, 219 vic->falcon.firmware.size, DMA_TO_DEVICE); 220 tegra_drm_free(tegra, vic->falcon.firmware.size, 221 vic->falcon.firmware.virt, 222 vic->falcon.firmware.iova); 223 } else { 224 dma_free_coherent(vic->dev, vic->falcon.firmware.size, 225 vic->falcon.firmware.virt, 226 vic->falcon.firmware.iova); 227 } 228 229 return 0; 230 } 231 232 static const struct host1x_client_ops vic_client_ops = { 233 .init = vic_init, 234 .exit = vic_exit, 235 }; 236 237 static int vic_load_firmware(struct vic *vic) 238 { 239 struct host1x_client *client = &vic->client.base; 240 struct tegra_drm *tegra = vic->client.drm; 241 static DEFINE_MUTEX(lock); 242 u32 fce_bin_data_offset; 243 dma_addr_t iova; 244 size_t size; 245 void *virt; 246 int err; 247 248 mutex_lock(&lock); 249 250 if (vic->falcon.firmware.virt) { 251 err = 0; 252 goto unlock; 253 } 254 255 err = falcon_read_firmware(&vic->falcon, vic->config->firmware); 256 if (err < 0) 257 goto unlock; 258 259 size = vic->falcon.firmware.size; 260 261 if (!client->group) { 262 virt = dma_alloc_coherent(vic->dev, size, &iova, GFP_KERNEL); 263 if (!virt) { 264 err = -ENOMEM; 265 goto unlock; 266 } 267 } else { 268 virt = tegra_drm_alloc(tegra, size, &iova); 269 if (IS_ERR(virt)) { 270 err = PTR_ERR(virt); 271 goto unlock; 272 } 273 } 274 275 vic->falcon.firmware.virt = virt; 276 vic->falcon.firmware.iova = iova; 277 278 err = falcon_load_firmware(&vic->falcon); 279 if (err < 0) 280 goto cleanup; 281 282 /* 283 * In this case we have received an IOVA from the shared domain, so we 284 * need to make sure to get the physical address so that the DMA API 285 * knows what memory pages to flush the cache for. 286 */ 287 if (client->group) { 288 dma_addr_t phys; 289 290 phys = dma_map_single(vic->dev, virt, size, DMA_TO_DEVICE); 291 292 err = dma_mapping_error(vic->dev, phys); 293 if (err < 0) 294 goto cleanup; 295 296 vic->falcon.firmware.phys = phys; 297 } 298 299 /* 300 * Check if firmware is new enough to not require mapping firmware 301 * to data buffer domains. 302 */ 303 fce_bin_data_offset = *(u32 *)(virt + VIC_UCODE_FCE_DATA_OFFSET); 304 305 if (!vic->config->supports_sid) { 306 vic->can_use_context = false; 307 } else if (vic->config->has_riscv) { 308 vic->can_use_context = true; 309 } else if (fce_bin_data_offset != 0x0 && fce_bin_data_offset != 0xa5a5a5a5) { 310 /* 311 * Firmware will access FCE through STREAMID0, so context 312 * isolation cannot be used. 313 */ 314 vic->can_use_context = false; 315 dev_warn_once(vic->dev, "context isolation disabled due to old firmware\n"); 316 } else { 317 vic->can_use_context = true; 318 } 319 320 unlock: 321 mutex_unlock(&lock); 322 return err; 323 324 cleanup: 325 if (!client->group) 326 dma_free_coherent(vic->dev, size, virt, iova); 327 else 328 tegra_drm_free(tegra, size, virt, iova); 329 330 mutex_unlock(&lock); 331 return err; 332 } 333 334 static int __maybe_unused vic_runtime_resume(struct device *dev) 335 { 336 struct vic *vic = dev_get_drvdata(dev); 337 int err; 338 339 err = clk_prepare_enable(vic->clk); 340 if (err < 0) 341 return err; 342 343 usleep_range(10, 20); 344 345 err = reset_control_deassert(vic->rst); 346 if (err < 0) 347 goto disable; 348 349 usleep_range(10, 20); 350 351 err = vic_load_firmware(vic); 352 if (err < 0) 353 goto assert; 354 355 err = vic_boot(vic); 356 if (err < 0) 357 goto assert; 358 359 return 0; 360 361 assert: 362 reset_control_assert(vic->rst); 363 disable: 364 clk_disable_unprepare(vic->clk); 365 return err; 366 } 367 368 static int __maybe_unused vic_runtime_suspend(struct device *dev) 369 { 370 struct vic *vic = dev_get_drvdata(dev); 371 int err; 372 373 host1x_channel_stop(vic->channel); 374 375 err = reset_control_assert(vic->rst); 376 if (err < 0) 377 return err; 378 379 usleep_range(2000, 4000); 380 381 clk_disable_unprepare(vic->clk); 382 383 return 0; 384 } 385 386 static int vic_open_channel(struct tegra_drm_client *client, 387 struct tegra_drm_context *context) 388 { 389 struct vic *vic = to_vic(client); 390 391 context->channel = host1x_channel_get(vic->channel); 392 if (!context->channel) 393 return -ENOMEM; 394 395 return 0; 396 } 397 398 static void vic_close_channel(struct tegra_drm_context *context) 399 { 400 host1x_channel_put(context->channel); 401 } 402 403 static int vic_can_use_memory_ctx(struct tegra_drm_client *client, bool *supported) 404 { 405 struct vic *vic = to_vic(client); 406 int err; 407 408 /* This doesn't access HW so it's safe to call without powering up. */ 409 err = vic_load_firmware(vic); 410 if (err < 0) 411 return err; 412 413 *supported = vic->can_use_context; 414 415 return 0; 416 } 417 418 static const struct tegra_drm_client_ops vic_ops = { 419 .open_channel = vic_open_channel, 420 .close_channel = vic_close_channel, 421 .submit = tegra_drm_submit, 422 .get_streamid_offset = tegra_drm_get_streamid_offset_thi, 423 .can_use_memory_ctx = vic_can_use_memory_ctx, 424 }; 425 426 #define NVIDIA_TEGRA_124_VIC_FIRMWARE "nvidia/tegra124/vic03_ucode.bin" 427 428 static const struct vic_config vic_t124_config = { 429 .firmware = NVIDIA_TEGRA_124_VIC_FIRMWARE, 430 .version = 0x40, 431 .supports_sid = false, 432 }; 433 434 #define NVIDIA_TEGRA_210_VIC_FIRMWARE "nvidia/tegra210/vic04_ucode.bin" 435 436 static const struct vic_config vic_t210_config = { 437 .firmware = NVIDIA_TEGRA_210_VIC_FIRMWARE, 438 .version = 0x21, 439 .supports_sid = false, 440 }; 441 442 #define NVIDIA_TEGRA_186_VIC_FIRMWARE "nvidia/tegra186/vic04_ucode.bin" 443 444 static const struct vic_config vic_t186_config = { 445 .firmware = NVIDIA_TEGRA_186_VIC_FIRMWARE, 446 .version = 0x18, 447 .supports_sid = true, 448 .transcfg_offset = 0x2044, 449 }; 450 451 #define NVIDIA_TEGRA_194_VIC_FIRMWARE "nvidia/tegra194/vic.bin" 452 453 static const struct vic_config vic_t194_config = { 454 .firmware = NVIDIA_TEGRA_194_VIC_FIRMWARE, 455 .version = 0x19, 456 .supports_sid = true, 457 .transcfg_offset = 0x2044, 458 }; 459 460 #define NVIDIA_TEGRA_234_VIC_FIRMWARE "nvidia/tegra234/vic.bin" 461 462 static const struct vic_config vic_t234_config = { 463 .firmware = NVIDIA_TEGRA_234_VIC_FIRMWARE, 464 .version = 0x23, 465 .supports_sid = true, 466 .transcfg_offset = 0x2044, 467 }; 468 469 #define NVIDIA_TEGRA_264_VIC_FIRMWARE "nvidia/tegra264/vic.bin" 470 #define NVIDIA_TEGRA_264_VIC_DESC "nvidia/tegra264/vic.bin.desc" 471 472 static const struct vic_config vic_t264_config = { 473 .firmware = NVIDIA_TEGRA_264_VIC_FIRMWARE, 474 .version = 0x264, 475 .supports_sid = true, 476 .has_riscv = true, 477 .transcfg_offset = 0x2244, 478 }; 479 480 static const struct of_device_id tegra_vic_of_match[] = { 481 { .compatible = "nvidia,tegra124-vic", .data = &vic_t124_config }, 482 { .compatible = "nvidia,tegra210-vic", .data = &vic_t210_config }, 483 { .compatible = "nvidia,tegra186-vic", .data = &vic_t186_config }, 484 { .compatible = "nvidia,tegra194-vic", .data = &vic_t194_config }, 485 { .compatible = "nvidia,tegra234-vic", .data = &vic_t234_config }, 486 { .compatible = "nvidia,tegra264-vic", .data = &vic_t264_config }, 487 { }, 488 }; 489 MODULE_DEVICE_TABLE(of, tegra_vic_of_match); 490 491 static int vic_probe(struct platform_device *pdev) 492 { 493 struct device *dev = &pdev->dev; 494 struct host1x_syncpt **syncpts; 495 struct vic *vic; 496 int err; 497 498 /* inherit DMA mask from host1x parent */ 499 err = dma_coerce_mask_and_coherent(dev, *dev->parent->dma_mask); 500 if (err < 0) { 501 dev_err(&pdev->dev, "failed to set DMA mask: %d\n", err); 502 return err; 503 } 504 505 vic = devm_kzalloc(dev, sizeof(*vic), GFP_KERNEL); 506 if (!vic) 507 return -ENOMEM; 508 509 vic->config = of_device_get_match_data(dev); 510 511 syncpts = devm_kzalloc(dev, sizeof(*syncpts), GFP_KERNEL); 512 if (!syncpts) 513 return -ENOMEM; 514 515 vic->regs = devm_platform_ioremap_resource(pdev, 0); 516 if (IS_ERR(vic->regs)) 517 return PTR_ERR(vic->regs); 518 519 vic->clk = devm_clk_get(dev, NULL); 520 if (IS_ERR(vic->clk)) { 521 dev_err(&pdev->dev, "failed to get clock\n"); 522 return PTR_ERR(vic->clk); 523 } 524 525 err = clk_set_rate(vic->clk, ULONG_MAX); 526 if (err < 0) { 527 dev_err(&pdev->dev, "failed to set clock rate\n"); 528 return err; 529 } 530 531 if (!dev->pm_domain) { 532 vic->rst = devm_reset_control_get(dev, "vic"); 533 if (IS_ERR(vic->rst)) { 534 dev_err(&pdev->dev, "failed to get reset\n"); 535 return PTR_ERR(vic->rst); 536 } 537 } 538 539 vic->falcon.dev = dev; 540 vic->falcon.regs = vic->regs; 541 vic->falcon.riscv = vic->config->has_riscv; 542 543 err = falcon_init(&vic->falcon); 544 if (err < 0) 545 return err; 546 547 platform_set_drvdata(pdev, vic); 548 549 INIT_LIST_HEAD(&vic->client.base.list); 550 vic->client.base.ops = &vic_client_ops; 551 vic->client.base.dev = dev; 552 vic->client.base.class = HOST1X_CLASS_VIC; 553 vic->client.base.syncpts = syncpts; 554 vic->client.base.num_syncpts = 1; 555 vic->dev = dev; 556 557 INIT_LIST_HEAD(&vic->client.list); 558 vic->client.version = vic->config->version; 559 vic->client.ops = &vic_ops; 560 561 err = host1x_client_register(&vic->client.base); 562 if (err < 0) { 563 dev_err(dev, "failed to register host1x client: %d\n", err); 564 goto exit_falcon; 565 } 566 567 pm_runtime_enable(dev); 568 pm_runtime_use_autosuspend(dev); 569 pm_runtime_set_autosuspend_delay(dev, 500); 570 571 return 0; 572 573 exit_falcon: 574 falcon_exit(&vic->falcon); 575 576 return err; 577 } 578 579 static void vic_remove(struct platform_device *pdev) 580 { 581 struct vic *vic = platform_get_drvdata(pdev); 582 583 pm_runtime_disable(&pdev->dev); 584 host1x_client_unregister(&vic->client.base); 585 falcon_exit(&vic->falcon); 586 } 587 588 static const struct dev_pm_ops vic_pm_ops = { 589 RUNTIME_PM_OPS(vic_runtime_suspend, vic_runtime_resume, NULL) 590 SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume) 591 }; 592 593 struct platform_driver tegra_vic_driver = { 594 .driver = { 595 .name = "tegra-vic", 596 .of_match_table = tegra_vic_of_match, 597 .pm = &vic_pm_ops 598 }, 599 .probe = vic_probe, 600 .remove = vic_remove, 601 }; 602 603 #if IS_ENABLED(CONFIG_ARCH_TEGRA_124_SOC) 604 MODULE_FIRMWARE(NVIDIA_TEGRA_124_VIC_FIRMWARE); 605 #endif 606 #if IS_ENABLED(CONFIG_ARCH_TEGRA_210_SOC) 607 MODULE_FIRMWARE(NVIDIA_TEGRA_210_VIC_FIRMWARE); 608 #endif 609 #if IS_ENABLED(CONFIG_ARCH_TEGRA_186_SOC) 610 MODULE_FIRMWARE(NVIDIA_TEGRA_186_VIC_FIRMWARE); 611 #endif 612 #if IS_ENABLED(CONFIG_ARCH_TEGRA_194_SOC) 613 MODULE_FIRMWARE(NVIDIA_TEGRA_194_VIC_FIRMWARE); 614 #endif 615 #if IS_ENABLED(CONFIG_ARCH_TEGRA_234_SOC) 616 MODULE_FIRMWARE(NVIDIA_TEGRA_234_VIC_FIRMWARE); 617 #endif 618 #if IS_ENABLED(CONFIG_ARCH_TEGRA_264_SOC) 619 MODULE_FIRMWARE(NVIDIA_TEGRA_264_VIC_FIRMWARE); 620 MODULE_FIRMWARE(NVIDIA_TEGRA_264_VIC_DESC); 621 #endif 622