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 #ifndef _KOMEDA_KMS_H_ 8 #define _KOMEDA_KMS_H_ 9 10 #include <linux/list.h> 11 #include <drm/drm_atomic.h> 12 #include <drm/drm_atomic_helper.h> 13 #include <drm/drm_blend.h> 14 #include <drm/drm_device.h> 15 #include <drm/drm_writeback.h> 16 #include <drm/drm_print.h> 17 18 /** 19 * struct komeda_plane - komeda instance of drm_plane 20 */ 21 struct komeda_plane { 22 /** @base: &drm_plane */ 23 struct drm_plane base; 24 /** 25 * @layer: 26 * 27 * represents available layer input pipelines for this plane. 28 * 29 * NOTE: 30 * the layer is not for a specific Layer, but indicate a group of 31 * Layers with same capabilities. 32 */ 33 struct komeda_layer *layer; 34 }; 35 36 /** 37 * struct komeda_plane_state 38 * 39 * The plane_state can be split into two data flow (left/right) and handled 40 * by two layers &komeda_plane.layer and &komeda_plane.layer.right 41 */ 42 struct komeda_plane_state { 43 /** @base: &drm_plane_state */ 44 struct drm_plane_state base; 45 /** @zlist_node: zorder list node */ 46 struct list_head zlist_node; 47 48 /** @layer_split: on/off layer_split */ 49 u8 layer_split : 1; 50 }; 51 52 /** 53 * struct komeda_wb_connector 54 */ 55 struct komeda_wb_connector { 56 /** @base: &drm_writeback_connector */ 57 struct drm_writeback_connector base; 58 59 /** @wb_layer: represents associated writeback pipeline of komeda */ 60 struct komeda_layer *wb_layer; 61 }; 62 63 /** 64 * struct komeda_crtc 65 */ 66 struct komeda_crtc { 67 /** @base: &drm_crtc */ 68 struct drm_crtc base; 69 /** @master: only master has display output */ 70 struct komeda_pipeline *master; 71 /** 72 * @slave: optional 73 * 74 * Doesn't have its own display output, the handled data flow will 75 * merge into the master. 76 */ 77 struct komeda_pipeline *slave; 78 79 /** @slave_planes: komeda slave planes mask */ 80 u32 slave_planes; 81 82 /** @wb_conn: komeda write back connector */ 83 struct komeda_wb_connector *wb_conn; 84 85 /** @disable_done: this flip_done is for tracing the disable */ 86 struct completion *disable_done; 87 88 /** @encoder: encoder at the end of the pipeline */ 89 struct drm_encoder encoder; 90 }; 91 92 /** 93 * struct komeda_crtc_state 94 */ 95 struct komeda_crtc_state { 96 /** @base: &drm_crtc_state */ 97 struct drm_crtc_state base; 98 99 /* private properties */ 100 101 /* computed state which are used by validate/check */ 102 /** 103 * @affected_pipes: 104 * the affected pipelines in once display instance 105 */ 106 u32 affected_pipes; 107 /** 108 * @active_pipes: 109 * the active pipelines in once display instance 110 */ 111 u32 active_pipes; 112 113 /** @clock_ratio: ratio of (aclk << 32)/pxlclk */ 114 u64 clock_ratio; 115 116 /** @max_slave_zorder: the maximum of slave zorder */ 117 u32 max_slave_zorder; 118 }; 119 120 /** struct komeda_kms_dev - for gather KMS related things */ 121 struct komeda_kms_dev { 122 /** @base: &drm_device */ 123 struct drm_device base; 124 125 /** @n_crtcs: valid numbers of crtcs in &komeda_kms_dev.crtcs */ 126 int n_crtcs; 127 /** @crtcs: crtcs list */ 128 struct komeda_crtc crtcs[KOMEDA_MAX_PIPELINES]; 129 }; 130 131 #define to_kplane(p) container_of(p, struct komeda_plane, base) 132 #define to_kplane_st(p) container_of(p, struct komeda_plane_state, base) 133 #define to_kconn(p) container_of(p, struct komeda_wb_connector, base) 134 #define to_kcrtc(p) container_of(p, struct komeda_crtc, base) 135 #define to_kcrtc_st(p) container_of(p, struct komeda_crtc_state, base) 136 #define to_kdev(p) container_of(p, struct komeda_kms_dev, base) 137 #define to_wb_conn(x) container_of(x, struct drm_writeback_connector, base) 138 139 static inline bool is_writeback_only(struct drm_crtc_state *st) 140 { 141 struct komeda_wb_connector *wb_conn = to_kcrtc(st->crtc)->wb_conn; 142 struct drm_connector *conn = wb_conn ? &wb_conn->base.base : NULL; 143 144 return conn && (st->connector_mask == BIT(drm_connector_index(conn))); 145 } 146 147 static inline bool 148 is_only_changed_connector(struct drm_crtc_state *st, struct drm_connector *conn) 149 { 150 struct drm_crtc_state *old_st; 151 u32 changed_connectors; 152 153 old_st = drm_atomic_get_old_crtc_state(st->state, st->crtc); 154 changed_connectors = st->connector_mask ^ old_st->connector_mask; 155 156 return BIT(drm_connector_index(conn)) == changed_connectors; 157 } 158 159 static inline bool has_flip_h(u32 rot) 160 { 161 u32 rotation = drm_rotation_simplify(rot, 162 DRM_MODE_ROTATE_0 | 163 DRM_MODE_ROTATE_90 | 164 DRM_MODE_REFLECT_MASK); 165 166 if (rotation & DRM_MODE_ROTATE_90) 167 return !!(rotation & DRM_MODE_REFLECT_Y); 168 else 169 return !!(rotation & DRM_MODE_REFLECT_X); 170 } 171 172 void komeda_crtc_get_color_config(struct drm_crtc_state *crtc_st, 173 u32 *color_depths, u32 *color_formats); 174 unsigned long komeda_crtc_get_aclk(struct komeda_crtc_state *kcrtc_st); 175 176 int komeda_kms_setup_crtcs(struct komeda_kms_dev *kms, struct komeda_dev *mdev); 177 178 int komeda_kms_add_crtcs(struct komeda_kms_dev *kms, struct komeda_dev *mdev); 179 int komeda_kms_add_planes(struct komeda_kms_dev *kms, struct komeda_dev *mdev); 180 int komeda_kms_add_private_objs(struct komeda_kms_dev *kms, 181 struct komeda_dev *mdev); 182 int komeda_kms_add_wb_connectors(struct komeda_kms_dev *kms, 183 struct komeda_dev *mdev); 184 void komeda_kms_cleanup_private_objs(struct komeda_kms_dev *kms); 185 186 void komeda_crtc_handle_event(struct komeda_crtc *kcrtc, 187 struct komeda_events *evts); 188 void komeda_crtc_flush_and_wait_for_flip_done(struct komeda_crtc *kcrtc, 189 struct completion *input_flip_done); 190 191 struct komeda_kms_dev *komeda_kms_attach(struct komeda_dev *mdev); 192 void komeda_kms_detach(struct komeda_kms_dev *kms); 193 void komeda_kms_shutdown(struct komeda_kms_dev *kms); 194 void komeda_pipeline_dump(struct komeda_pipeline *pipe); 195 196 #endif /*_KOMEDA_KMS_H_*/ 197