diff options
Diffstat (limited to 'hw/xfree86/drivers/modesetting/drmmode_display.c')
-rw-r--r-- | hw/xfree86/drivers/modesetting/drmmode_display.c | 97 |
1 files changed, 83 insertions, 14 deletions
diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c index 6a13660dd..4d8892fd5 100644 --- a/hw/xfree86/drivers/modesetting/drmmode_display.c +++ b/hw/xfree86/drivers/modesetting/drmmode_display.c @@ -52,6 +52,39 @@ static Bool drmmode_xf86crtc_resize(ScrnInfoPtr scrn, int width, int height); +static Bool +drmmode_zaphod_string_matches(ScrnInfoPtr scrn, const char *s, char *output_name) +{ + int i = 0; + char s1[20]; + + do { + switch(*s) { + case ',': + s1[i] = '\0'; + i = 0; + if (strcmp(s1, output_name) == 0) + return TRUE; + break; + case ' ': + case '\t': + case '\n': + case '\r': + break; + default: + s1[i] = *s; + i++; + break; + } + } while(*s++); + + s1[i] = '\0'; + if (strcmp(s1, output_name) == 0) + return TRUE; + + return FALSE; +} + int drmmode_bo_destroy(drmmode_ptr drmmode, drmmode_bo *bo) { @@ -788,15 +821,16 @@ drmmode_crtc_vblank_pipe(int crtc_id) return 0; } -static void +static unsigned int drmmode_crtc_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_res, int num) { xf86CrtcPtr crtc; drmmode_crtc_private_ptr drmmode_crtc; + modesettingEntPtr ms_ent = ms_ent_priv(pScrn); crtc = xf86CrtcCreate(pScrn, &drmmode_crtc_funcs); if (crtc == NULL) - return; + return 0; drmmode_crtc = xnfcalloc(sizeof(drmmode_crtc_private_rec), 1); drmmode_crtc->mode_crtc = @@ -804,6 +838,13 @@ drmmode_crtc_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_res drmmode_crtc->drmmode = drmmode; drmmode_crtc->vblank_pipe = drmmode_crtc_vblank_pipe(num); crtc->driver_private = drmmode_crtc; + + /* Mark num'th crtc as in use on this device. */ + ms_ent->assigned_crtcs |= (1 << num); + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, MS_LOGLEVEL_DEBUG, + "Allocated crtc nr. %d to this screen.\n", num); + + return 1; } static xf86OutputStatus @@ -1345,8 +1386,8 @@ drmmode_create_name(ScrnInfoPtr pScrn, drmModeConnectorPtr koutput, char *name, snprintf(name, 32, "%s-%d", output_names[koutput->connector_type], koutput->connector_type_id - 1); } -static void -drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_res, int num, Bool dynamic) +static unsigned int +drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_res, int num, Bool dynamic, int crtcshift) { xf86OutputPtr output; xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); @@ -1357,11 +1398,11 @@ drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_r char name[32]; int i; drmModePropertyBlobPtr path_blob = NULL; - + const char *s; koutput = drmModeGetConnector(drmmode->fd, mode_res->connectors[num]); if (!koutput) - return; + return 0; for (i = 0; i < koutput->count_props; i++) { props = drmModeGetProperty(drmmode->fd, koutput->props[i]); @@ -1392,7 +1433,7 @@ drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_r drmmode_output = output->driver_private; drmmode_output->output_id = mode_res->connectors[num]; drmmode_output->mode_output = koutput; - return; + return 1; } } @@ -1408,6 +1449,18 @@ drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_r } } + if (xf86IsEntityShared(pScrn->entityList[0])) { + if ((s = xf86GetOptValString(drmmode->Options, OPTION_ZAPHOD_HEADS))) { + if (!drmmode_zaphod_string_matches(pScrn, s, name)) + goto out_free_encoders; + } else { + if (!drmmode->is_secondary && (num != 0)) + goto out_free_encoders; + else if (drmmode->is_secondary && (num != 1)) + goto out_free_encoders; + } + } + output = xf86OutputCreate(pScrn, &drmmode_output_funcs, name); if (!output) { goto out_free_encoders; @@ -1433,7 +1486,7 @@ drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_r output->possible_crtcs = 0x7f; for (i = 0; i < koutput->count_encoders; i++) { - output->possible_crtcs &= kencoders[i]->possible_crtcs; + output->possible_crtcs &= kencoders[i]->possible_crtcs >> crtcshift; } /* work out the possible clones later */ output->possible_clones = 0; @@ -1452,7 +1505,8 @@ drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_r if (dynamic) output->randr_output = RROutputCreate(xf86ScrnToScreen(pScrn), output->name, strlen(output->name), output); - return; + return 1; + out_free_encoders: if (kencoders) { for (i = 0; i < koutput->count_encoders; i++) @@ -1461,6 +1515,7 @@ drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_r } drmModeFreeConnector(koutput); + return 0; } static uint32_t @@ -1682,10 +1737,13 @@ static const xf86CrtcConfigFuncsRec drmmode_xf86crtc_config_funcs = { Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp) { + modesettingEntPtr ms_ent = ms_ent_priv(pScrn); int i; int ret; uint64_t value = 0; + unsigned int crtcs_needed = 0; drmModeResPtr mode_res; + int crtcshift; /* check for dumb capability */ ret = drmGetCap(drmmode->fd, DRM_CAP_DUMB_BUFFER, &value); @@ -1703,15 +1761,26 @@ drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp) if (!mode_res) return FALSE; + crtcshift = ffs(ms_ent->assigned_crtcs ^ 0xffffffff) - 1; + for (i = 0; i < mode_res->count_connectors; i++) + crtcs_needed += drmmode_output_init(pScrn, drmmode, mode_res, i, FALSE, + crtcshift); + + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, MS_LOGLEVEL_DEBUG, + "Up to %d crtcs needed for screen.\n", crtcs_needed); + xf86CrtcSetSizeRange(pScrn, 320, 200, mode_res->max_width, mode_res->max_height); for (i = 0; i < mode_res->count_crtcs; i++) if (!xf86IsEntityShared(pScrn->entityList[0]) || - pScrn->confScreen->device->screen == i) - drmmode_crtc_init(pScrn, drmmode, mode_res, i); + (crtcs_needed && !(ms_ent->assigned_crtcs & (1 << i)))) + crtcs_needed -= drmmode_crtc_init(pScrn, drmmode, mode_res, i); - for (i = 0; i < mode_res->count_connectors; i++) - drmmode_output_init(pScrn, drmmode, mode_res, i, FALSE); + /* All ZaphodHeads outputs provided with matching crtcs? */ + if (xf86IsEntityShared(pScrn->entityList[0]) && (crtcs_needed > 0)) + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "%d ZaphodHeads crtcs unavailable. Some outputs will stay off.\n", + crtcs_needed); /* workout clones */ drmmode_clones_init(pScrn, drmmode, mode_res); @@ -1941,7 +2010,7 @@ drmmode_handle_uevents(int fd, void *closure) continue; changed = TRUE; - drmmode_output_init(scrn, drmmode, mode_res, i, 1); + drmmode_output_init(scrn, drmmode, mode_res, i, TRUE, 0); } if (changed) { |