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 10 static void 11 komeda_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 19 static struct drm_private_state * 20 komeda_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 34 static void 35 komeda_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 43 static 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 48 static 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 63 static struct drm_private_state * 64 komeda_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 78 static void 79 komeda_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 85 static 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 90 static 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 106 static struct drm_private_state * 107 komeda_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 121 static void 122 komeda_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 128 static 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 133 static 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 149 static struct drm_private_state * 150 komeda_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 164 static void 165 komeda_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 171 static 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 176 static 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 193 static struct drm_private_state * 194 komeda_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 208 static 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 214 static 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 219 static 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 236 static struct drm_private_state * 237 komeda_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 251 static void 252 komeda_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 258 static 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 263 static 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 279 static struct drm_private_state * 280 komeda_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 294 static void 295 komeda_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 301 static 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 306 static 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 322 static struct drm_private_state * 323 komeda_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 338 static void 339 komeda_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 345 static 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 350 static 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 366 int 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 425 void 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