xref: /OK3568_Linux_fs/kernel/drivers/gpu/drm/drm_encoder.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * Copyright (c) 2016 Intel Corporation
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * Permission to use, copy, modify, distribute, and sell this software and its
5*4882a593Smuzhiyun  * documentation for any purpose is hereby granted without fee, provided that
6*4882a593Smuzhiyun  * the above copyright notice appear in all copies and that both that copyright
7*4882a593Smuzhiyun  * notice and this permission notice appear in supporting documentation, and
8*4882a593Smuzhiyun  * that the name of the copyright holders not be used in advertising or
9*4882a593Smuzhiyun  * publicity pertaining to distribution of the software without specific,
10*4882a593Smuzhiyun  * written prior permission.  The copyright holders make no representations
11*4882a593Smuzhiyun  * about the suitability of this software for any purpose.  It is provided "as
12*4882a593Smuzhiyun  * is" without express or implied warranty.
13*4882a593Smuzhiyun  *
14*4882a593Smuzhiyun  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15*4882a593Smuzhiyun  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16*4882a593Smuzhiyun  * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17*4882a593Smuzhiyun  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18*4882a593Smuzhiyun  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19*4882a593Smuzhiyun  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
20*4882a593Smuzhiyun  * OF THIS SOFTWARE.
21*4882a593Smuzhiyun  */
22*4882a593Smuzhiyun 
23*4882a593Smuzhiyun #include <linux/export.h>
24*4882a593Smuzhiyun 
25*4882a593Smuzhiyun #include <drm/drm_bridge.h>
26*4882a593Smuzhiyun #include <drm/drm_device.h>
27*4882a593Smuzhiyun #include <drm/drm_drv.h>
28*4882a593Smuzhiyun #include <drm/drm_encoder.h>
29*4882a593Smuzhiyun 
30*4882a593Smuzhiyun #include "drm_crtc_internal.h"
31*4882a593Smuzhiyun 
32*4882a593Smuzhiyun /**
33*4882a593Smuzhiyun  * DOC: overview
34*4882a593Smuzhiyun  *
35*4882a593Smuzhiyun  * Encoders represent the connecting element between the CRTC (as the overall
36*4882a593Smuzhiyun  * pixel pipeline, represented by &struct drm_crtc) and the connectors (as the
37*4882a593Smuzhiyun  * generic sink entity, represented by &struct drm_connector). An encoder takes
38*4882a593Smuzhiyun  * pixel data from a CRTC and converts it to a format suitable for any attached
39*4882a593Smuzhiyun  * connector. Encoders are objects exposed to userspace, originally to allow
40*4882a593Smuzhiyun  * userspace to infer cloning and connector/CRTC restrictions. Unfortunately
41*4882a593Smuzhiyun  * almost all drivers get this wrong, making the uabi pretty much useless. On
42*4882a593Smuzhiyun  * top of that the exposed restrictions are too simple for today's hardware, and
43*4882a593Smuzhiyun  * the recommended way to infer restrictions is by using the
44*4882a593Smuzhiyun  * DRM_MODE_ATOMIC_TEST_ONLY flag for the atomic IOCTL.
45*4882a593Smuzhiyun  *
46*4882a593Smuzhiyun  * Otherwise encoders aren't used in the uapi at all (any modeset request from
47*4882a593Smuzhiyun  * userspace directly connects a connector with a CRTC), drivers are therefore
48*4882a593Smuzhiyun  * free to use them however they wish. Modeset helper libraries make strong use
49*4882a593Smuzhiyun  * of encoders to facilitate code sharing. But for more complex settings it is
50*4882a593Smuzhiyun  * usually better to move shared code into a separate &drm_bridge. Compared to
51*4882a593Smuzhiyun  * encoders, bridges also have the benefit of being purely an internal
52*4882a593Smuzhiyun  * abstraction since they are not exposed to userspace at all.
53*4882a593Smuzhiyun  *
54*4882a593Smuzhiyun  * Encoders are initialized with drm_encoder_init() and cleaned up using
55*4882a593Smuzhiyun  * drm_encoder_cleanup().
56*4882a593Smuzhiyun  */
57*4882a593Smuzhiyun static const struct drm_prop_enum_list drm_encoder_enum_list[] = {
58*4882a593Smuzhiyun 	{ DRM_MODE_ENCODER_NONE, "None" },
59*4882a593Smuzhiyun 	{ DRM_MODE_ENCODER_DAC, "DAC" },
60*4882a593Smuzhiyun 	{ DRM_MODE_ENCODER_TMDS, "TMDS" },
61*4882a593Smuzhiyun 	{ DRM_MODE_ENCODER_LVDS, "LVDS" },
62*4882a593Smuzhiyun 	{ DRM_MODE_ENCODER_TVDAC, "TV" },
63*4882a593Smuzhiyun 	{ DRM_MODE_ENCODER_VIRTUAL, "Virtual" },
64*4882a593Smuzhiyun 	{ DRM_MODE_ENCODER_DSI, "DSI" },
65*4882a593Smuzhiyun 	{ DRM_MODE_ENCODER_DPMST, "DP MST" },
66*4882a593Smuzhiyun 	{ DRM_MODE_ENCODER_DPI, "DPI" },
67*4882a593Smuzhiyun };
68*4882a593Smuzhiyun 
drm_encoder_register_all(struct drm_device * dev)69*4882a593Smuzhiyun int drm_encoder_register_all(struct drm_device *dev)
70*4882a593Smuzhiyun {
71*4882a593Smuzhiyun 	struct drm_encoder *encoder;
72*4882a593Smuzhiyun 	int ret = 0;
73*4882a593Smuzhiyun 
74*4882a593Smuzhiyun 	drm_for_each_encoder(encoder, dev) {
75*4882a593Smuzhiyun 		if (encoder->funcs->late_register)
76*4882a593Smuzhiyun 			ret = encoder->funcs->late_register(encoder);
77*4882a593Smuzhiyun 		if (ret)
78*4882a593Smuzhiyun 			return ret;
79*4882a593Smuzhiyun 	}
80*4882a593Smuzhiyun 
81*4882a593Smuzhiyun 	return 0;
82*4882a593Smuzhiyun }
83*4882a593Smuzhiyun 
drm_encoder_unregister_all(struct drm_device * dev)84*4882a593Smuzhiyun void drm_encoder_unregister_all(struct drm_device *dev)
85*4882a593Smuzhiyun {
86*4882a593Smuzhiyun 	struct drm_encoder *encoder;
87*4882a593Smuzhiyun 
88*4882a593Smuzhiyun 	drm_for_each_encoder(encoder, dev) {
89*4882a593Smuzhiyun 		if (encoder->funcs->early_unregister)
90*4882a593Smuzhiyun 			encoder->funcs->early_unregister(encoder);
91*4882a593Smuzhiyun 	}
92*4882a593Smuzhiyun }
93*4882a593Smuzhiyun 
94*4882a593Smuzhiyun /**
95*4882a593Smuzhiyun  * drm_encoder_init - Init a preallocated encoder
96*4882a593Smuzhiyun  * @dev: drm device
97*4882a593Smuzhiyun  * @encoder: the encoder to init
98*4882a593Smuzhiyun  * @funcs: callbacks for this encoder
99*4882a593Smuzhiyun  * @encoder_type: user visible type of the encoder
100*4882a593Smuzhiyun  * @name: printf style format string for the encoder name, or NULL for default name
101*4882a593Smuzhiyun  *
102*4882a593Smuzhiyun  * Initialises a preallocated encoder. Encoder should be subclassed as part of
103*4882a593Smuzhiyun  * driver encoder objects. At driver unload time drm_encoder_cleanup() should be
104*4882a593Smuzhiyun  * called from the driver's &drm_encoder_funcs.destroy hook.
105*4882a593Smuzhiyun  *
106*4882a593Smuzhiyun  * Returns:
107*4882a593Smuzhiyun  * Zero on success, error code on failure.
108*4882a593Smuzhiyun  */
drm_encoder_init(struct drm_device * dev,struct drm_encoder * encoder,const struct drm_encoder_funcs * funcs,int encoder_type,const char * name,...)109*4882a593Smuzhiyun int drm_encoder_init(struct drm_device *dev,
110*4882a593Smuzhiyun 		     struct drm_encoder *encoder,
111*4882a593Smuzhiyun 		     const struct drm_encoder_funcs *funcs,
112*4882a593Smuzhiyun 		     int encoder_type, const char *name, ...)
113*4882a593Smuzhiyun {
114*4882a593Smuzhiyun 	int ret;
115*4882a593Smuzhiyun 
116*4882a593Smuzhiyun 	/* encoder index is used with 32bit bitmasks */
117*4882a593Smuzhiyun 	if (WARN_ON(dev->mode_config.num_encoder >= 32))
118*4882a593Smuzhiyun 		return -EINVAL;
119*4882a593Smuzhiyun 
120*4882a593Smuzhiyun 	ret = drm_mode_object_add(dev, &encoder->base, DRM_MODE_OBJECT_ENCODER);
121*4882a593Smuzhiyun 	if (ret)
122*4882a593Smuzhiyun 		return ret;
123*4882a593Smuzhiyun 
124*4882a593Smuzhiyun 	encoder->dev = dev;
125*4882a593Smuzhiyun 	encoder->encoder_type = encoder_type;
126*4882a593Smuzhiyun 	encoder->funcs = funcs;
127*4882a593Smuzhiyun 	if (name) {
128*4882a593Smuzhiyun 		va_list ap;
129*4882a593Smuzhiyun 
130*4882a593Smuzhiyun 		va_start(ap, name);
131*4882a593Smuzhiyun 		encoder->name = kvasprintf(GFP_KERNEL, name, ap);
132*4882a593Smuzhiyun 		va_end(ap);
133*4882a593Smuzhiyun 	} else {
134*4882a593Smuzhiyun 		encoder->name = kasprintf(GFP_KERNEL, "%s-%d",
135*4882a593Smuzhiyun 					  drm_encoder_enum_list[encoder_type].name,
136*4882a593Smuzhiyun 					  encoder->base.id);
137*4882a593Smuzhiyun 	}
138*4882a593Smuzhiyun 	if (!encoder->name) {
139*4882a593Smuzhiyun 		ret = -ENOMEM;
140*4882a593Smuzhiyun 		goto out_put;
141*4882a593Smuzhiyun 	}
142*4882a593Smuzhiyun 
143*4882a593Smuzhiyun 	INIT_LIST_HEAD(&encoder->bridge_chain);
144*4882a593Smuzhiyun 	list_add_tail(&encoder->head, &dev->mode_config.encoder_list);
145*4882a593Smuzhiyun 	encoder->index = dev->mode_config.num_encoder++;
146*4882a593Smuzhiyun 
147*4882a593Smuzhiyun out_put:
148*4882a593Smuzhiyun 	if (ret)
149*4882a593Smuzhiyun 		drm_mode_object_unregister(dev, &encoder->base);
150*4882a593Smuzhiyun 
151*4882a593Smuzhiyun 	return ret;
152*4882a593Smuzhiyun }
153*4882a593Smuzhiyun EXPORT_SYMBOL(drm_encoder_init);
154*4882a593Smuzhiyun 
155*4882a593Smuzhiyun /**
156*4882a593Smuzhiyun  * drm_encoder_cleanup - cleans up an initialised encoder
157*4882a593Smuzhiyun  * @encoder: encoder to cleanup
158*4882a593Smuzhiyun  *
159*4882a593Smuzhiyun  * Cleans up the encoder but doesn't free the object.
160*4882a593Smuzhiyun  */
drm_encoder_cleanup(struct drm_encoder * encoder)161*4882a593Smuzhiyun void drm_encoder_cleanup(struct drm_encoder *encoder)
162*4882a593Smuzhiyun {
163*4882a593Smuzhiyun 	struct drm_device *dev = encoder->dev;
164*4882a593Smuzhiyun 	struct drm_bridge *bridge, *next;
165*4882a593Smuzhiyun 
166*4882a593Smuzhiyun 	/* Note that the encoder_list is considered to be static; should we
167*4882a593Smuzhiyun 	 * remove the drm_encoder at runtime we would have to decrement all
168*4882a593Smuzhiyun 	 * the indices on the drm_encoder after us in the encoder_list.
169*4882a593Smuzhiyun 	 */
170*4882a593Smuzhiyun 
171*4882a593Smuzhiyun 	list_for_each_entry_safe(bridge, next, &encoder->bridge_chain,
172*4882a593Smuzhiyun 				 chain_node)
173*4882a593Smuzhiyun 		drm_bridge_detach(bridge);
174*4882a593Smuzhiyun 
175*4882a593Smuzhiyun 	drm_mode_object_unregister(dev, &encoder->base);
176*4882a593Smuzhiyun 	kfree(encoder->name);
177*4882a593Smuzhiyun 	list_del(&encoder->head);
178*4882a593Smuzhiyun 	dev->mode_config.num_encoder--;
179*4882a593Smuzhiyun 
180*4882a593Smuzhiyun 	memset(encoder, 0, sizeof(*encoder));
181*4882a593Smuzhiyun }
182*4882a593Smuzhiyun EXPORT_SYMBOL(drm_encoder_cleanup);
183*4882a593Smuzhiyun 
drm_encoder_get_crtc(struct drm_encoder * encoder)184*4882a593Smuzhiyun static struct drm_crtc *drm_encoder_get_crtc(struct drm_encoder *encoder)
185*4882a593Smuzhiyun {
186*4882a593Smuzhiyun 	struct drm_connector *connector;
187*4882a593Smuzhiyun 	struct drm_device *dev = encoder->dev;
188*4882a593Smuzhiyun 	bool uses_atomic = false;
189*4882a593Smuzhiyun 	struct drm_connector_list_iter conn_iter;
190*4882a593Smuzhiyun 
191*4882a593Smuzhiyun 	/* For atomic drivers only state objects are synchronously updated and
192*4882a593Smuzhiyun 	 * protected by modeset locks, so check those first. */
193*4882a593Smuzhiyun 	drm_connector_list_iter_begin(dev, &conn_iter);
194*4882a593Smuzhiyun 	drm_for_each_connector_iter(connector, &conn_iter) {
195*4882a593Smuzhiyun 		if (!connector->state)
196*4882a593Smuzhiyun 			continue;
197*4882a593Smuzhiyun 
198*4882a593Smuzhiyun 		uses_atomic = true;
199*4882a593Smuzhiyun 
200*4882a593Smuzhiyun 		if (connector->state->best_encoder != encoder)
201*4882a593Smuzhiyun 			continue;
202*4882a593Smuzhiyun 
203*4882a593Smuzhiyun 		drm_connector_list_iter_end(&conn_iter);
204*4882a593Smuzhiyun 		return connector->state->crtc;
205*4882a593Smuzhiyun 	}
206*4882a593Smuzhiyun 	drm_connector_list_iter_end(&conn_iter);
207*4882a593Smuzhiyun 
208*4882a593Smuzhiyun 	/* Don't return stale data (e.g. pending async disable). */
209*4882a593Smuzhiyun 	if (uses_atomic)
210*4882a593Smuzhiyun 		return NULL;
211*4882a593Smuzhiyun 
212*4882a593Smuzhiyun 	return encoder->crtc;
213*4882a593Smuzhiyun }
214*4882a593Smuzhiyun 
drm_mode_getencoder(struct drm_device * dev,void * data,struct drm_file * file_priv)215*4882a593Smuzhiyun int drm_mode_getencoder(struct drm_device *dev, void *data,
216*4882a593Smuzhiyun 			struct drm_file *file_priv)
217*4882a593Smuzhiyun {
218*4882a593Smuzhiyun 	struct drm_mode_get_encoder *enc_resp = data;
219*4882a593Smuzhiyun 	struct drm_encoder *encoder;
220*4882a593Smuzhiyun 	struct drm_crtc *crtc;
221*4882a593Smuzhiyun 
222*4882a593Smuzhiyun 	if (!drm_core_check_feature(dev, DRIVER_MODESET))
223*4882a593Smuzhiyun 		return -EOPNOTSUPP;
224*4882a593Smuzhiyun 
225*4882a593Smuzhiyun 	encoder = drm_encoder_find(dev, file_priv, enc_resp->encoder_id);
226*4882a593Smuzhiyun 	if (!encoder)
227*4882a593Smuzhiyun 		return -ENOENT;
228*4882a593Smuzhiyun 
229*4882a593Smuzhiyun 	drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
230*4882a593Smuzhiyun 	crtc = drm_encoder_get_crtc(encoder);
231*4882a593Smuzhiyun 	if (crtc && drm_lease_held(file_priv, crtc->base.id))
232*4882a593Smuzhiyun 		enc_resp->crtc_id = crtc->base.id;
233*4882a593Smuzhiyun 	else
234*4882a593Smuzhiyun 		enc_resp->crtc_id = 0;
235*4882a593Smuzhiyun 	drm_modeset_unlock(&dev->mode_config.connection_mutex);
236*4882a593Smuzhiyun 
237*4882a593Smuzhiyun 	enc_resp->encoder_type = encoder->encoder_type;
238*4882a593Smuzhiyun 	enc_resp->encoder_id = encoder->base.id;
239*4882a593Smuzhiyun 	enc_resp->possible_crtcs = drm_lease_filter_crtcs(file_priv,
240*4882a593Smuzhiyun 							  encoder->possible_crtcs);
241*4882a593Smuzhiyun 	enc_resp->possible_clones = encoder->possible_clones;
242*4882a593Smuzhiyun 
243*4882a593Smuzhiyun 	return 0;
244*4882a593Smuzhiyun }
245