Linux Audio

Check our new training course

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