linux/drivers/gpu/host1x/dev.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Tegra host1x driver
   4 *
   5 * Copyright (c) 2010-2013, NVIDIA Corporation.
   6 */
   7
   8#include <linux/clk.h>
   9#include <linux/dma-mapping.h>
  10#include <linux/io.h>
  11#include <linux/list.h>
  12#include <linux/module.h>
  13#include <linux/of_device.h>
  14#include <linux/of.h>
  15#include <linux/slab.h>
  16
  17#define CREATE_TRACE_POINTS
  18#include <trace/events/host1x.h>
  19#undef CREATE_TRACE_POINTS
  20
  21#include "bus.h"
  22#include "channel.h"
  23#include "debug.h"
  24#include "dev.h"
  25#include "intr.h"
  26
  27#include "hw/host1x01.h"
  28#include "hw/host1x02.h"
  29#include "hw/host1x04.h"
  30#include "hw/host1x05.h"
  31#include "hw/host1x06.h"
  32#include "hw/host1x07.h"
  33
  34void host1x_hypervisor_writel(struct host1x *host1x, u32 v, u32 r)
  35{
  36        writel(v, host1x->hv_regs + r);
  37}
  38
  39u32 host1x_hypervisor_readl(struct host1x *host1x, u32 r)
  40{
  41        return readl(host1x->hv_regs + r);
  42}
  43
  44void host1x_sync_writel(struct host1x *host1x, u32 v, u32 r)
  45{
  46        void __iomem *sync_regs = host1x->regs + host1x->info->sync_offset;
  47
  48        writel(v, sync_regs + r);
  49}
  50
  51u32 host1x_sync_readl(struct host1x *host1x, u32 r)
  52{
  53        void __iomem *sync_regs = host1x->regs + host1x->info->sync_offset;
  54
  55        return readl(sync_regs + r);
  56}
  57
  58void host1x_ch_writel(struct host1x_channel *ch, u32 v, u32 r)
  59{
  60        writel(v, ch->regs + r);
  61}
  62
  63u32 host1x_ch_readl(struct host1x_channel *ch, u32 r)
  64{
  65        return readl(ch->regs + r);
  66}
  67
  68static const struct host1x_info host1x01_info = {
  69        .nb_channels = 8,
  70        .nb_pts = 32,
  71        .nb_mlocks = 16,
  72        .nb_bases = 8,
  73        .init = host1x01_init,
  74        .sync_offset = 0x3000,
  75        .dma_mask = DMA_BIT_MASK(32),
  76        .has_wide_gather = false,
  77        .has_hypervisor = false,
  78        .num_sid_entries = 0,
  79        .sid_table = NULL,
  80};
  81
  82static const struct host1x_info host1x02_info = {
  83        .nb_channels = 9,
  84        .nb_pts = 32,
  85        .nb_mlocks = 16,
  86        .nb_bases = 12,
  87        .init = host1x02_init,
  88        .sync_offset = 0x3000,
  89        .dma_mask = DMA_BIT_MASK(32),
  90        .has_wide_gather = false,
  91        .has_hypervisor = false,
  92        .num_sid_entries = 0,
  93        .sid_table = NULL,
  94};
  95
  96static const struct host1x_info host1x04_info = {
  97        .nb_channels = 12,
  98        .nb_pts = 192,
  99        .nb_mlocks = 16,
 100        .nb_bases = 64,
 101        .init = host1x04_init,
 102        .sync_offset = 0x2100,
 103        .dma_mask = DMA_BIT_MASK(34),
 104        .has_wide_gather = false,
 105        .has_hypervisor = false,
 106        .num_sid_entries = 0,
 107        .sid_table = NULL,
 108};
 109
 110static const struct host1x_info host1x05_info = {
 111        .nb_channels = 14,
 112        .nb_pts = 192,
 113        .nb_mlocks = 16,
 114        .nb_bases = 64,
 115        .init = host1x05_init,
 116        .sync_offset = 0x2100,
 117        .dma_mask = DMA_BIT_MASK(34),
 118        .has_wide_gather = false,
 119        .has_hypervisor = false,
 120        .num_sid_entries = 0,
 121        .sid_table = NULL,
 122};
 123
 124static const struct host1x_sid_entry tegra186_sid_table[] = {
 125        {
 126                /* VIC */
 127                .base = 0x1af0,
 128                .offset = 0x30,
 129                .limit = 0x34
 130        },
 131};
 132
 133static const struct host1x_info host1x06_info = {
 134        .nb_channels = 63,
 135        .nb_pts = 576,
 136        .nb_mlocks = 24,
 137        .nb_bases = 16,
 138        .init = host1x06_init,
 139        .sync_offset = 0x0,
 140        .dma_mask = DMA_BIT_MASK(40),
 141        .has_wide_gather = true,
 142        .has_hypervisor = true,
 143        .num_sid_entries = ARRAY_SIZE(tegra186_sid_table),
 144        .sid_table = tegra186_sid_table,
 145};
 146
 147static const struct host1x_sid_entry tegra194_sid_table[] = {
 148        {
 149                /* VIC */
 150                .base = 0x1af0,
 151                .offset = 0x30,
 152                .limit = 0x34
 153        },
 154};
 155
 156static const struct host1x_info host1x07_info = {
 157        .nb_channels = 63,
 158        .nb_pts = 704,
 159        .nb_mlocks = 32,
 160        .nb_bases = 0,
 161        .init = host1x07_init,
 162        .sync_offset = 0x0,
 163        .dma_mask = DMA_BIT_MASK(40),
 164        .has_wide_gather = true,
 165        .has_hypervisor = true,
 166        .num_sid_entries = ARRAY_SIZE(tegra194_sid_table),
 167        .sid_table = tegra194_sid_table,
 168};
 169
 170static const struct of_device_id host1x_of_match[] = {
 171        { .compatible = "nvidia,tegra194-host1x", .data = &host1x07_info, },
 172        { .compatible = "nvidia,tegra186-host1x", .data = &host1x06_info, },
 173        { .compatible = "nvidia,tegra210-host1x", .data = &host1x05_info, },
 174        { .compatible = "nvidia,tegra124-host1x", .data = &host1x04_info, },
 175        { .compatible = "nvidia,tegra114-host1x", .data = &host1x02_info, },
 176        { .compatible = "nvidia,tegra30-host1x", .data = &host1x01_info, },
 177        { .compatible = "nvidia,tegra20-host1x", .data = &host1x01_info, },
 178        { },
 179};
 180MODULE_DEVICE_TABLE(of, host1x_of_match);
 181
 182static void host1x_setup_sid_table(struct host1x *host)
 183{
 184        const struct host1x_info *info = host->info;
 185        unsigned int i;
 186
 187        for (i = 0; i < info->num_sid_entries; i++) {
 188                const struct host1x_sid_entry *entry = &info->sid_table[i];
 189
 190                host1x_hypervisor_writel(host, entry->offset, entry->base);
 191                host1x_hypervisor_writel(host, entry->limit, entry->base + 4);
 192        }
 193}
 194
 195static bool host1x_wants_iommu(struct host1x *host1x)
 196{
 197        /*
 198         * If we support addressing a maximum of 32 bits of physical memory
 199         * and if the host1x firewall is enabled, there's no need to enable
 200         * IOMMU support. This can happen for example on Tegra20, Tegra30
 201         * and Tegra114.
 202         *
 203         * Tegra124 and later can address up to 34 bits of physical memory and
 204         * many platforms come equipped with more than 2 GiB of system memory,
 205         * which requires crossing the 4 GiB boundary. But there's a catch: on
 206         * SoCs before Tegra186 (i.e. Tegra124 and Tegra210), the host1x can
 207         * only address up to 32 bits of memory in GATHER opcodes, which means
 208         * that command buffers need to either be in the first 2 GiB of system
 209         * memory (which could quickly lead to memory exhaustion), or command
 210         * buffers need to be treated differently from other buffers (which is
 211         * not possible with the current ABI).
 212         *
 213         * A third option is to use the IOMMU in these cases to make sure all
 214         * buffers will be mapped into a 32-bit IOVA space that host1x can
 215         * address. This allows all of the system memory to be used and works
 216         * within the limitations of the host1x on these SoCs.
 217         *
 218         * In summary, default to enable IOMMU on Tegra124 and later. For any
 219         * of the earlier SoCs, only use the IOMMU for additional safety when
 220         * the host1x firewall is disabled.
 221         */
 222        if (host1x->info->dma_mask <= DMA_BIT_MASK(32)) {
 223                if (IS_ENABLED(CONFIG_TEGRA_HOST1X_FIREWALL))
 224                        return false;
 225        }
 226
 227        return true;
 228}
 229
 230static struct iommu_domain *host1x_iommu_attach(struct host1x *host)
 231{
 232        struct iommu_domain *domain = iommu_get_domain_for_dev(host->dev);
 233        int err;
 234
 235        /*
 236         * We may not always want to enable IOMMU support (for example if the
 237         * host1x firewall is already enabled and we don't support addressing
 238         * more than 32 bits of physical memory), so check for that first.
 239         *
 240         * Similarly, if host1x is already attached to an IOMMU (via the DMA
 241         * API), don't try to attach again.
 242         */
 243        if (!host1x_wants_iommu(host) || domain)
 244                return domain;
 245
 246        host->group = iommu_group_get(host->dev);
 247        if (host->group) {
 248                struct iommu_domain_geometry *geometry;
 249                dma_addr_t start, end;
 250                unsigned long order;
 251
 252                err = iova_cache_get();
 253                if (err < 0)
 254                        goto put_group;
 255
 256                host->domain = iommu_domain_alloc(&platform_bus_type);
 257                if (!host->domain) {
 258                        err = -ENOMEM;
 259                        goto put_cache;
 260                }
 261
 262                err = iommu_attach_group(host->domain, host->group);
 263                if (err) {
 264                        if (err == -ENODEV)
 265                                err = 0;
 266
 267                        goto free_domain;
 268                }
 269
 270                geometry = &host->domain->geometry;
 271                start = geometry->aperture_start & host->info->dma_mask;
 272                end = geometry->aperture_end & host->info->dma_mask;
 273
 274                order = __ffs(host->domain->pgsize_bitmap);
 275                init_iova_domain(&host->iova, 1UL << order, start >> order);
 276                host->iova_end = end;
 277
 278                domain = host->domain;
 279        }
 280
 281        return domain;
 282
 283free_domain:
 284        iommu_domain_free(host->domain);
 285        host->domain = NULL;
 286put_cache:
 287        iova_cache_put();
 288put_group:
 289        iommu_group_put(host->group);
 290        host->group = NULL;
 291
 292        return ERR_PTR(err);
 293}
 294
 295static int host1x_iommu_init(struct host1x *host)
 296{
 297        u64 mask = host->info->dma_mask;
 298        struct iommu_domain *domain;
 299        int err;
 300
 301        domain = host1x_iommu_attach(host);
 302        if (IS_ERR(domain)) {
 303                err = PTR_ERR(domain);
 304                dev_err(host->dev, "failed to attach to IOMMU: %d\n", err);
 305                return err;
 306        }
 307
 308        /*
 309         * If we're not behind an IOMMU make sure we don't get push buffers
 310         * that are allocated outside of the range addressable by the GATHER
 311         * opcode.
 312         *
 313         * Newer generations of Tegra (Tegra186 and later) support a wide
 314         * variant of the GATHER opcode that allows addressing more bits.
 315         */
 316        if (!domain && !host->info->has_wide_gather)
 317                mask = DMA_BIT_MASK(32);
 318
 319        err = dma_coerce_mask_and_coherent(host->dev, mask);
 320        if (err < 0) {
 321                dev_err(host->dev, "failed to set DMA mask: %d\n", err);
 322                return err;
 323        }
 324
 325        return 0;
 326}
 327
 328static void host1x_iommu_exit(struct host1x *host)
 329{
 330        if (host->domain) {
 331                put_iova_domain(&host->iova);
 332                iommu_detach_group(host->domain, host->group);
 333
 334                iommu_domain_free(host->domain);
 335                host->domain = NULL;
 336
 337                iova_cache_put();
 338
 339                iommu_group_put(host->group);
 340                host->group = NULL;
 341        }
 342}
 343
 344static int host1x_probe(struct platform_device *pdev)
 345{
 346        struct host1x *host;
 347        struct resource *regs, *hv_regs = NULL;
 348        int syncpt_irq;
 349        int err;
 350
 351        host = devm_kzalloc(&pdev->dev, sizeof(*host), GFP_KERNEL);
 352        if (!host)
 353                return -ENOMEM;
 354
 355        host->info = of_device_get_match_data(&pdev->dev);
 356
 357        if (host->info->has_hypervisor) {
 358                regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vm");
 359                if (!regs) {
 360                        dev_err(&pdev->dev, "failed to get vm registers\n");
 361                        return -ENXIO;
 362                }
 363
 364                hv_regs = platform_get_resource_byname(pdev, IORESOURCE_MEM,
 365                                                       "hypervisor");
 366                if (!hv_regs) {
 367                        dev_err(&pdev->dev,
 368                                "failed to get hypervisor registers\n");
 369                        return -ENXIO;
 370                }
 371        } else {
 372                regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 373                if (!regs) {
 374                        dev_err(&pdev->dev, "failed to get registers\n");
 375                        return -ENXIO;
 376                }
 377        }
 378
 379        syncpt_irq = platform_get_irq(pdev, 0);
 380        if (syncpt_irq < 0)
 381                return syncpt_irq;
 382
 383        mutex_init(&host->devices_lock);
 384        INIT_LIST_HEAD(&host->devices);
 385        INIT_LIST_HEAD(&host->list);
 386        host->dev = &pdev->dev;
 387
 388        /* set common host1x device data */
 389        platform_set_drvdata(pdev, host);
 390
 391        host->regs = devm_ioremap_resource(&pdev->dev, regs);
 392        if (IS_ERR(host->regs))
 393                return PTR_ERR(host->regs);
 394
 395        if (host->info->has_hypervisor) {
 396                host->hv_regs = devm_ioremap_resource(&pdev->dev, hv_regs);
 397                if (IS_ERR(host->hv_regs))
 398                        return PTR_ERR(host->hv_regs);
 399        }
 400
 401        host->dev->dma_parms = &host->dma_parms;
 402        dma_set_max_seg_size(host->dev, UINT_MAX);
 403
 404        if (host->info->init) {
 405                err = host->info->init(host);
 406                if (err)
 407                        return err;
 408        }
 409
 410        host->clk = devm_clk_get(&pdev->dev, NULL);
 411        if (IS_ERR(host->clk)) {
 412                err = PTR_ERR(host->clk);
 413
 414                if (err != -EPROBE_DEFER)
 415                        dev_err(&pdev->dev, "failed to get clock: %d\n", err);
 416
 417                return err;
 418        }
 419
 420        host->rst = devm_reset_control_get(&pdev->dev, "host1x");
 421        if (IS_ERR(host->rst)) {
 422                err = PTR_ERR(host->rst);
 423                dev_err(&pdev->dev, "failed to get reset: %d\n", err);
 424                return err;
 425        }
 426
 427        err = host1x_iommu_init(host);
 428        if (err < 0) {
 429                dev_err(&pdev->dev, "failed to setup IOMMU: %d\n", err);
 430                return err;
 431        }
 432
 433        err = host1x_channel_list_init(&host->channel_list,
 434                                       host->info->nb_channels);
 435        if (err) {
 436                dev_err(&pdev->dev, "failed to initialize channel list\n");
 437                goto iommu_exit;
 438        }
 439
 440        err = clk_prepare_enable(host->clk);
 441        if (err < 0) {
 442                dev_err(&pdev->dev, "failed to enable clock\n");
 443                goto free_channels;
 444        }
 445
 446        err = reset_control_deassert(host->rst);
 447        if (err < 0) {
 448                dev_err(&pdev->dev, "failed to deassert reset: %d\n", err);
 449                goto unprepare_disable;
 450        }
 451
 452        err = host1x_syncpt_init(host);
 453        if (err) {
 454                dev_err(&pdev->dev, "failed to initialize syncpts\n");
 455                goto reset_assert;
 456        }
 457
 458        err = host1x_intr_init(host, syncpt_irq);
 459        if (err) {
 460                dev_err(&pdev->dev, "failed to initialize interrupts\n");
 461                goto deinit_syncpt;
 462        }
 463
 464        host1x_debug_init(host);
 465
 466        if (host->info->has_hypervisor)
 467                host1x_setup_sid_table(host);
 468
 469        err = host1x_register(host);
 470        if (err < 0)
 471                goto deinit_debugfs;
 472
 473        err = devm_of_platform_populate(&pdev->dev);
 474        if (err < 0)
 475                goto unregister;
 476
 477        return 0;
 478
 479unregister:
 480        host1x_unregister(host);
 481deinit_debugfs:
 482        host1x_debug_deinit(host);
 483        host1x_intr_deinit(host);
 484deinit_syncpt:
 485        host1x_syncpt_deinit(host);
 486reset_assert:
 487        reset_control_assert(host->rst);
 488unprepare_disable:
 489        clk_disable_unprepare(host->clk);
 490free_channels:
 491        host1x_channel_list_free(&host->channel_list);
 492iommu_exit:
 493        host1x_iommu_exit(host);
 494
 495        return err;
 496}
 497
 498static int host1x_remove(struct platform_device *pdev)
 499{
 500        struct host1x *host = platform_get_drvdata(pdev);
 501
 502        host1x_unregister(host);
 503        host1x_debug_deinit(host);
 504        host1x_intr_deinit(host);
 505        host1x_syncpt_deinit(host);
 506        reset_control_assert(host->rst);
 507        clk_disable_unprepare(host->clk);
 508        host1x_iommu_exit(host);
 509
 510        return 0;
 511}
 512
 513static struct platform_driver tegra_host1x_driver = {
 514        .driver = {
 515                .name = "tegra-host1x",
 516                .of_match_table = host1x_of_match,
 517        },
 518        .probe = host1x_probe,
 519        .remove = host1x_remove,
 520};
 521
 522static struct platform_driver * const drivers[] = {
 523        &tegra_host1x_driver,
 524        &tegra_mipi_driver,
 525};
 526
 527static int __init tegra_host1x_init(void)
 528{
 529        int err;
 530
 531        err = bus_register(&host1x_bus_type);
 532        if (err < 0)
 533                return err;
 534
 535        err = platform_register_drivers(drivers, ARRAY_SIZE(drivers));
 536        if (err < 0)
 537                bus_unregister(&host1x_bus_type);
 538
 539        return err;
 540}
 541module_init(tegra_host1x_init);
 542
 543static void __exit tegra_host1x_exit(void)
 544{
 545        platform_unregister_drivers(drivers, ARRAY_SIZE(drivers));
 546        bus_unregister(&host1x_bus_type);
 547}
 548module_exit(tegra_host1x_exit);
 549
 550/**
 551 * host1x_get_dma_mask() - query the supported DMA mask for host1x
 552 * @host1x: host1x instance
 553 *
 554 * Note that this returns the supported DMA mask for host1x, which can be
 555 * different from the applicable DMA mask under certain circumstances.
 556 */
 557u64 host1x_get_dma_mask(struct host1x *host1x)
 558{
 559        return host1x->info->dma_mask;
 560}
 561EXPORT_SYMBOL(host1x_get_dma_mask);
 562
 563MODULE_AUTHOR("Thierry Reding <thierry.reding@avionic-design.de>");
 564MODULE_AUTHOR("Terje Bergstrom <tbergstrom@nvidia.com>");
 565MODULE_DESCRIPTION("Host1x driver for Tegra products");
 566MODULE_LICENSE("GPL");
 567