Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/connector: Allow max possible encoders to attach to a connector

Currently we restrict the number of encoders that can be linked to
a connector to 3, increase it to match the maximum number of encoders
that can be initialized(32).

To more effiently do that lets switch from an array of encoder ids to
bitmask.

v2: Fixing missed return on amdgpu_dm_connector_to_encoder()

Suggested-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Alex Deucher <alexander.deucher@amd.com>
Cc: dri-devel@lists.freedesktop.org
Cc: intel-gfx@lists.freedesktop.org
Cc: nouveau@lists.freedesktop.org
Cc: amd-gfx@lists.freedesktop.org
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com>
Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20190913232857.389834-2-jose.souza@intel.com

authored by

José Roberto de Souza and committed by
Manasi Navare
62afb4ad a92462d6

+55 -83
+8 -15
drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
··· 217 217 struct drm_encoder *encoder; 218 218 const struct drm_connector_helper_funcs *connector_funcs = connector->helper_private; 219 219 bool connected; 220 - int i; 221 220 222 221 best_encoder = connector_funcs->best_encoder(connector); 223 222 224 - drm_connector_for_each_possible_encoder(connector, encoder, i) { 223 + drm_connector_for_each_possible_encoder(connector, encoder) { 225 224 if ((encoder == best_encoder) && (status == connector_status_connected)) 226 225 connected = true; 227 226 else ··· 235 236 int encoder_type) 236 237 { 237 238 struct drm_encoder *encoder; 238 - int i; 239 239 240 - drm_connector_for_each_possible_encoder(connector, encoder, i) { 240 + drm_connector_for_each_possible_encoder(connector, encoder) { 241 241 if (encoder->encoder_type == encoder_type) 242 242 return encoder; 243 243 } ··· 345 347 amdgpu_connector_best_single_encoder(struct drm_connector *connector) 346 348 { 347 349 struct drm_encoder *encoder; 348 - int i; 349 350 350 351 /* pick the first one */ 351 - drm_connector_for_each_possible_encoder(connector, encoder, i) 352 + drm_connector_for_each_possible_encoder(connector, encoder) 352 353 return encoder; 353 354 354 355 return NULL; ··· 1062 1065 /* find analog encoder */ 1063 1066 if (amdgpu_connector->dac_load_detect) { 1064 1067 struct drm_encoder *encoder; 1065 - int i; 1066 1068 1067 - drm_connector_for_each_possible_encoder(connector, encoder, i) { 1069 + drm_connector_for_each_possible_encoder(connector, encoder) { 1068 1070 if (encoder->encoder_type != DRM_MODE_ENCODER_DAC && 1069 1071 encoder->encoder_type != DRM_MODE_ENCODER_TVDAC) 1070 1072 continue; ··· 1113 1117 { 1114 1118 struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector); 1115 1119 struct drm_encoder *encoder; 1116 - int i; 1117 1120 1118 - drm_connector_for_each_possible_encoder(connector, encoder, i) { 1121 + drm_connector_for_each_possible_encoder(connector, encoder) { 1119 1122 if (amdgpu_connector->use_digital == true) { 1120 1123 if (encoder->encoder_type == DRM_MODE_ENCODER_TMDS) 1121 1124 return encoder; ··· 1129 1134 1130 1135 /* then check use digitial */ 1131 1136 /* pick the first one */ 1132 - drm_connector_for_each_possible_encoder(connector, encoder, i) 1137 + drm_connector_for_each_possible_encoder(connector, encoder) 1133 1138 return encoder; 1134 1139 1135 1140 return NULL; ··· 1266 1271 { 1267 1272 struct drm_encoder *encoder; 1268 1273 struct amdgpu_encoder *amdgpu_encoder; 1269 - int i; 1270 1274 1271 - drm_connector_for_each_possible_encoder(connector, encoder, i) { 1275 + drm_connector_for_each_possible_encoder(connector, encoder) { 1272 1276 amdgpu_encoder = to_amdgpu_encoder(encoder); 1273 1277 1274 1278 switch (amdgpu_encoder->encoder_id) { ··· 1286 1292 { 1287 1293 struct drm_encoder *encoder; 1288 1294 struct amdgpu_encoder *amdgpu_encoder; 1289 - int i; 1290 1295 bool found = false; 1291 1296 1292 - drm_connector_for_each_possible_encoder(connector, encoder, i) { 1297 + drm_connector_for_each_possible_encoder(connector, encoder) { 1293 1298 amdgpu_encoder = to_amdgpu_encoder(encoder); 1294 1299 if (amdgpu_encoder->caps & ATOM_ENCODER_CAP_RECORD_HBR2) 1295 1300 found = true;
+2 -3
drivers/gpu/drm/amd/amdgpu/dce_virtual.c
··· 260 260 dce_virtual_encoder(struct drm_connector *connector) 261 261 { 262 262 struct drm_encoder *encoder; 263 - int i; 264 263 265 - drm_connector_for_each_possible_encoder(connector, encoder, i) { 264 + drm_connector_for_each_possible_encoder(connector, encoder) { 266 265 if (encoder->encoder_type == DRM_MODE_ENCODER_VIRTUAL) 267 266 return encoder; 268 267 } 269 268 270 269 /* pick the first one */ 271 - drm_connector_for_each_possible_encoder(connector, encoder, i) 270 + drm_connector_for_each_possible_encoder(connector, encoder) 272 271 return encoder; 273 272 274 273 return NULL;
+7 -1
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
··· 4792 4792 4793 4793 static struct drm_encoder *amdgpu_dm_connector_to_encoder(struct drm_connector *connector) 4794 4794 { 4795 - return drm_encoder_find(connector->dev, NULL, connector->encoder_ids[0]); 4795 + struct drm_encoder *encoder; 4796 + 4797 + /* There is only one encoder per connector */ 4798 + drm_connector_for_each_possible_encoder(connector, encoder) 4799 + return encoder; 4800 + 4801 + return NULL; 4796 4802 } 4797 4803 4798 4804 static void amdgpu_dm_get_native_mode(struct drm_connector *connector)
+1 -2
drivers/gpu/drm/drm_client_modeset.c
··· 415 415 struct drm_crtc *crtc) 416 416 { 417 417 struct drm_encoder *encoder; 418 - int i; 419 418 420 - drm_connector_for_each_possible_encoder(connector, encoder, i) { 419 + drm_connector_for_each_possible_encoder(connector, encoder) { 421 420 if (encoder->possible_crtcs & drm_crtc_mask(crtc)) 422 421 return true; 423 422 }
+8 -23
drivers/gpu/drm/drm_connector.c
··· 365 365 int drm_connector_attach_encoder(struct drm_connector *connector, 366 366 struct drm_encoder *encoder) 367 367 { 368 - int i; 369 - 370 368 /* 371 369 * In the past, drivers have attempted to model the static association 372 370 * of connector to encoder in simple connector/encoder devices using a ··· 379 381 if (WARN_ON(connector->encoder)) 380 382 return -EINVAL; 381 383 382 - for (i = 0; i < ARRAY_SIZE(connector->encoder_ids); i++) { 383 - if (connector->encoder_ids[i] == 0) { 384 - connector->encoder_ids[i] = encoder->base.id; 385 - return 0; 386 - } 387 - } 388 - return -ENOMEM; 384 + connector->possible_encoders |= drm_encoder_mask(encoder); 385 + 386 + return 0; 389 387 } 390 388 EXPORT_SYMBOL(drm_connector_attach_encoder); 391 389 392 390 /** 393 - * drm_connector_has_possible_encoder - check if the connector and encoder are assosicated with each other 391 + * drm_connector_has_possible_encoder - check if the connector and encoder are 392 + * associated with each other 394 393 * @connector: the connector 395 394 * @encoder: the encoder 396 395 * ··· 397 402 bool drm_connector_has_possible_encoder(struct drm_connector *connector, 398 403 struct drm_encoder *encoder) 399 404 { 400 - struct drm_encoder *enc; 401 - int i; 402 - 403 - drm_connector_for_each_possible_encoder(connector, enc, i) { 404 - if (enc == encoder) 405 - return true; 406 - } 407 - 408 - return false; 405 + return connector->possible_encoders & drm_encoder_mask(encoder); 409 406 } 410 407 EXPORT_SYMBOL(drm_connector_has_possible_encoder); 411 408 ··· 2108 2121 int encoders_count = 0; 2109 2122 int ret = 0; 2110 2123 int copied = 0; 2111 - int i; 2112 2124 struct drm_mode_modeinfo u_mode; 2113 2125 struct drm_mode_modeinfo __user *mode_ptr; 2114 2126 uint32_t __user *encoder_ptr; ··· 2122 2136 if (!connector) 2123 2137 return -ENOENT; 2124 2138 2125 - drm_connector_for_each_possible_encoder(connector, encoder, i) 2126 - encoders_count++; 2139 + encoders_count = hweight32(connector->possible_encoders); 2127 2140 2128 2141 if ((out_resp->count_encoders >= encoders_count) && encoders_count) { 2129 2142 copied = 0; 2130 2143 encoder_ptr = (uint32_t __user *)(unsigned long)(out_resp->encoders_ptr); 2131 2144 2132 - drm_connector_for_each_possible_encoder(connector, encoder, i) { 2145 + drm_connector_for_each_possible_encoder(connector, encoder) { 2133 2146 if (put_user(encoder->base.id, encoder_ptr + copied)) { 2134 2147 ret = -EFAULT; 2135 2148 goto out;
+7 -2
drivers/gpu/drm/drm_crtc_helper.c
··· 488 488 struct drm_encoder * 489 489 drm_connector_get_single_encoder(struct drm_connector *connector) 490 490 { 491 - WARN_ON(connector->encoder_ids[1]); 492 - return drm_encoder_find(connector->dev, NULL, connector->encoder_ids[0]); 491 + struct drm_encoder *encoder; 492 + 493 + WARN_ON(hweight32(connector->possible_encoders) > 1); 494 + drm_connector_for_each_possible_encoder(connector, encoder) 495 + return encoder; 496 + 497 + return NULL; 493 498 } 494 499 495 500 /**
+1 -2
drivers/gpu/drm/drm_probe_helper.c
··· 93 93 struct drm_device *dev = connector->dev; 94 94 enum drm_mode_status ret = MODE_OK; 95 95 struct drm_encoder *encoder; 96 - int i; 97 96 98 97 /* Step 1: Validate against connector */ 99 98 ret = drm_connector_mode_valid(connector, mode); ··· 100 101 return ret; 101 102 102 103 /* Step 2: Validate against encoders and crtcs */ 103 - drm_connector_for_each_possible_encoder(connector, encoder, i) { 104 + drm_connector_for_each_possible_encoder(connector, encoder) { 104 105 struct drm_crtc *crtc; 105 106 106 107 ret = drm_encoder_mode_valid(encoder, mode);
+1 -1
drivers/gpu/drm/nouveau/dispnv04/disp.c
··· 257 257 258 258 list_for_each_entry_safe(connector, ct, 259 259 &dev->mode_config.connector_list, head) { 260 - if (!connector->encoder_ids[0]) { 260 + if (!connector->possible_encoders) { 261 261 NV_WARN(drm, "%s has no encoders, removing\n", 262 262 connector->name); 263 263 connector->funcs->destroy(connector);
+1 -1
drivers/gpu/drm/nouveau/dispnv50/disp.c
··· 2390 2390 2391 2391 /* cull any connectors we created that don't have an encoder */ 2392 2392 list_for_each_entry_safe(connector, tmp, &dev->mode_config.connector_list, head) { 2393 - if (connector->encoder_ids[0]) 2393 + if (connector->possible_encoders) 2394 2394 continue; 2395 2395 2396 2396 NV_WARN(drm, "%s has no encoders, removing\n",
+3 -4
drivers/gpu/drm/nouveau/nouveau_connector.c
··· 366 366 { 367 367 struct nouveau_encoder *nv_encoder; 368 368 struct drm_encoder *enc; 369 - int i; 370 369 371 - drm_connector_for_each_possible_encoder(connector, enc, i) { 370 + drm_connector_for_each_possible_encoder(connector, enc) { 372 371 nv_encoder = nouveau_encoder(enc); 373 372 374 373 if (type == DCB_OUTPUT_ANY || ··· 414 415 struct drm_device *dev = connector->dev; 415 416 struct nouveau_encoder *nv_encoder = NULL, *found = NULL; 416 417 struct drm_encoder *encoder; 417 - int i, ret; 418 + int ret; 418 419 bool switcheroo_ddc = false; 419 420 420 - drm_connector_for_each_possible_encoder(connector, encoder, i) { 421 + drm_connector_for_each_possible_encoder(connector, encoder) { 421 422 nv_encoder = nouveau_encoder(encoder); 422 423 423 424 switch (nv_encoder->dcb->type) {
+9 -18
drivers/gpu/drm/radeon/radeon_connectors.c
··· 249 249 struct drm_encoder *encoder; 250 250 const struct drm_connector_helper_funcs *connector_funcs = connector->helper_private; 251 251 bool connected; 252 - int i; 253 252 254 253 best_encoder = connector_funcs->best_encoder(connector); 255 254 256 - drm_connector_for_each_possible_encoder(connector, encoder, i) { 255 + drm_connector_for_each_possible_encoder(connector, encoder) { 257 256 if ((encoder == best_encoder) && (status == connector_status_connected)) 258 257 connected = true; 259 258 else ··· 268 269 static struct drm_encoder *radeon_find_encoder(struct drm_connector *connector, int encoder_type) 269 270 { 270 271 struct drm_encoder *encoder; 271 - int i; 272 272 273 - drm_connector_for_each_possible_encoder(connector, encoder, i) { 273 + drm_connector_for_each_possible_encoder(connector, encoder) { 274 274 if (encoder->encoder_type == encoder_type) 275 275 return encoder; 276 276 } ··· 378 380 static struct drm_encoder *radeon_best_single_encoder(struct drm_connector *connector) 379 381 { 380 382 struct drm_encoder *encoder; 381 - int i; 382 383 383 384 /* pick the first one */ 384 - drm_connector_for_each_possible_encoder(connector, encoder, i) 385 + drm_connector_for_each_possible_encoder(connector, encoder) 385 386 return encoder; 386 387 387 388 return NULL; ··· 425 428 426 429 list_for_each_entry(conflict, &dev->mode_config.connector_list, head) { 427 430 struct drm_encoder *enc; 428 - int i; 429 431 430 432 if (conflict == connector) 431 433 continue; 432 434 433 435 radeon_conflict = to_radeon_connector(conflict); 434 436 435 - drm_connector_for_each_possible_encoder(conflict, enc, i) { 437 + drm_connector_for_each_possible_encoder(conflict, enc) { 436 438 /* if the IDs match */ 437 439 if (enc == encoder) { 438 440 if (conflict->status != connector_status_connected) ··· 1359 1363 1360 1364 /* find analog encoder */ 1361 1365 if (radeon_connector->dac_load_detect) { 1362 - int i; 1363 - 1364 - drm_connector_for_each_possible_encoder(connector, encoder, i) { 1366 + drm_connector_for_each_possible_encoder(connector, encoder) { 1365 1367 if (encoder->encoder_type != DRM_MODE_ENCODER_DAC && 1366 1368 encoder->encoder_type != DRM_MODE_ENCODER_TVDAC) 1367 1369 continue; ··· 1437 1443 { 1438 1444 struct radeon_connector *radeon_connector = to_radeon_connector(connector); 1439 1445 struct drm_encoder *encoder; 1440 - int i; 1441 1446 1442 - drm_connector_for_each_possible_encoder(connector, encoder, i) { 1447 + drm_connector_for_each_possible_encoder(connector, encoder) { 1443 1448 if (radeon_connector->use_digital == true) { 1444 1449 if (encoder->encoder_type == DRM_MODE_ENCODER_TMDS) 1445 1450 return encoder; ··· 1453 1460 1454 1461 /* then check use digitial */ 1455 1462 /* pick the first one */ 1456 - drm_connector_for_each_possible_encoder(connector, encoder, i) 1463 + drm_connector_for_each_possible_encoder(connector, encoder) 1457 1464 return encoder; 1458 1465 1459 1466 return NULL; ··· 1596 1603 { 1597 1604 struct drm_encoder *encoder; 1598 1605 struct radeon_encoder *radeon_encoder; 1599 - int i; 1600 1606 1601 - drm_connector_for_each_possible_encoder(connector, encoder, i) { 1607 + drm_connector_for_each_possible_encoder(connector, encoder) { 1602 1608 radeon_encoder = to_radeon_encoder(encoder); 1603 1609 1604 1610 switch (radeon_encoder->encoder_id) { ··· 1616 1624 { 1617 1625 struct drm_encoder *encoder; 1618 1626 struct radeon_encoder *radeon_encoder; 1619 - int i; 1620 1627 bool found = false; 1621 1628 1622 - drm_connector_for_each_possible_encoder(connector, encoder, i) { 1629 + drm_connector_for_each_possible_encoder(connector, encoder) { 1623 1630 radeon_encoder = to_radeon_encoder(encoder); 1624 1631 if (radeon_encoder->caps & ATOM_ENCODER_CAP_RECORD_HBR2) 1625 1632 found = true;
+7 -11
include/drm/drm_connector.h
··· 1288 1288 /** @override_edid: has the EDID been overwritten through debugfs for testing? */ 1289 1289 bool override_edid; 1290 1290 1291 - #define DRM_CONNECTOR_MAX_ENCODER 3 1292 1291 /** 1293 - * @encoder_ids: Valid encoders for this connector. Please only use 1294 - * drm_connector_for_each_possible_encoder() to enumerate these. 1292 + * @possible_encoders: Bit mask of encoders that can drive this 1293 + * connector, drm_encoder_index() determines the index into the bitfield 1294 + * and the bits are set with drm_connector_attach_encoder(). 1295 1295 */ 1296 - uint32_t encoder_ids[DRM_CONNECTOR_MAX_ENCODER]; 1296 + u32 possible_encoders; 1297 1297 1298 1298 /** 1299 1299 * @encoder: Currently bound encoder driving this connector, if any. ··· 1608 1608 * drm_connector_for_each_possible_encoder - iterate connector's possible encoders 1609 1609 * @connector: &struct drm_connector pointer 1610 1610 * @encoder: &struct drm_encoder pointer used as cursor 1611 - * @__i: int iteration cursor, for macro-internal use 1612 1611 */ 1613 - #define drm_connector_for_each_possible_encoder(connector, encoder, __i) \ 1614 - for ((__i) = 0; (__i) < ARRAY_SIZE((connector)->encoder_ids) && \ 1615 - (connector)->encoder_ids[(__i)] != 0; (__i)++) \ 1616 - for_each_if((encoder) = \ 1617 - drm_encoder_find((connector)->dev, NULL, \ 1618 - (connector)->encoder_ids[(__i)])) \ 1612 + #define drm_connector_for_each_possible_encoder(connector, encoder) \ 1613 + drm_for_each_encoder_mask(encoder, (connector)->dev, \ 1614 + (connector)->possible_encoders) 1619 1615 1620 1616 #endif