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