[PATCH r128] Port to RandR
Alex Deucher
alexdeucher at gmail.com
Tue Jul 1 09:56:07 PDT 2014
On Sun, Jun 1, 2014 at 4:03 PM, Connor Behan <connor.behan at gmail.com> wrote:
> This rearranges the r128 code to use the Crtc and Ouput interfaces which
> should make the driver easier to maintain in the long run. User visible
> changes include DDC detection working in more cases and the ability to
> have multiple monitors with DRI.
>
> Some choices have been made to conserve memory. Modes can be switched up
> to the highest resolution specified in xorg.conf. If this is 1024x768
> for example, the front buffer will be 1024x768 instead of 1024x1024.
> This means 90 and 270 degree rotations will not work. However, scalings,
> reflections and 180 degree rotations can be set with the xrandr client
> program.
>
> Signed-off-by: Connor Behan <connor.behan at gmail.com>
A few comments below, but they can be addressed later if you want.
Other than that the patch is:
Reviewed-by: Alex Deucher <alexander.deucher at amd.com>
> ---
> configure.ac | 2 +-
> src/Makefile.am | 3 +-
> src/r128.h | 48 +-
> src/r128_crtc.c | 476 ++++++++++++++++++++
> src/r128_cursor.c | 294 ++++++------
> src/r128_driver.c | 1287 +++++++++++------------------------------------------
> src/r128_output.c | 465 +++++++++++++++++++
> src/r128_probe.c | 1 -
> src/r128_probe.h | 79 ++++
> src/r128_video.c | 17 +-
> 10 files changed, 1479 insertions(+), 1193 deletions(-)
> create mode 100644 src/r128_crtc.c
> create mode 100644 src/r128_output.c
>
> diff --git a/configure.ac b/configure.ac
> index 56554ec..3cc3113 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -76,7 +76,7 @@ XORG_DRIVER_CHECK_EXT(XF86MISC, xf86miscproto)
> XORG_DRIVER_CHECK_EXT(DPMSExtension, xextproto)
>
> # Obtain compiler/linker options for the driver dependencies
> -PKG_CHECK_MODULES(XORG, [xorg-server >= 1.2 xproto fontsproto $REQUIRED_MODULES])
> +PKG_CHECK_MODULES(XORG, [xorg-server >= 1.3 xproto fontsproto $REQUIRED_MODULES])
> PKG_CHECK_MODULES(XEXT, [xextproto >= 7.0.99.1],
> HAVE_XEXTPROTO_71="yes"; AC_DEFINE(HAVE_XEXTPROTO_71, 1, [xextproto 7.1 available]),
> HAVE_XEXTPROTO_71="no")
> diff --git a/src/Makefile.am b/src/Makefile.am
> index 23e6c49..e4618ea 100644
> --- a/src/Makefile.am
> +++ b/src/Makefile.am
> @@ -41,7 +41,8 @@ r128_drv_la_LDFLAGS = -module -avoid-version
> r128_drv_ladir = @moduledir@/drivers
> r128_drv_la_SOURCES = \
> r128_accel.c r128_cursor.c r128_dga.c r128_driver.c \
> - r128_video.c r128_misc.c r128_probe.c $(R128_EXA_SRCS) $(R128_DRI_SRCS)
> + r128_video.c r128_misc.c r128_crtc.c r128_output.c r128_probe.c \
> + $(R128_EXA_SRCS) $(R128_DRI_SRCS)
>
> EXTRA_DIST = \
> compat-api.h \
> diff --git a/src/r128.h b/src/r128.h
> index ee0b1d4..fe757f8 100644
> --- a/src/r128.h
> +++ b/src/r128.h
> @@ -74,6 +74,7 @@
> #endif
>
> #include "fb.h"
> +#include "xf86Crtc.h"
>
> #include "compat-api.h"
> #include "atipcirename.h"
> @@ -260,16 +261,6 @@ typedef struct {
> DisplayModePtr mode;
> } R128FBLayout;
>
> -typedef enum
> -{
> - MT_NONE,
> - MT_CRT,
> - MT_LCD,
> - MT_DFP,
> - MT_CTV,
> - MT_STV
> -} R128MonitorType;
> -
> #ifdef USE_EXA
> struct r128_2d_state {
> Bool in_use;
> @@ -523,10 +514,10 @@ typedef struct {
>
> Bool isDFP;
> Bool isPro2;
> - I2CBusPtr pI2CBus;
> - CARD32 DDCReg;
> + Bool DDC;
>
> Bool VGAAccess;
> + R128BIOSConnector BiosConnector[R128_MAX_BIOS_CONNECTOR];
>
> /****** Added for dualhead support *******************/
> BOOL HasCRTC2; /* M3/M4 */
> @@ -562,6 +553,39 @@ extern int R128MinBits(int val);
>
> extern void R128InitVideo(ScreenPtr pScreen);
>
> +extern void R128InitCommonRegisters(R128SavePtr save, R128InfoPtr info);
> +extern void R128InitFPRegisters(R128SavePtr orig, R128SavePtr save, DisplayModePtr mode, R128InfoPtr info);
> +extern Bool R128InitCrtcBase(xf86CrtcPtr crtc, R128SavePtr save, int x, int y);
> +extern Bool R128InitCrtcRegisters(ScrnInfoPtr pScrn, R128SavePtr save, DisplayModePtr mode, R128InfoPtr info);
> +extern void R128InitPLLRegisters(ScrnInfoPtr pScrn, R128SavePtr save, R128PLLPtr pll, double dot_clock);
> +extern Bool R128InitDDARegisters(ScrnInfoPtr pScrn, R128SavePtr save, R128PLLPtr pll, R128InfoPtr info, DisplayModePtr mode);
> +extern Bool R128InitCrtc2Base(xf86CrtcPtr crtc, R128SavePtr save, int x, int y);
> +extern Bool R128InitCrtc2Registers(ScrnInfoPtr pScrn, R128SavePtr save, DisplayModePtr mode, R128InfoPtr info);
> +extern void R128InitPLL2Registers(ScrnInfoPtr pScrn, R128SavePtr save, R128PLLPtr pll, double dot_clock);
> +extern Bool R128InitDDA2Registers(ScrnInfoPtr pScrn, R128SavePtr save, R128PLLPtr pll, R128InfoPtr info, DisplayModePtr mode);
> +extern void R128RestoreCommonRegisters(ScrnInfoPtr pScrn, R128SavePtr restore);
> +extern void R128RestoreFPRegisters(ScrnInfoPtr pScrn, R128SavePtr restore);
> +extern void R128RestoreCrtcRegisters(ScrnInfoPtr pScrn, R128SavePtr restore);
> +extern void R128RestorePLLRegisters(ScrnInfoPtr pScrn, R128SavePtr restore);
> +extern void R128RestoreDDARegisters(ScrnInfoPtr pScrn, R128SavePtr restore);
> +extern void R128RestoreCrtc2Registers(ScrnInfoPtr pScrn, R128SavePtr restore);
> +extern void R128RestorePLL2Registers(ScrnInfoPtr pScrn, R128SavePtr restore);
> +extern void R128RestoreDDA2Registers(ScrnInfoPtr pScrn, R128SavePtr restore);
> +
> +extern void r128_crtc_set_cursor_colors(xf86CrtcPtr crtc, int bg, int fg);
> +extern void r128_crtc_set_cursor_position(xf86CrtcPtr crtc, int x, int y);
> +extern void r128_crtc_show_cursor(xf86CrtcPtr crtc);
> +extern void r128_crtc_hide_cursor(xf86CrtcPtr crtc);
> +extern void r128_crtc_load_cursor_image(xf86CrtcPtr crtc, unsigned char *src);
> +
> +extern Bool R128SetupConnectors(ScrnInfoPtr pScrn);
> +extern Bool R128AllocateControllers(ScrnInfoPtr pScrn, int mask);
> +extern void R128Blank(ScrnInfoPtr pScrn);
> +extern void R128Unblank(ScrnInfoPtr pScrn);
> +extern void R128DPMSSetOn(xf86OutputPtr output);
> +extern void R128DPMSSetOff(xf86OutputPtr output);
> +extern DisplayModePtr R128ProbeOutputModes(xf86OutputPtr output);
> +
> #ifdef R128DRI
> extern Bool R128DRIScreenInit(ScreenPtr pScreen);
> extern void R128DRICloseScreen(ScreenPtr pScreen);
> diff --git a/src/r128_crtc.c b/src/r128_crtc.c
> new file mode 100644
> index 0000000..35e1fee
> --- /dev/null
> +++ b/src/r128_crtc.c
> @@ -0,0 +1,476 @@
> +/*
> + * Copyright 2000 ATI Technologies Inc., Markham, Ontario, and
> + * VA Linux Systems Inc., Fremont, California.
> + *
> + * All Rights Reserved.
> + *
> + * 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 on 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 (including the
> + * next paragraph) 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
> + * NON-INFRINGEMENT. IN NO EVENT SHALL ATI, VA LINUX SYSTEMS AND/OR
> + * THEIR SUPPLIERS 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.
> + */
> +
> +#ifdef HAVE_CONFIG_H
> +#include "config.h"
> +#endif
> +
> +#include <string.h>
> +#include <stdio.h>
> +
> +#include "xf86.h"
> +#include "xf86Modes.h"
> +
> +#include "r128.h"
> +#include "r128_probe.h"
> +#include "r128_reg.h"
> +
> +static void r128_crtc_load_lut(xf86CrtcPtr crtc);
> +
> +static void r128_crtc_dpms(xf86CrtcPtr crtc, int mode)
> +{
> + int mask;
> + ScrnInfoPtr pScrn = crtc->scrn;
> + R128InfoPtr info = R128PTR(pScrn);
> + unsigned char *R128MMIO = info->MMIO;
> + R128CrtcPrivatePtr r128_crtc = crtc->driver_private;
> +
> + /* XXX: The HSYNC and VSYNC bits for CRTC2 don't exist on the r128? */
> + mask = r128_crtc->crtc_id ? R128_CRTC2_DISP_DIS : (R128_CRTC_DISPLAY_DIS | R128_CRTC_HSYNC_DIS | R128_CRTC_VSYNC_DIS);
> +
You might also want to disable the CRTC altogether in the
non-DPMSModeOn cases using CRTC_GEN_CNTL.CRTC_EN and
CRTC2_GEN_CNTL.CRTC2_EN. It should save some additional power.
> + switch (mode) {
> + case DPMSModeOn:
> + if (r128_crtc->crtc_id) {
> + OUTREGP(R128_CRTC2_GEN_CNTL, 0, ~mask);
> + } else {
> + OUTREGP(R128_CRTC_EXT_CNTL, 0, ~mask);
> + }
> + break;
> + case DPMSModeStandby:
> + if (r128_crtc->crtc_id) {
> + OUTREGP(R128_CRTC2_GEN_CNTL, R128_CRTC2_DISP_DIS, ~mask);
> + } else {
> + OUTREGP(R128_CRTC_EXT_CNTL, (R128_CRTC_DISPLAY_DIS | R128_CRTC_HSYNC_DIS), ~mask);
> + }
> + break;
> + case DPMSModeSuspend:
> + if (r128_crtc->crtc_id) {
> + OUTREGP(R128_CRTC2_GEN_CNTL, R128_CRTC2_DISP_DIS, ~mask);
> + } else {
> + OUTREGP(R128_CRTC_EXT_CNTL, (R128_CRTC_DISPLAY_DIS | R128_CRTC_VSYNC_DIS), ~mask);
> + }
> + break;
> + case DPMSModeOff:
> + if (r128_crtc->crtc_id) {
> + OUTREGP(R128_CRTC2_GEN_CNTL, mask, ~mask);
> + } else {
> + OUTREGP(R128_CRTC_EXT_CNTL, mask, ~mask);
> + }
> + break;
> + }
> +
> + if (mode != DPMSModeOff)
> + r128_crtc_load_lut(crtc);
> +}
> +
> +void r128_crtc_load_lut(xf86CrtcPtr crtc)
> +{
> + ScrnInfoPtr pScrn = crtc->scrn;
> + R128InfoPtr info = R128PTR(pScrn);
> + unsigned char *R128MMIO = info->MMIO;
> + R128CrtcPrivatePtr r128_crtc = crtc->driver_private;
> + int i;
> +
> + if (!crtc->enabled)
> + return;
> +
> + PAL_SELECT(r128_crtc->crtc_id);
> +
> + for (i = 0; i < 256; i++) {
> + OUTPAL(i, r128_crtc->lut_r[i], r128_crtc->lut_g[i], r128_crtc->lut_b[i]);
> + }
> +}
> +
> +static Bool r128_crtc_mode_fixup(xf86CrtcPtr crtc, DisplayModePtr mode, DisplayModePtr adjusted_mode)
> +{
> + return TRUE;
> +}
> +
> +static void r128_crtc_mode_prepare(xf86CrtcPtr crtc)
> +{
> + r128_crtc_dpms(crtc, DPMSModeOff);
> +}
> +
> +static void r128_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, DisplayModePtr adjusted_mode, int x, int y)
> +{
> + ScrnInfoPtr pScrn = crtc->scrn;
> + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
> + R128CrtcPrivatePtr r128_crtc = crtc->driver_private;
> + R128InfoPtr info = R128PTR(pScrn);
> + R128OutputType otype = OUTPUT_NONE;
> +
> + double dot_clock = adjusted_mode->Clock / 1000.0;
> + int i;
> +
> + if (r128_crtc->cursor_offset) r128_crtc_hide_cursor(crtc);
> + xf86PrintModeline(pScrn->scrnIndex, adjusted_mode);
> + R128InitCommonRegisters(&info->ModeReg, info);
> +
> + for (i = 0; i < xf86_config->num_output; i++) {
> + xf86OutputPtr output = xf86_config->output[i];
> + R128OutputPrivatePtr r128_output = output->driver_private;
> +
> + if (output->crtc == crtc)
> + otype = r128_output->type;
> + }
> +
> + switch (r128_crtc->crtc_id) {
> + case 0:
> + R128InitCrtcRegisters(pScrn, &info->ModeReg, adjusted_mode, info);
> + R128InitCrtcBase(crtc, &info->ModeReg, x, y);
> + if (dot_clock) {
> + R128InitPLLRegisters(pScrn, &info->ModeReg, &info->pll, dot_clock);
> + R128InitDDARegisters(pScrn, &info->ModeReg, &info->pll, info, adjusted_mode);
> + } else {
> + info->ModeReg.ppll_ref_div = info->SavedReg.ppll_ref_div;
> + info->ModeReg.ppll_div_3 = info->SavedReg.ppll_div_3;
> + info->ModeReg.htotal_cntl = info->SavedReg.htotal_cntl;
> + info->ModeReg.dda_config = info->SavedReg.dda_config;
> + info->ModeReg.dda_on_off = info->SavedReg.dda_on_off;
> + }
> + break;
> + case 1:
> + R128InitCrtc2Registers(pScrn, &info->ModeReg, adjusted_mode, info);
> + R128InitCrtc2Base(crtc, &info->ModeReg, x, y);
> + if (dot_clock) {
> + R128InitPLL2Registers(pScrn, &info->ModeReg, &info->pll, dot_clock);
> + R128InitDDA2Registers(pScrn, &info->ModeReg, &info->pll, info, adjusted_mode);
> + }
> + break;
> + }
> +
> + if (otype == OUTPUT_DVI || otype == OUTPUT_LVDS)
> + R128InitFPRegisters(&info->SavedReg, &info->ModeReg, adjusted_mode, info);
You might want to split R128InitFPRegisters() up into specific
functions for TMDS and LVDS. I'm not sure if it properly handles the
combination of LVDS + TMDS correctly.
> + R128RestoreCommonRegisters(pScrn, &info->ModeReg);
> +
> + switch (r128_crtc->crtc_id) {
> + case 0:
> + R128RestoreDDARegisters(pScrn, &info->ModeReg);
> + R128RestoreCrtcRegisters(pScrn, &info->ModeReg);
> + R128RestorePLLRegisters(pScrn, &info->ModeReg);
> + break;
> + case 1:
> + R128RestoreDDA2Registers(pScrn, &info->ModeReg);
> + R128RestoreCrtc2Registers(pScrn, &info->ModeReg);
> + R128RestorePLL2Registers(pScrn, &info->ModeReg);
> + break;
> + }
> +
> + if (otype == OUTPUT_DVI || otype == OUTPUT_LVDS)
> + R128RestoreFPRegisters(pScrn, &info->ModeReg);
> +
Same here. You may want to split this up between TMDS and LVDS.
> + /* XXX: InitFPRegisters looks similar to radeon's InitRMXRegisters so
> + * maybe it should be called from mode_set in the output code.
> + */
You could probably break out the RMX controls as well since you can
use the RMX scaler on either TMDS or LVDS.
> + if (r128_crtc->cursor_offset) r128_crtc_show_cursor(crtc);
Is this needed?
> +}
> +
> +static void r128_crtc_mode_commit(xf86CrtcPtr crtc)
> +{
> + r128_crtc_dpms(crtc, DPMSModeOn);
> +}
> +
> +static void r128_crtc_gamma_set(xf86CrtcPtr crtc, CARD16 *red, CARD16 *green, CARD16 *blue, int size)
> +{
> + R128CrtcPrivatePtr r128_crtc = crtc->driver_private;
> + int i;
> +
> + for (i = 0; i < 256; i++) {
> + r128_crtc->lut_r[i] = red[i] >> 8;
> + r128_crtc->lut_g[i] = green[i] >> 8;
> + r128_crtc->lut_b[i] = blue[i] >> 8;
> + }
> +
> + r128_crtc_load_lut(crtc);
> +}
> +
> +static Bool r128_crtc_lock(xf86CrtcPtr crtc)
> +{
> + ScrnInfoPtr pScrn = crtc->scrn;
> + ScreenPtr pScreen = xf86ScrnToScreen(pScrn);
> + R128InfoPtr info = R128PTR(pScrn);
> +
> +#ifdef HAVE_XAA_H
> + if (info->accel) info->accel->Sync(pScrn);
> +#endif
> +#ifdef USE_EXA
> + if (info->ExaDriver) exaWaitSync(pScreen);
> +#endif
> +
> + return FALSE;
> +}
> +
> +static void r128_crtc_unlock(xf86CrtcPtr crtc)
> +{
> + ScrnInfoPtr pScrn = crtc->scrn;
> + ScreenPtr pScreen = xf86ScrnToScreen(pScrn);
> + R128InfoPtr info = R128PTR(pScrn);
> +
> +#ifdef HAVE_XAA_H
> + if (info->accel) info->accel->Sync(pScrn);
> +#endif
> +#ifdef USE_EXA
> + if (info->ExaDriver) exaWaitSync(pScreen);
> +#endif
> +}
> +
> +#ifdef HAVE_XAA_H
> +static FBLinearPtr r128_xf86AllocateOffscreenLinear(ScreenPtr pScreen, int length, int granularity,
> + MoveLinearCallbackProcPtr moveCB,
> + RemoveLinearCallbackProcPtr removeCB,
> + pointer privData)
> +{
> + FBLinearPtr linear;
> + int max_size;
> +
> + linear = xf86AllocateOffscreenLinear(pScreen, length, granularity, moveCB, removeCB, privData);
> + if (linear != NULL) return linear;
> +
> + /* The above allocation did not succeed, so purge unlocked stuff and try again. */
> + xf86QueryLargestOffscreenLinear(pScreen, &max_size, granularity, PRIORITY_EXTREME);
> +
> + if (max_size < length) return NULL;
> + xf86PurgeUnlockedOffscreenAreas(pScreen);
> +
> + linear = xf86AllocateOffscreenLinear(pScreen, length, granularity, moveCB, removeCB, privData);
> + return linear;
> +}
> +#endif
> +
> +static void *r128_crtc_shadow_allocate(xf86CrtcPtr crtc, int width, int height)
> +{
> + ScrnInfoPtr pScrn = crtc->scrn;
> + ScreenPtr pScreen = xf86ScrnToScreen(pScrn);
> + R128InfoPtr info = R128PTR(pScrn);
> +
> + R128CrtcPrivatePtr r128_crtc = crtc->driver_private;
> + unsigned long rotate_offset = 0;
> + unsigned long rotate_pitch;
> + int cpp = pScrn->bitsPerPixel / 8;
> + int align = 4096;
> + int size;
> +
> + rotate_pitch = pScrn->displayWidth * cpp;
> + size = rotate_pitch * height;
> +
> +#ifdef USE_EXA
> + if (info->ExaDriver) {
> + assert(r128_crtc->rotate_mem_exa == NULL);
> + r128_crtc->rotate_mem_exa = exaOffscreenAlloc(pScreen, size, align, TRUE, NULL, NULL);
> +
> + if (r128_crtc->rotate_mem_exa == NULL) {
> + xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
> + "Couldn't allocate shadow memory for rotated CRTC\n");
> + return NULL;
> + }
> +
> + rotate_offset = r128_crtc->rotate_mem_exa->offset;
> + }
> +#endif
> +#ifdef HAVE_XAA_H
> + if (info->accel) {
> + size = (size + cpp - 1) / cpp;
> + align = (align + cpp - 1) / cpp;
> +
> + assert(r128_crtc->rotate_mem_xaa == NULL);
> + r128_crtc->rotate_mem_xaa = r128_xf86AllocateOffscreenLinear(pScreen, size, align, NULL, NULL, NULL);
> +
> + if (r128_crtc->rotate_mem_exa == NULL) {
> + xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
> + "Couldn't allocate shadow memory for rotated CRTC\n");
> + return NULL;
> + }
> +
> + rotate_offset = r128_crtc->rotate_mem_xaa->offset * cpp;
> + }
> +#endif
> +
> + /* If allocations failed or if there was no accel. */
> + if (rotate_offset == 0)
> + return NULL;
> +
> + return info->FB + rotate_offset;
> +}
> +
> +static PixmapPtr r128_crtc_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height)
> +{
> + ScrnInfoPtr pScrn = crtc->scrn;
> + PixmapPtr rotate_pixmap;
> + unsigned long rotate_pitch;
> + int cpp = pScrn->bitsPerPixel / 8;
> +
> + if (!data) data = r128_crtc_shadow_allocate(crtc, width, height);
> +
> + rotate_pitch = pScrn->displayWidth * cpp;
> + rotate_pixmap = GetScratchPixmapHeader(xf86ScrnToScreen(pScrn),
> + width, height,
> + pScrn->depth,
> + pScrn->bitsPerPixel,
> + rotate_pitch,
> + data);
> +
> + if (rotate_pixmap == NULL) {
> + xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
> + "Couldn't allocate shadow memory for rotated CRTC\n");
> + return NULL;
> + }
> +
> + return rotate_pixmap;
> +}
> +
> +static void r128_crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data)
> +{
> + ScrnInfoPtr pScrn = crtc->scrn;
> + ScreenPtr pScreen = xf86ScrnToScreen(pScrn);
> + R128InfoPtr info = R128PTR(pScrn);
> +
> + R128CrtcPrivatePtr r128_crtc = crtc->driver_private;
> +
> + if (rotate_pixmap) FreeScratchPixmapHeader(rotate_pixmap);
> +
> + if (data) {
> +#ifdef USE_EXA
> + if (info->ExaDriver && r128_crtc->rotate_mem_exa != NULL) {
> + exaOffscreenFree(pScreen, r128_crtc->rotate_mem_exa);
> + r128_crtc->rotate_mem_exa = NULL;
> + }
> +#endif
> +#ifdef HAVE_XAA_H
> + if (info->accel) {
> + xf86FreeOffscreenLinear(r128_crtc->rotate_mem_xaa);
> + r128_crtc->rotate_mem_xaa = NULL;
> + }
> +#endif
> + }
> +}
> +
> +static const xf86CrtcFuncsRec r128_crtc_funcs = {
> + .dpms = r128_crtc_dpms,
> + .save = NULL,
> + .restore = NULL,
> + .mode_fixup = r128_crtc_mode_fixup,
> + .prepare = r128_crtc_mode_prepare,
> + .mode_set = r128_crtc_mode_set,
> + .commit = r128_crtc_mode_commit,
> + .gamma_set = r128_crtc_gamma_set,
> + .lock = r128_crtc_lock,
> + .unlock = r128_crtc_unlock,
> + .shadow_create = r128_crtc_shadow_create,
> + .shadow_allocate = r128_crtc_shadow_allocate,
> + .shadow_destroy = r128_crtc_shadow_destroy,
> + .set_cursor_colors = r128_crtc_set_cursor_colors,
> + .set_cursor_position = r128_crtc_set_cursor_position,
> + .show_cursor = r128_crtc_show_cursor,
> + .hide_cursor = r128_crtc_hide_cursor,
> + .load_cursor_image = r128_crtc_load_cursor_image,
> + .destroy = NULL,
> +};
> +
> +Bool R128AllocateControllers(ScrnInfoPtr pScrn, int mask)
> +{
> + R128EntPtr pR128Ent = R128EntPriv(pScrn);
> + R128InfoPtr info = R128PTR(pScrn);
> +
> + if (mask & 1) {
> + if (pR128Ent->Controller[0])
> + return TRUE;
> +
> + pR128Ent->pCrtc[0] = xf86CrtcCreate(pScrn, &r128_crtc_funcs);
> + if (!pR128Ent->pCrtc[0])
> + return FALSE;
> +
> + pR128Ent->Controller[0] = xnfcalloc(sizeof(R128CrtcPrivateRec), 1);
> + if (!pR128Ent->Controller[0])
> + return FALSE;
> +
> + pR128Ent->pCrtc[0]->driver_private = pR128Ent->Controller[0];
> + pR128Ent->Controller[0]->crtc_id = 0;
> + }
> +
> + if (mask & 2) {
> + if (!info->HasCRTC2)
> + return TRUE;
> +
> + pR128Ent->pCrtc[1] = xf86CrtcCreate(pScrn, &r128_crtc_funcs);
> + if (!pR128Ent->pCrtc[1])
> + return FALSE;
> +
> + pR128Ent->Controller[1] = xnfcalloc(sizeof(R128CrtcPrivateRec), 1);
> + if (!pR128Ent->Controller[1]) {
> + free(pR128Ent->Controller[0]);
> + return FALSE;
> + }
> +
> + pR128Ent->pCrtc[1]->driver_private = pR128Ent->Controller[1];
> + pR128Ent->Controller[1]->crtc_id = 1;
> + }
> +
> + return TRUE;
> +}
> +
> +void R128Blank(ScrnInfoPtr pScrn)
> +{
> + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
> + xf86OutputPtr output;
> + xf86CrtcPtr crtc;
> + int o, c;
> +
> + for (c = 0; c < xf86_config->num_crtc; c++) {
> + crtc = xf86_config->crtc[c];
> + for (o = 0; o < xf86_config->num_output; o++) {
> + output = xf86_config->output[o];
> + if (output->crtc != crtc)
> + continue;
> +
> + output->funcs->dpms(output, DPMSModeOff);
> + }
> + crtc->funcs->dpms(crtc, DPMSModeOff);
> + }
> +}
> +
> +void R128Unblank(ScrnInfoPtr pScrn)
> +{
> + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
> + xf86OutputPtr output;
> + xf86CrtcPtr crtc;
> + int o, c;
> +
> + for (c = 0; c < xf86_config->num_crtc; c++) {
> + crtc = xf86_config->crtc[c];
> + if (!crtc->enabled)
> + continue;
> + crtc->funcs->dpms(crtc, DPMSModeOn);
> + for (o = 0; o < xf86_config->num_output; o++) {
> + output = xf86_config->output[o];
> + if (output->crtc != crtc)
> + continue;
> +
> + output->funcs->dpms(output, DPMSModeOn);
> + }
> + }
> +}
> diff --git a/src/r128_cursor.c b/src/r128_cursor.c
> index b76913c..ad6752f 100644
> --- a/src/r128_cursor.c
> +++ b/src/r128_cursor.c
> @@ -59,6 +59,9 @@
> #include "exa.h"
> #endif
>
> +#define CURSOR_WIDTH 64
> +#define CURSOR_HEIGHT 64
> +
> #if X_BYTE_ORDER == X_BIG_ENDIAN
> #define P_SWAP32( a , b ) \
> ((char *)a)[0] = ((char *)b)[3]; \
> @@ -73,84 +76,121 @@
> ((char *)a)[3] = ((char *)b)[2]
> #endif
>
> +void r128_crtc_show_cursor(xf86CrtcPtr crtc)
> +{
> + ScrnInfoPtr pScrn = crtc->scrn;
> + R128CrtcPrivatePtr r128_crtc = crtc->driver_private;
> + R128InfoPtr info = R128PTR(pScrn);
> + unsigned char *R128MMIO = info->MMIO;
> + int crtc_id = r128_crtc->crtc_id;
> +
> + switch (crtc_id) {
> + case 0:
> + OUTREGP(R128_CRTC_GEN_CNTL, R128_CRTC_CUR_EN, ~R128_CRTC_CUR_EN);
> + break;
> + case 1:
> + OUTREGP(R128_CRTC2_GEN_CNTL, R128_CRTC2_CUR_EN, ~R128_CRTC2_CUR_EN);
> + break;
> + default:
> + return;
> + }
> +}
>
> -/* Set cursor foreground and background colors. */
> -static void R128SetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
> +void r128_crtc_hide_cursor(xf86CrtcPtr crtc)
> {
> - R128InfoPtr info = R128PTR(pScrn);
> + ScrnInfoPtr pScrn = crtc->scrn;
> + R128CrtcPrivatePtr r128_crtc = crtc->driver_private;
> + R128InfoPtr info = R128PTR(pScrn);
> unsigned char *R128MMIO = info->MMIO;
> + int crtc_id = r128_crtc->crtc_id;
>
> - if(info->IsSecondary)
> - {
> + switch (crtc_id) {
> + case 0:
> + OUTREGP(R128_CRTC_GEN_CNTL, 0, ~R128_CRTC_CUR_EN);
> + break;
> + case 1:
> + OUTREGP(R128_CRTC2_GEN_CNTL, 0, ~R128_CRTC2_CUR_EN);
> + break;
> + default:
> + return;
> + }
> +}
> +
> +void r128_crtc_set_cursor_colors(xf86CrtcPtr crtc, int bg, int fg)
> +{
> + ScrnInfoPtr pScrn = crtc->scrn;
> + R128CrtcPrivatePtr r128_crtc = crtc->driver_private;
> + R128InfoPtr info = R128PTR(pScrn);
> + unsigned char *R128MMIO = info->MMIO;
> + int crtc_id = r128_crtc->crtc_id;
> +
> + switch (crtc_id) {
> + case 0:
> + OUTREG(R128_CUR_CLR0, bg);
> + OUTREG(R128_CUR_CLR1, fg);
> + break;
> + case 1:
> OUTREG(R128_CUR2_CLR0, bg);
> OUTREG(R128_CUR2_CLR1, fg);
> - }
> - else
> - {
> - OUTREG(R128_CUR_CLR0, bg);
> - OUTREG(R128_CUR_CLR1, fg);
> + break;
> + default:
> + return;
> }
> }
>
> -/* Set cursor position to (x,y) with offset into cursor bitmap at
> - (xorigin,yorigin). */
> -static void R128SetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
> +void r128_crtc_set_cursor_position (xf86CrtcPtr crtc, int x, int y)
> {
> - R128InfoPtr info = R128PTR(pScrn);
> - unsigned char *R128MMIO = info->MMIO;
> - xf86CursorInfoPtr cursor = info->cursor;
> - int xorigin = 0;
> - int yorigin = 0;
> - int total_y = pScrn->frameY1 - pScrn->frameY0;
> -
> - if (x < 0) xorigin = -x;
> - if (y < 0) yorigin = -y;
> - if (y > total_y) y = total_y;
> - if (info->Flags & V_DBLSCAN) y *= 2;
> - if (xorigin >= cursor->MaxWidth) xorigin = cursor->MaxWidth - 1;
> - if (yorigin >= cursor->MaxHeight) yorigin = cursor->MaxHeight - 1;
> -
> - if(!info->IsSecondary)
> - {
> - OUTREG(R128_CUR_HORZ_VERT_OFF, R128_CUR_LOCK | (xorigin << 16) | yorigin);
> - OUTREG(R128_CUR_HORZ_VERT_POSN, (R128_CUR_LOCK
> - | ((xorigin ? 0 : x) << 16)
> - | (yorigin ? 0 : y)));
> - OUTREG(R128_CUR_OFFSET, info->cursor_start + yorigin * 16);
> - }
> - else
> - {
> - OUTREG(R128_CUR2_HORZ_VERT_OFF, (R128_CUR2_LOCK
> - | (xorigin << 16)
> - | yorigin));
> - OUTREG(R128_CUR2_HORZ_VERT_POSN, (R128_CUR2_LOCK
> - | ((xorigin ? 0 : x) << 16)
> - | (yorigin ? 0 : y)));
> - OUTREG(R128_CUR2_OFFSET,
> - info->cursor_start + pScrn->fbOffset + yorigin * 16);
> + ScrnInfoPtr pScrn = crtc->scrn;
> + R128InfoPtr info = R128PTR(pScrn);
> + R128CrtcPrivatePtr r128_crtc = crtc->driver_private;
> + unsigned char *R128MMIO = info->MMIO;
> + int crtc_id = r128_crtc->crtc_id;
> +
> + int xorigin = 0, yorigin = 0;
> + DisplayModePtr mode = &crtc->mode;
> +
> + if (x < 0) xorigin = -x + 1;
> + if (y < 0) yorigin = -y + 1;
> + if (xorigin >= CURSOR_WIDTH) xorigin = CURSOR_WIDTH - 1;
> + if (yorigin >= CURSOR_HEIGHT) yorigin = CURSOR_HEIGHT - 1;
> +
> + if (mode->Flags & V_INTERLACE)
> + y /= 2;
> + else if (mode->Flags & V_DBLSCAN)
> + y *= 2;
> +
> + if(crtc_id == 0) {
> + OUTREG(R128_CUR_HORZ_VERT_OFF, (R128_CUR_LOCK | (xorigin << 16) | yorigin));
> + OUTREG(R128_CUR_HORZ_VERT_POSN, (R128_CUR_LOCK | ((xorigin ? 0 : x) << 16) | (yorigin ? 0 : y)));
> + OUTREG(R128_CUR_OFFSET, r128_crtc->cursor_offset + pScrn->fbOffset + yorigin * 16);
> + } else if (crtc_id == 1) {
> + OUTREG(R128_CUR2_HORZ_VERT_OFF, (R128_CUR2_LOCK | (xorigin << 16) | yorigin));
> + OUTREG(R128_CUR2_HORZ_VERT_POSN, (R128_CUR2_LOCK | ((xorigin ? 0 : x) << 16) | (yorigin ? 0 : y)));
> + OUTREG(R128_CUR2_OFFSET, r128_crtc->cursor_offset + pScrn->fbOffset + yorigin * 16);
> }
> }
>
> -/* Copy cursor image from `image' to video memory. R128SetCursorPosition
> - will be called after this, so we can ignore xorigin and yorigin. */
> -static void R128LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *image)
> +void r128_crtc_load_cursor_image(xf86CrtcPtr crtc, unsigned char *src)
> {
> + ScrnInfoPtr pScrn = crtc->scrn;
> + R128CrtcPrivatePtr r128_crtc = crtc->driver_private;
> + int crtc_id = r128_crtc->crtc_id;
> +
> +
> R128InfoPtr info = R128PTR(pScrn);
> unsigned char *R128MMIO = info->MMIO;
> - CARD32 *s = (pointer)image;
> - CARD32 *d = (pointer)((CARD8*)info->FB + info->cursor_start);
> + CARD32 *s = (pointer)src;
> + CARD32 *d = (pointer)(info->FB + r128_crtc->cursor_offset + pScrn->fbOffset);
> + CARD32 save1 = 0;
> + CARD32 save2 = 0;
> int y;
> - CARD32 save;
>
> - if(!info->IsSecondary)
> - {
> - save = INREG(R128_CRTC_GEN_CNTL);
> - OUTREG(R128_CRTC_GEN_CNTL, save & (CARD32)~R128_CRTC_CUR_EN);
> - }
> - else
> - {
> - save = INREG(R128_CRTC2_GEN_CNTL);
> - OUTREG(R128_CRTC2_GEN_CNTL, save & (CARD32)~R128_CRTC2_CUR_EN);
> + if (crtc_id == 0) {
> + save1 = INREG(R128_CRTC_GEN_CNTL);
> + OUTREG(R128_CRTC_GEN_CNTL, save1 & (CARD32)~R128_CRTC_CUR_EN);
> + } else if (crtc_id == 1) {
> + save2 = INREG(R128_CRTC2_GEN_CNTL);
> + OUTREG(R128_CRTC2_GEN_CNTL, save2 & (CARD32)~R128_CRTC2_CUR_EN);
> }
>
> #if X_BYTE_ORDER == X_BIG_ENDIAN
> @@ -197,59 +237,10 @@ static void R128LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *image)
> }
> #endif
>
> - /* Set the area after the cursor to be all transparent so that we
> - won't display corrupted cursors on the screen */
> - for (y = 0; y < 64; y++) {
> - *d++ = 0xffffffff; /* The AND bits */
> - *d++ = 0xffffffff;
> - *d++ = 0x00000000; /* The XOR bits */
> - *d++ = 0x00000000;
> - }
> -
> -
> - if(!info->IsSecondary)
> - OUTREG(R128_CRTC_GEN_CNTL, save);
> + if (crtc_id == 0)
> + OUTREG(R128_CRTC_GEN_CNTL, save1);
> else
> - OUTREG(R128_CRTC2_GEN_CNTL, save);
> -
> -}
> -
> -/* Hide hardware cursor. */
> -static void R128HideCursor(ScrnInfoPtr pScrn)
> -{
> - R128InfoPtr info = R128PTR(pScrn);
> - unsigned char *R128MMIO = info->MMIO;
> -
> - if(info->IsSecondary)
> - OUTREGP(R128_CRTC2_GEN_CNTL, 0, ~R128_CRTC2_CUR_EN);
> - else
> - OUTREGP(R128_CRTC_GEN_CNTL, 0, ~R128_CRTC_CUR_EN);
> -}
> -
> -/* Show hardware cursor. */
> -static void R128ShowCursor(ScrnInfoPtr pScrn)
> -{
> - R128InfoPtr info = R128PTR(pScrn);
> - unsigned char *R128MMIO = info->MMIO;
> -
> - if(info->IsSecondary)
> - {
> - OUTREGP(R128_CRTC2_GEN_CNTL, R128_CRTC2_CUR_EN,
> - ~R128_CRTC2_CUR_EN);
> - }
> - else
> - {
> - OUTREGP(R128_CRTC_GEN_CNTL, R128_CRTC_CUR_EN, ~R128_CRTC_CUR_EN);
> - }
> -}
> -
> -/* Determine if hardware cursor is in use. */
> -static Bool R128UseHWCursor(ScreenPtr pScreen, CursorPtr pCurs)
> -{
> - ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
> - R128InfoPtr info = R128PTR(pScrn);
> -
> - return info->cursor_start ? TRUE : FALSE;
> + OUTREG(R128_CRTC2_GEN_CNTL, save2);
> }
>
> /* Initialize hardware cursor support. */
> @@ -257,77 +248,72 @@ Bool R128CursorInit(ScreenPtr pScreen)
> {
> ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
> R128InfoPtr info = R128PTR(pScrn);
> - xf86CursorInfoPtr cursor;
> FBAreaPtr fbarea = NULL;
> #ifdef USE_EXA
> ExaOffscreenArea* osArea = NULL;
> #else
> void* osArea = NULL;
> #endif
> + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
> + CARD32 cursor_offset = 0;
> + int cpp = info->CurrentLayout.pixel_bytes;
> int width;
> + int width_bytes;
> int height;
> int size;
> + int size_bytes;
> + int c;
>
> - int cpp = info->CurrentLayout.pixel_bytes;
> -
> - if (!(cursor = info->cursor = xf86CreateCursorInfoRec())) return FALSE;
> -
> - cursor->MaxWidth = 64;
> - cursor->MaxHeight = 64;
> - cursor->Flags = (HARDWARE_CURSOR_TRUECOLOR_AT_8BPP
> - | HARDWARE_CURSOR_SHOW_TRANSPARENT
> - | HARDWARE_CURSOR_UPDATE_UNHIDDEN
> -#if X_BYTE_ORDER == X_LITTLE_ENDIAN
> - | HARDWARE_CURSOR_BIT_ORDER_MSBFIRST
> -#endif
> - | HARDWARE_CURSOR_INVERT_MASK
> - | HARDWARE_CURSOR_AND_SOURCE_WITH_MASK
> - | HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64
> - | HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK);
> -
> - cursor->SetCursorColors = R128SetCursorColors;
> - cursor->SetCursorPosition = R128SetCursorPosition;
> - cursor->LoadCursorImage = R128LoadCursorImage;
> - cursor->HideCursor = R128HideCursor;
> - cursor->ShowCursor = R128ShowCursor;
> - cursor->UseHWCursor = R128UseHWCursor;
> -
> - size = (cursor->MaxWidth/4) * cursor->MaxHeight;
> + size = CURSOR_WIDTH * CURSOR_HEIGHT / 4;
> + size_bytes = size * 2;
> width = pScrn->displayWidth;
> - height = (size*2 + 1023) / pScrn->displayWidth;
> + width_bytes = width * (pScrn->bitsPerPixel / 8);
> + height = ((size_bytes * xf86_config->num_crtc) + width_bytes - 1) / width_bytes;
>
> if(!info->useEXA) {
> fbarea = xf86AllocateOffscreenArea(pScreen, width, height,
> 16, NULL, NULL, NULL);
>
> - if (fbarea) {
> - info->cursor_start = R128_ALIGN((fbarea->box.x1
> - + width * fbarea->box.y1)
> - * cpp, 16);
> - info->cursor_end = info->cursor_start + size;
> - }
> + if (fbarea)
> + cursor_offset = R128_ALIGN((fbarea->box.x1 + width * fbarea->box.y1) * cpp, 16);
> }
> #ifdef USE_EXA
> else {
> osArea = exaOffscreenAlloc(pScreen, width * height, 16,
> TRUE, NULL, NULL);
>
> - if (osArea) {
> - info->cursor_start = osArea->offset;
> - info->cursor_end = osArea->offset + osArea->size;
> - }
> + if (osArea)
> + cursor_offset = osArea->offset;
> }
> #endif
>
> if ((!info->useEXA && !fbarea) || (info->useEXA && !osArea)) {
> - info->cursor_start = 0;
> xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
> "Hardware cursor disabled"
> " due to insufficient offscreen memory\n");
> + return FALSE;
> + } else {
> + for (c = 0; c < xf86_config->num_crtc; c++) {
> + xf86CrtcPtr crtc = xf86_config->crtc[c];
> + R128CrtcPrivatePtr r128_crtc = crtc->driver_private;
> +
> + r128_crtc->cursor_offset = cursor_offset + (c * size);
> + xf86DrvMsg(pScrn->scrnIndex, X_INFO,
> + "Will use %d kb for hardware cursor %d at offset 0x%08x\n",
> + (size_bytes * xf86_config->num_crtc) / 1024, c,
> + (unsigned int)r128_crtc->cursor_offset);
> + }
> }
>
> - R128TRACE(("R128CursorInit (0x%08x-0x%08x)\n",
> - info->cursor_start, info->cursor_end));
> -
> - return xf86InitCursor(pScreen, cursor);
> + return xf86_cursors_init(pScreen, CURSOR_WIDTH, CURSOR_HEIGHT,
> + (HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
> + HARDWARE_CURSOR_AND_SOURCE_WITH_MASK |
> + HARDWARE_CURSOR_SHOW_TRANSPARENT |
> + HARDWARE_CURSOR_UPDATE_UNHIDDEN |
> +#if X_BYTE_ORDER == X_LITTLE_ENDIAN
> + HARDWARE_CURSOR_BIT_ORDER_MSBFIRST |
> +#endif
> + HARDWARE_CURSOR_INVERT_MASK |
> + HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK |
> + HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64));
> }
> diff --git a/src/r128_driver.c b/src/r128_driver.c
> index f425c3b..9205328 100644
> --- a/src/r128_driver.c
> +++ b/src/r128_driver.c
> @@ -84,6 +84,7 @@
> /* X and server generic header files */
> #include "xf86.h"
> #include "xf86_OSproc.h"
> +#include "xf86RandR12.h"
> #if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 6
> #include "xf86RAC.h"
> #include "xf86Resources.h"
> @@ -119,11 +120,6 @@ static Bool R128CloseScreen(CLOSE_SCREEN_ARGS_DECL);
> static Bool R128SaveScreen(ScreenPtr pScreen, int mode);
> static void R128Save(ScrnInfoPtr pScrn);
> static void R128Restore(ScrnInfoPtr pScrn);
> -static Bool R128ModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode);
> -static void R128DisplayPowerManagementSet(ScrnInfoPtr pScrn,
> - int PowerManagementMode, int flags);
> -static void R128DisplayPowerManagementSetLCD(ScrnInfoPtr pScrn,
> - int PowerManagementMode, int flags);
>
> typedef enum {
> OPTION_NOACCEL,
> @@ -258,6 +254,7 @@ static Bool R128MapMMIO(ScrnInfoPtr pScrn)
> info->PciTag,
> info->MMIOAddr,
> R128_MMIOSIZE);
> + if (!info->MMIO) return FALSE;
> #else
> int err = pci_device_map_range(info->PciInfo,
> info->MMIOAddr,
> @@ -274,7 +271,6 @@ static Bool R128MapMMIO(ScrnInfoPtr pScrn)
> #endif
> }
>
> - if (!info->MMIO) return FALSE;
> return TRUE;
> }
>
> @@ -402,78 +398,6 @@ void R128WaitForVerticalSync(ScrnInfoPtr pScrn)
> }
> }
>
> -/* Blank screen. */
> -static void R128Blank(ScrnInfoPtr pScrn)
> -{
> - R128InfoPtr info = R128PTR(pScrn);
> - unsigned char *R128MMIO = info->MMIO;
> -
> - if(!info->IsSecondary)
> - {
> - switch(info->DisplayType)
> - {
> - case MT_LCD:
> - OUTREGP(R128_LVDS_GEN_CNTL, R128_LVDS_DISPLAY_DIS,
> - ~R128_LVDS_DISPLAY_DIS);
> - break;
> - case MT_CRT:
> - OUTREGP(R128_CRTC_EXT_CNTL, R128_CRTC_DISPLAY_DIS, ~R128_CRTC_DISPLAY_DIS);
> - break;
> - case MT_DFP:
> - OUTREGP(R128_FP_GEN_CNTL, R128_FP_BLANK_DIS, ~R128_FP_BLANK_DIS);
> - break;
> - case MT_NONE:
> - default:
> - break;
> - }
> - }
> - else
> - {
> - OUTREGP(R128_CRTC2_GEN_CNTL, R128_CRTC2_DISP_DIS, ~R128_CRTC2_DISP_DIS);
> - }
> -}
> -
> -/* Unblank screen. */
> -static void R128Unblank(ScrnInfoPtr pScrn)
> -{
> - R128InfoPtr info = R128PTR(pScrn);
> - unsigned char *R128MMIO = info->MMIO;
> -
> - if(!info->IsSecondary)
> - {
> - switch(info->DisplayType)
> - {
> - case MT_LCD:
> - OUTREGP(R128_LVDS_GEN_CNTL, 0,
> - ~R128_LVDS_DISPLAY_DIS);
> - break;
> - case MT_CRT:
> - OUTREGP(R128_CRTC_EXT_CNTL, 0, ~R128_CRTC_DISPLAY_DIS);
> - break;
> - case MT_DFP:
> - OUTREGP(R128_FP_GEN_CNTL, 0, ~R128_FP_BLANK_DIS);
> - break;
> - case MT_NONE:
> - default:
> - break;
> - }
> - }
> - else
> - {
> - switch(info->DisplayType)
> - {
> - case MT_LCD:
> - case MT_DFP:
> - case MT_CRT:
> - OUTREGP(R128_CRTC2_GEN_CNTL, 0, ~R128_CRTC2_DISP_DIS);
> - break;
> - case MT_NONE:
> - default:
> - break;
> - }
> - }
> -}
> -
> /* Compute log base 2 of val. */
> int R128MinBits(int val)
> {
> @@ -1058,9 +982,9 @@ static Bool R128PreInitConfig(ScrnInfoPtr pScrn)
> xf86DrvMsg(pScrn->scrnIndex, X_INFO,
> "Option \"Display\" ignored "
> "(framebuffer device determines display type)\n");
> - else if (info->IsPrimary || info->IsSecondary)
> + else if (!Display)
> info->BIOSDisplay = R128_DUALHEAD;
> - else if (!Display || !xf86NameCmp(Display, "FP"))
> + else if (!xf86NameCmp(Display, "FP"))
> info->BIOSDisplay = R128_BIOS_DISPLAY_FP;
> else if (!xf86NameCmp(Display, "BIOS"))
> info->BIOSDisplay = INREG8(R128_BIOS_5_SCRATCH);
> @@ -1079,9 +1003,6 @@ static Bool R128PreInitConfig(ScrnInfoPtr pScrn)
> info->BIOSDisplay = R128_BIOS_DISPLAY_CRT;
> }
>
> - R128MMIO = NULL;
> - R128UnmapMMIO(pScrn);
> -
> /* RAM */
> switch (info->MemCntl & 0x3) {
> case 0: /* SDR SGRAM 1:1 */
> @@ -1256,6 +1177,7 @@ static Bool R128PreInitDDC(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10)
> #endif
>
> if (!xf86LoadSubModule(pScrn, "ddc")) return FALSE;
> + if (!xf86LoadSubModule(pScrn, "i2c")) return FALSE;
>
> #if defined(__powerpc__) || defined(__alpha__) || defined(__sparc__)
> /* Int10 is broken on PPC and some Alphas */
> @@ -1281,468 +1203,6 @@ static Bool R128PreInitGamma(ScrnInfoPtr pScrn)
> return TRUE;
> }
>
> -static void
> -R128I2CGetBits(I2CBusPtr b, int *Clock, int *data)
> -{
> - ScrnInfoPtr pScrn = xf86Screens[b->scrnIndex];
> - R128InfoPtr info = R128PTR(pScrn);
> - unsigned long val;
> - unsigned char *R128MMIO = info->MMIO;
> -
> - /* Get the result. */
> - val = INREG(info->DDCReg);
> - *Clock = (val & R128_GPIO_MONID_Y_3) != 0;
> - *data = (val & R128_GPIO_MONID_Y_0) != 0;
> -
> -}
> -
> -static void
> -R128I2CPutBits(I2CBusPtr b, int Clock, int data)
> -{
> - ScrnInfoPtr pScrn = xf86Screens[b->scrnIndex];
> - R128InfoPtr info = R128PTR(pScrn);
> - unsigned long val;
> - unsigned char *R128MMIO = info->MMIO;
> -
> - val = INREG(info->DDCReg)
> - & ~(CARD32)(R128_GPIO_MONID_EN_0 | R128_GPIO_MONID_EN_3);
> - val |= (Clock ? 0:R128_GPIO_MONID_EN_3);
> - val |= (data ? 0:R128_GPIO_MONID_EN_0);
> - OUTREG(info->DDCReg, val);
> -}
> -
> -
> -static Bool
> -R128I2cInit(ScrnInfoPtr pScrn)
> -{
> - R128InfoPtr info = R128PTR(pScrn);
> - if ( !xf86LoadSubModule(pScrn, "i2c") ) {
> - xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
> - "Failed to load i2c module\n");
> - return FALSE;
> - }
> -
> - info->pI2CBus = xf86CreateI2CBusRec();
> - if(!info->pI2CBus) return FALSE;
> -
> - info->pI2CBus->BusName = "DDC";
> - info->pI2CBus->scrnIndex = pScrn->scrnIndex;
> - info->DDCReg = R128_GPIO_MONID;
> - info->pI2CBus->I2CPutBits = R128I2CPutBits;
> - info->pI2CBus->I2CGetBits = R128I2CGetBits;
> - info->pI2CBus->AcknTimeout = 5;
> -
> - if (!xf86I2CBusInit(info->pI2CBus)) {
> - return FALSE;
> - }
> - return TRUE;
> -}
> -
> -/* return TRUE is a DFP is indeed connected to a DVI port */
> -static Bool R128GetDFPInfo(ScrnInfoPtr pScrn)
> -{
> - R128InfoPtr info = R128PTR(pScrn);
> - int i;
> - xf86MonPtr MonInfo = NULL;
> - xf86MonPtr ddc;
> - unsigned char *R128MMIO = info->MMIO;
> -
> - if(!R128I2cInit(pScrn)){
> - xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
> - "I2C initialization failed!\n");
> - }
> -
> - OUTREG(info->DDCReg, (INREG(info->DDCReg)
> - | R128_GPIO_MONID_MASK_0 | R128_GPIO_MONID_MASK_3));
> -
> - OUTREG(info->DDCReg, INREG(info->DDCReg)
> - & ~(CARD32)(R128_GPIO_MONID_A_0 | R128_GPIO_MONID_A_3));
> -
> - MonInfo = xf86DoEDID_DDC2(XF86_SCRN_ARG(pScrn), info->pI2CBus);
> - if(!MonInfo) {
> - xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
> - "No DFP detected\n");
> - return FALSE;
> - }
> - xf86SetDDCproperties(pScrn, MonInfo);
> - ddc = pScrn->monitor->DDC;
> -
> - for(i=0; i<4; i++)
> - {
> - if((ddc->det_mon[i].type == 0) &&
> - (ddc->det_mon[i].section.d_timings.h_active > 0) &&
> - (ddc->det_mon[i].section.d_timings.v_active > 0))
> - {
> - info->PanelXRes =
> - ddc->det_mon[i].section.d_timings.h_active;
> - info->PanelYRes =
> - ddc->det_mon[i].section.d_timings.v_active;
> -
> - info->HOverPlus =
> - ddc->det_mon[i].section.d_timings.h_sync_off;
> - info->HSyncWidth =
> - ddc->det_mon[i].section.d_timings.h_sync_width;
> - info->HBlank =
> - ddc->det_mon[i].section.d_timings.h_blanking;
> - info->VOverPlus =
> - ddc->det_mon[i].section.d_timings.v_sync_off;
> - info->VSyncWidth =
> - ddc->det_mon[i].section.d_timings.v_sync_width;
> - info->VBlank =
> - ddc->det_mon[i].section.d_timings.v_blanking;
> - }
> - }
> - return TRUE;
> -}
> -
> -
> -static void R128SetSyncRangeFromEdid(ScrnInfoPtr pScrn, int flag)
> -{
> - int i;
> - xf86MonPtr ddc = pScrn->monitor->DDC;
> - if(flag) /*HSync*/
> - {
> - for(i=0; i<4; i++)
> - {
> - if(ddc->det_mon[i].type == DS_RANGES)
> - {
> - pScrn->monitor->nHsync = 1;
> - pScrn->monitor->hsync[0].lo =
> - ddc->det_mon[i].section.ranges.min_h;
> - pScrn->monitor->hsync[0].hi =
> - ddc->det_mon[i].section.ranges.max_h;
> - return;
> - }
> - }
> - /*if no sync ranges detected in detailed timing table,
> - let's try to derive them from supported VESA modes
> - Are we doing too much here!!!?
> - **/
> - i = 0;
> - if(ddc->timings1.t1 & 0x02) /*800x600 at 56*/
> - {
> - pScrn->monitor->hsync[i].lo =
> - pScrn->monitor->hsync[i].hi = 35.2;
> - i++;
> - }
> - if(ddc->timings1.t1 & 0x04) /*640x480 at 75*/
> - {
> - pScrn->monitor->hsync[i].lo =
> - pScrn->monitor->hsync[i].hi = 37.5;
> - i++;
> - }
> - if((ddc->timings1.t1 & 0x08) || (ddc->timings1.t1 & 0x01))
> - {
> - pScrn->monitor->hsync[i].lo =
> - pScrn->monitor->hsync[i].hi = 37.9;
> - i++;
> - }
> - if(ddc->timings1.t2 & 0x40)
> - {
> - pScrn->monitor->hsync[i].lo =
> - pScrn->monitor->hsync[i].hi = 46.9;
> - i++;
> - }
> - if((ddc->timings1.t2 & 0x80) || (ddc->timings1.t2 & 0x08))
> - {
> - pScrn->monitor->hsync[i].lo =
> - pScrn->monitor->hsync[i].hi = 48.1;
> - i++;
> - }
> - if(ddc->timings1.t2 & 0x04)
> - {
> - pScrn->monitor->hsync[i].lo =
> - pScrn->monitor->hsync[i].hi = 56.5;
> - i++;
> - }
> - if(ddc->timings1.t2 & 0x02)
> - {
> - pScrn->monitor->hsync[i].lo =
> - pScrn->monitor->hsync[i].hi = 60.0;
> - i++;
> - }
> - if(ddc->timings1.t2 & 0x01)
> - {
> - pScrn->monitor->hsync[i].lo =
> - pScrn->monitor->hsync[i].hi = 64.0;
> - i++;
> - }
> - pScrn->monitor->nHsync = i;
> - }
> - else /*Vrefresh*/
> - {
> - for(i=0; i<4; i++)
> - {
> - if(ddc->det_mon[i].type == DS_RANGES)
> - {
> - pScrn->monitor->nVrefresh = 1;
> - pScrn->monitor->vrefresh[0].lo =
> - ddc->det_mon[i].section.ranges.min_v;
> - pScrn->monitor->vrefresh[0].hi =
> - ddc->det_mon[i].section.ranges.max_v;
> - return;
> - }
> - }
> - i = 0;
> - if(ddc->timings1.t1 & 0x02) /*800x600 at 56*/
> - {
> - pScrn->monitor->vrefresh[i].lo =
> - pScrn->monitor->vrefresh[i].hi = 56;
> - i++;
> - }
> - if((ddc->timings1.t1 & 0x01) || (ddc->timings1.t2 & 0x08))
> - {
> - pScrn->monitor->vrefresh[i].lo =
> - pScrn->monitor->vrefresh[i].hi = 60;
> - i++;
> - }
> - if(ddc->timings1.t2 & 0x04)
> - {
> - pScrn->monitor->vrefresh[i].lo =
> - pScrn->monitor->vrefresh[i].hi = 70;
> - i++;
> - }
> - if((ddc->timings1.t1 & 0x08) || (ddc->timings1.t2 & 0x80))
> - {
> - pScrn->monitor->vrefresh[i].lo =
> - pScrn->monitor->vrefresh[i].hi = 72;
> - i++;
> - }
> - if((ddc->timings1.t1 & 0x04) || (ddc->timings1.t2 & 0x40)
> - || (ddc->timings1.t2 & 0x02) || (ddc->timings1.t2 & 0x01))
> - {
> - pScrn->monitor->vrefresh[i].lo =
> - pScrn->monitor->vrefresh[i].hi = 75;
> - i++;
> - }
> - pScrn->monitor->nVrefresh = i;
> - }
> -}
> -
> -/***********
> - free's xf86ValidateModes routine deosn't work well with DFPs
> - here is our own validation routine. All modes between
> - 640<=XRes<=MaxRes and 480<=YRes<=MaxYRes will be permitted.
> - NOTE: RageProII doesn't support rmx, can only work with the
> - standard modes the monitor can support (scale).
> -************/
> -
> -static int R128ValidateFPModes(ScrnInfoPtr pScrn)
> -{
> - int i, j, count=0, width, height;
> - R128InfoPtr info = R128PTR(pScrn);
> - DisplayModePtr last = NULL, new = NULL, first = NULL;
> - xf86MonPtr ddc;
> -
> - /* Free any allocated modes during configuration. We don't need them*/
> - while (pScrn->modes)
> - {
> - xf86DeleteMode(&pScrn->modes, pScrn->modes);
> - }
> - while (pScrn->modePool)
> - {
> - xf86DeleteMode(&pScrn->modePool, pScrn->modePool);
> - }
> -
> - pScrn->virtualX = pScrn->display->virtualX;
> - pScrn->virtualY = pScrn->display->virtualY;
> -
> - /* If no mode specified in config, we use native resolution*/
> - if(!pScrn->display->modes[0])
> - {
> - pScrn->display->modes[0] = xnfalloc(16);
> - sprintf(pScrn->display->modes[0], "%dx%d",
> - info->PanelXRes, info->PanelYRes);
> - }
> -
> - for(i=0; pScrn->display->modes[i] != NULL; i++)
> - {
> - if (sscanf(pScrn->display->modes[i], "%dx%d", &width, &height) == 2)
> - {
> -
> - if(width < 640 || width > info->PanelXRes ||
> - height < 480 || height > info->PanelYRes)
> - {
> - xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
> - "Mode %s is out of range.\n"
> - "Valid mode should be between 640x480-%dx%d\n",
> - pScrn->display->modes[i], info->PanelXRes, info->PanelYRes);
> - continue;
> - }
> -
> - new = xnfcalloc(1, sizeof(DisplayModeRec));
> - new->prev = last;
> - new->name = xnfalloc(strlen(pScrn->display->modes[i]) + 1);
> - strcpy(new->name, pScrn->display->modes[i]);
> - new->HDisplay = new->CrtcHDisplay = width;
> - new->VDisplay = new->CrtcVDisplay = height;
> -
> - ddc = pScrn->monitor->DDC;
> - for(j=0; j<DET_TIMINGS; j++)
> - {
> - /*We use native mode clock only*/
> - if(ddc->det_mon[j].type == 0){
> - new->Clock = ddc->det_mon[j].section.d_timings.clock / 1000;
> - break;
> - }
> - }
> -
> - if(new->prev) new->prev->next = new;
> - last = new;
> - if(!first) first = new;
> - pScrn->display->virtualX =
> - pScrn->virtualX = MAX(pScrn->virtualX, width);
> - pScrn->display->virtualY =
> - pScrn->virtualY = MAX(pScrn->virtualY, height);
> - count++;
> - }
> - else
> - {
> - xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
> - "Mode name %s is invalid\n", pScrn->display->modes[i]);
> - continue;
> - }
> - }
> -
> - if(last)
> - {
> - last->next = first;
> - first->prev = last;
> - pScrn->modes = first;
> -
> - /*FIXME: May need to validate line pitch here*/
> - {
> - int dummy = 0;
> - switch(pScrn->depth / 8)
> - {
> - case 1:
> - dummy = 128 - pScrn->virtualX % 128;
> - break;
> - case 2:
> - dummy = 32 - pScrn->virtualX % 32;
> - break;
> - case 3:
> - case 4:
> - dummy = 16 - pScrn->virtualX % 16;
> - }
> - pScrn->displayWidth = pScrn->virtualX + dummy;
> - }
> -
> - }
> -
> - return count;
> -}
> -
> -
> -/* This is called by R128PreInit to validate modes and compute parameters
> - for all of the valid modes. */
> -static Bool R128PreInitModes(ScrnInfoPtr pScrn)
> -{
> - R128InfoPtr info = R128PTR(pScrn);
> - ClockRangePtr clockRanges;
> - int modesFound;
> -
> - if(info->isDFP) {
> - R128MapMem(pScrn);
> - info->BIOSDisplay = R128_BIOS_DISPLAY_FP;
> - /* validate if DFP really connected. */
> - if(!R128GetDFPInfo(pScrn)) {
> - info->isDFP = FALSE;
> - info->BIOSDisplay = R128_BIOS_DISPLAY_CRT;
> - } else if(!info->isPro2) {
> - /* RageProII doesn't support rmx, we can't use native-mode
> - stretching for other non-native modes. It will rely on
> - whatever VESA modes monitor can support. */
> - modesFound = R128ValidateFPModes(pScrn);
> - if(modesFound < 1) {
> - xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
> - "No valid mode found for this DFP/LCD\n");
> - R128UnmapMem(pScrn);
> - return FALSE;
> -
> - }
> - }
> - R128UnmapMem(pScrn);
> - }
> -
> - if(!info->isDFP || info->isPro2) {
> - /* Get mode information */
> - pScrn->progClock = TRUE;
> - clockRanges = xnfcalloc(sizeof(*clockRanges), 1);
> - clockRanges->next = NULL;
> - clockRanges->minClock = info->pll.min_pll_freq;
> - clockRanges->maxClock = info->pll.max_pll_freq * 10;
> - clockRanges->clockIndex = -1;
> - if (info->HasPanelRegs || info->isDFP) {
> - clockRanges->interlaceAllowed = FALSE;
> - clockRanges->doubleScanAllowed = FALSE;
> - } else {
> - clockRanges->interlaceAllowed = TRUE;
> - clockRanges->doubleScanAllowed = TRUE;
> - }
> -
> - if(pScrn->monitor->DDC) {
> - /*if we still don't know sync range yet, let's try EDID.
> - Note that, since we can have dual heads, the Xconfigurator
> - may not be able to probe both monitors correctly through
> - vbe probe function (R128ProbeDDC). Here we provide an
> - additional way to auto-detect sync ranges if they haven't
> - been added to XF86Config manually.
> - **/
> - if(pScrn->monitor->nHsync <= 0)
> - R128SetSyncRangeFromEdid(pScrn, 1);
> - if(pScrn->monitor->nVrefresh <= 0)
> - R128SetSyncRangeFromEdid(pScrn, 0);
> - }
> -
> - modesFound = xf86ValidateModes(pScrn,
> - pScrn->monitor->Modes,
> - pScrn->display->modes,
> - clockRanges,
> - NULL, /* linePitches */
> - 8 * 64, /* minPitch */
> - 8 * 1024, /* maxPitch */
> -/*
> - * ATI docs say pitchInc must be 8 * 64, but this doesn't permit a pitch of
> - * 800 bytes, which is known to work on the Rage128 LF on clamshell iBooks
> - */
> - 8 * 32, /* pitchInc */
> - 128, /* minHeight */
> - 2048, /* maxHeight */
> - pScrn->display->virtualX,
> - pScrn->display->virtualY,
> - info->FbMapSize,
> - LOOKUP_BEST_REFRESH);
> -
> - if (modesFound < 1 && info->FBDev) {
> - fbdevHWUseBuildinMode(pScrn);
> - pScrn->displayWidth = fbdevHWGetLineLength(pScrn)/(pScrn->bitsPerPixel/8);
> - modesFound = 1;
> - }
> -
> - if (modesFound == -1) return FALSE;
> - xf86PruneDriverModes(pScrn);
> - if (!modesFound || !pScrn->modes) {
> - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n");
> - return FALSE;
> - }
> - xf86SetCrtcForModes(pScrn, 0);
> - }
> - /* Set DPI */
> - pScrn->currentMode = pScrn->modes;
> - xf86PrintModes(pScrn);
> -
> - xf86SetDpi(pScrn, 0, 0);
> -
> - /* Get ScreenInit function */
> - if (!xf86LoadSubModule(pScrn, "fb")) return FALSE;
> -
> - info->CurrentLayout.displayWidth = pScrn->displayWidth;
> - info->CurrentLayout.mode = pScrn->currentMode;
> -
> - return TRUE;
> -}
> -
> /* This is called by R128PreInit to initialize the hardware cursor. */
> static Bool R128PreInitCursor(ScrnInfoPtr pScrn)
> {
> @@ -1885,6 +1345,43 @@ static Bool R128PreInitDRI(ScrnInfoPtr pScrn)
> }
> #endif
>
> +static Bool R128PreInitControllers(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10)
> +{
> + R128InfoPtr info = R128PTR(pScrn);
> + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
> + int i;
> + int mask;
> + int found = 0;
> +
> + if (info->IsPrimary)
> + mask = 1;
> + else if (info->IsSecondary)
> + mask = 2;
> + else
> + mask = 3;
> +
> + if (!R128GetBIOSParameters(pScrn, pInt10))
> + return FALSE;
> +
> + if (!R128GetPLLParameters(pScrn))
> + return FALSE;
> +
> + if (!R128AllocateControllers(pScrn, mask))
> + return FALSE;
> +
> + if (!R128SetupConnectors(pScrn))
> + return FALSE;
> +
> + for (i = 0; i < config->num_output; i++) {
> + xf86OutputPtr output = config->output[i];
> +
> + output->status = (*output->funcs->detect) (output);
> + if (output->status == XF86OutputStatusConnected)
> + found++;
> + }
> + return !!found;
> +}
> +
> static void
> R128ProbeDDC(ScrnInfoPtr pScrn, int indx)
> {
> @@ -1899,6 +1396,17 @@ R128ProbeDDC(ScrnInfoPtr pScrn, int indx)
> #endif
> }
>
> +static Bool R128CRTCResize(ScrnInfoPtr pScrn, int width, int height)
> +{
> + pScrn->virtualX = width;
> + pScrn->virtualY = height;
> + return TRUE;
> +}
> +
> +static const xf86CrtcConfigFuncsRec R128CRTCResizeFuncs = {
> + R128CRTCResize
> +};
> +
> /* R128PreInit is called once at server startup. */
> Bool R128PreInit(ScrnInfoPtr pScrn, int flags)
> {
> @@ -1976,6 +1484,9 @@ Bool R128PreInit(ScrnInfoPtr pScrn, int flags)
> #endif
> pScrn->monitor = pScrn->confScreen->monitor;
>
> + /* Allocate an xf86CrtcConfig */
> + xf86CrtcConfigInit(pScrn, &R128CRTCResizeFuncs);
> +
> if (!R128PreInitVisual(pScrn)) goto fail;
>
> /* We can't do this until we have a
> @@ -2016,8 +1527,6 @@ Bool R128PreInit(ScrnInfoPtr pScrn, int flags)
> "module load skipped\n");
> #endif
>
> -
> -
> if (!R128PreInitWeight(pScrn)) goto fail;
>
> if(xf86GetOptValInteger(info->Options, OPTION_VIDEO_KEY, &(info->videoKey))) {
> @@ -2053,20 +1562,30 @@ Bool R128PreInit(ScrnInfoPtr pScrn, int flags)
> }
>
> if (!info->FBDev)
> - if (!R128PreInitInt10(pScrn, &pInt10)) goto fail;
> -
> - if (!R128PreInitConfig(pScrn)) goto fail;
> + if (!R128PreInitInt10(pScrn, &pInt10)) goto fail;
>
> - if (!R128GetBIOSParameters(pScrn, pInt10)) goto fail;
> + if (!R128PreInitConfig(pScrn)) goto fail;
>
> - if (!R128GetPLLParameters(pScrn)) goto fail;
> + xf86CrtcSetSizeRange(pScrn, 320, 200, 4096, 4096);
>
> /* Don't fail on this one */
> - R128PreInitDDC(pScrn, pInt10);
> + info->DDC = R128PreInitDDC(pScrn, pInt10);
>
> - if (!R128PreInitGamma(pScrn)) goto fail;
> + if (!R128PreInitControllers(pScrn, pInt10)) goto fail;
> +
> + if (!xf86InitialConfiguration(pScrn, TRUE)) {
> + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes.\n");
> + goto fail;
> + }
> + pScrn->displayWidth = (pScrn->virtualX + 63) & ~63;
>
> - if (!R128PreInitModes(pScrn)) goto fail;
> + /* Set display resolution */
> + xf86SetDpi(pScrn, 0, 0);
> +
> + /* Get ScreenInit function */
> + if (!xf86LoadSubModule(pScrn, "fb")) return FALSE;
> +
> + if (!R128PreInitGamma(pScrn)) goto fail;
>
> if (!R128PreInitCursor(pScrn)) goto fail;
>
> @@ -2074,6 +1593,18 @@ Bool R128PreInit(ScrnInfoPtr pScrn, int flags)
> if (!R128PreInitDRI(pScrn)) goto fail;
> #endif
>
> + info->CurrentLayout.displayWidth = pScrn->displayWidth;
> +
> + if (!xf86RandR12PreInit(pScrn)) {
> + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "RandR initialization failure\n");
> + goto fail;
> + }
> +
> + if (pScrn->modes == NULL) {
> + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No modes.\n");
> + goto fail;
> + }
> +
> /* Free the video bios (if applicable) */
> if (info->VBIOS) {
> free(info->VBIOS);
> @@ -2084,6 +1615,9 @@ Bool R128PreInit(ScrnInfoPtr pScrn, int flags)
> if (pInt10)
> xf86FreeInt10(pInt10);
>
> + if (info->MMIO) R128UnmapMMIO(pScrn);
> + info->MMIO = NULL;
> +
> xf86DrvMsg(pScrn->scrnIndex, X_NOTICE,
> "For information on using the multimedia capabilities\n\tof this"
> " adapter, please see http://gatos.sf.net.\n");
> @@ -2116,56 +1650,66 @@ static void R128LoadPalette(ScrnInfoPtr pScrn, int numColors,
> int *indices, LOCO *colors, VisualPtr pVisual)
> {
> R128InfoPtr info = R128PTR(pScrn);
> - unsigned char *R128MMIO = info->MMIO;
> - int i, j;
> - int idx;
> - unsigned char r, g, b;
> -
> - /* If the second monitor is connected, we also
> - need to deal with the secondary palette*/
> - if (info->IsSecondary) j = 1;
> - else j = 0;
> -
> - PAL_SELECT(j);
> + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
> + int i, j;
> + int c, index;
> + CARD16 lut_r[256], lut_g[256], lut_b[256];
> +
> + for (c = 0; c < xf86_config->num_crtc; c++) {
> + xf86CrtcPtr crtc = xf86_config->crtc[c];
> + R128CrtcPrivatePtr r128_crtc = crtc->driver_private;
> +
> + for (i = 0 ; i < 256; i++) {
> + lut_r[i] = r128_crtc->lut_r[i] << 8;
> + lut_g[i] = r128_crtc->lut_g[i] << 8;
> + lut_b[i] = r128_crtc->lut_b[i] << 8;
> + }
>
> + switch (info->CurrentLayout.depth) {
> + case 15:
> + for (i = 0; i < numColors; i++) {
> + index = indices[i];
> + for (j = 0; j < 8; j++) {
> + lut_r[index * 8 + j] = colors[index].red << 8;
> + lut_g[index * 8 + j] = colors[index].green << 8;
> + lut_b[index * 8 + j] = colors[index].blue << 8;
> + }
> + }
> + case 16:
> + for (i = 0; i < numColors; i++) {
> + index = indices[i];
> +
> + /* XXX: The old version of R128LoadPalette did not do this and
> + * the old version of RADEONLoadPalette has a comment asking why.
> + */
> + if (i <= 31) {
> + for (j = 0; j < 8; j++) {
> + lut_r[index * 8 + j] = colors[index].red << 8;
> + lut_b[index * 8 + j] = colors[index].blue << 8;
> + }
> + }
>
> - /* Select palette 0 (main CRTC) if using FP-enabled chip */
> - /*if (info->HasPanelRegs || info->isDFP) PAL_SELECT(0);*/
> + for (j = 0; j < 4; j++) {
> + lut_g[index * 4 + j] = colors[index].green << 8;
> + }
> + }
> + default:
> + for (i = 0; i < numColors; i++) {
> + index = indices[i];
> + lut_r[index] = colors[index].red << 8;
> + lut_g[index] = colors[index].green << 8;
> + lut_b[index] = colors[index].blue << 8;
> + }
> + break;
> + }
>
> - if (info->CurrentLayout.depth == 15) {
> - /* 15bpp mode. This sends 32 values. */
> - for (i = 0; i < numColors; i++) {
> - idx = indices[i];
> - r = colors[idx].red;
> - g = colors[idx].green;
> - b = colors[idx].blue;
> - OUTPAL(idx * 8, r, g, b);
> - }
> - }
> - else if (info->CurrentLayout.depth == 16) {
> - /* 16bpp mode. This sends 64 values. */
> - /* There are twice as many green values as
> - there are values for red and blue. So,
> - we take each red and blue pair, and
> - combine it with each of the two green
> - values. */
> - for (i = 0; i < numColors; i++) {
> - idx = indices[i];
> - r = colors[idx / 2].red;
> - g = colors[idx].green;
> - b = colors[idx / 2].blue;
> - OUTPAL(idx * 4, r, g, b);
> - }
> - }
> - else {
> - /* 8bpp mode. This sends 256 values. */
> - for (i = 0; i < numColors; i++) {
> - idx = indices[i];
> - r = colors[idx].red;
> - b = colors[idx].blue;
> - g = colors[idx].green;
> - OUTPAL(idx, r, g, b);
> - }
> + /* Make the change through RandR */
> +#ifdef RANDR_12_INTERFACE
> + if (crtc->randr_crtc)
> + RRCrtcGammaSet(crtc->randr_crtc, lut_r, lut_g, lut_b);
> + else
> +#endif
> + crtc->funcs->gamma_set(crtc, lut_r, lut_g, lut_b, 256);
> }
> }
>
> @@ -2296,14 +1840,6 @@ Bool R128ScreenInit(SCREEN_INIT_ARGS_DECL)
> info->PaletteSavedOnVT = FALSE;
>
> R128Save(pScrn);
> - if (info->FBDev) {
> - if (!fbdevHWModeInit(pScrn, pScrn->currentMode)) return FALSE;
> - } else {
> - if (!R128ModeInit(pScrn, pScrn->currentMode)) return FALSE;
> - }
> -
> - R128SaveScreen(pScreen, SCREEN_SAVER_ON);
> - pScrn->AdjustFrame(ADJUST_FRAME_ARGS(pScrn, pScrn->frameX0, pScrn->frameY0));
>
> /* Visual setup */
> miClearVisualTypes();
> @@ -2701,6 +2237,19 @@ Bool R128ScreenInit(SCREEN_INIT_ARGS_DECL)
> #endif
> }
>
> + pScrn->vtSema = TRUE;
> + /* xf86CrtcRotate accesses pScrn->pScreen */
> + pScrn->pScreen = pScreen;
> +
> + if (info->FBDev) {
> + if (!fbdevHWModeInit(pScrn, pScrn->currentMode)) return FALSE;
> + } else {
> + if (!xf86SetDesiredModes(pScrn)) return FALSE;
> + }
> +
> + R128SaveScreen(pScreen, SCREEN_SAVER_ON);
> + //pScrn->AdjustFrame(ADJUST_FRAME_ARGS(pScrn, pScrn->frameX0, pScrn->frameY0));
> +
> /* DGA setup */
> R128DGAInit(pScreen);
>
> @@ -2737,28 +2286,11 @@ Bool R128ScreenInit(SCREEN_INIT_ARGS_DECL)
> xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using software cursor\n");
> }
>
> - /* Colormap setup */
> - if (!miCreateDefColormap(pScreen)) return FALSE;
> - if (!xf86HandleColormaps(pScreen, 256, info->dac6bits ? 6 : 8,
> - (info->FBDev ? fbdevHWLoadPaletteWeak() :
> - R128LoadPalette), NULL,
> - CMAP_PALETTED_TRUECOLOR
> - | CMAP_RELOAD_ON_MODE_SWITCH
> -#if 0 /* This option messes up text mode! (eich at suse.de) */
> - | CMAP_LOAD_EVEN_IF_OFFSCREEN
> -#endif
> - )) return FALSE;
> -
> /* DPMS setup - FIXME: also for mirror mode in non-fbdev case? - Michel */
> if (info->FBDev)
> xf86DPMSInit(pScreen, fbdevHWDPMSSetWeak(), 0);
> -
> - else {
> - if (info->DisplayType == MT_LCD)
> - xf86DPMSInit(pScreen, R128DisplayPowerManagementSetLCD, 0);
> - else
> - xf86DPMSInit(pScreen, R128DisplayPowerManagementSet, 0);
> - }
> + else
> + xf86DPMSInit(pScreen, xf86DPMSSet, 0);
>
> if (!info->IsSecondary)
> R128InitVideo(pScreen);
> @@ -2793,11 +2325,25 @@ Bool R128ScreenInit(SCREEN_INIT_ARGS_DECL)
> info->BlockHandler = pScreen->BlockHandler;
> pScreen->BlockHandler = R128BlockHandler;
>
> + if (!xf86CrtcScreenInit(pScreen)) return FALSE;
> +
> + /* Colormap setup */
> + if (!miCreateDefColormap(pScreen)) return FALSE;
> + if (!xf86HandleColormaps(pScreen, 256, info->dac6bits ? 6 : 8,
> + (info->FBDev ? fbdevHWLoadPaletteWeak() :
> + R128LoadPalette), NULL,
> + CMAP_PALETTED_TRUECOLOR
> + | CMAP_RELOAD_ON_MODE_SWITCH
> +#if 0 /* This option messes up text mode! (eich at suse.de) */
> + | CMAP_LOAD_EVEN_IF_OFFSCREEN
> +#endif
> + )) return FALSE;
> +
> return TRUE;
> }
>
> /* Write common registers (initialized to 0). */
> -static void R128RestoreCommonRegisters(ScrnInfoPtr pScrn, R128SavePtr restore)
> +void R128RestoreCommonRegisters(ScrnInfoPtr pScrn, R128SavePtr restore)
> {
> R128InfoPtr info = R128PTR(pScrn);
> unsigned char *R128MMIO = info->MMIO;
> @@ -2821,7 +2367,7 @@ static void R128RestoreCommonRegisters(ScrnInfoPtr pScrn, R128SavePtr restore)
> }
>
> /* Write CRTC registers. */
> -static void R128RestoreCrtcRegisters(ScrnInfoPtr pScrn, R128SavePtr restore)
> +void R128RestoreCrtcRegisters(ScrnInfoPtr pScrn, R128SavePtr restore)
> {
> R128InfoPtr info = R128PTR(pScrn);
> unsigned char *R128MMIO = info->MMIO;
> @@ -2844,7 +2390,7 @@ static void R128RestoreCrtcRegisters(ScrnInfoPtr pScrn, R128SavePtr restore)
> }
>
> /* Write CRTC2 registers. */
> -static void R128RestoreCrtc2Registers(ScrnInfoPtr pScrn,
> +void R128RestoreCrtc2Registers(ScrnInfoPtr pScrn,
> R128SavePtr restore)
> {
> R128InfoPtr info = R128PTR(pScrn);
> @@ -2863,7 +2409,7 @@ static void R128RestoreCrtc2Registers(ScrnInfoPtr pScrn,
> }
>
> /* Write flat panel registers */
> -static void R128RestoreFPRegisters(ScrnInfoPtr pScrn, R128SavePtr restore)
> +void R128RestoreFPRegisters(ScrnInfoPtr pScrn, R128SavePtr restore)
> {
> R128InfoPtr info = R128PTR(pScrn);
> unsigned char *R128MMIO = info->MMIO;
> @@ -2936,7 +2482,7 @@ static void R128PLL2WriteUpdate(ScrnInfoPtr pScrn)
> }
>
> /* Write PLL registers. */
> -static void R128RestorePLLRegisters(ScrnInfoPtr pScrn, R128SavePtr restore)
> +void R128RestorePLLRegisters(ScrnInfoPtr pScrn, R128SavePtr restore)
> {
> R128InfoPtr info = R128PTR(pScrn);
> unsigned char *R128MMIO = info->MMIO;
> @@ -2999,7 +2545,7 @@ static void R128RestorePLLRegisters(ScrnInfoPtr pScrn, R128SavePtr restore)
> }
>
> /* Write PLL2 registers. */
> -static void R128RestorePLL2Registers(ScrnInfoPtr pScrn, R128SavePtr restore)
> +void R128RestorePLL2Registers(ScrnInfoPtr pScrn, R128SavePtr restore)
> {
> R128InfoPtr info = R128PTR(pScrn);
> unsigned char *R128MMIO = info->MMIO;
> @@ -3068,7 +2614,7 @@ static void R128RestorePLL2Registers(ScrnInfoPtr pScrn, R128SavePtr restore)
> }
>
> /* Write DDA registers. */
> -static void R128RestoreDDARegisters(ScrnInfoPtr pScrn, R128SavePtr restore)
> +void R128RestoreDDARegisters(ScrnInfoPtr pScrn, R128SavePtr restore)
> {
> R128InfoPtr info = R128PTR(pScrn);
> unsigned char *R128MMIO = info->MMIO;
> @@ -3078,7 +2624,7 @@ static void R128RestoreDDARegisters(ScrnInfoPtr pScrn, R128SavePtr restore)
> }
>
> /* Write DDA registers. */
> -static void R128RestoreDDA2Registers(ScrnInfoPtr pScrn, R128SavePtr restore)
> +void R128RestoreDDA2Registers(ScrnInfoPtr pScrn, R128SavePtr restore)
> {
> R128InfoPtr info = R128PTR(pScrn);
> unsigned char *R128MMIO = info->MMIO;
> @@ -3087,126 +2633,6 @@ static void R128RestoreDDA2Registers(ScrnInfoPtr pScrn, R128SavePtr restore)
> OUTREG(R128_DDA2_ON_OFF, restore->dda2_on_off);
> }
>
> -/* Write palette data. */
> -static void R128RestorePalette(ScrnInfoPtr pScrn, R128SavePtr restore)
> -{
> - R128InfoPtr info = R128PTR(pScrn);
> - unsigned char *R128MMIO = info->MMIO;
> - int i;
> -
> - if (!restore->palette_valid) return;
> -
> - PAL_SELECT(1);
> - OUTPAL_START(0);
> - for (i = 0; i < 256; i++) {
> - R128WaitForFifo(pScrn, 32); /* delay */
> - OUTPAL_NEXT_CARD32(restore->palette2[i]);
> - }
> -
> - PAL_SELECT(0);
> - OUTPAL_START(0);
> - for (i = 0; i < 256; i++) {
> - R128WaitForFifo(pScrn, 32); /* delay */
> - OUTPAL_NEXT_CARD32(restore->palette[i]);
> - }
> -
> -}
> -
> -/* Write out state to define a new video mode. */
> -static void R128RestoreMode(ScrnInfoPtr pScrn, R128SavePtr restore)
> -{
> - R128InfoPtr info = R128PTR(pScrn);
> - DevUnion* pPriv;
> - R128EntPtr pR128Ent;
> - static R128SaveRec restore0;
> -
> - R128TRACE(("R128RestoreMode(%p)\n", restore));
> - if(!info->HasCRTC2)
> - {
> - R128RestoreCommonRegisters(pScrn, restore);
> - R128RestoreDDARegisters(pScrn, restore);
> - R128RestoreCrtcRegisters(pScrn, restore);
> - if((info->DisplayType == MT_DFP) ||
> - (info->DisplayType == MT_LCD))
> - {
> - R128RestoreFPRegisters(pScrn, restore);
> - }
> - R128RestorePLLRegisters(pScrn, restore);
> - return;
> - }
> -
> - pPriv = xf86GetEntityPrivate(pScrn->entityList[0],
> - getR128EntityIndex());
> - pR128Ent = pPriv->ptr;
> -
> -
> - /*****
> - When changing mode with Dual-head card (VE/M6), care must
> - be taken for the special order in setting registers. CRTC2 has
> - to be set before changing CRTC_EXT register.
> - In the dual-head setup, X server calls this routine twice with
> - primary and secondary pScrn pointers respectively. The calls
> - can come with different order. Regardless the order of X server issuing
> - the calls, we have to ensure we set registers in the right order!!!
> - Otherwise we may get a blank screen.
> - *****/
> -
> - if(info->IsSecondary)
> - {
> - if (!pR128Ent->RestorePrimary && !info->SwitchingMode)
> - R128RestoreCommonRegisters(pScrn, restore);
> - R128RestoreDDA2Registers(pScrn, restore);
> - R128RestoreCrtc2Registers(pScrn, restore);
> - R128RestorePLL2Registers(pScrn, restore);
> -
> - if(info->SwitchingMode) return;
> -
> - pR128Ent->IsSecondaryRestored = TRUE;
> -
> - if(pR128Ent->RestorePrimary)
> - {
> - R128InfoPtr info0 = R128PTR(pR128Ent->pPrimaryScrn);
> - pR128Ent->RestorePrimary = FALSE;
> -
> - R128RestoreCrtcRegisters(pScrn, &restore0);
> - if((info0->DisplayType == MT_DFP) ||
> - (info0->DisplayType == MT_LCD))
> - {
> - R128RestoreFPRegisters(pScrn, &restore0);
> - }
> -
> - R128RestorePLLRegisters(pScrn, &restore0);
> - pR128Ent->IsSecondaryRestored = FALSE;
> -
> - }
> - }
> - else
> - {
> - if (!pR128Ent->IsSecondaryRestored)
> - R128RestoreCommonRegisters(pScrn, restore);
> - R128RestoreDDARegisters(pScrn, restore);
> - if(!pR128Ent->HasSecondary || pR128Ent->IsSecondaryRestored
> - || info->SwitchingMode)
> - {
> - pR128Ent->IsSecondaryRestored = FALSE;
> - R128RestoreCrtcRegisters(pScrn, restore);
> - if((info->DisplayType == MT_DFP) ||
> - (info->DisplayType == MT_LCD))
> - {
> - R128RestoreFPRegisters(pScrn, restore);
> - }
> - R128RestorePLLRegisters(pScrn, restore);
> - }
> - else
> - {
> - memcpy(&restore0, restore, sizeof(restore0));
> - pR128Ent->RestorePrimary = TRUE;
> - }
> - }
> -
> - R128RestorePalette(pScrn, restore);
> -}
> -
> /* Read common registers. */
> static void R128SaveCommonRegisters(ScrnInfoPtr pScrn, R128SavePtr save)
> {
> @@ -3450,9 +2876,19 @@ static void R128Restore(ScrnInfoPtr pScrn)
> OUTREG(R128_CLOCK_CNTL_INDEX, restore->clock_cntl_index);
> OUTREG(R128_GEN_RESET_CNTL, restore->gen_reset_cntl);
> OUTREG(R128_DP_DATATYPE, restore->dp_datatype);
> +
> + R128RestoreCommonRegisters(pScrn, restore);
> + if (info->HasCRTC2) {
> + R128RestoreDDA2Registers(pScrn, restore);
> + R128RestoreCrtc2Registers(pScrn, restore);
> + R128RestorePLL2Registers(pScrn, restore);
> + }
> + R128RestoreDDARegisters(pScrn, restore);
> + R128RestoreCrtcRegisters(pScrn, restore);
> + R128RestorePLLRegisters(pScrn, restore);
> + R128RestoreFPRegisters(pScrn, restore);
> }
>
> - R128RestoreMode(pScrn, restore);
> #ifdef WITH_VGAHW
> if (info->VGAAccess) {
> vgaHWPtr hwp = VGAHWPTR(pScrn);
> @@ -3492,7 +2928,7 @@ static void R128Restore(ScrnInfoPtr pScrn)
> }
>
> /* Define common registers for requested video mode. */
> -static void R128InitCommonRegisters(R128SavePtr save, R128InfoPtr info)
> +void R128InitCommonRegisters(R128SavePtr save, R128InfoPtr info)
> {
> save->ovr_clr = 0;
> save->ovr_wid_left_right = 0;
> @@ -3518,8 +2954,64 @@ static void R128InitCommonRegisters(R128SavePtr save, R128InfoPtr info)
> save->bus_cntl |= R128_BUS_RD_DISCARD_EN | R128_BUS_RD_ABORT_EN;
> }
>
> +Bool R128InitCrtcBase(xf86CrtcPtr crtc, R128SavePtr save, int x, int y)
> +{
> + ScrnInfoPtr pScrn = crtc->scrn;
> + R128InfoPtr info = R128PTR(pScrn);
> + int offset = y * info->CurrentLayout.displayWidth + x;
> + int Base = pScrn->fbOffset;
> +
> + switch (info->CurrentLayout.pixel_code) {
> + case 15:
> + case 16: offset *= 2; break;
> + case 24: offset *= 3; break;
> + case 32: offset *= 4; break;
> + }
> + Base += offset;
> +
> + if (crtc->rotatedData != NULL)
> + Base = pScrn->fbOffset + (char *)crtc->rotatedData - (char *)info->FB;
> +
> + Base &= ~7; /* 3 lower bits are always 0 */
> + if (info->CurrentLayout.pixel_code == 24)
> + Base += 8 * (Base % 3); /* Must be multiple of 8 and 3 */
> +
> + save->crtc_offset = Base;
> + save->crtc_offset_cntl = 0;
> +
> + return TRUE;
> +}
> +
> +Bool R128InitCrtc2Base(xf86CrtcPtr crtc, R128SavePtr save, int x, int y)
> +{
> + ScrnInfoPtr pScrn = crtc->scrn;
> + R128InfoPtr info = R128PTR(pScrn);
> + int offset = y * info->CurrentLayout.displayWidth + x;
> + int Base = pScrn->fbOffset;
> +
> + switch (info->CurrentLayout.pixel_code) {
> + case 15:
> + case 16: offset *= 2; break;
> + case 24: offset *= 3; break;
> + case 32: offset *= 4; break;
> + }
> + Base += offset;
> +
> + if (crtc->rotatedData != NULL)
> + Base = pScrn->fbOffset + (char *)crtc->rotatedData - (char *)info->FB;
> +
> + Base &= ~7; /* 3 lower bits are always 0 */
> + if (info->CurrentLayout.pixel_code == 24)
> + Base += 8 * (Base % 3); /* Must be multiple of 8 and 3 */
> +
> + save->crtc2_offset = Base;
> + save->crtc2_offset_cntl = 0;
> +
> + return TRUE;
> +}
> +
> /* Define CRTC registers for requested video mode. */
> -static Bool R128InitCrtcRegisters(ScrnInfoPtr pScrn, R128SavePtr save,
> +Bool R128InitCrtcRegisters(ScrnInfoPtr pScrn, R128SavePtr save,
> DisplayModePtr mode, R128InfoPtr info)
> {
> int format;
> @@ -3633,8 +3125,6 @@ static Bool R128InitCrtcRegisters(ScrnInfoPtr pScrn, R128SavePtr save,
> | ((mode->Flags & V_NVSYNC)
> ? R128_CRTC_V_SYNC_POL
> : 0));
> - save->crtc_offset = 0;
> - save->crtc_offset_cntl = 0;
> save->crtc_pitch = info->CurrentLayout.displayWidth / 8;
>
> R128TRACE(("Pitch = %d bytes (virtualX = %d, displayWidth = %d)\n",
> @@ -3654,7 +3144,7 @@ static Bool R128InitCrtcRegisters(ScrnInfoPtr pScrn, R128SavePtr save,
> }
>
> /* Define CRTC2 registers for requested video mode. */
> -static Bool R128InitCrtc2Registers(ScrnInfoPtr pScrn, R128SavePtr save,
> +Bool R128InitCrtc2Registers(ScrnInfoPtr pScrn, R128SavePtr save,
> DisplayModePtr mode, R128InfoPtr info)
> {
> int format;
> @@ -3727,10 +3217,6 @@ static Bool R128InitCrtc2Registers(ScrnInfoPtr pScrn, R128SavePtr save,
> | ((mode->Flags & V_NVSYNC)
> ? R128_CRTC2_V_SYNC_POL
> : 0));
> -
> - save->crtc2_offset = 0;
> - save->crtc2_offset_cntl = 0;
> -
> save->crtc2_pitch = info->CurrentLayout.displayWidth / 8;
>
> R128TRACE(("Pitch = %d bytes (virtualX = %d, displayWidth = %d)\n",
> @@ -3740,7 +3226,7 @@ static Bool R128InitCrtc2Registers(ScrnInfoPtr pScrn, R128SavePtr save,
> }
>
> /* Define CRTC registers for requested video mode. */
> -static void R128InitFPRegisters(R128SavePtr orig, R128SavePtr save,
> +void R128InitFPRegisters(R128SavePtr orig, R128SavePtr save,
> DisplayModePtr mode, R128InfoPtr info)
> {
> int xres = mode->CrtcHDisplay;
> @@ -3853,7 +3339,7 @@ static void R128InitFPRegisters(R128SavePtr orig, R128SavePtr save,
> }
>
> /* Define PLL registers for requested video mode. */
> -static void R128InitPLLRegisters(ScrnInfoPtr pScrn, R128SavePtr save,
> +void R128InitPLLRegisters(ScrnInfoPtr pScrn, R128SavePtr save,
> R128PLLPtr pll, double dot_clock)
> {
> unsigned long freq = dot_clock * 100;
> @@ -3905,7 +3391,7 @@ static void R128InitPLLRegisters(ScrnInfoPtr pScrn, R128SavePtr save,
> }
>
> /* Define PLL2 registers for requested video mode. */
> -static void R128InitPLL2Registers(ScrnInfoPtr pScrn, R128SavePtr save,
> +void R128InitPLL2Registers(ScrnInfoPtr pScrn, R128SavePtr save,
> R128PLLPtr pll, double dot_clock)
> {
> unsigned long freq = dot_clock * 100;
> @@ -3957,7 +3443,7 @@ static void R128InitPLL2Registers(ScrnInfoPtr pScrn, R128SavePtr save,
> }
>
> /* Define DDA registers for requested video mode. */
> -static Bool R128InitDDARegisters(ScrnInfoPtr pScrn, R128SavePtr save,
> +Bool R128InitDDARegisters(ScrnInfoPtr pScrn, R128SavePtr save,
> R128PLLPtr pll, R128InfoPtr info,
> DisplayModePtr mode)
> {
> @@ -4026,7 +3512,7 @@ static Bool R128InitDDARegisters(ScrnInfoPtr pScrn, R128SavePtr save,
> }
>
> /* Define DDA2 registers for requested video mode. */
> -static Bool R128InitDDA2Registers(ScrnInfoPtr pScrn, R128SavePtr save,
> +Bool R128InitDDA2Registers(ScrnInfoPtr pScrn, R128SavePtr save,
> R128PLLPtr pll, R128InfoPtr info,
> DisplayModePtr mode)
> {
> @@ -4106,122 +3592,6 @@ static void R128InitPalette(R128SavePtr save)
> }
> #endif
>
> -/* Define registers for a requested video mode. */
> -static Bool R128Init(ScrnInfoPtr pScrn, DisplayModePtr mode, R128SavePtr save)
> -{
> - R128InfoPtr info = R128PTR(pScrn);
> - double dot_clock = mode->Clock/1000.0;
> -
> -#if R128_DEBUG
> - ErrorF("%-12.12s %7.2f %4d %4d %4d %4d %4d %4d %4d %4d (%d,%d)",
> - mode->name,
> - dot_clock,
> -
> - mode->HDisplay,
> - mode->HSyncStart,
> - mode->HSyncEnd,
> - mode->HTotal,
> -
> - mode->VDisplay,
> - mode->VSyncStart,
> - mode->VSyncEnd,
> - mode->VTotal,
> - pScrn->depth,
> - pScrn->bitsPerPixel);
> - if (mode->Flags & V_DBLSCAN) ErrorF(" D");
> - if (mode->Flags & V_CSYNC) ErrorF(" C");
> - if (mode->Flags & V_INTERLACE) ErrorF(" I");
> - if (mode->Flags & V_PHSYNC) ErrorF(" +H");
> - if (mode->Flags & V_NHSYNC) ErrorF(" -H");
> - if (mode->Flags & V_PVSYNC) ErrorF(" +V");
> - if (mode->Flags & V_NVSYNC) ErrorF(" -V");
> - ErrorF("\n");
> - ErrorF("%-12.12s %7.2f %4d %4d %4d %4d %4d %4d %4d %4d (%d,%d)",
> - mode->name,
> - dot_clock,
> -
> - mode->CrtcHDisplay,
> - mode->CrtcHSyncStart,
> - mode->CrtcHSyncEnd,
> - mode->CrtcHTotal,
> -
> - mode->CrtcVDisplay,
> - mode->CrtcVSyncStart,
> - mode->CrtcVSyncEnd,
> - mode->CrtcVTotal,
> - pScrn->depth,
> - pScrn->bitsPerPixel);
> - if (mode->Flags & V_DBLSCAN) ErrorF(" D");
> - if (mode->Flags & V_CSYNC) ErrorF(" C");
> - if (mode->Flags & V_INTERLACE) ErrorF(" I");
> - if (mode->Flags & V_PHSYNC) ErrorF(" +H");
> - if (mode->Flags & V_NHSYNC) ErrorF(" -H");
> - if (mode->Flags & V_PVSYNC) ErrorF(" +V");
> - if (mode->Flags & V_NVSYNC) ErrorF(" -V");
> - ErrorF("\n");
> -#endif
> -
> - info->Flags = mode->Flags;
> -
> - if(info->IsSecondary)
> - {
> - if (!R128InitCrtc2Registers(pScrn, save,
> - pScrn->currentMode,info))
> - return FALSE;
> - R128InitPLL2Registers(pScrn, save, &info->pll, dot_clock);
> - if (!R128InitDDA2Registers(pScrn, save, &info->pll, info, mode))
> - return FALSE;
> - }
> - else
> - {
> - R128InitCommonRegisters(save, info);
> - if(!R128InitCrtcRegisters(pScrn, save, mode, info))
> - return FALSE;
> - if(dot_clock)
> - {
> - R128InitPLLRegisters(pScrn, save, &info->pll, dot_clock);
> - if (!R128InitDDARegisters(pScrn, save, &info->pll, info, mode))
> - return FALSE;
> - }
> - else
> - {
> - save->ppll_ref_div = info->SavedReg.ppll_ref_div;
> - save->ppll_div_3 = info->SavedReg.ppll_div_3;
> - save->htotal_cntl = info->SavedReg.htotal_cntl;
> - save->dda_config = info->SavedReg.dda_config;
> - save->dda_on_off = info->SavedReg.dda_on_off;
> - }
> - /* not used for now */
> - /*if (!info->PaletteSavedOnVT) RADEONInitPalette(save);*/
> - }
> -
> - if (((info->DisplayType == MT_DFP) ||
> - (info->DisplayType == MT_LCD)))
> - {
> - R128InitFPRegisters(&info->SavedReg, save, mode, info);
> - }
> -
> - R128TRACE(("R128Init returns %p\n", save));
> - return TRUE;
> -}
> -
> -/* Initialize a new mode. */
> -static Bool R128ModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
> -{
> - R128InfoPtr info = R128PTR(pScrn);
> -
> - if (!R128Init(pScrn, mode, &info->ModeReg)) return FALSE;
> - /* FIXME? DRILock/DRIUnlock here? */
> - pScrn->vtSema = TRUE;
> - R128Blank(pScrn);
> - R128RestoreMode(pScrn, &info->ModeReg);
> - R128Unblank(pScrn);
> -
> - info->CurrentLayout.mode = mode;
> -
> - return TRUE;
> -}
> -
> static Bool R128SaveScreen(ScreenPtr pScreen, int mode)
> {
> ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
> @@ -4252,7 +3622,7 @@ Bool R128SwitchMode(SWITCH_MODE_ARGS_DECL)
> Bool ret;
>
> info->SwitchingMode = TRUE;
> - ret = R128ModeInit(pScrn, mode);
> + ret = xf86SetSingleMode(pScrn, mode, RR_Rotate_0);
> info->SwitchingMode = FALSE;
> return ret;
> }
> @@ -4379,10 +3749,16 @@ Bool R128EnterVT(VT_FUNC_ARGS_DECL)
> R128InfoPtr info = R128PTR(pScrn);
>
> R128TRACE(("R128EnterVT\n"));
> +
> + pScrn->vtSema = TRUE;
> if (info->FBDev) {
> if (!fbdevHWEnterVT(VT_FUNC_ARGS)) return FALSE;
> - } else
> - if (!R128ModeInit(pScrn, pScrn->currentMode)) return FALSE;
> + } else {
> + if (!xf86SetDesiredModes(pScrn)) return FALSE;
> + }
> +
> + //if (!R128ModeInit(pScrn, pScrn->currentMode)) return FALSE;
> +
> if (info->accelOn)
> R128EngineInit(pScrn);
>
> @@ -4399,7 +3775,7 @@ Bool R128EnterVT(VT_FUNC_ARGS_DECL)
> #endif
>
> info->PaletteSavedOnVT = FALSE;
> - pScrn->AdjustFrame(ADJUST_FRAME_ARGS(pScrn, pScrn->frameX0, pScrn->frameY0));
> + //pScrn->AdjustFrame(ADJUST_FRAME_ARGS(pScrn, pScrn->frameX0, pScrn->frameY0));
>
> return TRUE;
> }
> @@ -4504,130 +3880,3 @@ void R128FreeScreen(FREE_SCREEN_ARGS_DECL)
> #endif
> R128FreeRec(pScrn);
> }
> -
> -/* Sets VESA Display Power Management Signaling (DPMS) Mode. */
> -static void R128DisplayPowerManagementSet(ScrnInfoPtr pScrn,
> - int PowerManagementMode, int flags)
> -{
> - R128InfoPtr info = R128PTR(pScrn);
> - unsigned char *R128MMIO = info->MMIO;
> - int mask = (R128_CRTC_DISPLAY_DIS
> - | R128_CRTC_HSYNC_DIS
> - | R128_CRTC_VSYNC_DIS);
> - int mask2 = R128_CRTC2_DISP_DIS;
> -
> - switch (PowerManagementMode) {
> - case DPMSModeOn:
> - /* Screen: On; HSync: On, VSync: On */
> - if (info->IsSecondary)
> - OUTREGP(R128_CRTC2_GEN_CNTL, 0, ~mask2);
> - else
> - OUTREGP(R128_CRTC_EXT_CNTL, 0, ~mask);
> - break;
> - case DPMSModeStandby:
> - /* Screen: Off; HSync: Off, VSync: On */
> - if (info->IsSecondary)
> - OUTREGP(R128_CRTC2_GEN_CNTL, R128_CRTC2_DISP_DIS, ~mask2);
> - else
> - OUTREGP(R128_CRTC_EXT_CNTL,
> - R128_CRTC_DISPLAY_DIS | R128_CRTC_HSYNC_DIS, ~mask);
> - break;
> - case DPMSModeSuspend:
> - /* Screen: Off; HSync: On, VSync: Off */
> - if (info->IsSecondary)
> - OUTREGP(R128_CRTC2_GEN_CNTL, R128_CRTC2_DISP_DIS, ~mask2);
> - else
> - OUTREGP(R128_CRTC_EXT_CNTL,
> - R128_CRTC_DISPLAY_DIS | R128_CRTC_VSYNC_DIS, ~mask);
> - break;
> - case DPMSModeOff:
> - /* Screen: Off; HSync: Off, VSync: Off */
> - if (info->IsSecondary)
> - OUTREGP(R128_CRTC2_GEN_CNTL, mask2, ~mask2);
> - else
> - OUTREGP(R128_CRTC_EXT_CNTL, mask, ~mask);
> - break;
> - }
> - if(info->isDFP) {
> - switch (PowerManagementMode) {
> - case DPMSModeOn:
> - OUTREG(R128_FP_GEN_CNTL, INREG(R128_FP_GEN_CNTL) | (R128_FP_FPON | R128_FP_TDMS_EN));
> - break;
> - case DPMSModeStandby:
> - case DPMSModeSuspend:
> - case DPMSModeOff:
> - OUTREG(R128_FP_GEN_CNTL, INREG(R128_FP_GEN_CNTL) & ~(R128_FP_FPON | R128_FP_TDMS_EN));
> - break;
> - }
> - }
> -}
> -
> -static int r128_set_backlight_enable(ScrnInfoPtr pScrn, int on);
> -
> -static void R128DisplayPowerManagementSetLCD(ScrnInfoPtr pScrn,
> - int PowerManagementMode, int flags)
> -{
> - R128InfoPtr info = R128PTR(pScrn);
> - unsigned char *R128MMIO = info->MMIO;
> - int mask = R128_LVDS_DISPLAY_DIS;
> -
> - switch (PowerManagementMode) {
> - case DPMSModeOn:
> - /* Screen: On; HSync: On, VSync: On */
> - OUTREGP(R128_LVDS_GEN_CNTL, 0, ~mask);
> - r128_set_backlight_enable(pScrn, 1);
> - break;
> - case DPMSModeStandby:
> - /* Fall through */
> - case DPMSModeSuspend:
> - /* Fall through */
> - break;
> - case DPMSModeOff:
> - /* Screen: Off; HSync: Off, VSync: Off */
> - OUTREGP(R128_LVDS_GEN_CNTL, mask, ~mask);
> - r128_set_backlight_enable(pScrn, 0);
> - break;
> - }
> -}
> -
> -static int r128_set_backlight_enable(ScrnInfoPtr pScrn, int on)
> -{
> - R128InfoPtr info = R128PTR(pScrn);
> - unsigned char *R128MMIO = info->MMIO;
> - unsigned int lvds_gen_cntl = INREG(R128_LVDS_GEN_CNTL);
> -
> - lvds_gen_cntl |= (/*R128_LVDS_BL_MOD_EN |*/ R128_LVDS_BLON);
> - if (on) {
> - lvds_gen_cntl |= R128_LVDS_DIGON;
> - if (!(lvds_gen_cntl & R128_LVDS_ON)) {
> - lvds_gen_cntl &= ~R128_LVDS_BLON;
> - OUTREG(R128_LVDS_GEN_CNTL, lvds_gen_cntl);
> - (void)INREG(R128_LVDS_GEN_CNTL);
> - usleep(10000);
> - lvds_gen_cntl |= R128_LVDS_BLON;
> - OUTREG(R128_LVDS_GEN_CNTL, lvds_gen_cntl);
> - }
> -#if 0
> - lvds_gen_cntl &= ~R128_LVDS_BL_MOD_LEVEL_MASK;
> - lvds_gen_cntl |= (0xFF /* backlight_conv[level] */ <<
> - R128_LVDS_BL_MOD_LEVEL_SHIFT);
> -#endif
> - lvds_gen_cntl |= (R128_LVDS_ON | R128_LVDS_EN);
> - lvds_gen_cntl &= ~R128_LVDS_DISPLAY_DIS;
> - } else {
> -#if 0
> - lvds_gen_cntl &= ~R128_LVDS_BL_MOD_LEVEL_MASK;
> - lvds_gen_cntl |= (0xFF /* backlight_conv[0] */ <<
> - R128_LVDS_BL_MOD_LEVEL_SHIFT);
> -#endif
> - lvds_gen_cntl |= R128_LVDS_DISPLAY_DIS;
> - OUTREG(R128_LVDS_GEN_CNTL, lvds_gen_cntl);
> - usleep(10);
> - lvds_gen_cntl &= ~(R128_LVDS_ON | R128_LVDS_EN | R128_LVDS_BLON
> - | R128_LVDS_DIGON);
> - }
> -
> - OUTREG(R128_LVDS_GEN_CNTL, lvds_gen_cntl);
> -
> - return 0;
> -}
> diff --git a/src/r128_output.c b/src/r128_output.c
> new file mode 100644
> index 0000000..00d552f
> --- /dev/null
> +++ b/src/r128_output.c
> @@ -0,0 +1,465 @@
> +/*
> + * Copyright 2000 ATI Technologies Inc., Markham, Ontario, and
> + * VA Linux Systems Inc., Fremont, California.
> + *
> + * All Rights Reserved.
> + *
> + * 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 on 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 (including the
> + * next paragraph) 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
> + * NON-INFRINGEMENT. IN NO EVENT SHALL ATI, VA LINUX SYSTEMS AND/OR
> + * THEIR SUPPLIERS 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.
> + */
> +
> +#ifdef HAVE_CONFIG_H
> +#include "config.h"
> +#endif
> +
> +#include <string.h>
> +#include <stdio.h>
> +
> +#include "xf86.h"
> +#include "xf86Modes.h"
> +
> +#include "r128.h"
> +#include "r128_probe.h"
> +#include "r128_reg.h"
> +
> +static void R128ConnectorFindMonitor(ScrnInfoPtr pScrn, xf86OutputPtr output);
> +
> +static void r128_dpms(xf86OutputPtr output, int mode)
> +{
> + switch(mode) {
> + case DPMSModeOn:
> + R128DPMSSetOn(output);
> + break;
> + case DPMSModeStandby:
> + case DPMSModeSuspend:
> + case DPMSModeOff:
> + R128DPMSSetOff(output);
> + break;
> + }
> +}
> +
> +static void r128_save(xf86OutputPtr output)
> +{
> +}
> +
> +static void r128_restore(xf86OutputPtr output)
> +{
> +}
> +
> +static int r128_mode_valid(xf86OutputPtr output, DisplayModePtr mode)
> +{
> + return MODE_OK;
> +}
> +
> +static Bool r128_mode_fixup(xf86OutputPtr output, DisplayModePtr mode, DisplayModePtr adjusted_mode)
> +{
> + return TRUE;
> +}
> +
> +static void r128_mode_prepare(xf86OutputPtr output)
> +{
> + r128_dpms(output, DPMSModeOff);
> +}
> +
> +static void r128_mode_set(xf86OutputPtr output, DisplayModePtr mode, DisplayModePtr adjusted_mode)
> +{
> +}
> +
> +static void r128_mode_commit(xf86OutputPtr output)
> +{
> + r128_dpms(output, DPMSModeOn);
> +}
> +
> +static xf86OutputStatus r128_detect(xf86OutputPtr output)
> +{
> + ScrnInfoPtr pScrn = output->scrn;
> + R128OutputPrivatePtr r128_output = output->driver_private;
> +
> + r128_output->MonType = MT_UNKNOWN;
> + R128ConnectorFindMonitor(pScrn, output);
> +
> + if (r128_output->MonType == MT_UNKNOWN) {
> + output->subpixel_order = SubPixelUnknown;
> + return XF86OutputStatusUnknown;
> + } else if (r128_output->MonType == MT_NONE) {
> + output->subpixel_order = SubPixelUnknown;
> + return XF86OutputStatusDisconnected;
> + } else {
> + switch(r128_output->MonType) {
> + case MT_LCD:
> + case MT_DFP:
> + output->subpixel_order = SubPixelHorizontalRGB;
> + break;
> + default:
> + output->subpixel_order = SubPixelNone;
> + break;
> + }
> +
> + return XF86OutputStatusConnected;
> + }
> +}
> +
> +static DisplayModePtr r128_get_modes(xf86OutputPtr output)
> +{
> + DisplayModePtr modes;
> + modes = R128ProbeOutputModes(output);
> + return modes;
> +}
> +
> +static void r128_destroy(xf86OutputPtr output)
> +{
> + if (output->driver_private)
> + free(output->driver_private);
> +}
> +
> +static const xf86OutputFuncsRec r128_output_funcs = {
> + .dpms = r128_dpms,
> + .save = r128_save,
> + .restore = r128_restore,
> + .mode_valid = r128_mode_valid,
> + .mode_fixup = r128_mode_fixup,
> + .prepare = r128_mode_prepare,
> + .mode_set = r128_mode_set,
> + .commit = r128_mode_commit,
> + .detect = r128_detect,
> + .get_modes = r128_get_modes,
> + .destroy = r128_destroy,
> +};
> +
> +void R128DPMSSetOn(xf86OutputPtr output)
> +{
> + ScrnInfoPtr pScrn = output->scrn;
> + R128InfoPtr info = R128PTR(pScrn);
> + unsigned char *R128MMIO = info->MMIO;
> + R128OutputPrivatePtr r128_output = output->driver_private;
> + R128MonitorType MonType = r128_output->MonType;
> +
> + switch(MonType) {
> + case MT_LCD:
> + OUTREGP(R128_LVDS_GEN_CNTL, R128_LVDS_BLON, ~R128_LVDS_BLON);
> + usleep(info->PanelPwrDly * 1000);
> + OUTREGP(R128_LVDS_GEN_CNTL, R128_LVDS_ON, ~R128_LVDS_ON);
> + break;
> + case MT_DFP:
> + OUTREGP(R128_FP_GEN_CNTL, (R128_FP_FPON | R128_FP_TDMS_EN), ~(R128_FP_FPON | R128_FP_TDMS_EN));
> + break;
> + default:
> + break;
> + }
> +}
> +
> +void R128DPMSSetOff(xf86OutputPtr output)
> +{
> + ScrnInfoPtr pScrn = output->scrn;
> + R128InfoPtr info = R128PTR(pScrn);
> + unsigned char *R128MMIO = info->MMIO;
> + R128OutputPrivatePtr r128_output = output->driver_private;
> + R128MonitorType MonType = r128_output->MonType;
> +
> + switch(MonType) {
> + case MT_LCD:
> + OUTREGP(R128_LVDS_GEN_CNTL, 0, ~(R128_LVDS_BLON | R128_LVDS_ON));
> + break;
> + case MT_DFP:
> + OUTREGP(R128_FP_GEN_CNTL, 0, ~(R128_FP_FPON | R128_FP_TDMS_EN));
> + break;
> + default:
> + break;
> + }
> +}
> +
> +static R128MonitorType R128DisplayDDCConnected(xf86OutputPtr output)
> +{
> + ScrnInfoPtr pScrn = output->scrn;
> + R128InfoPtr info = R128PTR(pScrn);
> + unsigned char *R128MMIO = info->MMIO;
> + R128OutputPrivatePtr r128_output = output->driver_private;
> +
> + R128MonitorType MonType = MT_NONE;
> + xf86MonPtr *MonInfo = &output->MonInfo;
> + CARD32 mask1, mask2;
> +
> + if (r128_output->type == OUTPUT_LVDS) {
> + return MT_LCD;
> + } else if (r128_output->type == OUTPUT_VGA) {
> + mask1 = R128_GPIO_MONID_MASK_1 | R128_GPIO_MONID_MASK_3;
> + mask2 = R128_GPIO_MONID_A_1 | R128_GPIO_MONID_A_3;
> + } else {
> + mask1 = R128_GPIO_MONID_MASK_0 | R128_GPIO_MONID_MASK_3;
> + mask2 = R128_GPIO_MONID_A_0 | R128_GPIO_MONID_A_3;
> + }
> +
> + if (r128_output->pI2CBus) {
> + R128I2CBusPtr pR128I2CBus = &(r128_output->ddc_i2c);
> +
> + /* XXX: Radeon does something here to appease old monitors. */
> + OUTREG(pR128I2CBus->ddc_reg, INREG(pR128I2CBus->ddc_reg) | mask1);
> + OUTREG(pR128I2CBus->ddc_reg, INREG(pR128I2CBus->ddc_reg) & ~mask2);
> + *MonInfo = xf86DoEDID_DDC2(XF86_SCRN_ARG(pScrn), r128_output->pI2CBus);
> + } else {
> + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "DDC2/I2C is not properly initialized\n");
> + return MT_NONE;
> + }
> +
> + if (*MonInfo) {
> + if (r128_output->type == OUTPUT_VGA) {
> + MonType = MT_CRT;
> + } else {
> + if ((*MonInfo)->rawData[0x14] & 0x80)
> + MonType = MT_DFP;
> + else
> + MonType = MT_CRT;
> + }
> + }
> +
> + return MonType;
> +}
> +
> +static void R128ConnectorFindMonitor(ScrnInfoPtr pScrn, xf86OutputPtr output)
> +{
> + R128OutputPrivatePtr r128_output = output->driver_private;
> +
> + /* XXX: We should figure out how the DAC and BIOS scratch registers work
> + * to handle the non-DDC case. */
> + if (r128_output->MonType == MT_UNKNOWN)
> + r128_output->MonType = R128DisplayDDCConnected(output);
> +}
> +
> +DisplayModePtr R128ProbeOutputModes(xf86OutputPtr output)
> +{
> + ScrnInfoPtr pScrn = output->scrn;
> + R128OutputPrivatePtr r128_output = output->driver_private;
> + DisplayModePtr modes = NULL;
> + DisplayModePtr mode;
> + xf86MonPtr edid_mon;
> +
> + if (r128_output->pI2CBus) {
> + edid_mon = xf86OutputGetEDID(output, r128_output->pI2CBus);
> + xf86OutputSetEDID(output, edid_mon);
> + modes = xf86OutputGetEDIDModes(output);
> + }
> +
> + /* Letting this function return NULL would be a bad idea. With old cards
> + * like r128, users often specify a small resolution in order to get DRI.
> + * If the X server has to guess modes, the list it comes up with includes
> + * high resolutions.
> + */
> + if (!modes)
> + modes = xf86GetDefaultModes();
> +
> + for (mode = modes; mode != NULL; mode = mode->next) {
> + xf86SetModeCrtc(mode, INTERLACE_HALVE_V);
> + if (mode->status == MODE_OK)
> + mode->status = R128ValidMode(XF86_SCRN_ARG(pScrn), mode, TRUE, MODECHECK_FINAL);
> + }
> +
> + xf86ValidateModesUserConfig(pScrn, modes);
> + xf86PruneInvalidModes(pScrn, &modes, FALSE);
> +
> + return modes;
> +}
> +
> +static xf86OutputPtr R128OutputCreate(ScrnInfoPtr pScrn, const char *name, int i)
> +{
> + char buf[32];
> + sprintf(buf, name, i);
> + return xf86OutputCreate(pScrn, &r128_output_funcs, buf);
> +}
> +
> +static void R128I2CGetBits(I2CBusPtr b, int *Clock, int *data)
> +{
> + ScrnInfoPtr pScrn = xf86Screens[b->scrnIndex];
> + R128InfoPtr info = R128PTR(pScrn);
> + unsigned long val;
> + unsigned char *R128MMIO = info->MMIO;
> + R128I2CBusPtr pR128I2CBus = b->DriverPrivate.ptr;
> +
> + /* Get the result. */
> + val = INREG(pR128I2CBus->ddc_reg);
> + *Clock = (val & pR128I2CBus->get_clk_mask) != 0;
> + *data = (val & pR128I2CBus->get_data_mask) != 0;
> +}
> +
> +static void R128I2CPutBits(I2CBusPtr b, int Clock, int data)
> +{
> + ScrnInfoPtr pScrn = xf86Screens[b->scrnIndex];
> + R128InfoPtr info = R128PTR(pScrn);
> + unsigned long val;
> + unsigned char *R128MMIO = info->MMIO;
> + R128I2CBusPtr pR128I2CBus = b->DriverPrivate.ptr;
> +
> + val = INREG(pR128I2CBus->ddc_reg)
> + & ~(CARD32)(pR128I2CBus->put_clk_mask | pR128I2CBus->put_data_mask);
> + val |= (Clock ? 0 : pR128I2CBus->put_clk_mask);
> + val |= (data ? 0 : pR128I2CBus->put_data_mask);
> + OUTREG(pR128I2CBus->ddc_reg, val);
> +}
> +
> +static Bool R128I2CInit(xf86OutputPtr output, I2CBusPtr *bus_ptr, char *name)
> +{
> + ScrnInfoPtr pScrn = output->scrn;
> + R128OutputPrivatePtr r128_output = output->driver_private;
> + R128I2CBusPtr pR128I2CBus = &(r128_output->ddc_i2c);
> + I2CBusPtr pI2CBus;
> +
> + pI2CBus = xf86CreateI2CBusRec();
> + if(!pI2CBus) return FALSE;
> +
> + pI2CBus->BusName = name;
> + pI2CBus->scrnIndex = pScrn->scrnIndex;
> + pI2CBus->I2CPutBits = R128I2CPutBits;
> + pI2CBus->I2CGetBits = R128I2CGetBits;
> + pI2CBus->AcknTimeout = 5;
> +
> + pI2CBus->DriverPrivate.ptr = (pointer)pR128I2CBus;
> + if (!xf86I2CBusInit(pI2CBus)) return FALSE;
> +
> + *bus_ptr = pI2CBus;
> + return TRUE;
> +}
> +
> +void R128SetOutputType(ScrnInfoPtr pScrn, R128OutputPrivatePtr r128_output)
> +{
> + R128OutputType output = OUTPUT_NONE;
> +
> + switch (r128_output->ConnectorType) {
> + case CONNECTOR_VGA:
> + output = OUTPUT_VGA;
> + break;
> + case CONNECTOR_LVDS:
> + output = OUTPUT_LVDS;
> + break;
> + case CONNECTOR_DVI_D:
> + case CONNECTOR_DVI_I:
> + case CONNECTOR_DVI_A:
> + output = OUTPUT_DVI;
> + break;
> + default:
> + output = OUTPUT_NONE;
> + }
> +
> + r128_output->type = output;
> +}
> +
> +void R128SetupGenericConnectors(ScrnInfoPtr pScrn)
> +{
> + R128InfoPtr info = R128PTR(pScrn);
> +
> + if (!info->HasCRTC2 && !info->isDFP) {
> + info->BiosConnector[0].ConnectorType = CONNECTOR_VGA;
> + info->BiosConnector[0].valid = TRUE;
> + return;
> + } else if (!info->HasCRTC2) {
> + info->BiosConnector[0].ConnectorType = CONNECTOR_DVI_D;
> + info->BiosConnector[0].valid = TRUE;
> + return;
> + }
> +
> + info->BiosConnector[0].ConnectorType = CONNECTOR_LVDS;
> + info->BiosConnector[0].valid = TRUE;
> +
> + info->BiosConnector[1].ConnectorType = CONNECTOR_VGA;
> + info->BiosConnector[1].valid = TRUE;
> +}
> +
> +Bool R128SetupConnectors(ScrnInfoPtr pScrn)
> +{
> + R128InfoPtr info = R128PTR(pScrn);
> + xf86OutputPtr output;
> + int num_vga = 0;
> + int num_dvi = 0;
> + int i;
> +
> + for (i = 0; i < R128_MAX_BIOS_CONNECTOR; i++) {
> + info->BiosConnector[i].valid = FALSE;
> + info->BiosConnector[i].ConnectorType = CONNECTOR_NONE;
> + }
> +
> + /* XXX: Can we make R128GetConnectorInfoFromBIOS()? */
> + R128SetupGenericConnectors(pScrn);
> +
> + for (i = 0; i < R128_MAX_BIOS_CONNECTOR; i++) {
> + if (info->BiosConnector[i].valid) {
> + if ((info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_D) ||
> + (info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_I) ||
> + (info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_A)) {
> + num_dvi++;
> + } else if (info->BiosConnector[i].ConnectorType == CONNECTOR_VGA) {
> + num_vga++;
> + }
> + }
> + }
> +
> + for (i = 0; i < R128_MAX_BIOS_CONNECTOR; i++) {
> + if (info->BiosConnector[i].valid) {
> + R128I2CBusRec i2c;
> + R128OutputPrivatePtr r128_output;
> + R128ConnectorType conntype = info->BiosConnector[i].ConnectorType;
> +
> + if (conntype == CONNECTOR_NONE)
> + continue;
> +
> + r128_output = xnfcalloc(sizeof(R128OutputPrivateRec), 1);
> + if (!r128_output) return FALSE;
> +
> + r128_output->MonType = MT_UNKNOWN;
> + r128_output->ConnectorType = conntype;
> + r128_output->num = i;
> +
> + if (conntype == CONNECTOR_LVDS) {
> + output = R128OutputCreate(pScrn, "LVDS", 0);
> + } else if (conntype == CONNECTOR_VGA) {
> + output = R128OutputCreate(pScrn, "VGA-%d", --num_vga);
> + } else {
> + output = R128OutputCreate(pScrn, "DVI-%d", --num_dvi);
> + }
> +
> + if (!output) return FALSE;
> + output->interlaceAllowed = TRUE;
> + output->doubleScanAllowed = TRUE;
> + output->driver_private = r128_output;
> + output->possible_clones = 0;
> + if (conntype == CONNECTOR_LVDS || !info->HasCRTC2)
> + output->possible_crtcs = 1;
> + else
> + output->possible_crtcs = 2;
> +
> + if (conntype != CONNECTOR_LVDS && info->DDC) {
> + i2c.ddc_reg = R128_GPIO_MONID;
> + i2c.put_clk_mask = R128_GPIO_MONID_EN_3;
> + i2c.get_clk_mask = R128_GPIO_MONID_Y_3;
> + if (conntype == CONNECTOR_VGA) {
> + i2c.put_data_mask = R128_GPIO_MONID_EN_1;
> + i2c.get_data_mask = R128_GPIO_MONID_Y_1;
> + } else {
> + i2c.put_data_mask = R128_GPIO_MONID_EN_0;
> + i2c.get_data_mask = R128_GPIO_MONID_Y_0;
> + }
> + r128_output->ddc_i2c = i2c;
> + R128I2CInit(output, &r128_output->pI2CBus, output->name);
> + }
> +
> + R128SetOutputType(pScrn, r128_output);
> + }
> + }
> +
> + return TRUE;
> +}
> diff --git a/src/r128_probe.c b/src/r128_probe.c
> index 12e0c1c..e623bc9 100644
> --- a/src/r128_probe.c
> +++ b/src/r128_probe.c
> @@ -48,7 +48,6 @@
> #include "xf86Resources.h"
> #endif
>
> -#include "compat-api.h"
> #include "r128_probe.h"
>
> #ifndef XSERVER_LIBPCIACCESS
> diff --git a/src/r128_probe.h b/src/r128_probe.h
> index 7b55e71..f521a13 100644
> --- a/src/r128_probe.h
> +++ b/src/r128_probe.h
> @@ -37,6 +37,15 @@
> #define _R128_PROBE_H_ 1
>
> #include "xf86str.h"
> +#include "xf86DDC.h"
> +#include "randrstr.h"
> +#include "xf86Crtc.h"
> +
> +#include "compat-api.h"
> +
> +#ifdef USE_EXA
> +#include "exa.h"
> +#endif
>
> /* Chip definitions */
> #define PCI_VENDOR_ATI 0x1002
> @@ -90,6 +99,73 @@
>
> extern DriverRec R128;
>
> +typedef enum
> +{
> + MT_UNKNOWN = -1,
> + MT_NONE = 0,
> + MT_CRT = 1,
> + MT_LCD = 2,
> + MT_DFP = 3,
> + MT_CTV = 4,
> + MT_STV = 5
> +} R128MonitorType;
> +
> +typedef enum
> +{
> + CONNECTOR_NONE,
> + CONNECTOR_VGA,
> + CONNECTOR_DVI_I,
> + CONNECTOR_DVI_D,
> + CONNECTOR_DVI_A,
> + CONNECTOR_LVDS
> +} R128ConnectorType;
> +
> +typedef enum
> +{
> + OUTPUT_NONE,
> + OUTPUT_VGA,
> + OUTPUT_DVI,
> + OUTPUT_LVDS
> +} R128OutputType;
> +
> +typedef struct {
> + CARD32 ddc_reg;
> + CARD32 put_clk_mask;
> + CARD32 put_data_mask;
> + CARD32 get_clk_mask;
> + CARD32 get_data_mask;
> +} R128I2CBusRec, *R128I2CBusPtr;
> +
> +typedef struct _R128CrtcPrivateRec {
> +#ifdef HAVE_XAA_H
> + FBLinearPtr rotate_mem_xaa;
> +#endif
> +#ifdef USE_EXA
> + ExaOffscreenArea *rotate_mem_exa;
> +#endif
> + int crtc_id;
> + CARD32 cursor_offset;
> + /* Lookup table values to be set when the CRTC is enabled */
> + CARD8 lut_r[256], lut_g[256], lut_b[256];
> +} R128CrtcPrivateRec, *R128CrtcPrivatePtr;
> +
> +typedef struct {
> + R128ConnectorType ConnectorType;
> + Bool valid;
> +} R128BIOSConnector;
> +
> +typedef struct _R128OutputPrivateRec {
> + int num;
> + R128OutputType type;
> + R128ConnectorType ConnectorType;
> + R128MonitorType MonType;
> + I2CBusPtr pI2CBus;
> + R128I2CBusRec ddc_i2c;
> +} R128OutputPrivateRec, *R128OutputPrivatePtr;
> +
> +#define R128_MAX_CRTC 2
> +#define R128_MAX_BIOS_CONNECTOR 2
> +
> typedef struct
> {
> Bool IsDRIEnabled;
> @@ -101,6 +177,9 @@ typedef struct
> Bool IsSecondaryRestored;
> Bool RestorePrimary;
>
> + xf86CrtcPtr pCrtc[R128_MAX_CRTC];
> + R128CrtcPrivatePtr Controller[R128_MAX_CRTC];
> +
> ScrnInfoPtr pSecondaryScrn;
> ScrnInfoPtr pPrimaryScrn;
> } R128EntRec, *R128EntPtr;
> diff --git a/src/r128_video.c b/src/r128_video.c
> index dccaa42..6439a24 100644
> --- a/src/r128_video.c
> +++ b/src/r128_video.c
> @@ -226,7 +226,7 @@ R128SetupImageVideo(ScreenPtr pScreen)
> return NULL;
>
> adapt->type = XvWindowMask | XvInputMask | XvImageMask;
> - adapt->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT;
> + adapt->flags = VIDEO_OVERLAID_IMAGES /*| VIDEO_CLIP_TO_VIEWPORT*/;
> adapt->name = "ATI Rage128 Video Overlay";
> adapt->nEncodings = 1;
> adapt->pEncodings = &DummyEncoding;
> @@ -849,6 +849,13 @@ R128PutImage(
> int top, left, npixels, nlines;
> BoxRec dstBox;
> CARD32 tmp;
> +
> + /* Currently, the video is only visible on the first monitor.
> + * In the future we could try to make this smarter, or just implement
> + * textured video. */
> + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
> + xf86CrtcPtr crtc = xf86_config->crtc[0];
> +
> #if X_BYTE_ORDER == X_BIG_ENDIAN
> unsigned char *R128MMIO = info->MMIO;
> CARD32 config_cntl = INREG(R128_CONFIG_CNTL);
> @@ -893,10 +900,10 @@ R128PutImage(
> clipBoxes, width, height))
> return Success;
>
> - dstBox.x1 -= pScrn->frameX0;
> - dstBox.x2 -= pScrn->frameX0;
> - dstBox.y1 -= pScrn->frameY0;
> - dstBox.y2 -= pScrn->frameY0;
> + dstBox.x1 -= crtc->x;
> + dstBox.x2 -= crtc->x;
> + dstBox.y1 -= crtc->y;
> + dstBox.y2 -= crtc->y;
>
> switch(id) {
> case FOURCC_YV12:
> --
> 1.9.3
>
> _______________________________________________
> xorg-driver-ati mailing list
> xorg-driver-ati at lists.x.org
> http://lists.x.org/mailman/listinfo/xorg-driver-ati
More information about the xorg-driver-ati
mailing list