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