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