1/*
2 * Copyright (C) 1998 The XFree86 Project, Inc.  All Rights Reserved.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to
6 * deal in the Software without restriction, including without limitation the
7 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 * sell copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
17 * XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
18 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 *
21 * Except as contained in this notice, the name of the XFree86 Project shall
22 * not be used in advertising or otherwise to promote the sale, use or other
23 * dealings in this Software without prior written authorization from the
24 * XFree86 Project.
25 */
26
27/*
28 * This is essentially a transfer of the 3.3 sources written by
29 * Marc Langenbach and Tim Rowley.
30 *
31 * The initial port of this driver to XFree86 4.0 was done by
32 * Marc Langenbach <mlangen@studcs.uni-sb.de>
33 * Additions, updates and bugfixes by Dejan Ilic <dejan.ilic@home.se>
34 */
35
36#ifdef HAVE_CONFIG_H
37#include "config.h"
38#endif
39
40/*
41 * includes
42 */
43
44#include "rendition.h"
45#include "rendition_options.h"
46
47#include "hwcursor.h"
48#include "xf86int10.h"
49
50#include "vtypes.h"
51#include "vboard.h"
52#include "vmodes.h"
53#include "vramdac.h"
54#include "rendition_shadow.h"
55#include "vbe.h"
56
57#ifdef XSERVER_LIBPCIACCESS
58# include <pciaccess.h>
59# define DEVICE_ID(p)  (p)->device_id
60#else
61# define DEVICE_ID(p)  (p)->chipType
62#endif
63
64
65/*
66 * defines
67 */
68
69#undef DEBUG
70
71#define RENDITION_NAME            "RENDITION"
72#define RENDITION_DRIVER_NAME     "rendition"
73#define RENDITION_VERSION_NAME    PACKAGE_VERSION
74#define RENDITION_VERSION_MAJOR   PACKAGE_VERSION_MAJOR
75#define RENDITION_VERSION_MINOR   PACKAGE_VERSION_MINOR
76#define RENDITION_PATCHLEVEL      PACKAGE_VERSION_PATCHLEVEL
77#define RENDITION_VERSION_CURRENT ((RENDITION_VERSION_MAJOR << 24) | \
78                 (RENDITION_VERSION_MINOR << 16) | RENDITION_PATCHLEVEL)
79
80/*
81 * Constants for the (theoretical) maximum width and height that can
82 * be used to display data on the CRT.  These were calculated from
83 * the HORZ and VERT macors, respectively, in vmodes.c.
84 */
85static const int MAX_HDISPLAY = 2048;
86static const int MAX_VDISPLAY = 2048;
87
88/*
89 * Constants for the (theoretical) maximum line length of a scan line
90 * and scan lines per screen (including overdraw).  These were
91 * calculated from the HORZ and VERT macors, respectively, in vmodes.c.
92 */
93static const int MAX_HTOTAL   = 2880;
94static const int MAX_VTOTAL   = 2184;
95
96/*
97 * local function prototypes
98 */
99
100static const OptionInfoRec * renditionAvailableOptions(int, int);
101static void       renditionIdentify(int);
102#ifdef XSERVER_LIBPCIACCESS
103static Bool renditionPciProbe(DriverPtr drv, int entity_num,
104    struct pci_device *dev, intptr_t match_data);
105#else
106static Bool       renditionProbe(DriverPtr, int);
107#endif
108static Bool       renditionPreInit(ScrnInfoPtr, int);
109static Bool       renditionScreenInit(SCREEN_INIT_ARGS_DECL);
110static Bool       renditionSwitchMode(SWITCH_MODE_ARGS_DECL);
111static void       renditionAdjustFrame(ADJUST_FRAME_ARGS_DECL);
112static Bool       renditionEnterVT(VT_FUNC_ARGS_DECL);
113static void       renditionLeaveVT(VT_FUNC_ARGS_DECL);
114static void       renditionFreeScreen(FREE_SCREEN_ARGS_DECL);
115
116static ModeStatus renditionValidMode(SCRN_ARG_TYPE, DisplayModePtr, Bool, int);
117static Bool renditionMapMem(ScrnInfoPtr pScreenInfo);
118static Bool renditionUnmapMem(ScrnInfoPtr pScreenInfo);
119#if 0
120static xf86MonPtr renditionDDC(ScrnInfoPtr pScreenInfo);
121static unsigned int renditionDDC1Read (ScrnInfoPtr pScreenInfo);
122#endif
123static xf86MonPtr renditionProbeDDC(ScrnInfoPtr pScrn, int index);
124
125static void renditionLoadPalette(ScrnInfoPtr, int, int *, LOCO *, VisualPtr);
126static renditionPtr renditionGetRec(ScrnInfoPtr pScreenInfo);
127
128
129/*
130 * global data
131 */
132
133OptionInfoRec const renditionOptions[]={
134    { OPTION_FBWC,      "FramebufferWC", OPTV_BOOLEAN, {0}, FALSE },
135    { OPTION_SW_CURSOR, "SW_Cursor", OPTV_BOOLEAN, {0}, FALSE },
136    { OPTION_NOACCEL,   "NoAccel",  OPTV_BOOLEAN, {0}, FALSE },
137    { OPTION_OVERCLOCK_MEM,"Overclock_Mem",  OPTV_BOOLEAN, {0}, FALSE },
138    { OPTION_NO_DDC,    "NoDDC",    OPTV_BOOLEAN, {0}, FALSE },
139    { OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE },
140    { OPTION_ROTATE,    "Rotate",   OPTV_ANYSTR,  {0}, FALSE },
141    { -1,                NULL,      OPTV_NONE,    {0}, FALSE }
142};
143
144enum renditionTypes {
145    CHIP_RENDITION_V1000,
146    CHIP_RENDITION_V2x00
147};
148
149/* supported chipsets */
150static SymTabRec renditionChipsets[] = {
151    {CHIP_RENDITION_V1000, "V1000"},
152    {CHIP_RENDITION_V2x00, "V2x00"},
153    {-1,                   NULL}
154};
155
156#ifdef XSERVER_LIBPCIACCESS
157#define RENDITION_DEVICE_MATCH(d, i) \
158    { 0x1163, (d), PCI_MATCH_ANY, PCI_MATCH_ANY, 0, 0, (i) }
159
160static const struct pci_id_match rendition_device_match[] = {
161    RENDITION_DEVICE_MATCH(PCI_CHIP_V1000, CHIP_RENDITION_V1000),
162    RENDITION_DEVICE_MATCH(PCI_CHIP_V2x00, CHIP_RENDITION_V2x00),
163
164    { 0, 0, 0 }
165};
166#else
167static PciChipsets renditionPCIchipsets[] = {
168  { CHIP_RENDITION_V1000, PCI_CHIP_V1000, RES_SHARED_VGA },
169  { CHIP_RENDITION_V2x00, PCI_CHIP_V2x00, RES_SHARED_VGA },
170  { -1,                   -1,             RES_UNDEFINED }
171};
172#endif
173
174_X_EXPORT DriverRec RENDITION={
175    RENDITION_VERSION_CURRENT,
176    "rendition",
177    renditionIdentify,
178#ifdef XSERVER_LIBPCIACCESS
179    NULL,
180#else
181    renditionProbe,
182#endif
183    renditionAvailableOptions,
184    NULL,
185    0,
186    NULL,
187
188#ifdef XSERVER_LIBPCIACCESS
189    rendition_device_match,
190    renditionPciProbe
191#endif
192};
193
194#ifdef XFree86LOADER
195
196/* Module loader interface */
197
198static MODULESETUPPROTO(renditionSetup);
199
200static XF86ModuleVersionInfo renditionVersionRec = {
201    RENDITION_DRIVER_NAME,
202    MODULEVENDORSTRING,
203    MODINFOSTRING1,
204    MODINFOSTRING2,
205    XORG_VERSION_CURRENT,
206    RENDITION_VERSION_MAJOR, RENDITION_VERSION_MINOR, RENDITION_PATCHLEVEL,
207    ABI_CLASS_VIDEODRV,
208    ABI_VIDEODRV_VERSION,
209    MOD_CLASS_VIDEODRV,
210    {0, 0, 0, 0}
211};
212
213_X_EXPORT XF86ModuleData renditionModuleData =
214               { &renditionVersionRec, renditionSetup, NULL };
215
216static pointer
217renditionSetup(pointer Module, pointer Options, int *ErrorMajor,
218               int *ErrorMinor)
219{
220    static Bool Initialised = FALSE;
221
222    if (!Initialised) {
223        Initialised = TRUE;
224        xf86AddDriver(&RENDITION, Module, 1);
225        return (pointer) TRUE;
226    }
227
228    if (ErrorMajor)
229        *ErrorMajor = LDR_ONCEONLY;
230
231    return NULL;
232}
233
234#endif
235
236
237/*
238 * functions
239 */
240
241static const OptionInfoRec *
242renditionAvailableOptions(int chipid, int busid)
243{
244    return renditionOptions;
245}
246
247static void
248renditionIdentify(int flags)
249{
250    xf86PrintChipsets(RENDITION_NAME,
251        "rendition driver (version " RENDITION_VERSION_NAME ") for chipsets",
252        renditionChipsets);
253}
254
255
256
257#ifdef XSERVER_LIBPCIACCESS
258static Bool
259renditionPciProbe(DriverPtr drv, int entity_num, struct pci_device *dev,
260		  intptr_t match_data)
261{
262    ScrnInfoPtr pScrn;
263
264
265    /* Allocate a ScrnInfoRec and claim the slot */
266    pScrn = xf86ConfigPciEntity(NULL, 0, entity_num, NULL, RES_SHARED_VGA,
267				NULL, NULL, NULL, NULL);
268    if (pScrn != NULL) {
269	renditionPtr pRendition;
270
271
272	pScrn->driverVersion = RENDITION_VERSION_CURRENT;
273	pScrn->driverName    = RENDITION_DRIVER_NAME;
274	pScrn->name          = RENDITION_NAME;
275	pScrn->Probe         = NULL;
276	pScrn->PreInit       = renditionPreInit;
277	pScrn->ScreenInit    = renditionScreenInit;
278	pScrn->SwitchMode    = renditionSwitchMode;
279	pScrn->AdjustFrame   = renditionAdjustFrame;
280	pScrn->EnterVT       = renditionEnterVT;
281	pScrn->LeaveVT       = renditionLeaveVT;
282	pScrn->FreeScreen    = renditionFreeScreen;
283	pScrn->ValidMode     = renditionValidMode;
284
285	/* allocate driver private structure */
286	pRendition = renditionGetRec(pScrn);
287	if (pRendition == NULL) {
288	    return FALSE;
289	}
290
291	pRendition->pEnt = xf86GetEntityInfo(entity_num);
292	pRendition->PciInfo = dev;
293    }
294
295    return (pScrn != NULL);
296}
297
298#else
299
300/*
301 * This function is called once, at the start of the first server generation to
302 * do a minimal probe for supported hardware.
303 */
304static Bool
305renditionProbe(DriverPtr drv, int flags)
306{
307    Bool foundScreen=FALSE;
308    int numDevSections, numUsed;
309    GDevPtr *devSections;
310    int *usedChips;
311    int c;
312
313    /* Find the config file Device sections that match this
314     * driver, and return if there are none. */
315    if ((numDevSections=xf86MatchDevice(RENDITION_DRIVER_NAME, &devSections)) <= 0)
316        return FALSE;
317
318    /* PCI BUS */
319    if (xf86GetPciVideoInfo()) {
320        numUsed=xf86MatchPciInstances(RENDITION_DRIVER_NAME, PCI_VENDOR_RENDITION,
321                    renditionChipsets, renditionPCIchipsets,
322                    devSections, numDevSections, drv, &usedChips);
323
324	free(devSections);
325	if (numUsed <= 0)
326	    return FALSE;
327
328        if (flags & PROBE_DETECT)
329            foundScreen = TRUE;
330        else for (c=0; c<numUsed; c++) {
331            ScrnInfoPtr pScrn;
332            /* Allocate a ScrnInfoRec and claim the slot */
333            pScrn=NULL;
334            if ((pScrn = xf86ConfigPciEntity(pScrn, 0,usedChips[c],
335						   renditionPCIchipsets, NULL,
336						   NULL, NULL, NULL, NULL))) {
337
338		pScrn->driverVersion=RENDITION_VERSION_CURRENT;
339		pScrn->driverName   =RENDITION_DRIVER_NAME;
340		pScrn->name         =RENDITION_NAME;
341		pScrn->Probe        =renditionProbe;
342		pScrn->PreInit      =renditionPreInit;
343		pScrn->ScreenInit   =renditionScreenInit;
344		pScrn->SwitchMode   =renditionSwitchMode;
345		pScrn->AdjustFrame  =renditionAdjustFrame;
346		pScrn->EnterVT      =renditionEnterVT;
347		pScrn->LeaveVT      =renditionLeaveVT;
348		pScrn->FreeScreen   =renditionFreeScreen;
349		pScrn->ValidMode    =renditionValidMode;
350		foundScreen=TRUE;
351	    }
352        }
353	free(usedChips);
354    }
355    return foundScreen;
356}
357#endif
358
359#if 0
360static Bool
361renditionClockSelect(ScrnInfoPtr pScreenInfo, int ClockNumber)
362{
363        vgaHWPtr pvgaHW = VGAHWPTR(pScreenInfo);
364        static CARD8 save_misc;
365
366        switch (ClockNumber)
367        {
368            case CLK_REG_SAVE:
369                save_misc = inb(pvgaHW->PIOOffset + VGA_MISC_OUT_R);
370                break;
371
372            case CLK_REG_RESTORE:
373                outb(pvgaHW->PIOOffset + VGA_MISC_OUT_W, save_misc);
374                break;
375
376            default:
377                outb(pvgaHW->PIOOffset + VGA_MISC_OUT_W,
378		     (save_misc & 0xF3) | ((ClockNumber << 2) & 0x0C));
379                break;
380        }
381
382    return TRUE;
383}
384#endif
385
386static renditionPtr
387renditionGetRec(ScrnInfoPtr pScreenInfo)
388{
389#ifdef DEBUG
390    ErrorF("GetRec ...!!!!\n");
391    sleep(1);
392#endif
393    if (!pScreenInfo->driverPrivate)
394        pScreenInfo->driverPrivate=calloc(sizeof(renditionRec), 1);
395
396    /* perhaps some initialization? <ml> */
397
398#ifdef DEBUG
399    ErrorF("GetRec ...!!!!\n");
400    sleep(1);
401#endif
402    return (renditionPtr)pScreenInfo->driverPrivate;
403}
404
405
406static void
407renditionFreeRec(ScrnInfoPtr pScreenInfo)
408{
409#ifdef DEBUG
410    ErrorF("FreeRec...!!!!\n");
411    sleep(1);
412#endif
413    if (xf86LoaderCheckSymbol("vgaHWFreeHWRec"))
414	vgaHWFreeHWRec(pScreenInfo);
415    free(pScreenInfo->driverPrivate);
416    pScreenInfo->driverPrivate=NULL;
417
418#ifdef DEBUG
419    ErrorF("FreeRec OK...!!!!\n");
420    sleep(1);
421#endif
422}
423
424#if 0
425static void
426renditionProtect(ScrnInfoPtr pScreenInfo, Bool On)
427{
428#ifdef DEBUG
429    ErrorF("Protect...!!!!\n");
430    sleep(1);
431#endif
432
433    vgaHWProtect(pScreenInfo, On);
434
435#ifdef DEBUG
436    ErrorF("Protect OK...!!!!\n");
437    sleep(1);
438#endif
439}
440#endif
441
442static Bool
443renditionSaveScreen(ScreenPtr pScreen, int mode)
444{
445#ifdef DEBUG
446    ErrorF("Savescreen...!!!!\n");
447    sleep(1);
448#endif
449
450    return vgaHWSaveScreen(pScreen, mode);
451}
452
453#if 0
454static void
455renditionBlankScreen(ScrnInfoPtr pScreenInfo, Bool Unblank)
456{
457#ifdef DEBUG
458    ErrorF("Blankscreen...!!!!\n");
459    sleep(1);
460#endif
461
462    vgaHWBlankScreen(pScreenInfo, Unblank);
463#ifdef DEBUG
464    ErrorF("Blankscreen OK...!!!!\n");
465    sleep(1);
466#endif
467}
468#endif
469
470
471/*
472 * This function is called once for each screen at the start of the first
473 * server generation to initialise the screen for all server generations.
474 */
475
476static Bool
477renditionPreInit(ScrnInfoPtr pScreenInfo, int flags)
478{
479    static ClockRange renditionClockRange = {NULL, 0, 135000, -1, FALSE, TRUE, 1, 1, 0};
480    MessageType       From;
481    int               videoRam, Rounding, nModes = 0;
482    renditionPtr      pRendition;
483    char             *in_string;
484    vgaHWPtr          pvgaHW;
485
486#ifdef DEBUG
487    ErrorF("Rendition: renditionPreInit() called\n");
488#endif
489
490    /* Check the number of entities, and fail if it isn't one. */
491    if (pScreenInfo->numEntities != 1)
492	return FALSE;
493
494#ifndef XSERVER_LIBPCIACCESS
495    /* allocate driver private structure */
496    if (!renditionGetRec(pScreenInfo))
497        return FALSE;
498#endif
499
500    pRendition=RENDITIONPTR(pScreenInfo);
501
502#ifndef XSERVER_LIBPCIACCESS
503    /* Get the entity, and make sure it is PCI. */
504    pRendition->pEnt = xf86GetEntityInfo(pScreenInfo->entityList[0]);
505    if (pRendition->pEnt->location.type != BUS_PCI)
506	return FALSE;
507#endif
508
509    if (flags & PROBE_DETECT) {
510        ConfiguredMonitor =
511	    renditionProbeDDC(pScreenInfo, pRendition->pEnt->index);
512        return TRUE;
513    }
514
515    /* set the monitor */
516    pScreenInfo->monitor=pScreenInfo->confScreen->monitor;
517
518    /* Initialize the card through int10 interface if needed */
519    if (xf86LoadSubModule(pScreenInfo, "int10")){
520        xf86Int10InfoPtr pInt=NULL;
521
522        xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO, "Initializing int10\n");
523        pInt = xf86InitInt10(pRendition->pEnt->index);
524        xf86FreeInt10(pInt);
525    }
526
527#ifndef XSERVER_LIBPCIACCESS
528    /* Find the PCI info for this screen */
529    pRendition->PciInfo = xf86GetPciInfoForEntity(pRendition->pEnt->index);
530    pRendition->pcitag= pciTag(pRendition->PciInfo->bus,
531               pRendition->PciInfo->device, pRendition->PciInfo->func);
532
533    /*
534     * XXX This could be refined if some VGA memory resources are not
535     * decoded in operating mode.
536     */
537    xf86SetOperatingState(resVgaMem, pRendition->pEnt->index, ResUnusedOpr);
538
539    if (xf86RegisterResources(pRendition->pEnt->index, NULL, ResExclusive))
540         return FALSE;
541
542
543    /* Operations for which memory access is required. */
544    pScreenInfo->racMemFlags = RAC_FB | RAC_CURSOR;
545    /* Operations for which I/O access is required. (XXX Check this) */
546    pScreenInfo->racIoFlags = RAC_FB | RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT;
547#endif
548    /* determine depth, bpp, etc. */
549    if (!xf86SetDepthBpp(pScreenInfo, 0, 0, 0, Support32bppFb))
550        return FALSE;
551
552    /* Verify that the color depth is supported. */
553    switch( pScreenInfo->depth ) {
554
555        case 8:
556        case 16:
557        case 24:
558        {
559            break;
560        }
561
562        case 15:
563        {
564            if (PCI_CHIP_V1000 == DEVICE_ID(pRendition->PciInfo)) {
565                xf86DrvMsg( pScreenInfo->scrnIndex, X_ERROR,
566                        "Given depth (%d) is not supported by this chipset.\n",
567                        pScreenInfo->depth);
568                return FALSE;
569            }
570        }
571
572        default:
573        {
574            xf86DrvMsg( pScreenInfo->scrnIndex, X_ERROR,
575                    "Given depth (%d) is not supported by this driver\n",
576                    pScreenInfo->depth );
577            return FALSE;
578        }
579
580    } /* End of switch( pScreenInfo->depth ) {*/
581
582
583    /* Print the color depth and frame buffer bits per pixel. */
584    xf86PrintDepthBpp( pScreenInfo );
585
586
587    /* collect all of the options flags and process them */
588
589    xf86CollectOptions(pScreenInfo, NULL);
590    if (!(pRendition->Options = malloc(sizeof(renditionOptions))))
591	return FALSE;
592    memcpy(pRendition->Options, renditionOptions, sizeof(renditionOptions));
593    xf86ProcessOptions(pScreenInfo->scrnIndex, pScreenInfo->options,
594        pRendition->Options);
595
596
597    /* Load fb */
598    if (!xf86LoadSubModule(pScreenInfo, "fb"))
599      return FALSE;
600
601    /* determine colour weights */
602    pScreenInfo->rgbBits=8;
603
604    if (pScreenInfo->depth > 8) {
605      rgb defaultWeight = {0, 0, 0};
606      rgb defaultMask = {0, 0, 0};
607
608      xf86PrintDepthBpp(pScreenInfo);
609
610      /* Standard defaults are OK if depths are OK */
611      if (!xf86SetWeight(pScreenInfo, defaultWeight, defaultMask))
612        return FALSE;
613      else{
614	/* XXX:  Check that returned weight is supported */
615      }
616    }
617
618    /* determine default visual */
619    if (!xf86SetDefaultVisual(pScreenInfo, -1))
620      return FALSE;
621
622    /* the gamma fields must be initialised when using the new cmap code */
623    if (pScreenInfo->depth > 1) {
624        Gamma zeros = {0.0, 0.0, 0.0};
625
626        if (!xf86SetGamma(pScreenInfo, zeros))
627            return FALSE;
628    }
629
630    /* the Rendition chips have a programmable clock */
631    pScreenInfo->progClock=TRUE;
632
633    /* set various fields according to the given options */
634    /* to be filled in <ml> */
635
636    if (PCI_CHIP_V1000 == DEVICE_ID(pRendition->PciInfo)) {
637      pRendition->board.chip=V1000_DEVICE;
638    }
639    else {
640      pRendition->board.chip=V2000_DEVICE;
641      renditionClockRange.maxClock = 170000;
642      renditionClockRange.clockIndex = -1;
643    }
644
645    if (!xf86LoadSubModule(pScreenInfo, "vgahw")){
646        return FALSE;
647    }
648
649    if (!vgaHWGetHWRec(pScreenInfo))
650        return FALSE;
651
652    pvgaHW = VGAHWPTR(pScreenInfo);
653    pvgaHW->MapSize = 0x00010000;       /* Standard 64kB VGA window */
654    vgaHWSetStdFuncs(pvgaHW);
655    vgaHWGetIOBase(pvgaHW);             /* Get VGA I/O base */
656
657#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 12
658    pRendition->board.vgaio_base = pvgaHW->PIOOffset;
659#else
660    pRendition->board.vgaio_base = 0;
661#endif
662    pRendition->board.io_base = pRendition->board.vgaio_base
663#ifdef XSERVER_LIBPCIACCESS
664	+ pRendition->PciInfo->regions[1].base_addr;
665#else
666	+ pRendition->PciInfo->ioBase[1]
667#endif
668	;
669    pRendition->board.mmio_base=0;
670    pRendition->board.vmmio_base=0;
671    pRendition->board.mem_size=0;
672#ifndef XSERVER_LIBPCIACCESS
673    pRendition->board.mem_base=(vu8 *)pRendition->PciInfo->memBase[0];
674#endif
675    pRendition->board.vmem_base=NULL;
676    pRendition->board.init=0;
677
678    if (pScreenInfo->chipset)
679        xf86DrvMsg(pScreenInfo->scrnIndex, X_CONFIG, "Chipset: \"%s\".\n",
680            pScreenInfo->chipset);
681    else
682        xf86DrvMsg(pScreenInfo->scrnIndex, X_PROBED, "Chipset: \"%s\".\n",
683            renditionChipsets[
684        pRendition->board.chip==V1000_DEVICE ? 0:1].name);
685
686    /* I do not get the IO base addres <ml> */
687    /* XXX Is this still true?  If so, the wrong base is being checked */
688    xf86DrvMsg(pScreenInfo->scrnIndex, X_PROBED,
689	       "Rendition %s @ %lx/%lx\n",
690	       renditionChipsets[pRendition->board.chip==V1000_DEVICE ? 0:1]
691	       .name,
692#ifdef XSERVER_LIBPCIACCESS
693	       pRendition->PciInfo->regions[1].base_addr,
694	       pRendition->PciInfo->regions[0].base_addr
695#else
696	       pRendition->PciInfo->ioBase[1],
697	       pRendition->PciInfo->memBase[0]
698#endif
699	       );
700
701    /* First of all get a "clean" starting state */
702    verite_resetboard(pScreenInfo);
703
704    /* determine video ram -- to do so, we assume a full size memory of 16M,
705     * then map it and use verite_getmemorysize() to determine the real
706     * amount of memory */
707    pScreenInfo->videoRam = 16<<10;
708    pRendition->board.mem_size = pScreenInfo->videoRam * 1024;
709    renditionMapMem(pScreenInfo);
710
711    videoRam=verite_getmemorysize(pScreenInfo)>>10;
712    renditionUnmapMem(pScreenInfo);
713
714    From = X_PROBED;
715    xf86DrvMsg(pScreenInfo->scrnIndex, From, "videoRam: %d kBytes\n", videoRam);
716    pScreenInfo->videoRam=videoRam;
717    pRendition->board.mem_size=videoRam * 1024;
718
719    /* Load the needed symbols */
720
721    pRendition->board.shadowfb=TRUE;
722
723    if ((in_string = xf86GetOptValString(pRendition->Options, OPTION_ROTATE))){
724	if(!xf86NameCmp(in_string, "CW")) {
725	    /* accel is disabled below for shadowFB */
726	    pRendition->board.shadowfb = TRUE;
727	    pRendition->board.rotate = 1;
728	    xf86DrvMsg(pScreenInfo->scrnIndex, X_CONFIG,
729		       "Rotating screen clockwise - acceleration disabled\n");
730	} else if(!xf86NameCmp(in_string, "CCW")) {
731	    pRendition->board.shadowfb = TRUE;
732	    pRendition->board.rotate = -1;
733	    xf86DrvMsg(pScreenInfo->scrnIndex, X_CONFIG,  "Rotating screen "
734		       "counter clockwise - acceleration disabled\n");
735	} else {
736	    xf86DrvMsg(pScreenInfo->scrnIndex, X_CONFIG,
737		       "\"%s\" is not a valid value for Option \"Rotate\"\n",
738		       in_string);
739	    xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
740		       "Valid options are \"CW\" or \"CCW\"\n");
741	}
742    }
743
744    if (xf86ReturnOptValBool(pRendition->Options, OPTION_SHADOW_FB,1)||
745	pRendition->board.rotate) {
746	if (!xf86LoadSubModule(pScreenInfo, "shadowfb")) {
747	    xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
748		       "Oops, \"ShadowFB\" module loading failed, disabling ShadowFB!\n");
749	}
750	else{
751	    pRendition->board.shadowfb=TRUE;
752	    xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
753		       "Using \"Shadow Framebuffer\"\n");
754	}
755    }
756    else {
757	pRendition->board.shadowfb=FALSE;
758	xf86DrvMsg(pScreenInfo->scrnIndex, X_CONFIG,
759		   "\"Shadow Framebuffer\" disabled\n");
760    }
761
762
763    /* Load Ramdac module if needed */
764    if (!xf86ReturnOptValBool(pRendition->Options, OPTION_SW_CURSOR,0) &&
765	!pRendition->board.rotate){
766      if (!xf86LoadSubModule(pScreenInfo, "ramdac")) {
767	return FALSE;
768      }
769    }
770
771#if 0
772    /* Load DDC module if needed */
773    if (!xf86ReturnOptValBool(pRendition->Options, OPTION_NO_DDC,0)){
774      if (!xf86LoadSubModule(pScreenInfo, "ddc")) {
775	xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR,
776		   ("Loading of DDC library failed, skipping DDC-probe\n"));
777      }
778      else {
779	pScreenInfo->monitor->DDC = renditionDDC(pScreenInfo);
780      }
781    }
782    else {
783      xf86DrvMsg(pScreenInfo->scrnIndex, X_CONFIG,
784		 ("Skipping DDC probe on users request\n"));
785    }
786#else
787    /* Load DDC module if needed */
788    if (!xf86ReturnOptValBool(pRendition->Options, OPTION_NO_DDC,0)){
789      if (!xf86LoadSubModule(pScreenInfo, "ddc")) {
790	xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR,
791		   ("Loading of DDC library failed, skipping DDC-probe\n"));
792      }
793      else {
794	  xf86MonPtr mon;
795	  mon = renditionProbeDDC(pScreenInfo, pRendition->pEnt->index);
796	  xf86PrintEDID(mon);
797	  xf86SetDDCproperties(pScreenInfo, mon);
798      }
799    }
800    else {
801      xf86DrvMsg(pScreenInfo->scrnIndex, X_CONFIG,
802		 ("Skipping DDC probe on users request\n"));
803    }
804#endif
805
806    /* Set the virtual X rounding (in bits) */
807    if (pScreenInfo->depth == 8)
808        Rounding = 16 * 8;
809    else
810        Rounding = 16;
811
812    /*
813     * Validate the modes.  Note that the limits passed to
814     * xf86ValidateModes() are VGA CRTC architectural limits.
815     */
816    nModes = xf86ValidateModes(pScreenInfo,
817            pScreenInfo->monitor->Modes, pScreenInfo->display->modes,
818            &renditionClockRange, NULL, 8, MAX_HDISPLAY, Rounding,
819            1, MAX_VDISPLAY, pScreenInfo->display->virtualX,
820            pScreenInfo->display->virtualY,
821            0x10000, LOOKUP_CLOSEST_CLOCK | LOOKUP_CLKDIV2);
822
823    if (nModes < 0)
824        return FALSE;
825
826    /* Remove invalid modes */
827    xf86PruneDriverModes(pScreenInfo);
828
829    /* Set CRTC values for the modes */
830    xf86SetCrtcForModes(pScreenInfo, 0);
831
832    /* Set current mode to the first in list */
833    pScreenInfo->currentMode = pScreenInfo->modes;
834
835    /* Print mode list */
836    xf86PrintModes(pScreenInfo);
837
838    /* Set display resolution */
839    xf86SetDpi(pScreenInfo, 0, 0);
840
841    /* Only one chipset here */
842    if (!pScreenInfo->chipset)
843        pScreenInfo->chipset = (char *)renditionChipsets[0].name;
844
845    if(!xf86ReturnOptValBool(pRendition->Options, OPTION_SW_CURSOR,0)){
846      if(!pRendition->board.rotate)
847	/* Do preemtive things for HW cursor */
848	RenditionHWCursorPreInit(pScreenInfo);
849      else{
850	xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
851		   "Hardware cursor not supported on rotated screen\n");
852	xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
853		   "Software cursor activated\n");
854      }
855    }
856    else
857      xf86DrvMsg(pScreenInfo->scrnIndex, X_CONFIG,
858		 "Software cursor selected\n");
859
860#ifdef DEBUG
861    ErrorF("PreInit OK...!!!!\n");
862    sleep(2);
863#endif
864
865    return TRUE;        /* Tada! */
866}
867
868
869/* Save mode on server entry */
870static void
871renditionSave(ScrnInfoPtr pScreenInfo)
872{
873#ifdef DEBUG
874    ErrorF("Save...!!!!\n");
875    sleep(1);
876#endif
877    vgaHWSave(pScreenInfo, &VGAHWPTR(pScreenInfo)->SavedReg,VGA_SR_ALL);
878
879#ifdef DEBUG
880    ErrorF("Save OK...!!!!\n");
881    sleep(1);
882#endif
883}
884
885#if 0
886/* Restore the mode that was saved on server entry */
887static void
888renditionRestore(ScrnInfoPtr pScreenInfo)
889{
890#ifdef DEBUG
891    ErrorF("Restore...!!!!\n");
892    sleep(1);
893#endif
894
895    vgaHWProtect(pScreenInfo, TRUE);
896    vgaHWRestore(pScreenInfo, &VGAHWPTR(pScreenInfo)->SavedReg, VGA_SR_ALL);
897    vgaHWProtect(pScreenInfo, FALSE);
898
899    verite_setmode(pScreenInfo, &RENDITIONPTR(pScreenInfo)->mode);
900
901#ifdef DEBUG
902    ErrorF("Restore OK...!!!!\n");
903    sleep(1);
904#endif
905}
906#endif
907
908/* Set a graphics mode */
909static Bool
910renditionSetMode(ScrnInfoPtr pScreenInfo, DisplayModePtr pMode)
911{
912    struct verite_modeinfo_t *modeinfo=&RENDITIONPTR(pScreenInfo)->mode;
913
914#ifdef DEBUG
915    ErrorF("RENDITION: renditionSetMode() called\n");
916    ErrorF("Setmode...!!!!\n");
917    sleep(1);
918#endif
919
920    /* construct a modeinfo for the verite_setmode function */
921    modeinfo->clock=pMode->SynthClock;
922    modeinfo->hdisplay=pMode->HDisplay;
923    modeinfo->hsyncstart=pMode->HSyncStart;
924    modeinfo->hsyncend=pMode->HSyncEnd;
925    modeinfo->htotal=pMode->HTotal;
926    modeinfo->hskew=pMode->HSkew;
927    modeinfo->vdisplay=pMode->VDisplay;
928    modeinfo->vsyncstart=pMode->VSyncStart;
929    modeinfo->vsyncend=pMode->VSyncEnd;
930    modeinfo->vtotal=pMode->VTotal;
931
932    modeinfo->screenwidth = pMode->HDisplay;
933    modeinfo->virtualwidth = pScreenInfo->virtualX & 0xfff8;
934    modeinfo->screenheight = pMode->VDisplay;
935    modeinfo->virtualheight = pScreenInfo->virtualY & 0xfff8;
936
937    if ((pMode->Flags&(V_PHSYNC|V_NHSYNC))
938        && (pMode->Flags&(V_PVSYNC|V_NVSYNC))) {
939        modeinfo->hsynchi=((pMode->Flags&V_PHSYNC) == V_PHSYNC);
940        modeinfo->vsynchi=((pMode->Flags&V_PVSYNC) == V_PVSYNC);
941    }
942    else {
943        int VDisplay=pMode->VDisplay;
944        if (pMode->Flags & V_DBLSCAN)
945            VDisplay*=2;
946        if (VDisplay < 400) {
947            /* +hsync -vsync */
948            modeinfo->hsynchi=1;
949            modeinfo->vsynchi=0;
950        }
951        else if (VDisplay < 480) {
952            /* -hsync +vsync */
953            modeinfo->hsynchi=0;
954            modeinfo->vsynchi=1;
955        }
956        else if (VDisplay < 768) {
957            /* -hsync -vsync */
958            modeinfo->hsynchi=0;
959            modeinfo->vsynchi=0;
960        }
961        else {
962            /* +hsync +vsync */
963            modeinfo->hsynchi=1;
964            modeinfo->vsynchi=1;
965        }
966    }
967
968    switch (pScreenInfo->bitsPerPixel) {
969        case 8:
970            modeinfo->bitsperpixel=8;
971            modeinfo->pixelformat=V_PIXFMT_8I;
972            break;
973        case 16:
974            modeinfo->bitsperpixel=16;
975            if (pScreenInfo->weight.green == 5)
976                /* on a V1000, this looks too 'red/magenta' <ml> */
977                modeinfo->pixelformat=V_PIXFMT_1555;
978            else
979                modeinfo->pixelformat=V_PIXFMT_565;
980            break;
981        case 32:
982            modeinfo->bitsperpixel=32;
983            modeinfo->pixelformat=V_PIXFMT_8888;
984            break;
985    }
986    modeinfo->fifosize=128;
987    modeinfo->flags=pMode->Flags;
988
989    verite_setmode(pScreenInfo,&RENDITIONPTR(pScreenInfo)->mode);
990#ifdef DEBUG
991    ErrorF("Setmode OK...!!!!\n");
992    sleep(1);
993#endif
994    return TRUE;
995}
996
997static void
998renditionLeaveGraphics(ScrnInfoPtr pScreenInfo)
999{
1000    renditionPtr pRendition = RENDITIONPTR(pScreenInfo);
1001
1002#ifdef DEBUG
1003    ErrorF("RENDITION: renditionLeaveGraphics() called\n");
1004    sleep(1);
1005#endif
1006    verite_restore(pScreenInfo, &pRendition->saveRegs);
1007
1008    vgaHWProtect(pScreenInfo, TRUE);
1009    vgaHWRestore(pScreenInfo, &VGAHWPTR(pScreenInfo)->SavedReg, VGA_SR_ALL);
1010    vgaHWProtect(pScreenInfo, FALSE);
1011
1012    vgaHWLock(VGAHWPTR(pScreenInfo));
1013
1014#ifdef DEBUG
1015    ErrorF("Leavegraphics OK...!!!!\n");
1016    sleep(1);
1017#endif
1018}
1019
1020
1021/* Unravel the screen */
1022static Bool
1023renditionCloseScreen(CLOSE_SCREEN_ARGS_DECL)
1024{
1025    ScrnInfoPtr pScreenInfo = xf86ScreenToScrn(pScreen);
1026    renditionPtr prenditionPriv=renditionGetRec(pScreenInfo);
1027    Bool Closed = TRUE;
1028
1029#ifdef DEBUG
1030    ErrorF("RENDITION: renditionCloseScreen() called\n");
1031    sleep(1);
1032#endif
1033
1034    if (prenditionPriv->board.hwcursor_used)
1035	RenditionHWCursorRelease(pScreenInfo);
1036
1037    if (pScreenInfo->vtSema)
1038	renditionLeaveGraphics(pScreenInfo);
1039
1040    pScreenInfo->vtSema = FALSE;
1041
1042    if (prenditionPriv
1043	&& (pScreen->CloseScreen = prenditionPriv->CloseScreen)) {
1044        prenditionPriv->CloseScreen = NULL;
1045        Closed = (*pScreen->CloseScreen)(CLOSE_SCREEN_ARGS);
1046    }
1047
1048#ifdef DEBUG
1049    ErrorF("Closescreen OK...!!!!\n");
1050    sleep(1);
1051#endif
1052    return Closed;
1053}
1054
1055
1056static void
1057renditionDPMSSet(ScrnInfoPtr pScreen, int mode, int flags)
1058{
1059#ifdef DEBUG
1060    ErrorF("RENDITION: renditionDPMSSet() called\n");
1061#endif
1062
1063    vgaHWDPMSSet(pScreen, mode, flags);
1064}
1065
1066static Bool
1067renditionScreenInit(SCREEN_INIT_ARGS_DECL)
1068{
1069    ScrnInfoPtr pScreenInfo = xf86ScreenToScrn(pScreen);
1070    renditionPtr pRendition = RENDITIONPTR(pScreenInfo);
1071    Bool Inited = FALSE;
1072    unsigned char *FBBase;
1073    VisualPtr visual;
1074    vgaHWPtr pvgaHW;
1075    int displayWidth,width,height;
1076    int scrnIndex = pScreenInfo->scrnIndex;
1077
1078#ifdef DEBUG
1079    ErrorF("RENDITION: renditionScreenInit() called\n");
1080    sleep(1);
1081#endif
1082    /* Get vgahw private     */
1083    pvgaHW = VGAHWPTR(pScreenInfo);
1084
1085    /* Get driver private */
1086    pRendition=renditionGetRec(pScreenInfo);
1087
1088    /* Save the current state and setup the current mode */
1089    renditionSave(pScreenInfo);
1090
1091    /* Map VGA aperture */
1092    if (!vgaHWMapMem(pScreenInfo))
1093        return FALSE;
1094
1095    if (!renditionMapMem(pScreenInfo))
1096	return FALSE;
1097
1098    /* Unlock VGA registers */
1099    vgaHWUnlock(pvgaHW);
1100
1101    verite_save(pScreenInfo);
1102
1103    pScreenInfo->vtSema = TRUE;
1104
1105    if (!renditionSetMode(pScreenInfo, pScreenInfo->currentMode))
1106        return FALSE;
1107
1108    /* blank the screen */
1109    renditionSaveScreen(pScreen, SCREEN_SAVER_ON);
1110
1111    (*pScreenInfo->AdjustFrame)(ADJUST_FRAME_ARGS(pScreenInfo,
1112						  pScreenInfo->frameX0, pScreenInfo->frameY0));
1113
1114
1115    miClearVisualTypes();
1116
1117    if (!miSetVisualTypes(pScreenInfo->depth,
1118			  miGetDefaultVisualMask(pScreenInfo->depth),
1119			  pScreenInfo->rgbBits, pScreenInfo->defaultVisual))
1120	return FALSE;
1121
1122    miSetPixmapDepths ();
1123
1124    if (pRendition->board.rotate) {
1125	height = pScreenInfo->virtualX;
1126	width = pScreenInfo->virtualY;
1127    } else {
1128	width = pScreenInfo->virtualX;
1129	height = pScreenInfo->virtualY;
1130    }
1131
1132    if(pRendition->board.shadowfb) {
1133	pRendition->board.shadowPitch
1134	    = BitmapBytePad(pScreenInfo->bitsPerPixel * width);
1135	pRendition->board.shadowPtr
1136	    = malloc(pRendition->board.shadowPitch * height);
1137	displayWidth = pRendition->board.shadowPitch
1138	    / (pScreenInfo->bitsPerPixel >> 3);
1139	FBBase = pRendition->board.shadowPtr;
1140    } else {
1141	pRendition->board.shadowPtr = NULL;
1142	FBBase = pRendition->board.vmem_base+pRendition->board.fbOffset;
1143	displayWidth=pScreenInfo->displayWidth;
1144    }
1145
1146    Inited = fbScreenInit(pScreen, FBBase,
1147			  width, height,
1148			  pScreenInfo->xDpi, pScreenInfo->yDpi,
1149			  displayWidth,
1150			  pScreenInfo->bitsPerPixel);
1151
1152    if (!Inited)
1153        return FALSE;
1154
1155    if (pScreenInfo->bitsPerPixel > 8) {
1156        /* Fixup RGB ordering */
1157        visual=pScreen->visuals+pScreen->numVisuals;
1158        while (--visual >= pScreen->visuals) {
1159	    if ((visual->class | DynamicClass) == DirectColor){
1160		visual->offsetRed = pScreenInfo->offset.red;
1161		visual->offsetGreen = pScreenInfo->offset.green;
1162		visual->offsetBlue = pScreenInfo->offset.blue;
1163		visual->redMask = pScreenInfo->mask.red;
1164		visual->greenMask = pScreenInfo->mask.green;
1165		visual->blueMask = pScreenInfo->mask.blue;
1166	    }
1167	}
1168    }
1169
1170    /* must be after RGB ordering fixed */
1171    fbPictureInit (pScreen, 0, 0);
1172
1173    xf86SetBlackWhitePixels(pScreen);
1174
1175    /*********************************************************/
1176    /* The actual setup of the driver-specific code          */
1177    /* has to be after fbScreenInit and before cursor init */
1178    /*********************************************************/
1179
1180    /* Initialise cursor functions */
1181    xf86SetSilkenMouse(pScreen);
1182    miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
1183
1184    if(!xf86ReturnOptValBool(pRendition->Options, OPTION_SW_CURSOR,0)&&
1185       !pRendition->board.rotate){
1186	/* Initialise HW cursor */
1187	if(!RenditionHWCursorInit(pScreen)){
1188	    xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR,
1189		       "Hardware Cursor initalization failed!!\n");
1190	}
1191    }
1192
1193    if (pRendition->board.shadowfb) {
1194	RefreshAreaFuncPtr refreshArea = renditionRefreshArea;
1195
1196	if(pRendition->board.rotate) {
1197	    if (!pRendition->board.PointerMoved) {
1198		pRendition->board.PointerMoved = pScreenInfo->PointerMoved;
1199		pScreenInfo->PointerMoved = renditionPointerMoved;
1200	    }
1201
1202	    switch(pScreenInfo->bitsPerPixel) {
1203		case 8:         refreshArea = renditionRefreshArea8;  break;
1204		case 16:        refreshArea = renditionRefreshArea16; break;
1205		case 24:        refreshArea = renditionRefreshArea24; break;
1206		case 32:        refreshArea = renditionRefreshArea32; break;
1207	    }
1208	}
1209
1210	ShadowFBInit(pScreen, refreshArea);
1211    }
1212
1213    /* Setup default colourmap */
1214    if (!miCreateDefColormap(pScreen))
1215	return FALSE;
1216
1217    /* Try the new code based on the new colormap layer */
1218    if (pScreenInfo->depth > 1)
1219	if (!xf86HandleColormaps(pScreen, 256, pScreenInfo->rgbBits,
1220				 renditionLoadPalette, NULL,
1221				 CMAP_RELOAD_ON_MODE_SWITCH)) {
1222	    xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR,
1223		       "Colormap initialization failed\n");
1224	    return FALSE;
1225	}
1226
1227    xf86DPMSInit(pScreen, renditionDPMSSet, 0);
1228
1229    if (xf86ReturnOptValBool(pRendition->Options, OPTION_OVERCLOCK_MEM,0)) {
1230	pRendition->board.overclock_mem=TRUE;
1231    }
1232
1233    /* Wrap the screen's CloseScreen vector and set its SaveScreen vector */
1234    pRendition->CloseScreen = pScreen->CloseScreen;
1235    pScreen->CloseScreen = renditionCloseScreen;
1236    pScreen->SaveScreen = renditionSaveScreen;
1237
1238    if (!Inited)
1239        renditionCloseScreen(CLOSE_SCREEN_ARGS);
1240
1241    if (serverGeneration == 1)
1242	xf86ShowUnusedOptions(pScreenInfo->scrnIndex, pScreenInfo->options);
1243
1244#ifdef DEBUG
1245    ErrorF("ScreenInit OK...!!!!\n");
1246    sleep(1);
1247#endif
1248    return Inited;
1249}
1250
1251static Bool
1252renditionSwitchMode(SWITCH_MODE_ARGS_DECL)
1253{
1254    SCRN_INFO_PTR(arg);
1255#ifdef DEBUG
1256    ErrorF("RENDITION: renditionSwitchMode() called\n");
1257#endif
1258    return renditionSetMode(pScreenInfo, mode);
1259}
1260
1261
1262static void
1263renditionAdjustFrame(ADJUST_FRAME_ARGS_DECL)
1264{
1265    SCRN_INFO_PTR(arg);
1266    renditionPtr pRendition = RENDITIONPTR(pScreenInfo);
1267    int offset, virtualwidth, bitsPerPixel;
1268
1269#ifdef DEBUG
1270    ErrorF("RENDITION: renditionAdjustFrame() called\n");
1271#endif
1272
1273    bitsPerPixel=pScreenInfo->bitsPerPixel;
1274    virtualwidth=pRendition->mode.virtualwidth;
1275    offset=(y*virtualwidth+x)*(bitsPerPixel>>3);
1276
1277    offset+= pRendition->board.fbOffset;
1278
1279#ifdef DEBUG
1280    ErrorF ("MOVING SCREEN %d bytes!!\n",offset);
1281#endif
1282    verite_setframebase(pScreenInfo, offset);
1283}
1284
1285
1286static Bool
1287renditionEnterVT(VT_FUNC_ARGS_DECL)
1288{
1289    SCRN_INFO_PTR(arg);
1290    vgaHWPtr pvgaHW = VGAHWPTR(pScreenInfo);
1291
1292#ifdef DEBUG
1293    ErrorF("RENDITION: renditionEnterVT() called\n");
1294#endif
1295
1296    /* Map VGA aperture */
1297    if (!vgaHWMapMem(pScreenInfo))
1298        return FALSE;
1299
1300    /* Unlock VGA registers */
1301    vgaHWUnlock(pvgaHW);
1302
1303    if (!renditionSetMode(pScreenInfo, pScreenInfo->currentMode))
1304        return FALSE;
1305
1306    (*pScreenInfo->AdjustFrame)(ADJUST_FRAME_ARGS(pScreenInfo,
1307						  pScreenInfo->frameX0, pScreenInfo->frameY0));
1308
1309    return TRUE;
1310}
1311
1312
1313static void
1314renditionLeaveVT(VT_FUNC_ARGS_DECL)
1315{
1316    SCRN_INFO_PTR(arg);
1317#ifdef DEBUG
1318    ErrorF("RENDITION: renditionLeaveVT() called\n");
1319#endif
1320    renditionLeaveGraphics(pScreenInfo);
1321}
1322
1323
1324static void
1325renditionFreeScreen(FREE_SCREEN_ARGS_DECL)
1326{
1327    SCRN_INFO_PTR(arg);
1328    renditionFreeRec(pScreenInfo);
1329}
1330
1331
1332static ModeStatus
1333renditionValidMode(SCRN_ARG_TYPE arg, DisplayModePtr pMode, Bool Verbose,
1334		   int flags)
1335{
1336    if (pMode->Flags & V_INTERLACE)
1337        return MODE_NO_INTERLACE;
1338
1339    return MODE_OK;
1340}
1341
1342static Bool
1343renditionMapMem(ScrnInfoPtr pScreenInfo)
1344{
1345    Bool WriteCombine;
1346    int mapOption;
1347    renditionPtr pRendition = RENDITIONPTR(pScreenInfo);
1348#ifdef XSERVER_LIBPCIACCESS
1349    int err;
1350#endif
1351
1352#ifdef DEBUG
1353    ErrorF("Mapping ...\n");
1354#ifndef XSERVER_LIBPCIACCESS
1355    ErrorF("%d %d %d %x %d\n", pScreenInfo->scrnIndex, VIDMEM_FRAMEBUFFER,
1356	   pRendition->pcitag,
1357	   pRendition->board.mem_base, pScreenInfo->videoRam * 1024);
1358#endif
1359#endif
1360
1361    if (pRendition->board.chip == V1000_DEVICE){
1362	/* Some V1000 boards are known to have problems with Write-Combining */
1363	/* V2x00 also found to have similar problems with memcpy & WC ! */
1364	WriteCombine = 0;
1365    } else {
1366	/* Activate Write_Combine if possible */
1367	WriteCombine = 1;
1368    }
1369       /* Override on users request */
1370    WriteCombine
1371	= xf86ReturnOptValBool(pRendition->Options, OPTION_FBWC, WriteCombine);
1372#ifdef XSERVER_LIBPCIACCESS
1373    mapOption = PCI_DEV_MAP_FLAG_WRITABLE;
1374    if (WriteCombine)
1375	mapOption |= PCI_DEV_MAP_FLAG_WRITE_COMBINE;
1376
1377    err = pci_device_map_range(pRendition->PciInfo,
1378			       pRendition->PciInfo->regions[0].base_addr,
1379			       pRendition->PciInfo->regions[0].size,
1380			       mapOption, (void *)&pRendition->board.vmem_base);
1381
1382    return (err == 0);
1383#else
1384    if (WriteCombine) {
1385	xf86DrvMsg(pScreenInfo->scrnIndex, X_CONFIG,
1386		   ("Requesting Write-Combined memory access\n"));
1387	mapOption = VIDMEM_FRAMEBUFFER;
1388    } else {
1389	xf86DrvMsg(pScreenInfo->scrnIndex, X_CONFIG,
1390		   ("Requesting MMIO-style memory access\n"));
1391	mapOption = VIDMEM_MMIO;
1392    }
1393
1394    pRendition->board.vmem_base=
1395        xf86MapPciMem(pScreenInfo->scrnIndex, mapOption,
1396		      pRendition->pcitag,
1397		      (unsigned long)pRendition->board.mem_base,
1398		      pScreenInfo->videoRam * 1024);
1399    return TRUE;
1400#endif
1401
1402#ifdef DEBUG0
1403    ErrorF("Done\n");
1404#endif
1405}
1406
1407static Bool
1408renditionUnmapMem(ScrnInfoPtr pScreenInfo)
1409{
1410  renditionPtr pRendition = RENDITIONPTR(pScreenInfo);
1411#ifdef DEBUG
1412  ErrorF("Unmapping ...\n");
1413#endif
1414
1415#ifndef XSERVER_LIBPCIACCESS
1416    xf86UnMapVidMem(pScreenInfo->scrnIndex,
1417        pRendition->board.vmem_base,
1418		    pScreenInfo->videoRam * 1024);
1419#else
1420    pci_device_unmap_range(pRendition->PciInfo,
1421			   pRendition->board.vmem_base,
1422			   pRendition->PciInfo->regions[0].size);
1423#endif
1424    return TRUE;
1425#ifdef DEBUG0
1426    ErrorF("Done\n");
1427#endif
1428}
1429
1430static void
1431renditionLoadPalette(ScrnInfoPtr pScreenInfo, int numColors,
1432		     int *indices, LOCO *colors,
1433		     VisualPtr pVisual)
1434{
1435  verite_setpalette(pScreenInfo, numColors, indices, colors, pVisual);
1436}
1437
1438xf86MonPtr
1439renditionProbeDDC(ScrnInfoPtr pScreenInfo, int index)
1440{
1441  vbeInfoPtr pVbe;
1442  xf86MonPtr mon = NULL;
1443
1444  if (xf86LoadSubModule(pScreenInfo, "vbe")) {
1445    pVbe = VBEInit(NULL,index);
1446    mon = vbeDoEDID(pVbe, NULL);
1447    vbeFree(pVbe);
1448  }
1449  return mon;
1450}
1451
1452# if 0
1453static xf86MonPtr
1454renditionDDC (ScrnInfoPtr pScreenInfo)
1455{
1456  renditionPtr pRendition = RENDITIONPTR(pScreenInfo);
1457  unsigned long iob=pRendition->board.io_base;
1458  vu32 temp;
1459
1460  xf86MonPtr MonInfo = NULL;
1461  temp = verite_in32(iob+CRTCCTL); /* Remember original value */
1462
1463  /* Enable DDC1 */
1464  verite_out32(iob+CRTCCTL,(temp|
1465		       CRTCCTL_ENABLEDDC|
1466		       CRTCCTL_VSYNCENABLE|
1467		       CRTCCTL_VIDEOENABLE));
1468
1469  MonInfo = xf86DoEDID_DDC1(pScreenInfo->scrnIndex,
1470			    vgaHWddc1SetSpeed,
1471			    renditionDDC1Read );
1472
1473  verite_out32(iob+CRTCCTL,temp); /* return the original values */
1474
1475  xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
1476	     "DDC Monitor info: %p\n", MonInfo);
1477
1478  xf86PrintEDID( MonInfo );
1479  xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
1480	     "end of DDC Monitor info\n\n");
1481
1482  /* xf86SetDDCproperties(pScreenInfo, MonInfo); */
1483  return MonInfo;
1484}
1485
1486static unsigned int
1487renditionDDC1Read (ScrnInfoPtr pScreenInfo)
1488{
1489  renditionPtr pRendition = RENDITIONPTR(pScreenInfo);
1490  unsigned long iob=pRendition->board.io_base;
1491  vu32 value = 0;
1492
1493  /* wait for Vsync */
1494  while (!(verite_in32(iob+CRTCSTATUS) & CRTCSTATUS_VERT_SYNC));
1495  while (verite_in32(iob+CRTCSTATUS) & CRTCSTATUS_VERT_SYNC);
1496
1497  /* Read the value */
1498  value = verite_in32(iob+CRTCCTL) & CRTCCTL_DDCDATA;
1499  return value;
1500}
1501
1502#endif
1503