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 <linux/clk.h> 8 #include <linux/pm_runtime.h> 9 #include <linux/spinlock.h> 10 11 #include <drm/drm_atomic.h> 12 #include <drm/drm_atomic_helper.h> 13 #include <drm/drm_crtc_helper.h> 14 #include <drm/drm_plane_helper.h> 15 #include <drm/drm_print.h> 16 #include <drm/drm_vblank.h> 17 18 #include "komeda_dev.h" 19 #include "komeda_kms.h" 20 21 struct drm_crtc_helper_funcs komeda_crtc_helper_funcs = { 22 }; 23 24 static const struct drm_crtc_funcs komeda_crtc_funcs = { 25 }; 26 27 int komeda_kms_setup_crtcs(struct komeda_kms_dev *kms, 28 struct komeda_dev *mdev) 29 { 30 struct komeda_crtc *crtc; 31 struct komeda_pipeline *master; 32 char str[16]; 33 int i; 34 35 kms->n_crtcs = 0; 36 37 for (i = 0; i < mdev->n_pipelines; i++) { 38 crtc = &kms->crtcs[kms->n_crtcs]; 39 master = mdev->pipelines[i]; 40 41 crtc->master = master; 42 crtc->slave = NULL; 43 44 if (crtc->slave) 45 sprintf(str, "pipe-%d", crtc->slave->id); 46 else 47 sprintf(str, "None"); 48 49 DRM_INFO("crtc%d: master(pipe-%d) slave(%s) output: %s.\n", 50 kms->n_crtcs, master->id, str, 51 master->of_output_dev ? 52 master->of_output_dev->full_name : "None"); 53 54 kms->n_crtcs++; 55 } 56 57 return 0; 58 } 59 60 static struct drm_plane * 61 get_crtc_primary(struct komeda_kms_dev *kms, struct komeda_crtc *crtc) 62 { 63 struct komeda_plane *kplane; 64 struct drm_plane *plane; 65 66 drm_for_each_plane(plane, &kms->base) { 67 if (plane->type != DRM_PLANE_TYPE_PRIMARY) 68 continue; 69 70 kplane = to_kplane(plane); 71 /* only master can be primary */ 72 if (kplane->layer->base.pipeline == crtc->master) 73 return plane; 74 } 75 76 return NULL; 77 } 78 79 static int komeda_crtc_add(struct komeda_kms_dev *kms, 80 struct komeda_crtc *kcrtc) 81 { 82 struct drm_crtc *crtc = &kcrtc->base; 83 int err; 84 85 err = drm_crtc_init_with_planes(&kms->base, crtc, 86 get_crtc_primary(kms, kcrtc), NULL, 87 &komeda_crtc_funcs, NULL); 88 if (err) 89 return err; 90 91 drm_crtc_helper_add(crtc, &komeda_crtc_helper_funcs); 92 drm_crtc_vblank_reset(crtc); 93 94 crtc->port = kcrtc->master->of_output_port; 95 96 return 0; 97 } 98 99 int komeda_kms_add_crtcs(struct komeda_kms_dev *kms, struct komeda_dev *mdev) 100 { 101 int i, err; 102 103 for (i = 0; i < kms->n_crtcs; i++) { 104 err = komeda_crtc_add(kms, &kms->crtcs[i]); 105 if (err) 106 return err; 107 } 108 109 return 0; 110 } 111