161f1c4a8Sjames qian wang (Arm Technology China) /* SPDX-License-Identifier: GPL-2.0 */
261f1c4a8Sjames qian wang (Arm Technology China) /*
361f1c4a8Sjames qian wang (Arm Technology China)  * (C) COPYRIGHT 2018 ARM Limited. All rights reserved.
461f1c4a8Sjames qian wang (Arm Technology China)  * Author: James.Qian.Wang <james.qian.wang@arm.com>
561f1c4a8Sjames qian wang (Arm Technology China)  *
661f1c4a8Sjames qian wang (Arm Technology China)  */
761f1c4a8Sjames qian wang (Arm Technology China) #ifndef _KOMEDA_KMS_H_
861f1c4a8Sjames qian wang (Arm Technology China) #define _KOMEDA_KMS_H_
961f1c4a8Sjames qian wang (Arm Technology China) 
10109bd7d5SLowry Li (Arm Technology China) #include <linux/list.h>
1161f1c4a8Sjames qian wang (Arm Technology China) #include <drm/drm_atomic.h>
1261f1c4a8Sjames qian wang (Arm Technology China) #include <drm/drm_atomic_helper.h>
1361f1c4a8Sjames qian wang (Arm Technology China) #include <drm/drm_crtc_helper.h>
146649a95dSSam Ravnborg #include <drm/drm_device.h>
1561f1c4a8Sjames qian wang (Arm Technology China) #include <drm/drm_writeback.h>
165d51f6c0Sjames qian wang (Arm Technology China) #include <drm/drm_print.h>
17f5f0a68eSjames qian wang (Arm Technology China) #include <video/videomode.h>
18f5f0a68eSjames qian wang (Arm Technology China) #include <video/display_timing.h>
1961f1c4a8Sjames qian wang (Arm Technology China) 
208c919745Sjames qian wang (Arm Technology China) /**
218c919745Sjames qian wang (Arm Technology China)  * struct komeda_plane - komeda instance of drm_plane
228c919745Sjames qian wang (Arm Technology China)  */
2361f1c4a8Sjames qian wang (Arm Technology China) struct komeda_plane {
2461f1c4a8Sjames qian wang (Arm Technology China) 	/** @base: &drm_plane */
2561f1c4a8Sjames qian wang (Arm Technology China) 	struct drm_plane base;
2661f1c4a8Sjames qian wang (Arm Technology China) 	/**
2761f1c4a8Sjames qian wang (Arm Technology China) 	 * @layer:
2861f1c4a8Sjames qian wang (Arm Technology China) 	 *
2961f1c4a8Sjames qian wang (Arm Technology China) 	 * represents available layer input pipelines for this plane.
3061f1c4a8Sjames qian wang (Arm Technology China) 	 *
3161f1c4a8Sjames qian wang (Arm Technology China) 	 * NOTE:
3261f1c4a8Sjames qian wang (Arm Technology China) 	 * the layer is not for a specific Layer, but indicate a group of
3361f1c4a8Sjames qian wang (Arm Technology China) 	 * Layers with same capabilities.
3461f1c4a8Sjames qian wang (Arm Technology China) 	 */
3561f1c4a8Sjames qian wang (Arm Technology China) 	struct komeda_layer *layer;
3661f1c4a8Sjames qian wang (Arm Technology China) };
3761f1c4a8Sjames qian wang (Arm Technology China) 
3861f1c4a8Sjames qian wang (Arm Technology China) /**
3961f1c4a8Sjames qian wang (Arm Technology China)  * struct komeda_plane_state
4061f1c4a8Sjames qian wang (Arm Technology China)  *
4161f1c4a8Sjames qian wang (Arm Technology China)  * The plane_state can be split into two data flow (left/right) and handled
4261f1c4a8Sjames qian wang (Arm Technology China)  * by two layers &komeda_plane.layer and &komeda_plane.layer.right
4361f1c4a8Sjames qian wang (Arm Technology China)  */
4461f1c4a8Sjames qian wang (Arm Technology China) struct komeda_plane_state {
4561f1c4a8Sjames qian wang (Arm Technology China) 	/** @base: &drm_plane_state */
4661f1c4a8Sjames qian wang (Arm Technology China) 	struct drm_plane_state base;
47109bd7d5SLowry Li (Arm Technology China) 	/** @zlist_node: zorder list node */
48109bd7d5SLowry Li (Arm Technology China) 	struct list_head zlist_node;
4961f1c4a8Sjames qian wang (Arm Technology China) 
50990dee3aSjames qian wang (Arm Technology China) 	/** @layer_split: on/off layer_split */
51990dee3aSjames qian wang (Arm Technology China) 	u8 layer_split : 1;
5261f1c4a8Sjames qian wang (Arm Technology China) };
5361f1c4a8Sjames qian wang (Arm Technology China) 
5461f1c4a8Sjames qian wang (Arm Technology China) /**
5561f1c4a8Sjames qian wang (Arm Technology China)  * struct komeda_wb_connector
5661f1c4a8Sjames qian wang (Arm Technology China)  */
5761f1c4a8Sjames qian wang (Arm Technology China) struct komeda_wb_connector {
5861f1c4a8Sjames qian wang (Arm Technology China) 	/** @base: &drm_writeback_connector */
5961f1c4a8Sjames qian wang (Arm Technology China) 	struct drm_writeback_connector base;
6061f1c4a8Sjames qian wang (Arm Technology China) 
6161f1c4a8Sjames qian wang (Arm Technology China) 	/** @wb_layer: represents associated writeback pipeline of komeda */
6261f1c4a8Sjames qian wang (Arm Technology China) 	struct komeda_layer *wb_layer;
6361f1c4a8Sjames qian wang (Arm Technology China) };
6461f1c4a8Sjames qian wang (Arm Technology China) 
6561f1c4a8Sjames qian wang (Arm Technology China) /**
6661f1c4a8Sjames qian wang (Arm Technology China)  * struct komeda_crtc
6761f1c4a8Sjames qian wang (Arm Technology China)  */
6861f1c4a8Sjames qian wang (Arm Technology China) struct komeda_crtc {
6961f1c4a8Sjames qian wang (Arm Technology China) 	/** @base: &drm_crtc */
7061f1c4a8Sjames qian wang (Arm Technology China) 	struct drm_crtc base;
7161f1c4a8Sjames qian wang (Arm Technology China) 	/** @master: only master has display output */
7261f1c4a8Sjames qian wang (Arm Technology China) 	struct komeda_pipeline *master;
7361f1c4a8Sjames qian wang (Arm Technology China) 	/**
7461f1c4a8Sjames qian wang (Arm Technology China) 	 * @slave: optional
7561f1c4a8Sjames qian wang (Arm Technology China) 	 *
7661f1c4a8Sjames qian wang (Arm Technology China) 	 * Doesn't have its own display output, the handled data flow will
7761f1c4a8Sjames qian wang (Arm Technology China) 	 * merge into the master.
7861f1c4a8Sjames qian wang (Arm Technology China) 	 */
7961f1c4a8Sjames qian wang (Arm Technology China) 	struct komeda_pipeline *slave;
80b7925b61Sjames qian wang (Arm Technology China) 
813b9dfa4eSLowry Li (Arm Technology China) 	/** @slave_planes: komeda slave planes mask */
823b9dfa4eSLowry Li (Arm Technology China) 	u32 slave_planes;
833b9dfa4eSLowry Li (Arm Technology China) 
845d51f6c0Sjames qian wang (Arm Technology China) 	/** @wb_conn: komeda write back connector */
855d51f6c0Sjames qian wang (Arm Technology China) 	struct komeda_wb_connector *wb_conn;
865d51f6c0Sjames qian wang (Arm Technology China) 
878c919745Sjames qian wang (Arm Technology China) 	/** @disable_done: this flip_done is for tracing the disable */
88b7925b61Sjames qian wang (Arm Technology China) 	struct completion *disable_done;
8961f1c4a8Sjames qian wang (Arm Technology China) };
9061f1c4a8Sjames qian wang (Arm Technology China) 
918c919745Sjames qian wang (Arm Technology China) /**
928c919745Sjames qian wang (Arm Technology China)  * struct komeda_crtc_state
938c919745Sjames qian wang (Arm Technology China)  */
9461f1c4a8Sjames qian wang (Arm Technology China) struct komeda_crtc_state {
9561f1c4a8Sjames qian wang (Arm Technology China) 	/** @base: &drm_crtc_state */
9661f1c4a8Sjames qian wang (Arm Technology China) 	struct drm_crtc_state base;
9761f1c4a8Sjames qian wang (Arm Technology China) 
9861f1c4a8Sjames qian wang (Arm Technology China) 	/* private properties */
9961f1c4a8Sjames qian wang (Arm Technology China) 
10061f1c4a8Sjames qian wang (Arm Technology China) 	/* computed state which are used by validate/check */
1018c919745Sjames qian wang (Arm Technology China) 	/**
1028c919745Sjames qian wang (Arm Technology China) 	 * @affected_pipes:
1038c919745Sjames qian wang (Arm Technology China) 	 * the affected pipelines in once display instance
1048c919745Sjames qian wang (Arm Technology China) 	 */
10561f1c4a8Sjames qian wang (Arm Technology China) 	u32 affected_pipes;
1068c919745Sjames qian wang (Arm Technology China) 	/**
1078c919745Sjames qian wang (Arm Technology China) 	 * @active_pipes:
1088c919745Sjames qian wang (Arm Technology China) 	 * the active pipelines in once display instance
1098c919745Sjames qian wang (Arm Technology China) 	 */
11061f1c4a8Sjames qian wang (Arm Technology China) 	u32 active_pipes;
1111f7f9ab7Sjames qian wang (Arm Technology China) 
1126f84da0cSjames qian wang (Arm Technology China) 	/** @clock_ratio: ratio of (aclk << 32)/pxlclk */
1131f7f9ab7Sjames qian wang (Arm Technology China) 	u64 clock_ratio;
1143b9dfa4eSLowry Li (Arm Technology China) 
1153b9dfa4eSLowry Li (Arm Technology China) 	/** @max_slave_zorder: the maximum of slave zorder */
1163b9dfa4eSLowry Li (Arm Technology China) 	u32 max_slave_zorder;
11761f1c4a8Sjames qian wang (Arm Technology China) };
11861f1c4a8Sjames qian wang (Arm Technology China) 
11961f1c4a8Sjames qian wang (Arm Technology China) /** struct komeda_kms_dev - for gather KMS related things */
12061f1c4a8Sjames qian wang (Arm Technology China) struct komeda_kms_dev {
12161f1c4a8Sjames qian wang (Arm Technology China) 	/** @base: &drm_device */
12261f1c4a8Sjames qian wang (Arm Technology China) 	struct drm_device base;
12361f1c4a8Sjames qian wang (Arm Technology China) 
12461f1c4a8Sjames qian wang (Arm Technology China) 	/** @n_crtcs: valid numbers of crtcs in &komeda_kms_dev.crtcs */
12561f1c4a8Sjames qian wang (Arm Technology China) 	int n_crtcs;
12661f1c4a8Sjames qian wang (Arm Technology China) 	/** @crtcs: crtcs list */
12761f1c4a8Sjames qian wang (Arm Technology China) 	struct komeda_crtc crtcs[KOMEDA_MAX_PIPELINES];
12861f1c4a8Sjames qian wang (Arm Technology China) };
12961f1c4a8Sjames qian wang (Arm Technology China) 
13061f1c4a8Sjames qian wang (Arm Technology China) #define to_kplane(p)	container_of(p, struct komeda_plane, base)
13161f1c4a8Sjames qian wang (Arm Technology China) #define to_kplane_st(p)	container_of(p, struct komeda_plane_state, base)
13261f1c4a8Sjames qian wang (Arm Technology China) #define to_kconn(p)	container_of(p, struct komeda_wb_connector, base)
13361f1c4a8Sjames qian wang (Arm Technology China) #define to_kcrtc(p)	container_of(p, struct komeda_crtc, base)
13461f1c4a8Sjames qian wang (Arm Technology China) #define to_kcrtc_st(p)	container_of(p, struct komeda_crtc_state, base)
13561f1c4a8Sjames qian wang (Arm Technology China) #define to_kdev(p)	container_of(p, struct komeda_kms_dev, base)
1365d51f6c0Sjames qian wang (Arm Technology China) #define to_wb_conn(x)	container_of(x, struct drm_writeback_connector, base)
1375d51f6c0Sjames qian wang (Arm Technology China) 
1385d51f6c0Sjames qian wang (Arm Technology China) static inline bool is_writeback_only(struct drm_crtc_state *st)
1395d51f6c0Sjames qian wang (Arm Technology China) {
1405d51f6c0Sjames qian wang (Arm Technology China) 	struct komeda_wb_connector *wb_conn = to_kcrtc(st->crtc)->wb_conn;
1415d51f6c0Sjames qian wang (Arm Technology China) 	struct drm_connector *conn = wb_conn ? &wb_conn->base.base : NULL;
1425d51f6c0Sjames qian wang (Arm Technology China) 
1435d51f6c0Sjames qian wang (Arm Technology China) 	return conn && (st->connector_mask == BIT(drm_connector_index(conn)));
1445d51f6c0Sjames qian wang (Arm Technology China) }
1455d51f6c0Sjames qian wang (Arm Technology China) 
1465d51f6c0Sjames qian wang (Arm Technology China) static inline bool
1475d51f6c0Sjames qian wang (Arm Technology China) is_only_changed_connector(struct drm_crtc_state *st, struct drm_connector *conn)
1485d51f6c0Sjames qian wang (Arm Technology China) {
1495d51f6c0Sjames qian wang (Arm Technology China) 	struct drm_crtc_state *old_st;
1505d51f6c0Sjames qian wang (Arm Technology China) 	u32 changed_connectors;
1515d51f6c0Sjames qian wang (Arm Technology China) 
1525d51f6c0Sjames qian wang (Arm Technology China) 	old_st = drm_atomic_get_old_crtc_state(st->state, st->crtc);
1535d51f6c0Sjames qian wang (Arm Technology China) 	changed_connectors = st->connector_mask ^ old_st->connector_mask;
1545d51f6c0Sjames qian wang (Arm Technology China) 
1555d51f6c0Sjames qian wang (Arm Technology China) 	return BIT(drm_connector_index(conn)) == changed_connectors;
1565d51f6c0Sjames qian wang (Arm Technology China) }
15761f1c4a8Sjames qian wang (Arm Technology China) 
158a407a650Sjames qian wang (Arm Technology China) static inline bool has_flip_h(u32 rot)
159a407a650Sjames qian wang (Arm Technology China) {
160a407a650Sjames qian wang (Arm Technology China) 	u32 rotation = drm_rotation_simplify(rot,
161a407a650Sjames qian wang (Arm Technology China) 					     DRM_MODE_ROTATE_0 |
162a407a650Sjames qian wang (Arm Technology China) 					     DRM_MODE_ROTATE_90 |
163a407a650Sjames qian wang (Arm Technology China) 					     DRM_MODE_REFLECT_MASK);
164a407a650Sjames qian wang (Arm Technology China) 
165a407a650Sjames qian wang (Arm Technology China) 	if (rotation & DRM_MODE_ROTATE_90)
166a407a650Sjames qian wang (Arm Technology China) 		return !!(rotation & DRM_MODE_REFLECT_Y);
167a407a650Sjames qian wang (Arm Technology China) 	else
168a407a650Sjames qian wang (Arm Technology China) 		return !!(rotation & DRM_MODE_REFLECT_X);
169a407a650Sjames qian wang (Arm Technology China) }
170a407a650Sjames qian wang (Arm Technology China) 
1716f84da0cSjames qian wang (Arm Technology China) unsigned long komeda_calc_aclk(struct komeda_crtc_state *kcrtc_st);
1721f7f9ab7Sjames qian wang (Arm Technology China) 
17361f1c4a8Sjames qian wang (Arm Technology China) int komeda_kms_setup_crtcs(struct komeda_kms_dev *kms, struct komeda_dev *mdev);
17461f1c4a8Sjames qian wang (Arm Technology China) 
17561f1c4a8Sjames qian wang (Arm Technology China) int komeda_kms_add_crtcs(struct komeda_kms_dev *kms, struct komeda_dev *mdev);
17661f1c4a8Sjames qian wang (Arm Technology China) int komeda_kms_add_planes(struct komeda_kms_dev *kms, struct komeda_dev *mdev);
17761f1c4a8Sjames qian wang (Arm Technology China) int komeda_kms_add_private_objs(struct komeda_kms_dev *kms,
17861f1c4a8Sjames qian wang (Arm Technology China) 				struct komeda_dev *mdev);
1795d51f6c0Sjames qian wang (Arm Technology China) int komeda_kms_add_wb_connectors(struct komeda_kms_dev *kms,
1805d51f6c0Sjames qian wang (Arm Technology China) 				 struct komeda_dev *mdev);
181ee6b73d6Sjames qian wang (Arm Technology China) void komeda_kms_cleanup_private_objs(struct komeda_kms_dev *kms);
18261f1c4a8Sjames qian wang (Arm Technology China) 
1830dac37bfSjames qian wang (Arm Technology China) void komeda_crtc_handle_event(struct komeda_crtc   *kcrtc,
1840dac37bfSjames qian wang (Arm Technology China) 			      struct komeda_events *evts);
1850dac37bfSjames qian wang (Arm Technology China) 
18661f1c4a8Sjames qian wang (Arm Technology China) struct komeda_kms_dev *komeda_kms_attach(struct komeda_dev *mdev);
18761f1c4a8Sjames qian wang (Arm Technology China) void komeda_kms_detach(struct komeda_kms_dev *kms);
18861f1c4a8Sjames qian wang (Arm Technology China) 
18961f1c4a8Sjames qian wang (Arm Technology China) #endif /*_KOMEDA_KMS_H_*/
190