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_types.h"
32 #include "transform.h"
33 
34 /*******************************************************************************
35  * Private functions
36  ******************************************************************************/
37 static bool construct(struct dc_context *ctx, struct dc_plane_state *plane_state)
38 {
39 	plane_state->ctx = ctx;
40 	memset(&plane_state->hdr_static_ctx,
41 			0, sizeof(struct dc_hdr_static_metadata));
42 	return true;
43 }
44 
45 static void destruct(struct dc_plane_state *plane_state)
46 {
47 	if (plane_state->gamma_correction != NULL) {
48 		dc_gamma_release(&plane_state->gamma_correction);
49 	}
50 	if (plane_state->in_transfer_func != NULL) {
51 		dc_transfer_func_release(
52 				plane_state->in_transfer_func);
53 		plane_state->in_transfer_func = NULL;
54 	}
55 }
56 
57 /*******************************************************************************
58  * Public functions
59  ******************************************************************************/
60 void enable_surface_flip_reporting(struct dc_plane_state *plane_state,
61 		uint32_t controller_id)
62 {
63 	plane_state->irq_source = controller_id + DC_IRQ_SOURCE_PFLIP1 - 1;
64 	/*register_flip_interrupt(surface);*/
65 }
66 
67 struct dc_plane_state *dc_create_plane_state(struct dc *dc)
68 {
69 	struct dc *core_dc = dc;
70 
71 	struct dc_plane_state *plane_state = dm_alloc(sizeof(*plane_state));
72 
73 	if (NULL == plane_state)
74 		goto alloc_fail;
75 
76 	if (false == construct(core_dc->ctx, plane_state))
77 		goto construct_fail;
78 
79 	atomic_inc(&plane_state->ref_count);
80 
81 	return plane_state;
82 
83 construct_fail:
84 	dm_free(plane_state);
85 
86 alloc_fail:
87 	return NULL;
88 }
89 
90 const struct dc_plane_status *dc_plane_get_status(
91 		const struct dc_plane_state *plane_state)
92 {
93 	const struct dc_plane_status *plane_status;
94 	struct dc  *core_dc;
95 	int i;
96 
97 	if (!plane_state ||
98 		!plane_state->ctx ||
99 		!plane_state->ctx->dc) {
100 		ASSERT(0);
101 		return NULL; /* remove this if above assert never hit */
102 	}
103 
104 	plane_status = &plane_state->status;
105 	core_dc = plane_state->ctx->dc;
106 
107 	if (core_dc->current_state == 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_state->res_ctx.pipe_ctx[i];
113 
114 		if (pipe_ctx->plane_state != plane_state)
115 			continue;
116 
117 		core_dc->hwss.update_pending_status(pipe_ctx);
118 	}
119 
120 	return plane_status;
121 }
122 
123 void dc_plane_state_retain(struct dc_plane_state *plane_state)
124 {
125 	ASSERT(atomic_read(&plane_state->ref_count) > 0);
126 	atomic_inc(&plane_state->ref_count);
127 }
128 
129 void dc_plane_state_release(struct dc_plane_state *plane_state)
130 {
131 	ASSERT(atomic_read(&plane_state->ref_count) > 0);
132 	atomic_dec(&plane_state->ref_count);
133 
134 	if (atomic_read(&plane_state->ref_count) == 0) {
135 		destruct(plane_state);
136 		dm_free(plane_state);
137 	}
138 }
139 
140 void dc_gamma_retain(struct dc_gamma *gamma)
141 {
142 	ASSERT(atomic_read(&gamma->ref_count) > 0);
143 	atomic_inc(&gamma->ref_count);
144 }
145 
146 void dc_gamma_release(struct dc_gamma **gamma)
147 {
148 	ASSERT(atomic_read(&(*gamma)->ref_count) > 0);
149 	atomic_dec(&(*gamma)->ref_count);
150 
151 	if (atomic_read(&(*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 	atomic_inc(&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(atomic_read(&tf->ref_count) > 0);
175 	atomic_inc(&tf->ref_count);
176 }
177 
178 void dc_transfer_func_release(struct dc_transfer_func *tf)
179 {
180 	ASSERT(atomic_read(&tf->ref_count) > 0);
181 	atomic_dec(&tf->ref_count);
182 
183 	if (atomic_read(&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 	atomic_inc(&tf->ref_count);
195 
196 	return tf;
197 
198 alloc_fail:
199 	return NULL;
200 }
201 
202 
203