FILE
dc_surface.c
File preview with syntax highlighting.
linux-6.19.14/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_types.h" 32#include "transform.h" 33#include "dpp.h" 34 35#include "dc_plane_priv.h" 36 37/******************************************************************************* 38 * Private functions 39 ******************************************************************************/ 40void dc_plane_construct(struct dc_context *ctx, struct dc_plane_state *plane_state) 41{ 42 plane_state->ctx = ctx; 43 44 plane_state->gamma_correction.is_identity = true; 45 46 plane_state->in_transfer_func.type = TF_TYPE_BYPASS; 47 48 plane_state->in_shaper_func.type = TF_TYPE_BYPASS; 49 50 plane_state->lut3d_func.state.raw = 0; 51 52 plane_state->blend_tf.type = TF_TYPE_BYPASS; 53 54 plane_state->pre_multiplied_alpha = true; 55 56} 57 58void dc_plane_destruct(struct dc_plane_state *plane_state) 59{ 60 // no more pointers to free within dc_plane_state 61} 62 63 64/* dc_state is passed in separately since it may differ from the current dc state accessible from plane_state e.g. 65 * if the driver is doing an update from an old context to a new one and the caller wants the pipe mask for the new 66 * context rather than the existing one 67 */ 68uint8_t dc_plane_get_pipe_mask(struct dc_state *dc_state, const struct dc_plane_state *plane_state) 69{ 70 uint8_t pipe_mask = 0; 71 int i; 72 73 for (i = 0; i < plane_state->ctx->dc->res_pool->pipe_count; i++) { 74 struct pipe_ctx *pipe_ctx = &dc_state->res_ctx.pipe_ctx[i]; 75 76 if (pipe_ctx->plane_state == plane_state && pipe_ctx->plane_res.hubp) 77 pipe_mask |= 1 << pipe_ctx->plane_res.hubp->inst; 78 } 79 80 return pipe_mask; 81} 82 83/******************************************************************************* 84 * Public functions 85 ******************************************************************************/ 86struct dc_plane_state *dc_create_plane_state(const struct dc *dc) 87{ 88 struct dc_plane_state *plane_state = kvzalloc(sizeof(*plane_state), 89 GFP_ATOMIC); 90 91 if (NULL == plane_state) 92 return NULL; 93 94 kref_init(&plane_state->refcount); 95 dc_plane_construct(dc->ctx, plane_state); 96 97 return plane_state; 98} 99 100/* 101 ***************************************************************************** 102 * Function: dc_plane_get_status 103 * 104 * @brief 105 * Looks up the pipe context of plane_state and updates the pending status 106 * of the pipe context. Then returns plane_state->status 107 * 108 * @param [in] plane_state: pointer to the plane_state to get the status of 109 ***************************************************************************** 110 */ 111const struct dc_plane_status *dc_plane_get_status( 112 const struct dc_plane_state *plane_state, 113 union dc_plane_status_update_flags flags) 114{ 115 const struct dc_plane_status *plane_status; 116 struct dc *dc; 117 int i; 118 119 if (!plane_state || 120 !plane_state->ctx || 121 !plane_state->ctx->dc) { 122 ASSERT(0); 123 return NULL; /* remove this if above assert never hit */ 124 } 125 126 plane_status = &plane_state->status; 127 dc = plane_state->ctx->dc; 128 129 if (dc->current_state == NULL) 130 return NULL; 131 132 /* Find the current plane state and set its pending bit to false */ 133 for (i = 0; i < dc->res_pool->pipe_count; i++) { 134 struct pipe_ctx *pipe_ctx = 135 &dc->current_state->res_ctx.pipe_ctx[i]; 136 137 if (pipe_ctx->plane_state != plane_state) 138 continue; 139 140 if (pipe_ctx->plane_state && flags.bits.address) 141 pipe_ctx->plane_state->status.is_flip_pending = false; 142 143 break; 144 } 145 146 dc_exit_ips_for_hw_access(dc); 147 148 for (i = 0; i < dc->res_pool->pipe_count; i++) { 149 struct pipe_ctx *pipe_ctx = 150 &dc->current_state->res_ctx.pipe_ctx[i]; 151 152 if (pipe_ctx->plane_state != plane_state) 153 continue; 154 155 if (flags.bits.address) 156 dc->hwss.update_pending_status(pipe_ctx); 157 } 158 159 return plane_status; 160} 161 162void dc_plane_state_retain(struct dc_plane_state *plane_state) 163{ 164 kref_get(&plane_state->refcount); 165} 166 167static void dc_plane_state_free(struct kref *kref) 168{ 169 struct dc_plane_state *plane_state = container_of(kref, struct dc_plane_state, refcount); 170 dc_plane_destruct(plane_state); 171 kvfree(plane_state); 172} 173 174void dc_plane_state_release(struct dc_plane_state *plane_state) 175{ 176 kref_put(&plane_state->refcount, dc_plane_state_free); 177} 178 179void dc_gamma_retain(struct dc_gamma *gamma) 180{ 181 kref_get(&gamma->refcount); 182} 183 184static void dc_gamma_free(struct kref *kref) 185{ 186 struct dc_gamma *gamma = container_of(kref, struct dc_gamma, refcount); 187 kvfree(gamma); 188} 189 190void dc_gamma_release(struct dc_gamma **gamma) 191{ 192 kref_put(&(*gamma)->refcount, dc_gamma_free); 193 *gamma = NULL; 194} 195 196struct dc_gamma *dc_create_gamma(void) 197{ 198 struct dc_gamma *gamma = kvzalloc(sizeof(*gamma), GFP_KERNEL); 199 200 if (gamma == NULL) 201 goto alloc_fail; 202 203 kref_init(&gamma->refcount); 204 return gamma; 205 206alloc_fail: 207 return NULL; 208} 209 210void dc_transfer_func_retain(struct dc_transfer_func *tf) 211{ 212 kref_get(&tf->refcount); 213} 214 215static void dc_transfer_func_free(struct kref *kref) 216{ 217 struct dc_transfer_func *tf = container_of(kref, struct dc_transfer_func, refcount); 218 kvfree(tf); 219} 220 221void dc_transfer_func_release(struct dc_transfer_func *tf) 222{ 223 kref_put(&tf->refcount, dc_transfer_func_free); 224} 225 226struct dc_transfer_func *dc_create_transfer_func(void) 227{ 228 struct dc_transfer_func *tf = kvzalloc(sizeof(*tf), GFP_KERNEL); 229 230 if (tf == NULL) 231 goto alloc_fail; 232 233 kref_init(&tf->refcount); 234 235 return tf; 236 237alloc_fail: 238 return NULL; 239} 240 241static void dc_3dlut_func_free(struct kref *kref) 242{ 243 struct dc_3dlut *lut = container_of(kref, struct dc_3dlut, refcount); 244 245 kvfree(lut); 246} 247 248struct dc_3dlut *dc_create_3dlut_func(void) 249{ 250 struct dc_3dlut *lut = kvzalloc(sizeof(*lut), GFP_KERNEL); 251 252 if (lut == NULL) 253 goto alloc_fail; 254 255 kref_init(&lut->refcount); 256 lut->state.raw = 0; 257 258 return lut; 259 260alloc_fail: 261 return NULL; 262 263} 264 265void dc_3dlut_func_release(struct dc_3dlut *lut) 266{ 267 kref_put(&lut->refcount, dc_3dlut_func_free); 268} 269 270void dc_3dlut_func_retain(struct dc_3dlut *lut) 271{ 272 kref_get(&lut->refcount); 273} 274 275void dc_plane_force_dcc_and_tiling_disable(struct dc_plane_state *plane_state, 276 bool clear_tiling) 277{ 278 struct dc *dc; 279 int i; 280 281 if (!plane_state) 282 return; 283 284 dc = plane_state->ctx->dc; 285 286 if (!dc || !dc->current_state) 287 return; 288 289 for (i = 0; i < dc->res_pool->pipe_count; i++) { 290 struct pipe_ctx *pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i]; 291 292 if (!pipe_ctx) 293 continue; 294 295 if (dc->hwss.clear_surface_dcc_and_tiling) 296 dc->hwss.clear_surface_dcc_and_tiling(pipe_ctx, plane_state, clear_tiling); 297 } 298} 299 300void dc_plane_copy_config(struct dc_plane_state *dst, const struct dc_plane_state *src) 301{ 302 struct kref temp_refcount; 303 304 /* backup persistent info */ 305 memcpy(&temp_refcount, &dst->refcount, sizeof(struct kref)); 306 307 /* copy all configuration information */ 308 memcpy(dst, src, sizeof(struct dc_plane_state)); 309 310 /* restore persistent info */ 311 memcpy(&dst->refcount, &temp_refcount, sizeof(struct kref)); 312}
~/
Read-only file preview.