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_dc.h" 32 #include "transform.h" 33 34 /******************************************************************************* 35 * Private structures 36 ******************************************************************************/ 37 struct surface { 38 struct core_surface protected; 39 enum dc_irq_source irq_source; 40 int ref_count; 41 }; 42 43 struct gamma { 44 struct core_gamma protected; 45 int ref_count; 46 }; 47 48 #define DC_SURFACE_TO_SURFACE(dc_surface) container_of(dc_surface, struct surface, protected.public) 49 #define CORE_SURFACE_TO_SURFACE(core_surface) container_of(core_surface, struct surface, protected) 50 51 #define DC_GAMMA_TO_GAMMA(dc_gamma) \ 52 container_of(dc_gamma, struct gamma, protected.public) 53 #define CORE_GAMMA_TO_GAMMA(core_gamma) \ 54 container_of(core_gamma, struct gamma, protected) 55 56 /******************************************************************************* 57 * Private functions 58 ******************************************************************************/ 59 static bool construct(struct dc_context *ctx, struct surface *surface) 60 { 61 surface->protected.ctx = ctx; 62 return true; 63 } 64 65 static void destruct(struct surface *surface) 66 { 67 if (surface->protected.public.gamma_correction != NULL) 68 dc_gamma_release(surface->protected.public.gamma_correction); 69 } 70 71 /******************************************************************************* 72 * Public functions 73 ******************************************************************************/ 74 void enable_surface_flip_reporting(struct dc_surface *dc_surface, 75 uint32_t controller_id) 76 { 77 struct surface *surface = DC_SURFACE_TO_SURFACE(dc_surface); 78 surface->irq_source = controller_id + DC_IRQ_SOURCE_PFLIP1 - 1; 79 /*register_flip_interrupt(surface);*/ 80 } 81 82 struct dc_surface *dc_create_surface(const struct dc *dc) 83 { 84 struct core_dc *core_dc = DC_TO_CORE(dc); 85 86 struct surface *surface = dm_alloc(sizeof(*surface)); 87 88 if (NULL == surface) 89 goto alloc_fail; 90 91 if (false == construct(core_dc->ctx, surface)) 92 goto construct_fail; 93 94 dc_surface_retain(&surface->protected.public); 95 96 return &surface->protected.public; 97 98 construct_fail: 99 dm_free(surface); 100 101 alloc_fail: 102 return NULL; 103 } 104 105 const struct dc_surface_status *dc_surface_get_status( 106 const struct dc_surface *dc_surface) 107 { 108 struct dc_surface_status *surface_status; 109 struct core_surface *core_surface; 110 struct core_dc *core_dc; 111 int i; 112 113 if (dc_surface == NULL) 114 return NULL; 115 116 core_surface = DC_SURFACE_TO_CORE(dc_surface); 117 118 if (core_surface == NULL || core_surface->ctx == NULL) 119 return NULL; 120 121 surface_status = &core_surface->status; 122 123 if (core_surface->ctx == NULL || core_surface->ctx->dc == NULL) 124 return NULL; 125 126 core_dc = DC_TO_CORE(core_surface->ctx->dc); 127 128 129 if (core_dc->current_context == NULL) 130 return NULL; 131 132 for (i = 0; i < core_dc->current_context->res_ctx.pool->pipe_count; 133 i++) { 134 struct pipe_ctx *pipe_ctx = 135 &core_dc->current_context->res_ctx.pipe_ctx[i]; 136 137 if (pipe_ctx->surface != 138 DC_SURFACE_TO_CORE(dc_surface)) 139 continue; 140 141 core_dc->hwss.update_pending_status(pipe_ctx); 142 } 143 144 return surface_status; 145 } 146 147 void dc_surface_retain(const struct dc_surface *dc_surface) 148 { 149 struct surface *surface = DC_SURFACE_TO_SURFACE(dc_surface); 150 151 ++surface->ref_count; 152 } 153 154 void dc_surface_release(const struct dc_surface *dc_surface) 155 { 156 struct surface *surface = DC_SURFACE_TO_SURFACE(dc_surface); 157 158 --surface->ref_count; 159 160 if (surface->ref_count == 0) { 161 destruct(surface); 162 dm_free(surface); 163 } 164 } 165 166 static bool construct_gamma(struct gamma *gamma) 167 { 168 return true; 169 } 170 171 static void destruct_gamma(struct gamma *gamma) 172 { 173 174 } 175 176 void dc_gamma_retain(const struct dc_gamma *dc_gamma) 177 { 178 struct gamma *gamma = DC_GAMMA_TO_GAMMA(dc_gamma); 179 180 ++gamma->ref_count; 181 } 182 183 void dc_gamma_release(const struct dc_gamma *dc_gamma) 184 { 185 struct gamma *gamma = DC_GAMMA_TO_GAMMA(dc_gamma); 186 --gamma->ref_count; 187 188 if (gamma->ref_count == 0) { 189 destruct_gamma(gamma); 190 dm_free(gamma); 191 } 192 } 193 194 struct dc_gamma *dc_create_gamma() 195 { 196 struct gamma *gamma = dm_alloc(sizeof(*gamma)); 197 198 if (gamma == NULL) 199 goto alloc_fail; 200 201 if (false == construct_gamma(gamma)) 202 goto construct_fail; 203 204 dc_gamma_retain(&gamma->protected.public); 205 206 return &gamma->protected.public; 207 208 construct_fail: 209 dm_free(gamma); 210 211 alloc_fail: 212 return NULL; 213 } 214 215