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_compiz_atomic_duplicate_state(struct drm_private_obj *obj) 65 { 66 struct komeda_compiz_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_compiz_atomic_destroy_state(struct drm_private_obj *obj, 80 struct drm_private_state *state) 81 { 82 kfree(to_compiz_st(priv_to_comp_st(state))); 83 } 84 85 static const struct drm_private_state_funcs komeda_compiz_obj_funcs = { 86 .atomic_duplicate_state = komeda_compiz_atomic_duplicate_state, 87 .atomic_destroy_state = komeda_compiz_atomic_destroy_state, 88 }; 89 90 static int komeda_compiz_obj_add(struct komeda_kms_dev *kms, 91 struct komeda_compiz *compiz) 92 { 93 struct komeda_compiz_state *st; 94 95 st = kzalloc(sizeof(*st), GFP_KERNEL); 96 if (!st) 97 return -ENOMEM; 98 99 st->base.component = &compiz->base; 100 drm_atomic_private_obj_init(&kms->base, &compiz->base.obj, &st->base.obj, 101 &komeda_compiz_obj_funcs); 102 103 return 0; 104 } 105 106 static struct drm_private_state * 107 komeda_improc_atomic_duplicate_state(struct drm_private_obj *obj) 108 { 109 struct komeda_improc_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_improc_atomic_destroy_state(struct drm_private_obj *obj, 123 struct drm_private_state *state) 124 { 125 kfree(to_improc_st(priv_to_comp_st(state))); 126 } 127 128 static const struct drm_private_state_funcs komeda_improc_obj_funcs = { 129 .atomic_duplicate_state = komeda_improc_atomic_duplicate_state, 130 .atomic_destroy_state = komeda_improc_atomic_destroy_state, 131 }; 132 133 static int komeda_improc_obj_add(struct komeda_kms_dev *kms, 134 struct komeda_improc *improc) 135 { 136 struct komeda_improc_state *st; 137 138 st = kzalloc(sizeof(*st), GFP_KERNEL); 139 if (!st) 140 return -ENOMEM; 141 142 st->base.component = &improc->base; 143 drm_atomic_private_obj_init(&kms->base, &improc->base.obj, &st->base.obj, 144 &komeda_improc_obj_funcs); 145 146 return 0; 147 } 148 149 static struct drm_private_state * 150 komeda_timing_ctrlr_atomic_duplicate_state(struct drm_private_obj *obj) 151 { 152 struct komeda_timing_ctrlr_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_timing_ctrlr_atomic_destroy_state(struct drm_private_obj *obj, 166 struct drm_private_state *state) 167 { 168 kfree(to_ctrlr_st(priv_to_comp_st(state))); 169 } 170 171 static const struct drm_private_state_funcs komeda_timing_ctrlr_obj_funcs = { 172 .atomic_duplicate_state = komeda_timing_ctrlr_atomic_duplicate_state, 173 .atomic_destroy_state = komeda_timing_ctrlr_atomic_destroy_state, 174 }; 175 176 static int komeda_timing_ctrlr_obj_add(struct komeda_kms_dev *kms, 177 struct komeda_timing_ctrlr *ctrlr) 178 { 179 struct komeda_compiz_state *st; 180 181 st = kzalloc(sizeof(*st), GFP_KERNEL); 182 if (!st) 183 return -ENOMEM; 184 185 st->base.component = &ctrlr->base; 186 drm_atomic_private_obj_init(&kms->base, &ctrlr->base.obj, &st->base.obj, 187 &komeda_timing_ctrlr_obj_funcs); 188 189 return 0; 190 } 191 192 static struct drm_private_state * 193 komeda_pipeline_atomic_duplicate_state(struct drm_private_obj *obj) 194 { 195 struct komeda_pipeline_state *st; 196 197 st = kmemdup(obj->state, sizeof(*st), GFP_KERNEL); 198 if (!st) 199 return NULL; 200 201 st->active_comps = 0; 202 203 __drm_atomic_helper_private_obj_duplicate_state(obj, &st->obj); 204 205 return &st->obj; 206 } 207 208 static void 209 komeda_pipeline_atomic_destroy_state(struct drm_private_obj *obj, 210 struct drm_private_state *state) 211 { 212 kfree(priv_to_pipe_st(state)); 213 } 214 215 static const struct drm_private_state_funcs komeda_pipeline_obj_funcs = { 216 .atomic_duplicate_state = komeda_pipeline_atomic_duplicate_state, 217 .atomic_destroy_state = komeda_pipeline_atomic_destroy_state, 218 }; 219 220 static int komeda_pipeline_obj_add(struct komeda_kms_dev *kms, 221 struct komeda_pipeline *pipe) 222 { 223 struct komeda_pipeline_state *st; 224 225 st = kzalloc(sizeof(*st), GFP_KERNEL); 226 if (!st) 227 return -ENOMEM; 228 229 st->pipe = pipe; 230 drm_atomic_private_obj_init(&kms->base, &pipe->obj, &st->obj, 231 &komeda_pipeline_obj_funcs); 232 233 return 0; 234 } 235 236 int komeda_kms_add_private_objs(struct komeda_kms_dev *kms, 237 struct komeda_dev *mdev) 238 { 239 struct komeda_pipeline *pipe; 240 int i, j, err; 241 242 for (i = 0; i < mdev->n_pipelines; i++) { 243 pipe = mdev->pipelines[i]; 244 245 err = komeda_pipeline_obj_add(kms, pipe); 246 if (err) 247 return err; 248 249 for (j = 0; j < pipe->n_layers; j++) { 250 err = komeda_layer_obj_add(kms, pipe->layers[j]); 251 if (err) 252 return err; 253 } 254 255 err = komeda_compiz_obj_add(kms, pipe->compiz); 256 if (err) 257 return err; 258 259 err = komeda_improc_obj_add(kms, pipe->improc); 260 if (err) 261 return err; 262 263 err = komeda_timing_ctrlr_obj_add(kms, pipe->ctrlr); 264 if (err) 265 return err; 266 } 267 268 return 0; 269 } 270 271 void komeda_kms_cleanup_private_objs(struct komeda_kms_dev *kms) 272 { 273 struct drm_mode_config *config = &kms->base.mode_config; 274 struct drm_private_obj *obj, *next; 275 276 list_for_each_entry_safe(obj, next, &config->privobj_list, head) 277 drm_atomic_private_obj_fini(obj); 278 } 279