Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: MIT
0002 /*
0003  * Copyright 2018 Noralf Trønnes
0004  * Copyright (c) 2006-2009 Red Hat Inc.
0005  * Copyright (c) 2006-2008 Intel Corporation
0006  *   Jesse Barnes <jesse.barnes@intel.com>
0007  * Copyright (c) 2007 Dave Airlie <airlied@linux.ie>
0008  */
0009 
0010 #include "drm/drm_modeset_lock.h"
0011 #include <linux/module.h>
0012 #include <linux/mutex.h>
0013 #include <linux/slab.h>
0014 #include <linux/string_helpers.h>
0015 
0016 #include <drm/drm_atomic.h>
0017 #include <drm/drm_client.h>
0018 #include <drm/drm_connector.h>
0019 #include <drm/drm_crtc.h>
0020 #include <drm/drm_device.h>
0021 #include <drm/drm_drv.h>
0022 #include <drm/drm_edid.h>
0023 #include <drm/drm_encoder.h>
0024 #include <drm/drm_print.h>
0025 
0026 #include "drm_crtc_internal.h"
0027 #include "drm_internal.h"
0028 
0029 #define DRM_CLIENT_MAX_CLONED_CONNECTORS    8
0030 
0031 struct drm_client_offset {
0032     int x, y;
0033 };
0034 
0035 int drm_client_modeset_create(struct drm_client_dev *client)
0036 {
0037     struct drm_device *dev = client->dev;
0038     unsigned int num_crtc = dev->mode_config.num_crtc;
0039     unsigned int max_connector_count = 1;
0040     struct drm_mode_set *modeset;
0041     struct drm_crtc *crtc;
0042     unsigned int i = 0;
0043 
0044     /* Add terminating zero entry to enable index less iteration */
0045     client->modesets = kcalloc(num_crtc + 1, sizeof(*client->modesets), GFP_KERNEL);
0046     if (!client->modesets)
0047         return -ENOMEM;
0048 
0049     mutex_init(&client->modeset_mutex);
0050 
0051     drm_for_each_crtc(crtc, dev)
0052         client->modesets[i++].crtc = crtc;
0053 
0054     /* Cloning is only supported in the single crtc case. */
0055     if (num_crtc == 1)
0056         max_connector_count = DRM_CLIENT_MAX_CLONED_CONNECTORS;
0057 
0058     for (modeset = client->modesets; modeset->crtc; modeset++) {
0059         modeset->connectors = kcalloc(max_connector_count,
0060                           sizeof(*modeset->connectors), GFP_KERNEL);
0061         if (!modeset->connectors)
0062             goto err_free;
0063     }
0064 
0065     return 0;
0066 
0067 err_free:
0068     drm_client_modeset_free(client);
0069 
0070     return -ENOMEM;
0071 }
0072 
0073 static void drm_client_modeset_release(struct drm_client_dev *client)
0074 {
0075     struct drm_mode_set *modeset;
0076     unsigned int i;
0077 
0078     drm_client_for_each_modeset(modeset, client) {
0079         drm_mode_destroy(client->dev, modeset->mode);
0080         modeset->mode = NULL;
0081         modeset->fb = NULL;
0082 
0083         for (i = 0; i < modeset->num_connectors; i++) {
0084             drm_connector_put(modeset->connectors[i]);
0085             modeset->connectors[i] = NULL;
0086         }
0087         modeset->num_connectors = 0;
0088     }
0089 }
0090 
0091 void drm_client_modeset_free(struct drm_client_dev *client)
0092 {
0093     struct drm_mode_set *modeset;
0094 
0095     mutex_lock(&client->modeset_mutex);
0096 
0097     drm_client_modeset_release(client);
0098 
0099     drm_client_for_each_modeset(modeset, client)
0100         kfree(modeset->connectors);
0101 
0102     mutex_unlock(&client->modeset_mutex);
0103 
0104     mutex_destroy(&client->modeset_mutex);
0105     kfree(client->modesets);
0106 }
0107 
0108 static struct drm_mode_set *
0109 drm_client_find_modeset(struct drm_client_dev *client, struct drm_crtc *crtc)
0110 {
0111     struct drm_mode_set *modeset;
0112 
0113     drm_client_for_each_modeset(modeset, client)
0114         if (modeset->crtc == crtc)
0115             return modeset;
0116 
0117     return NULL;
0118 }
0119 
0120 static struct drm_display_mode *
0121 drm_connector_get_tiled_mode(struct drm_connector *connector)
0122 {
0123     struct drm_display_mode *mode;
0124 
0125     list_for_each_entry(mode, &connector->modes, head) {
0126         if (mode->hdisplay == connector->tile_h_size &&
0127             mode->vdisplay == connector->tile_v_size)
0128             return mode;
0129     }
0130     return NULL;
0131 }
0132 
0133 static struct drm_display_mode *
0134 drm_connector_fallback_non_tiled_mode(struct drm_connector *connector)
0135 {
0136     struct drm_display_mode *mode;
0137 
0138     list_for_each_entry(mode, &connector->modes, head) {
0139         if (mode->hdisplay == connector->tile_h_size &&
0140             mode->vdisplay == connector->tile_v_size)
0141             continue;
0142         return mode;
0143     }
0144     return NULL;
0145 }
0146 
0147 static struct drm_display_mode *
0148 drm_connector_has_preferred_mode(struct drm_connector *connector, int width, int height)
0149 {
0150     struct drm_display_mode *mode;
0151 
0152     list_for_each_entry(mode, &connector->modes, head) {
0153         if (mode->hdisplay > width ||
0154             mode->vdisplay > height)
0155             continue;
0156         if (mode->type & DRM_MODE_TYPE_PREFERRED)
0157             return mode;
0158     }
0159     return NULL;
0160 }
0161 
0162 static struct drm_display_mode *drm_connector_pick_cmdline_mode(struct drm_connector *connector)
0163 {
0164     struct drm_cmdline_mode *cmdline_mode;
0165     struct drm_display_mode *mode;
0166     bool prefer_non_interlace;
0167 
0168     /*
0169      * Find a user-defined mode. If the user gave us a valid
0170      * mode on the kernel command line, it will show up in this
0171      * list.
0172      */
0173 
0174     list_for_each_entry(mode, &connector->modes, head) {
0175         if (mode->type & DRM_MODE_TYPE_USERDEF)
0176             return mode;
0177     }
0178 
0179     cmdline_mode = &connector->cmdline_mode;
0180     if (cmdline_mode->specified == false)
0181         return NULL;
0182 
0183     /*
0184      * Attempt to find a matching mode in the list of modes we
0185      * have gotten so far.
0186      */
0187 
0188     prefer_non_interlace = !cmdline_mode->interlace;
0189 again:
0190     list_for_each_entry(mode, &connector->modes, head) {
0191         /* Check (optional) mode name first */
0192         if (!strcmp(mode->name, cmdline_mode->name))
0193             return mode;
0194 
0195         /* check width/height */
0196         if (mode->hdisplay != cmdline_mode->xres ||
0197             mode->vdisplay != cmdline_mode->yres)
0198             continue;
0199 
0200         if (cmdline_mode->refresh_specified) {
0201             if (drm_mode_vrefresh(mode) != cmdline_mode->refresh)
0202                 continue;
0203         }
0204 
0205         if (cmdline_mode->interlace) {
0206             if (!(mode->flags & DRM_MODE_FLAG_INTERLACE))
0207                 continue;
0208         } else if (prefer_non_interlace) {
0209             if (mode->flags & DRM_MODE_FLAG_INTERLACE)
0210                 continue;
0211         }
0212         return mode;
0213     }
0214 
0215     if (prefer_non_interlace) {
0216         prefer_non_interlace = false;
0217         goto again;
0218     }
0219 
0220     return NULL;
0221 }
0222 
0223 static bool drm_connector_enabled(struct drm_connector *connector, bool strict)
0224 {
0225     bool enable;
0226 
0227     if (connector->display_info.non_desktop)
0228         return false;
0229 
0230     if (strict)
0231         enable = connector->status == connector_status_connected;
0232     else
0233         enable = connector->status != connector_status_disconnected;
0234 
0235     return enable;
0236 }
0237 
0238 static void drm_client_connectors_enabled(struct drm_connector **connectors,
0239                       unsigned int connector_count,
0240                       bool *enabled)
0241 {
0242     bool any_enabled = false;
0243     struct drm_connector *connector;
0244     int i = 0;
0245 
0246     for (i = 0; i < connector_count; i++) {
0247         connector = connectors[i];
0248         enabled[i] = drm_connector_enabled(connector, true);
0249         DRM_DEBUG_KMS("connector %d enabled? %s\n", connector->base.id,
0250                   connector->display_info.non_desktop ? "non desktop" : str_yes_no(enabled[i]));
0251 
0252         any_enabled |= enabled[i];
0253     }
0254 
0255     if (any_enabled)
0256         return;
0257 
0258     for (i = 0; i < connector_count; i++)
0259         enabled[i] = drm_connector_enabled(connectors[i], false);
0260 }
0261 
0262 static bool drm_client_target_cloned(struct drm_device *dev,
0263                      struct drm_connector **connectors,
0264                      unsigned int connector_count,
0265                      struct drm_display_mode **modes,
0266                      struct drm_client_offset *offsets,
0267                      bool *enabled, int width, int height)
0268 {
0269     int count, i, j;
0270     bool can_clone = false;
0271     struct drm_display_mode *dmt_mode, *mode;
0272 
0273     /* only contemplate cloning in the single crtc case */
0274     if (dev->mode_config.num_crtc > 1)
0275         return false;
0276 
0277     count = 0;
0278     for (i = 0; i < connector_count; i++) {
0279         if (enabled[i])
0280             count++;
0281     }
0282 
0283     /* only contemplate cloning if more than one connector is enabled */
0284     if (count <= 1)
0285         return false;
0286 
0287     /* check the command line or if nothing common pick 1024x768 */
0288     can_clone = true;
0289     for (i = 0; i < connector_count; i++) {
0290         if (!enabled[i])
0291             continue;
0292         modes[i] = drm_connector_pick_cmdline_mode(connectors[i]);
0293         if (!modes[i]) {
0294             can_clone = false;
0295             break;
0296         }
0297         for (j = 0; j < i; j++) {
0298             if (!enabled[j])
0299                 continue;
0300             if (!drm_mode_match(modes[j], modes[i],
0301                         DRM_MODE_MATCH_TIMINGS |
0302                         DRM_MODE_MATCH_CLOCK |
0303                         DRM_MODE_MATCH_FLAGS |
0304                         DRM_MODE_MATCH_3D_FLAGS))
0305                 can_clone = false;
0306         }
0307     }
0308 
0309     if (can_clone) {
0310         DRM_DEBUG_KMS("can clone using command line\n");
0311         return true;
0312     }
0313 
0314     /* try and find a 1024x768 mode on each connector */
0315     can_clone = true;
0316     dmt_mode = drm_mode_find_dmt(dev, 1024, 768, 60, false);
0317 
0318     for (i = 0; i < connector_count; i++) {
0319         if (!enabled[i])
0320             continue;
0321 
0322         list_for_each_entry(mode, &connectors[i]->modes, head) {
0323             if (drm_mode_match(mode, dmt_mode,
0324                        DRM_MODE_MATCH_TIMINGS |
0325                        DRM_MODE_MATCH_CLOCK |
0326                        DRM_MODE_MATCH_FLAGS |
0327                        DRM_MODE_MATCH_3D_FLAGS))
0328                 modes[i] = mode;
0329         }
0330         if (!modes[i])
0331             can_clone = false;
0332     }
0333 
0334     if (can_clone) {
0335         DRM_DEBUG_KMS("can clone using 1024x768\n");
0336         return true;
0337     }
0338     DRM_INFO("kms: can't enable cloning when we probably wanted to.\n");
0339     return false;
0340 }
0341 
0342 static int drm_client_get_tile_offsets(struct drm_connector **connectors,
0343                        unsigned int connector_count,
0344                        struct drm_display_mode **modes,
0345                        struct drm_client_offset *offsets,
0346                        int idx,
0347                        int h_idx, int v_idx)
0348 {
0349     struct drm_connector *connector;
0350     int i;
0351     int hoffset = 0, voffset = 0;
0352 
0353     for (i = 0; i < connector_count; i++) {
0354         connector = connectors[i];
0355         if (!connector->has_tile)
0356             continue;
0357 
0358         if (!modes[i] && (h_idx || v_idx)) {
0359             DRM_DEBUG_KMS("no modes for connector tiled %d %d\n", i,
0360                       connector->base.id);
0361             continue;
0362         }
0363         if (connector->tile_h_loc < h_idx)
0364             hoffset += modes[i]->hdisplay;
0365 
0366         if (connector->tile_v_loc < v_idx)
0367             voffset += modes[i]->vdisplay;
0368     }
0369     offsets[idx].x = hoffset;
0370     offsets[idx].y = voffset;
0371     DRM_DEBUG_KMS("returned %d %d for %d %d\n", hoffset, voffset, h_idx, v_idx);
0372     return 0;
0373 }
0374 
0375 static bool drm_client_target_preferred(struct drm_connector **connectors,
0376                     unsigned int connector_count,
0377                     struct drm_display_mode **modes,
0378                     struct drm_client_offset *offsets,
0379                     bool *enabled, int width, int height)
0380 {
0381     const u64 mask = BIT_ULL(connector_count) - 1;
0382     struct drm_connector *connector;
0383     u64 conn_configured = 0;
0384     int tile_pass = 0;
0385     int num_tiled_conns = 0;
0386     int i;
0387 
0388     for (i = 0; i < connector_count; i++) {
0389         if (connectors[i]->has_tile &&
0390             connectors[i]->status == connector_status_connected)
0391             num_tiled_conns++;
0392     }
0393 
0394 retry:
0395     for (i = 0; i < connector_count; i++) {
0396         connector = connectors[i];
0397 
0398         if (conn_configured & BIT_ULL(i))
0399             continue;
0400 
0401         if (enabled[i] == false) {
0402             conn_configured |= BIT_ULL(i);
0403             continue;
0404         }
0405 
0406         /* first pass over all the untiled connectors */
0407         if (tile_pass == 0 && connector->has_tile)
0408             continue;
0409 
0410         if (tile_pass == 1) {
0411             if (connector->tile_h_loc != 0 ||
0412                 connector->tile_v_loc != 0)
0413                 continue;
0414 
0415         } else {
0416             if (connector->tile_h_loc != tile_pass - 1 &&
0417                 connector->tile_v_loc != tile_pass - 1)
0418             /* if this tile_pass doesn't cover any of the tiles - keep going */
0419                 continue;
0420 
0421             /*
0422              * find the tile offsets for this pass - need to find
0423              * all tiles left and above
0424              */
0425             drm_client_get_tile_offsets(connectors, connector_count, modes, offsets, i,
0426                             connector->tile_h_loc, connector->tile_v_loc);
0427         }
0428         DRM_DEBUG_KMS("looking for cmdline mode on connector %d\n",
0429                   connector->base.id);
0430 
0431         /* got for command line mode first */
0432         modes[i] = drm_connector_pick_cmdline_mode(connector);
0433         if (!modes[i]) {
0434             DRM_DEBUG_KMS("looking for preferred mode on connector %d %d\n",
0435                       connector->base.id, connector->tile_group ? connector->tile_group->id : 0);
0436             modes[i] = drm_connector_has_preferred_mode(connector, width, height);
0437         }
0438         /* No preferred modes, pick one off the list */
0439         if (!modes[i] && !list_empty(&connector->modes)) {
0440             list_for_each_entry(modes[i], &connector->modes, head)
0441                 break;
0442         }
0443         /*
0444          * In case of tiled mode if all tiles not present fallback to
0445          * first available non tiled mode.
0446          * After all tiles are present, try to find the tiled mode
0447          * for all and if tiled mode not present due to fbcon size
0448          * limitations, use first non tiled mode only for
0449          * tile 0,0 and set to no mode for all other tiles.
0450          */
0451         if (connector->has_tile) {
0452             if (num_tiled_conns <
0453                 connector->num_h_tile * connector->num_v_tile ||
0454                 (connector->tile_h_loc == 0 &&
0455                  connector->tile_v_loc == 0 &&
0456                  !drm_connector_get_tiled_mode(connector))) {
0457                 DRM_DEBUG_KMS("Falling back to non tiled mode on Connector %d\n",
0458                           connector->base.id);
0459                 modes[i] = drm_connector_fallback_non_tiled_mode(connector);
0460             } else {
0461                 modes[i] = drm_connector_get_tiled_mode(connector);
0462             }
0463         }
0464 
0465         DRM_DEBUG_KMS("found mode %s\n", modes[i] ? modes[i]->name :
0466               "none");
0467         conn_configured |= BIT_ULL(i);
0468     }
0469 
0470     if ((conn_configured & mask) != mask) {
0471         tile_pass++;
0472         goto retry;
0473     }
0474     return true;
0475 }
0476 
0477 static bool connector_has_possible_crtc(struct drm_connector *connector,
0478                     struct drm_crtc *crtc)
0479 {
0480     struct drm_encoder *encoder;
0481 
0482     drm_connector_for_each_possible_encoder(connector, encoder) {
0483         if (encoder->possible_crtcs & drm_crtc_mask(crtc))
0484             return true;
0485     }
0486 
0487     return false;
0488 }
0489 
0490 static int drm_client_pick_crtcs(struct drm_client_dev *client,
0491                  struct drm_connector **connectors,
0492                  unsigned int connector_count,
0493                  struct drm_crtc **best_crtcs,
0494                  struct drm_display_mode **modes,
0495                  int n, int width, int height)
0496 {
0497     struct drm_device *dev = client->dev;
0498     struct drm_connector *connector;
0499     int my_score, best_score, score;
0500     struct drm_crtc **crtcs, *crtc;
0501     struct drm_mode_set *modeset;
0502     int o;
0503 
0504     if (n == connector_count)
0505         return 0;
0506 
0507     connector = connectors[n];
0508 
0509     best_crtcs[n] = NULL;
0510     best_score = drm_client_pick_crtcs(client, connectors, connector_count,
0511                        best_crtcs, modes, n + 1, width, height);
0512     if (modes[n] == NULL)
0513         return best_score;
0514 
0515     crtcs = kcalloc(connector_count, sizeof(*crtcs), GFP_KERNEL);
0516     if (!crtcs)
0517         return best_score;
0518 
0519     my_score = 1;
0520     if (connector->status == connector_status_connected)
0521         my_score++;
0522     if (connector->cmdline_mode.specified)
0523         my_score++;
0524     if (drm_connector_has_preferred_mode(connector, width, height))
0525         my_score++;
0526 
0527     /*
0528      * select a crtc for this connector and then attempt to configure
0529      * remaining connectors
0530      */
0531     drm_client_for_each_modeset(modeset, client) {
0532         crtc = modeset->crtc;
0533 
0534         if (!connector_has_possible_crtc(connector, crtc))
0535             continue;
0536 
0537         for (o = 0; o < n; o++)
0538             if (best_crtcs[o] == crtc)
0539                 break;
0540 
0541         if (o < n) {
0542             /* ignore cloning unless only a single crtc */
0543             if (dev->mode_config.num_crtc > 1)
0544                 continue;
0545 
0546             if (!drm_mode_equal(modes[o], modes[n]))
0547                 continue;
0548         }
0549 
0550         crtcs[n] = crtc;
0551         memcpy(crtcs, best_crtcs, n * sizeof(*crtcs));
0552         score = my_score + drm_client_pick_crtcs(client, connectors, connector_count,
0553                              crtcs, modes, n + 1, width, height);
0554         if (score > best_score) {
0555             best_score = score;
0556             memcpy(best_crtcs, crtcs, connector_count * sizeof(*crtcs));
0557         }
0558     }
0559 
0560     kfree(crtcs);
0561     return best_score;
0562 }
0563 
0564 /* Try to read the BIOS display configuration and use it for the initial config */
0565 static bool drm_client_firmware_config(struct drm_client_dev *client,
0566                        struct drm_connector **connectors,
0567                        unsigned int connector_count,
0568                        struct drm_crtc **crtcs,
0569                        struct drm_display_mode **modes,
0570                        struct drm_client_offset *offsets,
0571                        bool *enabled, int width, int height)
0572 {
0573     const int count = min_t(unsigned int, connector_count, BITS_PER_LONG);
0574     unsigned long conn_configured, conn_seq, mask;
0575     struct drm_device *dev = client->dev;
0576     int i, j;
0577     bool *save_enabled;
0578     bool fallback = true, ret = true;
0579     int num_connectors_enabled = 0;
0580     int num_connectors_detected = 0;
0581     int num_tiled_conns = 0;
0582     struct drm_modeset_acquire_ctx ctx;
0583 
0584     if (!drm_drv_uses_atomic_modeset(dev))
0585         return false;
0586 
0587     if (WARN_ON(count <= 0))
0588         return false;
0589 
0590     save_enabled = kcalloc(count, sizeof(bool), GFP_KERNEL);
0591     if (!save_enabled)
0592         return false;
0593 
0594     drm_modeset_acquire_init(&ctx, 0);
0595 
0596     while (drm_modeset_lock_all_ctx(dev, &ctx) != 0)
0597         drm_modeset_backoff(&ctx);
0598 
0599     memcpy(save_enabled, enabled, count);
0600     mask = GENMASK(count - 1, 0);
0601     conn_configured = 0;
0602     for (i = 0; i < count; i++) {
0603         if (connectors[i]->has_tile &&
0604             connectors[i]->status == connector_status_connected)
0605             num_tiled_conns++;
0606     }
0607 retry:
0608     conn_seq = conn_configured;
0609     for (i = 0; i < count; i++) {
0610         struct drm_connector *connector;
0611         struct drm_encoder *encoder;
0612         struct drm_crtc *new_crtc;
0613 
0614         connector = connectors[i];
0615 
0616         if (conn_configured & BIT(i))
0617             continue;
0618 
0619         if (conn_seq == 0 && !connector->has_tile)
0620             continue;
0621 
0622         if (connector->status == connector_status_connected)
0623             num_connectors_detected++;
0624 
0625         if (!enabled[i]) {
0626             DRM_DEBUG_KMS("connector %s not enabled, skipping\n",
0627                       connector->name);
0628             conn_configured |= BIT(i);
0629             continue;
0630         }
0631 
0632         if (connector->force == DRM_FORCE_OFF) {
0633             DRM_DEBUG_KMS("connector %s is disabled by user, skipping\n",
0634                       connector->name);
0635             enabled[i] = false;
0636             continue;
0637         }
0638 
0639         encoder = connector->state->best_encoder;
0640         if (!encoder || WARN_ON(!connector->state->crtc)) {
0641             if (connector->force > DRM_FORCE_OFF)
0642                 goto bail;
0643 
0644             DRM_DEBUG_KMS("connector %s has no encoder or crtc, skipping\n",
0645                       connector->name);
0646             enabled[i] = false;
0647             conn_configured |= BIT(i);
0648             continue;
0649         }
0650 
0651         num_connectors_enabled++;
0652 
0653         new_crtc = connector->state->crtc;
0654 
0655         /*
0656          * Make sure we're not trying to drive multiple connectors
0657          * with a single CRTC, since our cloning support may not
0658          * match the BIOS.
0659          */
0660         for (j = 0; j < count; j++) {
0661             if (crtcs[j] == new_crtc) {
0662                 DRM_DEBUG_KMS("fallback: cloned configuration\n");
0663                 goto bail;
0664             }
0665         }
0666 
0667         DRM_DEBUG_KMS("looking for cmdline mode on connector %s\n",
0668                   connector->name);
0669 
0670         /* go for command line mode first */
0671         modes[i] = drm_connector_pick_cmdline_mode(connector);
0672 
0673         /* try for preferred next */
0674         if (!modes[i]) {
0675             DRM_DEBUG_KMS("looking for preferred mode on connector %s %d\n",
0676                       connector->name, connector->has_tile);
0677             modes[i] = drm_connector_has_preferred_mode(connector, width, height);
0678         }
0679 
0680         /* No preferred mode marked by the EDID? Are there any modes? */
0681         if (!modes[i] && !list_empty(&connector->modes)) {
0682             DRM_DEBUG_KMS("using first mode listed on connector %s\n",
0683                       connector->name);
0684             modes[i] = list_first_entry(&connector->modes,
0685                             struct drm_display_mode,
0686                             head);
0687         }
0688 
0689         /* last resort: use current mode */
0690         if (!modes[i]) {
0691             /*
0692              * IMPORTANT: We want to use the adjusted mode (i.e.
0693              * after the panel fitter upscaling) as the initial
0694              * config, not the input mode, which is what crtc->mode
0695              * usually contains. But since our current
0696              * code puts a mode derived from the post-pfit timings
0697              * into crtc->mode this works out correctly.
0698              *
0699              * This is crtc->mode and not crtc->state->mode for the
0700              * fastboot check to work correctly.
0701              */
0702             DRM_DEBUG_KMS("looking for current mode on connector %s\n",
0703                       connector->name);
0704             modes[i] = &connector->state->crtc->mode;
0705         }
0706         /*
0707          * In case of tiled modes, if all tiles are not present
0708          * then fallback to a non tiled mode.
0709          */
0710         if (connector->has_tile &&
0711             num_tiled_conns < connector->num_h_tile * connector->num_v_tile) {
0712             DRM_DEBUG_KMS("Falling back to non tiled mode on Connector %d\n",
0713                       connector->base.id);
0714             modes[i] = drm_connector_fallback_non_tiled_mode(connector);
0715         }
0716         crtcs[i] = new_crtc;
0717 
0718         DRM_DEBUG_KMS("connector %s on [CRTC:%d:%s]: %dx%d%s\n",
0719                   connector->name,
0720                   connector->state->crtc->base.id,
0721                   connector->state->crtc->name,
0722                   modes[i]->hdisplay, modes[i]->vdisplay,
0723                   modes[i]->flags & DRM_MODE_FLAG_INTERLACE ? "i" : "");
0724 
0725         fallback = false;
0726         conn_configured |= BIT(i);
0727     }
0728 
0729     if ((conn_configured & mask) != mask && conn_configured != conn_seq)
0730         goto retry;
0731 
0732     /*
0733      * If the BIOS didn't enable everything it could, fall back to have the
0734      * same user experiencing of lighting up as much as possible like the
0735      * fbdev helper library.
0736      */
0737     if (num_connectors_enabled != num_connectors_detected &&
0738         num_connectors_enabled < dev->mode_config.num_crtc) {
0739         DRM_DEBUG_KMS("fallback: Not all outputs enabled\n");
0740         DRM_DEBUG_KMS("Enabled: %i, detected: %i\n", num_connectors_enabled,
0741                   num_connectors_detected);
0742         fallback = true;
0743     }
0744 
0745     if (fallback) {
0746 bail:
0747         DRM_DEBUG_KMS("Not using firmware configuration\n");
0748         memcpy(enabled, save_enabled, count);
0749         ret = false;
0750     }
0751 
0752     drm_modeset_drop_locks(&ctx);
0753     drm_modeset_acquire_fini(&ctx);
0754 
0755     kfree(save_enabled);
0756     return ret;
0757 }
0758 
0759 /**
0760  * drm_client_modeset_probe() - Probe for displays
0761  * @client: DRM client
0762  * @width: Maximum display mode width (optional)
0763  * @height: Maximum display mode height (optional)
0764  *
0765  * This function sets up display pipelines for enabled connectors and stores the
0766  * config in the client's modeset array.
0767  *
0768  * Returns:
0769  * Zero on success or negative error code on failure.
0770  */
0771 int drm_client_modeset_probe(struct drm_client_dev *client, unsigned int width, unsigned int height)
0772 {
0773     struct drm_connector *connector, **connectors = NULL;
0774     struct drm_connector_list_iter conn_iter;
0775     struct drm_device *dev = client->dev;
0776     unsigned int total_modes_count = 0;
0777     struct drm_client_offset *offsets;
0778     unsigned int connector_count = 0;
0779     struct drm_display_mode **modes;
0780     struct drm_crtc **crtcs;
0781     int i, ret = 0;
0782     bool *enabled;
0783 
0784     DRM_DEBUG_KMS("\n");
0785 
0786     if (!width)
0787         width = dev->mode_config.max_width;
0788     if (!height)
0789         height = dev->mode_config.max_height;
0790 
0791     drm_connector_list_iter_begin(dev, &conn_iter);
0792     drm_client_for_each_connector_iter(connector, &conn_iter) {
0793         struct drm_connector **tmp;
0794 
0795         tmp = krealloc(connectors, (connector_count + 1) * sizeof(*connectors), GFP_KERNEL);
0796         if (!tmp) {
0797             ret = -ENOMEM;
0798             goto free_connectors;
0799         }
0800 
0801         connectors = tmp;
0802         drm_connector_get(connector);
0803         connectors[connector_count++] = connector;
0804     }
0805     drm_connector_list_iter_end(&conn_iter);
0806 
0807     if (!connector_count)
0808         return 0;
0809 
0810     crtcs = kcalloc(connector_count, sizeof(*crtcs), GFP_KERNEL);
0811     modes = kcalloc(connector_count, sizeof(*modes), GFP_KERNEL);
0812     offsets = kcalloc(connector_count, sizeof(*offsets), GFP_KERNEL);
0813     enabled = kcalloc(connector_count, sizeof(bool), GFP_KERNEL);
0814     if (!crtcs || !modes || !enabled || !offsets) {
0815         DRM_ERROR("Memory allocation failed\n");
0816         ret = -ENOMEM;
0817         goto out;
0818     }
0819 
0820     mutex_lock(&client->modeset_mutex);
0821 
0822     mutex_lock(&dev->mode_config.mutex);
0823     for (i = 0; i < connector_count; i++)
0824         total_modes_count += connectors[i]->funcs->fill_modes(connectors[i], width, height);
0825     if (!total_modes_count)
0826         DRM_DEBUG_KMS("No connectors reported connected with modes\n");
0827     drm_client_connectors_enabled(connectors, connector_count, enabled);
0828 
0829     if (!drm_client_firmware_config(client, connectors, connector_count, crtcs,
0830                     modes, offsets, enabled, width, height)) {
0831         memset(modes, 0, connector_count * sizeof(*modes));
0832         memset(crtcs, 0, connector_count * sizeof(*crtcs));
0833         memset(offsets, 0, connector_count * sizeof(*offsets));
0834 
0835         if (!drm_client_target_cloned(dev, connectors, connector_count, modes,
0836                           offsets, enabled, width, height) &&
0837             !drm_client_target_preferred(connectors, connector_count, modes,
0838                          offsets, enabled, width, height))
0839             DRM_ERROR("Unable to find initial modes\n");
0840 
0841         DRM_DEBUG_KMS("picking CRTCs for %dx%d config\n",
0842                   width, height);
0843 
0844         drm_client_pick_crtcs(client, connectors, connector_count,
0845                       crtcs, modes, 0, width, height);
0846     }
0847     mutex_unlock(&dev->mode_config.mutex);
0848 
0849     drm_client_modeset_release(client);
0850 
0851     for (i = 0; i < connector_count; i++) {
0852         struct drm_display_mode *mode = modes[i];
0853         struct drm_crtc *crtc = crtcs[i];
0854         struct drm_client_offset *offset = &offsets[i];
0855 
0856         if (mode && crtc) {
0857             struct drm_mode_set *modeset = drm_client_find_modeset(client, crtc);
0858             struct drm_connector *connector = connectors[i];
0859 
0860             DRM_DEBUG_KMS("desired mode %s set on crtc %d (%d,%d)\n",
0861                       mode->name, crtc->base.id, offset->x, offset->y);
0862 
0863             if (WARN_ON_ONCE(modeset->num_connectors == DRM_CLIENT_MAX_CLONED_CONNECTORS ||
0864                      (dev->mode_config.num_crtc > 1 && modeset->num_connectors == 1))) {
0865                 ret = -EINVAL;
0866                 break;
0867             }
0868 
0869             modeset->mode = drm_mode_duplicate(dev, mode);
0870             drm_connector_get(connector);
0871             modeset->connectors[modeset->num_connectors++] = connector;
0872             modeset->x = offset->x;
0873             modeset->y = offset->y;
0874         }
0875     }
0876 
0877     mutex_unlock(&client->modeset_mutex);
0878 out:
0879     kfree(crtcs);
0880     kfree(modes);
0881     kfree(offsets);
0882     kfree(enabled);
0883 free_connectors:
0884     for (i = 0; i < connector_count; i++)
0885         drm_connector_put(connectors[i]);
0886     kfree(connectors);
0887 
0888     return ret;
0889 }
0890 EXPORT_SYMBOL(drm_client_modeset_probe);
0891 
0892 /**
0893  * drm_client_rotation() - Check the initial rotation value
0894  * @modeset: DRM modeset
0895  * @rotation: Returned rotation value
0896  *
0897  * This function checks if the primary plane in @modeset can hw rotate
0898  * to match the rotation needed on its connector.
0899  *
0900  * Note: Currently only 0 and 180 degrees are supported.
0901  *
0902  * Return:
0903  * True if the plane can do the rotation, false otherwise.
0904  */
0905 bool drm_client_rotation(struct drm_mode_set *modeset, unsigned int *rotation)
0906 {
0907     struct drm_connector *connector = modeset->connectors[0];
0908     struct drm_plane *plane = modeset->crtc->primary;
0909     struct drm_cmdline_mode *cmdline;
0910     u64 valid_mask = 0;
0911     unsigned int i;
0912 
0913     if (!modeset->num_connectors)
0914         return false;
0915 
0916     switch (connector->display_info.panel_orientation) {
0917     case DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP:
0918         *rotation = DRM_MODE_ROTATE_180;
0919         break;
0920     case DRM_MODE_PANEL_ORIENTATION_LEFT_UP:
0921         *rotation = DRM_MODE_ROTATE_90;
0922         break;
0923     case DRM_MODE_PANEL_ORIENTATION_RIGHT_UP:
0924         *rotation = DRM_MODE_ROTATE_270;
0925         break;
0926     default:
0927         *rotation = DRM_MODE_ROTATE_0;
0928     }
0929 
0930     /**
0931      * The panel already defined the default rotation
0932      * through its orientation. Whatever has been provided
0933      * on the command line needs to be added to that.
0934      *
0935      * Unfortunately, the rotations are at different bit
0936      * indices, so the math to add them up are not as
0937      * trivial as they could.
0938      *
0939      * Reflections on the other hand are pretty trivial to deal with, a
0940      * simple XOR between the two handle the addition nicely.
0941      */
0942     cmdline = &connector->cmdline_mode;
0943     if (cmdline->specified && cmdline->rotation_reflection) {
0944         unsigned int cmdline_rest, panel_rest;
0945         unsigned int cmdline_rot, panel_rot;
0946         unsigned int sum_rot, sum_rest;
0947 
0948         panel_rot = ilog2(*rotation & DRM_MODE_ROTATE_MASK);
0949         cmdline_rot = ilog2(cmdline->rotation_reflection & DRM_MODE_ROTATE_MASK);
0950         sum_rot = (panel_rot + cmdline_rot) % 4;
0951 
0952         panel_rest = *rotation & ~DRM_MODE_ROTATE_MASK;
0953         cmdline_rest = cmdline->rotation_reflection & ~DRM_MODE_ROTATE_MASK;
0954         sum_rest = panel_rest ^ cmdline_rest;
0955 
0956         *rotation = (1 << sum_rot) | sum_rest;
0957     }
0958 
0959     /*
0960      * TODO: support 90 / 270 degree hardware rotation,
0961      * depending on the hardware this may require the framebuffer
0962      * to be in a specific tiling format.
0963      */
0964     if (((*rotation & DRM_MODE_ROTATE_MASK) != DRM_MODE_ROTATE_0 &&
0965          (*rotation & DRM_MODE_ROTATE_MASK) != DRM_MODE_ROTATE_180) ||
0966         !plane->rotation_property)
0967         return false;
0968 
0969     for (i = 0; i < plane->rotation_property->num_values; i++)
0970         valid_mask |= (1ULL << plane->rotation_property->values[i]);
0971 
0972     if (!(*rotation & valid_mask))
0973         return false;
0974 
0975     return true;
0976 }
0977 EXPORT_SYMBOL(drm_client_rotation);
0978 
0979 static int drm_client_modeset_commit_atomic(struct drm_client_dev *client, bool active, bool check)
0980 {
0981     struct drm_device *dev = client->dev;
0982     struct drm_plane *plane;
0983     struct drm_atomic_state *state;
0984     struct drm_modeset_acquire_ctx ctx;
0985     struct drm_mode_set *mode_set;
0986     int ret;
0987 
0988     drm_modeset_acquire_init(&ctx, 0);
0989 
0990     state = drm_atomic_state_alloc(dev);
0991     if (!state) {
0992         ret = -ENOMEM;
0993         goto out_ctx;
0994     }
0995 
0996     state->acquire_ctx = &ctx;
0997 retry:
0998     drm_for_each_plane(plane, dev) {
0999         struct drm_plane_state *plane_state;
1000 
1001         plane_state = drm_atomic_get_plane_state(state, plane);
1002         if (IS_ERR(plane_state)) {
1003             ret = PTR_ERR(plane_state);
1004             goto out_state;
1005         }
1006 
1007         plane_state->rotation = DRM_MODE_ROTATE_0;
1008 
1009         /* disable non-primary: */
1010         if (plane->type == DRM_PLANE_TYPE_PRIMARY)
1011             continue;
1012 
1013         ret = __drm_atomic_helper_disable_plane(plane, plane_state);
1014         if (ret != 0)
1015             goto out_state;
1016     }
1017 
1018     drm_client_for_each_modeset(mode_set, client) {
1019         struct drm_plane *primary = mode_set->crtc->primary;
1020         unsigned int rotation;
1021 
1022         if (drm_client_rotation(mode_set, &rotation)) {
1023             struct drm_plane_state *plane_state;
1024 
1025             /* Cannot fail as we've already gotten the plane state above */
1026             plane_state = drm_atomic_get_new_plane_state(state, primary);
1027             plane_state->rotation = rotation;
1028         }
1029 
1030         ret = __drm_atomic_helper_set_config(mode_set, state);
1031         if (ret != 0)
1032             goto out_state;
1033 
1034         /*
1035          * __drm_atomic_helper_set_config() sets active when a
1036          * mode is set, unconditionally clear it if we force DPMS off
1037          */
1038         if (!active) {
1039             struct drm_crtc *crtc = mode_set->crtc;
1040             struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
1041 
1042             crtc_state->active = false;
1043         }
1044     }
1045 
1046     if (check)
1047         ret = drm_atomic_check_only(state);
1048     else
1049         ret = drm_atomic_commit(state);
1050 
1051 out_state:
1052     if (ret == -EDEADLK)
1053         goto backoff;
1054 
1055     drm_atomic_state_put(state);
1056 out_ctx:
1057     drm_modeset_drop_locks(&ctx);
1058     drm_modeset_acquire_fini(&ctx);
1059 
1060     return ret;
1061 
1062 backoff:
1063     drm_atomic_state_clear(state);
1064     drm_modeset_backoff(&ctx);
1065 
1066     goto retry;
1067 }
1068 
1069 static int drm_client_modeset_commit_legacy(struct drm_client_dev *client)
1070 {
1071     struct drm_device *dev = client->dev;
1072     struct drm_mode_set *mode_set;
1073     struct drm_plane *plane;
1074     int ret = 0;
1075 
1076     drm_modeset_lock_all(dev);
1077     drm_for_each_plane(plane, dev) {
1078         if (plane->type != DRM_PLANE_TYPE_PRIMARY)
1079             drm_plane_force_disable(plane);
1080 
1081         if (plane->rotation_property)
1082             drm_mode_plane_set_obj_prop(plane,
1083                             plane->rotation_property,
1084                             DRM_MODE_ROTATE_0);
1085     }
1086 
1087     drm_client_for_each_modeset(mode_set, client) {
1088         struct drm_crtc *crtc = mode_set->crtc;
1089 
1090         if (crtc->funcs->cursor_set2) {
1091             ret = crtc->funcs->cursor_set2(crtc, NULL, 0, 0, 0, 0, 0);
1092             if (ret)
1093                 goto out;
1094         } else if (crtc->funcs->cursor_set) {
1095             ret = crtc->funcs->cursor_set(crtc, NULL, 0, 0, 0);
1096             if (ret)
1097                 goto out;
1098         }
1099 
1100         ret = drm_mode_set_config_internal(mode_set);
1101         if (ret)
1102             goto out;
1103     }
1104 out:
1105     drm_modeset_unlock_all(dev);
1106 
1107     return ret;
1108 }
1109 
1110 /**
1111  * drm_client_modeset_check() - Check modeset configuration
1112  * @client: DRM client
1113  *
1114  * Check modeset configuration.
1115  *
1116  * Returns:
1117  * Zero on success or negative error code on failure.
1118  */
1119 int drm_client_modeset_check(struct drm_client_dev *client)
1120 {
1121     int ret;
1122 
1123     if (!drm_drv_uses_atomic_modeset(client->dev))
1124         return 0;
1125 
1126     mutex_lock(&client->modeset_mutex);
1127     ret = drm_client_modeset_commit_atomic(client, true, true);
1128     mutex_unlock(&client->modeset_mutex);
1129 
1130     return ret;
1131 }
1132 EXPORT_SYMBOL(drm_client_modeset_check);
1133 
1134 /**
1135  * drm_client_modeset_commit_locked() - Force commit CRTC configuration
1136  * @client: DRM client
1137  *
1138  * Commit modeset configuration to crtcs without checking if there is a DRM
1139  * master. The assumption is that the caller already holds an internal DRM
1140  * master reference acquired with drm_master_internal_acquire().
1141  *
1142  * Returns:
1143  * Zero on success or negative error code on failure.
1144  */
1145 int drm_client_modeset_commit_locked(struct drm_client_dev *client)
1146 {
1147     struct drm_device *dev = client->dev;
1148     int ret;
1149 
1150     mutex_lock(&client->modeset_mutex);
1151     if (drm_drv_uses_atomic_modeset(dev))
1152         ret = drm_client_modeset_commit_atomic(client, true, false);
1153     else
1154         ret = drm_client_modeset_commit_legacy(client);
1155     mutex_unlock(&client->modeset_mutex);
1156 
1157     return ret;
1158 }
1159 EXPORT_SYMBOL(drm_client_modeset_commit_locked);
1160 
1161 /**
1162  * drm_client_modeset_commit() - Commit CRTC configuration
1163  * @client: DRM client
1164  *
1165  * Commit modeset configuration to crtcs.
1166  *
1167  * Returns:
1168  * Zero on success or negative error code on failure.
1169  */
1170 int drm_client_modeset_commit(struct drm_client_dev *client)
1171 {
1172     struct drm_device *dev = client->dev;
1173     int ret;
1174 
1175     if (!drm_master_internal_acquire(dev))
1176         return -EBUSY;
1177 
1178     ret = drm_client_modeset_commit_locked(client);
1179 
1180     drm_master_internal_release(dev);
1181 
1182     return ret;
1183 }
1184 EXPORT_SYMBOL(drm_client_modeset_commit);
1185 
1186 static void drm_client_modeset_dpms_legacy(struct drm_client_dev *client, int dpms_mode)
1187 {
1188     struct drm_device *dev = client->dev;
1189     struct drm_connector *connector;
1190     struct drm_mode_set *modeset;
1191     struct drm_modeset_acquire_ctx ctx;
1192     int j;
1193     int ret;
1194 
1195     DRM_MODESET_LOCK_ALL_BEGIN(dev, ctx, 0, ret);
1196     drm_client_for_each_modeset(modeset, client) {
1197         if (!modeset->crtc->enabled)
1198             continue;
1199 
1200         for (j = 0; j < modeset->num_connectors; j++) {
1201             connector = modeset->connectors[j];
1202             connector->funcs->dpms(connector, dpms_mode);
1203             drm_object_property_set_value(&connector->base,
1204                 dev->mode_config.dpms_property, dpms_mode);
1205         }
1206     }
1207     DRM_MODESET_LOCK_ALL_END(dev, ctx, ret);
1208 }
1209 
1210 /**
1211  * drm_client_modeset_dpms() - Set DPMS mode
1212  * @client: DRM client
1213  * @mode: DPMS mode
1214  *
1215  * Note: For atomic drivers @mode is reduced to on/off.
1216  *
1217  * Returns:
1218  * Zero on success or negative error code on failure.
1219  */
1220 int drm_client_modeset_dpms(struct drm_client_dev *client, int mode)
1221 {
1222     struct drm_device *dev = client->dev;
1223     int ret = 0;
1224 
1225     if (!drm_master_internal_acquire(dev))
1226         return -EBUSY;
1227 
1228     mutex_lock(&client->modeset_mutex);
1229     if (drm_drv_uses_atomic_modeset(dev))
1230         ret = drm_client_modeset_commit_atomic(client, mode == DRM_MODE_DPMS_ON, false);
1231     else
1232         drm_client_modeset_dpms_legacy(client, mode);
1233     mutex_unlock(&client->modeset_mutex);
1234 
1235     drm_master_internal_release(dev);
1236 
1237     return ret;
1238 }
1239 EXPORT_SYMBOL(drm_client_modeset_dpms);