cregit-Linux how code gets into the kernel

Release 4.11 drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c

/*
 * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */
#include <core/tegra.h>
#ifdef CONFIG_NOUVEAU_PLATFORM_DRIVER
#include "priv.h"


static int nvkm_device_tegra_power_up(struct nvkm_device_tegra *tdev) { int ret; ret = regulator_enable(tdev->vdd); if (ret) goto err_power; ret = clk_prepare_enable(tdev->clk); if (ret) goto err_clk; if (tdev->clk_ref) { ret = clk_prepare_enable(tdev->clk_ref); if (ret) goto err_clk_ref; } ret = clk_prepare_enable(tdev->clk_pwr); if (ret) goto err_clk_pwr; clk_set_rate(tdev->clk_pwr, 204000000); udelay(10); reset_control_assert(tdev->rst); udelay(10); ret = tegra_powergate_remove_clamping(TEGRA_POWERGATE_3D); if (ret) goto err_clamp; udelay(10); reset_control_deassert(tdev->rst); udelay(10); return 0; err_clamp: clk_disable_unprepare(tdev->clk_pwr); err_clk_pwr: if (tdev->clk_ref) clk_disable_unprepare(tdev->clk_ref); err_clk_ref: clk_disable_unprepare(tdev->clk); err_clk: regulator_disable(tdev->vdd); err_power: return ret; }

Contributors

PersonTokensPropCommitsCommitProp
Ben Skeggs15479.79%266.67%
Alexandre Courbot3920.21%133.33%
Total193100.00%3100.00%


static int nvkm_device_tegra_power_down(struct nvkm_device_tegra *tdev) { reset_control_assert(tdev->rst); udelay(10); clk_disable_unprepare(tdev->clk_pwr); if (tdev->clk_ref) clk_disable_unprepare(tdev->clk_ref); clk_disable_unprepare(tdev->clk); udelay(10); return regulator_disable(tdev->vdd); }

Contributors

PersonTokensPropCommitsCommitProp
Ben Skeggs5079.37%150.00%
Alexandre Courbot1320.63%150.00%
Total63100.00%2100.00%


static void nvkm_device_tegra_probe_iommu(struct nvkm_device_tegra *tdev) { #if IS_ENABLED(CONFIG_IOMMU_API) struct device *dev = &tdev->pdev->dev; unsigned long pgsize_bitmap; int ret; if (!tdev->func->iommu_bit) return; mutex_init(&tdev->iommu.mutex); if (iommu_present(&platform_bus_type)) { tdev->iommu.domain = iommu_domain_alloc(&platform_bus_type); if (!tdev->iommu.domain) goto error; /* * A IOMMU is only usable if it supports page sizes smaller * or equal to the system's PAGE_SIZE, with a preference if * both are equal. */ pgsize_bitmap = tdev->iommu.domain->ops->pgsize_bitmap; if (pgsize_bitmap & PAGE_SIZE) { tdev->iommu.pgshift = PAGE_SHIFT; } else { tdev->iommu.pgshift = fls(pgsize_bitmap & ~PAGE_MASK); if (tdev->iommu.pgshift == 0) { dev_warn(dev, "unsupported IOMMU page size\n"); goto free_domain; } tdev->iommu.pgshift -= 1; } ret = iommu_attach_device(tdev->iommu.domain, dev); if (ret) goto free_domain; ret = nvkm_mm_init(&tdev->iommu.mm, 0, (1ULL << tdev->func->iommu_bit) >> tdev->iommu.pgshift, 1); if (ret) goto detach_device; } return; detach_device: iommu_detach_device(tdev->iommu.domain, dev); free_domain: iommu_domain_free(tdev->iommu.domain); error: tdev->iommu.domain = NULL; tdev->iommu.pgshift = 0; dev_err(dev, "cannot initialize IOMMU MM\n"); #endif }

Contributors

PersonTokensPropCommitsCommitProp
Ben Skeggs26194.22%133.33%
Alexandre Courbot155.42%133.33%
Christophe Jaillet10.36%133.33%
Total277100.00%3100.00%


static void nvkm_device_tegra_remove_iommu(struct nvkm_device_tegra *tdev) { #if IS_ENABLED(CONFIG_IOMMU_API) if (tdev->iommu.domain) { nvkm_mm_fini(&tdev->iommu.mm); iommu_detach_device(tdev->iommu.domain, tdev->device.dev); iommu_domain_free(tdev->iommu.domain); } #endif }

Contributors

PersonTokensPropCommitsCommitProp
Ben Skeggs63100.00%1100.00%
Total63100.00%1100.00%


static struct nvkm_device_tegra * nvkm_device_tegra(struct nvkm_device *device) { return container_of(device, struct nvkm_device_tegra, device); }

Contributors

PersonTokensPropCommitsCommitProp
Ben Skeggs24100.00%3100.00%
Total24100.00%3100.00%


static struct resource * nvkm_device_tegra_resource(struct nvkm_device *device, unsigned bar) { struct nvkm_device_tegra *tdev = nvkm_device_tegra(device); return platform_get_resource(tdev->pdev, IORESOURCE_MEM, bar); }

Contributors

PersonTokensPropCommitsCommitProp
Ben Skeggs38100.00%2100.00%
Total38100.00%2100.00%


static resource_size_t nvkm_device_tegra_resource_addr(struct nvkm_device *device, unsigned bar) { struct resource *res = nvkm_device_tegra_resource(device, bar); return res ? res->start : 0; }

Contributors

PersonTokensPropCommitsCommitProp
Ben Skeggs35100.00%1100.00%
Total35100.00%1100.00%


static resource_size_t nvkm_device_tegra_resource_size(struct nvkm_device *device, unsigned bar) { struct resource *res = nvkm_device_tegra_resource(device, bar); return res ? resource_size(res) : 0; }

Contributors

PersonTokensPropCommitsCommitProp
Ben Skeggs36100.00%1100.00%
Total36100.00%1100.00%


static irqreturn_t nvkm_device_tegra_intr(int irq, void *arg) { struct nvkm_device_tegra *tdev = arg; struct nvkm_device *device = &tdev->device; bool handled = false; nvkm_mc_intr_unarm(device); nvkm_mc_intr(device, &handled); nvkm_mc_intr_rearm(device); return handled ? IRQ_HANDLED : IRQ_NONE; }

Contributors

PersonTokensPropCommitsCommitProp
Ben Skeggs60100.00%3100.00%
Total60100.00%3100.00%


static void nvkm_device_tegra_fini(struct nvkm_device *device, bool suspend) { struct nvkm_device_tegra *tdev = nvkm_device_tegra(device); if (tdev->irq) { free_irq(tdev->irq, tdev); tdev->irq = 0; }; }

Contributors

PersonTokensPropCommitsCommitProp
Ben Skeggs48100.00%1100.00%
Total48100.00%1100.00%


static int nvkm_device_tegra_init(struct nvkm_device *device) { struct nvkm_device_tegra *tdev = nvkm_device_tegra(device); int irq, ret; irq = platform_get_irq_byname(tdev->pdev, "stall"); if (irq < 0) return irq; ret = request_irq(irq, nvkm_device_tegra_intr, IRQF_SHARED, "nvkm", tdev); if (ret) return ret; tdev->irq = irq; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Ben Skeggs77100.00%1100.00%
Total77100.00%1100.00%


static void * nvkm_device_tegra_dtor(struct nvkm_device *device) { struct nvkm_device_tegra *tdev = nvkm_device_tegra(device); nvkm_device_tegra_power_down(tdev); nvkm_device_tegra_remove_iommu(tdev); return tdev; }

Contributors

PersonTokensPropCommitsCommitProp
Ben Skeggs35100.00%1100.00%
Total35100.00%1100.00%

static const struct nvkm_device_func nvkm_device_tegra_func = { .tegra = nvkm_device_tegra, .dtor = nvkm_device_tegra_dtor, .init = nvkm_device_tegra_init, .fini = nvkm_device_tegra_fini, .resource_addr = nvkm_device_tegra_resource_addr, .resource_size = nvkm_device_tegra_resource_size, .cpu_coherent = false, };
int nvkm_device_tegra_new(const struct nvkm_device_tegra_func *func, struct platform_device *pdev, const char *cfg, const char *dbg, bool detect, bool mmio, u64 subdev_mask, struct nvkm_device **pdevice) { struct nvkm_device_tegra *tdev; int ret; if (!(tdev = kzalloc(sizeof(*tdev), GFP_KERNEL))) return -ENOMEM; tdev->func = func; tdev->pdev = pdev; tdev->vdd = devm_regulator_get(&pdev->dev, "vdd"); if (IS_ERR(tdev->vdd)) { ret = PTR_ERR(tdev->vdd); goto free; } tdev->rst = devm_reset_control_get(&pdev->dev, "gpu"); if (IS_ERR(tdev->rst)) { ret = PTR_ERR(tdev->rst); goto free; } tdev->clk = devm_clk_get(&pdev->dev, "gpu"); if (IS_ERR(tdev->clk)) { ret = PTR_ERR(tdev->clk); goto free; } if (func->require_ref_clk) tdev->clk_ref = devm_clk_get(&pdev->dev, "ref"); if (IS_ERR(tdev->clk_ref)) { ret = PTR_ERR(tdev->clk_ref); goto free; } tdev->clk_pwr = devm_clk_get(&pdev->dev, "pwr"); if (IS_ERR(tdev->clk_pwr)) { ret = PTR_ERR(tdev->clk_pwr); goto free; } /** * The IOMMU bit defines the upper limit of the GPU-addressable space. * This will be refined in nouveau_ttm_init but we need to do it early * for instmem to behave properly */ ret = dma_set_mask(&pdev->dev, DMA_BIT_MASK(tdev->func->iommu_bit)); if (ret) goto free; nvkm_device_tegra_probe_iommu(tdev); ret = nvkm_device_tegra_power_up(tdev); if (ret) goto remove; tdev->gpu_speedo = tegra_sku_info.gpu_speedo_value; tdev->gpu_speedo_id = tegra_sku_info.gpu_speedo_id; ret = nvkm_device_ctor(&nvkm_device_tegra_func, NULL, &pdev->dev, NVKM_DEVICE_TEGRA, pdev->id, NULL, cfg, dbg, detect, mmio, subdev_mask, &tdev->device); if (ret) goto powerdown; *pdevice = &tdev->device; return 0; powerdown: nvkm_device_tegra_power_down(tdev); remove: nvkm_device_tegra_remove_iommu(tdev); free: kfree(tdev); return ret; }

Contributors

PersonTokensPropCommitsCommitProp
Ben Skeggs25761.78%444.44%
Alexandre Courbot9021.63%444.44%
Thierry Reding6916.59%111.11%
Total416100.00%9100.00%

#else
int nvkm_device_tegra_new(const struct nvkm_device_tegra_func *func, struct platform_device *pdev, const char *cfg, const char *dbg, bool detect, bool mmio, u64 subdev_mask, struct nvkm_device **pdevice) { return -ENOSYS; }

Contributors

PersonTokensPropCommitsCommitProp
Ben Skeggs3986.67%150.00%
Alexandre Courbot613.33%150.00%
Total45100.00%2100.00%

#endif

Overall Contributors

PersonTokensPropCommitsCommitProp
Ben Skeggs122983.78%646.15%
Alexandre Courbot16311.11%430.77%
Thierry Reding694.70%17.69%
Karol Herbst50.34%17.69%
Christophe Jaillet10.07%17.69%
Total1467100.00%13100.00%
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.