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