komeda_private_obj.c (10561B)
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * (C) COPYRIGHT 2018 ARM Limited. All rights reserved. 4 * Author: James.Qian.Wang <james.qian.wang@arm.com> 5 * 6 */ 7#include "komeda_dev.h" 8#include "komeda_kms.h" 9 10static void 11komeda_component_state_reset(struct komeda_component_state *st) 12{ 13 st->binding_user = NULL; 14 st->affected_inputs = st->active_inputs; 15 st->active_inputs = 0; 16 st->changed_active_inputs = 0; 17} 18 19static struct drm_private_state * 20komeda_layer_atomic_duplicate_state(struct drm_private_obj *obj) 21{ 22 struct komeda_layer_state *st; 23 24 st = kmemdup(obj->state, sizeof(*st), GFP_KERNEL); 25 if (!st) 26 return NULL; 27 28 komeda_component_state_reset(&st->base); 29 __drm_atomic_helper_private_obj_duplicate_state(obj, &st->base.obj); 30 31 return &st->base.obj; 32} 33 34static void 35komeda_layer_atomic_destroy_state(struct drm_private_obj *obj, 36 struct drm_private_state *state) 37{ 38 struct komeda_layer_state *st = to_layer_st(priv_to_comp_st(state)); 39 40 kfree(st); 41} 42 43static const struct drm_private_state_funcs komeda_layer_obj_funcs = { 44 .atomic_duplicate_state = komeda_layer_atomic_duplicate_state, 45 .atomic_destroy_state = komeda_layer_atomic_destroy_state, 46}; 47 48static int komeda_layer_obj_add(struct komeda_kms_dev *kms, 49 struct komeda_layer *layer) 50{ 51 struct komeda_layer_state *st; 52 53 st = kzalloc(sizeof(*st), GFP_KERNEL); 54 if (!st) 55 return -ENOMEM; 56 57 st->base.component = &layer->base; 58 drm_atomic_private_obj_init(&kms->base, &layer->base.obj, &st->base.obj, 59 &komeda_layer_obj_funcs); 60 return 0; 61} 62 63static struct drm_private_state * 64komeda_scaler_atomic_duplicate_state(struct drm_private_obj *obj) 65{ 66 struct komeda_scaler_state *st; 67 68 st = kmemdup(obj->state, sizeof(*st), GFP_KERNEL); 69 if (!st) 70 return NULL; 71 72 komeda_component_state_reset(&st->base); 73 __drm_atomic_helper_private_obj_duplicate_state(obj, &st->base.obj); 74 75 return &st->base.obj; 76} 77 78static void 79komeda_scaler_atomic_destroy_state(struct drm_private_obj *obj, 80 struct drm_private_state *state) 81{ 82 kfree(to_scaler_st(priv_to_comp_st(state))); 83} 84 85static const struct drm_private_state_funcs komeda_scaler_obj_funcs = { 86 .atomic_duplicate_state = komeda_scaler_atomic_duplicate_state, 87 .atomic_destroy_state = komeda_scaler_atomic_destroy_state, 88}; 89 90static int komeda_scaler_obj_add(struct komeda_kms_dev *kms, 91 struct komeda_scaler *scaler) 92{ 93 struct komeda_scaler_state *st; 94 95 st = kzalloc(sizeof(*st), GFP_KERNEL); 96 if (!st) 97 return -ENOMEM; 98 99 st->base.component = &scaler->base; 100 drm_atomic_private_obj_init(&kms->base, 101 &scaler->base.obj, &st->base.obj, 102 &komeda_scaler_obj_funcs); 103 return 0; 104} 105 106static struct drm_private_state * 107komeda_compiz_atomic_duplicate_state(struct drm_private_obj *obj) 108{ 109 struct komeda_compiz_state *st; 110 111 st = kmemdup(obj->state, sizeof(*st), GFP_KERNEL); 112 if (!st) 113 return NULL; 114 115 komeda_component_state_reset(&st->base); 116 __drm_atomic_helper_private_obj_duplicate_state(obj, &st->base.obj); 117 118 return &st->base.obj; 119} 120 121static void 122komeda_compiz_atomic_destroy_state(struct drm_private_obj *obj, 123 struct drm_private_state *state) 124{ 125 kfree(to_compiz_st(priv_to_comp_st(state))); 126} 127 128static const struct drm_private_state_funcs komeda_compiz_obj_funcs = { 129 .atomic_duplicate_state = komeda_compiz_atomic_duplicate_state, 130 .atomic_destroy_state = komeda_compiz_atomic_destroy_state, 131}; 132 133static int komeda_compiz_obj_add(struct komeda_kms_dev *kms, 134 struct komeda_compiz *compiz) 135{ 136 struct komeda_compiz_state *st; 137 138 st = kzalloc(sizeof(*st), GFP_KERNEL); 139 if (!st) 140 return -ENOMEM; 141 142 st->base.component = &compiz->base; 143 drm_atomic_private_obj_init(&kms->base, &compiz->base.obj, &st->base.obj, 144 &komeda_compiz_obj_funcs); 145 146 return 0; 147} 148 149static struct drm_private_state * 150komeda_splitter_atomic_duplicate_state(struct drm_private_obj *obj) 151{ 152 struct komeda_splitter_state *st; 153 154 st = kmemdup(obj->state, sizeof(*st), GFP_KERNEL); 155 if (!st) 156 return NULL; 157 158 komeda_component_state_reset(&st->base); 159 __drm_atomic_helper_private_obj_duplicate_state(obj, &st->base.obj); 160 161 return &st->base.obj; 162} 163 164static void 165komeda_splitter_atomic_destroy_state(struct drm_private_obj *obj, 166 struct drm_private_state *state) 167{ 168 kfree(to_splitter_st(priv_to_comp_st(state))); 169} 170 171static const struct drm_private_state_funcs komeda_splitter_obj_funcs = { 172 .atomic_duplicate_state = komeda_splitter_atomic_duplicate_state, 173 .atomic_destroy_state = komeda_splitter_atomic_destroy_state, 174}; 175 176static int komeda_splitter_obj_add(struct komeda_kms_dev *kms, 177 struct komeda_splitter *splitter) 178{ 179 struct komeda_splitter_state *st; 180 181 st = kzalloc(sizeof(*st), GFP_KERNEL); 182 if (!st) 183 return -ENOMEM; 184 185 st->base.component = &splitter->base; 186 drm_atomic_private_obj_init(&kms->base, 187 &splitter->base.obj, &st->base.obj, 188 &komeda_splitter_obj_funcs); 189 190 return 0; 191} 192 193static struct drm_private_state * 194komeda_merger_atomic_duplicate_state(struct drm_private_obj *obj) 195{ 196 struct komeda_merger_state *st; 197 198 st = kmemdup(obj->state, sizeof(*st), GFP_KERNEL); 199 if (!st) 200 return NULL; 201 202 komeda_component_state_reset(&st->base); 203 __drm_atomic_helper_private_obj_duplicate_state(obj, &st->base.obj); 204 205 return &st->base.obj; 206} 207 208static void komeda_merger_atomic_destroy_state(struct drm_private_obj *obj, 209 struct drm_private_state *state) 210{ 211 kfree(to_merger_st(priv_to_comp_st(state))); 212} 213 214static const struct drm_private_state_funcs komeda_merger_obj_funcs = { 215 .atomic_duplicate_state = komeda_merger_atomic_duplicate_state, 216 .atomic_destroy_state = komeda_merger_atomic_destroy_state, 217}; 218 219static int komeda_merger_obj_add(struct komeda_kms_dev *kms, 220 struct komeda_merger *merger) 221{ 222 struct komeda_merger_state *st; 223 224 st = kzalloc(sizeof(*st), GFP_KERNEL); 225 if (!st) 226 return -ENOMEM; 227 228 st->base.component = &merger->base; 229 drm_atomic_private_obj_init(&kms->base, 230 &merger->base.obj, &st->base.obj, 231 &komeda_merger_obj_funcs); 232 233 return 0; 234} 235 236static struct drm_private_state * 237komeda_improc_atomic_duplicate_state(struct drm_private_obj *obj) 238{ 239 struct komeda_improc_state *st; 240 241 st = kmemdup(obj->state, sizeof(*st), GFP_KERNEL); 242 if (!st) 243 return NULL; 244 245 komeda_component_state_reset(&st->base); 246 __drm_atomic_helper_private_obj_duplicate_state(obj, &st->base.obj); 247 248 return &st->base.obj; 249} 250 251static void 252komeda_improc_atomic_destroy_state(struct drm_private_obj *obj, 253 struct drm_private_state *state) 254{ 255 kfree(to_improc_st(priv_to_comp_st(state))); 256} 257 258static const struct drm_private_state_funcs komeda_improc_obj_funcs = { 259 .atomic_duplicate_state = komeda_improc_atomic_duplicate_state, 260 .atomic_destroy_state = komeda_improc_atomic_destroy_state, 261}; 262 263static int komeda_improc_obj_add(struct komeda_kms_dev *kms, 264 struct komeda_improc *improc) 265{ 266 struct komeda_improc_state *st; 267 268 st = kzalloc(sizeof(*st), GFP_KERNEL); 269 if (!st) 270 return -ENOMEM; 271 272 st->base.component = &improc->base; 273 drm_atomic_private_obj_init(&kms->base, &improc->base.obj, &st->base.obj, 274 &komeda_improc_obj_funcs); 275 276 return 0; 277} 278 279static struct drm_private_state * 280komeda_timing_ctrlr_atomic_duplicate_state(struct drm_private_obj *obj) 281{ 282 struct komeda_timing_ctrlr_state *st; 283 284 st = kmemdup(obj->state, sizeof(*st), GFP_KERNEL); 285 if (!st) 286 return NULL; 287 288 komeda_component_state_reset(&st->base); 289 __drm_atomic_helper_private_obj_duplicate_state(obj, &st->base.obj); 290 291 return &st->base.obj; 292} 293 294static void 295komeda_timing_ctrlr_atomic_destroy_state(struct drm_private_obj *obj, 296 struct drm_private_state *state) 297{ 298 kfree(to_ctrlr_st(priv_to_comp_st(state))); 299} 300 301static const struct drm_private_state_funcs komeda_timing_ctrlr_obj_funcs = { 302 .atomic_duplicate_state = komeda_timing_ctrlr_atomic_duplicate_state, 303 .atomic_destroy_state = komeda_timing_ctrlr_atomic_destroy_state, 304}; 305 306static int komeda_timing_ctrlr_obj_add(struct komeda_kms_dev *kms, 307 struct komeda_timing_ctrlr *ctrlr) 308{ 309 struct komeda_compiz_state *st; 310 311 st = kzalloc(sizeof(*st), GFP_KERNEL); 312 if (!st) 313 return -ENOMEM; 314 315 st->base.component = &ctrlr->base; 316 drm_atomic_private_obj_init(&kms->base, &ctrlr->base.obj, &st->base.obj, 317 &komeda_timing_ctrlr_obj_funcs); 318 319 return 0; 320} 321 322static struct drm_private_state * 323komeda_pipeline_atomic_duplicate_state(struct drm_private_obj *obj) 324{ 325 struct komeda_pipeline_state *st; 326 327 st = kmemdup(obj->state, sizeof(*st), GFP_KERNEL); 328 if (!st) 329 return NULL; 330 331 st->active_comps = 0; 332 333 __drm_atomic_helper_private_obj_duplicate_state(obj, &st->obj); 334 335 return &st->obj; 336} 337 338static void 339komeda_pipeline_atomic_destroy_state(struct drm_private_obj *obj, 340 struct drm_private_state *state) 341{ 342 kfree(priv_to_pipe_st(state)); 343} 344 345static const struct drm_private_state_funcs komeda_pipeline_obj_funcs = { 346 .atomic_duplicate_state = komeda_pipeline_atomic_duplicate_state, 347 .atomic_destroy_state = komeda_pipeline_atomic_destroy_state, 348}; 349 350static int komeda_pipeline_obj_add(struct komeda_kms_dev *kms, 351 struct komeda_pipeline *pipe) 352{ 353 struct komeda_pipeline_state *st; 354 355 st = kzalloc(sizeof(*st), GFP_KERNEL); 356 if (!st) 357 return -ENOMEM; 358 359 st->pipe = pipe; 360 drm_atomic_private_obj_init(&kms->base, &pipe->obj, &st->obj, 361 &komeda_pipeline_obj_funcs); 362 363 return 0; 364} 365 366int komeda_kms_add_private_objs(struct komeda_kms_dev *kms, 367 struct komeda_dev *mdev) 368{ 369 struct komeda_pipeline *pipe; 370 int i, j, err; 371 372 for (i = 0; i < mdev->n_pipelines; i++) { 373 pipe = mdev->pipelines[i]; 374 375 err = komeda_pipeline_obj_add(kms, pipe); 376 if (err) 377 return err; 378 379 for (j = 0; j < pipe->n_layers; j++) { 380 err = komeda_layer_obj_add(kms, pipe->layers[j]); 381 if (err) 382 return err; 383 } 384 385 if (pipe->wb_layer) { 386 err = komeda_layer_obj_add(kms, pipe->wb_layer); 387 if (err) 388 return err; 389 } 390 391 for (j = 0; j < pipe->n_scalers; j++) { 392 err = komeda_scaler_obj_add(kms, pipe->scalers[j]); 393 if (err) 394 return err; 395 } 396 397 err = komeda_compiz_obj_add(kms, pipe->compiz); 398 if (err) 399 return err; 400 401 if (pipe->splitter) { 402 err = komeda_splitter_obj_add(kms, pipe->splitter); 403 if (err) 404 return err; 405 } 406 407 if (pipe->merger) { 408 err = komeda_merger_obj_add(kms, pipe->merger); 409 if (err) 410 return err; 411 } 412 413 err = komeda_improc_obj_add(kms, pipe->improc); 414 if (err) 415 return err; 416 417 err = komeda_timing_ctrlr_obj_add(kms, pipe->ctrlr); 418 if (err) 419 return err; 420 } 421 422 return 0; 423} 424 425void komeda_kms_cleanup_private_objs(struct komeda_kms_dev *kms) 426{ 427 struct drm_mode_config *config = &kms->base.mode_config; 428 struct drm_private_obj *obj, *next; 429 430 list_for_each_entry_safe(obj, next, &config->privobj_list, head) 431 drm_atomic_private_obj_fini(obj); 432}