0001
0002
0003
0004
0005
0006
0007 #include "komeda_dev.h"
0008 #include "komeda_kms.h"
0009
0010 static void
0011 komeda_component_state_reset(struct komeda_component_state *st)
0012 {
0013 st->binding_user = NULL;
0014 st->affected_inputs = st->active_inputs;
0015 st->active_inputs = 0;
0016 st->changed_active_inputs = 0;
0017 }
0018
0019 static struct drm_private_state *
0020 komeda_layer_atomic_duplicate_state(struct drm_private_obj *obj)
0021 {
0022 struct komeda_layer_state *st;
0023
0024 st = kmemdup(obj->state, sizeof(*st), GFP_KERNEL);
0025 if (!st)
0026 return NULL;
0027
0028 komeda_component_state_reset(&st->base);
0029 __drm_atomic_helper_private_obj_duplicate_state(obj, &st->base.obj);
0030
0031 return &st->base.obj;
0032 }
0033
0034 static void
0035 komeda_layer_atomic_destroy_state(struct drm_private_obj *obj,
0036 struct drm_private_state *state)
0037 {
0038 struct komeda_layer_state *st = to_layer_st(priv_to_comp_st(state));
0039
0040 kfree(st);
0041 }
0042
0043 static const struct drm_private_state_funcs komeda_layer_obj_funcs = {
0044 .atomic_duplicate_state = komeda_layer_atomic_duplicate_state,
0045 .atomic_destroy_state = komeda_layer_atomic_destroy_state,
0046 };
0047
0048 static int komeda_layer_obj_add(struct komeda_kms_dev *kms,
0049 struct komeda_layer *layer)
0050 {
0051 struct komeda_layer_state *st;
0052
0053 st = kzalloc(sizeof(*st), GFP_KERNEL);
0054 if (!st)
0055 return -ENOMEM;
0056
0057 st->base.component = &layer->base;
0058 drm_atomic_private_obj_init(&kms->base, &layer->base.obj, &st->base.obj,
0059 &komeda_layer_obj_funcs);
0060 return 0;
0061 }
0062
0063 static struct drm_private_state *
0064 komeda_scaler_atomic_duplicate_state(struct drm_private_obj *obj)
0065 {
0066 struct komeda_scaler_state *st;
0067
0068 st = kmemdup(obj->state, sizeof(*st), GFP_KERNEL);
0069 if (!st)
0070 return NULL;
0071
0072 komeda_component_state_reset(&st->base);
0073 __drm_atomic_helper_private_obj_duplicate_state(obj, &st->base.obj);
0074
0075 return &st->base.obj;
0076 }
0077
0078 static void
0079 komeda_scaler_atomic_destroy_state(struct drm_private_obj *obj,
0080 struct drm_private_state *state)
0081 {
0082 kfree(to_scaler_st(priv_to_comp_st(state)));
0083 }
0084
0085 static const struct drm_private_state_funcs komeda_scaler_obj_funcs = {
0086 .atomic_duplicate_state = komeda_scaler_atomic_duplicate_state,
0087 .atomic_destroy_state = komeda_scaler_atomic_destroy_state,
0088 };
0089
0090 static int komeda_scaler_obj_add(struct komeda_kms_dev *kms,
0091 struct komeda_scaler *scaler)
0092 {
0093 struct komeda_scaler_state *st;
0094
0095 st = kzalloc(sizeof(*st), GFP_KERNEL);
0096 if (!st)
0097 return -ENOMEM;
0098
0099 st->base.component = &scaler->base;
0100 drm_atomic_private_obj_init(&kms->base,
0101 &scaler->base.obj, &st->base.obj,
0102 &komeda_scaler_obj_funcs);
0103 return 0;
0104 }
0105
0106 static struct drm_private_state *
0107 komeda_compiz_atomic_duplicate_state(struct drm_private_obj *obj)
0108 {
0109 struct komeda_compiz_state *st;
0110
0111 st = kmemdup(obj->state, sizeof(*st), GFP_KERNEL);
0112 if (!st)
0113 return NULL;
0114
0115 komeda_component_state_reset(&st->base);
0116 __drm_atomic_helper_private_obj_duplicate_state(obj, &st->base.obj);
0117
0118 return &st->base.obj;
0119 }
0120
0121 static void
0122 komeda_compiz_atomic_destroy_state(struct drm_private_obj *obj,
0123 struct drm_private_state *state)
0124 {
0125 kfree(to_compiz_st(priv_to_comp_st(state)));
0126 }
0127
0128 static const struct drm_private_state_funcs komeda_compiz_obj_funcs = {
0129 .atomic_duplicate_state = komeda_compiz_atomic_duplicate_state,
0130 .atomic_destroy_state = komeda_compiz_atomic_destroy_state,
0131 };
0132
0133 static int komeda_compiz_obj_add(struct komeda_kms_dev *kms,
0134 struct komeda_compiz *compiz)
0135 {
0136 struct komeda_compiz_state *st;
0137
0138 st = kzalloc(sizeof(*st), GFP_KERNEL);
0139 if (!st)
0140 return -ENOMEM;
0141
0142 st->base.component = &compiz->base;
0143 drm_atomic_private_obj_init(&kms->base, &compiz->base.obj, &st->base.obj,
0144 &komeda_compiz_obj_funcs);
0145
0146 return 0;
0147 }
0148
0149 static struct drm_private_state *
0150 komeda_splitter_atomic_duplicate_state(struct drm_private_obj *obj)
0151 {
0152 struct komeda_splitter_state *st;
0153
0154 st = kmemdup(obj->state, sizeof(*st), GFP_KERNEL);
0155 if (!st)
0156 return NULL;
0157
0158 komeda_component_state_reset(&st->base);
0159 __drm_atomic_helper_private_obj_duplicate_state(obj, &st->base.obj);
0160
0161 return &st->base.obj;
0162 }
0163
0164 static void
0165 komeda_splitter_atomic_destroy_state(struct drm_private_obj *obj,
0166 struct drm_private_state *state)
0167 {
0168 kfree(to_splitter_st(priv_to_comp_st(state)));
0169 }
0170
0171 static const struct drm_private_state_funcs komeda_splitter_obj_funcs = {
0172 .atomic_duplicate_state = komeda_splitter_atomic_duplicate_state,
0173 .atomic_destroy_state = komeda_splitter_atomic_destroy_state,
0174 };
0175
0176 static int komeda_splitter_obj_add(struct komeda_kms_dev *kms,
0177 struct komeda_splitter *splitter)
0178 {
0179 struct komeda_splitter_state *st;
0180
0181 st = kzalloc(sizeof(*st), GFP_KERNEL);
0182 if (!st)
0183 return -ENOMEM;
0184
0185 st->base.component = &splitter->base;
0186 drm_atomic_private_obj_init(&kms->base,
0187 &splitter->base.obj, &st->base.obj,
0188 &komeda_splitter_obj_funcs);
0189
0190 return 0;
0191 }
0192
0193 static struct drm_private_state *
0194 komeda_merger_atomic_duplicate_state(struct drm_private_obj *obj)
0195 {
0196 struct komeda_merger_state *st;
0197
0198 st = kmemdup(obj->state, sizeof(*st), GFP_KERNEL);
0199 if (!st)
0200 return NULL;
0201
0202 komeda_component_state_reset(&st->base);
0203 __drm_atomic_helper_private_obj_duplicate_state(obj, &st->base.obj);
0204
0205 return &st->base.obj;
0206 }
0207
0208 static void komeda_merger_atomic_destroy_state(struct drm_private_obj *obj,
0209 struct drm_private_state *state)
0210 {
0211 kfree(to_merger_st(priv_to_comp_st(state)));
0212 }
0213
0214 static const struct drm_private_state_funcs komeda_merger_obj_funcs = {
0215 .atomic_duplicate_state = komeda_merger_atomic_duplicate_state,
0216 .atomic_destroy_state = komeda_merger_atomic_destroy_state,
0217 };
0218
0219 static int komeda_merger_obj_add(struct komeda_kms_dev *kms,
0220 struct komeda_merger *merger)
0221 {
0222 struct komeda_merger_state *st;
0223
0224 st = kzalloc(sizeof(*st), GFP_KERNEL);
0225 if (!st)
0226 return -ENOMEM;
0227
0228 st->base.component = &merger->base;
0229 drm_atomic_private_obj_init(&kms->base,
0230 &merger->base.obj, &st->base.obj,
0231 &komeda_merger_obj_funcs);
0232
0233 return 0;
0234 }
0235
0236 static struct drm_private_state *
0237 komeda_improc_atomic_duplicate_state(struct drm_private_obj *obj)
0238 {
0239 struct komeda_improc_state *st;
0240
0241 st = kmemdup(obj->state, sizeof(*st), GFP_KERNEL);
0242 if (!st)
0243 return NULL;
0244
0245 komeda_component_state_reset(&st->base);
0246 __drm_atomic_helper_private_obj_duplicate_state(obj, &st->base.obj);
0247
0248 return &st->base.obj;
0249 }
0250
0251 static void
0252 komeda_improc_atomic_destroy_state(struct drm_private_obj *obj,
0253 struct drm_private_state *state)
0254 {
0255 kfree(to_improc_st(priv_to_comp_st(state)));
0256 }
0257
0258 static const struct drm_private_state_funcs komeda_improc_obj_funcs = {
0259 .atomic_duplicate_state = komeda_improc_atomic_duplicate_state,
0260 .atomic_destroy_state = komeda_improc_atomic_destroy_state,
0261 };
0262
0263 static int komeda_improc_obj_add(struct komeda_kms_dev *kms,
0264 struct komeda_improc *improc)
0265 {
0266 struct komeda_improc_state *st;
0267
0268 st = kzalloc(sizeof(*st), GFP_KERNEL);
0269 if (!st)
0270 return -ENOMEM;
0271
0272 st->base.component = &improc->base;
0273 drm_atomic_private_obj_init(&kms->base, &improc->base.obj, &st->base.obj,
0274 &komeda_improc_obj_funcs);
0275
0276 return 0;
0277 }
0278
0279 static struct drm_private_state *
0280 komeda_timing_ctrlr_atomic_duplicate_state(struct drm_private_obj *obj)
0281 {
0282 struct komeda_timing_ctrlr_state *st;
0283
0284 st = kmemdup(obj->state, sizeof(*st), GFP_KERNEL);
0285 if (!st)
0286 return NULL;
0287
0288 komeda_component_state_reset(&st->base);
0289 __drm_atomic_helper_private_obj_duplicate_state(obj, &st->base.obj);
0290
0291 return &st->base.obj;
0292 }
0293
0294 static void
0295 komeda_timing_ctrlr_atomic_destroy_state(struct drm_private_obj *obj,
0296 struct drm_private_state *state)
0297 {
0298 kfree(to_ctrlr_st(priv_to_comp_st(state)));
0299 }
0300
0301 static const struct drm_private_state_funcs komeda_timing_ctrlr_obj_funcs = {
0302 .atomic_duplicate_state = komeda_timing_ctrlr_atomic_duplicate_state,
0303 .atomic_destroy_state = komeda_timing_ctrlr_atomic_destroy_state,
0304 };
0305
0306 static int komeda_timing_ctrlr_obj_add(struct komeda_kms_dev *kms,
0307 struct komeda_timing_ctrlr *ctrlr)
0308 {
0309 struct komeda_compiz_state *st;
0310
0311 st = kzalloc(sizeof(*st), GFP_KERNEL);
0312 if (!st)
0313 return -ENOMEM;
0314
0315 st->base.component = &ctrlr->base;
0316 drm_atomic_private_obj_init(&kms->base, &ctrlr->base.obj, &st->base.obj,
0317 &komeda_timing_ctrlr_obj_funcs);
0318
0319 return 0;
0320 }
0321
0322 static struct drm_private_state *
0323 komeda_pipeline_atomic_duplicate_state(struct drm_private_obj *obj)
0324 {
0325 struct komeda_pipeline_state *st;
0326
0327 st = kmemdup(obj->state, sizeof(*st), GFP_KERNEL);
0328 if (!st)
0329 return NULL;
0330
0331 st->active_comps = 0;
0332
0333 __drm_atomic_helper_private_obj_duplicate_state(obj, &st->obj);
0334
0335 return &st->obj;
0336 }
0337
0338 static void
0339 komeda_pipeline_atomic_destroy_state(struct drm_private_obj *obj,
0340 struct drm_private_state *state)
0341 {
0342 kfree(priv_to_pipe_st(state));
0343 }
0344
0345 static const struct drm_private_state_funcs komeda_pipeline_obj_funcs = {
0346 .atomic_duplicate_state = komeda_pipeline_atomic_duplicate_state,
0347 .atomic_destroy_state = komeda_pipeline_atomic_destroy_state,
0348 };
0349
0350 static int komeda_pipeline_obj_add(struct komeda_kms_dev *kms,
0351 struct komeda_pipeline *pipe)
0352 {
0353 struct komeda_pipeline_state *st;
0354
0355 st = kzalloc(sizeof(*st), GFP_KERNEL);
0356 if (!st)
0357 return -ENOMEM;
0358
0359 st->pipe = pipe;
0360 drm_atomic_private_obj_init(&kms->base, &pipe->obj, &st->obj,
0361 &komeda_pipeline_obj_funcs);
0362
0363 return 0;
0364 }
0365
0366 int komeda_kms_add_private_objs(struct komeda_kms_dev *kms,
0367 struct komeda_dev *mdev)
0368 {
0369 struct komeda_pipeline *pipe;
0370 int i, j, err;
0371
0372 for (i = 0; i < mdev->n_pipelines; i++) {
0373 pipe = mdev->pipelines[i];
0374
0375 err = komeda_pipeline_obj_add(kms, pipe);
0376 if (err)
0377 return err;
0378
0379 for (j = 0; j < pipe->n_layers; j++) {
0380 err = komeda_layer_obj_add(kms, pipe->layers[j]);
0381 if (err)
0382 return err;
0383 }
0384
0385 if (pipe->wb_layer) {
0386 err = komeda_layer_obj_add(kms, pipe->wb_layer);
0387 if (err)
0388 return err;
0389 }
0390
0391 for (j = 0; j < pipe->n_scalers; j++) {
0392 err = komeda_scaler_obj_add(kms, pipe->scalers[j]);
0393 if (err)
0394 return err;
0395 }
0396
0397 err = komeda_compiz_obj_add(kms, pipe->compiz);
0398 if (err)
0399 return err;
0400
0401 if (pipe->splitter) {
0402 err = komeda_splitter_obj_add(kms, pipe->splitter);
0403 if (err)
0404 return err;
0405 }
0406
0407 if (pipe->merger) {
0408 err = komeda_merger_obj_add(kms, pipe->merger);
0409 if (err)
0410 return err;
0411 }
0412
0413 err = komeda_improc_obj_add(kms, pipe->improc);
0414 if (err)
0415 return err;
0416
0417 err = komeda_timing_ctrlr_obj_add(kms, pipe->ctrlr);
0418 if (err)
0419 return err;
0420 }
0421
0422 return 0;
0423 }
0424
0425 void komeda_kms_cleanup_private_objs(struct komeda_kms_dev *kms)
0426 {
0427 struct drm_mode_config *config = &kms->base.mode_config;
0428 struct drm_private_obj *obj, *next;
0429
0430 list_for_each_entry_safe(obj, next, &config->privobj_list, head)
0431 drm_atomic_private_obj_fini(obj);
0432 }