14562236bSHarry Wentland /*
24562236bSHarry Wentland  * Copyright 2015 Advanced Micro Devices, Inc.
34562236bSHarry Wentland  *
44562236bSHarry Wentland  * Permission is hereby granted, free of charge, to any person obtaining a
54562236bSHarry Wentland  * copy of this software and associated documentation files (the "Software"),
64562236bSHarry Wentland  * to deal in the Software without restriction, including without limitation
74562236bSHarry Wentland  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
84562236bSHarry Wentland  * and/or sell copies of the Software, and to permit persons to whom the
94562236bSHarry Wentland  * Software is furnished to do so, subject to the following conditions:
104562236bSHarry Wentland  *
114562236bSHarry Wentland  * The above copyright notice and this permission notice shall be included in
124562236bSHarry Wentland  * all copies or substantial portions of the Software.
134562236bSHarry Wentland  *
144562236bSHarry Wentland  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
154562236bSHarry Wentland  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
164562236bSHarry Wentland  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
174562236bSHarry Wentland  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
184562236bSHarry Wentland  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
194562236bSHarry Wentland  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
204562236bSHarry Wentland  * OTHER DEALINGS IN THE SOFTWARE.
214562236bSHarry Wentland  *
224562236bSHarry Wentland  * Authors: AMD
234562236bSHarry Wentland  *
244562236bSHarry Wentland  */
254562236bSHarry Wentland 
264562236bSHarry Wentland /* DC interface (public) */
274562236bSHarry Wentland #include "dm_services.h"
284562236bSHarry Wentland #include "dc.h"
294562236bSHarry Wentland 
304562236bSHarry Wentland /* DC core (private) */
314562236bSHarry Wentland #include "core_dc.h"
324562236bSHarry Wentland #include "transform.h"
334562236bSHarry Wentland 
344562236bSHarry Wentland /*******************************************************************************
354562236bSHarry Wentland  * Private structures
364562236bSHarry Wentland  ******************************************************************************/
374562236bSHarry Wentland struct surface {
384562236bSHarry Wentland 	struct core_surface protected;
394562236bSHarry Wentland 	enum dc_irq_source irq_source;
404562236bSHarry Wentland 	int ref_count;
414562236bSHarry Wentland };
424562236bSHarry Wentland 
434562236bSHarry Wentland struct gamma {
444562236bSHarry Wentland 	struct core_gamma protected;
454562236bSHarry Wentland 	int ref_count;
464562236bSHarry Wentland };
474562236bSHarry Wentland 
484562236bSHarry Wentland #define DC_SURFACE_TO_SURFACE(dc_surface) container_of(dc_surface, struct surface, protected.public)
494562236bSHarry Wentland #define CORE_SURFACE_TO_SURFACE(core_surface) container_of(core_surface, struct surface, protected)
504562236bSHarry Wentland 
514562236bSHarry Wentland #define DC_GAMMA_TO_GAMMA(dc_gamma) \
524562236bSHarry Wentland 	container_of(dc_gamma, struct gamma, protected.public)
534562236bSHarry Wentland #define CORE_GAMMA_TO_GAMMA(core_gamma) \
544562236bSHarry Wentland 	container_of(core_gamma, struct gamma, protected)
554562236bSHarry Wentland 
564562236bSHarry Wentland /*******************************************************************************
574562236bSHarry Wentland  * Private functions
584562236bSHarry Wentland  ******************************************************************************/
594562236bSHarry Wentland static bool construct(struct dc_context *ctx, struct surface *surface)
604562236bSHarry Wentland {
614562236bSHarry Wentland 	surface->protected.ctx = ctx;
621646a6feSAndrew Wong 	memset(&surface->protected.public.hdr_static_ctx,
631646a6feSAndrew Wong 			0, sizeof(struct dc_hdr_static_metadata));
644562236bSHarry Wentland 	return true;
654562236bSHarry Wentland }
664562236bSHarry Wentland 
674562236bSHarry Wentland static void destruct(struct surface *surface)
684562236bSHarry Wentland {
6980bd2096SYongqiang Sun 	if (surface->protected.public.gamma_correction != NULL) {
70aff20230SYongqiang Sun 		dc_gamma_release(&surface->protected.public.gamma_correction);
7180bd2096SYongqiang Sun 	}
7280bd2096SYongqiang Sun 	if (surface->protected.public.in_transfer_func != NULL) {
73fb735a9fSAnthony Koo 		dc_transfer_func_release(
74fb735a9fSAnthony Koo 				surface->protected.public.in_transfer_func);
7580bd2096SYongqiang Sun 		surface->protected.public.in_transfer_func = NULL;
7680bd2096SYongqiang Sun 	}
774562236bSHarry Wentland }
784562236bSHarry Wentland 
794562236bSHarry Wentland /*******************************************************************************
804562236bSHarry Wentland  * Public functions
814562236bSHarry Wentland  ******************************************************************************/
824562236bSHarry Wentland void enable_surface_flip_reporting(struct dc_surface *dc_surface,
834562236bSHarry Wentland 		uint32_t controller_id)
844562236bSHarry Wentland {
854562236bSHarry Wentland 	struct surface *surface = DC_SURFACE_TO_SURFACE(dc_surface);
864562236bSHarry Wentland 	surface->irq_source = controller_id + DC_IRQ_SOURCE_PFLIP1 - 1;
874562236bSHarry Wentland 	/*register_flip_interrupt(surface);*/
884562236bSHarry Wentland }
894562236bSHarry Wentland 
904562236bSHarry Wentland struct dc_surface *dc_create_surface(const struct dc *dc)
914562236bSHarry Wentland {
924562236bSHarry Wentland 	struct core_dc *core_dc = DC_TO_CORE(dc);
934562236bSHarry Wentland 
944562236bSHarry Wentland 	struct surface *surface = dm_alloc(sizeof(*surface));
954562236bSHarry Wentland 
964562236bSHarry Wentland 	if (NULL == surface)
974562236bSHarry Wentland 		goto alloc_fail;
984562236bSHarry Wentland 
994562236bSHarry Wentland 	if (false == construct(core_dc->ctx, surface))
1004562236bSHarry Wentland 		goto construct_fail;
1014562236bSHarry Wentland 
102db96c69eSAndrey Grodzovsky 	++surface->ref_count;
1034562236bSHarry Wentland 
1044562236bSHarry Wentland 	return &surface->protected.public;
1054562236bSHarry Wentland 
1064562236bSHarry Wentland construct_fail:
1074562236bSHarry Wentland 	dm_free(surface);
1084562236bSHarry Wentland 
1094562236bSHarry Wentland alloc_fail:
1104562236bSHarry Wentland 	return NULL;
1114562236bSHarry Wentland }
1124562236bSHarry Wentland 
1134562236bSHarry Wentland const struct dc_surface_status *dc_surface_get_status(
1144562236bSHarry Wentland 		const struct dc_surface *dc_surface)
1154562236bSHarry Wentland {
1164562236bSHarry Wentland 	struct dc_surface_status *surface_status;
11764801369SHarry Wentland 	struct core_surface *core_surface = DC_SURFACE_TO_CORE(dc_surface);
1184562236bSHarry Wentland 	struct core_dc *core_dc;
1194562236bSHarry Wentland 	int i;
1204562236bSHarry Wentland 
121e4e354b0STony Cheng 	if (!dc_surface ||
122e4e354b0STony Cheng 		!core_surface->ctx ||
123e4e354b0STony Cheng 		!core_surface->ctx->dc) {
124e4e354b0STony Cheng 		ASSERT(0);
125e4e354b0STony Cheng 		return NULL; /* remove this if above assert never hit */
126e4e354b0STony Cheng 	}
1274562236bSHarry Wentland 
1284562236bSHarry Wentland 	surface_status = &core_surface->status;
1294562236bSHarry Wentland 	core_dc = DC_TO_CORE(core_surface->ctx->dc);
1304562236bSHarry Wentland 
1314562236bSHarry Wentland 	if (core_dc->current_context == NULL)
1324562236bSHarry Wentland 		return NULL;
1334562236bSHarry Wentland 
134a2b8659dSTony Cheng 	for (i = 0; i < core_dc->res_pool->pipe_count; i++) {
1354562236bSHarry Wentland 		struct pipe_ctx *pipe_ctx =
1364562236bSHarry Wentland 				&core_dc->current_context->res_ctx.pipe_ctx[i];
1374562236bSHarry Wentland 
138e4e354b0STony Cheng 		if (pipe_ctx->surface != core_surface)
1394562236bSHarry Wentland 			continue;
1404562236bSHarry Wentland 
1414562236bSHarry Wentland 		core_dc->hwss.update_pending_status(pipe_ctx);
1424562236bSHarry Wentland 	}
1434562236bSHarry Wentland 
1444562236bSHarry Wentland 	return surface_status;
1454562236bSHarry Wentland }
1464562236bSHarry Wentland 
1474562236bSHarry Wentland void dc_surface_retain(const struct dc_surface *dc_surface)
1484562236bSHarry Wentland {
1494562236bSHarry Wentland 	struct surface *surface = DC_SURFACE_TO_SURFACE(dc_surface);
1504562236bSHarry Wentland 
151db96c69eSAndrey Grodzovsky 	ASSERT(surface->ref_count > 0);
1524562236bSHarry Wentland 	++surface->ref_count;
1534562236bSHarry Wentland }
1544562236bSHarry Wentland 
1554562236bSHarry Wentland void dc_surface_release(const struct dc_surface *dc_surface)
1564562236bSHarry Wentland {
1574562236bSHarry Wentland 	struct surface *surface = DC_SURFACE_TO_SURFACE(dc_surface);
1584562236bSHarry Wentland 
159db96c69eSAndrey Grodzovsky 	ASSERT(surface->ref_count > 0);
1604562236bSHarry Wentland 	--surface->ref_count;
1614562236bSHarry Wentland 
1624562236bSHarry Wentland 	if (surface->ref_count == 0) {
1634562236bSHarry Wentland 		destruct(surface);
1644562236bSHarry Wentland 		dm_free(surface);
1654562236bSHarry Wentland 	}
1664562236bSHarry Wentland }
1674562236bSHarry Wentland 
1684562236bSHarry Wentland void dc_gamma_retain(const struct dc_gamma *dc_gamma)
1694562236bSHarry Wentland {
1704562236bSHarry Wentland 	struct gamma *gamma = DC_GAMMA_TO_GAMMA(dc_gamma);
1714562236bSHarry Wentland 
172db96c69eSAndrey Grodzovsky 	ASSERT(gamma->ref_count > 0);
1734562236bSHarry Wentland 	++gamma->ref_count;
1744562236bSHarry Wentland }
1754562236bSHarry Wentland 
176aff20230SYongqiang Sun void dc_gamma_release(const struct dc_gamma **dc_gamma)
1774562236bSHarry Wentland {
178aff20230SYongqiang Sun 	struct gamma *gamma = DC_GAMMA_TO_GAMMA(*dc_gamma);
179db96c69eSAndrey Grodzovsky 
180db96c69eSAndrey Grodzovsky 	ASSERT(gamma->ref_count > 0);
1814562236bSHarry Wentland 	--gamma->ref_count;
1824562236bSHarry Wentland 
183fb735a9fSAnthony Koo 	if (gamma->ref_count == 0)
1844562236bSHarry Wentland 		dm_free(gamma);
185aff20230SYongqiang Sun 
186aff20230SYongqiang Sun 	*dc_gamma = NULL;
1874562236bSHarry Wentland }
1884562236bSHarry Wentland 
1894562236bSHarry Wentland struct dc_gamma *dc_create_gamma()
1904562236bSHarry Wentland {
1914562236bSHarry Wentland 	struct gamma *gamma = dm_alloc(sizeof(*gamma));
1924562236bSHarry Wentland 
1934562236bSHarry Wentland 	if (gamma == NULL)
1944562236bSHarry Wentland 		goto alloc_fail;
1954562236bSHarry Wentland 
196db96c69eSAndrey Grodzovsky 	++gamma->ref_count;
1974562236bSHarry Wentland 
1984562236bSHarry Wentland 	return &gamma->protected.public;
1994562236bSHarry Wentland 
200fb735a9fSAnthony Koo alloc_fail:
201fb735a9fSAnthony Koo 	return NULL;
202fb735a9fSAnthony Koo }
203fb735a9fSAnthony Koo 
2047b0c470fSLeo (Sunpeng) Li void dc_transfer_func_retain(struct dc_transfer_func *tf)
205fb735a9fSAnthony Koo {
206db96c69eSAndrey Grodzovsky 	ASSERT(tf->ref_count > 0);
207fb735a9fSAnthony Koo 	++tf->ref_count;
208fb735a9fSAnthony Koo }
209fb735a9fSAnthony Koo 
2107b0c470fSLeo (Sunpeng) Li void dc_transfer_func_release(struct dc_transfer_func *tf)
211fb735a9fSAnthony Koo {
212db96c69eSAndrey Grodzovsky 	ASSERT(tf->ref_count > 0);
213fb735a9fSAnthony Koo 	--tf->ref_count;
214fb735a9fSAnthony Koo 
215fb735a9fSAnthony Koo 	if (tf->ref_count == 0)
216fb735a9fSAnthony Koo 		dm_free(tf);
217fb735a9fSAnthony Koo }
218fb735a9fSAnthony Koo 
21990e508baSAnthony Koo struct dc_transfer_func *dc_create_transfer_func()
220fb735a9fSAnthony Koo {
2217b0c470fSLeo (Sunpeng) Li 	struct dc_transfer_func *tf = dm_alloc(sizeof(*tf));
222fb735a9fSAnthony Koo 
223fb735a9fSAnthony Koo 	if (tf == NULL)
224fb735a9fSAnthony Koo 		goto alloc_fail;
225fb735a9fSAnthony Koo 
226db96c69eSAndrey Grodzovsky 	++tf->ref_count;
227fb735a9fSAnthony Koo 
2287b0c470fSLeo (Sunpeng) Li 	return tf;
2294562236bSHarry Wentland 
2304562236bSHarry Wentland alloc_fail:
2314562236bSHarry Wentland 	return NULL;
2324562236bSHarry Wentland }
2334562236bSHarry Wentland 
234fb735a9fSAnthony Koo 
235