linux/drivers/gpu/drm/arm/display/komeda/komeda_private_obj.c
<<
>>
Prefs
   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}
 433