diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2010-10-25 10:37:08 +1000 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2010-10-25 10:46:53 +1000 |
commit | 9737a812aacbc544b93eeaa031cf1c2e8adbd661 (patch) | |
tree | 1b1b66bbd4509f6ad5f78187e3c9ab6bcd26e1ca | |
parent | d40c16f5497739c0215f37566db1651a74cb20ba (diff) |
kms: initial pass at supporting zaphod-mode
This works ok from some simple testing, there's undoubtedly things that
will need polishing still however.
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r-- | man/nouveau.man | 10 | ||||
-rw-r--r-- | src/drmmode_display.c | 66 | ||||
-rw-r--r-- | src/nv_const.h | 2 | ||||
-rw-r--r-- | src/nv_driver.c | 19 | ||||
-rw-r--r-- | src/nv_type.h | 1 |
5 files changed, 92 insertions, 6 deletions
diff --git a/man/nouveau.man b/man/nouveau.man index a8961ad..39de690 100644 --- a/man/nouveau.man +++ b/man/nouveau.man @@ -80,6 +80,16 @@ Enable or disable wfb, only affects nv50+. Useful for some legacy configurations Synchronize GLX clients to VBlank. Useful where tearing is a problem, harmful if the GPU isn't fast enough to keep up with the monitor refresh rate. Default: off. +.TP +.BI "Option \*qZaphodHeads\*q \*q" string \*q +Specify the randr output(s) to use with zaphod mode for a particular driver +instance. If you use this option you most use this option for all instances +of the driver. +.br +For example: +.B +Option \*qZaphodHeads\*q \*qLVDS,VGA-0\*q +will assign xrandr outputs LVDS and VGA-0 to this instance of the driver. .SH "SEE ALSO" __xservername__(__appmansuffix__), __xconfigfile__(__filemansuffix__), Xserver(__appmansuffix__), X(__miscmansuffix__) .SH AUTHORS diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 94b19ea..c5b57eb 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -945,13 +945,48 @@ const char *output_names[] = { "None", }; #define NUM_OUTPUT_NAMES (sizeof(output_names) / sizeof(output_names[0])) +static Bool +drmmode_zaphod_match(ScrnInfoPtr pScrn, 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; +} + static void drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num) { + NVPtr pNv = NVPTR(pScrn); xf86OutputPtr output; drmModeConnectorPtr koutput; drmModeEncoderPtr kencoder; drmmode_output_private_ptr drmmode_output; + const char *s; char name[32]; koutput = drmModeGetConnector(drmmode->fd, @@ -973,6 +1008,28 @@ drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num) output_names[koutput->connector_type], koutput->connector_type_id); + if (xf86IsEntityShared(pScrn->entityList[0])) { + s = xf86GetOptValString(pNv->Options, OPTION_ZAPHOD_HEADS); + if (s) { + if (!drmmode_zaphod_match(pScrn, s, name)) { + drmModeFreeEncoder(kencoder); + drmModeFreeConnector(koutput); + return; + } + } else { + if (pNv->Primary && (num != 0)) { + drmModeFreeEncoder(kencoder); + drmModeFreeConnector(koutput); + return; + } else + if (pNv->Secondary && (num != 1)) { + drmModeFreeEncoder(kencoder); + drmModeFreeConnector(koutput); + return; + } + } + } + output = xf86OutputCreate (pScrn, &drmmode_output_funcs, name); if (!output) { drmModeFreeEncoder(kencoder); @@ -1003,8 +1060,6 @@ drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num) output->interlaceAllowed = true; output->doubleScanAllowed = true; - - return; } static Bool @@ -1121,8 +1176,11 @@ Bool drmmode_pre_init(ScrnInfoPtr pScrn, int fd, int cpp) xf86CrtcSetSizeRange(pScrn, 320, 200, drmmode->mode_res->max_width, drmmode->mode_res->max_height); - for (i = 0; i < drmmode->mode_res->count_crtcs; i++) - drmmode_crtc_init(pScrn, drmmode, i); + for (i = 0; i < drmmode->mode_res->count_crtcs; i++) { + if (!xf86IsEntityShared(pScrn->entityList[0] || + pScrn->confScreen->device->screen == i)) + drmmode_crtc_init(pScrn, drmmode, i); + } for (i = 0; i < drmmode->mode_res->count_connectors; i++) drmmode_output_init(pScrn, drmmode, i); diff --git a/src/nv_const.h b/src/nv_const.h index c355cad..f80d125 100644 --- a/src/nv_const.h +++ b/src/nv_const.h @@ -15,6 +15,7 @@ typedef enum { OPTION_VIDEO_KEY, OPTION_WFB, OPTION_GLX_VBLANK, + OPTION_ZAPHOD_HEADS, } NVOpts; @@ -26,6 +27,7 @@ static const OptionInfoRec NVOptions[] = { { OPTION_VIDEO_KEY, "VideoKey", OPTV_INTEGER, {0}, FALSE }, { OPTION_WFB, "WrappedFB", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_GLX_VBLANK, "GLXVBlank", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_ZAPHOD_HEADS, "ZaphodHeads", OPTV_STRING, {0}, FALSE }, { -1, NULL, OPTV_NONE, {0}, FALSE } }; diff --git a/src/nv_driver.c b/src/nv_driver.c index fad7d6a..f351fac 100644 --- a/src/nv_driver.c +++ b/src/nv_driver.c @@ -205,6 +205,7 @@ NVPciProbe(DriverPtr drv, int entity_num, struct pci_device *pci_dev, { -1, -1, NULL } }; struct nouveau_device *dev = NULL; + EntityInfoPtr pEnt = NULL; ScrnInfoPtr pScrn = NULL; drmVersion *version; int chipset, ret; @@ -280,6 +281,12 @@ NVPciProbe(DriverPtr drv, int entity_num, struct pci_device *pci_dev, pScrn->LeaveVT = NVLeaveVT; pScrn->FreeScreen = NVFreeScreen; + xf86SetEntitySharable(entity_num); + + pEnt = xf86GetEntityInfo(entity_num); + xf86SetEntityInstanceForScreen(pScrn, pEnt->index, xf86GetNumEntityInstances(pEnt->index) - 1); + free(pEnt); + return TRUE; } @@ -628,10 +635,18 @@ NVPreInit(ScrnInfoPtr pScrn, int flags) pNv->pEnt = xf86GetEntityInfo(pScrn->entityList[0]); if (pNv->pEnt->location.type != BUS_PCI) return FALSE; - + + if (xf86IsEntityShared(pScrn->entityList[0])) { + if(!xf86IsPrimInitDone(pScrn->entityList[0])) { + pNv->Primary = TRUE; + xf86SetPrimInitDone(pScrn->entityList[0]); + } else { + pNv->Secondary = TRUE; + } + } + /* Find the PCI info for this screen */ pNv->PciInfo = xf86GetPciInfoForEntity(pNv->pEnt->index); - pNv->Primary = xf86IsPrimaryPci(pNv->PciInfo); /* Initialise the kernel module */ if (!NVPreInitDRM(pScrn)) diff --git a/src/nv_type.h b/src/nv_type.h index 94c385a..4204556 100644 --- a/src/nv_type.h +++ b/src/nv_type.h @@ -33,6 +33,7 @@ typedef struct _NVRec { EntityInfoPtr pEnt; struct pci_device *PciInfo; Bool Primary; + Bool Secondary; /* Various pinned memory regions */ struct nouveau_bo * scanout; |