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_client_modeset.c (32972B)


      1// SPDX-License-Identifier: MIT
      2/*
      3 * Copyright 2018 Noralf Trønnes
      4 * Copyright (c) 2006-2009 Red Hat Inc.
      5 * Copyright (c) 2006-2008 Intel Corporation
      6 *   Jesse Barnes <jesse.barnes@intel.com>
      7 * Copyright (c) 2007 Dave Airlie <airlied@linux.ie>
      8 */
      9
     10#include "drm/drm_modeset_lock.h"
     11#include <linux/module.h>
     12#include <linux/mutex.h>
     13#include <linux/slab.h>
     14#include <linux/string_helpers.h>
     15
     16#include <drm/drm_atomic.h>
     17#include <drm/drm_client.h>
     18#include <drm/drm_connector.h>
     19#include <drm/drm_crtc.h>
     20#include <drm/drm_device.h>
     21#include <drm/drm_drv.h>
     22#include <drm/drm_encoder.h>
     23#include <drm/drm_print.h>
     24
     25#include "drm_crtc_internal.h"
     26#include "drm_internal.h"
     27
     28#define DRM_CLIENT_MAX_CLONED_CONNECTORS	8
     29
     30struct drm_client_offset {
     31	int x, y;
     32};
     33
     34int drm_client_modeset_create(struct drm_client_dev *client)
     35{
     36	struct drm_device *dev = client->dev;
     37	unsigned int num_crtc = dev->mode_config.num_crtc;
     38	unsigned int max_connector_count = 1;
     39	struct drm_mode_set *modeset;
     40	struct drm_crtc *crtc;
     41	unsigned int i = 0;
     42
     43	/* Add terminating zero entry to enable index less iteration */
     44	client->modesets = kcalloc(num_crtc + 1, sizeof(*client->modesets), GFP_KERNEL);
     45	if (!client->modesets)
     46		return -ENOMEM;
     47
     48	mutex_init(&client->modeset_mutex);
     49
     50	drm_for_each_crtc(crtc, dev)
     51		client->modesets[i++].crtc = crtc;
     52
     53	/* Cloning is only supported in the single crtc case. */
     54	if (num_crtc == 1)
     55		max_connector_count = DRM_CLIENT_MAX_CLONED_CONNECTORS;
     56
     57	for (modeset = client->modesets; modeset->crtc; modeset++) {
     58		modeset->connectors = kcalloc(max_connector_count,
     59					      sizeof(*modeset->connectors), GFP_KERNEL);
     60		if (!modeset->connectors)
     61			goto err_free;
     62	}
     63
     64	return 0;
     65
     66err_free:
     67	drm_client_modeset_free(client);
     68
     69	return -ENOMEM;
     70}
     71
     72static void drm_client_modeset_release(struct drm_client_dev *client)
     73{
     74	struct drm_mode_set *modeset;
     75	unsigned int i;
     76
     77	drm_client_for_each_modeset(modeset, client) {
     78		drm_mode_destroy(client->dev, modeset->mode);
     79		modeset->mode = NULL;
     80		modeset->fb = NULL;
     81
     82		for (i = 0; i < modeset->num_connectors; i++) {
     83			drm_connector_put(modeset->connectors[i]);
     84			modeset->connectors[i] = NULL;
     85		}
     86		modeset->num_connectors = 0;
     87	}
     88}
     89
     90void drm_client_modeset_free(struct drm_client_dev *client)
     91{
     92	struct drm_mode_set *modeset;
     93
     94	mutex_lock(&client->modeset_mutex);
     95
     96	drm_client_modeset_release(client);
     97
     98	drm_client_for_each_modeset(modeset, client)
     99		kfree(modeset->connectors);
    100
    101	mutex_unlock(&client->modeset_mutex);
    102
    103	mutex_destroy(&client->modeset_mutex);
    104	kfree(client->modesets);
    105}
    106
    107static struct drm_mode_set *
    108drm_client_find_modeset(struct drm_client_dev *client, struct drm_crtc *crtc)
    109{
    110	struct drm_mode_set *modeset;
    111
    112	drm_client_for_each_modeset(modeset, client)
    113		if (modeset->crtc == crtc)
    114			return modeset;
    115
    116	return NULL;
    117}
    118
    119static struct drm_display_mode *
    120drm_connector_get_tiled_mode(struct drm_connector *connector)
    121{
    122	struct drm_display_mode *mode;
    123
    124	list_for_each_entry(mode, &connector->modes, head) {
    125		if (mode->hdisplay == connector->tile_h_size &&
    126		    mode->vdisplay == connector->tile_v_size)
    127			return mode;
    128	}
    129	return NULL;
    130}
    131
    132static struct drm_display_mode *
    133drm_connector_fallback_non_tiled_mode(struct drm_connector *connector)
    134{
    135	struct drm_display_mode *mode;
    136
    137	list_for_each_entry(mode, &connector->modes, head) {
    138		if (mode->hdisplay == connector->tile_h_size &&
    139		    mode->vdisplay == connector->tile_v_size)
    140			continue;
    141		return mode;
    142	}
    143	return NULL;
    144}
    145
    146static struct drm_display_mode *
    147drm_connector_has_preferred_mode(struct drm_connector *connector, int width, int height)
    148{
    149	struct drm_display_mode *mode;
    150
    151	list_for_each_entry(mode, &connector->modes, head) {
    152		if (mode->hdisplay > width ||
    153		    mode->vdisplay > height)
    154			continue;
    155		if (mode->type & DRM_MODE_TYPE_PREFERRED)
    156			return mode;
    157	}
    158	return NULL;
    159}
    160
    161static struct drm_display_mode *
    162drm_connector_pick_cmdline_mode(struct drm_connector *connector)
    163{
    164	struct drm_cmdline_mode *cmdline_mode;
    165	struct drm_display_mode *mode;
    166	bool prefer_non_interlace;
    167
    168	cmdline_mode = &connector->cmdline_mode;
    169	if (cmdline_mode->specified == false)
    170		return NULL;
    171
    172	/* attempt to find a matching mode in the list of modes
    173	 *  we have gotten so far, if not add a CVT mode that conforms
    174	 */
    175	if (cmdline_mode->rb || cmdline_mode->margins)
    176		goto create_mode;
    177
    178	prefer_non_interlace = !cmdline_mode->interlace;
    179again:
    180	list_for_each_entry(mode, &connector->modes, head) {
    181		/* Check (optional) mode name first */
    182		if (!strcmp(mode->name, cmdline_mode->name))
    183			return mode;
    184
    185		/* check width/height */
    186		if (mode->hdisplay != cmdline_mode->xres ||
    187		    mode->vdisplay != cmdline_mode->yres)
    188			continue;
    189
    190		if (cmdline_mode->refresh_specified) {
    191			if (drm_mode_vrefresh(mode) != cmdline_mode->refresh)
    192				continue;
    193		}
    194
    195		if (cmdline_mode->interlace) {
    196			if (!(mode->flags & DRM_MODE_FLAG_INTERLACE))
    197				continue;
    198		} else if (prefer_non_interlace) {
    199			if (mode->flags & DRM_MODE_FLAG_INTERLACE)
    200				continue;
    201		}
    202		return mode;
    203	}
    204
    205	if (prefer_non_interlace) {
    206		prefer_non_interlace = false;
    207		goto again;
    208	}
    209
    210create_mode:
    211	mode = drm_mode_create_from_cmdline_mode(connector->dev, cmdline_mode);
    212	if (mode)
    213		list_add(&mode->head, &connector->modes);
    214
    215	return mode;
    216}
    217
    218static bool drm_connector_enabled(struct drm_connector *connector, bool strict)
    219{
    220	bool enable;
    221
    222	if (connector->display_info.non_desktop)
    223		return false;
    224
    225	if (strict)
    226		enable = connector->status == connector_status_connected;
    227	else
    228		enable = connector->status != connector_status_disconnected;
    229
    230	return enable;
    231}
    232
    233static void drm_client_connectors_enabled(struct drm_connector **connectors,
    234					  unsigned int connector_count,
    235					  bool *enabled)
    236{
    237	bool any_enabled = false;
    238	struct drm_connector *connector;
    239	int i = 0;
    240
    241	for (i = 0; i < connector_count; i++) {
    242		connector = connectors[i];
    243		enabled[i] = drm_connector_enabled(connector, true);
    244		DRM_DEBUG_KMS("connector %d enabled? %s\n", connector->base.id,
    245			      connector->display_info.non_desktop ? "non desktop" : str_yes_no(enabled[i]));
    246
    247		any_enabled |= enabled[i];
    248	}
    249
    250	if (any_enabled)
    251		return;
    252
    253	for (i = 0; i < connector_count; i++)
    254		enabled[i] = drm_connector_enabled(connectors[i], false);
    255}
    256
    257static bool drm_client_target_cloned(struct drm_device *dev,
    258				     struct drm_connector **connectors,
    259				     unsigned int connector_count,
    260				     struct drm_display_mode **modes,
    261				     struct drm_client_offset *offsets,
    262				     bool *enabled, int width, int height)
    263{
    264	int count, i, j;
    265	bool can_clone = false;
    266	struct drm_display_mode *dmt_mode, *mode;
    267
    268	/* only contemplate cloning in the single crtc case */
    269	if (dev->mode_config.num_crtc > 1)
    270		return false;
    271
    272	count = 0;
    273	for (i = 0; i < connector_count; i++) {
    274		if (enabled[i])
    275			count++;
    276	}
    277
    278	/* only contemplate cloning if more than one connector is enabled */
    279	if (count <= 1)
    280		return false;
    281
    282	/* check the command line or if nothing common pick 1024x768 */
    283	can_clone = true;
    284	for (i = 0; i < connector_count; i++) {
    285		if (!enabled[i])
    286			continue;
    287		modes[i] = drm_connector_pick_cmdline_mode(connectors[i]);
    288		if (!modes[i]) {
    289			can_clone = false;
    290			break;
    291		}
    292		for (j = 0; j < i; j++) {
    293			if (!enabled[j])
    294				continue;
    295			if (!drm_mode_match(modes[j], modes[i],
    296					    DRM_MODE_MATCH_TIMINGS |
    297					    DRM_MODE_MATCH_CLOCK |
    298					    DRM_MODE_MATCH_FLAGS |
    299					    DRM_MODE_MATCH_3D_FLAGS))
    300				can_clone = false;
    301		}
    302	}
    303
    304	if (can_clone) {
    305		DRM_DEBUG_KMS("can clone using command line\n");
    306		return true;
    307	}
    308
    309	/* try and find a 1024x768 mode on each connector */
    310	can_clone = true;
    311	dmt_mode = drm_mode_find_dmt(dev, 1024, 768, 60, false);
    312
    313	for (i = 0; i < connector_count; i++) {
    314		if (!enabled[i])
    315			continue;
    316
    317		list_for_each_entry(mode, &connectors[i]->modes, head) {
    318			if (drm_mode_match(mode, dmt_mode,
    319					   DRM_MODE_MATCH_TIMINGS |
    320					   DRM_MODE_MATCH_CLOCK |
    321					   DRM_MODE_MATCH_FLAGS |
    322					   DRM_MODE_MATCH_3D_FLAGS))
    323				modes[i] = mode;
    324		}
    325		if (!modes[i])
    326			can_clone = false;
    327	}
    328
    329	if (can_clone) {
    330		DRM_DEBUG_KMS("can clone using 1024x768\n");
    331		return true;
    332	}
    333	DRM_INFO("kms: can't enable cloning when we probably wanted to.\n");
    334	return false;
    335}
    336
    337static int drm_client_get_tile_offsets(struct drm_connector **connectors,
    338				       unsigned int connector_count,
    339				       struct drm_display_mode **modes,
    340				       struct drm_client_offset *offsets,
    341				       int idx,
    342				       int h_idx, int v_idx)
    343{
    344	struct drm_connector *connector;
    345	int i;
    346	int hoffset = 0, voffset = 0;
    347
    348	for (i = 0; i < connector_count; i++) {
    349		connector = connectors[i];
    350		if (!connector->has_tile)
    351			continue;
    352
    353		if (!modes[i] && (h_idx || v_idx)) {
    354			DRM_DEBUG_KMS("no modes for connector tiled %d %d\n", i,
    355				      connector->base.id);
    356			continue;
    357		}
    358		if (connector->tile_h_loc < h_idx)
    359			hoffset += modes[i]->hdisplay;
    360
    361		if (connector->tile_v_loc < v_idx)
    362			voffset += modes[i]->vdisplay;
    363	}
    364	offsets[idx].x = hoffset;
    365	offsets[idx].y = voffset;
    366	DRM_DEBUG_KMS("returned %d %d for %d %d\n", hoffset, voffset, h_idx, v_idx);
    367	return 0;
    368}
    369
    370static bool drm_client_target_preferred(struct drm_connector **connectors,
    371					unsigned int connector_count,
    372					struct drm_display_mode **modes,
    373					struct drm_client_offset *offsets,
    374					bool *enabled, int width, int height)
    375{
    376	const u64 mask = BIT_ULL(connector_count) - 1;
    377	struct drm_connector *connector;
    378	u64 conn_configured = 0;
    379	int tile_pass = 0;
    380	int num_tiled_conns = 0;
    381	int i;
    382
    383	for (i = 0; i < connector_count; i++) {
    384		if (connectors[i]->has_tile &&
    385		    connectors[i]->status == connector_status_connected)
    386			num_tiled_conns++;
    387	}
    388
    389retry:
    390	for (i = 0; i < connector_count; i++) {
    391		connector = connectors[i];
    392
    393		if (conn_configured & BIT_ULL(i))
    394			continue;
    395
    396		if (enabled[i] == false) {
    397			conn_configured |= BIT_ULL(i);
    398			continue;
    399		}
    400
    401		/* first pass over all the untiled connectors */
    402		if (tile_pass == 0 && connector->has_tile)
    403			continue;
    404
    405		if (tile_pass == 1) {
    406			if (connector->tile_h_loc != 0 ||
    407			    connector->tile_v_loc != 0)
    408				continue;
    409
    410		} else {
    411			if (connector->tile_h_loc != tile_pass - 1 &&
    412			    connector->tile_v_loc != tile_pass - 1)
    413			/* if this tile_pass doesn't cover any of the tiles - keep going */
    414				continue;
    415
    416			/*
    417			 * find the tile offsets for this pass - need to find
    418			 * all tiles left and above
    419			 */
    420			drm_client_get_tile_offsets(connectors, connector_count, modes, offsets, i,
    421						    connector->tile_h_loc, connector->tile_v_loc);
    422		}
    423		DRM_DEBUG_KMS("looking for cmdline mode on connector %d\n",
    424			      connector->base.id);
    425
    426		/* got for command line mode first */
    427		modes[i] = drm_connector_pick_cmdline_mode(connector);
    428		if (!modes[i]) {
    429			DRM_DEBUG_KMS("looking for preferred mode on connector %d %d\n",
    430				      connector->base.id, connector->tile_group ? connector->tile_group->id : 0);
    431			modes[i] = drm_connector_has_preferred_mode(connector, width, height);
    432		}
    433		/* No preferred modes, pick one off the list */
    434		if (!modes[i] && !list_empty(&connector->modes)) {
    435			list_for_each_entry(modes[i], &connector->modes, head)
    436				break;
    437		}
    438		/*
    439		 * In case of tiled mode if all tiles not present fallback to
    440		 * first available non tiled mode.
    441		 * After all tiles are present, try to find the tiled mode
    442		 * for all and if tiled mode not present due to fbcon size
    443		 * limitations, use first non tiled mode only for
    444		 * tile 0,0 and set to no mode for all other tiles.
    445		 */
    446		if (connector->has_tile) {
    447			if (num_tiled_conns <
    448			    connector->num_h_tile * connector->num_v_tile ||
    449			    (connector->tile_h_loc == 0 &&
    450			     connector->tile_v_loc == 0 &&
    451			     !drm_connector_get_tiled_mode(connector))) {
    452				DRM_DEBUG_KMS("Falling back to non tiled mode on Connector %d\n",
    453					      connector->base.id);
    454				modes[i] = drm_connector_fallback_non_tiled_mode(connector);
    455			} else {
    456				modes[i] = drm_connector_get_tiled_mode(connector);
    457			}
    458		}
    459
    460		DRM_DEBUG_KMS("found mode %s\n", modes[i] ? modes[i]->name :
    461			  "none");
    462		conn_configured |= BIT_ULL(i);
    463	}
    464
    465	if ((conn_configured & mask) != mask) {
    466		tile_pass++;
    467		goto retry;
    468	}
    469	return true;
    470}
    471
    472static bool connector_has_possible_crtc(struct drm_connector *connector,
    473					struct drm_crtc *crtc)
    474{
    475	struct drm_encoder *encoder;
    476
    477	drm_connector_for_each_possible_encoder(connector, encoder) {
    478		if (encoder->possible_crtcs & drm_crtc_mask(crtc))
    479			return true;
    480	}
    481
    482	return false;
    483}
    484
    485static int drm_client_pick_crtcs(struct drm_client_dev *client,
    486				 struct drm_connector **connectors,
    487				 unsigned int connector_count,
    488				 struct drm_crtc **best_crtcs,
    489				 struct drm_display_mode **modes,
    490				 int n, int width, int height)
    491{
    492	struct drm_device *dev = client->dev;
    493	struct drm_connector *connector;
    494	int my_score, best_score, score;
    495	struct drm_crtc **crtcs, *crtc;
    496	struct drm_mode_set *modeset;
    497	int o;
    498
    499	if (n == connector_count)
    500		return 0;
    501
    502	connector = connectors[n];
    503
    504	best_crtcs[n] = NULL;
    505	best_score = drm_client_pick_crtcs(client, connectors, connector_count,
    506					   best_crtcs, modes, n + 1, width, height);
    507	if (modes[n] == NULL)
    508		return best_score;
    509
    510	crtcs = kcalloc(connector_count, sizeof(*crtcs), GFP_KERNEL);
    511	if (!crtcs)
    512		return best_score;
    513
    514	my_score = 1;
    515	if (connector->status == connector_status_connected)
    516		my_score++;
    517	if (connector->cmdline_mode.specified)
    518		my_score++;
    519	if (drm_connector_has_preferred_mode(connector, width, height))
    520		my_score++;
    521
    522	/*
    523	 * select a crtc for this connector and then attempt to configure
    524	 * remaining connectors
    525	 */
    526	drm_client_for_each_modeset(modeset, client) {
    527		crtc = modeset->crtc;
    528
    529		if (!connector_has_possible_crtc(connector, crtc))
    530			continue;
    531
    532		for (o = 0; o < n; o++)
    533			if (best_crtcs[o] == crtc)
    534				break;
    535
    536		if (o < n) {
    537			/* ignore cloning unless only a single crtc */
    538			if (dev->mode_config.num_crtc > 1)
    539				continue;
    540
    541			if (!drm_mode_equal(modes[o], modes[n]))
    542				continue;
    543		}
    544
    545		crtcs[n] = crtc;
    546		memcpy(crtcs, best_crtcs, n * sizeof(*crtcs));
    547		score = my_score + drm_client_pick_crtcs(client, connectors, connector_count,
    548							 crtcs, modes, n + 1, width, height);
    549		if (score > best_score) {
    550			best_score = score;
    551			memcpy(best_crtcs, crtcs, connector_count * sizeof(*crtcs));
    552		}
    553	}
    554
    555	kfree(crtcs);
    556	return best_score;
    557}
    558
    559/* Try to read the BIOS display configuration and use it for the initial config */
    560static bool drm_client_firmware_config(struct drm_client_dev *client,
    561				       struct drm_connector **connectors,
    562				       unsigned int connector_count,
    563				       struct drm_crtc **crtcs,
    564				       struct drm_display_mode **modes,
    565				       struct drm_client_offset *offsets,
    566				       bool *enabled, int width, int height)
    567{
    568	const int count = min_t(unsigned int, connector_count, BITS_PER_LONG);
    569	unsigned long conn_configured, conn_seq, mask;
    570	struct drm_device *dev = client->dev;
    571	int i, j;
    572	bool *save_enabled;
    573	bool fallback = true, ret = true;
    574	int num_connectors_enabled = 0;
    575	int num_connectors_detected = 0;
    576	int num_tiled_conns = 0;
    577	struct drm_modeset_acquire_ctx ctx;
    578
    579	if (!drm_drv_uses_atomic_modeset(dev))
    580		return false;
    581
    582	if (WARN_ON(count <= 0))
    583		return false;
    584
    585	save_enabled = kcalloc(count, sizeof(bool), GFP_KERNEL);
    586	if (!save_enabled)
    587		return false;
    588
    589	drm_modeset_acquire_init(&ctx, 0);
    590
    591	while (drm_modeset_lock_all_ctx(dev, &ctx) != 0)
    592		drm_modeset_backoff(&ctx);
    593
    594	memcpy(save_enabled, enabled, count);
    595	mask = GENMASK(count - 1, 0);
    596	conn_configured = 0;
    597	for (i = 0; i < count; i++) {
    598		if (connectors[i]->has_tile &&
    599		    connectors[i]->status == connector_status_connected)
    600			num_tiled_conns++;
    601	}
    602retry:
    603	conn_seq = conn_configured;
    604	for (i = 0; i < count; i++) {
    605		struct drm_connector *connector;
    606		struct drm_encoder *encoder;
    607		struct drm_crtc *new_crtc;
    608
    609		connector = connectors[i];
    610
    611		if (conn_configured & BIT(i))
    612			continue;
    613
    614		if (conn_seq == 0 && !connector->has_tile)
    615			continue;
    616
    617		if (connector->status == connector_status_connected)
    618			num_connectors_detected++;
    619
    620		if (!enabled[i]) {
    621			DRM_DEBUG_KMS("connector %s not enabled, skipping\n",
    622				      connector->name);
    623			conn_configured |= BIT(i);
    624			continue;
    625		}
    626
    627		if (connector->force == DRM_FORCE_OFF) {
    628			DRM_DEBUG_KMS("connector %s is disabled by user, skipping\n",
    629				      connector->name);
    630			enabled[i] = false;
    631			continue;
    632		}
    633
    634		encoder = connector->state->best_encoder;
    635		if (!encoder || WARN_ON(!connector->state->crtc)) {
    636			if (connector->force > DRM_FORCE_OFF)
    637				goto bail;
    638
    639			DRM_DEBUG_KMS("connector %s has no encoder or crtc, skipping\n",
    640				      connector->name);
    641			enabled[i] = false;
    642			conn_configured |= BIT(i);
    643			continue;
    644		}
    645
    646		num_connectors_enabled++;
    647
    648		new_crtc = connector->state->crtc;
    649
    650		/*
    651		 * Make sure we're not trying to drive multiple connectors
    652		 * with a single CRTC, since our cloning support may not
    653		 * match the BIOS.
    654		 */
    655		for (j = 0; j < count; j++) {
    656			if (crtcs[j] == new_crtc) {
    657				DRM_DEBUG_KMS("fallback: cloned configuration\n");
    658				goto bail;
    659			}
    660		}
    661
    662		DRM_DEBUG_KMS("looking for cmdline mode on connector %s\n",
    663			      connector->name);
    664
    665		/* go for command line mode first */
    666		modes[i] = drm_connector_pick_cmdline_mode(connector);
    667
    668		/* try for preferred next */
    669		if (!modes[i]) {
    670			DRM_DEBUG_KMS("looking for preferred mode on connector %s %d\n",
    671				      connector->name, connector->has_tile);
    672			modes[i] = drm_connector_has_preferred_mode(connector, width, height);
    673		}
    674
    675		/* No preferred mode marked by the EDID? Are there any modes? */
    676		if (!modes[i] && !list_empty(&connector->modes)) {
    677			DRM_DEBUG_KMS("using first mode listed on connector %s\n",
    678				      connector->name);
    679			modes[i] = list_first_entry(&connector->modes,
    680						    struct drm_display_mode,
    681						    head);
    682		}
    683
    684		/* last resort: use current mode */
    685		if (!modes[i]) {
    686			/*
    687			 * IMPORTANT: We want to use the adjusted mode (i.e.
    688			 * after the panel fitter upscaling) as the initial
    689			 * config, not the input mode, which is what crtc->mode
    690			 * usually contains. But since our current
    691			 * code puts a mode derived from the post-pfit timings
    692			 * into crtc->mode this works out correctly.
    693			 *
    694			 * This is crtc->mode and not crtc->state->mode for the
    695			 * fastboot check to work correctly.
    696			 */
    697			DRM_DEBUG_KMS("looking for current mode on connector %s\n",
    698				      connector->name);
    699			modes[i] = &connector->state->crtc->mode;
    700		}
    701		/*
    702		 * In case of tiled modes, if all tiles are not present
    703		 * then fallback to a non tiled mode.
    704		 */
    705		if (connector->has_tile &&
    706		    num_tiled_conns < connector->num_h_tile * connector->num_v_tile) {
    707			DRM_DEBUG_KMS("Falling back to non tiled mode on Connector %d\n",
    708				      connector->base.id);
    709			modes[i] = drm_connector_fallback_non_tiled_mode(connector);
    710		}
    711		crtcs[i] = new_crtc;
    712
    713		DRM_DEBUG_KMS("connector %s on [CRTC:%d:%s]: %dx%d%s\n",
    714			      connector->name,
    715			      connector->state->crtc->base.id,
    716			      connector->state->crtc->name,
    717			      modes[i]->hdisplay, modes[i]->vdisplay,
    718			      modes[i]->flags & DRM_MODE_FLAG_INTERLACE ? "i" : "");
    719
    720		fallback = false;
    721		conn_configured |= BIT(i);
    722	}
    723
    724	if ((conn_configured & mask) != mask && conn_configured != conn_seq)
    725		goto retry;
    726
    727	/*
    728	 * If the BIOS didn't enable everything it could, fall back to have the
    729	 * same user experiencing of lighting up as much as possible like the
    730	 * fbdev helper library.
    731	 */
    732	if (num_connectors_enabled != num_connectors_detected &&
    733	    num_connectors_enabled < dev->mode_config.num_crtc) {
    734		DRM_DEBUG_KMS("fallback: Not all outputs enabled\n");
    735		DRM_DEBUG_KMS("Enabled: %i, detected: %i\n", num_connectors_enabled,
    736			      num_connectors_detected);
    737		fallback = true;
    738	}
    739
    740	if (fallback) {
    741bail:
    742		DRM_DEBUG_KMS("Not using firmware configuration\n");
    743		memcpy(enabled, save_enabled, count);
    744		ret = false;
    745	}
    746
    747	drm_modeset_drop_locks(&ctx);
    748	drm_modeset_acquire_fini(&ctx);
    749
    750	kfree(save_enabled);
    751	return ret;
    752}
    753
    754/**
    755 * drm_client_modeset_probe() - Probe for displays
    756 * @client: DRM client
    757 * @width: Maximum display mode width (optional)
    758 * @height: Maximum display mode height (optional)
    759 *
    760 * This function sets up display pipelines for enabled connectors and stores the
    761 * config in the client's modeset array.
    762 *
    763 * Returns:
    764 * Zero on success or negative error code on failure.
    765 */
    766int drm_client_modeset_probe(struct drm_client_dev *client, unsigned int width, unsigned int height)
    767{
    768	struct drm_connector *connector, **connectors = NULL;
    769	struct drm_connector_list_iter conn_iter;
    770	struct drm_device *dev = client->dev;
    771	unsigned int total_modes_count = 0;
    772	struct drm_client_offset *offsets;
    773	unsigned int connector_count = 0;
    774	struct drm_display_mode **modes;
    775	struct drm_crtc **crtcs;
    776	int i, ret = 0;
    777	bool *enabled;
    778
    779	DRM_DEBUG_KMS("\n");
    780
    781	if (!width)
    782		width = dev->mode_config.max_width;
    783	if (!height)
    784		height = dev->mode_config.max_height;
    785
    786	drm_connector_list_iter_begin(dev, &conn_iter);
    787	drm_client_for_each_connector_iter(connector, &conn_iter) {
    788		struct drm_connector **tmp;
    789
    790		tmp = krealloc(connectors, (connector_count + 1) * sizeof(*connectors), GFP_KERNEL);
    791		if (!tmp) {
    792			ret = -ENOMEM;
    793			goto free_connectors;
    794		}
    795
    796		connectors = tmp;
    797		drm_connector_get(connector);
    798		connectors[connector_count++] = connector;
    799	}
    800	drm_connector_list_iter_end(&conn_iter);
    801
    802	if (!connector_count)
    803		return 0;
    804
    805	crtcs = kcalloc(connector_count, sizeof(*crtcs), GFP_KERNEL);
    806	modes = kcalloc(connector_count, sizeof(*modes), GFP_KERNEL);
    807	offsets = kcalloc(connector_count, sizeof(*offsets), GFP_KERNEL);
    808	enabled = kcalloc(connector_count, sizeof(bool), GFP_KERNEL);
    809	if (!crtcs || !modes || !enabled || !offsets) {
    810		DRM_ERROR("Memory allocation failed\n");
    811		ret = -ENOMEM;
    812		goto out;
    813	}
    814
    815	mutex_lock(&client->modeset_mutex);
    816
    817	mutex_lock(&dev->mode_config.mutex);
    818	for (i = 0; i < connector_count; i++)
    819		total_modes_count += connectors[i]->funcs->fill_modes(connectors[i], width, height);
    820	if (!total_modes_count)
    821		DRM_DEBUG_KMS("No connectors reported connected with modes\n");
    822	drm_client_connectors_enabled(connectors, connector_count, enabled);
    823
    824	if (!drm_client_firmware_config(client, connectors, connector_count, crtcs,
    825					modes, offsets, enabled, width, height)) {
    826		memset(modes, 0, connector_count * sizeof(*modes));
    827		memset(crtcs, 0, connector_count * sizeof(*crtcs));
    828		memset(offsets, 0, connector_count * sizeof(*offsets));
    829
    830		if (!drm_client_target_cloned(dev, connectors, connector_count, modes,
    831					      offsets, enabled, width, height) &&
    832		    !drm_client_target_preferred(connectors, connector_count, modes,
    833						 offsets, enabled, width, height))
    834			DRM_ERROR("Unable to find initial modes\n");
    835
    836		DRM_DEBUG_KMS("picking CRTCs for %dx%d config\n",
    837			      width, height);
    838
    839		drm_client_pick_crtcs(client, connectors, connector_count,
    840				      crtcs, modes, 0, width, height);
    841	}
    842	mutex_unlock(&dev->mode_config.mutex);
    843
    844	drm_client_modeset_release(client);
    845
    846	for (i = 0; i < connector_count; i++) {
    847		struct drm_display_mode *mode = modes[i];
    848		struct drm_crtc *crtc = crtcs[i];
    849		struct drm_client_offset *offset = &offsets[i];
    850
    851		if (mode && crtc) {
    852			struct drm_mode_set *modeset = drm_client_find_modeset(client, crtc);
    853			struct drm_connector *connector = connectors[i];
    854
    855			DRM_DEBUG_KMS("desired mode %s set on crtc %d (%d,%d)\n",
    856				      mode->name, crtc->base.id, offset->x, offset->y);
    857
    858			if (WARN_ON_ONCE(modeset->num_connectors == DRM_CLIENT_MAX_CLONED_CONNECTORS ||
    859					 (dev->mode_config.num_crtc > 1 && modeset->num_connectors == 1))) {
    860				ret = -EINVAL;
    861				break;
    862			}
    863
    864			modeset->mode = drm_mode_duplicate(dev, mode);
    865			drm_connector_get(connector);
    866			modeset->connectors[modeset->num_connectors++] = connector;
    867			modeset->x = offset->x;
    868			modeset->y = offset->y;
    869		}
    870	}
    871
    872	mutex_unlock(&client->modeset_mutex);
    873out:
    874	kfree(crtcs);
    875	kfree(modes);
    876	kfree(offsets);
    877	kfree(enabled);
    878free_connectors:
    879	for (i = 0; i < connector_count; i++)
    880		drm_connector_put(connectors[i]);
    881	kfree(connectors);
    882
    883	return ret;
    884}
    885EXPORT_SYMBOL(drm_client_modeset_probe);
    886
    887/**
    888 * drm_client_rotation() - Check the initial rotation value
    889 * @modeset: DRM modeset
    890 * @rotation: Returned rotation value
    891 *
    892 * This function checks if the primary plane in @modeset can hw rotate
    893 * to match the rotation needed on its connector.
    894 *
    895 * Note: Currently only 0 and 180 degrees are supported.
    896 *
    897 * Return:
    898 * True if the plane can do the rotation, false otherwise.
    899 */
    900bool drm_client_rotation(struct drm_mode_set *modeset, unsigned int *rotation)
    901{
    902	struct drm_connector *connector = modeset->connectors[0];
    903	struct drm_plane *plane = modeset->crtc->primary;
    904	struct drm_cmdline_mode *cmdline;
    905	u64 valid_mask = 0;
    906	unsigned int i;
    907
    908	if (!modeset->num_connectors)
    909		return false;
    910
    911	switch (connector->display_info.panel_orientation) {
    912	case DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP:
    913		*rotation = DRM_MODE_ROTATE_180;
    914		break;
    915	case DRM_MODE_PANEL_ORIENTATION_LEFT_UP:
    916		*rotation = DRM_MODE_ROTATE_90;
    917		break;
    918	case DRM_MODE_PANEL_ORIENTATION_RIGHT_UP:
    919		*rotation = DRM_MODE_ROTATE_270;
    920		break;
    921	default:
    922		*rotation = DRM_MODE_ROTATE_0;
    923	}
    924
    925	/**
    926	 * The panel already defined the default rotation
    927	 * through its orientation. Whatever has been provided
    928	 * on the command line needs to be added to that.
    929	 *
    930	 * Unfortunately, the rotations are at different bit
    931	 * indices, so the math to add them up are not as
    932	 * trivial as they could.
    933	 *
    934	 * Reflections on the other hand are pretty trivial to deal with, a
    935	 * simple XOR between the two handle the addition nicely.
    936	 */
    937	cmdline = &connector->cmdline_mode;
    938	if (cmdline->specified && cmdline->rotation_reflection) {
    939		unsigned int cmdline_rest, panel_rest;
    940		unsigned int cmdline_rot, panel_rot;
    941		unsigned int sum_rot, sum_rest;
    942
    943		panel_rot = ilog2(*rotation & DRM_MODE_ROTATE_MASK);
    944		cmdline_rot = ilog2(cmdline->rotation_reflection & DRM_MODE_ROTATE_MASK);
    945		sum_rot = (panel_rot + cmdline_rot) % 4;
    946
    947		panel_rest = *rotation & ~DRM_MODE_ROTATE_MASK;
    948		cmdline_rest = cmdline->rotation_reflection & ~DRM_MODE_ROTATE_MASK;
    949		sum_rest = panel_rest ^ cmdline_rest;
    950
    951		*rotation = (1 << sum_rot) | sum_rest;
    952	}
    953
    954	/*
    955	 * TODO: support 90 / 270 degree hardware rotation,
    956	 * depending on the hardware this may require the framebuffer
    957	 * to be in a specific tiling format.
    958	 */
    959	if (((*rotation & DRM_MODE_ROTATE_MASK) != DRM_MODE_ROTATE_0 &&
    960	     (*rotation & DRM_MODE_ROTATE_MASK) != DRM_MODE_ROTATE_180) ||
    961	    !plane->rotation_property)
    962		return false;
    963
    964	for (i = 0; i < plane->rotation_property->num_values; i++)
    965		valid_mask |= (1ULL << plane->rotation_property->values[i]);
    966
    967	if (!(*rotation & valid_mask))
    968		return false;
    969
    970	return true;
    971}
    972EXPORT_SYMBOL(drm_client_rotation);
    973
    974static int drm_client_modeset_commit_atomic(struct drm_client_dev *client, bool active, bool check)
    975{
    976	struct drm_device *dev = client->dev;
    977	struct drm_plane *plane;
    978	struct drm_atomic_state *state;
    979	struct drm_modeset_acquire_ctx ctx;
    980	struct drm_mode_set *mode_set;
    981	int ret;
    982
    983	drm_modeset_acquire_init(&ctx, 0);
    984
    985	state = drm_atomic_state_alloc(dev);
    986	if (!state) {
    987		ret = -ENOMEM;
    988		goto out_ctx;
    989	}
    990
    991	state->acquire_ctx = &ctx;
    992retry:
    993	drm_for_each_plane(plane, dev) {
    994		struct drm_plane_state *plane_state;
    995
    996		plane_state = drm_atomic_get_plane_state(state, plane);
    997		if (IS_ERR(plane_state)) {
    998			ret = PTR_ERR(plane_state);
    999			goto out_state;
   1000		}
   1001
   1002		plane_state->rotation = DRM_MODE_ROTATE_0;
   1003
   1004		/* disable non-primary: */
   1005		if (plane->type == DRM_PLANE_TYPE_PRIMARY)
   1006			continue;
   1007
   1008		ret = __drm_atomic_helper_disable_plane(plane, plane_state);
   1009		if (ret != 0)
   1010			goto out_state;
   1011	}
   1012
   1013	drm_client_for_each_modeset(mode_set, client) {
   1014		struct drm_plane *primary = mode_set->crtc->primary;
   1015		unsigned int rotation;
   1016
   1017		if (drm_client_rotation(mode_set, &rotation)) {
   1018			struct drm_plane_state *plane_state;
   1019
   1020			/* Cannot fail as we've already gotten the plane state above */
   1021			plane_state = drm_atomic_get_new_plane_state(state, primary);
   1022			plane_state->rotation = rotation;
   1023		}
   1024
   1025		ret = __drm_atomic_helper_set_config(mode_set, state);
   1026		if (ret != 0)
   1027			goto out_state;
   1028
   1029		/*
   1030		 * __drm_atomic_helper_set_config() sets active when a
   1031		 * mode is set, unconditionally clear it if we force DPMS off
   1032		 */
   1033		if (!active) {
   1034			struct drm_crtc *crtc = mode_set->crtc;
   1035			struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
   1036
   1037			crtc_state->active = false;
   1038		}
   1039	}
   1040
   1041	if (check)
   1042		ret = drm_atomic_check_only(state);
   1043	else
   1044		ret = drm_atomic_commit(state);
   1045
   1046out_state:
   1047	if (ret == -EDEADLK)
   1048		goto backoff;
   1049
   1050	drm_atomic_state_put(state);
   1051out_ctx:
   1052	drm_modeset_drop_locks(&ctx);
   1053	drm_modeset_acquire_fini(&ctx);
   1054
   1055	return ret;
   1056
   1057backoff:
   1058	drm_atomic_state_clear(state);
   1059	drm_modeset_backoff(&ctx);
   1060
   1061	goto retry;
   1062}
   1063
   1064static int drm_client_modeset_commit_legacy(struct drm_client_dev *client)
   1065{
   1066	struct drm_device *dev = client->dev;
   1067	struct drm_mode_set *mode_set;
   1068	struct drm_plane *plane;
   1069	int ret = 0;
   1070
   1071	drm_modeset_lock_all(dev);
   1072	drm_for_each_plane(plane, dev) {
   1073		if (plane->type != DRM_PLANE_TYPE_PRIMARY)
   1074			drm_plane_force_disable(plane);
   1075
   1076		if (plane->rotation_property)
   1077			drm_mode_plane_set_obj_prop(plane,
   1078						    plane->rotation_property,
   1079						    DRM_MODE_ROTATE_0);
   1080	}
   1081
   1082	drm_client_for_each_modeset(mode_set, client) {
   1083		struct drm_crtc *crtc = mode_set->crtc;
   1084
   1085		if (crtc->funcs->cursor_set2) {
   1086			ret = crtc->funcs->cursor_set2(crtc, NULL, 0, 0, 0, 0, 0);
   1087			if (ret)
   1088				goto out;
   1089		} else if (crtc->funcs->cursor_set) {
   1090			ret = crtc->funcs->cursor_set(crtc, NULL, 0, 0, 0);
   1091			if (ret)
   1092				goto out;
   1093		}
   1094
   1095		ret = drm_mode_set_config_internal(mode_set);
   1096		if (ret)
   1097			goto out;
   1098	}
   1099out:
   1100	drm_modeset_unlock_all(dev);
   1101
   1102	return ret;
   1103}
   1104
   1105/**
   1106 * drm_client_modeset_check() - Check modeset configuration
   1107 * @client: DRM client
   1108 *
   1109 * Check modeset configuration.
   1110 *
   1111 * Returns:
   1112 * Zero on success or negative error code on failure.
   1113 */
   1114int drm_client_modeset_check(struct drm_client_dev *client)
   1115{
   1116	int ret;
   1117
   1118	if (!drm_drv_uses_atomic_modeset(client->dev))
   1119		return 0;
   1120
   1121	mutex_lock(&client->modeset_mutex);
   1122	ret = drm_client_modeset_commit_atomic(client, true, true);
   1123	mutex_unlock(&client->modeset_mutex);
   1124
   1125	return ret;
   1126}
   1127EXPORT_SYMBOL(drm_client_modeset_check);
   1128
   1129/**
   1130 * drm_client_modeset_commit_locked() - Force commit CRTC configuration
   1131 * @client: DRM client
   1132 *
   1133 * Commit modeset configuration to crtcs without checking if there is a DRM
   1134 * master. The assumption is that the caller already holds an internal DRM
   1135 * master reference acquired with drm_master_internal_acquire().
   1136 *
   1137 * Returns:
   1138 * Zero on success or negative error code on failure.
   1139 */
   1140int drm_client_modeset_commit_locked(struct drm_client_dev *client)
   1141{
   1142	struct drm_device *dev = client->dev;
   1143	int ret;
   1144
   1145	mutex_lock(&client->modeset_mutex);
   1146	if (drm_drv_uses_atomic_modeset(dev))
   1147		ret = drm_client_modeset_commit_atomic(client, true, false);
   1148	else
   1149		ret = drm_client_modeset_commit_legacy(client);
   1150	mutex_unlock(&client->modeset_mutex);
   1151
   1152	return ret;
   1153}
   1154EXPORT_SYMBOL(drm_client_modeset_commit_locked);
   1155
   1156/**
   1157 * drm_client_modeset_commit() - Commit CRTC configuration
   1158 * @client: DRM client
   1159 *
   1160 * Commit modeset configuration to crtcs.
   1161 *
   1162 * Returns:
   1163 * Zero on success or negative error code on failure.
   1164 */
   1165int drm_client_modeset_commit(struct drm_client_dev *client)
   1166{
   1167	struct drm_device *dev = client->dev;
   1168	int ret;
   1169
   1170	if (!drm_master_internal_acquire(dev))
   1171		return -EBUSY;
   1172
   1173	ret = drm_client_modeset_commit_locked(client);
   1174
   1175	drm_master_internal_release(dev);
   1176
   1177	return ret;
   1178}
   1179EXPORT_SYMBOL(drm_client_modeset_commit);
   1180
   1181static void drm_client_modeset_dpms_legacy(struct drm_client_dev *client, int dpms_mode)
   1182{
   1183	struct drm_device *dev = client->dev;
   1184	struct drm_connector *connector;
   1185	struct drm_mode_set *modeset;
   1186	struct drm_modeset_acquire_ctx ctx;
   1187	int j;
   1188	int ret;
   1189
   1190	DRM_MODESET_LOCK_ALL_BEGIN(dev, ctx, 0, ret);
   1191	drm_client_for_each_modeset(modeset, client) {
   1192		if (!modeset->crtc->enabled)
   1193			continue;
   1194
   1195		for (j = 0; j < modeset->num_connectors; j++) {
   1196			connector = modeset->connectors[j];
   1197			connector->funcs->dpms(connector, dpms_mode);
   1198			drm_object_property_set_value(&connector->base,
   1199				dev->mode_config.dpms_property, dpms_mode);
   1200		}
   1201	}
   1202	DRM_MODESET_LOCK_ALL_END(dev, ctx, ret);
   1203}
   1204
   1205/**
   1206 * drm_client_modeset_dpms() - Set DPMS mode
   1207 * @client: DRM client
   1208 * @mode: DPMS mode
   1209 *
   1210 * Note: For atomic drivers @mode is reduced to on/off.
   1211 *
   1212 * Returns:
   1213 * Zero on success or negative error code on failure.
   1214 */
   1215int drm_client_modeset_dpms(struct drm_client_dev *client, int mode)
   1216{
   1217	struct drm_device *dev = client->dev;
   1218	int ret = 0;
   1219
   1220	if (!drm_master_internal_acquire(dev))
   1221		return -EBUSY;
   1222
   1223	mutex_lock(&client->modeset_mutex);
   1224	if (drm_drv_uses_atomic_modeset(dev))
   1225		ret = drm_client_modeset_commit_atomic(client, mode == DRM_MODE_DPMS_ON, false);
   1226	else
   1227		drm_client_modeset_dpms_legacy(client, mode);
   1228	mutex_unlock(&client->modeset_mutex);
   1229
   1230	drm_master_internal_release(dev);
   1231
   1232	return ret;
   1233}
   1234EXPORT_SYMBOL(drm_client_modeset_dpms);