blob: 9146aead973ba77b695181e8b4e7f046d499a60d [file] [log] [blame]
Thierry Reding5acd3512017-11-10 15:27:25 +01001/*
2 * Copyright (C) 2017 NVIDIA CORPORATION. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#include <drm/drm_atomic.h>
10#include <drm/drm_atomic_helper.h>
11#include <drm/drm_plane_helper.h>
12
13#include "dc.h"
14#include "plane.h"
15
16static void tegra_plane_destroy(struct drm_plane *plane)
17{
18 struct tegra_plane *p = to_tegra_plane(plane);
19
20 drm_plane_cleanup(plane);
21 kfree(p);
22}
23
24static void tegra_plane_reset(struct drm_plane *plane)
25{
26 struct tegra_plane_state *state;
27
28 if (plane->state)
29 __drm_atomic_helper_plane_destroy_state(plane->state);
30
31 kfree(plane->state);
32 plane->state = NULL;
33
34 state = kzalloc(sizeof(*state), GFP_KERNEL);
35 if (state) {
36 plane->state = &state->base;
37 plane->state->plane = plane;
38 }
39}
40
41static struct drm_plane_state *
42tegra_plane_atomic_duplicate_state(struct drm_plane *plane)
43{
44 struct tegra_plane_state *state = to_tegra_plane_state(plane->state);
45 struct tegra_plane_state *copy;
46
47 copy = kmalloc(sizeof(*copy), GFP_KERNEL);
48 if (!copy)
49 return NULL;
50
51 __drm_atomic_helper_plane_duplicate_state(plane, &copy->base);
52 copy->tiling = state->tiling;
53 copy->format = state->format;
54 copy->swap = state->swap;
55
56 return &copy->base;
57}
58
59static void tegra_plane_atomic_destroy_state(struct drm_plane *plane,
60 struct drm_plane_state *state)
61{
62 __drm_atomic_helper_plane_destroy_state(state);
63 kfree(state);
64}
65
66const struct drm_plane_funcs tegra_plane_funcs = {
67 .update_plane = drm_atomic_helper_update_plane,
68 .disable_plane = drm_atomic_helper_disable_plane,
69 .destroy = tegra_plane_destroy,
70 .reset = tegra_plane_reset,
71 .atomic_duplicate_state = tegra_plane_atomic_duplicate_state,
72 .atomic_destroy_state = tegra_plane_atomic_destroy_state,
73};
74
75int tegra_plane_state_add(struct tegra_plane *plane,
76 struct drm_plane_state *state)
77{
78 struct drm_crtc_state *crtc_state;
79 struct tegra_dc_state *tegra;
80 struct drm_rect clip;
81 int err;
82
83 /* Propagate errors from allocation or locking failures. */
84 crtc_state = drm_atomic_get_crtc_state(state->state, state->crtc);
85 if (IS_ERR(crtc_state))
86 return PTR_ERR(crtc_state);
87
88 clip.x1 = 0;
89 clip.y1 = 0;
90 clip.x2 = crtc_state->mode.hdisplay;
91 clip.y2 = crtc_state->mode.vdisplay;
92
93 /* Check plane state for visibility and calculate clipping bounds */
94 err = drm_atomic_helper_check_plane_state(state, crtc_state, &clip,
95 0, INT_MAX, true, true);
96 if (err < 0)
97 return err;
98
99 tegra = to_dc_state(crtc_state);
100
101 tegra->planes |= WIN_A_ACT_REQ << plane->index;
102
103 return 0;
104}
105
106int tegra_plane_format(u32 fourcc, u32 *format, u32 *swap)
107{
108 /* assume no swapping of fetched data */
109 if (swap)
110 *swap = BYTE_SWAP_NOSWAP;
111
112 switch (fourcc) {
Thierry Reding511c7022017-11-14 16:07:40 +0100113 case DRM_FORMAT_ARGB4444:
114 *format = WIN_COLOR_DEPTH_B4G4R4A4;
Thierry Reding7772fda2017-10-12 17:30:55 +0200115 break;
116
Thierry Reding511c7022017-11-14 16:07:40 +0100117 case DRM_FORMAT_ARGB1555:
118 *format = WIN_COLOR_DEPTH_B5G5R5A1;
Thierry Reding5acd3512017-11-10 15:27:25 +0100119 break;
120
Thierry Reding511c7022017-11-14 16:07:40 +0100121 case DRM_FORMAT_RGB565:
122 *format = WIN_COLOR_DEPTH_B5G6R5;
123 break;
124
125 case DRM_FORMAT_RGBA5551:
126 *format = WIN_COLOR_DEPTH_A1B5G5R5;
Thierry Reding7772fda2017-10-12 17:30:55 +0200127 break;
128
129 case DRM_FORMAT_ARGB8888:
Thierry Reding5acd3512017-11-10 15:27:25 +0100130 *format = WIN_COLOR_DEPTH_B8G8R8A8;
131 break;
132
Thierry Reding511c7022017-11-14 16:07:40 +0100133 case DRM_FORMAT_ABGR8888:
134 *format = WIN_COLOR_DEPTH_R8G8B8A8;
135 break;
136
137 case DRM_FORMAT_ABGR4444:
138 *format = WIN_COLOR_DEPTH_R4G4B4A4;
139 break;
140
141 case DRM_FORMAT_ABGR1555:
142 *format = WIN_COLOR_DEPTH_R5G5B5A;
143 break;
144
145 case DRM_FORMAT_BGRA5551:
146 *format = WIN_COLOR_DEPTH_AR5G5B5;
147 break;
148
149 case DRM_FORMAT_XRGB1555:
150 *format = WIN_COLOR_DEPTH_B5G5R5X1;
151 break;
152
153 case DRM_FORMAT_RGBX5551:
154 *format = WIN_COLOR_DEPTH_X1B5G5R5;
155 break;
156
157 case DRM_FORMAT_XBGR1555:
158 *format = WIN_COLOR_DEPTH_R5G5B5X1;
159 break;
160
161 case DRM_FORMAT_BGRX5551:
162 *format = WIN_COLOR_DEPTH_X1R5G5B5;
163 break;
164
165 case DRM_FORMAT_BGR565:
166 *format = WIN_COLOR_DEPTH_R5G6B5;
167 break;
168
169 case DRM_FORMAT_BGRA8888:
170 *format = WIN_COLOR_DEPTH_A8R8G8B8;
171 break;
172
173 case DRM_FORMAT_RGBA8888:
174 *format = WIN_COLOR_DEPTH_A8B8G8R8;
175 break;
176
177 case DRM_FORMAT_XRGB8888:
178 *format = WIN_COLOR_DEPTH_B8G8R8X8;
179 break;
180
181 case DRM_FORMAT_XBGR8888:
182 *format = WIN_COLOR_DEPTH_R8G8B8X8;
Thierry Reding5acd3512017-11-10 15:27:25 +0100183 break;
184
185 case DRM_FORMAT_UYVY:
186 *format = WIN_COLOR_DEPTH_YCbCr422;
187 break;
188
189 case DRM_FORMAT_YUYV:
190 if (!swap)
191 return -EINVAL;
192
193 *format = WIN_COLOR_DEPTH_YCbCr422;
194 *swap = BYTE_SWAP_SWAP2;
195 break;
196
197 case DRM_FORMAT_YUV420:
198 *format = WIN_COLOR_DEPTH_YCbCr420P;
199 break;
200
201 case DRM_FORMAT_YUV422:
202 *format = WIN_COLOR_DEPTH_YCbCr422P;
203 break;
204
205 default:
206 return -EINVAL;
207 }
208
209 return 0;
210}
211
212bool tegra_plane_format_is_yuv(unsigned int format, bool *planar)
213{
214 switch (format) {
215 case WIN_COLOR_DEPTH_YCbCr422:
216 case WIN_COLOR_DEPTH_YUV422:
217 if (planar)
218 *planar = false;
219
220 return true;
221
222 case WIN_COLOR_DEPTH_YCbCr420P:
223 case WIN_COLOR_DEPTH_YUV420P:
224 case WIN_COLOR_DEPTH_YCbCr422P:
225 case WIN_COLOR_DEPTH_YUV422P:
226 case WIN_COLOR_DEPTH_YCbCr422R:
227 case WIN_COLOR_DEPTH_YUV422R:
228 case WIN_COLOR_DEPTH_YCbCr422RA:
229 case WIN_COLOR_DEPTH_YUV422RA:
230 if (planar)
231 *planar = true;
232
233 return true;
234 }
235
236 if (planar)
237 *planar = false;
238
239 return false;
240}