From 9d77db3c730780c8ef5ccd4b66403ff5675cfe4e Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Mon, 13 May 2024 10:30:14 +0000 Subject: [PATCH] modify sin led gpio --- kernel/drivers/gpu/drm/tegra/plane.c | 125 ++++++++++++++++++++++++++++++++++++++++- 1 files changed, 120 insertions(+), 5 deletions(-) diff --git a/kernel/drivers/gpu/drm/tegra/plane.c b/kernel/drivers/gpu/drm/tegra/plane.c index d068e8a..539d149 100644 --- a/kernel/drivers/gpu/drm/tegra/plane.c +++ b/kernel/drivers/gpu/drm/tegra/plane.c @@ -1,13 +1,14 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (C) 2017 NVIDIA CORPORATION. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. */ + +#include <linux/iommu.h> #include <drm/drm_atomic.h> #include <drm/drm_atomic_helper.h> +#include <drm/drm_fourcc.h> +#include <drm/drm_gem_framebuffer_helper.h> #include <drm/drm_plane_helper.h> #include "dc.h" @@ -25,6 +26,7 @@ { struct tegra_plane *p = to_tegra_plane(plane); struct tegra_plane_state *state; + unsigned int i; if (plane->state) __drm_atomic_helper_plane_destroy_state(plane->state); @@ -38,6 +40,9 @@ plane->state->plane = plane; plane->state->zpos = p->index; plane->state->normalized_zpos = p->index; + + for (i = 0; i < 3; i++) + state->iova[i] = DMA_MAPPING_ERROR; } } @@ -56,11 +61,17 @@ copy->tiling = state->tiling; copy->format = state->format; copy->swap = state->swap; - copy->bottom_up = state->bottom_up; + copy->reflect_x = state->reflect_x; + copy->reflect_y = state->reflect_y; copy->opaque = state->opaque; for (i = 0; i < 2; i++) copy->blending[i] = state->blending[i]; + + for (i = 0; i < 3; i++) { + copy->iova[i] = DMA_MAPPING_ERROR; + copy->sgt[i] = NULL; + } return ©->base; } @@ -97,6 +108,110 @@ .format_mod_supported = tegra_plane_format_mod_supported, }; +static int tegra_dc_pin(struct tegra_dc *dc, struct tegra_plane_state *state) +{ + struct iommu_domain *domain = iommu_get_domain_for_dev(dc->dev); + unsigned int i; + int err; + + for (i = 0; i < state->base.fb->format->num_planes; i++) { + struct tegra_bo *bo = tegra_fb_get_plane(state->base.fb, i); + dma_addr_t phys_addr, *phys; + struct sg_table *sgt; + + if (!domain || dc->client.group) + phys = &phys_addr; + else + phys = NULL; + + sgt = host1x_bo_pin(dc->dev, &bo->base, phys); + if (IS_ERR(sgt)) { + err = PTR_ERR(sgt); + goto unpin; + } + + if (sgt) { + err = dma_map_sgtable(dc->dev, sgt, DMA_TO_DEVICE, 0); + if (err) + goto unpin; + + /* + * The display controller needs contiguous memory, so + * fail if the buffer is discontiguous and we fail to + * map its SG table to a single contiguous chunk of + * I/O virtual memory. + */ + if (sgt->nents > 1) { + err = -EINVAL; + goto unpin; + } + + state->iova[i] = sg_dma_address(sgt->sgl); + state->sgt[i] = sgt; + } else { + state->iova[i] = phys_addr; + } + } + + return 0; + +unpin: + dev_err(dc->dev, "failed to map plane %u: %d\n", i, err); + + while (i--) { + struct tegra_bo *bo = tegra_fb_get_plane(state->base.fb, i); + struct sg_table *sgt = state->sgt[i]; + + if (sgt) + dma_unmap_sgtable(dc->dev, sgt, DMA_TO_DEVICE, 0); + + host1x_bo_unpin(dc->dev, &bo->base, sgt); + state->iova[i] = DMA_MAPPING_ERROR; + state->sgt[i] = NULL; + } + + return err; +} + +static void tegra_dc_unpin(struct tegra_dc *dc, struct tegra_plane_state *state) +{ + unsigned int i; + + for (i = 0; i < state->base.fb->format->num_planes; i++) { + struct tegra_bo *bo = tegra_fb_get_plane(state->base.fb, i); + struct sg_table *sgt = state->sgt[i]; + + if (sgt) + dma_unmap_sgtable(dc->dev, sgt, DMA_TO_DEVICE, 0); + + host1x_bo_unpin(dc->dev, &bo->base, sgt); + state->iova[i] = DMA_MAPPING_ERROR; + state->sgt[i] = NULL; + } +} + +int tegra_plane_prepare_fb(struct drm_plane *plane, + struct drm_plane_state *state) +{ + struct tegra_dc *dc = to_tegra_dc(state->crtc); + + if (!state->fb) + return 0; + + drm_gem_fb_prepare_fb(plane, state); + + return tegra_dc_pin(dc, to_tegra_plane_state(state)); +} + +void tegra_plane_cleanup_fb(struct drm_plane *plane, + struct drm_plane_state *state) +{ + struct tegra_dc *dc = to_tegra_dc(state->crtc); + + if (dc) + tegra_dc_unpin(dc, to_tegra_plane_state(state)); +} + int tegra_plane_state_add(struct tegra_plane *plane, struct drm_plane_state *state) { -- Gitblit v1.6.2