cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

drm_encoder.c (9457B)


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