summaryrefslogtreecommitdiff
path: root/src/nv50_randr.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nv50_randr.c')
-rw-r--r--src/nv50_randr.c899
1 files changed, 0 insertions, 899 deletions
diff --git a/src/nv50_randr.c b/src/nv50_randr.c
deleted file mode 100644
index b163fda..0000000
--- a/src/nv50_randr.c
+++ /dev/null
@@ -1,899 +0,0 @@
-/*
- * Copyright 2008 Maarten Maathuis
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include "nv50_randr.h"
-#include "X11/Xatom.h"
-
-/*
- * A randr-1.2 wrapper around the NV50 driver.
- */
-
-/*
- * CRTC stuff.
- */
-
-static void
-nv50_crtc_dpms(xf86CrtcPtr crtc, int mode)
-{
- ScrnInfoPtr pScrn = crtc->scrn;
- NV50CrtcPrivatePtr nv_crtc = crtc->driver_private;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "nv50_crtc_dpms is called with mode %d for %s.\n", mode, nv_crtc->crtc->index ? "CRTC1" : "CRTC0");
-
- switch (mode) {
- case DPMSModeOn:
- nv_crtc->crtc->active = TRUE;
- break;
- case DPMSModeSuspend:
- case DPMSModeStandby:
- case DPMSModeOff:
- default:
- nv_crtc->crtc->active = FALSE;
- break;
- }
-}
-
-static Bool
-nv50_crtc_lock(xf86CrtcPtr crtc)
-{
- return FALSE;
-}
-
-static Bool
-nv50_crtc_mode_fixup(xf86CrtcPtr crtc, DisplayModePtr mode,
- DisplayModePtr adjusted_mode)
-{
- return TRUE;
-}
-
-static void
-nv50_crtc_prepare(xf86CrtcPtr crtc)
-{
- NV50CrtcPrivatePtr nv_crtc = crtc->driver_private;
- ScrnInfoPtr pScrn = crtc->scrn;
- NVPtr pNv = NVPTR(pScrn);
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
- nouveauOutputPtr output;
- int i;
-
- /* Rewire internal stucts to match randr-1.2... yet again.. */
- for (i = 0; i < xf86_config->num_output; i++) {
- xf86OutputPtr output = xf86_config->output[i];
- NV50OutputPrivatePtr nv50_output = output->driver_private;
- nouveauOutputPtr nv_output = nv50_output->output;
-
- if (output->crtc) {
- NV50CrtcPrivatePtr nv50_crtc =
- output->crtc->driver_private;
- nv_output->crtc = nv50_crtc->crtc;
- } else {
- nv_output->crtc = NULL;
- }
- }
-
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "nv50_crtc_prepare is called for %s.\n",
- nv_crtc->crtc->index ? "CRTC1" : "CRTC0");
-
- nv_crtc->crtc->active = TRUE;
- nv_crtc->crtc->modeset_lock = TRUE;
-
- /* Detach any unused outputs. */
- for (output = pNv->output; output != NULL; output = output->next) {
- if (!output->crtc)
- output->ModeSet(output, NULL);
- }
-}
-
-static void
-nv50_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
- DisplayModePtr adjusted_mode, int x, int y)
-{
- ScrnInfoPtr pScrn = crtc->scrn;
- NV50CrtcPrivatePtr nv_crtc = crtc->driver_private;
- struct nouveau_bo *bo;
-
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "nv50_crtc_mode_set is called for %s.\n",
- nv_crtc->crtc->index ? "CRTC1" : "CRTC0");
-
- NVPtr pNv = NVPTR(pScrn);
-
- bo = pNv->scanout;
- if (crtc->rotatedData) {
- bo = nv_crtc->shadow;
- x = 0;
- y = 0;
- }
-
- nv_crtc->crtc->SetFB(nv_crtc->crtc, bo);
- nv_crtc->crtc->SetFBOffset(nv_crtc->crtc, x, y);
- nv_crtc->crtc->ModeSet(nv_crtc->crtc, mode);
-}
-
-static void
-nv50_crtc_gamma_set(xf86CrtcPtr crtc, CARD16 *red, CARD16 *green, CARD16 *blue, int size)
-{
- ScrnInfoPtr pScrn = crtc->scrn;
- NV50CrtcPrivatePtr nv_crtc = crtc->driver_private;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "nv50_crtc_gamma_set is called for %s.\n", nv_crtc->crtc->index ? "CRTC1" : "CRTC0");
-
- nv_crtc->crtc->GammaSet(nv_crtc->crtc, (uint16_t *) red, (uint16_t *) green, (uint16_t *) blue, size);
-}
-
-static void
-nv50_crtc_commit(xf86CrtcPtr crtc)
-{
- ScrnInfoPtr pScrn = crtc->scrn;
- NV50CrtcPrivatePtr nv_crtc = crtc->driver_private;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "nv50_crtc_commit is called for %s.\n", nv_crtc->crtc->index ? "CRTC1" : "CRTC0");
-
- NVPtr pNv = NVPTR(pScrn);
-
- /* Let's detect any outputs and connectors that have gone inactive. */
- uint8_t crtc_active_mask = 0;
- int i, j;
- nouveauOutputPtr output;
-
- for (i = 0; i < DCB_MAX_NUM_I2C_ENTRIES; i++) {
- Bool connector_active = FALSE;
- for (j = 0; j < MAX_OUTPUTS_PER_CONNECTOR; j++) {
- output = pNv->connector[i]->outputs[j];
- if (output) {
- if (output->crtc) {
- crtc_active_mask |= 1 << output->crtc->index;
- connector_active = TRUE;
- } else {
- output->active = FALSE;
- }
- }
- }
-
- pNv->connector[i]->active = connector_active;
- }
-
- /* Blank any crtc's that are inactive. */
- if (!(crtc_active_mask & (1 << 0)))
- pNv->crtc[0]->Blank(pNv->crtc[0], TRUE);
-
- if (!(crtc_active_mask & (1 << 1)))
- pNv->crtc[1]->Blank(pNv->crtc[1], TRUE);
-
- xf86_reload_cursors(pScrn->pScreen);
-
- NV50DisplayCommand(pScrn, NV50_UPDATE_DISPLAY, 0);
-
- nv_crtc->crtc->modeset_lock = FALSE;
-}
-
-/*
- * Cursor CRTC stuff.
- */
-
-static void
-nv50_crtc_show_cursor(xf86CrtcPtr crtc)
-{
- //ScrnInfoPtr pScrn = crtc->scrn;
- NV50CrtcPrivatePtr nv_crtc = crtc->driver_private;
- //xf86DrvMsg(pScrn->scrnIndex, X_INFO, "nv50_crtc_show_cursor is called for %s.\n", nv_crtc->crtc->index ? "CRTC1" : "CRTC0");
-
- if (!nv_crtc->crtc->blanked)
- nv_crtc->crtc->ShowCursor(nv_crtc->crtc, FALSE);
-}
-
-static void
-nv50_crtc_hide_cursor(xf86CrtcPtr crtc)
-{
- //ScrnInfoPtr pScrn = crtc->scrn;
- NV50CrtcPrivatePtr nv_crtc = crtc->driver_private;
- //xf86DrvMsg(pScrn->scrnIndex, X_INFO, "nv50_crtc_hide_cursor is called for %s.\n", nv_crtc->crtc->index ? "CRTC1" : "CRTC0");
-
- nv_crtc->crtc->HideCursor(nv_crtc->crtc, FALSE);
-}
-
-static void
-nv50_crtc_set_cursor_position(xf86CrtcPtr crtc, int x, int y)
-{
- NV50CrtcPrivatePtr nv_crtc = crtc->driver_private;
-
- nv_crtc->crtc->SetCursorPosition(nv_crtc->crtc, x, y);
-}
-
-static void
-nv50_crtc_load_cursor_argb(xf86CrtcPtr crtc, CARD32 *src)
-{
- //ScrnInfoPtr pScrn = crtc->scrn;
- NV50CrtcPrivatePtr nv_crtc = crtc->driver_private;
- //xf86DrvMsg(pScrn->scrnIndex, X_INFO, "nv50_crtc_load_cursor_argb is called for %s.\n", nv_crtc->crtc->index ? "CRTC1" : "CRTC0");
-
- nv_crtc->crtc->LoadCursor(nv_crtc->crtc, TRUE, (uint32_t *) src);
-}
-
-static void *
-nv50_crtc_shadow_allocate (xf86CrtcPtr crtc, int width, int height)
-{
- ScrnInfoPtr pScrn = crtc->scrn;
- NV50CrtcPrivatePtr nv_crtc = crtc->driver_private;
- NVPtr pNv = NVPTR(pScrn);
- int size, pitch;
-
- ErrorF("nv50_crtc_shadow_allocate\n");
-
- pitch = pScrn->displayWidth * (pScrn->bitsPerPixel/8);
- size = pitch * height;
-
- if (nouveau_bo_new(pNv->dev, NOUVEAU_BO_VRAM |
- NOUVEAU_BO_MAP, 64, size, &nv_crtc->shadow)) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Failed to allocate memory for shadow buffer!\n");
- return NULL;
- }
-
- if (nv_crtc->shadow && nouveau_bo_map(nv_crtc->shadow, NOUVEAU_BO_RDWR)) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Failed to map shadow buffer.\n");
- return NULL;
- }
-
- pNv->shadow[nv_crtc->crtc->index] = nv_crtc->shadow;
-
- return nv_crtc->shadow->map;
-}
-
-static PixmapPtr
-nv50_crtc_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height)
-{
- ScrnInfoPtr pScrn = crtc->scrn;
- uint32_t pitch;
- PixmapPtr rotate_pixmap;
-
- ErrorF("nv50_crtc_shadow_create\n");
-
- if (!data)
- data = crtc->funcs->shadow_allocate (crtc, width, height);
-
- pitch = pScrn->displayWidth * (pScrn->bitsPerPixel/8);
-
- rotate_pixmap = GetScratchPixmapHeader(pScrn->pScreen,
- width, height,
- pScrn->depth,
- pScrn->bitsPerPixel,
- pitch,
- data);
-
- if (rotate_pixmap == NULL) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Couldn't allocate shadow pixmap for rotated CRTC\n");
- }
-
- return rotate_pixmap;
-}
-
-static void
-nv50_crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data)
-{
- ScrnInfoPtr pScrn = crtc->scrn;
- NV50CrtcPrivatePtr nv_crtc = crtc->driver_private;
- NVPtr pNv = NVPTR(pScrn);
- ScreenPtr pScreen = pScrn->pScreen;
-
- ErrorF("nv50_crtc_shadow_destroy\n");
-
- if (rotate_pixmap)
- pScreen->DestroyPixmap(rotate_pixmap);
-
- if (nv_crtc->shadow)
- nouveau_bo_ref(NULL, &nv_crtc->shadow);
-
- nv_crtc->shadow = NULL;
- /* for easy acces by exa */
- pNv->shadow[nv_crtc->crtc->index] = NULL;
-}
-
-#if XF86_CRTC_VERSION >= 2
-static void
-nv50_crtc_set_origin(xf86CrtcPtr crtc, int x, int y)
-{
- ScrnInfoPtr pScrn = crtc->scrn;
- NV50CrtcPrivatePtr nv_crtc = crtc->driver_private;
- nouveauCrtcPtr nvcrtc = nv_crtc->crtc; /* sigh.. */
- NVPtr pNv = NVPTR(pScrn);
- uint32_t fb;
-
- nvcrtc->SetFB(nvcrtc, pNv->scanout);
- nvcrtc->SetFBOffset(nvcrtc, x, y);
- nvcrtc->fb_pitch = pScrn->displayWidth * (pScrn->bitsPerPixel >> 3);
- fb = nvcrtc->front_buffer->offset - pNv->dev->vm_vram_base;
-
- NV50CrtcCommand(nvcrtc, NV50_CRTC0_FB_OFFSET, fb >> 8);
- NV50CrtcCommand(nvcrtc, NV50_CRTC0_FB_PITCH, nvcrtc->fb_pitch | (1<<20));
- NV50CrtcCommand(nvcrtc, NV50_CRTC0_FB_SIZE, (pScrn->virtualY << 16) |
- pScrn->virtualX);
-
- NV50DisplayCommand(pScrn, NV50_UPDATE_DISPLAY, 0);
-}
-#endif
-
-static void
-nv50_crtc_destroy(xf86CrtcPtr crtc)
-{
- xfree(crtc->driver_private);
-}
-
-static const xf86CrtcFuncsRec nv50_crtc_funcs = {
- .dpms = nv50_crtc_dpms,
- .save = NULL,
- .restore = NULL,
- .lock = nv50_crtc_lock,
- .unlock = NULL,
- .mode_fixup = nv50_crtc_mode_fixup,
- .prepare = nv50_crtc_prepare,
- .mode_set = nv50_crtc_mode_set,
- .gamma_set = nv50_crtc_gamma_set,
- .commit = nv50_crtc_commit,
- .shadow_create = nv50_crtc_shadow_create,
- .shadow_allocate = nv50_crtc_shadow_allocate,
- .shadow_destroy = nv50_crtc_shadow_destroy,
- .set_cursor_position = nv50_crtc_set_cursor_position,
- .show_cursor = nv50_crtc_show_cursor,
- .hide_cursor = nv50_crtc_hide_cursor,
- .load_cursor_argb = nv50_crtc_load_cursor_argb,
- .destroy = nv50_crtc_destroy,
-#if XF86_CRTC_VERSION >= 2
- .set_origin = nv50_crtc_set_origin,
-#endif
-};
-
-void
-nv50_crtc_init(ScrnInfoPtr pScrn, int crtc_num)
-{
- NVPtr pNv = NVPTR(pScrn);
- xf86CrtcPtr crtc;
- NV50CrtcPrivatePtr nv_crtc;
-
- crtc = xf86CrtcCreate(pScrn, &nv50_crtc_funcs);
- if (crtc == NULL)
- return;
-
- nv_crtc = xnfcalloc (sizeof (NV50CrtcPrivateRec), 1);
- nv_crtc->crtc = pNv->crtc[crtc_num];
-
- crtc->driver_private = nv_crtc;
-}
-
-
-/*
- * "Output" stuff.
- */
-
-static void
-nv50_output_dpms(xf86OutputPtr output, int mode)
-{
- ScrnInfoPtr pScrn = output->scrn;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "nv50_output_dpms is called with mode %d.\n", mode);
-
- NVPtr pNv = NVPTR(pScrn);
- NV50OutputPrivatePtr nv_output = output->driver_private;
-
- /* Keep the crtc wiring consistent with randr-1.2 */
- if (output->crtc) {
- NV50CrtcPrivatePtr nv_crtc = output->crtc->driver_private;
- nv_output->output->crtc = nv_crtc->crtc;
- } else {
- nv_output->output->crtc = NULL;
- }
-
- /* Our crtc's map 1:1 onto randr-1.2 crtc's. */
- switch (mode) {
- case DPMSModeOn:
- nv_output->output->active = TRUE;
- break;
- case DPMSModeSuspend:
- case DPMSModeStandby:
- case DPMSModeOff:
- default:
- nv_output->output->active = FALSE;
- break;
- }
-
- /* Set dpms on all outputs for ths connector, just to be safe. */
- nouveauConnectorPtr connector =
- pNv->connector[nv_output->output->dcb->i2c_index];
- int i;
- for (i = 0; i < MAX_OUTPUTS_PER_CONNECTOR; i++) {
- if (connector->outputs[i])
- connector->outputs[i]->SetPowerMode(connector->outputs[i], mode);
- }
-}
-
-static int
-nv50_output_mode_valid(xf86OutputPtr output, DisplayModePtr mode)
-{
- ScrnInfoPtr pScrn = output->scrn;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "nv50_output_mode_valid is called.\n");
-
- NV50OutputPrivatePtr nv_output = output->driver_private;
-
- return nv_output->output->ModeValid(nv_output->output, mode);
-}
-
-static Bool
-nv50_output_mode_fixup(xf86OutputPtr output, DisplayModePtr mode, DisplayModePtr adjusted_mode)
-{
- return TRUE;
-}
-
-static void
-nv50_output_mode_set(xf86OutputPtr output, DisplayModePtr mode, DisplayModePtr adjusted_mode)
-{
- ScrnInfoPtr pScrn = output->scrn;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "nv50_output_mode_set is called.\n");
-
- NV50OutputPrivatePtr nv_output = output->driver_private;
-
- nv_output->output->ModeSet(nv_output->output, mode);
-}
-
-static xf86OutputStatus
-nv50_output_detect(xf86OutputPtr output)
-{
- ScrnInfoPtr pScrn = output->scrn;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "nv50_output_detect is called.\n");
-
- NVPtr pNv = NVPTR(pScrn);
- NV50OutputPrivatePtr nv_output = output->driver_private;
- nouveauConnectorPtr connector =
- pNv->connector[nv_output->output->dcb->i2c_index];
-
- if (!connector)
- return XF86OutputStatusDisconnected;
-
- Bool detect_present = FALSE;
- Bool detect_digital = FALSE;
- xf86MonPtr ddc_mon = connector->DDCDetect(connector);
- int i;
-
- if (!ddc_mon) {
- for (i = 0; i < MAX_OUTPUTS_PER_CONNECTOR; i++) {
- if (connector->outputs[i] && connector->outputs[i]->Detect) {
- detect_present = connector->outputs[i]->Detect(connector->outputs[i]);
- if (detect_present) {
- if (connector->outputs[i]->type == OUTPUT_TMDS || connector->outputs[i]->type == OUTPUT_LVDS)
- detect_digital = TRUE;
- break;
- }
- }
- }
- }
-
- /* HACK: assume that a connector only holds output in the case of a tv-out */
- if (nv_output->output->type == OUTPUT_TV)
- return XF86OutputStatusUnknown;
-
- /*
- * We abuse randr-1.2 outputs as connector, so here we have to determine what actual output is connected to the connector.
- */
- if (ddc_mon || detect_present) {
- Bool is_digital = FALSE;
- Bool found = FALSE;
- nouveauCrtcPtr crtc_backup = nv_output->output->crtc;
- nv_output->output->crtc = NULL;
- nv_output->output->connector = NULL;
-
- if (ddc_mon)
- is_digital = ddc_mon->features.input_type;
- else
- is_digital = detect_digital;
-
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Detected a %s output on %s\n", is_digital ? "Digital" : "Analog", connector->name);
-
- for (i = 0; i < MAX_OUTPUTS_PER_CONNECTOR; i++) {
- if (!is_digital && (connector->outputs[i]->type == OUTPUT_ANALOG || connector->outputs[i]->type == OUTPUT_TV)) {
- found = TRUE;
- } else if (is_digital && (connector->outputs[i]->type == OUTPUT_TMDS || connector->outputs[i]->type == OUTPUT_LVDS)) {
- found = TRUE;
- }
- if (found) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Found a suitable output, index %d\n", i);
- connector->connected_output = i;
- connector->outputs[i]->connector = connector;
- connector->outputs[i]->crtc = crtc_backup;
- nv_output->output = connector->outputs[i];
- break;
- }
- }
- }
-
- if (ddc_mon || detect_present) {
- free(ddc_mon);
- return XF86OutputStatusConnected;
- } else {
- return XF86OutputStatusDisconnected;
- }
-}
-
-static DisplayModePtr
-nv50_output_get_modes(xf86OutputPtr output)
-{
- ScrnInfoPtr pScrn = output->scrn;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "nv50_output_detect is called.\n");
-
- NVPtr pNv = NVPTR(pScrn);
- NV50OutputPrivatePtr nv_output = output->driver_private;
- nouveauConnectorPtr connector =
- pNv->connector[nv_output->output->dcb->i2c_index];
-
- xf86MonPtr ddc_mon = connector->DDCDetect(connector);
-
- xf86OutputSetEDID(output, ddc_mon);
-
- DisplayModePtr ddc_modes = connector->GetDDCModes(connector);
- DisplayModePtr default_modes = NULL;
-
- xf86DeleteMode(&nv_output->output->native_mode, nv_output->output->native_mode);
- nv_output->output->native_mode = NULL;
- if (nv_output->output->crtc)
- nv_output->output->crtc->native_mode = NULL;
-
- /* typically only LVDS will hit this code path. */
- if (!ddc_modes) {
- DisplayModeRec mode = {};
-
- if (nv_output->output->type == OUTPUT_LVDS &&
- nouveau_bios_fp_mode(pScrn, &mode)) {
- mode.status = MODE_OK;
- mode.type = M_T_DRIVER | M_T_PREFERRED;
- xf86SetModeDefaultName(&mode);
-
- ddc_modes = xf86DuplicateMode(&mode);
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "LVDS: Using a bios mode, which should work, if it doesn't please report.\n");
- }
- }
-
- if (!ddc_modes && nv_output->output->type == OUTPUT_LVDS) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "LVDS and no modes found, bailing out.\n");
- return NULL;
- }
-
- /* NV5x hardware can also do scaling on analog connections. */
- if (ddc_modes) {
- /* Use the first preferred mode as native mode. */
- DisplayModePtr mode;
-
- /* Find the preferred mode. */
- for (mode = ddc_modes; mode != NULL; mode = mode->next) {
- if (mode->type & M_T_PREFERRED) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "%s: preferred mode is %s\n",
- output->name, mode->name);
- break;
- }
- }
-
- /* TODO: Scaling needs a native mode, maybe fail in a better way. */
- if (!mode) {
- mode = ddc_modes;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "%s: no preferred mode found, using %s\n",
- output->name, mode->name);
- }
-
- nv_output->output->native_mode = xf86DuplicateMode(mode);
- }
-
- /* No ddc means no native mode, so make one up to avoid crashes. */
- if (!nv_output->output->native_mode)
- nv_output->output->native_mode = xf86CVTMode(1024, 768, 60.0, FALSE, FALSE);
-
- xf86SetModeCrtc(nv_output->output->native_mode, 0);
-
- if (nv_output->output->crtc)
- nv_output->output->crtc->native_mode = nv_output->output->native_mode;
-
- if (nv_output->output->type == OUTPUT_LVDS &&
- (!ddc_mon ||!GTF_SUPPORTED(ddc_mon->features.msc))) {
-#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1,6,99,1,0)
- default_modes = xf86GetDefaultModes(output->interlaceAllowed,
- output->doubleScanAllowed);
-#else
- default_modes = xf86GetDefaultModes();
-#endif
- }
-
- xf86ModesAdd(ddc_modes, default_modes);
- return ddc_modes;
-}
-
-static void
-nv50_output_destroy(xf86OutputPtr output)
-{
- NV50OutputPrivatePtr nv_output = output->driver_private;
-
- xf86DeleteMode(&nv_output->output->native_mode, nv_output->output->native_mode);
-
- xfree(output->driver_private);
- output->driver_private = NULL;
-}
-
-void
-nv50_output_prepare(xf86OutputPtr output)
-{
- ScrnInfoPtr pScrn = output->scrn;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "nv50_output_prepare is called.\n");
-
- NV50OutputPrivatePtr nv_output = output->driver_private;
- NV50CrtcPrivatePtr nv_crtc = output->crtc->driver_private;
-
- /* Set the real crtc now. */
- nv_output->output->crtc = nv_crtc->crtc;
-
- /* Transfer some output properties to the crtc for easy access. */
- nv_output->output->crtc->scale_mode = nv_output->output->scale_mode;
- nv_output->output->crtc->dithering = nv_output->output->dithering;
- nv_output->output->crtc->native_mode = nv_output->output->native_mode;
-
- if (nv_output->output->scale_mode != SCALE_PANEL)
- nv_output->output->crtc->use_native_mode = TRUE;
- else
- nv_output->output->crtc->use_native_mode = FALSE;
-}
-
-static void
-nv50_output_commit(xf86OutputPtr output)
-{
- ScrnInfoPtr pScrn = output->scrn;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "nv50_output_commit is called.\n");
-}
-
-#ifdef RANDR_GET_CRTC_INTERFACE
-static xf86CrtcPtr
-nv50_output_get_crtc(xf86OutputPtr output)
-{
- ScrnInfoPtr pScrn = output->scrn;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "nv50_output_get_crtc is called.\n");
-
- NV50OutputPrivatePtr nv_output = output->driver_private;
- nouveauCrtcPtr crtc = nv_output->output->GetCurrentCrtc(nv_output->output);
-
- /*
- * Match the internal crtc to the public crtc.
- * Note that GetCurrentCrtc() retrieves hardware state.
- * Otherwise we could have just used output->crtc.
- */
- if (crtc) {
- int i;
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
- for (i = 0; i < xf86_config->num_crtc; i++) {
- NV50CrtcPrivatePtr nv_crtc = xf86_config->crtc[i]->driver_private;
- if (nv_crtc->crtc == crtc)
- return xf86_config->crtc[i];
- }
- }
-
- return NULL;
-}
-#endif /* RANDR_GET_CRTC_INTERFACE */
-
-/*
- * Output properties.
- */
-
-/*
- * Several scaling modes exist, let the user choose.
- */
-#define SCALING_MODE_NAME "SCALING_MODE"
-static const struct {
- char *name;
- enum scaling_modes mode;
-} scaling_mode[] = {
- { "panel", SCALE_PANEL },
- { "fullscreen", SCALE_FULLSCREEN },
- { "aspect", SCALE_ASPECT },
- { "noscale", SCALE_NOSCALE },
- { NULL, SCALE_INVALID}
-};
-static Atom scaling_mode_atom;
-
-#define DITHERING_MODE_NAME "DITHERING"
-static Atom dithering_atom;
-
-int
-nv_scaling_mode_lookup(char *name, int size)
-{
- int i;
-
- /* for when name is zero terminated */
- if (size < 0)
- size = strlen(name);
-
- for (i = 0; scaling_mode[i].name; i++)
- /* We're getting non-terminated strings */
- if (strlen(scaling_mode[i].name) >= size &&
- !strncasecmp(name, scaling_mode[i].name, size))
- break;
-
- return scaling_mode[i].mode;
-}
-
-void
-nv50_output_create_resources(xf86OutputPtr output)
-{
- NV50OutputPrivatePtr nv_output = output->driver_private;
- ScrnInfoPtr pScrn = output->scrn;
- INT32 dithering_range[2] = { 0, 1 };
- int error, i;
-
- /*
- * Setup scaling mode property.
- */
- scaling_mode_atom = MakeAtom(SCALING_MODE_NAME, sizeof(SCALING_MODE_NAME) - 1, TRUE);
-
- error = RRConfigureOutputProperty(output->randr_output,
- scaling_mode_atom, TRUE, FALSE, FALSE,
- 0, NULL);
-
- if (error != 0) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "RRConfigureOutputProperty error, %d\n", error);
- }
-
- char *existing_scale_name = NULL;
- for (i = 0; scaling_mode[i].name; i++)
- if (scaling_mode[i].mode == nv_output->output->scale_mode)
- existing_scale_name = scaling_mode[i].name;
-
- error = RRChangeOutputProperty(output->randr_output, scaling_mode_atom,
- XA_STRING, 8, PropModeReplace,
- strlen(existing_scale_name),
- existing_scale_name, FALSE, TRUE);
-
- if (error != 0) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Failed to set scaling mode, %d\n", error);
- }
-
- if (nv_output->output->type == OUTPUT_TMDS || nv_output->output->type == OUTPUT_LVDS) {
- /*
- * Setup dithering property.
- */
- dithering_atom = MakeAtom(DITHERING_MODE_NAME, sizeof(DITHERING_MODE_NAME) - 1, TRUE);
-
- error = RRConfigureOutputProperty(output->randr_output,
- dithering_atom, TRUE, TRUE, FALSE,
- 2, dithering_range);
-
- if (error != 0) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "RRConfigureOutputProperty error, %d\n", error);
- }
-
- error = RRChangeOutputProperty(output->randr_output, dithering_atom,
- XA_INTEGER, 32, PropModeReplace, 1, &nv_output->output->dithering,
- FALSE, TRUE);
-
- if (error != 0) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Failed to set dithering mode, %d\n", error);
- }
- }
-}
-
-Bool
-nv50_output_set_property(xf86OutputPtr output, Atom property,
- RRPropertyValuePtr value)
-{
- NV50OutputPrivatePtr nv_output = output->driver_private;
-
- if (property == scaling_mode_atom) {
- int32_t ret;
- char *name = NULL;
-
- if (value->type != XA_STRING || value->format != 8)
- return FALSE;
-
- name = (char *) value->data;
-
- /* Match a string to a scaling mode */
- ret = nv_scaling_mode_lookup(name, value->size);
- if (ret == SCALE_INVALID)
- return FALSE;
-
- /* LVDS must always use gpu scaling. */
- if (ret == SCALE_PANEL && nv_output->output->type == OUTPUT_LVDS)
- return FALSE;
-
- nv_output->output->scale_mode = ret;
- if (nv_output->output->crtc) /* normally prepare sets all these things for the crtc. */
- nv_output->output->crtc->scale_mode = ret;
- return TRUE;
- } else if (property == dithering_atom) {
- if (value->type != XA_INTEGER || value->format != 32)
- return FALSE;
-
- int32_t val = *(int32_t *) value->data;
-
- if (val < 0 || val > 1)
- return FALSE;
-
- nv_output->output->dithering = val;
- if (nv_output->output->crtc) /* normally prepare sets all these things for the crtc. */
- nv_output->output->crtc->dithering = val;
- return TRUE;
- }
-
- return TRUE;
-}
-
-static const xf86OutputFuncsRec nv50_output_funcs = {
- .dpms = nv50_output_dpms,
- .save = NULL,
- .restore = NULL,
- .mode_valid = nv50_output_mode_valid,
- .mode_fixup = nv50_output_mode_fixup,
- .mode_set = nv50_output_mode_set,
- .detect = nv50_output_detect,
- .get_modes = nv50_output_get_modes,
- .destroy = nv50_output_destroy,
- .prepare = nv50_output_prepare,
- .commit = nv50_output_commit,
-#ifdef RANDR_GET_CRTC_INTERFACE
- .get_crtc = nv50_output_get_crtc,
-#endif /*RANDR_GET_CRTC_INTERFACE */
- .create_resources = nv50_output_create_resources,
- .set_property = nv50_output_set_property,
-};
-
-void
-nv50_output_create(ScrnInfoPtr pScrn)
-{
- NVPtr pNv = NVPTR(pScrn);
- xf86OutputPtr output;
- NV50OutputPrivatePtr nv_output;
- int i;
-
- /* this is a 1:1 hookup of the connectors. */
- for (i = 0; i < DCB_MAX_NUM_I2C_ENTRIES; i++) {
- if (!(pNv->connector[i]->outputs[0]))
- continue; /* An empty connector is not useful. */
-
- if (!(output = xf86OutputCreate(pScrn, &nv50_output_funcs, pNv->connector[i]->name)))
- return;
-
- if (!(nv_output = xnfcalloc(sizeof(NV50OutputPrivateRec), 1)))
- return;
-
- output->driver_private = nv_output;
-
- nv_output->output = pNv->connector[i]->outputs[0]; /* initially just wire up the first output available. */
-
- output->possible_crtcs = nv_output->output->allowed_crtc;
- output->possible_clones = 0;
-
- if (nv_output->output->type == OUTPUT_TMDS || nv_output->output->type == OUTPUT_LVDS) {
- output->doubleScanAllowed = false;
- output->interlaceAllowed = false;
- } else {
- output->doubleScanAllowed = true;
- output->interlaceAllowed = true;
- }
- }
-}