plane.c (8632987380765dee716d460640aa58d58d52998e) | plane.c (c6aeaf56f468a565f6d2f27325fc07d35cdcd3cb) |
---|---|
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Copyright (C) 2017 NVIDIA CORPORATION. All rights reserved. 4 */ 5 6#include <linux/iommu.h> 7#include <linux/interconnect.h> 8 --- 60 unchanged lines hidden (view full) --- 69 copy->peak_memory_bandwidth = state->peak_memory_bandwidth; 70 copy->avg_memory_bandwidth = state->avg_memory_bandwidth; 71 72 for (i = 0; i < 2; i++) 73 copy->blending[i] = state->blending[i]; 74 75 for (i = 0; i < 3; i++) { 76 copy->iova[i] = DMA_MAPPING_ERROR; | 1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Copyright (C) 2017 NVIDIA CORPORATION. All rights reserved. 4 */ 5 6#include <linux/iommu.h> 7#include <linux/interconnect.h> 8 --- 60 unchanged lines hidden (view full) --- 69 copy->peak_memory_bandwidth = state->peak_memory_bandwidth; 70 copy->avg_memory_bandwidth = state->avg_memory_bandwidth; 71 72 for (i = 0; i < 2; i++) 73 copy->blending[i] = state->blending[i]; 74 75 for (i = 0; i < 3; i++) { 76 copy->iova[i] = DMA_MAPPING_ERROR; |
77 copy->sgt[i] = NULL; | 77 copy->map[i] = NULL; |
78 } 79 80 return ©->base; 81} 82 83static void tegra_plane_atomic_destroy_state(struct drm_plane *plane, 84 struct drm_plane_state *state) 85{ --- 47 unchanged lines hidden (view full) --- 133 .reset = tegra_plane_reset, 134 .atomic_duplicate_state = tegra_plane_atomic_duplicate_state, 135 .atomic_destroy_state = tegra_plane_atomic_destroy_state, 136 .format_mod_supported = tegra_plane_format_mod_supported, 137}; 138 139static int tegra_dc_pin(struct tegra_dc *dc, struct tegra_plane_state *state) 140{ | 78 } 79 80 return ©->base; 81} 82 83static void tegra_plane_atomic_destroy_state(struct drm_plane *plane, 84 struct drm_plane_state *state) 85{ --- 47 unchanged lines hidden (view full) --- 133 .reset = tegra_plane_reset, 134 .atomic_duplicate_state = tegra_plane_atomic_duplicate_state, 135 .atomic_destroy_state = tegra_plane_atomic_destroy_state, 136 .format_mod_supported = tegra_plane_format_mod_supported, 137}; 138 139static int tegra_dc_pin(struct tegra_dc *dc, struct tegra_plane_state *state) 140{ |
141 struct iommu_domain *domain = iommu_get_domain_for_dev(dc->dev); | |
142 unsigned int i; 143 int err; 144 145 for (i = 0; i < state->base.fb->format->num_planes; i++) { 146 struct tegra_bo *bo = tegra_fb_get_plane(state->base.fb, i); | 141 unsigned int i; 142 int err; 143 144 for (i = 0; i < state->base.fb->format->num_planes; i++) { 145 struct tegra_bo *bo = tegra_fb_get_plane(state->base.fb, i); |
147 dma_addr_t phys_addr, *phys; 148 struct sg_table *sgt; | 146 struct host1x_bo_mapping *map; |
149 | 147 |
150 /* 151 * If we're not attached to a domain, we already stored the 152 * physical address when the buffer was allocated. If we're 153 * part of a group that's shared between all display 154 * controllers, we've also already mapped the framebuffer 155 * through the SMMU. In both cases we can short-circuit the 156 * code below and retrieve the stored IOV address. 157 */ 158 if (!domain || dc->client.group) 159 phys = &phys_addr; 160 else 161 phys = NULL; 162 163 sgt = host1x_bo_pin(dc->dev, &bo->base, phys); 164 if (IS_ERR(sgt)) { 165 err = PTR_ERR(sgt); | 148 map = host1x_bo_pin(dc->dev, &bo->base, DMA_TO_DEVICE); 149 if (IS_ERR(map)) { 150 err = PTR_ERR(map); |
166 goto unpin; 167 } 168 | 151 goto unpin; 152 } 153 |
169 if (sgt) { 170 err = dma_map_sgtable(dc->dev, sgt, DMA_TO_DEVICE, 0); 171 if (err) 172 goto unpin; 173 | 154 if (!dc->client.group) { |
174 /* 175 * The display controller needs contiguous memory, so 176 * fail if the buffer is discontiguous and we fail to 177 * map its SG table to a single contiguous chunk of 178 * I/O virtual memory. 179 */ | 155 /* 156 * The display controller needs contiguous memory, so 157 * fail if the buffer is discontiguous and we fail to 158 * map its SG table to a single contiguous chunk of 159 * I/O virtual memory. 160 */ |
180 if (sgt->nents > 1) { | 161 if (map->chunks > 1) { |
181 err = -EINVAL; 182 goto unpin; 183 } 184 | 162 err = -EINVAL; 163 goto unpin; 164 } 165 |
185 state->iova[i] = sg_dma_address(sgt->sgl); 186 state->sgt[i] = sgt; | 166 state->iova[i] = map->phys; |
187 } else { | 167 } else { |
188 state->iova[i] = phys_addr; | 168 state->iova[i] = bo->iova; |
189 } | 169 } |
170 171 state->map[i] = map; |
|
190 } 191 192 return 0; 193 194unpin: 195 dev_err(dc->dev, "failed to map plane %u: %d\n", i, err); 196 197 while (i--) { | 172 } 173 174 return 0; 175 176unpin: 177 dev_err(dc->dev, "failed to map plane %u: %d\n", i, err); 178 179 while (i--) { |
198 struct tegra_bo *bo = tegra_fb_get_plane(state->base.fb, i); 199 struct sg_table *sgt = state->sgt[i]; 200 201 if (sgt) 202 dma_unmap_sgtable(dc->dev, sgt, DMA_TO_DEVICE, 0); 203 204 host1x_bo_unpin(dc->dev, &bo->base, sgt); | 180 host1x_bo_unpin(state->map[i]); |
205 state->iova[i] = DMA_MAPPING_ERROR; | 181 state->iova[i] = DMA_MAPPING_ERROR; |
206 state->sgt[i] = NULL; | 182 state->map[i] = NULL; |
207 } 208 209 return err; 210} 211 212static void tegra_dc_unpin(struct tegra_dc *dc, struct tegra_plane_state *state) 213{ 214 unsigned int i; 215 216 for (i = 0; i < state->base.fb->format->num_planes; i++) { | 183 } 184 185 return err; 186} 187 188static void tegra_dc_unpin(struct tegra_dc *dc, struct tegra_plane_state *state) 189{ 190 unsigned int i; 191 192 for (i = 0; i < state->base.fb->format->num_planes; i++) { |
217 struct tegra_bo *bo = tegra_fb_get_plane(state->base.fb, i); 218 struct sg_table *sgt = state->sgt[i]; 219 220 if (sgt) 221 dma_unmap_sgtable(dc->dev, sgt, DMA_TO_DEVICE, 0); 222 223 host1x_bo_unpin(dc->dev, &bo->base, sgt); | 193 host1x_bo_unpin(state->map[i]); |
224 state->iova[i] = DMA_MAPPING_ERROR; | 194 state->iova[i] = DMA_MAPPING_ERROR; |
225 state->sgt[i] = NULL; | 195 state->map[i] = NULL; |
226 } 227} 228 229int tegra_plane_prepare_fb(struct drm_plane *plane, 230 struct drm_plane_state *state) 231{ 232 struct tegra_dc *dc = to_tegra_dc(state->crtc); 233 --- 532 unchanged lines hidden --- | 196 } 197} 198 199int tegra_plane_prepare_fb(struct drm_plane *plane, 200 struct drm_plane_state *state) 201{ 202 struct tegra_dc *dc = to_tegra_dc(state->crtc); 203 --- 532 unchanged lines hidden --- |