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 
48fb735a9fSAnthony Koo struct transfer_func {
49fb735a9fSAnthony Koo 	struct core_transfer_func protected;
50fb735a9fSAnthony Koo 	int ref_count;
51fb735a9fSAnthony Koo };
52fb735a9fSAnthony Koo 
534562236bSHarry Wentland #define DC_SURFACE_TO_SURFACE(dc_surface) container_of(dc_surface, struct surface, protected.public)
544562236bSHarry Wentland #define CORE_SURFACE_TO_SURFACE(core_surface) container_of(core_surface, struct surface, protected)
554562236bSHarry Wentland 
564562236bSHarry Wentland #define DC_GAMMA_TO_GAMMA(dc_gamma) \
574562236bSHarry Wentland 	container_of(dc_gamma, struct gamma, protected.public)
58fb735a9fSAnthony Koo #define DC_TRANSFER_FUNC_TO_TRANSFER_FUNC(dc_tf) \
59fb735a9fSAnthony Koo 	container_of(dc_tf, struct transfer_func, protected.public)
604562236bSHarry Wentland #define CORE_GAMMA_TO_GAMMA(core_gamma) \
614562236bSHarry Wentland 	container_of(core_gamma, struct gamma, protected)
624562236bSHarry Wentland 
634562236bSHarry Wentland /*******************************************************************************
644562236bSHarry Wentland  * Private functions
654562236bSHarry Wentland  ******************************************************************************/
664562236bSHarry Wentland static bool construct(struct dc_context *ctx, struct surface *surface)
674562236bSHarry Wentland {
684562236bSHarry Wentland 	surface->protected.ctx = ctx;
691646a6feSAndrew Wong 	memset(&surface->protected.public.hdr_static_ctx,
701646a6feSAndrew Wong 			0, sizeof(struct dc_hdr_static_metadata));
714562236bSHarry Wentland 	return true;
724562236bSHarry Wentland }
734562236bSHarry Wentland 
744562236bSHarry Wentland static void destruct(struct surface *surface)
754562236bSHarry Wentland {
7680bd2096SYongqiang Sun 	if (surface->protected.public.gamma_correction != NULL) {
77aff20230SYongqiang Sun 		dc_gamma_release(&surface->protected.public.gamma_correction);
7880bd2096SYongqiang Sun 	}
7980bd2096SYongqiang Sun 	if (surface->protected.public.in_transfer_func != NULL) {
80fb735a9fSAnthony Koo 		dc_transfer_func_release(
81fb735a9fSAnthony Koo 				surface->protected.public.in_transfer_func);
8280bd2096SYongqiang Sun 		surface->protected.public.in_transfer_func = NULL;
8380bd2096SYongqiang Sun 	}
844562236bSHarry Wentland }
854562236bSHarry Wentland 
864562236bSHarry Wentland /*******************************************************************************
874562236bSHarry Wentland  * Public functions
884562236bSHarry Wentland  ******************************************************************************/
894562236bSHarry Wentland void enable_surface_flip_reporting(struct dc_surface *dc_surface,
904562236bSHarry Wentland 		uint32_t controller_id)
914562236bSHarry Wentland {
924562236bSHarry Wentland 	struct surface *surface = DC_SURFACE_TO_SURFACE(dc_surface);
934562236bSHarry Wentland 	surface->irq_source = controller_id + DC_IRQ_SOURCE_PFLIP1 - 1;
944562236bSHarry Wentland 	/*register_flip_interrupt(surface);*/
954562236bSHarry Wentland }
964562236bSHarry Wentland 
974562236bSHarry Wentland struct dc_surface *dc_create_surface(const struct dc *dc)
984562236bSHarry Wentland {
994562236bSHarry Wentland 	struct core_dc *core_dc = DC_TO_CORE(dc);
1004562236bSHarry Wentland 
1014562236bSHarry Wentland 	struct surface *surface = dm_alloc(sizeof(*surface));
1024562236bSHarry Wentland 
1034562236bSHarry Wentland 	if (NULL == surface)
1044562236bSHarry Wentland 		goto alloc_fail;
1054562236bSHarry Wentland 
1064562236bSHarry Wentland 	if (false == construct(core_dc->ctx, surface))
1074562236bSHarry Wentland 		goto construct_fail;
1084562236bSHarry Wentland 
109db96c69eSAndrey Grodzovsky 	++surface->ref_count;
1104562236bSHarry Wentland 
1114562236bSHarry Wentland 	return &surface->protected.public;
1124562236bSHarry Wentland 
1134562236bSHarry Wentland construct_fail:
1144562236bSHarry Wentland 	dm_free(surface);
1154562236bSHarry Wentland 
1164562236bSHarry Wentland alloc_fail:
1174562236bSHarry Wentland 	return NULL;
1184562236bSHarry Wentland }
1194562236bSHarry Wentland 
1204562236bSHarry Wentland const struct dc_surface_status *dc_surface_get_status(
1214562236bSHarry Wentland 		const struct dc_surface *dc_surface)
1224562236bSHarry Wentland {
1234562236bSHarry Wentland 	struct dc_surface_status *surface_status;
124e4e354b0STony Cheng 	struct core_surface *core_surface = DC_SURFACE_TO_CORE(dc_surface);;
1254562236bSHarry Wentland 	struct core_dc *core_dc;
1264562236bSHarry Wentland 	int i;
1274562236bSHarry Wentland 
128e4e354b0STony Cheng 	if (!dc_surface ||
129e4e354b0STony Cheng 		!core_surface->ctx ||
130e4e354b0STony Cheng 		!core_surface->ctx->dc) {
131e4e354b0STony Cheng 		ASSERT(0);
132e4e354b0STony Cheng 		return NULL; /* remove this if above assert never hit */
133e4e354b0STony Cheng 	}
1344562236bSHarry Wentland 
1354562236bSHarry Wentland 	surface_status = &core_surface->status;
1364562236bSHarry Wentland 	core_dc = DC_TO_CORE(core_surface->ctx->dc);
1374562236bSHarry Wentland 
1384562236bSHarry Wentland 	if (core_dc->current_context == NULL)
1394562236bSHarry Wentland 		return NULL;
1404562236bSHarry Wentland 
1414562236bSHarry Wentland 	for (i = 0; i < core_dc->current_context->res_ctx.pool->pipe_count;
1424562236bSHarry Wentland 			i++) {
1434562236bSHarry Wentland 		struct pipe_ctx *pipe_ctx =
1444562236bSHarry Wentland 				&core_dc->current_context->res_ctx.pipe_ctx[i];
1454562236bSHarry Wentland 
146e4e354b0STony Cheng 		if (pipe_ctx->surface != core_surface)
1474562236bSHarry Wentland 			continue;
1484562236bSHarry Wentland 
1494562236bSHarry Wentland 		core_dc->hwss.update_pending_status(pipe_ctx);
1504562236bSHarry Wentland 	}
1514562236bSHarry Wentland 
1524562236bSHarry Wentland 	return surface_status;
1534562236bSHarry Wentland }
1544562236bSHarry Wentland 
1554562236bSHarry Wentland void dc_surface_retain(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 
1634562236bSHarry Wentland void dc_surface_release(const struct dc_surface *dc_surface)
1644562236bSHarry Wentland {
1654562236bSHarry Wentland 	struct surface *surface = DC_SURFACE_TO_SURFACE(dc_surface);
1664562236bSHarry Wentland 
167db96c69eSAndrey Grodzovsky 	ASSERT(surface->ref_count > 0);
1684562236bSHarry Wentland 	--surface->ref_count;
1694562236bSHarry Wentland 
1704562236bSHarry Wentland 	if (surface->ref_count == 0) {
1714562236bSHarry Wentland 		destruct(surface);
1724562236bSHarry Wentland 		dm_free(surface);
1734562236bSHarry Wentland 	}
1744562236bSHarry Wentland }
1754562236bSHarry Wentland 
1764562236bSHarry Wentland void dc_gamma_retain(const struct dc_gamma *dc_gamma)
1774562236bSHarry Wentland {
1784562236bSHarry Wentland 	struct gamma *gamma = DC_GAMMA_TO_GAMMA(dc_gamma);
1794562236bSHarry Wentland 
180db96c69eSAndrey Grodzovsky 	ASSERT(gamma->ref_count > 0);
1814562236bSHarry Wentland 	++gamma->ref_count;
1824562236bSHarry Wentland }
1834562236bSHarry Wentland 
184aff20230SYongqiang Sun void dc_gamma_release(const struct dc_gamma **dc_gamma)
1854562236bSHarry Wentland {
186aff20230SYongqiang Sun 	struct gamma *gamma = DC_GAMMA_TO_GAMMA(*dc_gamma);
187db96c69eSAndrey Grodzovsky 
188db96c69eSAndrey Grodzovsky 	ASSERT(gamma->ref_count > 0);
1894562236bSHarry Wentland 	--gamma->ref_count;
1904562236bSHarry Wentland 
191fb735a9fSAnthony Koo 	if (gamma->ref_count == 0)
1924562236bSHarry Wentland 		dm_free(gamma);
193aff20230SYongqiang Sun 
194aff20230SYongqiang Sun 	*dc_gamma = NULL;
1954562236bSHarry Wentland }
1964562236bSHarry Wentland 
1974562236bSHarry Wentland struct dc_gamma *dc_create_gamma()
1984562236bSHarry Wentland {
1994562236bSHarry Wentland 	struct gamma *gamma = dm_alloc(sizeof(*gamma));
2004562236bSHarry Wentland 
2014562236bSHarry Wentland 	if (gamma == NULL)
2024562236bSHarry Wentland 		goto alloc_fail;
2034562236bSHarry Wentland 
204db96c69eSAndrey Grodzovsky 	++gamma->ref_count;
2054562236bSHarry Wentland 
2064562236bSHarry Wentland 	return &gamma->protected.public;
2074562236bSHarry Wentland 
208fb735a9fSAnthony Koo alloc_fail:
209fb735a9fSAnthony Koo 	return NULL;
210fb735a9fSAnthony Koo }
211fb735a9fSAnthony Koo 
212fb735a9fSAnthony Koo void dc_transfer_func_retain(const struct dc_transfer_func *dc_tf)
213fb735a9fSAnthony Koo {
214fb735a9fSAnthony Koo 	struct transfer_func *tf = DC_TRANSFER_FUNC_TO_TRANSFER_FUNC(dc_tf);
215fb735a9fSAnthony Koo 
216db96c69eSAndrey Grodzovsky 	ASSERT(tf->ref_count > 0);
217fb735a9fSAnthony Koo 	++tf->ref_count;
218fb735a9fSAnthony Koo }
219fb735a9fSAnthony Koo 
220fb735a9fSAnthony Koo void dc_transfer_func_release(const struct dc_transfer_func *dc_tf)
221fb735a9fSAnthony Koo {
222fb735a9fSAnthony Koo 	struct transfer_func *tf = DC_TRANSFER_FUNC_TO_TRANSFER_FUNC(dc_tf);
223db96c69eSAndrey Grodzovsky 
224db96c69eSAndrey Grodzovsky 	ASSERT(tf->ref_count > 0);
225fb735a9fSAnthony Koo 	--tf->ref_count;
226fb735a9fSAnthony Koo 
227fb735a9fSAnthony Koo 	if (tf->ref_count == 0)
228fb735a9fSAnthony Koo 		dm_free(tf);
229fb735a9fSAnthony Koo }
230fb735a9fSAnthony Koo 
23190e508baSAnthony Koo struct dc_transfer_func *dc_create_transfer_func()
232fb735a9fSAnthony Koo {
233fb735a9fSAnthony Koo 	struct transfer_func *tf = dm_alloc(sizeof(*tf));
234fb735a9fSAnthony Koo 
235fb735a9fSAnthony Koo 	if (tf == NULL)
236fb735a9fSAnthony Koo 		goto alloc_fail;
237fb735a9fSAnthony Koo 
238db96c69eSAndrey Grodzovsky 	++tf->ref_count;
239fb735a9fSAnthony Koo 
240fb735a9fSAnthony Koo 	return &tf->protected.public;
2414562236bSHarry Wentland 
2424562236bSHarry Wentland alloc_fail:
2434562236bSHarry Wentland 	return NULL;
2444562236bSHarry Wentland }
2454562236bSHarry Wentland 
246fb735a9fSAnthony Koo 
247