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) */
31fb3466a4SBhawanpreet Lakha #include "core_types.h"
324562236bSHarry Wentland #include "transform.h"
33d94585a0SYue Hin Lau #include "dpp.h"
344562236bSHarry Wentland 
354562236bSHarry Wentland /*******************************************************************************
364562236bSHarry Wentland  * Private functions
374562236bSHarry Wentland  ******************************************************************************/
dc_plane_construct(struct dc_context * ctx,struct dc_plane_state * plane_state)38d9e32672SAnthony Koo static void dc_plane_construct(struct dc_context *ctx, struct dc_plane_state *plane_state)
394562236bSHarry Wentland {
403be5262eSHarry Wentland 	plane_state->ctx = ctx;
41e43a432cSAnthony Koo 
42e43a432cSAnthony Koo 	plane_state->gamma_correction = dc_create_gamma();
43ccab1217SKrunoslav Kovac 	if (plane_state->gamma_correction != NULL)
44e43a432cSAnthony Koo 		plane_state->gamma_correction->is_identity = true;
45e43a432cSAnthony Koo 
46e43a432cSAnthony Koo 	plane_state->in_transfer_func = dc_create_transfer_func();
47ccab1217SKrunoslav Kovac 	if (plane_state->in_transfer_func != NULL) {
48e43a432cSAnthony Koo 		plane_state->in_transfer_func->type = TF_TYPE_BYPASS;
494562236bSHarry Wentland 	}
506fbefb84SHarry Wentland 	plane_state->in_shaper_func = dc_create_transfer_func();
516fbefb84SHarry Wentland 	if (plane_state->in_shaper_func != NULL) {
526fbefb84SHarry Wentland 		plane_state->in_shaper_func->type = TF_TYPE_BYPASS;
536fbefb84SHarry Wentland 	}
546fbefb84SHarry Wentland 
556fbefb84SHarry Wentland 	plane_state->lut3d_func = dc_create_3dlut_func();
56ece11e7bSJosip Pavic 
57f99b6f4fSVitaly Prosyak 	plane_state->blend_tf = dc_create_transfer_func();
58f99b6f4fSVitaly Prosyak 	if (plane_state->blend_tf != NULL) {
59f99b6f4fSVitaly Prosyak 		plane_state->blend_tf->type = TF_TYPE_BYPASS;
60f99b6f4fSVitaly Prosyak 	}
616fbefb84SHarry Wentland 
62*76818cddSSung Joon Kim 	plane_state->pre_multiplied_alpha = true;
63*76818cddSSung Joon Kim 
64ccab1217SKrunoslav Kovac }
654562236bSHarry Wentland 
dc_plane_destruct(struct dc_plane_state * plane_state)66d9e32672SAnthony Koo static void dc_plane_destruct(struct dc_plane_state *plane_state)
674562236bSHarry Wentland {
683be5262eSHarry Wentland 	if (plane_state->gamma_correction != NULL) {
693be5262eSHarry Wentland 		dc_gamma_release(&plane_state->gamma_correction);
7080bd2096SYongqiang Sun 	}
713be5262eSHarry Wentland 	if (plane_state->in_transfer_func != NULL) {
72fb735a9fSAnthony Koo 		dc_transfer_func_release(
733be5262eSHarry Wentland 				plane_state->in_transfer_func);
743be5262eSHarry Wentland 		plane_state->in_transfer_func = NULL;
7580bd2096SYongqiang Sun 	}
766fbefb84SHarry Wentland 	if (plane_state->in_shaper_func != NULL) {
776fbefb84SHarry Wentland 		dc_transfer_func_release(
786fbefb84SHarry Wentland 				plane_state->in_shaper_func);
796fbefb84SHarry Wentland 		plane_state->in_shaper_func = NULL;
806fbefb84SHarry Wentland 	}
816fbefb84SHarry Wentland 	if (plane_state->lut3d_func != NULL) {
826fbefb84SHarry Wentland 		dc_3dlut_func_release(
836fbefb84SHarry Wentland 				plane_state->lut3d_func);
846fbefb84SHarry Wentland 		plane_state->lut3d_func = NULL;
856fbefb84SHarry Wentland 	}
86f99b6f4fSVitaly Prosyak 	if (plane_state->blend_tf != NULL) {
87f99b6f4fSVitaly Prosyak 		dc_transfer_func_release(
88f99b6f4fSVitaly Prosyak 				plane_state->blend_tf);
89f99b6f4fSVitaly Prosyak 		plane_state->blend_tf = NULL;
90f99b6f4fSVitaly Prosyak 	}
916fbefb84SHarry Wentland 
924562236bSHarry Wentland }
934562236bSHarry Wentland 
944562236bSHarry Wentland /*******************************************************************************
954562236bSHarry Wentland  * Public functions
964562236bSHarry Wentland  ******************************************************************************/
enable_surface_flip_reporting(struct dc_plane_state * plane_state,uint32_t controller_id)973be5262eSHarry Wentland void enable_surface_flip_reporting(struct dc_plane_state *plane_state,
984562236bSHarry Wentland 		uint32_t controller_id)
994562236bSHarry Wentland {
1003be5262eSHarry Wentland 	plane_state->irq_source = controller_id + DC_IRQ_SOURCE_PFLIP1 - 1;
1014562236bSHarry Wentland 	/*register_flip_interrupt(surface);*/
1024562236bSHarry Wentland }
1034562236bSHarry Wentland 
dc_create_plane_state(struct dc * dc)104fb3466a4SBhawanpreet Lakha struct dc_plane_state *dc_create_plane_state(struct dc *dc)
1054562236bSHarry Wentland {
106f7dbe918SMichel Dänzer 	struct dc_plane_state *plane_state = kvzalloc(sizeof(*plane_state),
1072004f45eSHarry Wentland 							GFP_KERNEL);
1084562236bSHarry Wentland 
1093be5262eSHarry Wentland 	if (NULL == plane_state)
110db6c3bdcSDave Airlie 		return NULL;
1114562236bSHarry Wentland 
1124d090f0fSDave Airlie 	kref_init(&plane_state->refcount);
1132b77dcc5SAnthony Koo 	dc_plane_construct(dc->ctx, plane_state);
1144562236bSHarry Wentland 
1153be5262eSHarry Wentland 	return plane_state;
1164562236bSHarry Wentland }
1174562236bSHarry Wentland 
11825e98237SLee Jones /*
119a27f1996SYasir Al Shekerchi  *****************************************************************************
120a27f1996SYasir Al Shekerchi  *  Function: dc_plane_get_status
121a27f1996SYasir Al Shekerchi  *
122a27f1996SYasir Al Shekerchi  *  @brief
123a27f1996SYasir Al Shekerchi  *     Looks up the pipe context of plane_state and updates the pending status
124a27f1996SYasir Al Shekerchi  *     of the pipe context. Then returns plane_state->status
125a27f1996SYasir Al Shekerchi  *
126a27f1996SYasir Al Shekerchi  *  @param [in] plane_state: pointer to the plane_state to get the status of
127a27f1996SYasir Al Shekerchi  *****************************************************************************
128a27f1996SYasir Al Shekerchi  */
dc_plane_get_status(const struct dc_plane_state * plane_state)1293be5262eSHarry Wentland const struct dc_plane_status *dc_plane_get_status(
1303be5262eSHarry Wentland 		const struct dc_plane_state *plane_state)
1314562236bSHarry Wentland {
1323be5262eSHarry Wentland 	const struct dc_plane_status *plane_status;
1332b77dcc5SAnthony Koo 	struct dc  *dc;
1344562236bSHarry Wentland 	int i;
1354562236bSHarry Wentland 
1363be5262eSHarry Wentland 	if (!plane_state ||
1373be5262eSHarry Wentland 		!plane_state->ctx ||
1383be5262eSHarry Wentland 		!plane_state->ctx->dc) {
139e4e354b0STony Cheng 		ASSERT(0);
140e4e354b0STony Cheng 		return NULL; /* remove this if above assert never hit */
141e4e354b0STony Cheng 	}
1424562236bSHarry Wentland 
1433be5262eSHarry Wentland 	plane_status = &plane_state->status;
1442b77dcc5SAnthony Koo 	dc = plane_state->ctx->dc;
1454562236bSHarry Wentland 
1462b77dcc5SAnthony Koo 	if (dc->current_state == NULL)
1474562236bSHarry Wentland 		return NULL;
1484562236bSHarry Wentland 
149128c075aSWesley Chalmers 	/* Find the current plane state and set its pending bit to false */
1502b77dcc5SAnthony Koo 	for (i = 0; i < dc->res_pool->pipe_count; i++) {
151128c075aSWesley Chalmers 		struct pipe_ctx *pipe_ctx =
1522b77dcc5SAnthony Koo 				&dc->current_state->res_ctx.pipe_ctx[i];
153128c075aSWesley Chalmers 
154128c075aSWesley Chalmers 		if (pipe_ctx->plane_state != plane_state)
155128c075aSWesley Chalmers 			continue;
156128c075aSWesley Chalmers 
157128c075aSWesley Chalmers 		pipe_ctx->plane_state->status.is_flip_pending = false;
158128c075aSWesley Chalmers 
159128c075aSWesley Chalmers 		break;
160128c075aSWesley Chalmers 	}
161128c075aSWesley Chalmers 
1622b77dcc5SAnthony Koo 	for (i = 0; i < dc->res_pool->pipe_count; i++) {
1634562236bSHarry Wentland 		struct pipe_ctx *pipe_ctx =
1642b77dcc5SAnthony Koo 				&dc->current_state->res_ctx.pipe_ctx[i];
1654562236bSHarry Wentland 
1663be5262eSHarry Wentland 		if (pipe_ctx->plane_state != plane_state)
1674562236bSHarry Wentland 			continue;
1684562236bSHarry Wentland 
1692b77dcc5SAnthony Koo 		dc->hwss.update_pending_status(pipe_ctx);
1704562236bSHarry Wentland 	}
1714562236bSHarry Wentland 
1723be5262eSHarry Wentland 	return plane_status;
1734562236bSHarry Wentland }
1744562236bSHarry Wentland 
dc_plane_state_retain(struct dc_plane_state * plane_state)1753be5262eSHarry Wentland void dc_plane_state_retain(struct dc_plane_state *plane_state)
1764562236bSHarry Wentland {
1774d090f0fSDave Airlie 	kref_get(&plane_state->refcount);
1784d090f0fSDave Airlie }
1794d090f0fSDave Airlie 
dc_plane_state_free(struct kref * kref)1804d090f0fSDave Airlie static void dc_plane_state_free(struct kref *kref)
1814d090f0fSDave Airlie {
1824d090f0fSDave Airlie 	struct dc_plane_state *plane_state = container_of(kref, struct dc_plane_state, refcount);
183d9e32672SAnthony Koo 	dc_plane_destruct(plane_state);
184f7dbe918SMichel Dänzer 	kvfree(plane_state);
1854562236bSHarry Wentland }
1864562236bSHarry Wentland 
dc_plane_state_release(struct dc_plane_state * plane_state)1873be5262eSHarry Wentland void dc_plane_state_release(struct dc_plane_state *plane_state)
1884562236bSHarry Wentland {
1894d090f0fSDave Airlie 	kref_put(&plane_state->refcount, dc_plane_state_free);
1904562236bSHarry Wentland }
1914562236bSHarry Wentland 
dc_gamma_retain(struct dc_gamma * gamma)1927a6c4af6SHarry Wentland void dc_gamma_retain(struct dc_gamma *gamma)
1934562236bSHarry Wentland {
1945c58ab0bSDave Airlie 	kref_get(&gamma->refcount);
1955c58ab0bSDave Airlie }
1965c58ab0bSDave Airlie 
dc_gamma_free(struct kref * kref)1975c58ab0bSDave Airlie static void dc_gamma_free(struct kref *kref)
1985c58ab0bSDave Airlie {
1995c58ab0bSDave Airlie 	struct dc_gamma *gamma = container_of(kref, struct dc_gamma, refcount);
200f7dbe918SMichel Dänzer 	kvfree(gamma);
2014562236bSHarry Wentland }
2024562236bSHarry Wentland 
dc_gamma_release(struct dc_gamma ** gamma)2037a6c4af6SHarry Wentland void dc_gamma_release(struct dc_gamma **gamma)
2044562236bSHarry Wentland {
2055c58ab0bSDave Airlie 	kref_put(&(*gamma)->refcount, dc_gamma_free);
2067a6c4af6SHarry Wentland 	*gamma = NULL;
2074562236bSHarry Wentland }
2084562236bSHarry Wentland 
dc_create_gamma(void)209a4718a5bSDave Airlie struct dc_gamma *dc_create_gamma(void)
2104562236bSHarry Wentland {
211f7dbe918SMichel Dänzer 	struct dc_gamma *gamma = kvzalloc(sizeof(*gamma), GFP_KERNEL);
2124562236bSHarry Wentland 
2134562236bSHarry Wentland 	if (gamma == NULL)
2144562236bSHarry Wentland 		goto alloc_fail;
2154562236bSHarry Wentland 
2165c58ab0bSDave Airlie 	kref_init(&gamma->refcount);
2177a6c4af6SHarry Wentland 	return gamma;
2184562236bSHarry Wentland 
219fb735a9fSAnthony Koo alloc_fail:
220fb735a9fSAnthony Koo 	return NULL;
221fb735a9fSAnthony Koo }
222fb735a9fSAnthony Koo 
dc_transfer_func_retain(struct dc_transfer_func * tf)2237b0c470fSLeo (Sunpeng) Li void dc_transfer_func_retain(struct dc_transfer_func *tf)
224fb735a9fSAnthony Koo {
22593052132SDave Airlie 	kref_get(&tf->refcount);
22693052132SDave Airlie }
22793052132SDave Airlie 
dc_transfer_func_free(struct kref * kref)22893052132SDave Airlie static void dc_transfer_func_free(struct kref *kref)
22993052132SDave Airlie {
23093052132SDave Airlie 	struct dc_transfer_func *tf = container_of(kref, struct dc_transfer_func, refcount);
231f7dbe918SMichel Dänzer 	kvfree(tf);
232fb735a9fSAnthony Koo }
233fb735a9fSAnthony Koo 
dc_transfer_func_release(struct dc_transfer_func * tf)2347b0c470fSLeo (Sunpeng) Li void dc_transfer_func_release(struct dc_transfer_func *tf)
235fb735a9fSAnthony Koo {
23693052132SDave Airlie 	kref_put(&tf->refcount, dc_transfer_func_free);
237fb735a9fSAnthony Koo }
238fb735a9fSAnthony Koo 
dc_create_transfer_func(void)2397ac7aebeSColin Ian King struct dc_transfer_func *dc_create_transfer_func(void)
240fb735a9fSAnthony Koo {
241f7dbe918SMichel Dänzer 	struct dc_transfer_func *tf = kvzalloc(sizeof(*tf), GFP_KERNEL);
242fb735a9fSAnthony Koo 
243fb735a9fSAnthony Koo 	if (tf == NULL)
244fb735a9fSAnthony Koo 		goto alloc_fail;
245fb735a9fSAnthony Koo 
24693052132SDave Airlie 	kref_init(&tf->refcount);
247fb735a9fSAnthony Koo 
2487b0c470fSLeo (Sunpeng) Li 	return tf;
2494562236bSHarry Wentland 
2504562236bSHarry Wentland alloc_fail:
2514562236bSHarry Wentland 	return NULL;
2524562236bSHarry Wentland }
2534562236bSHarry Wentland 
dc_3dlut_func_free(struct kref * kref)2546fbefb84SHarry Wentland static void dc_3dlut_func_free(struct kref *kref)
2556fbefb84SHarry Wentland {
2566fbefb84SHarry Wentland 	struct dc_3dlut *lut = container_of(kref, struct dc_3dlut, refcount);
2576fbefb84SHarry Wentland 
2586fbefb84SHarry Wentland 	kvfree(lut);
2596fbefb84SHarry Wentland }
2606fbefb84SHarry Wentland 
dc_create_3dlut_func(void)2616fbefb84SHarry Wentland struct dc_3dlut *dc_create_3dlut_func(void)
2626fbefb84SHarry Wentland {
2636fbefb84SHarry Wentland 	struct dc_3dlut *lut = kvzalloc(sizeof(*lut), GFP_KERNEL);
2646fbefb84SHarry Wentland 
2656fbefb84SHarry Wentland 	if (lut == NULL)
2666fbefb84SHarry Wentland 		goto alloc_fail;
2676fbefb84SHarry Wentland 
2686fbefb84SHarry Wentland 	kref_init(&lut->refcount);
269a2080098SVitaly Prosyak 	lut->state.raw = 0;
2706fbefb84SHarry Wentland 
2716fbefb84SHarry Wentland 	return lut;
2726fbefb84SHarry Wentland 
2736fbefb84SHarry Wentland alloc_fail:
2746fbefb84SHarry Wentland 	return NULL;
2756fbefb84SHarry Wentland 
2766fbefb84SHarry Wentland }
2776fbefb84SHarry Wentland 
dc_3dlut_func_release(struct dc_3dlut * lut)2786fbefb84SHarry Wentland void dc_3dlut_func_release(struct dc_3dlut *lut)
2796fbefb84SHarry Wentland {
2806fbefb84SHarry Wentland 	kref_put(&lut->refcount, dc_3dlut_func_free);
2816fbefb84SHarry Wentland }
2826fbefb84SHarry Wentland 
dc_3dlut_func_retain(struct dc_3dlut * lut)2836fbefb84SHarry Wentland void dc_3dlut_func_retain(struct dc_3dlut *lut)
2846fbefb84SHarry Wentland {
2856fbefb84SHarry Wentland 	kref_get(&lut->refcount);
2866fbefb84SHarry Wentland }
2876fbefb84SHarry Wentland 
288fb735a9fSAnthony Koo 
289