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

drm/omap: Get rid of DRM_OMAP_NUM_CRTCS config option

Allocate one CRTC for each connected output and get rid of
DRM_OMAP_NUM_CRTCS config option. We still can not create more CRTCs
than we have DSS display managers. We also reserve one overlay per
CRTC for primary plane so we can not have more CRTCs than we have
overlays either.

Signed-off-by: Jyri Sarha <jsarha@ti.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>

authored by

Jyri Sarha and committed by
Tomi Valkeinen
f1118b89 c9af3ed7

+16 -52
-9
drivers/gpu/drm/omapdrm/Kconfig
··· 10 10 11 11 if DRM_OMAP 12 12 13 - config DRM_OMAP_NUM_CRTCS 14 - int "Number of CRTCs" 15 - range 1 10 16 - default 1 if ARCH_OMAP2 || ARCH_OMAP3 17 - default 2 if ARCH_OMAP4 18 - help 19 - Select the number of video overlays which can be used as framebuffers. 20 - The remaining overlays are reserved for video. 21 - 22 13 source "drivers/gpu/drm/omapdrm/dss/Kconfig" 23 14 source "drivers/gpu/drm/omapdrm/displays/Kconfig" 24 15
+16 -43
drivers/gpu/drm/omapdrm/omap_drv.c
··· 34 34 #define DRIVER_MINOR 0 35 35 #define DRIVER_PATCHLEVEL 0 36 36 37 - static int num_crtc = CONFIG_DRM_OMAP_NUM_CRTCS; 38 - 39 - MODULE_PARM_DESC(num_crtc, "Number of overlays to use as CRTCs"); 40 - module_param(num_crtc, int, 0600); 41 - 42 37 /* 43 38 * mode config funcs 44 39 */ ··· 314 319 struct omap_dss_device *dssdev = NULL; 315 320 int num_ovls = priv->dispc_ops->get_num_ovls(); 316 321 int num_mgrs = priv->dispc_ops->get_num_mgrs(); 317 - int num_crtcs; 322 + int num_crtcs = 0; 318 323 int i, id = 0; 319 324 int ret; 320 325 u32 possible_crtcs; ··· 326 331 return ret; 327 332 328 333 /* 329 - * We usually don't want to create a CRTC for each manager, at least 330 - * not until we have a way to expose private planes to userspace. 331 - * Otherwise there would not be enough video pipes left for drm planes. 332 - * We use the num_crtc argument to limit the number of crtcs we create. 334 + * Let's create one CRTC for each connected DSS device if we 335 + * have display managers and overlays (for primary planes) for 336 + * them. 333 337 */ 334 - num_crtcs = min3(num_crtc, num_mgrs, num_ovls); 338 + for_each_dss_dev(dssdev) 339 + if (omapdss_device_is_connected(dssdev)) 340 + num_crtcs++; 341 + 342 + num_crtcs = min3(num_crtcs, num_mgrs, num_ovls); 335 343 possible_crtcs = (1 << num_crtcs) - 1; 336 344 337 345 dssdev = NULL; ··· 374 376 drm_mode_connector_attach_encoder(connector, encoder); 375 377 376 378 /* 377 - * if we have reached the limit of the crtcs we are allowed to 378 - * create, let's not try to look for a crtc for this 379 - * panel/encoder and onwards, we will, of course, populate the 380 - * the possible_crtcs field for all the encoders with the final 381 - * set of crtcs we create 379 + * if we have reached the limit of the crtcs we can 380 + * create, let's not try to create a crtc for this 381 + * panel/encoder and onwards. 382 382 */ 383 383 if (id == num_crtcs) 384 384 continue; ··· 411 415 } 412 416 413 417 /* 414 - * we have allocated crtcs according to the need of the panels/encoders, 415 - * adding more crtcs here if needed 416 - */ 417 - for (; id < num_crtcs; id++) { 418 - 419 - /* find a free manager for this crtc */ 420 - for (i = 0; i < num_mgrs; i++) { 421 - if (!channel_used(dev, i)) 422 - break; 423 - } 424 - 425 - if (i == num_mgrs) { 426 - /* this shouldn't really happen */ 427 - dev_err(dev->dev, "no managers left for crtc\n"); 428 - return -ENOMEM; 429 - } 430 - 431 - ret = omap_modeset_create_crtc(dev, id, i, 432 - possible_crtcs); 433 - if (ret < 0) { 434 - dev_err(dev->dev, 435 - "could not create CRTC (channel %u)\n", i); 436 - return ret; 437 - } 438 - } 439 - 440 - /* 441 418 * Create normal planes for the remaining overlays: 442 419 */ 443 420 for (; id < num_ovls; id++) { ··· 425 456 priv->planes[priv->num_planes++] = plane; 426 457 } 427 458 459 + /* 460 + * populate the the possible_crtcs field for all the encoders 461 + * we created. 462 + */ 428 463 for (i = 0; i < priv->num_encoders; i++) { 429 464 struct drm_encoder *encoder = priv->encoders[i]; 430 465 struct omap_dss_device *dssdev =