blob: 78b24aa1ac83d533ff79f82d2faf52a53341d381 [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) {
113 case DRM_FORMAT_XBGR8888:
114 *format = WIN_COLOR_DEPTH_R8G8B8A8;
115 break;
116
117 case DRM_FORMAT_XRGB8888:
118 *format = WIN_COLOR_DEPTH_B8G8R8A8;
119 break;
120
121 case DRM_FORMAT_RGB565:
122 *format = WIN_COLOR_DEPTH_B5G6R5;
123 break;
124
125 case DRM_FORMAT_UYVY:
126 *format = WIN_COLOR_DEPTH_YCbCr422;
127 break;
128
129 case DRM_FORMAT_YUYV:
130 if (!swap)
131 return -EINVAL;
132
133 *format = WIN_COLOR_DEPTH_YCbCr422;
134 *swap = BYTE_SWAP_SWAP2;
135 break;
136
137 case DRM_FORMAT_YUV420:
138 *format = WIN_COLOR_DEPTH_YCbCr420P;
139 break;
140
141 case DRM_FORMAT_YUV422:
142 *format = WIN_COLOR_DEPTH_YCbCr422P;
143 break;
144
145 default:
146 return -EINVAL;
147 }
148
149 return 0;
150}
151
152bool tegra_plane_format_is_yuv(unsigned int format, bool *planar)
153{
154 switch (format) {
155 case WIN_COLOR_DEPTH_YCbCr422:
156 case WIN_COLOR_DEPTH_YUV422:
157 if (planar)
158 *planar = false;
159
160 return true;
161
162 case WIN_COLOR_DEPTH_YCbCr420P:
163 case WIN_COLOR_DEPTH_YUV420P:
164 case WIN_COLOR_DEPTH_YCbCr422P:
165 case WIN_COLOR_DEPTH_YUV422P:
166 case WIN_COLOR_DEPTH_YCbCr422R:
167 case WIN_COLOR_DEPTH_YUV422R:
168 case WIN_COLOR_DEPTH_YCbCr422RA:
169 case WIN_COLOR_DEPTH_YUV422RA:
170 if (planar)
171 *planar = true;
172
173 return true;
174 }
175
176 if (planar)
177 *planar = false;
178
179 return false;
180}