plane.c (728d90bdc9e480dc93913e59a0aa3c896c7aa697) plane.c (2e8d8749f6f9bb35b947228271dc9ec31be93335)
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Copyright (C) 2017 NVIDIA CORPORATION. All rights reserved.
4 */
5
6#include <drm/drm_atomic.h>
7#include <drm/drm_atomic_helper.h>
8#include <drm/drm_fourcc.h>
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Copyright (C) 2017 NVIDIA CORPORATION. All rights reserved.
4 */
5
6#include <drm/drm_atomic.h>
7#include <drm/drm_atomic_helper.h>
8#include <drm/drm_fourcc.h>
9#include <drm/drm_gem_framebuffer_helper.h>
9#include <drm/drm_plane_helper.h>
10
11#include "dc.h"
12#include "plane.h"
13
14static void tegra_plane_destroy(struct drm_plane *plane)
15{
16 struct tegra_plane *p = to_tegra_plane(plane);
17
18 drm_plane_cleanup(plane);
19 kfree(p);
20}
21
22static void tegra_plane_reset(struct drm_plane *plane)
23{
24 struct tegra_plane *p = to_tegra_plane(plane);
25 struct tegra_plane_state *state;
10#include <drm/drm_plane_helper.h>
11
12#include "dc.h"
13#include "plane.h"
14
15static void tegra_plane_destroy(struct drm_plane *plane)
16{
17 struct tegra_plane *p = to_tegra_plane(plane);
18
19 drm_plane_cleanup(plane);
20 kfree(p);
21}
22
23static void tegra_plane_reset(struct drm_plane *plane)
24{
25 struct tegra_plane *p = to_tegra_plane(plane);
26 struct tegra_plane_state *state;
27 unsigned int i;
26
27 if (plane->state)
28 __drm_atomic_helper_plane_destroy_state(plane->state);
29
30 kfree(plane->state);
31 plane->state = NULL;
32
33 state = kzalloc(sizeof(*state), GFP_KERNEL);
34 if (state) {
35 plane->state = &state->base;
36 plane->state->plane = plane;
37 plane->state->zpos = p->index;
38 plane->state->normalized_zpos = p->index;
28
29 if (plane->state)
30 __drm_atomic_helper_plane_destroy_state(plane->state);
31
32 kfree(plane->state);
33 plane->state = NULL;
34
35 state = kzalloc(sizeof(*state), GFP_KERNEL);
36 if (state) {
37 plane->state = &state->base;
38 plane->state->plane = plane;
39 plane->state->zpos = p->index;
40 plane->state->normalized_zpos = p->index;
41
42 for (i = 0; i < 3; i++)
43 state->iova[i] = DMA_MAPPING_ERROR;
39 }
40}
41
42static struct drm_plane_state *
43tegra_plane_atomic_duplicate_state(struct drm_plane *plane)
44{
45 struct tegra_plane_state *state = to_tegra_plane_state(plane->state);
46 struct tegra_plane_state *copy;

--- 8 unchanged lines hidden (view full) ---

55 copy->format = state->format;
56 copy->swap = state->swap;
57 copy->bottom_up = state->bottom_up;
58 copy->opaque = state->opaque;
59
60 for (i = 0; i < 2; i++)
61 copy->blending[i] = state->blending[i];
62
44 }
45}
46
47static struct drm_plane_state *
48tegra_plane_atomic_duplicate_state(struct drm_plane *plane)
49{
50 struct tegra_plane_state *state = to_tegra_plane_state(plane->state);
51 struct tegra_plane_state *copy;

--- 8 unchanged lines hidden (view full) ---

60 copy->format = state->format;
61 copy->swap = state->swap;
62 copy->bottom_up = state->bottom_up;
63 copy->opaque = state->opaque;
64
65 for (i = 0; i < 2; i++)
66 copy->blending[i] = state->blending[i];
67
68 for (i = 0; i < 3; i++) {
69 copy->iova[i] = DMA_MAPPING_ERROR;
70 copy->sgt[i] = NULL;
71 }
72
63 return &copy->base;
64}
65
66static void tegra_plane_atomic_destroy_state(struct drm_plane *plane,
67 struct drm_plane_state *state)
68{
69 __drm_atomic_helper_plane_destroy_state(state);
70 kfree(state);

--- 19 unchanged lines hidden (view full) ---

90 .disable_plane = drm_atomic_helper_disable_plane,
91 .destroy = tegra_plane_destroy,
92 .reset = tegra_plane_reset,
93 .atomic_duplicate_state = tegra_plane_atomic_duplicate_state,
94 .atomic_destroy_state = tegra_plane_atomic_destroy_state,
95 .format_mod_supported = tegra_plane_format_mod_supported,
96};
97
73 return &copy->base;
74}
75
76static void tegra_plane_atomic_destroy_state(struct drm_plane *plane,
77 struct drm_plane_state *state)
78{
79 __drm_atomic_helper_plane_destroy_state(state);
80 kfree(state);

--- 19 unchanged lines hidden (view full) ---

100 .disable_plane = drm_atomic_helper_disable_plane,
101 .destroy = tegra_plane_destroy,
102 .reset = tegra_plane_reset,
103 .atomic_duplicate_state = tegra_plane_atomic_duplicate_state,
104 .atomic_destroy_state = tegra_plane_atomic_destroy_state,
105 .format_mod_supported = tegra_plane_format_mod_supported,
106};
107
108static int tegra_dc_pin(struct tegra_dc *dc, struct tegra_plane_state *state)
109{
110 unsigned int i;
111 int err;
112
113 for (i = 0; i < state->base.fb->format->num_planes; i++) {
114 struct tegra_bo *bo = tegra_fb_get_plane(state->base.fb, i);
115
116 if (!dc->client.group) {
117 struct sg_table *sgt;
118
119 sgt = host1x_bo_pin(dc->dev, &bo->base, NULL);
120 if (IS_ERR(sgt)) {
121 err = PTR_ERR(sgt);
122 goto unpin;
123 }
124
125 err = dma_map_sg(dc->dev, sgt->sgl, sgt->nents,
126 DMA_TO_DEVICE);
127 if (err == 0) {
128 err = -ENOMEM;
129 goto unpin;
130 }
131
132 state->iova[i] = sg_dma_address(sgt->sgl);
133 state->sgt[i] = sgt;
134 } else {
135 state->iova[i] = bo->iova;
136 }
137 }
138
139 return 0;
140
141unpin:
142 dev_err(dc->dev, "failed to map plane %u: %d\n", i, err);
143
144 while (i--) {
145 struct tegra_bo *bo = tegra_fb_get_plane(state->base.fb, i);
146 struct sg_table *sgt = state->sgt[i];
147
148 dma_unmap_sg(dc->dev, sgt->sgl, sgt->nents, DMA_TO_DEVICE);
149 host1x_bo_unpin(dc->dev, &bo->base, sgt);
150
151 state->iova[i] = DMA_MAPPING_ERROR;
152 state->sgt[i] = NULL;
153 }
154
155 return err;
156}
157
158static void tegra_dc_unpin(struct tegra_dc *dc, struct tegra_plane_state *state)
159{
160 unsigned int i;
161
162 for (i = 0; i < state->base.fb->format->num_planes; i++) {
163 struct tegra_bo *bo = tegra_fb_get_plane(state->base.fb, i);
164
165 if (!dc->client.group) {
166 struct sg_table *sgt = state->sgt[i];
167
168 if (sgt) {
169 dma_unmap_sg(dc->dev, sgt->sgl, sgt->nents,
170 DMA_TO_DEVICE);
171 host1x_bo_unpin(dc->dev, &bo->base, sgt);
172 }
173 }
174
175 state->iova[i] = DMA_MAPPING_ERROR;
176 state->sgt[i] = NULL;
177 }
178}
179
180int tegra_plane_prepare_fb(struct drm_plane *plane,
181 struct drm_plane_state *state)
182{
183 struct tegra_dc *dc = to_tegra_dc(state->crtc);
184
185 if (!state->fb)
186 return 0;
187
188 drm_gem_fb_prepare_fb(plane, state);
189
190 return tegra_dc_pin(dc, to_tegra_plane_state(state));
191}
192
193void tegra_plane_cleanup_fb(struct drm_plane *plane,
194 struct drm_plane_state *state)
195{
196 struct tegra_dc *dc = to_tegra_dc(state->crtc);
197
198 if (dc)
199 tegra_dc_unpin(dc, to_tegra_plane_state(state));
200}
201
98int tegra_plane_state_add(struct tegra_plane *plane,
99 struct drm_plane_state *state)
100{
101 struct drm_crtc_state *crtc_state;
102 struct tegra_dc_state *tegra;
103 int err;
104
105 /* Propagate errors from allocation or locking failures. */

--- 375 unchanged lines hidden ---
202int tegra_plane_state_add(struct tegra_plane *plane,
203 struct drm_plane_state *state)
204{
205 struct drm_crtc_state *crtc_state;
206 struct tegra_dc_state *tegra;
207 int err;
208
209 /* Propagate errors from allocation or locking failures. */

--- 375 unchanged lines hidden ---