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 <drm/drm_atomic.h> 8 #include <drm/drm_atomic_helper.h> 9 #include <drm/drm_plane_helper.h> 10 #include "komeda_dev.h" 11 #include "komeda_kms.h" 12 13 static const struct drm_plane_helper_funcs komeda_plane_helper_funcs = { 14 }; 15 16 static void komeda_plane_destroy(struct drm_plane *plane) 17 { 18 drm_plane_cleanup(plane); 19 20 kfree(to_kplane(plane)); 21 } 22 23 static const struct drm_plane_funcs komeda_plane_funcs = { 24 }; 25 26 /* for komeda, which is pipeline can be share between crtcs */ 27 static u32 get_possible_crtcs(struct komeda_kms_dev *kms, 28 struct komeda_pipeline *pipe) 29 { 30 struct komeda_crtc *crtc; 31 u32 possible_crtcs = 0; 32 int i; 33 34 for (i = 0; i < kms->n_crtcs; i++) { 35 crtc = &kms->crtcs[i]; 36 37 if ((pipe == crtc->master) || (pipe == crtc->slave)) 38 possible_crtcs |= BIT(i); 39 } 40 41 return possible_crtcs; 42 } 43 44 /* use Layer0 as primary */ 45 static u32 get_plane_type(struct komeda_kms_dev *kms, 46 struct komeda_component *c) 47 { 48 bool is_primary = (c->id == KOMEDA_COMPONENT_LAYER0); 49 50 return is_primary ? DRM_PLANE_TYPE_PRIMARY : DRM_PLANE_TYPE_OVERLAY; 51 } 52 53 static int komeda_plane_add(struct komeda_kms_dev *kms, 54 struct komeda_layer *layer) 55 { 56 struct komeda_dev *mdev = kms->base.dev_private; 57 struct komeda_component *c = &layer->base; 58 struct komeda_plane *kplane; 59 struct drm_plane *plane; 60 u32 *formats, n_formats = 0; 61 int err; 62 63 kplane = kzalloc(sizeof(*kplane), GFP_KERNEL); 64 if (!kplane) 65 return -ENOMEM; 66 67 plane = &kplane->base; 68 kplane->layer = layer; 69 70 formats = komeda_get_layer_fourcc_list(&mdev->fmt_tbl, 71 layer->layer_type, &n_formats); 72 73 err = drm_universal_plane_init(&kms->base, plane, 74 get_possible_crtcs(kms, c->pipeline), 75 &komeda_plane_funcs, 76 formats, n_formats, NULL, 77 get_plane_type(kms, c), 78 "%s", c->name); 79 80 komeda_put_fourcc_list(formats); 81 82 if (err) 83 goto cleanup; 84 85 drm_plane_helper_add(plane, &komeda_plane_helper_funcs); 86 87 return 0; 88 cleanup: 89 komeda_plane_destroy(plane); 90 return err; 91 } 92 93 int komeda_kms_add_planes(struct komeda_kms_dev *kms, struct komeda_dev *mdev) 94 { 95 struct komeda_pipeline *pipe; 96 int i, j, err; 97 98 for (i = 0; i < mdev->n_pipelines; i++) { 99 pipe = mdev->pipelines[i]; 100 101 for (j = 0; j < pipe->n_layers; j++) { 102 err = komeda_plane_add(kms, pipe->layers[j]); 103 if (err) 104 return err; 105 } 106 } 107 108 return 0; 109 } 110