433 lines · c
1// SPDX-License-Identifier: GPL-2.02/*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 void11komeda_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 void35komeda_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 void79komeda_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 void122komeda_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 void165komeda_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 void252komeda_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 void295komeda_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 void339komeda_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}433