]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blob - drivers/gpu/drm/amd/display/dc/core/dc_surface.c
941b3671375d68cf19e06535c3d19eaffa7325c4
[mirror_ubuntu-bionic-kernel.git] / drivers / gpu / drm / amd / display / dc / core / dc_surface.c
1 /*
2 * Copyright 2015 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Authors: AMD
23 *
24 */
25
26 /* DC interface (public) */
27 #include "dm_services.h"
28 #include "dc.h"
29
30 /* DC core (private) */
31 #include "core_dc.h"
32 #include "transform.h"
33
34 /*******************************************************************************
35 * Private functions
36 ******************************************************************************/
37 static bool construct(struct dc_context *ctx, struct dc_plane_state *surface)
38 {
39 surface->ctx = ctx;
40 memset(&surface->hdr_static_ctx,
41 0, sizeof(struct dc_hdr_static_metadata));
42 return true;
43 }
44
45 static void destruct(struct dc_plane_state *surface)
46 {
47 if (surface->gamma_correction != NULL) {
48 dc_gamma_release(&surface->gamma_correction);
49 }
50 if (surface->in_transfer_func != NULL) {
51 dc_transfer_func_release(
52 surface->in_transfer_func);
53 surface->in_transfer_func = NULL;
54 }
55 }
56
57 /*******************************************************************************
58 * Public functions
59 ******************************************************************************/
60 void enable_surface_flip_reporting(struct dc_plane_state *surface,
61 uint32_t controller_id)
62 {
63 surface->irq_source = controller_id + DC_IRQ_SOURCE_PFLIP1 - 1;
64 /*register_flip_interrupt(surface);*/
65 }
66
67 struct dc_plane_state *dc_create_surface(const struct dc *dc)
68 {
69 struct core_dc *core_dc = DC_TO_CORE(dc);
70
71 struct dc_plane_state *surface = dm_alloc(sizeof(*surface));
72
73 if (NULL == surface)
74 goto alloc_fail;
75
76 if (false == construct(core_dc->ctx, surface))
77 goto construct_fail;
78
79 ++surface->ref_count;
80
81 return surface;
82
83 construct_fail:
84 dm_free(surface);
85
86 alloc_fail:
87 return NULL;
88 }
89
90 const struct dc_surface_status *dc_surface_get_status(
91 const struct dc_plane_state *dc_surface)
92 {
93 const struct dc_surface_status *surface_status;
94 struct core_dc *core_dc;
95 int i;
96
97 if (!dc_surface ||
98 !dc_surface->ctx ||
99 !dc_surface->ctx->dc) {
100 ASSERT(0);
101 return NULL; /* remove this if above assert never hit */
102 }
103
104 surface_status = &dc_surface->status;
105 core_dc = DC_TO_CORE(dc_surface->ctx->dc);
106
107 if (core_dc->current_context == NULL)
108 return NULL;
109
110 for (i = 0; i < core_dc->res_pool->pipe_count; i++) {
111 struct pipe_ctx *pipe_ctx =
112 &core_dc->current_context->res_ctx.pipe_ctx[i];
113
114 if (pipe_ctx->surface != dc_surface)
115 continue;
116
117 core_dc->hwss.update_pending_status(pipe_ctx);
118 }
119
120 return surface_status;
121 }
122
123 void dc_surface_retain(struct dc_plane_state *surface)
124 {
125 ASSERT(surface->ref_count > 0);
126 ++surface->ref_count;
127 }
128
129 void dc_surface_release(struct dc_plane_state *surface)
130 {
131 ASSERT(surface->ref_count > 0);
132 --surface->ref_count;
133
134 if (surface->ref_count == 0) {
135 destruct(surface);
136 dm_free(surface);
137 }
138 }
139
140 void dc_gamma_retain(struct dc_gamma *gamma)
141 {
142 ASSERT(gamma->ref_count > 0);
143 ++gamma->ref_count;
144 }
145
146 void dc_gamma_release(struct dc_gamma **gamma)
147 {
148 ASSERT((*gamma)->ref_count > 0);
149 --(*gamma)->ref_count;
150
151 if ((*gamma)->ref_count == 0)
152 dm_free((*gamma));
153
154 *gamma = NULL;
155 }
156
157 struct dc_gamma *dc_create_gamma()
158 {
159 struct dc_gamma *gamma = dm_alloc(sizeof(*gamma));
160
161 if (gamma == NULL)
162 goto alloc_fail;
163
164 ++gamma->ref_count;
165
166 return gamma;
167
168 alloc_fail:
169 return NULL;
170 }
171
172 void dc_transfer_func_retain(struct dc_transfer_func *tf)
173 {
174 ASSERT(tf->ref_count > 0);
175 ++tf->ref_count;
176 }
177
178 void dc_transfer_func_release(struct dc_transfer_func *tf)
179 {
180 ASSERT(tf->ref_count > 0);
181 --tf->ref_count;
182
183 if (tf->ref_count == 0)
184 dm_free(tf);
185 }
186
187 struct dc_transfer_func *dc_create_transfer_func()
188 {
189 struct dc_transfer_func *tf = dm_alloc(sizeof(*tf));
190
191 if (tf == NULL)
192 goto alloc_fail;
193
194 ++tf->ref_count;
195
196 return tf;
197
198 alloc_fail:
199 return NULL;
200 }
201
202