コード例 #1
0
ファイル: vmodes.c プロジェクト: rickgaiser/xfree86-ps2
int v_setmode(struct v_board_t *board, struct v_modeinfo_t *mode)
{
    int tmp;
    int doubleclock=0;
    int M, N, P;
    int iob=board->io_base;
 
    /* switching to native mode */
    v_out8(iob+MODEREG, NATIVE_MODE|VESA_MODE);

    /* flipping some bytes */
    /* Must be something better to do than this -- FIX */
    switch (mode->bitsperpixel) {
    case 32:
      v_out8(iob+MEMENDIAN, MEMENDIAN_NO);
      break;
    case 16:
      v_out8(iob+MEMENDIAN, MEMENDIAN_HW);
      break;
    case 8:
      v_out8(iob+MEMENDIAN, MEMENDIAN_END);
      break;
    }

    if (OFLG_ISSET(OPTION_OVERCLOCK_MEM, &vga256InfoRec.options)) {
	/* increase Mem/Sys clock to avoid nasty artifacts */
	if (board->chip != V1000_DEVICE) {
	  v_out32(iob+SCLKPLL, 0xa484d);  /* mclk=110 sclk=55 */
					  /* M/N/P/P = 77/5/2/4 */
	  usleep(500);
	}
    }

    /* this has something to do with memory */
    tmp=v_in32(iob+DRAMCTL)&0xdfff;              /* reset bit 13 */
    v_out32(iob+DRAMCTL, tmp|0x330000);
 
    /* program pixel clock */
    if (board->chip == V1000_DEVICE) {
        if (110.0 < V1000CalcClock(mode->clock/1000.0, &M, &N, &P)) {
            P++;
            doubleclock=1;
        }
        set_PLL(iob, combineNMP(N, M, P));
    } 
    else {
	tmp = (~0x1800) & v_in32(iob+DRAMCTL);
        v_out32(iob+DRAMCTL, tmp);
        V2200CalcClock(mode->clock/1000.0, &M, &N, &P);
        v_out32(iob+PCLKPLL, v2kcombineNMP(N, M, P));
    }
    usleep(500);

    /* init the ramdac */
    v_initdac(board, mode->bitsperpixel, doubleclock);

    v_out32(iob+CRTCHORZ, HORZ(mode->hsyncstart-mode->hdisplay, 
                               mode->hsyncend-mode->hsyncstart,
                               mode->htotal-mode->hsyncend,
                               mode->hdisplay));
    v_out32(iob+CRTCVERT, VERT(mode->vsyncstart-mode->vdisplay, 
                               mode->vsyncend-mode->vsyncstart,
                               mode->vtotal-mode->vsyncend,
                               mode->vdisplay));

    /* fill in the mode parameters */
    memcpy(&(board->mode), mode, sizeof(struct v_modeinfo_t));
    board->mode.fifosize=128;
    board->mode.pll_m=M;
    board->mode.pll_n=N;
    board->mode.pll_p=P;
    board->mode.doubleclock=doubleclock;
    if (0 == board->mode.virtualwidth)
        board->mode.virtualwidth=board->mode.screenwidth;

    board->init=1;
    v_setframebase(board, 0);

    /* Need to fix up syncs */

    /* enable the display */
    v_out32(iob+CRTCCTL, CTL(0, mode->hsynchi, mode->vsynchi)
                        |mode->pixelformat
                        |CRTCCTL_VIDEOFIFOSIZE128
                        |CRTCCTL_HSYNCENABLE
                        |CRTCCTL_VSYNCENABLE
                        |CRTCCTL_VIDEOENABLE);
   return 0;
}
コード例 #2
0
ファイル: s3init.c プロジェクト: rickgaiser/xfree86-ps2
void
s3CleanUp(void)
{
   int   i;
   unsigned char tmp;

   outb(vgaCRIndex, 0x39);
   outb(vgaCRReg, 0xa5);

   if (s3MmioMem != NULL ) {
      WaitIdle();
      VerticalRetraceWait();
      ((mmtr)s3MmioMem)->memport_regs.regs.fifo_control = oldS3->fifo[0];
      WaitIdle();                  /* Don't ask... */
      ((mmtr)s3MmioMem)->memport_regs.regs.streams_timeout = oldS3->fifo[1];
   }

   #if 1			   
   			/* This seems to help, but maybe a wait for */
			/* VSYNC would be better than WaitIdleEmpty(). */
   				/* STREAMS disable code, for 24 & 32 Bpp */
   if ( ( s3InfoRec.bitsPerPixel == 32 || 
          s3InfoRec.bitsPerPixel == 24 ) &&
          s3MmioMem != NULL ) {
	  			/* temp - KJB */
       ((mmtr)s3MmioMem)->streams_regs.regs.prim_fbaddr0 = 0;
	      /*  ((y * s3DisplayWidth + (x & ~3)) * s3Bpp) */ /* & ~3 */;
	      			/* end temp */
       
       outb(vgaCRIndex, 0x67);
       tmp = inb(vgaCRReg);
       /* WaitIdleEmpty(); */
 				/* Disable STREAMS processor */
       outb( vgaCRReg, tmp & ~0x0C );
   }	
   #endif

   vgaProtect(TRUE);

   if (s3NewMmio)	{
      outb (vgaCRIndex, 0x58);
      outb (vgaCRReg, s3SAM256); /* disable linear mode */
   } /* end BL */


   WaitQueue(8);
   outb(vgaCRIndex, 0x35);
   tmp = inb(vgaCRReg);
   outb(vgaCRReg, (tmp & 0xf0));
   cebank();

   if (s3NewMmio) {
      outb(vgaCRIndex, 0x53);
      outb(vgaCRReg, 0x00);
   }

   /* Restore S3 Trio32/64 ext. sequenzer (PLL) registers */
   if (DAC_IS_TRIO)
   {
      outb(0x3c2, oldS3->Trio[0]);
      outb(0x3c4, 0x08); outb(0x3c5, 0x06);

      outb(0x3c4, 0x09); outb(0x3c5, oldS3->Trio[2]);
      outb(0x3c4, 0x0a); outb(0x3c5, oldS3->Trio[3]);
      outb(0x3c4, 0x0b); outb(0x3c5, oldS3->Trio[4]);
      outb(0x3c4, 0x0d); outb(0x3c5, oldS3->Trio[5]);

      outb(0x3c4, 0x10); outb(0x3c5, oldS3->Trio[8]);
      outb(0x3c4, 0x11); outb(0x3c5, oldS3->Trio[9]);
      outb(0x3c4, 0x12); outb(0x3c5, oldS3->Trio[10]);
      outb(0x3c4, 0x13); outb(0x3c5, oldS3->Trio[11]);
      outb(0x3c4, 0x1a); outb(0x3c5, oldS3->Trio[12]);
      outb(0x3c4, 0x1b); outb(0x3c5, oldS3->Trio[13]);
      outb(0x3c4, 0x15);
      tmp = inb(0x3c5) & ~0x21;
      outb(0x3c5, tmp | 0x03);
      outb(0x3c5, tmp | 0x23);
      outb(0x3c5, tmp | 0x03);

      outb(0x3c4, 0x15); outb(0x3c5, oldS3->Trio[6]);
      outb(0x3c4, 0x18); outb(0x3c5, oldS3->Trio[7]);

      outb(0x3c4, 0x08); outb(0x3c5, oldS3->Trio[1]);

   }



   /* restore s3 special bits */

   /* restore 801 specific registers */

   for (i = 32; i < 46; i++) {
      outb(vgaCRIndex, 0x40 + i);
      outb(vgaCRReg, oldS3->s3sysreg[i]);

   }
   for (i = 0; i < 16; i++) {
      if (!((1 << i) & reg50_mask))
	 continue;
      outb(vgaCRIndex, 0x50 + i);
      outb(vgaCRReg, oldS3->s3sysreg[i + 16]);
   }
   for (i = 0; i < 5; i++) {
      outb(vgaCRIndex, 0x30 + i);
      outb(vgaCRReg, oldS3->s3reg[i]);
      outb(vgaCRIndex, 0x38 + i);
      outb(vgaCRReg, oldS3->s3reg[5 + i]);
   }
   outb(vgaCRIndex, 0x36);
   outb(vgaCRReg, oldS3->s3reg[10]);


   for (i = 0; i < 16; i++) {
      outb(vgaCRIndex, 0x40 + i);
      outb(vgaCRReg, oldS3->s3sysreg[i]);
   }

   outb(vgaCRIndex, 0x45);
   inb(vgaCRReg);         /* reset color stack pointer */
   outb(vgaCRIndex, 0x4A);
   for (i = 0; i < 4; i++)
      outb(vgaCRReg, oldS3->ColorStack[i]);

   outb(vgaCRIndex, 0x45);
   inb(vgaCRReg);         /* reset color stack pointer */
   outb(vgaCRIndex, 0x4B);
   for (i = 4; i < 8; i++)
      outb(vgaCRReg, oldS3->ColorStack[i]);


   if (OFLG_ISSET(CLOCK_OPTION_ICS2595, &s3InfoRec.clockOptions)){
      outb(vgaCRIndex, 0x42);
      outb(vgaCRReg, (oldS3->s3sysreg[2] & 0xf0) | 0x01);
      outb(vgaCRIndex, 0x5c);	/* switch back to 28MHz clock */
      outb(vgaCRReg,   0x20);
      outb(vgaCRReg,   0x00);
   }

   vgaHWRestore((vgaHWPtr)oldS3);

   outb(0x3c2, old_clock);

   i = inb(0x3CC);
   if (savedVgaIOBase == 0x3B0)
      i &= 0xFE;
   else
      i |= 0x01;
   outb(0x3C2, i);

   vgaIOBase = savedVgaIOBase;
   vgaCRIndex = vgaIOBase + 4;
   vgaCRReg = vgaIOBase + 5;

   vgaProtect(FALSE);

#ifdef PC98
	crtswitch(0);
#endif

   xf86DisableIOPorts(s3InfoRec.scrnIndex);
}
コード例 #3
0
ファイル: mach8.c プロジェクト: chenbk85/code-reading
/*
 * mach8Probe --
 *     probe and initialize the hardware driver
 */
Bool
mach8Probe()
{
    int            j, memavail, rounding;
    short          temp;
    DisplayModePtr pMode, pEnd, pmaxX = NULL, pmaxY = NULL;
    int            maxX, maxY;
    OFlagSet       validOptions;
    int            tx, ty;

    mach8InfoRec.maxClock = mach8MaxClock;

    xf86ClearIOPortList(mach8InfoRec.scrnIndex);
    xf86AddIOPorts(mach8InfoRec.scrnIndex, Num_mach8_IOPorts, mach8_IOPorts);

    if (mach8InfoRec.chipset) {
	if (StrCaseCmp(mach8InfoRec.chipset, "mach8")) {
	    ErrorF("Chipset specified in XF86Config is not \"mach8\" (%s)!\n",
		   mach8InfoRec.chipset);
	    return(FALSE);
	}
	xf86EnableIOPorts(mach8InfoRec.scrnIndex);
    }
    else
    {
	xf86EnableIOPorts(mach8InfoRec.scrnIndex);

	/* Reset the 8514/A, and disable all interrupts. */
	outw(SUBSYS_CNTL, GPCTRL_RESET | CHPTEST_NORMAL);
	outw(SUBSYS_CNTL, GPCTRL_ENAB | CHPTEST_NORMAL);

	/* Check to see if an 8514/A is actually installed by writing to
	 * the ERR_TERM register, and reading back.  The 0x5a5a value is
	 * entirely arbitrary.
	 */
	outw(ERR_TERM, 0x5a5a);
	ProbeWaitIdleEmpty();
	if (inw(ERR_TERM) != 0x5a5a) {
	    ErrorF("%s: No 8514/A registers detected!\n", mach8InfoRec.name);
	    xf86DisableIOPorts(mach8InfoRec.scrnIndex);
	    return(FALSE);
	}
	/* 6 mar 93 TCG : let's make certain */
	outw(ERR_TERM, 0x2525);
	ProbeWaitIdleEmpty();
	if (inw(ERR_TERM) != 0x2525) {
	    ErrorF("%s: No 8514/A registers detected!\n", mach8InfoRec.name);
	    xf86DisableIOPorts(mach8InfoRec.scrnIndex);
	    return(FALSE);
	}

	temp = inw(ROM_ADDR_1);
	outw(ROM_ADDR_1, 0x5555);
	ProbeWaitIdleEmpty();
	if (inw(ROM_ADDR_1) != 0x5555) {
	    ErrorF("%s: No ATI accelerator detected\n", mach8InfoRec.name);
	    xf86DisableIOPorts(mach8InfoRec.scrnIndex);
	    return(FALSE);
	}
	outw(ROM_ADDR_1, 0x2a2a);
	ProbeWaitIdleEmpty();
	if (inw(ROM_ADDR_1) != 0x2a2a) {
	    ErrorF("%s: No ATI accelerator detected\n", mach8InfoRec.name);
	    xf86DisableIOPorts(mach8InfoRec.scrnIndex);
	    return(FALSE);
	}
	outw(ROM_ADDR_1, temp);

	outw(DESTX_DIASTP, 0xaaaa);
	ProbeWaitIdleEmpty();
	if ((inw(READ_SRC_X) != 0xaaaa) && xf86Verbose) {
	    outw(DESTX_DIASTP, 0x5555);
	    ProbeWaitIdleEmpty();
	    if (inw(READ_SRC_X) == 0x0555) {
		ErrorF("%s %s: Mach-32 detected, used as a Mach-8\n",
			XCONFIG_PROBED, mach8InfoRec.name);
	    }
	    else
		ErrorF("%s %s: Mach-8 detected\n", XCONFIG_PROBED,
			mach8InfoRec.name);
	}
    }

    OFLG_ZERO(&validOptions);
    OFLG_SET(OPTION_CSYNC, &validOptions);
    xf86VerifyOptions(&validOptions, &mach8InfoRec);

    if (!mach8InfoRec.clocks)
    {
	outw(DISP_CNTL, DISPEN_DISAB /*| INTERLACE*/ | MEMCFG_4 | ODDBNKENAB);
	/* 13-jun-93 TCG : set up dummy video mode */
	outw(SHADOW_SET, 1);
	outw(SHADOW_CTL, 0);
	outw(SHADOW_SET, 2);
	outw(SHADOW_CTL, 0);
	outw(SHADOW_SET, 0);
	outw(ADVFUNC_CNTL, DISABPASSTHRU);

	/* vt: 480 488 +31 528 hz: 640 656 +248 920 */
	outw(V_TOTAL, 0x420);
	outw(V_DISP, 0x3c0);
	outw(V_SYNC_STRT, 0x3d0);
	outw(V_SYNC_WID, 0x1f);
	outw(H_TOTAL, 0x72);
	outw(H_DISP, 0x4f);
	outw(H_SYNC_STRT, 0x51);
	outw(H_SYNC_WID, 0x1f);

	outw(DAC_MASK, 0x00);
	outw(DISP_CNTL, DISPEN_ENAB | MEMCFG_4 | ODDBNKENAB);

	/* 2-oct-93 TCG : detect clocks with dif4 fix */
	mach8clkprobedif4fix = TRUE;
	xf86GetClocks(16, mach8ClockSelect, (void (*)())NoopDDA,
			(SaveScreenProcPtr)NoopDDA, DISP_STAT, 2, 7, 44900,
			&mach8InfoRec);
	outw(CLOCK_SEL, 0); /* reset pass-through */
	mach8clkprobedif4fix = FALSE;

	outw(SHADOW_SET, 1);
	outw(SHADOW_CTL, 0x3f);
	outw(SHADOW_SET, 2);
	outw(SHADOW_CTL, 0x3f);
	outw(SHADOW_SET, 0);

	outw(DAC_MASK, 0xff);

	for (j = 0; j < 16; j++)
	    mach8InfoRec.clock[j + 16] = mach8InfoRec.clock[j] / 2;

	mach8InfoRec.clocks = 32;
    }

    temp = inw(CONFIG_STATUS_1);
    if (!mach8InfoRec.videoRam) {
        switch((temp & 0x60) >> 5)
        {
            case 0:
                mach8InfoRec.videoRam = 512;
                break;
            case 1:
                mach8InfoRec.videoRam = 1024;
                break;
            default: /* 2 & 3 reserved in mach-8, used in mach-32 ? */
                mach8InfoRec.videoRam = 1024;
                break;
        }
    }

    mach8InfoRec.chipset = "mach8";
    xf86ProbeFailed = FALSE;
    mach8DramUsed = (temp & 0x10) != 0;
    if (xf86Verbose)
    {
        ErrorF("%s %s: (mem: %dk %cRAM numclocks: %d)",
               OFLG_ISSET(XCONFIG_VIDEORAM,&mach8InfoRec.xconfigFlag) ?
               XCONFIG_GIVEN : XCONFIG_PROBED,
               mach8InfoRec.name,
               mach8InfoRec.videoRam,
               mach8DramUsed ? 'D' : 'V',
               mach8InfoRec.clocks);

        for (j=0; j < mach8InfoRec.clocks; j++)
        {
            if ((j % 8) == 0)
                ErrorF("\n%s %s: clocks:", 
                   OFLG_ISSET(XCONFIG_CLOCKS,&mach8InfoRec.xconfigFlag) ?
                   XCONFIG_GIVEN : XCONFIG_PROBED,
                   mach8InfoRec.name);
            ErrorF(" %6.2f", (double)mach8InfoRec.clock[j]/1000.0);
        }
        ErrorF("\n");
    }

    memavail = mach8InfoRec.videoRam*1024;
    if (mach8InfoRec.virtualX > 0 &&
        mach8InfoRec.virtualX * mach8InfoRec.virtualY > memavail)
    {
        ErrorF("%s: Too little memory for virtual resolution %d %d\n",
               mach8InfoRec.name, mach8InfoRec.virtualX,
               mach8InfoRec.virtualY);
        return(FALSE);
    }

    maxX = maxY = -1;
    pMode = mach8InfoRec.modes;
    if (pMode == NULL) {
        ErrorF("No modes supplied in XF86Config\n");
        return(FALSE);
    }
    pEnd = NULL;
    tx = mach8InfoRec.virtualX;
    ty = mach8InfoRec.virtualY;
    do {
	  DisplayModePtr pModeSv;
	  /*
	   * xf86LookupMode returns FALSE if it ran into an invalid
	   * parameter
	   */
	  if(xf86LookupMode(pMode, &mach8InfoRec, LOOKUP_DEFAULT) == FALSE) {
		pModeSv=pMode->next;
		xf86DeleteMode(&mach8InfoRec, pMode);
		pMode = pModeSv; 
	  } else if (pMode->HDisplay > 1024) {
		pModeSv=pMode->next;
		ErrorF("%s %s: Width to large for mode %s (max 1024)\n", 
			XCONFIG_PROBED, mach8InfoRec.name, pMode->name);
		xf86DeleteMode(&mach8InfoRec, pMode);
		pMode = pModeSv;
	  } else if (pMode->HDisplay * pMode->VDisplay > memavail) {
		pModeSv=pMode->next;
		ErrorF("%s %s: Too little memory for mode %s\n", 
			XCONFIG_PROBED, mach8InfoRec.name, pMode->name);
		xf86DeleteMode(&mach8InfoRec, pMode);
		pMode = pModeSv;
	  } else if (((tx > 0) && (pMode->HDisplay > tx)) || 
		     ((ty > 0) && (pMode->VDisplay > ty))) {
		pModeSv=pMode->next;
		ErrorF("%s %s: Resolution %dx%d too large for virtual %dx%d\n",
			XCONFIG_PROBED, mach8InfoRec.name,
			pMode->HDisplay, pMode->VDisplay, tx, ty);
		xf86DeleteMode(&mach8InfoRec, pMode);
		pMode = pModeSv;
	  } else {
		/*
		 * Successfully looked up this mode.  If pEnd isn't 
		 * initialized, set it to this mode.
		 */
		if(pEnd == (DisplayModePtr) NULL)
			pEnd = pMode;

		if (pMode->HDisplay > maxX)
		{
			maxX = pMode->HDisplay;
			pmaxX = pMode;
		}
		if (pMode->VDisplay > maxY)
		{
			maxY = pMode->VDisplay;
			pmaxY = pMode;
		}

		pMode = pMode->next;
	  }
    } while (pMode != pEnd);
  
    mach8InfoRec.virtualX = max(maxX, mach8InfoRec.virtualX);
    mach8InfoRec.virtualY = max(maxY, mach8InfoRec.virtualY);
  
    rounding = 8;
  
    if (mach8InfoRec.virtualX % rounding)
    {
        mach8InfoRec.virtualX -= mach8InfoRec.virtualX % rounding;
	ErrorF("%s %s: Virtual width rounded down to a multiple of %d (%d)\n",
	       XCONFIG_PROBED, mach8InfoRec.name, rounding,
	       mach8InfoRec.virtualX);
        if (mach8InfoRec.virtualX < maxX)
        {
            ErrorF(
		"%s: Rounded down virtual width (%d) is too small for mode %s",
                   mach8InfoRec.name, mach8InfoRec.virtualX, pmaxX->name);
            return(FALSE);
        }
        ErrorF("%s: Virtual width rounded down to a multiple of %d (%d)\n",
               mach8InfoRec.name, rounding, mach8InfoRec.virtualX);
    }

    if (mach8InfoRec.virtualX > 1024)
    {
        ErrorF("%s: Virtual width must be no greater than 1024\n",mach8InfoRec.name);
        return(FALSE);
    }
    if ( mach8InfoRec.virtualX * mach8InfoRec.virtualY > memavail)
    {
        if (mach8InfoRec.virtualX != maxX || mach8InfoRec.virtualY != maxY)
            ErrorF(
	      "%s: Too little memory to accomodate virtual size and mode %s\n",
                   mach8InfoRec.name,
                   (mach8InfoRec.virtualX == maxX) ? pmaxX->name : pmaxY->name);
        else
            ErrorF("%s: Too little memory to accomodate modes %s and %s\n",
                   mach8InfoRec.name, pmaxX->name, pmaxY->name);
        return(FALSE);
    }
    if (xf86Verbose)
        ErrorF("%s %s: Virtual resolution set to %dx%d\n",
	       OFLG_ISSET(XCONFIG_VIRTUAL,&mach8InfoRec.xconfigFlag) ?
		  XCONFIG_GIVEN : XCONFIG_PROBED, mach8InfoRec.name,
               mach8InfoRec.virtualX, mach8InfoRec.virtualY);

    return(TRUE);
}