Mercurial > mplayer.hg
comparison drivers/radeon/radeonfb.c @ 2037:11cae7a32291
Rage theatre detection
author | nick |
---|---|
date | Mon, 01 Oct 2001 18:15:25 +0000 |
parents | 609d4ea3d72b |
children | db1880f741d4 |
comparison
equal
deleted
inserted
replaced
2036:029bad24d022 | 2037:11cae7a32291 |
---|---|
259 int crtDispType; | 259 int crtDispType; |
260 int dviDispType; | 260 int dviDispType; |
261 int hasTVout; | 261 int hasTVout; |
262 int isM7; | 262 int isM7; |
263 int isR200; | 263 int isR200; |
264 int theatre_num; | |
264 | 265 |
265 u32 mmio_base_phys; | 266 u32 mmio_base_phys; |
266 u32 fb_base_phys; | 267 u32 fb_base_phys; |
267 | 268 |
268 u32 mmio_base; | 269 u32 mmio_base; |
396 radeon_engine_flush (rinfo); | 397 radeon_engine_flush (rinfo); |
397 return; | 398 return; |
398 } | 399 } |
399 } | 400 } |
400 } | 401 } |
402 | |
401 | 403 |
402 | 404 |
403 #define radeon_engine_idle() _radeon_engine_idle(rinfo) | 405 #define radeon_engine_idle() _radeon_engine_idle(rinfo) |
404 #define radeon_fifo_wait(entries) _radeon_fifo_wait(rinfo,entries) | 406 #define radeon_fifo_wait(entries) _radeon_fifo_wait(rinfo,entries) |
405 | 407 |
618 id_table: radeonfb_pci_table, | 620 id_table: radeonfb_pci_table, |
619 probe: radeonfb_pci_register, | 621 probe: radeonfb_pci_register, |
620 remove: radeonfb_pci_unregister, | 622 remove: radeonfb_pci_unregister, |
621 }; | 623 }; |
622 | 624 |
625 static void _radeon_wait_for_idle(struct radeonfb_info *rinfo); | |
626 /* Restore the acceleration hardware to its previous state. */ | |
627 static void _radeon_engine_restore(struct radeonfb_info *rinfo) | |
628 { | |
629 int pitch64; | |
630 | |
631 radeon_fifo_wait(1); | |
632 /* turn of all automatic flushing - we'll do it all */ | |
633 OUTREG(RB2D_DSTCACHE_MODE, 0); | |
634 | |
635 pitch64 = ((rinfo->xres * (rinfo->bpp / 8) + 0x3f)) >> 6; | |
636 | |
637 radeon_fifo_wait(1); | |
638 OUTREG(DEFAULT_OFFSET, (INREG(DEFAULT_OFFSET) & 0xC0000000) | | |
639 (pitch64 << 22)); | |
640 | |
641 radeon_fifo_wait(1); | |
642 #if defined(__BIG_ENDIAN) | |
643 OUTREGP(DP_DATATYPE, | |
644 HOST_BIG_ENDIAN_EN, ~HOST_BIG_ENDIAN_EN); | |
645 #else | |
646 OUTREGP(DP_DATATYPE, 0, ~HOST_BIG_ENDIAN_EN); | |
647 #endif | |
648 | |
649 radeon_fifo_wait(1); | |
650 OUTREG(DEFAULT_SC_BOTTOM_RIGHT, (DEFAULT_SC_RIGHT_MAX | |
651 | DEFAULT_SC_BOTTOM_MAX)); | |
652 radeon_fifo_wait(1); | |
653 OUTREG(DP_GUI_MASTER_CNTL, (INREG(DP_GUI_MASTER_CNTL) | |
654 | GMC_BRUSH_SOLID_COLOR | |
655 | GMC_SRC_DATATYPE_COLOR)); | |
656 | |
657 radeon_fifo_wait(7); | |
658 OUTREG(DST_LINE_START, 0); | |
659 OUTREG(DST_LINE_END, 0); | |
660 OUTREG(DP_BRUSH_FRGD_CLR, 0xffffffff); | |
661 OUTREG(DP_BRUSH_BKGD_CLR, 0x00000000); | |
662 OUTREG(DP_SRC_FRGD_CLR, 0xffffffff); | |
663 OUTREG(DP_SRC_BKGD_CLR, 0x00000000); | |
664 OUTREG(DP_WRITE_MASK, 0xffffffff); | |
665 | |
666 _radeon_wait_for_idle(rinfo); | |
667 } | |
668 | |
669 /* The FIFO has 64 slots. This routines waits until at least `entries' of | |
670 these slots are empty. */ | |
671 #define RADEON_TIMEOUT 2000000 /* Fall out of wait loops after this count */ | |
672 static void _radeon_wait_for_fifo_function(struct radeonfb_info *rinfo, int entries) | |
673 { | |
674 int i; | |
675 | |
676 for (;;) { | |
677 for (i = 0; i < RADEON_TIMEOUT; i++) { | |
678 if((INREG(RBBM_STATUS) & RBBM_FIFOCNT_MASK) >= entries) return; | |
679 } | |
680 radeon_engine_reset(); | |
681 _radeon_engine_restore(rinfo); | |
682 /* it might be that DRI has been compiled in, but corresponding | |
683 library was not loaded.. */ | |
684 } | |
685 } | |
686 /* Wait for the graphics engine to be completely idle: the FIFO has | |
687 drained, the Pixel Cache is flushed, and the engine is idle. This is a | |
688 standard "sync" function that will make the hardware "quiescent". */ | |
689 static void _radeon_wait_for_idle(struct radeonfb_info *rinfo) | |
690 { | |
691 int i; | |
692 | |
693 _radeon_wait_for_fifo_function(rinfo, 64); | |
694 | |
695 for (;;) { | |
696 for (i = 0; i < RADEON_TIMEOUT; i++) { | |
697 if (!(INREG(RBBM_STATUS) & RBBM_ACTIVE)) { | |
698 radeon_engine_flush(rinfo); | |
699 return; | |
700 } | |
701 } | |
702 _radeon_engine_reset(rinfo); | |
703 _radeon_engine_restore(rinfo); | |
704 } | |
705 } | |
706 | |
707 | |
708 static u32 RADEONVIP_idle(struct radeonfb_info *rinfo) | |
709 { | |
710 u32 timeout; | |
711 | |
712 _radeon_wait_for_idle(rinfo); | |
713 timeout = INREG(VIPH_TIMEOUT_STAT); | |
714 if(timeout & VIPH_TIMEOUT_STAT__VIPH_REG_STAT) /* lockup ?? */ | |
715 { | |
716 radeon_fifo_wait(2); | |
717 OUTREG(VIPH_TIMEOUT_STAT, (timeout & 0xffffff00) | VIPH_TIMEOUT_STAT__VIPH_REG_AK); | |
718 _radeon_wait_for_idle(rinfo); | |
719 return (INREG(VIPH_CONTROL) & 0x2000) ? VIP_BUSY : VIP_RESET; | |
720 } | |
721 _radeon_wait_for_idle(rinfo); | |
722 return (INREG(VIPH_CONTROL) & 0x2000) ? VIP_BUSY : VIP_IDLE ; | |
723 } | |
724 | |
623 | 725 |
624 int __init radeonfb_init (void) | 726 int __init radeonfb_init (void) |
625 { | 727 { |
626 #ifdef CONFIG_MTRR | 728 #ifdef CONFIG_MTRR |
627 if (nomtrr) { | 729 if (nomtrr) { |
681 MODULE_DESCRIPTION("framebuffer driver for ATI Radeon chipset. Ver: "RADEON_VERSION); | 783 MODULE_DESCRIPTION("framebuffer driver for ATI Radeon chipset. Ver: "RADEON_VERSION); |
682 #ifdef CONFIG_MTRR | 784 #ifdef CONFIG_MTRR |
683 MODULE_PARM(nomtrr, "i"); | 785 MODULE_PARM(nomtrr, "i"); |
684 MODULE_PARM_DESC(nomtrr, "Don't touch MTRR (touch=0(default))"); | 786 MODULE_PARM_DESC(nomtrr, "Don't touch MTRR (touch=0(default))"); |
685 #endif | 787 #endif |
788 | |
789 /* address format: | |
790 ((device & 0x3)<<14) | (fifo << 12) | (addr) | |
791 */ | |
792 | |
793 static int RADEONVIP_read(struct radeonfb_info *rinfo, u32 address, u32 count, u8 *buffer) | |
794 { | |
795 u32 status,tmp; | |
796 | |
797 if((count!=1) && (count!=2) && (count!=4)) | |
798 { | |
799 printk("radeonfb: Attempt to access VIP bus with non-stadard transaction length\n"); | |
800 return 0; | |
801 } | |
802 | |
803 radeon_fifo_wait(2); | |
804 OUTREG(VIPH_REG_ADDR, address | 0x2000); | |
805 while(VIP_BUSY == (status = RADEONVIP_idle(rinfo))); | |
806 if(VIP_IDLE != status) return 0; | |
807 | |
808 /* | |
809 disable VIPH_REGR_DIS to enable VIP cycle. | |
810 The LSB of VIPH_TIMEOUT_STAT are set to 0 | |
811 because 1 would have acknowledged various VIP | |
812 interrupts unexpectedly | |
813 */ | |
814 radeon_fifo_wait(2); | |
815 OUTREG(VIPH_TIMEOUT_STAT, INREG(VIPH_TIMEOUT_STAT) & (0xffffff00 & ~VIPH_TIMEOUT_STAT__VIPH_REGR_DIS) ); | |
816 /* | |
817 the value returned here is garbage. The read merely initiates | |
818 a register cycle | |
819 */ | |
820 _radeon_wait_for_idle(rinfo); | |
821 INREG(VIPH_REG_DATA); | |
822 | |
823 while(VIP_BUSY == (status = RADEONVIP_idle(rinfo))); | |
824 if(VIP_IDLE != status) return 0; | |
825 /* | |
826 set VIPH_REGR_DIS so that the read won't take too long. | |
827 */ | |
828 _radeon_wait_for_idle(rinfo); | |
829 tmp=INREG(VIPH_TIMEOUT_STAT); | |
830 OUTREG(VIPH_TIMEOUT_STAT, (tmp & 0xffffff00) | VIPH_TIMEOUT_STAT__VIPH_REGR_DIS); | |
831 _radeon_wait_for_idle(rinfo); | |
832 switch(count){ | |
833 case 1: | |
834 *buffer=(u8)(INREG(VIPH_REG_DATA) & 0xff); | |
835 break; | |
836 case 2: | |
837 *(u16 *)buffer=(u16) (INREG(VIPH_REG_DATA) & 0xffff); | |
838 break; | |
839 case 4: | |
840 *(u32 *)buffer=(u32) ( INREG(VIPH_REG_DATA) & 0xffffffff); | |
841 break; | |
842 } | |
843 while(VIP_BUSY == (status = RADEONVIP_idle(rinfo))); | |
844 if(VIP_IDLE != status) return 0; | |
845 /* | |
846 so that reading VIPH_REG_DATA would not trigger unnecessary vip cycles. | |
847 */ | |
848 OUTREG(VIPH_TIMEOUT_STAT, (INREG(VIPH_TIMEOUT_STAT) & 0xffffff00) | VIPH_TIMEOUT_STAT__VIPH_REGR_DIS); | |
849 return 1; | |
850 } | |
851 | |
852 static int theatre_read(struct radeonfb_info *rinfo,u32 reg, u32 *data) | |
853 { | |
854 if(rinfo->theatre_num<0) return 0; | |
855 return RADEONVIP_read(rinfo, ((rinfo->theatre_num & 0x3)<<14) | reg,4, (u8 *) data); | |
856 } | |
686 | 857 |
687 static char * GET_MON_NAME(int type) | 858 static char * GET_MON_NAME(int type) |
688 { | 859 { |
689 char *pret; | 860 char *pret; |
690 switch(type) | 861 switch(type) |
1000 rinfo->mtrr.vram_valid = 1; | 1171 rinfo->mtrr.vram_valid = 1; |
1001 /* let there be speed */ | 1172 /* let there be speed */ |
1002 printk("radeonfb: MTRR set to ON\n"); | 1173 printk("radeonfb: MTRR set to ON\n"); |
1003 } | 1174 } |
1004 #endif /* CONFIG_MTRR */ | 1175 #endif /* CONFIG_MTRR */ |
1005 | 1176 rinfo->theatre_num = -1; |
1006 return 0; | 1177 for(i=0;i<4;i++) |
1178 { | |
1179 if(RADEONVIP_read(rinfo, ((i & 0x03)<<14) | VIP_VIP_VENDOR_DEVICE_ID, 4, (u8 *)&tmp) && | |
1180 (tmp==RT_ATI_ID)) | |
1181 { | |
1182 rinfo->theatre_num=i; | |
1183 break; | |
1184 } | |
1185 } | |
1186 if(rinfo->theatre_num >= 0) { | |
1187 printk("radeonfb: Device %d on VIP bus ids as %x\n",i,tmp); | |
1188 theatre_read(rinfo,VIP_VIP_REVISION_ID, &tmp); | |
1189 printk("radeonfb: Detected Rage Theatre revision %8.8X\n", tmp); | |
1190 } | |
1191 else printk("radeonfb: Rage Theatre not detected\n"); | |
1192 return 0; | |
1007 } | 1193 } |
1008 | 1194 |
1009 | 1195 |
1010 | 1196 |
1011 static void __devexit radeonfb_pci_unregister (struct pci_dev *pdev) | 1197 static void __devexit radeonfb_pci_unregister (struct pci_dev *pdev) |