diff --git a/BaS_gcc/BaS_gcc.files b/BaS_gcc/BaS_gcc.files index a04be06..1d85f7b 100644 --- a/BaS_gcc/BaS_gcc.files +++ b/BaS_gcc/BaS_gcc.files @@ -207,3 +207,12 @@ util/setjmp.S include/x86emu_regs.h x86emu/x86emu_util.c include/setjmp.h +video/video.c +video/fbmem.c +video/fbmodedb.c +video/fbmon.c +video/fnt_st_8x16.c +video/offscreen.c +video/vdi_fill.c +video/videl.c +video/video.c diff --git a/BaS_gcc/Makefile b/BaS_gcc/Makefile index 68b06a4..549fd5f 100644 --- a/BaS_gcc/Makefile +++ b/BaS_gcc/Makefile @@ -47,6 +47,9 @@ CFLAGS=-mcpu=5474 \ CFLAGS_OPTIMIZED = -mcpu=5474 \ -Wall \ -O2 \ + -ffixed-a3 \ + -ffixed-a4 \ + -ffixed-a5 \ -g \ -fomit-frame-pointer \ -ffreestanding \ diff --git a/BaS_gcc/dma/dma.c b/BaS_gcc/dma/dma.c index 381142d..0bfc190 100644 --- a/BaS_gcc/dma/dma.c +++ b/BaS_gcc/dma/dma.c @@ -39,7 +39,7 @@ #error "unknown machine!" #endif /* MACHINE_FIREBEE */ -//#define DBG_DMA +// #define DBG_DMA #ifdef DBG_DMA #define dbg(format, arg...) do { xprintf("DEBUG: %s(): " format, __FUNCTION__, ##arg); } while (0) #else diff --git a/BaS_gcc/include/pci.h b/BaS_gcc/include/pci.h index 32756a8..f3218e1 100644 --- a/BaS_gcc/include/pci.h +++ b/BaS_gcc/include/pci.h @@ -194,8 +194,8 @@ typedef struct /* structure of address conversion */ #define PCI_COMMAND(i) (((i) >> 16) & 0xffff) /* register 0x08 macros */ -#define PCI_CLASS_CODE(i) ((swpl((i)) & 0xffff0000) >> 16) -#define PCI_SUBCLASS(i) ((swpl((i)) & 0xffffff00) >> 8) +#define PCI_CLASS_CODE(i) ((swpl((i)) & 0xff000000) >> 24) +#define PCI_SUBCLASS(i) ((swpl((i)) & 0xffff0000) >> 16) #define PCI_PROG_IF(i) ((swpl((i)) & 0x0000ff00) >> 8) #define PCI_REVISION_ID(i) ((swpl((i)) & 0x000000ff)) diff --git a/BaS_gcc/pci/pci.c b/BaS_gcc/pci/pci.c index 664c790..c718751 100644 --- a/BaS_gcc/pci/pci.c +++ b/BaS_gcc/pci/pci.c @@ -33,7 +33,7 @@ #include "interrupts.h" #include "wait.h" -//#define DEBUG_PCI +#define DEBUG_PCI #ifdef DEBUG_PCI #define dbg(format, arg...) do { xprintf("DEBUG: %s(): " format, __FUNCTION__, ##arg); } while (0) #else @@ -333,7 +333,7 @@ uint32_t pci_read_config_longword(int32_t handle, int offset) /* finish PCI configuration access special cycle (allow regular PCI accesses) */ MCF_PCI_PCICAR &= ~MCF_PCI_PCICAR_E; - pci_check_status(); + //pci_check_status(); return value; } @@ -593,6 +593,11 @@ int32_t pci_find_classcode(uint32_t classcode, int index) { value = pci_read_config_longword(handle, PCICCR); + dbg("classcode to search for=%x\r\n", classcode); + dbg("PCI_CLASSCODE found=%x\r\n", PCI_CLASS_CODE(value)); + dbg("PCI_SUBCLASS found=%x\r\n", PCI_SUBCLASS(value)); + dbg("PCI_PROG_IF found=%x\r\n", PCI_PROG_IF(value)); + if ((classcode & (1 << 26) ? ((PCI_CLASS_CODE(value) == (classcode & 0xff))) : true) && (classcode & (1 << 25) ? ((PCI_SUBCLASS(value) == ((classcode & 0xff00) >> 8))) : true) && (classcode & (1 << 24) ? ((PCI_PROG_IF(value) == ((classcode & 0xff0000) >> 16))) : true)) @@ -930,7 +935,7 @@ static void pci_device_config(uint16_t bus, uint16_t device, uint16_t function) /* fill resource descriptor */ rd->next = sizeof(struct pci_rd); - rd->flags = 0 | FLG_32BIT | FLG_16BIT | FLG_8BIT | 2; /* little endian, lane swapped */ + rd->flags = 0 | FLG_32BIT | FLG_16BIT | FLG_8BIT | ORD_INTEL_LS; /* little endian, lane swapped */ rd->start = address; rd->length = size; rd->offset = 0; @@ -1222,15 +1227,21 @@ void init_pci(void) /* Configure Initiator Windows */ - /* initiator window 0 base / translation adress register */ - MCF_PCI_PCIIW0BTAR = (PCI_MEMORY_OFFSET | (((PCI_MEMORY_SIZE - 1) >> 8) & 0xffff0000)) - | ((PCI_MEMORY_OFFSET >> 16) & 0xff00); + /* + * initiator window 0 base / translation adress register + * used for PCI memory access + */ + MCF_PCI_PCIIW0BTAR = (PCI_MEMORY_OFFSET + ((PCI_MEMORY_SIZE - 1) >> 8)) + + (PCI_MEMORY_OFFSET >> 16); NOP(); dbg("PCIIW0BTAR=0x%08x\r\n", MCF_PCI_PCIIW0BTAR); - /* initiator window 1 base / translation adress register */ - MCF_PCI_PCIIW1BTAR = (PCI_IO_OFFSET | ((PCI_IO_SIZE - 1) >> 8)) & 0xffff0000; + /* + * initiator window 1 base / translation adress register + * used for PCI I/O access + */ + MCF_PCI_PCIIW1BTAR = (PCI_IO_OFFSET + ((PCI_IO_SIZE - 1) >> 8)) & 0xffff0000; NOP(); /* initiator window 2 base / translation address register */ MCF_PCI_PCIIW2BTAR = 0L; /* not used */ @@ -1241,6 +1252,7 @@ void init_pci(void) MCF_PCI_PCIIWCR_WINCTRL0_E | MCF_PCI_PCIIWCR_WINCTRL1_E; NOP(); + /* * Initialize target control register. * Used when an external bus master accesses the Coldfire PCI as target diff --git a/BaS_gcc/radeon/radeon_base.c b/BaS_gcc/radeon/radeon_base.c index e86a1fd..32d47dd 100644 --- a/BaS_gcc/radeon/radeon_base.c +++ b/BaS_gcc/radeon/radeon_base.c @@ -7,7 +7,7 @@ * Copyright 2000 Ani Joshi * * i2c bits from Luca Tettamanti - * + * * Special thanks to ATI DevRel team for their hardware donations. * * ...Insert GPL boilerplate here... @@ -59,14 +59,16 @@ #include "ati_ids.h" #include "driver_mem.h" #include "bas_printf.h" +#include "bas_string.h" #include "exceptions.h" /* for set_ipl() */ #define DBG_RADEON #ifdef DBG_RADEON -#define dbg(format, arg...) do { xprintf("DEBUG: " format, ##arg); } while (0) +#define dbg(format, arg...) do { xprintf("DEBUG (%s()): " format, __FUNCTION__, ##arg);} while(0) #else -#define dbg(format, arg...) do { ; } while (0) +#define dbg(format, arg...) do {;} while (0) #endif /* DBG_RADEON */ +#define err(format, arg...) do { xprintf("ERROR (%s()): " format, __FUNCTION__, ##arg); } while(0) extern void run_bios(struct radeonfb_info *rinfo); @@ -75,146 +77,146 @@ extern void run_bios(struct radeonfb_info *rinfo); #define CHIP_DEF(id, family, flags) \ { \ - PCI_VENDOR_ID_ATI, \ - id, \ - PCI_ANY_ID, \ - PCI_ANY_ID, \ - 0, \ - 0, \ - (flags) | (CHIP_FAMILY_##family) \ + PCI_VENDOR_ID_ATI, \ + id, \ + PCI_ANY_ID, \ + PCI_ANY_ID, \ + 0, \ + 0, \ + (flags) | (CHIP_FAMILY_##family) \ } -struct pci_device_id radeonfb_pci_table[] = +struct pci_device_id radeonfb_pci_table[] = { - /* Mobility M6 */ - CHIP_DEF(PCI_CHIP_RADEON_LY, RV100, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), - CHIP_DEF(PCI_CHIP_RADEON_LZ, RV100, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), - /* Radeon VE/7000 */ - CHIP_DEF(PCI_CHIP_RV100_QY, RV100, CHIP_HAS_CRTC2), - CHIP_DEF(PCI_CHIP_RV100_QZ, RV100, CHIP_HAS_CRTC2), - /* Radeon IGP320M (U1) */ - CHIP_DEF(PCI_CHIP_RS100_4336, RS100, CHIP_HAS_CRTC2 | CHIP_IS_IGP | CHIP_IS_MOBILITY), - /* Radeon IGP320 (A3) */ - CHIP_DEF(PCI_CHIP_RS100_4136, RS100, CHIP_HAS_CRTC2 | CHIP_IS_IGP), - /* IGP330M/340M/350M (U2) */ - CHIP_DEF(PCI_CHIP_RS200_4337, RS200, CHIP_HAS_CRTC2 | CHIP_IS_IGP | CHIP_IS_MOBILITY), - /* IGP330/340/350 (A4) */ - CHIP_DEF(PCI_CHIP_RS200_4137, RS200, CHIP_HAS_CRTC2 | CHIP_IS_IGP), - /* Mobility 7000 IGP */ - CHIP_DEF(PCI_CHIP_RS250_4437, RS200, CHIP_HAS_CRTC2 | CHIP_IS_IGP | CHIP_IS_MOBILITY), - /* 7000 IGP (A4+) */ - CHIP_DEF(PCI_CHIP_RS250_4237, RS200, CHIP_HAS_CRTC2 | CHIP_IS_IGP), - /* 8500 AIW */ - CHIP_DEF(PCI_CHIP_R200_BB, R200, CHIP_HAS_CRTC2), - CHIP_DEF(PCI_CHIP_R200_BC, R200, CHIP_HAS_CRTC2), - /* 8700/8800 */ - CHIP_DEF(PCI_CHIP_R200_QH, R200, CHIP_HAS_CRTC2), - /* 8500 */ - CHIP_DEF(PCI_CHIP_R200_QL, R200, CHIP_HAS_CRTC2), - /* 9100 */ - CHIP_DEF(PCI_CHIP_R200_QM, R200, CHIP_HAS_CRTC2), - /* Mobility M7 */ - CHIP_DEF(PCI_CHIP_RADEON_LW, RV200, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), - CHIP_DEF(PCI_CHIP_RADEON_LX, RV200, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), - /* 7500 */ - CHIP_DEF(PCI_CHIP_RV200_QW, RV200, CHIP_HAS_CRTC2), - CHIP_DEF(PCI_CHIP_RV200_QX, RV200, CHIP_HAS_CRTC2), - /* Mobility M9 */ - CHIP_DEF(PCI_CHIP_RV250_Ld, RV250, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), - CHIP_DEF(PCI_CHIP_RV250_Le, RV250, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), - CHIP_DEF(PCI_CHIP_RV250_Lf, RV250, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), - CHIP_DEF(PCI_CHIP_RV250_Lg, RV250, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), - /* 9000/Pro */ - CHIP_DEF(PCI_CHIP_RV250_If, RV250, CHIP_HAS_CRTC2), - CHIP_DEF(PCI_CHIP_RV250_Ig, RV250, CHIP_HAS_CRTC2), - /* Mobility 9100 IGP (U3) */ - CHIP_DEF(PCI_CHIP_RS300_5835, RS300, CHIP_HAS_CRTC2 | CHIP_IS_IGP | CHIP_IS_MOBILITY), - CHIP_DEF(PCI_CHIP_RS350_7835, RS300, CHIP_HAS_CRTC2 | CHIP_IS_IGP | CHIP_IS_MOBILITY), - /* 9100 IGP (A5) */ - CHIP_DEF(PCI_CHIP_RS300_5834, RS300, CHIP_HAS_CRTC2 | CHIP_IS_IGP), - CHIP_DEF(PCI_CHIP_RS350_7834, RS300, CHIP_HAS_CRTC2 | CHIP_IS_IGP), - /* Mobility 9200 (M9+) */ - CHIP_DEF(PCI_CHIP_RV280_5C61, RV280, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), - CHIP_DEF(PCI_CHIP_RV280_5C63, RV280, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), - /* 9200 */ - CHIP_DEF(PCI_CHIP_RV280_5960, RV280, CHIP_HAS_CRTC2), - CHIP_DEF(PCI_CHIP_RV280_5961, RV280, CHIP_HAS_CRTC2), - CHIP_DEF(PCI_CHIP_RV280_5962, RV280, CHIP_HAS_CRTC2), - CHIP_DEF(PCI_CHIP_RV280_5964, RV280, CHIP_HAS_CRTC2), - /* 9500 */ - CHIP_DEF(PCI_CHIP_R300_AD, R300, CHIP_HAS_CRTC2), - CHIP_DEF(PCI_CHIP_R300_AE, R300, CHIP_HAS_CRTC2), - /* 9600TX / FireGL Z1 */ - CHIP_DEF(PCI_CHIP_R300_AF, R300, CHIP_HAS_CRTC2), - CHIP_DEF(PCI_CHIP_R300_AG, R300, CHIP_HAS_CRTC2), - /* 9700/9500/Pro/FireGL X1 */ - CHIP_DEF(PCI_CHIP_R300_ND, R300, CHIP_HAS_CRTC2), - CHIP_DEF(PCI_CHIP_R300_NE, R300, CHIP_HAS_CRTC2), - CHIP_DEF(PCI_CHIP_R300_NF, R300, CHIP_HAS_CRTC2), - CHIP_DEF(PCI_CHIP_R300_NG, R300, CHIP_HAS_CRTC2), - /* Mobility M10/M11 */ - CHIP_DEF(PCI_CHIP_RV350_NP, RV350, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), - CHIP_DEF(PCI_CHIP_RV350_NQ, RV350, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), - CHIP_DEF(PCI_CHIP_RV350_NR, RV350, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), - CHIP_DEF(PCI_CHIP_RV350_NS, RV350, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), - CHIP_DEF(PCI_CHIP_RV350_NT, RV350, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), - CHIP_DEF(PCI_CHIP_RV350_NV, RV350, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), - /* 9600/FireGL T2 */ - CHIP_DEF(PCI_CHIP_RV350_AP, RV350, CHIP_HAS_CRTC2), - CHIP_DEF(PCI_CHIP_RV350_AQ, RV350, CHIP_HAS_CRTC2), - CHIP_DEF(PCI_CHIP_RV360_AR, RV350, CHIP_HAS_CRTC2), - CHIP_DEF(PCI_CHIP_RV350_AS, RV350, CHIP_HAS_CRTC2), - CHIP_DEF(PCI_CHIP_RV350_AT, RV350, CHIP_HAS_CRTC2), - CHIP_DEF(PCI_CHIP_RV350_AV, RV350, CHIP_HAS_CRTC2), - /* 9800/Pro/FileGL X2 */ - CHIP_DEF(PCI_CHIP_R350_AH, R350, CHIP_HAS_CRTC2), - CHIP_DEF(PCI_CHIP_R350_AI, R350, CHIP_HAS_CRTC2), - CHIP_DEF(PCI_CHIP_R350_AJ, R350, CHIP_HAS_CRTC2), - CHIP_DEF(PCI_CHIP_R350_AK, R350, CHIP_HAS_CRTC2), - CHIP_DEF(PCI_CHIP_R350_NH, R350, CHIP_HAS_CRTC2), - CHIP_DEF(PCI_CHIP_R350_NI, R350, CHIP_HAS_CRTC2), - CHIP_DEF(PCI_CHIP_R360_NJ, R350, CHIP_HAS_CRTC2), - CHIP_DEF(PCI_CHIP_R350_NK, R350, CHIP_HAS_CRTC2), - /* Newer stuff */ - CHIP_DEF(PCI_CHIP_RV380_3E50, RV380, CHIP_HAS_CRTC2), - CHIP_DEF(PCI_CHIP_RV380_3E54, RV380, CHIP_HAS_CRTC2), - CHIP_DEF(PCI_CHIP_RV380_3150, RV380, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), - CHIP_DEF(PCI_CHIP_RV380_3154, RV380, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), - CHIP_DEF(PCI_CHIP_RV370_5B60, RV380, CHIP_HAS_CRTC2), - CHIP_DEF(PCI_CHIP_RV370_5B62, RV380, CHIP_HAS_CRTC2), - CHIP_DEF(PCI_CHIP_RV370_5B64, RV380, CHIP_HAS_CRTC2), - CHIP_DEF(PCI_CHIP_RV370_5B65, RV380, CHIP_HAS_CRTC2), - CHIP_DEF(PCI_CHIP_RV370_5460, RV380, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), - CHIP_DEF(PCI_CHIP_RV370_5464, RV380, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), - CHIP_DEF(PCI_CHIP_R420_JH, R420, CHIP_HAS_CRTC2), - CHIP_DEF(PCI_CHIP_R420_JI, R420, CHIP_HAS_CRTC2), - CHIP_DEF(PCI_CHIP_R420_JJ, R420, CHIP_HAS_CRTC2), - CHIP_DEF(PCI_CHIP_R420_JK, R420, CHIP_HAS_CRTC2), - CHIP_DEF(PCI_CHIP_R420_JL, R420, CHIP_HAS_CRTC2), - CHIP_DEF(PCI_CHIP_R420_JM, R420, CHIP_HAS_CRTC2), - CHIP_DEF(PCI_CHIP_R420_JN, R420, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), - CHIP_DEF(PCI_CHIP_R420_JP, R420, CHIP_HAS_CRTC2), - CHIP_DEF(PCI_CHIP_R423_UH, R420, CHIP_HAS_CRTC2), - CHIP_DEF(PCI_CHIP_R423_UI, R420, CHIP_HAS_CRTC2), - CHIP_DEF(PCI_CHIP_R423_UJ, R420, CHIP_HAS_CRTC2), - CHIP_DEF(PCI_CHIP_R423_UK, R420, CHIP_HAS_CRTC2), - CHIP_DEF(PCI_CHIP_R423_UQ, R420, CHIP_HAS_CRTC2), - CHIP_DEF(PCI_CHIP_R423_UR, R420, CHIP_HAS_CRTC2), - CHIP_DEF(PCI_CHIP_R423_UT, R420, CHIP_HAS_CRTC2), - CHIP_DEF(PCI_CHIP_R423_5D57, R420, CHIP_HAS_CRTC2), - /* Original Radeon/7200 */ - CHIP_DEF(PCI_CHIP_RADEON_QD, RADEON, 0), - CHIP_DEF(PCI_CHIP_RADEON_QE, RADEON, 0), - CHIP_DEF(PCI_CHIP_RADEON_QF, RADEON, 0), - CHIP_DEF(PCI_CHIP_RADEON_QG, RADEON, 0), - { 0, 0, 0, 0, 0, 0, 0 } + /* Mobility M6 */ + CHIP_DEF(PCI_CHIP_RADEON_LY, RV100, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), + CHIP_DEF(PCI_CHIP_RADEON_LZ, RV100, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), + /* Radeon VE/7000 */ + CHIP_DEF(PCI_CHIP_RV100_QY, RV100, CHIP_HAS_CRTC2), + CHIP_DEF(PCI_CHIP_RV100_QZ, RV100, CHIP_HAS_CRTC2), + /* Radeon IGP320M (U1) */ + CHIP_DEF(PCI_CHIP_RS100_4336, RS100, CHIP_HAS_CRTC2 | CHIP_IS_IGP | CHIP_IS_MOBILITY), + /* Radeon IGP320 (A3) */ + CHIP_DEF(PCI_CHIP_RS100_4136, RS100, CHIP_HAS_CRTC2 | CHIP_IS_IGP), + /* IGP330M/340M/350M (U2) */ + CHIP_DEF(PCI_CHIP_RS200_4337, RS200, CHIP_HAS_CRTC2 | CHIP_IS_IGP | CHIP_IS_MOBILITY), + /* IGP330/340/350 (A4) */ + CHIP_DEF(PCI_CHIP_RS200_4137, RS200, CHIP_HAS_CRTC2 | CHIP_IS_IGP), + /* Mobility 7000 IGP */ + CHIP_DEF(PCI_CHIP_RS250_4437, RS200, CHIP_HAS_CRTC2 | CHIP_IS_IGP | CHIP_IS_MOBILITY), + /* 7000 IGP (A4+) */ + CHIP_DEF(PCI_CHIP_RS250_4237, RS200, CHIP_HAS_CRTC2 | CHIP_IS_IGP), + /* 8500 AIW */ + CHIP_DEF(PCI_CHIP_R200_BB, R200, CHIP_HAS_CRTC2), + CHIP_DEF(PCI_CHIP_R200_BC, R200, CHIP_HAS_CRTC2), + /* 8700/8800 */ + CHIP_DEF(PCI_CHIP_R200_QH, R200, CHIP_HAS_CRTC2), + /* 8500 */ + CHIP_DEF(PCI_CHIP_R200_QL, R200, CHIP_HAS_CRTC2), + /* 9100 */ + CHIP_DEF(PCI_CHIP_R200_QM, R200, CHIP_HAS_CRTC2), + /* Mobility M7 */ + CHIP_DEF(PCI_CHIP_RADEON_LW, RV200, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), + CHIP_DEF(PCI_CHIP_RADEON_LX, RV200, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), + /* 7500 */ + CHIP_DEF(PCI_CHIP_RV200_QW, RV200, CHIP_HAS_CRTC2), + CHIP_DEF(PCI_CHIP_RV200_QX, RV200, CHIP_HAS_CRTC2), + /* Mobility M9 */ + CHIP_DEF(PCI_CHIP_RV250_Ld, RV250, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), + CHIP_DEF(PCI_CHIP_RV250_Le, RV250, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), + CHIP_DEF(PCI_CHIP_RV250_Lf, RV250, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), + CHIP_DEF(PCI_CHIP_RV250_Lg, RV250, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), + /* 9000/Pro */ + CHIP_DEF(PCI_CHIP_RV250_If, RV250, CHIP_HAS_CRTC2), + CHIP_DEF(PCI_CHIP_RV250_Ig, RV250, CHIP_HAS_CRTC2), + /* Mobility 9100 IGP (U3) */ + CHIP_DEF(PCI_CHIP_RS300_5835, RS300, CHIP_HAS_CRTC2 | CHIP_IS_IGP | CHIP_IS_MOBILITY), + CHIP_DEF(PCI_CHIP_RS350_7835, RS300, CHIP_HAS_CRTC2 | CHIP_IS_IGP | CHIP_IS_MOBILITY), + /* 9100 IGP (A5) */ + CHIP_DEF(PCI_CHIP_RS300_5834, RS300, CHIP_HAS_CRTC2 | CHIP_IS_IGP), + CHIP_DEF(PCI_CHIP_RS350_7834, RS300, CHIP_HAS_CRTC2 | CHIP_IS_IGP), + /* Mobility 9200 (M9+) */ + CHIP_DEF(PCI_CHIP_RV280_5C61, RV280, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), + CHIP_DEF(PCI_CHIP_RV280_5C63, RV280, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), + /* 9200 */ + CHIP_DEF(PCI_CHIP_RV280_5960, RV280, CHIP_HAS_CRTC2), + CHIP_DEF(PCI_CHIP_RV280_5961, RV280, CHIP_HAS_CRTC2), + CHIP_DEF(PCI_CHIP_RV280_5962, RV280, CHIP_HAS_CRTC2), + CHIP_DEF(PCI_CHIP_RV280_5964, RV280, CHIP_HAS_CRTC2), + /* 9500 */ + CHIP_DEF(PCI_CHIP_R300_AD, R300, CHIP_HAS_CRTC2), + CHIP_DEF(PCI_CHIP_R300_AE, R300, CHIP_HAS_CRTC2), + /* 9600TX / FireGL Z1 */ + CHIP_DEF(PCI_CHIP_R300_AF, R300, CHIP_HAS_CRTC2), + CHIP_DEF(PCI_CHIP_R300_AG, R300, CHIP_HAS_CRTC2), + /* 9700/9500/Pro/FireGL X1 */ + CHIP_DEF(PCI_CHIP_R300_ND, R300, CHIP_HAS_CRTC2), + CHIP_DEF(PCI_CHIP_R300_NE, R300, CHIP_HAS_CRTC2), + CHIP_DEF(PCI_CHIP_R300_NF, R300, CHIP_HAS_CRTC2), + CHIP_DEF(PCI_CHIP_R300_NG, R300, CHIP_HAS_CRTC2), + /* Mobility M10/M11 */ + CHIP_DEF(PCI_CHIP_RV350_NP, RV350, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), + CHIP_DEF(PCI_CHIP_RV350_NQ, RV350, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), + CHIP_DEF(PCI_CHIP_RV350_NR, RV350, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), + CHIP_DEF(PCI_CHIP_RV350_NS, RV350, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), + CHIP_DEF(PCI_CHIP_RV350_NT, RV350, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), + CHIP_DEF(PCI_CHIP_RV350_NV, RV350, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), + /* 9600/FireGL T2 */ + CHIP_DEF(PCI_CHIP_RV350_AP, RV350, CHIP_HAS_CRTC2), + CHIP_DEF(PCI_CHIP_RV350_AQ, RV350, CHIP_HAS_CRTC2), + CHIP_DEF(PCI_CHIP_RV360_AR, RV350, CHIP_HAS_CRTC2), + CHIP_DEF(PCI_CHIP_RV350_AS, RV350, CHIP_HAS_CRTC2), + CHIP_DEF(PCI_CHIP_RV350_AT, RV350, CHIP_HAS_CRTC2), + CHIP_DEF(PCI_CHIP_RV350_AV, RV350, CHIP_HAS_CRTC2), + /* 9800/Pro/FileGL X2 */ + CHIP_DEF(PCI_CHIP_R350_AH, R350, CHIP_HAS_CRTC2), + CHIP_DEF(PCI_CHIP_R350_AI, R350, CHIP_HAS_CRTC2), + CHIP_DEF(PCI_CHIP_R350_AJ, R350, CHIP_HAS_CRTC2), + CHIP_DEF(PCI_CHIP_R350_AK, R350, CHIP_HAS_CRTC2), + CHIP_DEF(PCI_CHIP_R350_NH, R350, CHIP_HAS_CRTC2), + CHIP_DEF(PCI_CHIP_R350_NI, R350, CHIP_HAS_CRTC2), + CHIP_DEF(PCI_CHIP_R360_NJ, R350, CHIP_HAS_CRTC2), + CHIP_DEF(PCI_CHIP_R350_NK, R350, CHIP_HAS_CRTC2), + /* Newer stuff */ + CHIP_DEF(PCI_CHIP_RV380_3E50, RV380, CHIP_HAS_CRTC2), + CHIP_DEF(PCI_CHIP_RV380_3E54, RV380, CHIP_HAS_CRTC2), + CHIP_DEF(PCI_CHIP_RV380_3150, RV380, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), + CHIP_DEF(PCI_CHIP_RV380_3154, RV380, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), + CHIP_DEF(PCI_CHIP_RV370_5B60, RV380, CHIP_HAS_CRTC2), + CHIP_DEF(PCI_CHIP_RV370_5B62, RV380, CHIP_HAS_CRTC2), + CHIP_DEF(PCI_CHIP_RV370_5B64, RV380, CHIP_HAS_CRTC2), + CHIP_DEF(PCI_CHIP_RV370_5B65, RV380, CHIP_HAS_CRTC2), + CHIP_DEF(PCI_CHIP_RV370_5460, RV380, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), + CHIP_DEF(PCI_CHIP_RV370_5464, RV380, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), + CHIP_DEF(PCI_CHIP_R420_JH, R420, CHIP_HAS_CRTC2), + CHIP_DEF(PCI_CHIP_R420_JI, R420, CHIP_HAS_CRTC2), + CHIP_DEF(PCI_CHIP_R420_JJ, R420, CHIP_HAS_CRTC2), + CHIP_DEF(PCI_CHIP_R420_JK, R420, CHIP_HAS_CRTC2), + CHIP_DEF(PCI_CHIP_R420_JL, R420, CHIP_HAS_CRTC2), + CHIP_DEF(PCI_CHIP_R420_JM, R420, CHIP_HAS_CRTC2), + CHIP_DEF(PCI_CHIP_R420_JN, R420, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), + CHIP_DEF(PCI_CHIP_R420_JP, R420, CHIP_HAS_CRTC2), + CHIP_DEF(PCI_CHIP_R423_UH, R420, CHIP_HAS_CRTC2), + CHIP_DEF(PCI_CHIP_R423_UI, R420, CHIP_HAS_CRTC2), + CHIP_DEF(PCI_CHIP_R423_UJ, R420, CHIP_HAS_CRTC2), + CHIP_DEF(PCI_CHIP_R423_UK, R420, CHIP_HAS_CRTC2), + CHIP_DEF(PCI_CHIP_R423_UQ, R420, CHIP_HAS_CRTC2), + CHIP_DEF(PCI_CHIP_R423_UR, R420, CHIP_HAS_CRTC2), + CHIP_DEF(PCI_CHIP_R423_UT, R420, CHIP_HAS_CRTC2), + CHIP_DEF(PCI_CHIP_R423_5D57, R420, CHIP_HAS_CRTC2), + /* Original Radeon/7200 */ + CHIP_DEF(PCI_CHIP_RADEON_QD, RADEON, 0), + CHIP_DEF(PCI_CHIP_RADEON_QE, RADEON, 0), + CHIP_DEF(PCI_CHIP_RADEON_QF, RADEON, 0), + CHIP_DEF(PCI_CHIP_RADEON_QG, RADEON, 0), + { 0, 0, 0, 0, 0, 0, 0 } }; typedef struct { - uint16_t reg; - uint32_t val; + uint16_t reg; + uint32_t val; } reg_val; @@ -223,28 +225,29 @@ typedef struct */ static reg_val common_regs[] = { - { OVR_CLR, 0 }, - { OVR_WID_LEFT_RIGHT, 0 }, - { OVR_WID_TOP_BOTTOM, 0 }, - { OV0_SCALE_CNTL, 0 }, - { SUBPIC_CNTL, 0 }, - { VIPH_CONTROL, 0 }, - { I2C_CNTL_1, 0 }, - { GEN_INT_CNTL, 0 }, - { CAP0_TRIG_CNTL, 0 }, - { CAP1_TRIG_CNTL, 0 }, + { OVR_CLR, 0 }, + { OVR_WID_LEFT_RIGHT, 0 }, + { OVR_WID_TOP_BOTTOM, 0 }, + { OV0_SCALE_CNTL, 0 }, + { SUBPIC_CNTL, 0 }, + { VIPH_CONTROL, 0 }, + { I2C_CNTL_1, 0 }, + { GEN_INT_CNTL, 0 }, + { CAP0_TRIG_CNTL, 0 }, + { CAP1_TRIG_CNTL, 0 }, }; extern struct fb_info *info_fb; #define rinfo ((struct radeonfb_info *) info_fb->par) static uint32_t inreg(uint32_t addr) { - return INREG(addr); + return swpl(*(uint32_t *)(rinfo->mmio_base + addr)); + //return INREG(addr); } static void outreg(uint32_t addr, uint32_t val) { - OUTREG(addr, val); + OUTREG(addr, val); } #undef rinfo @@ -255,11 +258,11 @@ static void outreg(uint32_t addr, uint32_t val) void _OUTREGP(struct radeonfb_info *rinfo, uint32_t addr, uint32_t val, uint32_t mask) { - uint32_t tmp; - tmp = INREG(addr); - tmp &= (mask); - tmp |= (val); - OUTREG(addr, tmp); + uint32_t tmp; + tmp = INREG(addr); + tmp &= (mask); + tmp |= (val); + OUTREG(addr, tmp); } /* @@ -281,174 +284,181 @@ void _OUTREGP(struct radeonfb_info *rinfo, uint32_t addr, uint32_t val, uint32_t */ void radeon_pll_errata_after_index(struct radeonfb_info *rinfo) { - if (!(rinfo->errata & CHIP_ERRATA_PLL_DUMMYREADS)) - return; - (void)INREG(CLOCK_CNTL_DATA); - (void)INREG(CRTC_GEN_CNTL); + if (!(rinfo->errata & CHIP_ERRATA_PLL_DUMMYREADS)) + return; + (void)INREG(CLOCK_CNTL_DATA); + (void)INREG(CRTC_GEN_CNTL); } void radeon_pll_errata_after_data(struct radeonfb_info *rinfo) { - if (rinfo->errata & CHIP_ERRATA_PLL_DELAY) - { - /* we can't deal with posted writes here ... */ - radeon_msleep(5); - } + if (rinfo->errata & CHIP_ERRATA_PLL_DELAY) + { + /* we can't deal with posted writes here ... */ + radeon_msleep(5); + } - if (rinfo->errata & CHIP_ERRATA_R300_CG) - { - uint32_t save, tmp; - save = INREG(CLOCK_CNTL_INDEX); - tmp = save & ~(0x3f | PLL_WR_EN); - OUTREG(CLOCK_CNTL_INDEX, tmp); - tmp = INREG(CLOCK_CNTL_DATA); - OUTREG(CLOCK_CNTL_INDEX, save); - } + if (rinfo->errata & CHIP_ERRATA_R300_CG) + { + uint32_t save, tmp; + save = INREG(CLOCK_CNTL_INDEX); + tmp = save & ~(0x3f | PLL_WR_EN); + OUTREG(CLOCK_CNTL_INDEX, tmp); + tmp = INREG(CLOCK_CNTL_DATA); + OUTREG(CLOCK_CNTL_INDEX, save); + } } uint32_t __INPLL(struct radeonfb_info *rinfo, uint32_t addr) { - uint32_t data; + uint32_t data; - OUTREG8(CLOCK_CNTL_INDEX, addr & 0x0000003f); - radeon_pll_errata_after_index(rinfo); - data = INREG(CLOCK_CNTL_DATA); - radeon_pll_errata_after_data(rinfo); - return data; + OUTREG8(CLOCK_CNTL_INDEX, addr & 0x0000003f); + radeon_pll_errata_after_index(rinfo); + data = INREG(CLOCK_CNTL_DATA); + radeon_pll_errata_after_data(rinfo); + return data; } void __OUTPLL(struct radeonfb_info *rinfo, uint32_t index, uint32_t val) { - OUTREG8(CLOCK_CNTL_INDEX, (index & 0x0000003f) | 0x00000080); - radeon_pll_errata_after_index(rinfo); - OUTREG(CLOCK_CNTL_DATA, val); - radeon_pll_errata_after_data(rinfo); + OUTREG8(CLOCK_CNTL_INDEX, (index & 0x0000003f) | 0x00000080); + radeon_pll_errata_after_index(rinfo); + OUTREG(CLOCK_CNTL_DATA, val); + radeon_pll_errata_after_data(rinfo); } void __OUTPLLP(struct radeonfb_info *rinfo, uint32_t index, uint32_t val, uint32_t mask) { - uint32_t tmp; + uint32_t tmp; - tmp = __INPLL(rinfo, index); - tmp &= (mask); - tmp |= (val); - __OUTPLL(rinfo, index, tmp); + tmp = __INPLL(rinfo, index); + tmp &= (mask); + tmp |= (val); + __OUTPLL(rinfo, index, tmp); } static int round_div(int num, int den) { - return(num + (den / 2)) / den; + return(num + (den / 2)) / den; } static uint32_t read_vline_crnt(struct radeonfb_info *rinfo) { - return((INREG(CRTC_VLINE_CRNT_VLINE) >> 16) & 0x3FF); + return((INREG(CRTC_VLINE_CRNT_VLINE) >> 16) & 0x3FF); } static int radeon_map_ROM(struct radeonfb_info *rinfo) { - uint16_t dptr; - uint8_t rom_type; + uint16_t dptr; + uint8_t rom_type; - /* - * If this is a primary card, there is a shadow copy of the - * ROM somewhere in the first meg. We will just ignore the copy - * and use the ROM directly. - */ + /* + * If this is a primary card, there is a shadow copy of the + * ROM somewhere in the first meg. We will just ignore the copy + * and use the ROM directly. + */ - /* Fix from ATI for problem with Radeon hardware not leaving ROM enabled */ + /* Fix from ATI for problem with Radeon hardware not leaving ROM enabled */ - uint32_t temp; + uint32_t temp; - temp = INREG(MPP_TB_CONFIG); - temp &= 0x00ffffffu; - temp |= 0x04 << 24; - OUTREG(MPP_TB_CONFIG, temp); - temp = INREG(MPP_TB_CONFIG); - - if (rinfo->bios_seg == NULL) - { - dbg("%s: ROM failed to map\r\n", __FUNCTION__); - return -1; - } + dbg("mmio_base=%p\r\n", rinfo->mmio_base); + dbg("bios_seg=%p\r\n", rinfo->bios_seg); + dbg("bios_seg_phys=%p\r\n", rinfo->bios_seg_phys); - /* Very simple test to make sure it appeared */ - if (BIOS_IN16(0) != 0xaa55) - { - dbg("%s: Invalid ROM signature", __FUNCTION__); - goto failed; - } + temp = inreg(MPP_TB_CONFIG); - /* Look for the PCI data to check the ROM type */ - dptr = BIOS_IN16(0x18); + dbg("temp=%d\r\n", temp); + temp &= 0x00ffffffu; + temp |= 0x04 << 24; + OUTREG(MPP_TB_CONFIG, temp); + temp = INREG(MPP_TB_CONFIG); - /* Check the PCI data signature. If it's wrong, we still assume a normal x86 ROM - * for now, until I've verified this works everywhere. The goal here is more - * to phase out Open Firmware images. - * - * Currently, we only look at the first PCI data, we could iteratre and deal with - * them all, and we should use fb_bios_start relative to start of image and not - * relative start of ROM, but so far, I never found a dual-image ATI card - * - * typedef struct { - * u32 signature; + 0x00 - * u16 vendor; + 0x04 - * u16 device; + 0x06 - * u16 reserved_1; + 0x08 - * u16 dlen; + 0x0a - * u8 drevision; + 0x0c - * u8 class_hi; + 0x0d - * u16 class_lo; + 0x0e - * u16 ilen; + 0x10 - * u16 irevision; + 0x12 - * u8 type; + 0x14 - * u8 indicator; + 0x15 - * u16 reserved_2; + 0x16 - * } pci_data_t; - */ - if (BIOS_IN32(dptr) != (('R' << 24) | ('I' << 16) | ('C' << 8) | 'P')) - { - dbg("%s: PCI DATA signature in ROM incorrect: %p\r\n", __FUNCTION__, BIOS_IN32(dptr)); - goto anyway; - } - rom_type = BIOS_IN8(dptr + 0x14); - switch(rom_type) - { - case 0: - dbg("%s: Found Intel x86 BIOS ROM Image\r\n", __FUNCTION__); - break; - case 1: - dbg("%s: Found Open Firmware ROM Image\r\n", __FUNCTION__); - goto failed; - case 2: - dbg("%s: Found HP PA-RISC ROM Image\r\n", __FUNCTION__); - goto failed; - default: - dbg("%s: Found unknown type %d ROM Image\r\n", rom_type, __FUNCTION__); - goto failed; - } + if (rinfo->bios_seg == NULL) + { + dbg("ROM failed to map\r\n"); + return -1; + } + + /* Very simple test to make sure it appeared */ + if (BIOS_IN16(0) != 0xaa55) + { + dbg("Invalid ROM signature"); + goto failed; + } + + /* Look for the PCI data to check the ROM type */ + dptr = BIOS_IN16(0x18); + + /* + * Check the PCI data signature. If it's wrong, we still assume a normal x86 ROM + * for now, until I've verified this works everywhere. The goal here is more + * to phase out Open Firmware images. + * + * Currently, we only look at the first PCI data, we could iteratre and deal with + * them all, and we should use fb_bios_start relative to start of image and not + * relative start of ROM, but so far, I never found a dual-image ATI card + * + * typedef struct { + * u32 signature; + 0x00 + * u16 vendor; + 0x04 + * u16 device; + 0x06 + * u16 reserved_1; + 0x08 + * u16 dlen; + 0x0a + * u8 drevision; + 0x0c + * u8 class_hi; + 0x0d + * u16 class_lo; + 0x0e + * u16 ilen; + 0x10 + * u16 irevision; + 0x12 + * u8 type; + 0x14 + * u8 indicator; + 0x15 + * u16 reserved_2; + 0x16 + * } pci_data_t; + */ + if (BIOS_IN32(dptr) != (('R' << 24) | ('I' << 16) | ('C' << 8) | 'P')) + { + dbg("PCI DATA signature in ROM incorrect: %p\r\n", BIOS_IN32(dptr)); + goto anyway; + } + rom_type = BIOS_IN8(dptr + 0x14); + switch(rom_type) + { + case 0: + dbg("Found Intel x86 BIOS ROM Image\r\n"); + break; + case 1: + dbg("Found Open Firmware ROM Image\r\n"); + goto failed; + case 2: + dbg("Found HP PA-RISC ROM Image\r\n"); + goto failed; + default: + dbg("Found unknown type %d ROM Image\r\n", rom_type); + goto failed; + } anyway: - /* Locate the flat panel infos, do some sanity checking !!! */ - rinfo->fp_bios_start = BIOS_IN16(0x48); - dbg("%s: BIOS start offset: %p\r\n", __FUNCTION__, BIOS_IN16(0x48)); + /* Locate the flat panel infos, do some sanity checking !!! */ + rinfo->fp_bios_start = BIOS_IN16(0x48); + dbg("BIOS start offset: %p\r\n", BIOS_IN16(0x48)); - /* Save BIOS PLL informations */ - { - uint16_t pll_info_block = BIOS_IN16(rinfo->fp_bios_start + 0x30); + /* Save BIOS PLL informations */ + { + uint16_t pll_info_block = BIOS_IN16(rinfo->fp_bios_start + 0x30); - dbg("%s: BIOS PLL info block offset: %p\r\n", __FUNCTION__, BIOS_IN16(rinfo->fp_bios_start + 0x30)); - rinfo->bios_pll.sclk = BIOS_IN16(pll_info_block + 0x08); - rinfo->bios_pll.mclk = BIOS_IN16(pll_info_block + 0x0a); - rinfo->bios_pll.ref_clk = BIOS_IN16(pll_info_block + 0x0e); - rinfo->bios_pll.ref_div = BIOS_IN16(pll_info_block + 0x10); - rinfo->bios_pll.ppll_min = BIOS_IN32(pll_info_block + 0x12); - rinfo->bios_pll.ppll_max = BIOS_IN32(pll_info_block + 0x16); - } - return 0; + dbg("BIOS PLL info block offset: %p\r\n", BIOS_IN16(rinfo->fp_bios_start + 0x30)); + rinfo->bios_pll.sclk = BIOS_IN16(pll_info_block + 0x08); + rinfo->bios_pll.mclk = BIOS_IN16(pll_info_block + 0x0a); + rinfo->bios_pll.ref_clk = BIOS_IN16(pll_info_block + 0x0e); + rinfo->bios_pll.ref_div = BIOS_IN16(pll_info_block + 0x10); + rinfo->bios_pll.ppll_min = BIOS_IN32(pll_info_block + 0x12); + rinfo->bios_pll.ppll_max = BIOS_IN32(pll_info_block + 0x16); + } + return 0; failed: - rinfo->bios_seg = NULL; - return -1; //-ENXIO; + rinfo->bios_seg = NULL; + return -1; //-ENXIO; } /* @@ -456,166 +466,166 @@ failed: */ static int radeon_probe_pll_params(struct radeonfb_info *rinfo) { - uint8_t ppll_div_sel; - unsigned Ns, Nm, M; - unsigned sclk, mclk, tmp, ref_div; - int hTotal, vTotal, num, denom, m, n; - double hz, vclk; - int32_t xtal; - uint32_t start_tv, stop_tv; - int timeout = 0; - int ipl; + uint8_t ppll_div_sel; + unsigned Ns, Nm, M; + unsigned sclk, mclk, tmp, ref_div; + int hTotal, vTotal, num, denom, m, n; + double hz, vclk; + int32_t xtal; + uint32_t start_tv, stop_tv; + int timeout = 0; + int ipl; - /* - * Ugh, we cut interrupts, bad bad bad, but we want some precision - * here, so... --BenH - */ - dbg("%s: radeon_probe_pll_params\r\n", __FUNCTION__); + /* + * Ugh, we cut interrupts, bad bad bad, but we want some precision + * here, so... --BenH + */ + dbg("radeon_probe_pll_params\r\n"); - /* Flush PCI buffers ? */ - tmp = INREG16(DEVICE_ID); + /* Flush PCI buffers ? */ + tmp = INREG16(DEVICE_ID); - ipl = set_ipl(0); + ipl = set_ipl(0); - start_tv = get_timer(); - while (read_vline_crnt(rinfo) != 0) - { - if ((get_timer() - start_tv) > US_TO_TIMER(10000000UL)) /* 10 sec */ - { - timeout=1; - break; - } - } + start_tv = get_timer(); + while (read_vline_crnt(rinfo) != 0) + { + if ((get_timer() - start_tv) > US_TO_TIMER(10000000UL)) /* 10 sec */ + { + timeout=1; + break; + } + } - if (!timeout) - { - start_tv = get_timer(); - while (read_vline_crnt(rinfo) == 0) - { - if ((get_timer() - start_tv) > US_TO_TIMER(1000000UL)) /* 1 sec */ - { - timeout=1; - break; - } - } - if (!timeout) - { - while (read_vline_crnt(rinfo) != 0) - { - if ((get_timer() - start_tv) > US_TO_TIMER(10000000UL)) /* 10 sec */ - { - timeout=1; - break; - } - } - } - } - stop_tv = get_timer(); + if (!timeout) + { + start_tv = get_timer(); + while (read_vline_crnt(rinfo) == 0) + { + if ((get_timer() - start_tv) > US_TO_TIMER(1000000UL)) /* 1 sec */ + { + timeout=1; + break; + } + } + if (!timeout) + { + while (read_vline_crnt(rinfo) != 0) + { + if ((get_timer() - start_tv) > US_TO_TIMER(10000000UL)) /* 10 sec */ + { + timeout=1; + break; + } + } + } + } + stop_tv = get_timer(); - set_ipl(ipl); + set_ipl(ipl); - hz = US_TO_TIMER(1000000.0) / (double)(stop_tv - start_tv); - dbg("%s:hz %d\r\n", __FUNCTION__, (int32_t) hz); + hz = US_TO_TIMER(1000000.0) / (double)(stop_tv - start_tv); + dbg("hz %d\r\n", (int32_t) hz); - hTotal = ((INREG(CRTC_H_TOTAL_DISP) & 0x1ff) + 1) * 8; - vTotal = ((INREG(CRTC_V_TOTAL_DISP) & 0x3ff) + 1); - dbg("%s:hTotal=%d\r\n", __FUNCTION__, hTotal); - dbg("%s:vTotal=%d\r\n", __FUNCTION__, vTotal); + hTotal = ((INREG(CRTC_H_TOTAL_DISP) & 0x1ff) + 1) * 8; + vTotal = ((INREG(CRTC_V_TOTAL_DISP) & 0x3ff) + 1); + dbg("hTotal=%d\r\n", hTotal); + dbg("vTotal=%d\r\n", vTotal); - vclk = (double) hTotal * (double) vTotal * hz; - dbg("%s:vclk=%d\r\n", __FUNCTION__, (int) vclk); + vclk = (double) hTotal * (double) vTotal * hz; + dbg("vclk=%d\r\n", (int) vclk); - switch ((INPLL(PPLL_REF_DIV) & 0x30000) >> 16) - { - case 1: - n = ((INPLL(M_SPLL_REF_FB_DIV) >> 16) & 0xff); - m = (INPLL(M_SPLL_REF_FB_DIV) & 0xff); - num = 2 * n; - denom = 2 * m; - break; + switch ((INPLL(PPLL_REF_DIV) & 0x30000) >> 16) + { + case 1: + n = ((INPLL(M_SPLL_REF_FB_DIV) >> 16) & 0xff); + m = (INPLL(M_SPLL_REF_FB_DIV) & 0xff); + num = 2 * n; + denom = 2 * m; + break; - case 2: - n = ((INPLL(M_SPLL_REF_FB_DIV) >> 8) & 0xff); - m = (INPLL(M_SPLL_REF_FB_DIV) & 0xff); - num = 2 * n; - denom = 2 * m; - break; + case 2: + n = ((INPLL(M_SPLL_REF_FB_DIV) >> 8) & 0xff); + m = (INPLL(M_SPLL_REF_FB_DIV) & 0xff); + num = 2 * n; + denom = 2 * m; + break; - case 0: - default: - num = 1; - denom = 1; - break; - } + case 0: + default: + num = 1; + denom = 1; + break; + } - ppll_div_sel = INREG8(CLOCK_CNTL_INDEX + 1) & 0x3; - radeon_pll_errata_after_index(rinfo); + ppll_div_sel = INREG8(CLOCK_CNTL_INDEX + 1) & 0x3; + radeon_pll_errata_after_index(rinfo); - n = (INPLL(PPLL_DIV_0 + ppll_div_sel) & 0x7ff); - m = (INPLL(PPLL_REF_DIV) & 0x3ff); + n = (INPLL(PPLL_DIV_0 + ppll_div_sel) & 0x7ff); + m = (INPLL(PPLL_REF_DIV) & 0x3ff); - num *= n; - denom *= m; + num *= n; + denom *= m; - switch((INPLL(PPLL_DIV_0 + ppll_div_sel) >> 16) & 0x7) - { - case 1: - denom *= 2; - break; + switch((INPLL(PPLL_DIV_0 + ppll_div_sel) >> 16) & 0x7) + { + case 1: + denom *= 2; + break; - case 2: - denom *= 4; - break; - - case 3: - denom *= 8; - break; + case 2: + denom *= 4; + break; - case 4: - denom *= 3; - break; + case 3: + denom *= 8; + break; - case 6: - denom *= 6; - break; + case 4: + denom *= 3; + break; - case 7: - denom *= 12; - break; - } - vclk *= (double) denom; - vclk /= (double) (1000 * num); - xtal = (int32_t) vclk; + case 6: + denom *= 6; + break; - if ((xtal > 26900) && (xtal < 27100)) - xtal = 2700; /* 27 MHz */ - else if ((xtal > 14200) && (xtal < 14400)) - xtal = 1432; - else if ((xtal > 29400) && (xtal < 29600)) - xtal = 2950; - else - { - dbg("%s: xtal calculation failed: %d\r\n", __FUNCTION__, xtal); - return -1; /* error */ - } + case 7: + denom *= 12; + break; + } + vclk *= (double) denom; + vclk /= (double) (1000 * num); + xtal = (int32_t) vclk; - tmp = INPLL(M_SPLL_REF_FB_DIV); - ref_div = INPLL(PPLL_REF_DIV) & 0x3ff; + if ((xtal > 26900) && (xtal < 27100)) + xtal = 2700; /* 27 MHz */ + else if ((xtal > 14200) && (xtal < 14400)) + xtal = 1432; + else if ((xtal > 29400) && (xtal < 29600)) + xtal = 2950; + else + { + dbg("xtal calculation failed: %d\r\n", xtal); + return -1; /* error */ + } - Ns = (tmp & 0xff0000) >> 16; - Nm = (tmp & 0xff00) >> 8; - M = (tmp & 0xff); + tmp = INPLL(M_SPLL_REF_FB_DIV); + ref_div = INPLL(PPLL_REF_DIV) & 0x3ff; - sclk = round_div((2 * Ns * xtal), (2 * M)); - mclk = round_div((2 * Nm * xtal), (2 * M)); + Ns = (tmp & 0xff0000) >> 16; + Nm = (tmp & 0xff00) >> 8; + M = (tmp & 0xff); - /* we're done, hopefully these are sane values */ - rinfo->pll.ref_clk = xtal; - rinfo->pll.ref_div = ref_div; - rinfo->pll.sclk = sclk; - rinfo->pll.mclk = mclk; + sclk = round_div((2 * Ns * xtal), (2 * M)); + mclk = round_div((2 * Nm * xtal), (2 * M)); - return 0; + /* we're done, hopefully these are sane values */ + rinfo->pll.ref_clk = xtal; + rinfo->pll.ref_div = ref_div; + rinfo->pll.sclk = sclk; + rinfo->pll.mclk = mclk; + + return 0; } /* @@ -623,812 +633,812 @@ static int radeon_probe_pll_params(struct radeonfb_info *rinfo) */ static void radeon_get_pllinfo(struct radeonfb_info *rinfo) { - /* - * In the case nothing works, these are defaults; they are mostly - * incomplete, however. It does provide ppll_max and _min values - * even for most other methods, however. - */ - dbg("%s:\r\n", __FUNCTION__); + /* + * In the case nothing works, these are defaults; they are mostly + * incomplete, however. It does provide ppll_max and _min values + * even for most other methods, however. + */ + dbg("\r\n"); - switch(rinfo->chipset) - { - case PCI_DEVICE_ID_ATI_RADEON_QW: - case PCI_DEVICE_ID_ATI_RADEON_QX: - rinfo->pll.ppll_max = 35000; - rinfo->pll.ppll_min = 12000; - rinfo->pll.mclk = 23000; - rinfo->pll.sclk = 23000; - rinfo->pll.ref_clk = 2700; - break; + switch(rinfo->chipset) + { + case PCI_DEVICE_ID_ATI_RADEON_QW: + case PCI_DEVICE_ID_ATI_RADEON_QX: + rinfo->pll.ppll_max = 35000; + rinfo->pll.ppll_min = 12000; + rinfo->pll.mclk = 23000; + rinfo->pll.sclk = 23000; + rinfo->pll.ref_clk = 2700; + break; - case PCI_DEVICE_ID_ATI_RADEON_QL: - case PCI_DEVICE_ID_ATI_RADEON_QN: - case PCI_DEVICE_ID_ATI_RADEON_QO: - case PCI_DEVICE_ID_ATI_RADEON_Ql: - case PCI_DEVICE_ID_ATI_RADEON_BB: - rinfo->pll.ppll_max = 35000; - rinfo->pll.ppll_min = 12000; - rinfo->pll.mclk = 27500; - rinfo->pll.sclk = 27500; - rinfo->pll.ref_clk = 2700; - break; + case PCI_DEVICE_ID_ATI_RADEON_QL: + case PCI_DEVICE_ID_ATI_RADEON_QN: + case PCI_DEVICE_ID_ATI_RADEON_QO: + case PCI_DEVICE_ID_ATI_RADEON_Ql: + case PCI_DEVICE_ID_ATI_RADEON_BB: + rinfo->pll.ppll_max = 35000; + rinfo->pll.ppll_min = 12000; + rinfo->pll.mclk = 27500; + rinfo->pll.sclk = 27500; + rinfo->pll.ref_clk = 2700; + break; - case PCI_DEVICE_ID_ATI_RADEON_Id: - case PCI_DEVICE_ID_ATI_RADEON_Ie: - case PCI_DEVICE_ID_ATI_RADEON_If: - case PCI_DEVICE_ID_ATI_RADEON_Ig: - rinfo->pll.ppll_max = 35000; - rinfo->pll.ppll_min = 12000; - rinfo->pll.mclk = 25000; - rinfo->pll.sclk = 25000; - rinfo->pll.ref_clk = 2700; - break; + case PCI_DEVICE_ID_ATI_RADEON_Id: + case PCI_DEVICE_ID_ATI_RADEON_Ie: + case PCI_DEVICE_ID_ATI_RADEON_If: + case PCI_DEVICE_ID_ATI_RADEON_Ig: + rinfo->pll.ppll_max = 35000; + rinfo->pll.ppll_min = 12000; + rinfo->pll.mclk = 25000; + rinfo->pll.sclk = 25000; + rinfo->pll.ref_clk = 2700; + break; - case PCI_DEVICE_ID_ATI_RADEON_ND: - case PCI_DEVICE_ID_ATI_RADEON_NE: - case PCI_DEVICE_ID_ATI_RADEON_NF: - case PCI_DEVICE_ID_ATI_RADEON_NG: - rinfo->pll.ppll_max = 40000; - rinfo->pll.ppll_min = 20000; - rinfo->pll.mclk = 27000; - rinfo->pll.sclk = 27000; - rinfo->pll.ref_clk = 2700; - break; + case PCI_DEVICE_ID_ATI_RADEON_ND: + case PCI_DEVICE_ID_ATI_RADEON_NE: + case PCI_DEVICE_ID_ATI_RADEON_NF: + case PCI_DEVICE_ID_ATI_RADEON_NG: + rinfo->pll.ppll_max = 40000; + rinfo->pll.ppll_min = 20000; + rinfo->pll.mclk = 27000; + rinfo->pll.sclk = 27000; + rinfo->pll.ref_clk = 2700; + break; - case PCI_DEVICE_ID_ATI_RADEON_QD: - case PCI_DEVICE_ID_ATI_RADEON_QE: - case PCI_DEVICE_ID_ATI_RADEON_QF: - case PCI_DEVICE_ID_ATI_RADEON_QG: - default: - rinfo->pll.ppll_max = 35000; - rinfo->pll.ppll_min = 12000; - rinfo->pll.mclk = 16600; - rinfo->pll.sclk = 16600; - rinfo->pll.ref_clk = 2700; - break; - } - rinfo->pll.ref_div = INPLL(PPLL_REF_DIV) & PPLL_REF_DIV_MASK; + case PCI_DEVICE_ID_ATI_RADEON_QD: + case PCI_DEVICE_ID_ATI_RADEON_QE: + case PCI_DEVICE_ID_ATI_RADEON_QF: + case PCI_DEVICE_ID_ATI_RADEON_QG: + default: + rinfo->pll.ppll_max = 35000; + rinfo->pll.ppll_min = 12000; + rinfo->pll.mclk = 16600; + rinfo->pll.sclk = 16600; + rinfo->pll.ref_clk = 2700; + break; + } + rinfo->pll.ref_div = INPLL(PPLL_REF_DIV) & PPLL_REF_DIV_MASK; - /* - * Check out if we have an X86 which gave us some PLL informations - * and if yes, retreive them - */ - if (!force_measure_pll && (rinfo->bios_seg != NULL)) - { - rinfo->pll.sclk = rinfo->bios_pll.sclk; - rinfo->pll.mclk = rinfo->bios_pll.mclk; - rinfo->pll.ref_clk = rinfo->bios_pll.ref_clk; - rinfo->pll.ref_div = rinfo->bios_pll.ref_div; - rinfo->pll.ppll_min = rinfo->bios_pll.ppll_min; - rinfo->pll.ppll_max = rinfo->bios_pll.ppll_max; - dbg("%s: Retreived PLL infos from BIOS\r\n", __FUNCTION__); + /* + * Check out if we have an X86 which gave us some PLL informations + * and if yes, retreive them + */ + if (!force_measure_pll && (rinfo->bios_seg != NULL)) + { + rinfo->pll.sclk = rinfo->bios_pll.sclk; + rinfo->pll.mclk = rinfo->bios_pll.mclk; + rinfo->pll.ref_clk = rinfo->bios_pll.ref_clk; + rinfo->pll.ref_div = rinfo->bios_pll.ref_div; + rinfo->pll.ppll_min = rinfo->bios_pll.ppll_min; + rinfo->pll.ppll_max = rinfo->bios_pll.ppll_max; + dbg("Retreived PLL infos from BIOS\r\n"); - goto found; - } + goto found; + } - /* - * We didn't get PLL parameters from either OF or BIOS, we try to - * probe them - */ - if (radeon_probe_pll_params(rinfo) == 0) - { - dbg("%s: Retreived PLL infos from registers\r\n", __FUNCTION__); - goto found; - } + /* + * We didn't get PLL parameters from either OF or BIOS, we try to + * probe them + */ + if (radeon_probe_pll_params(rinfo) == 0) + { + dbg("Retreived PLL infos from registers\r\n"); + goto found; + } - /* - * Fall back to already-set defaults... - */ - dbg("%s: Used default PLL infos\r\n", __FUNCTION__); + /* + * Fall back to already-set defaults... + */ + dbg("Used default PLL infos\r\n"); found: - /* - * Some methods fail to retreive SCLK and MCLK values, we apply default - * settings in this case (200Mhz). If that really happne often, we could - * fetch from registers instead... - */ - if (rinfo->pll.mclk == 0) - rinfo->pll.mclk = 20000; - if (rinfo->pll.sclk == 0) - rinfo->pll.sclk = 20000; + /* + * Some methods fail to retreive SCLK and MCLK values, we apply default + * settings in this case (200Mhz). If that really happne often, we could + * fetch from registers instead... + */ + if (rinfo->pll.mclk == 0) + rinfo->pll.mclk = 20000; + if (rinfo->pll.sclk == 0) + rinfo->pll.sclk = 20000; - dbg("%s: Reference=%d MHz (RefDiv=0x%x) Memory=%d MHz\r\n", __FUNCTION__, - rinfo->pll.ref_clk / 100, rinfo->pll.ref_div, rinfo->pll.mclk / 100); - dbg("%s: System=%d MHz PLL min %d, max %d\r\n", __FUNCTION__, - rinfo->pll.sclk / 100, rinfo->pll.ppll_min, rinfo->pll.ppll_max); + dbg("Reference=%d MHz (RefDiv=0x%x) Memory=%d MHz\r\n", + rinfo->pll.ref_clk / 100, rinfo->pll.ref_div, rinfo->pll.mclk / 100); + dbg("System=%d MHz PLL min %d, max %d\r\n", + rinfo->pll.sclk / 100, rinfo->pll.ppll_min, rinfo->pll.ppll_max); } static int var_to_depth(const struct fb_var_screeninfo *var) { - if (var->bits_per_pixel != 16) - return var->bits_per_pixel; + if (var->bits_per_pixel != 16) + return var->bits_per_pixel; - return(var->green.length == 5) ? 15 : 16; + return(var->green.length == 5) ? 15 : 16; } int radeonfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) { - struct radeonfb_info *rinfo = info->par; - struct fb_var_screeninfo v; - int nom, den; - uint32_t pitch; + struct radeonfb_info *rinfo = info->par; + struct fb_var_screeninfo v; + int nom, den; + uint32_t pitch; - dbg("%s:\r\n", __FUNCTION__); + dbg("\r\n"); - /* clocks over 135 MHz have heat isues with DVI on RV100 */ - if ((rinfo->mon1_type == MT_DFP) && (rinfo->family == CHIP_FAMILY_RV100) && ((100000000 / var->pixclock) > 13500)) - { - dbg("%s: mode %d x %d x %d", __FUNCTION__, var->xres, var->yres, var->bits_per_pixel); - dbg("%s: rejected, RV100 DVI clock over 135 MHz\r\n", __FUNCTION__); + /* clocks over 135 MHz have heat isues with DVI on RV100 */ + if ((rinfo->mon1_type == MT_DFP) && (rinfo->family == CHIP_FAMILY_RV100) && ((100000000 / var->pixclock) > 13500)) + { + dbg("mode %d x %d x %d", var->xres, var->yres, var->bits_per_pixel); + dbg("rejected, RV100 DVI clock over 135 MHz\r\n"); - return -1; //-EINVAL; - } + return -1; //-EINVAL; + } - if (radeon_match_mode(rinfo, &v, var)) - return -1; //-EINVAL; + if (radeon_match_mode(rinfo, &v, var)) + return -1; //-EINVAL; - switch (v.bits_per_pixel) - { - case 0 ... 8: - v.bits_per_pixel = 8; - break; + switch (v.bits_per_pixel) + { + case 0 ... 8: + v.bits_per_pixel = 8; + break; - case 9 ... 16: - v.bits_per_pixel = 16; - break; + case 9 ... 16: + v.bits_per_pixel = 16; + break; #if 0 /* Doesn't seem to work */ - case 17 ... 24: - v.bits_per_pixel = 24; - break; -#endif - case 25 ... 32: - v.bits_per_pixel = 32; - break; + case 17 ... 24: + v.bits_per_pixel = 24; + break; +#endif + case 25 ... 32: + v.bits_per_pixel = 32; + break; - default: - return -1; //-EINVAL; - } + default: + return -1; //-EINVAL; + } - switch (var_to_depth(&v)) - { - case 8: - nom = den = 1; - v.red.offset = v.green.offset = v.blue.offset = 0; - v.red.length = v.green.length = v.blue.length = 8; - v.transp.offset = v.transp.length = 0; - break; + switch (var_to_depth(&v)) + { + case 8: + nom = den = 1; + v.red.offset = v.green.offset = v.blue.offset = 0; + v.red.length = v.green.length = v.blue.length = 8; + v.transp.offset = v.transp.length = 0; + break; - case 15: - nom = 2; - den = 1; - v.red.offset = 10; - v.green.offset = 5; - v.blue.offset = 0; - v.red.length = v.green.length = v.blue.length = 5; - v.transp.offset = v.transp.length = 0; - break; + case 15: + nom = 2; + den = 1; + v.red.offset = 10; + v.green.offset = 5; + v.blue.offset = 0; + v.red.length = v.green.length = v.blue.length = 5; + v.transp.offset = v.transp.length = 0; + break; - case 16: - nom = 2; - den = 1; - v.red.offset = 11; - v.green.offset = 5; - v.blue.offset = 0; - v.red.length = 5; - v.green.length = 6; - v.blue.length = 5; - v.transp.offset = v.transp.length = 0; - break; + case 16: + nom = 2; + den = 1; + v.red.offset = 11; + v.green.offset = 5; + v.blue.offset = 0; + v.red.length = 5; + v.green.length = 6; + v.blue.length = 5; + v.transp.offset = v.transp.length = 0; + break; - case 24: - nom = 4; - den = 1; - v.red.offset = 16; - v.green.offset = 8; - v.blue.offset = 0; - v.red.length = v.blue.length = v.green.length = 8; - v.transp.offset = v.transp.length = 0; - break; + case 24: + nom = 4; + den = 1; + v.red.offset = 16; + v.green.offset = 8; + v.blue.offset = 0; + v.red.length = v.blue.length = v.green.length = 8; + v.transp.offset = v.transp.length = 0; + break; - case 32: - nom = 4; - den = 1; - v.red.offset = 16; - v.green.offset = 8; - v.blue.offset = 0; - v.red.length = v.blue.length = v.green.length = 8; - v.transp.offset = 24; - v.transp.length = 8; - break; + case 32: + nom = 4; + den = 1; + v.red.offset = 16; + v.green.offset = 8; + v.blue.offset = 0; + v.red.length = v.blue.length = v.green.length = 8; + v.transp.offset = 24; + v.transp.length = 8; + break; default: - dbg("radeonfb: mode %d x %d x %d rejected, color depth invalid\r\n ", - var->xres, var->yres, var->bits_per_pixel); - return -1; //-EINVAL; - } + dbg("radeonfb: mode %d x %d x %d rejected, color depth invalid\r\n ", + var->xres, var->yres, var->bits_per_pixel); + return -1; //-EINVAL; + } - if (v.yres_virtual < v.yres) - v.yres_virtual = v.yres; - if (v.xres_virtual < v.xres) - v.xres_virtual = v.xres; + if (v.yres_virtual < v.yres) + v.yres_virtual = v.yres; + if (v.xres_virtual < v.xres) + v.xres_virtual = v.xres; - /* - * XXX I'm adjusting xres_virtual to the pitch, that may help XFree - * with some panels, though I don't quite like this solution - */ - pitch = ((v.xres_virtual * ((v.bits_per_pixel + 1) / 8) + 0x3f) & ~(0x3f)) >> 6; - v.xres_virtual = (pitch << 6) / ((v.bits_per_pixel + 1) / 8); + /* + * XXX I'm adjusting xres_virtual to the pitch, that may help XFree + * with some panels, though I don't quite like this solution + */ + pitch = ((v.xres_virtual * ((v.bits_per_pixel + 1) / 8) + 0x3f) & ~(0x3f)) >> 6; + v.xres_virtual = (pitch << 6) / ((v.bits_per_pixel + 1) / 8); - if (((v.xres_virtual * v.yres_virtual * nom) / den) > info->screen_size) - { - dbg("%s: mode %d x %d rejected (screen size too small)\r\n", __FUNCTION__, v.xres_virtual, v.yres_virtual); - return -1; //-EINVAL; - } + if (((v.xres_virtual * v.yres_virtual * nom) / den) > info->screen_size) + { + dbg("mode %d x %d rejected (screen size too small)\r\n", v.xres_virtual, v.yres_virtual); + return -1; //-EINVAL; + } - if (v.xres_virtual < v.xres) - v.xres = v.xres_virtual; - - if (v.xoffset < 0) - v.xoffset = 0; + if (v.xres_virtual < v.xres) + v.xres = v.xres_virtual; - if (v.yoffset < 0) - v.yoffset = 0; + if (v.xoffset < 0) + v.xoffset = 0; - if (v.xoffset > v.xres_virtual - v.xres) - v.xoffset = v.xres_virtual - v.xres - 1; + if (v.yoffset < 0) + v.yoffset = 0; - if (v.yoffset > v.yres_virtual - v.yres) - v.yoffset = v.yres_virtual - v.yres - 1; + if (v.xoffset > v.xres_virtual - v.xres) + v.xoffset = v.xres_virtual - v.xres - 1; - v.red.msb_right = v.green.msb_right = v.blue.msb_right = 0; - v.transp.offset = v.transp.length = v.transp.msb_right = 0; + if (v.yoffset > v.yres_virtual - v.yres) + v.yoffset = v.yres_virtual - v.yres - 1; - dbg("%s: using mode %d x %d \r\n", __FUNCTION__, v.xres, v.yres); + v.red.msb_right = v.green.msb_right = v.blue.msb_right = 0; + v.transp.offset = v.transp.length = v.transp.msb_right = 0; - memcpy(var, &v, sizeof(v)); + dbg("using mode %d x %d \r\n", v.xres, v.yres); - return 0; + memcpy(var, &v, sizeof(v)); + + return 0; } int radeonfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) { - struct radeonfb_info *rinfo = info->par; + struct radeonfb_info *rinfo = info->par; // DPRINT("radeonfb: radeonfb_pan_display\r\n"); - if ((var->xoffset + var->xres) > var->xres_virtual) - return -1; //-EINVAL; + if ((var->xoffset + var->xres) > var->xres_virtual) + return -1; //-EINVAL; - if (((var->yoffset * var->xres_virtual) + var->xoffset) >= - (rinfo->mapped_vram - (var->yres * var->xres * (var->bits_per_pixel / 8)))) - return -1; //-EINVAL; + if (((var->yoffset * var->xres_virtual) + var->xoffset) >= + (rinfo->mapped_vram - (var->yres * var->xres * (var->bits_per_pixel / 8)))) + return -1; //-EINVAL; - if (rinfo->asleep) - return 0; + if (rinfo->asleep) + return 0; - radeon_wait_for_fifo(rinfo, 2); - rinfo->fb_offset = ((var->yoffset * var->xres_virtual + var->xoffset) * var->bits_per_pixel / 8) & ~7; - rinfo->dst_pitch_offset = (rinfo->pitch << 22) | ((rinfo->fb_local_base + rinfo->fb_offset) >> 10); - OUTREG(CRTC_OFFSET, rinfo->fb_offset); + radeon_wait_for_fifo(rinfo, 2); + rinfo->fb_offset = ((var->yoffset * var->xres_virtual + var->xoffset) * var->bits_per_pixel / 8) & ~7; + rinfo->dst_pitch_offset = (rinfo->pitch << 22) | ((rinfo->fb_local_base + rinfo->fb_offset) >> 10); + OUTREG(CRTC_OFFSET, rinfo->fb_offset); - return 0; + return 0; } short mirror; int radeonfb_ioctl(unsigned int cmd, unsigned long arg, struct fb_info *info) { - struct radeonfb_info *rinfo = info->par; - uint32_t tmp; - uint32_t value = 0; + struct radeonfb_info *rinfo = info->par; + uint32_t tmp; + uint32_t value = 0; - switch(cmd) - { - /* - * TODO: set mirror accordingly for non-Mobility chipsets with 2 CRTC's - * and do something better using 2nd CRTC instead of just hackish - * routing to second output - */ - case FBIO_RADEON_SET_MIRROR: - if (!rinfo->is_mobility) - return -1; //-EINVAL; - radeon_wait_for_fifo(rinfo, 2); + switch(cmd) + { + /* + * TODO: set mirror accordingly for non-Mobility chipsets with 2 CRTC's + * and do something better using 2nd CRTC instead of just hackish + * routing to second output + */ + case FBIO_RADEON_SET_MIRROR: + if (!rinfo->is_mobility) + return -1; //-EINVAL; + radeon_wait_for_fifo(rinfo, 2); - if (value & 0x01) - { - tmp = INREG(LVDS_GEN_CNTL); - tmp |= (LVDS_ON | LVDS_BLON); - } - else - { - tmp = INREG(LVDS_GEN_CNTL); - tmp &= ~(LVDS_ON | LVDS_BLON); - } - OUTREG(LVDS_GEN_CNTL, tmp); + if (value & 0x01) + { + tmp = INREG(LVDS_GEN_CNTL); + tmp |= (LVDS_ON | LVDS_BLON); + } + else + { + tmp = INREG(LVDS_GEN_CNTL); + tmp &= ~(LVDS_ON | LVDS_BLON); + } + OUTREG(LVDS_GEN_CNTL, tmp); - if (value & 0x02) - { - tmp = INREG(CRTC_EXT_CNTL); - tmp |= CRTC_CRT_ON; - mirror = 1; - } - else - { - tmp = INREG(CRTC_EXT_CNTL); - tmp &= ~CRTC_CRT_ON; - mirror = 0; - } - OUTREG(CRTC_EXT_CNTL, tmp); - return 0; + if (value & 0x02) + { + tmp = INREG(CRTC_EXT_CNTL); + tmp |= CRTC_CRT_ON; + mirror = 1; + } + else + { + tmp = INREG(CRTC_EXT_CNTL); + tmp &= ~CRTC_CRT_ON; + mirror = 0; + } + OUTREG(CRTC_EXT_CNTL, tmp); + return 0; - case FBIO_RADEON_GET_MIRROR: - if (!rinfo->is_mobility) - return -1; //-EINVAL; - tmp = INREG(LVDS_GEN_CNTL); - if ((LVDS_ON | LVDS_BLON) & tmp) - value |= 0x01; - tmp = INREG(CRTC_EXT_CNTL); - if (CRTC_CRT_ON & tmp) - value |= 0x02; - return 0; + case FBIO_RADEON_GET_MIRROR: + if (!rinfo->is_mobility) + return -1; //-EINVAL; + tmp = INREG(LVDS_GEN_CNTL); + if ((LVDS_ON | LVDS_BLON) & tmp) + value |= 0x01; + tmp = INREG(CRTC_EXT_CNTL); + if (CRTC_CRT_ON & tmp) + value |= 0x02; + return 0; - default: - return -1; //-EINVAL; - } - return -1; //-EINVAL; + default: + return -1; //-EINVAL; + } + return -1; //-EINVAL; } int32_t radeon_screen_blank(struct radeonfb_info *rinfo, int32_t blank, int32_t mode_switch) { - uint32_t val; - uint32_t tmp_pix_clks; - int unblank = 0; + uint32_t val; + uint32_t tmp_pix_clks; + int unblank = 0; - if (rinfo->lock_blank) - return 0; + if (rinfo->lock_blank) + return 0; - dbg("radeonfb: radeon_screen_blank\r\n"); - radeon_engine_idle(); - val = INREG(CRTC_EXT_CNTL); - val &= ~(CRTC_DISPLAY_DIS | CRTC_HSYNC_DIS | CRTC_VSYNC_DIS); + dbg("radeonfb: radeon_screen_blank\r\n"); + radeon_engine_idle(); + val = INREG(CRTC_EXT_CNTL); + val &= ~(CRTC_DISPLAY_DIS | CRTC_HSYNC_DIS | CRTC_VSYNC_DIS); - switch(blank) - { - case FB_BLANK_VSYNC_SUSPEND: - val |= (CRTC_DISPLAY_DIS | CRTC_VSYNC_DIS); - break; + switch(blank) + { + case FB_BLANK_VSYNC_SUSPEND: + val |= (CRTC_DISPLAY_DIS | CRTC_VSYNC_DIS); + break; - case FB_BLANK_HSYNC_SUSPEND: - val |= (CRTC_DISPLAY_DIS | CRTC_HSYNC_DIS); - break; + case FB_BLANK_HSYNC_SUSPEND: + val |= (CRTC_DISPLAY_DIS | CRTC_HSYNC_DIS); + break; - case FB_BLANK_POWERDOWN: - val |= (CRTC_DISPLAY_DIS | CRTC_VSYNC_DIS | CRTC_HSYNC_DIS); - break; + case FB_BLANK_POWERDOWN: + val |= (CRTC_DISPLAY_DIS | CRTC_VSYNC_DIS | CRTC_HSYNC_DIS); + break; - case FB_BLANK_NORMAL: - val |= CRTC_DISPLAY_DIS; - break; + case FB_BLANK_NORMAL: + val |= CRTC_DISPLAY_DIS; + break; - case FB_BLANK_UNBLANK: - default: - unblank = 1; - break; - } - OUTREG(CRTC_EXT_CNTL, val); + case FB_BLANK_UNBLANK: + default: + unblank = 1; + break; + } + OUTREG(CRTC_EXT_CNTL, val); - switch(rinfo->mon1_type) - { - case MT_DFP: - if (unblank) - OUTREGP(FP_GEN_CNTL, (FP_FPON | FP_TMDS_EN), ~(FP_FPON | FP_TMDS_EN)); - else - { - if (mode_switch || blank == FB_BLANK_NORMAL) - break; - OUTREGP(FP_GEN_CNTL, 0, ~(FP_FPON | FP_TMDS_EN)); - } - break; + switch(rinfo->mon1_type) + { + case MT_DFP: + if (unblank) + OUTREGP(FP_GEN_CNTL, (FP_FPON | FP_TMDS_EN), ~(FP_FPON | FP_TMDS_EN)); + else + { + if (mode_switch || blank == FB_BLANK_NORMAL) + break; + OUTREGP(FP_GEN_CNTL, 0, ~(FP_FPON | FP_TMDS_EN)); + } + break; - case MT_LCD: - rinfo->lvds_timer = 0; - val = INREG(LVDS_GEN_CNTL); - if (unblank) - { - uint32_t target_val = (val & ~LVDS_DISPLAY_DIS) | LVDS_BLON | LVDS_ON - | LVDS_EN | (rinfo->init_state.lvds_gen_cntl & (LVDS_DIGON | LVDS_BL_MOD_EN)); - if ((val ^ target_val) == LVDS_DISPLAY_DIS) - OUTREG(LVDS_GEN_CNTL, target_val); - else if ((val ^ target_val) != 0) - { - OUTREG(LVDS_GEN_CNTL, target_val & ~(LVDS_ON | LVDS_BL_MOD_EN)); - rinfo->init_state.lvds_gen_cntl &= ~LVDS_STATE_MASK; - rinfo->init_state.lvds_gen_cntl |= target_val & LVDS_STATE_MASK; - if (mode_switch) - { - radeon_msleep(rinfo->panel_info.pwr_delay); - OUTREG(LVDS_GEN_CNTL, target_val); - } - else - { - rinfo->pending_lvds_gen_cntl = target_val; - rinfo->lvds_timer = (int32_t)rinfo->panel_info.pwr_delay; - } - } - } - else - { - val |= LVDS_DISPLAY_DIS; - OUTREG(LVDS_GEN_CNTL, val); - /* We don't do a full switch-off on a simple mode switch */ - if (mode_switch || blank == FB_BLANK_NORMAL) - break; + case MT_LCD: + rinfo->lvds_timer = 0; + val = INREG(LVDS_GEN_CNTL); + if (unblank) + { + uint32_t target_val = (val & ~LVDS_DISPLAY_DIS) | LVDS_BLON | LVDS_ON + | LVDS_EN | (rinfo->init_state.lvds_gen_cntl & (LVDS_DIGON | LVDS_BL_MOD_EN)); + if ((val ^ target_val) == LVDS_DISPLAY_DIS) + OUTREG(LVDS_GEN_CNTL, target_val); + else if ((val ^ target_val) != 0) + { + OUTREG(LVDS_GEN_CNTL, target_val & ~(LVDS_ON | LVDS_BL_MOD_EN)); + rinfo->init_state.lvds_gen_cntl &= ~LVDS_STATE_MASK; + rinfo->init_state.lvds_gen_cntl |= target_val & LVDS_STATE_MASK; + if (mode_switch) + { + radeon_msleep(rinfo->panel_info.pwr_delay); + OUTREG(LVDS_GEN_CNTL, target_val); + } + else + { + rinfo->pending_lvds_gen_cntl = target_val; + rinfo->lvds_timer = (int32_t)rinfo->panel_info.pwr_delay; + } + } + } + else + { + val |= LVDS_DISPLAY_DIS; + OUTREG(LVDS_GEN_CNTL, val); + /* We don't do a full switch-off on a simple mode switch */ + if (mode_switch || blank == FB_BLANK_NORMAL) + break; - /* Asic bug, when turning off LVDS_ON, we have to make sure - * RADEON_PIXCLK_LVDS_ALWAYS_ON bit is off - */ - tmp_pix_clks = INPLL(PIXCLKS_CNTL); - if (rinfo->is_mobility || rinfo->is_IGP) - OUTPLLP(PIXCLKS_CNTL, 0, ~PIXCLK_LVDS_ALWAYS_ONb); + /* Asic bug, when turning off LVDS_ON, we have to make sure + * RADEON_PIXCLK_LVDS_ALWAYS_ON bit is off + */ + tmp_pix_clks = INPLL(PIXCLKS_CNTL); + if (rinfo->is_mobility || rinfo->is_IGP) + OUTPLLP(PIXCLKS_CNTL, 0, ~PIXCLK_LVDS_ALWAYS_ONb); - val &= ~(LVDS_BL_MOD_EN); - OUTREG(LVDS_GEN_CNTL, val); + val &= ~(LVDS_BL_MOD_EN); + OUTREG(LVDS_GEN_CNTL, val); - wait(100); + wait(100); - val &= ~(LVDS_ON | LVDS_EN); - OUTREG(LVDS_GEN_CNTL, val); - val &= ~LVDS_DIGON; - rinfo->pending_lvds_gen_cntl = val; - rinfo->lvds_timer = (int32_t)rinfo->panel_info.pwr_delay; - rinfo->init_state.lvds_gen_cntl &= ~LVDS_STATE_MASK; - rinfo->init_state.lvds_gen_cntl |= val & LVDS_STATE_MASK; + val &= ~(LVDS_ON | LVDS_EN); + OUTREG(LVDS_GEN_CNTL, val); + val &= ~LVDS_DIGON; + rinfo->pending_lvds_gen_cntl = val; + rinfo->lvds_timer = (int32_t)rinfo->panel_info.pwr_delay; + rinfo->init_state.lvds_gen_cntl &= ~LVDS_STATE_MASK; + rinfo->init_state.lvds_gen_cntl |= val & LVDS_STATE_MASK; - if (rinfo->is_mobility || rinfo->is_IGP) - OUTPLL(PIXCLKS_CNTL, tmp_pix_clks); - } - break; - case MT_CRT: - // todo: powerdown DAC - default: - break; - } - /* let fbcon do a soft blank for us */ - return(blank == FB_BLANK_NORMAL) ? -1 /* -EINVAL */ : 0; + if (rinfo->is_mobility || rinfo->is_IGP) + OUTPLL(PIXCLKS_CNTL, tmp_pix_clks); + } + break; + case MT_CRT: + // todo: powerdown DAC + default: + break; + } + /* let fbcon do a soft blank for us */ + return(blank == FB_BLANK_NORMAL) ? -1 /* -EINVAL */ : 0; } int radeonfb_blank(int blank, struct fb_info *info) { - struct radeonfb_info *rinfo = info->par; + struct radeonfb_info *rinfo = info->par; - if (rinfo->asleep) - return 0; + if (rinfo->asleep) + return 0; - return radeon_screen_blank(rinfo, blank, 0); + return radeon_screen_blank(rinfo, blank, 0); } static int radeon_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue, unsigned transp, struct fb_info *info) { - struct radeonfb_info *rinfo = info->par; - uint32_t pindex; + struct radeonfb_info *rinfo = info->par; + uint32_t pindex; - if (regno > 255) - return 1; + if (regno > 255) + return 1; - red >>= 8; - green >>= 8; - blue >>= 8; + red >>= 8; + green >>= 8; + blue >>= 8; - rinfo->palette[regno].red = red; - rinfo->palette[regno].green = green; - rinfo->palette[regno].blue = blue; + rinfo->palette[regno].red = red; + rinfo->palette[regno].green = green; + rinfo->palette[regno].blue = blue; - /* default */ - pindex = regno; - if (!rinfo->asleep) - { - radeon_wait_for_fifo(rinfo, 9); - if (rinfo->bpp == 16) - { - pindex = regno * 8; - if (rinfo->depth == 16 && regno > 63) - return 1; - if (rinfo->depth == 15 && regno > 31) - return 1; + /* default */ + pindex = regno; + if (!rinfo->asleep) + { + radeon_wait_for_fifo(rinfo, 9); + if (rinfo->bpp == 16) + { + pindex = regno * 8; + if (rinfo->depth == 16 && regno > 63) + return 1; + if (rinfo->depth == 15 && regno > 31) + return 1; - /* - * For 565, the green component is mixed one order - * below - */ - if (rinfo->depth == 16) - { - OUTREG(PALETTE_INDEX, pindex>>1); - OUTREG(PALETTE_DATA,(rinfo->palette[regno>>1].red << 16) - | (green << 8) | (rinfo->palette[regno>>1].blue)); - green = rinfo->palette[regno<<1].green; - } - } - if (rinfo->depth != 16 || regno < 32) - { - OUTREG(PALETTE_INDEX, pindex); - OUTREG(PALETTE_DATA, (red << 16) | (green << 8) | blue); - } - } - return 0; + /* + * For 565, the green component is mixed one order + * below + */ + if (rinfo->depth == 16) + { + OUTREG(PALETTE_INDEX, pindex>>1); + OUTREG(PALETTE_DATA,(rinfo->palette[regno>>1].red << 16) + | (green << 8) | (rinfo->palette[regno>>1].blue)); + green = rinfo->palette[regno<<1].green; + } + } + if (rinfo->depth != 16 || regno < 32) + { + OUTREG(PALETTE_INDEX, pindex); + OUTREG(PALETTE_DATA, (red << 16) | (green << 8) | blue); + } + } + return 0; } int radeonfb_setcolreg(unsigned regno, unsigned red, unsigned green, - unsigned blue, unsigned transp, struct fb_info *info) + unsigned blue, unsigned transp, struct fb_info *info) { - struct radeonfb_info *rinfo = info->par; - uint32_t dac_cntl2, vclk_cntl = 0; - int rc; + struct radeonfb_info *rinfo = info->par; + uint32_t dac_cntl2, vclk_cntl = 0; + int rc; - if (!rinfo->asleep) - { - if (rinfo->is_mobility) - { - vclk_cntl = INPLL(VCLK_ECP_CNTL); - OUTPLL(VCLK_ECP_CNTL, vclk_cntl & ~PIXCLK_DAC_ALWAYS_ONb); - } + if (!rinfo->asleep) + { + if (rinfo->is_mobility) + { + vclk_cntl = INPLL(VCLK_ECP_CNTL); + OUTPLL(VCLK_ECP_CNTL, vclk_cntl & ~PIXCLK_DAC_ALWAYS_ONb); + } - /* Make sure we are on first palette */ - if (rinfo->has_CRTC2) - { - dac_cntl2 = INREG(DAC_CNTL2); - dac_cntl2 &= ~DAC2_PALETTE_ACCESS_CNTL; - OUTREG(DAC_CNTL2, dac_cntl2); - } - } - rc = radeon_setcolreg(regno, red, green, blue, transp, info); - if (!rinfo->asleep && rinfo->is_mobility) - OUTPLL(VCLK_ECP_CNTL, vclk_cntl); + /* Make sure we are on first palette */ + if (rinfo->has_CRTC2) + { + dac_cntl2 = INREG(DAC_CNTL2); + dac_cntl2 &= ~DAC2_PALETTE_ACCESS_CNTL; + OUTREG(DAC_CNTL2, dac_cntl2); + } + } + rc = radeon_setcolreg(regno, red, green, blue, transp, info); + if (!rinfo->asleep && rinfo->is_mobility) + OUTPLL(VCLK_ECP_CNTL, vclk_cntl); - return rc; + return rc; } static void radeon_save_state(struct radeonfb_info *rinfo, struct radeon_regs *save) { - /* CRTC regs */ - save->crtc_gen_cntl = INREG(CRTC_GEN_CNTL); - save->crtc_ext_cntl = INREG(CRTC_EXT_CNTL); - save->crtc_more_cntl = INREG(CRTC_MORE_CNTL); - save->dac_cntl = INREG(DAC_CNTL); - save->crtc_h_total_disp = INREG(CRTC_H_TOTAL_DISP); - save->crtc_h_sync_strt_wid = INREG(CRTC_H_SYNC_STRT_WID); - save->crtc_v_total_disp = INREG(CRTC_V_TOTAL_DISP); - save->crtc_v_sync_strt_wid = INREG(CRTC_V_SYNC_STRT_WID); - save->crtc_pitch = INREG(CRTC_PITCH); - save->surface_cntl = INREG(SURFACE_CNTL); + /* CRTC regs */ + save->crtc_gen_cntl = INREG(CRTC_GEN_CNTL); + save->crtc_ext_cntl = INREG(CRTC_EXT_CNTL); + save->crtc_more_cntl = INREG(CRTC_MORE_CNTL); + save->dac_cntl = INREG(DAC_CNTL); + save->crtc_h_total_disp = INREG(CRTC_H_TOTAL_DISP); + save->crtc_h_sync_strt_wid = INREG(CRTC_H_SYNC_STRT_WID); + save->crtc_v_total_disp = INREG(CRTC_V_TOTAL_DISP); + save->crtc_v_sync_strt_wid = INREG(CRTC_V_SYNC_STRT_WID); + save->crtc_pitch = INREG(CRTC_PITCH); + save->surface_cntl = INREG(SURFACE_CNTL); - /* FP regs */ - save->fp_crtc_h_total_disp = INREG(FP_CRTC_H_TOTAL_DISP); - save->fp_crtc_v_total_disp = INREG(FP_CRTC_V_TOTAL_DISP); - save->fp_gen_cntl = INREG(FP_GEN_CNTL); - save->fp_h_sync_strt_wid = INREG(FP_H_SYNC_STRT_WID); - save->fp_horz_stretch = INREG(FP_HORZ_STRETCH); - save->fp_v_sync_strt_wid = INREG(FP_V_SYNC_STRT_WID); - save->fp_vert_stretch = INREG(FP_VERT_STRETCH); - save->lvds_gen_cntl = INREG(LVDS_GEN_CNTL); - save->lvds_pll_cntl = INREG(LVDS_PLL_CNTL); - save->tmds_crc = INREG(TMDS_CRC); - save->tmds_transmitter_cntl = INREG(TMDS_TRANSMITTER_CNTL); - save->vclk_ecp_cntl = INPLL(VCLK_ECP_CNTL); - /* PLL regs */ + /* FP regs */ + save->fp_crtc_h_total_disp = INREG(FP_CRTC_H_TOTAL_DISP); + save->fp_crtc_v_total_disp = INREG(FP_CRTC_V_TOTAL_DISP); + save->fp_gen_cntl = INREG(FP_GEN_CNTL); + save->fp_h_sync_strt_wid = INREG(FP_H_SYNC_STRT_WID); + save->fp_horz_stretch = INREG(FP_HORZ_STRETCH); + save->fp_v_sync_strt_wid = INREG(FP_V_SYNC_STRT_WID); + save->fp_vert_stretch = INREG(FP_VERT_STRETCH); + save->lvds_gen_cntl = INREG(LVDS_GEN_CNTL); + save->lvds_pll_cntl = INREG(LVDS_PLL_CNTL); + save->tmds_crc = INREG(TMDS_CRC); + save->tmds_transmitter_cntl = INREG(TMDS_TRANSMITTER_CNTL); + save->vclk_ecp_cntl = INPLL(VCLK_ECP_CNTL); + /* PLL regs */ - save->clk_cntl_index = INREG(CLOCK_CNTL_INDEX) & ~0x3f; - radeon_pll_errata_after_index(rinfo); - save->ppll_div_3 = INPLL(PPLL_DIV_3); - save->ppll_ref_div = INPLL(PPLL_REF_DIV); + save->clk_cntl_index = INREG(CLOCK_CNTL_INDEX) & ~0x3f; + radeon_pll_errata_after_index(rinfo); + save->ppll_div_3 = INPLL(PPLL_DIV_3); + save->ppll_ref_div = INPLL(PPLL_REF_DIV); } static void radeon_write_pll_regs(struct radeonfb_info *rinfo, struct radeon_regs *mode) { - int i; + int i; - dbg("radeonfb: radeon_write_pll_regs\r\n"); - radeon_wait_for_fifo(rinfo, 20); + dbg("radeonfb: radeon_write_pll_regs\r\n"); + radeon_wait_for_fifo(rinfo, 20); #if 0 - /* Workaround from XFree */ - if (rinfo->is_mobility) - { - /* A temporal workaround for the occational blanking on certain laptop - * panels. This appears to related to the PLL divider registers - * (fail to lock?). It occurs even when all dividers are the same - * with their old settings. In this case we really don't need to - * fiddle with PLL registers. By doing this we can avoid the blanking - * problem with some panels. - */ - if ((mode->ppll_ref_div == (INPLL(PPLL_REF_DIV) & PPLL_REF_DIV_MASK)) - && (mode->ppll_div_3 == (INPLL(PPLL_DIV_3) & (PPLL_POST3_DIV_MASK | PPLL_FB3_DIV_MASK)))) - { - /* We still have to force a switch to selected PPLL div thanks to - * an XFree86 driver bug which will switch it away in some cases - * even when using UseFDev */ - OUTREGP(CLOCK_CNTL_INDEX, - mode->clk_cntl_index & PPLL_DIV_SEL_MASK, - ~PPLL_DIV_SEL_MASK); - radeon_pll_errata_after_index(rinfo); - radeon_pll_errata_after_data(rinfo); - return; - } - } + /* Workaround from XFree */ + if (rinfo->is_mobility) + { + /* A temporal workaround for the occational blanking on certain laptop + * panels. This appears to related to the PLL divider registers + * (fail to lock?). It occurs even when all dividers are the same + * with their old settings. In this case we really don't need to + * fiddle with PLL registers. By doing this we can avoid the blanking + * problem with some panels. + */ + if ((mode->ppll_ref_div == (INPLL(PPLL_REF_DIV) & PPLL_REF_DIV_MASK)) + && (mode->ppll_div_3 == (INPLL(PPLL_DIV_3) & (PPLL_POST3_DIV_MASK | PPLL_FB3_DIV_MASK)))) + { + /* We still have to force a switch to selected PPLL div thanks to + * an XFree86 driver bug which will switch it away in some cases + * even when using UseFDev */ + OUTREGP(CLOCK_CNTL_INDEX, + mode->clk_cntl_index & PPLL_DIV_SEL_MASK, + ~PPLL_DIV_SEL_MASK); + radeon_pll_errata_after_index(rinfo); + radeon_pll_errata_after_data(rinfo); + return; + } + } #endif - /* Swich VCKL clock input to CPUCLK so it stays fed while PPLL updates*/ - OUTPLLP(VCLK_ECP_CNTL, VCLK_SRC_SEL_CPUCLK, ~VCLK_SRC_SEL_MASK); + /* Swich VCKL clock input to CPUCLK so it stays fed while PPLL updates*/ + OUTPLLP(VCLK_ECP_CNTL, VCLK_SRC_SEL_CPUCLK, ~VCLK_SRC_SEL_MASK); - /* Reset PPLL & enable atomic update */ - OUTPLLP(PPLL_CNTL, PPLL_RESET | PPLL_ATOMIC_UPDATE_EN | PPLL_VGA_ATOMIC_UPDATE_EN, - ~(PPLL_RESET | PPLL_ATOMIC_UPDATE_EN | PPLL_VGA_ATOMIC_UPDATE_EN)); + /* Reset PPLL & enable atomic update */ + OUTPLLP(PPLL_CNTL, PPLL_RESET | PPLL_ATOMIC_UPDATE_EN | PPLL_VGA_ATOMIC_UPDATE_EN, + ~(PPLL_RESET | PPLL_ATOMIC_UPDATE_EN | PPLL_VGA_ATOMIC_UPDATE_EN)); - /* Switch to selected PPLL divider */ - OUTREGP(CLOCK_CNTL_INDEX, mode->clk_cntl_index & PPLL_DIV_SEL_MASK, ~PPLL_DIV_SEL_MASK); - radeon_pll_errata_after_index(rinfo); - radeon_pll_errata_after_data(rinfo); + /* Switch to selected PPLL divider */ + OUTREGP(CLOCK_CNTL_INDEX, mode->clk_cntl_index & PPLL_DIV_SEL_MASK, ~PPLL_DIV_SEL_MASK); + radeon_pll_errata_after_index(rinfo); + radeon_pll_errata_after_data(rinfo); - /* Set PPLL ref. div */ - if (rinfo->family == CHIP_FAMILY_R300 || rinfo->family == CHIP_FAMILY_RS300 - || rinfo->family == CHIP_FAMILY_R350 || rinfo->family == CHIP_FAMILY_RV350) - { - if (mode->ppll_ref_div & R300_PPLL_REF_DIV_ACC_MASK) - { - /* - * When restoring console mode, use saved PPLL_REF_DIV - * setting. - */ - OUTPLLP(PPLL_REF_DIV, mode->ppll_ref_div, 0); - } - else - { - /* R300 uses ref_div_acc field as real ref divider */ - OUTPLLP(PPLL_REF_DIV,(mode->ppll_ref_div << R300_PPLL_REF_DIV_ACC_SHIFT),~R300_PPLL_REF_DIV_ACC_MASK); - } - } - else - OUTPLLP(PPLL_REF_DIV, mode->ppll_ref_div, ~PPLL_REF_DIV_MASK); + /* Set PPLL ref. div */ + if (rinfo->family == CHIP_FAMILY_R300 || rinfo->family == CHIP_FAMILY_RS300 + || rinfo->family == CHIP_FAMILY_R350 || rinfo->family == CHIP_FAMILY_RV350) + { + if (mode->ppll_ref_div & R300_PPLL_REF_DIV_ACC_MASK) + { + /* + * When restoring console mode, use saved PPLL_REF_DIV + * setting. + */ + OUTPLLP(PPLL_REF_DIV, mode->ppll_ref_div, 0); + } + else + { + /* R300 uses ref_div_acc field as real ref divider */ + OUTPLLP(PPLL_REF_DIV,(mode->ppll_ref_div << R300_PPLL_REF_DIV_ACC_SHIFT),~R300_PPLL_REF_DIV_ACC_MASK); + } + } + else + OUTPLLP(PPLL_REF_DIV, mode->ppll_ref_div, ~PPLL_REF_DIV_MASK); - /* Set PPLL divider 3 & post divider*/ - OUTPLLP(PPLL_DIV_3, mode->ppll_div_3, ~PPLL_FB3_DIV_MASK); - OUTPLLP(PPLL_DIV_3, mode->ppll_div_3, ~PPLL_POST3_DIV_MASK); + /* Set PPLL divider 3 & post divider*/ + OUTPLLP(PPLL_DIV_3, mode->ppll_div_3, ~PPLL_FB3_DIV_MASK); + OUTPLLP(PPLL_DIV_3, mode->ppll_div_3, ~PPLL_POST3_DIV_MASK); - /* Write update */ - while (INPLL(PPLL_REF_DIV) & PPLL_ATOMIC_UPDATE_R); - OUTPLLP(PPLL_REF_DIV, PPLL_ATOMIC_UPDATE_W, ~PPLL_ATOMIC_UPDATE_W); + /* Write update */ + while (INPLL(PPLL_REF_DIV) & PPLL_ATOMIC_UPDATE_R); + OUTPLLP(PPLL_REF_DIV, PPLL_ATOMIC_UPDATE_W, ~PPLL_ATOMIC_UPDATE_W); - /* Wait read update complete */ - /* FIXME: Certain revisions of R300 can't recover here. Not sure of - the cause yet, but this workaround will mask the problem for now. - Other chips usually will pass at the very first test, so the - workaround shouldn't have any effect on them. */ + /* Wait read update complete */ + /* FIXME: Certain revisions of R300 can't recover here. Not sure of + the cause yet, but this workaround will mask the problem for now. + Other chips usually will pass at the very first test, so the + workaround shouldn't have any effect on them. */ - for (i = 0; (i < 10000 && INPLL(PPLL_REF_DIV) & PPLL_ATOMIC_UPDATE_R); i++); - OUTPLL(HTOTAL_CNTL, 0); + for (i = 0; (i < 10000 && INPLL(PPLL_REF_DIV) & PPLL_ATOMIC_UPDATE_R); i++); + OUTPLL(HTOTAL_CNTL, 0); - /* Clear reset & atomic update */ - OUTPLLP(PPLL_CNTL, 0, ~(PPLL_RESET | PPLL_SLEEP | PPLL_ATOMIC_UPDATE_EN | PPLL_VGA_ATOMIC_UPDATE_EN)); + /* Clear reset & atomic update */ + OUTPLLP(PPLL_CNTL, 0, ~(PPLL_RESET | PPLL_SLEEP | PPLL_ATOMIC_UPDATE_EN | PPLL_VGA_ATOMIC_UPDATE_EN)); - /* We may want some locking ... oh well */ - radeon_msleep(5); + /* We may want some locking ... oh well */ + radeon_msleep(5); - /* Switch back VCLK source to PPLL */ - OUTPLLP(VCLK_ECP_CNTL, VCLK_SRC_SEL_PPLLCLK, ~VCLK_SRC_SEL_MASK); + /* Switch back VCLK source to PPLL */ + OUTPLLP(VCLK_ECP_CNTL, VCLK_SRC_SEL_PPLLCLK, ~VCLK_SRC_SEL_MASK); } static void radeon_wait_vbl(struct fb_info *info) { - uint32_t cnt = INREG(CRTC_CRNT_FRAME); + uint32_t cnt = INREG(CRTC_CRNT_FRAME); - while (cnt == INREG(CRTC_CRNT_FRAME)); + while (cnt == INREG(CRTC_CRNT_FRAME)); } static void radeon_timer_func(void) { - struct fb_info *info = info_fb; - struct radeonfb_info *rinfo = info->par; - struct fb_var_screeninfo var; - uint32_t x, y; - int chg, disp; + struct fb_info *info = info_fb; + struct radeonfb_info *rinfo = info->par; + struct fb_var_screeninfo var; + uint32_t x, y; + int chg, disp; #ifdef FIXME_LATER - static int32_t start_timer; + static int32_t start_timer; - /* delayed LVDS panel power up/down */ - if (rinfo->lvds_timer) - { - if (!start_timer) - start_timer = *_hz_200; + /* delayed LVDS panel power up/down */ + if (rinfo->lvds_timer) + { + if (!start_timer) + start_timer = *_hz_200; - if (((*_hz_200 - start_timer) * 5) >= (int32_t)rinfo->lvds_timer) - { - rinfo->lvds_timer = 0; - radeon_engine_idle(); - OUTREG(LVDS_GEN_CNTL, rinfo->pending_lvds_gen_cntl); - } - } - else - start_timer = 0; + if (((*_hz_200 - start_timer) * 5) >= (int32_t)rinfo->lvds_timer) + { + rinfo->lvds_timer = 0; + radeon_engine_idle(); + OUTREG(LVDS_GEN_CNTL, rinfo->pending_lvds_gen_cntl); + } + } + else + start_timer = 0; #endif /* FIXME_LATER */ - if (rinfo->RenderCallback != NULL) - rinfo->RenderCallback(rinfo); + if (rinfo->RenderCallback != NULL) + rinfo->RenderCallback(rinfo); - if ((info->screen_mono != NULL) && info->update_mono) - { - int32_t foreground = 255, background = 0; - uint8_t *src_buf = (uint8_t *)info->screen_mono; - int skipleft = ((int)src_buf & 3) << 3; - int dst_x = 0; - int w = (int)info->var.xres_virtual; - int h = (int)info->var.yres_virtual; + if ((info->screen_mono != NULL) && info->update_mono) + { + int32_t foreground = 255, background = 0; + uint8_t *src_buf = (uint8_t *)info->screen_mono; + int skipleft = ((int)src_buf & 3) << 3; + int dst_x = 0; + int w = (int)info->var.xres_virtual; + int h = (int)info->var.yres_virtual; // info->fbops->SetClippingRectangle(info,0,0,w-1,h-1); - src_buf = (uint8_t*)((int32_t)src_buf & ~3); - dst_x -= (int32_t)skipleft; - w += (int32_t)skipleft; - info->fbops->SetupForScanlineCPUToScreenColorExpandFill(info,(int)foreground,(int)background,3,0xffffffff); - info->fbops->SubsequentScanlineCPUToScreenColorExpandFill(info,(int)dst_x,0,w,h,skipleft); + src_buf = (uint8_t*)((int32_t)src_buf & ~3); + dst_x -= (int32_t)skipleft; + w += (int32_t)skipleft; + info->fbops->SetupForScanlineCPUToScreenColorExpandFill(info,(int)foreground,(int)background,3,0xffffffff); + info->fbops->SubsequentScanlineCPUToScreenColorExpandFill(info,(int)dst_x,0,w,h,skipleft); - while (--h >= 0) - { - info->fbops->SubsequentScanline(info, (unsigned long *) src_buf); - src_buf += (info->var.xres_virtual >> 3); - } + while (--h >= 0) + { + info->fbops->SubsequentScanline(info, (unsigned long *) src_buf); + src_buf += (info->var.xres_virtual >> 3); + } // info->fbops->DisableClipping(info); - if (info->update_mono > 0) - info->update_mono = 0; - } + if (info->update_mono > 0) + info->update_mono = 0; + } - if ((info->var.xres_virtual != info->var.xres) - || (info->var.yres_virtual != info->var.yres)) - { - int ipl; - ipl = set_ipl(0); + if ((info->var.xres_virtual != info->var.xres) + || (info->var.yres_virtual != info->var.yres)) + { + int ipl; + ipl = set_ipl(0); - chg = 0; - x = info->var.xoffset; - y = info->var.yoffset; + chg = 0; + x = info->var.xoffset; + y = info->var.yoffset; - if (((x + info->var.xres) < info->var.xres_virtual) && (rinfo->cursor_x >= (info->var.xres - 8))) - { - x += 8; - chg = 1; - } - else if ((x >= 8) && (rinfo->cursor_x <= 8)) - { - x -= 8; - chg = 1; - } + if (((x + info->var.xres) < info->var.xres_virtual) && (rinfo->cursor_x >= (info->var.xres - 8))) + { + x += 8; + chg = 1; + } + else if ((x >= 8) && (rinfo->cursor_x <= 8)) + { + x -= 8; + chg = 1; + } - if (((y + info->var.yres) < info->var.yres_virtual) && (rinfo->cursor_y >= (info->var.yres - 8))) - { - y += 8; - chg = 1; - } - else if ((y >=8) && (rinfo->cursor_y <= 8)) - { - y -= 8; - chg = 1; - } + if (((y + info->var.yres) < info->var.yres_virtual) && (rinfo->cursor_y >= (info->var.yres - 8))) + { + y += 8; + chg = 1; + } + else if ((y >=8) && (rinfo->cursor_y <= 8)) + { + y -= 8; + chg = 1; + } - if (chg) - { - memcpy(&var, &info->var, sizeof(struct fb_var_screeninfo)); - var.xoffset = x; - var.yoffset = y; - disp = rinfo->cursor_show; - if (disp) - info->fbops->HideCursor(info); + if (chg) + { + memcpy(&var, &info->var, sizeof(struct fb_var_screeninfo)); + var.xoffset = x; + var.yoffset = y; + disp = rinfo->cursor_show; + if (disp) + info->fbops->HideCursor(info); - fb_pan_display(info,&var); + fb_pan_display(info,&var); - if (disp) - info->fbops->ShowCursor(info); - } - set_ipl(ipl); - } + if (disp) + info->fbops->ShowCursor(info); + } + set_ipl(ipl); + } } /* @@ -1437,71 +1447,71 @@ static void radeon_timer_func(void) */ void radeon_write_mode(struct radeonfb_info *rinfo, struct radeon_regs *mode, int32_t regs_only) { - int i; - int primary_mon = PRIMARY_MONITOR(rinfo); + int i; + int primary_mon = PRIMARY_MONITOR(rinfo); - dbg("radeonfb: radeon_write_mode\r\n"); + dbg("radeonfb: radeon_write_mode\r\n"); - if (!regs_only) - radeon_screen_blank(rinfo, FB_BLANK_NORMAL, 0); + if (!regs_only) + radeon_screen_blank(rinfo, FB_BLANK_NORMAL, 0); - radeon_wait_for_fifo(rinfo, 31); + radeon_wait_for_fifo(rinfo, 31); - for (i = 0; i < 10; i++) - OUTREG(common_regs[i].reg, common_regs[i].val); + for (i = 0; i < 10; i++) + OUTREG(common_regs[i].reg, common_regs[i].val); - /* Apply surface registers */ - for (i = 0; i < 8; i++) - { - OUTREG(SURFACE0_LOWER_BOUND + 0x10*i, mode->surf_lower_bound[i]); - OUTREG(SURFACE0_UPPER_BOUND + 0x10*i, mode->surf_upper_bound[i]); - OUTREG(SURFACE0_INFO + 0x10*i, mode->surf_info[i]); - } - OUTREG(CRTC_GEN_CNTL, mode->crtc_gen_cntl); - OUTREGP(CRTC_EXT_CNTL, mode->crtc_ext_cntl, ~(CRTC_HSYNC_DIS | CRTC_VSYNC_DIS | CRTC_DISPLAY_DIS)); - OUTREG(CRTC_MORE_CNTL, mode->crtc_more_cntl); - OUTREGP(DAC_CNTL, mode->dac_cntl, DAC_RANGE_CNTL | DAC_BLANKING); - OUTREG(CRTC_H_TOTAL_DISP, mode->crtc_h_total_disp); - OUTREG(CRTC_H_SYNC_STRT_WID, mode->crtc_h_sync_strt_wid); - OUTREG(CRTC_V_TOTAL_DISP, mode->crtc_v_total_disp); - OUTREG(CRTC_V_SYNC_STRT_WID, mode->crtc_v_sync_strt_wid); - rinfo->fb_offset = 0; - rinfo->dst_pitch_offset = (rinfo->pitch << 22) | ((rinfo->fb_local_base + rinfo->fb_offset) >> 10); - OUTREG(CRTC_OFFSET, rinfo->fb_offset); + /* Apply surface registers */ + for (i = 0; i < 8; i++) + { + OUTREG(SURFACE0_LOWER_BOUND + 0x10*i, mode->surf_lower_bound[i]); + OUTREG(SURFACE0_UPPER_BOUND + 0x10*i, mode->surf_upper_bound[i]); + OUTREG(SURFACE0_INFO + 0x10*i, mode->surf_info[i]); + } + OUTREG(CRTC_GEN_CNTL, mode->crtc_gen_cntl); + OUTREGP(CRTC_EXT_CNTL, mode->crtc_ext_cntl, ~(CRTC_HSYNC_DIS | CRTC_VSYNC_DIS | CRTC_DISPLAY_DIS)); + OUTREG(CRTC_MORE_CNTL, mode->crtc_more_cntl); + OUTREGP(DAC_CNTL, mode->dac_cntl, DAC_RANGE_CNTL | DAC_BLANKING); + OUTREG(CRTC_H_TOTAL_DISP, mode->crtc_h_total_disp); + OUTREG(CRTC_H_SYNC_STRT_WID, mode->crtc_h_sync_strt_wid); + OUTREG(CRTC_V_TOTAL_DISP, mode->crtc_v_total_disp); + OUTREG(CRTC_V_SYNC_STRT_WID, mode->crtc_v_sync_strt_wid); + rinfo->fb_offset = 0; + rinfo->dst_pitch_offset = (rinfo->pitch << 22) | ((rinfo->fb_local_base + rinfo->fb_offset) >> 10); + OUTREG(CRTC_OFFSET, rinfo->fb_offset); #ifdef RADEON_TILING - if (rinfo->tilingEnabled) - { - if (rinfo->family >= CHIP_FAMILY_R300) - OUTREG(CRTC_OFFSET_CNTL, R300_CRTC_X_Y_MODE_EN | R300_CRTC_MICRO_TILE_BUFFER_DIS | R300_CRTC_MACRO_TILE_EN); - else - OUTREG(CRTC_OFFSET_CNTL, CRTC_OFFSET_CNTL__CRTC_TILE_EN); - } - else + if (rinfo->tilingEnabled) + { + if (rinfo->family >= CHIP_FAMILY_R300) + OUTREG(CRTC_OFFSET_CNTL, R300_CRTC_X_Y_MODE_EN | R300_CRTC_MICRO_TILE_BUFFER_DIS | R300_CRTC_MACRO_TILE_EN); + else + OUTREG(CRTC_OFFSET_CNTL, CRTC_OFFSET_CNTL__CRTC_TILE_EN); + } + else #endif - OUTREG(CRTC_OFFSET_CNTL, 0); + OUTREG(CRTC_OFFSET_CNTL, 0); - OUTREG(CRTC_PITCH, mode->crtc_pitch); - OUTREG(SURFACE_CNTL, mode->surface_cntl); - radeon_write_pll_regs(rinfo, mode); + OUTREG(CRTC_PITCH, mode->crtc_pitch); + OUTREG(SURFACE_CNTL, mode->surface_cntl); + radeon_write_pll_regs(rinfo, mode); - if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD)) - { - radeon_wait_for_fifo(rinfo, 10); - OUTREG(FP_CRTC_H_TOTAL_DISP, mode->fp_crtc_h_total_disp); - OUTREG(FP_CRTC_V_TOTAL_DISP, mode->fp_crtc_v_total_disp); - OUTREG(FP_H_SYNC_STRT_WID, mode->fp_h_sync_strt_wid); - OUTREG(FP_V_SYNC_STRT_WID, mode->fp_v_sync_strt_wid); - OUTREG(FP_HORZ_STRETCH, mode->fp_horz_stretch); - OUTREG(FP_VERT_STRETCH, mode->fp_vert_stretch); - OUTREG(FP_GEN_CNTL, mode->fp_gen_cntl); - OUTREG(TMDS_CRC, mode->tmds_crc); - OUTREG(TMDS_TRANSMITTER_CNTL, mode->tmds_transmitter_cntl); - } + if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD)) + { + radeon_wait_for_fifo(rinfo, 10); + OUTREG(FP_CRTC_H_TOTAL_DISP, mode->fp_crtc_h_total_disp); + OUTREG(FP_CRTC_V_TOTAL_DISP, mode->fp_crtc_v_total_disp); + OUTREG(FP_H_SYNC_STRT_WID, mode->fp_h_sync_strt_wid); + OUTREG(FP_V_SYNC_STRT_WID, mode->fp_v_sync_strt_wid); + OUTREG(FP_HORZ_STRETCH, mode->fp_horz_stretch); + OUTREG(FP_VERT_STRETCH, mode->fp_vert_stretch); + OUTREG(FP_GEN_CNTL, mode->fp_gen_cntl); + OUTREG(TMDS_CRC, mode->tmds_crc); + OUTREG(TMDS_TRANSMITTER_CNTL, mode->tmds_transmitter_cntl); + } - if (!regs_only) - radeon_screen_blank(rinfo, FB_BLANK_UNBLANK, 0); - radeon_wait_for_fifo(rinfo, 2); - OUTPLL(VCLK_ECP_CNTL, mode->vclk_ecp_cntl); + if (!regs_only) + radeon_screen_blank(rinfo, FB_BLANK_UNBLANK, 0); + radeon_wait_for_fifo(rinfo, 2); + OUTPLL(VCLK_ECP_CNTL, mode->vclk_ecp_cntl); } /* @@ -1509,859 +1519,882 @@ void radeon_write_mode(struct radeonfb_info *rinfo, struct radeon_regs *mode, in */ static void radeon_calc_pll_regs(struct radeonfb_info *rinfo, struct radeon_regs *regs, uint32_t freq) { - static const struct - { - int divider; - int bitvalue; - } *post_div, - post_divs[] = - { - { 1, 0 }, - { 2, 1 }, - { 4, 2 }, - { 8, 3 }, - { 3, 4 }, - { 16, 5 }, - { 6, 6 }, - { 12, 7 }, - { 0, 0 }, - }; - int fb_div, pll_output_freq = 0; - int uses_dvo = 0; + static const struct + { + int divider; + int bitvalue; + } *post_div, + post_divs[] = + { + { 1, 0 }, + { 2, 1 }, + { 4, 2 }, + { 8, 3 }, + { 3, 4 }, + { 16, 5 }, + { 6, 6 }, + { 12, 7 }, + { 0, 0 }, + }; + int fb_div, pll_output_freq = 0; + int uses_dvo = 0; - /* Check if the DVO port is enabled and sourced from the primary CRTC. I'm - * not sure which model starts having FP2_GEN_CNTL, I assume anything more - * recent than an r(v)100... - */ + /* Check if the DVO port is enabled and sourced from the primary CRTC. I'm + * not sure which model starts having FP2_GEN_CNTL, I assume anything more + * recent than an r(v)100... + */ #if 1 - /* XXX I had reports of flicker happening with the cinema display - * on TMDS1 that seem to be fixed if I also forbit odd dividers in - * this case. This could just be a bandwidth calculation issue, I - * haven't implemented the bandwidth code yet, but in the meantime, - * forcing uses_dvo to 1 fixes it and shouln't have bad side effects, - * I haven't seen a case were were absolutely needed an odd PLL - * divider. I'll find a better fix once I have more infos on the - * real cause of the problem. - */ - while (rinfo->has_CRTC2) - { - uint32_t fp2_gen_cntl = INREG(FP2_GEN_CNTL); - uint32_t disp_output_cntl; - int source; + /* XXX I had reports of flicker happening with the cinema display + * on TMDS1 that seem to be fixed if I also forbit odd dividers in + * this case. This could just be a bandwidth calculation issue, I + * haven't implemented the bandwidth code yet, but in the meantime, + * forcing uses_dvo to 1 fixes it and shouln't have bad side effects, + * I haven't seen a case were were absolutely needed an odd PLL + * divider. I'll find a better fix once I have more infos on the + * real cause of the problem. + */ + while (rinfo->has_CRTC2) + { + uint32_t fp2_gen_cntl = INREG(FP2_GEN_CNTL); + uint32_t disp_output_cntl; + int source; - /* FP2 path not enabled */ - if ((fp2_gen_cntl & FP2_ON) == 0) - break; + /* FP2 path not enabled */ + if ((fp2_gen_cntl & FP2_ON) == 0) + break; - /* Not all chip revs have the same format for this register, - * extract the source selection - */ - if (rinfo->family == CHIP_FAMILY_R200 || rinfo->family == CHIP_FAMILY_R300 - || rinfo->family == CHIP_FAMILY_R350 || rinfo->family == CHIP_FAMILY_RV350) - { - source = (fp2_gen_cntl >> 10) & 0x3; - /* sourced from transform unit, check for transform unit - * own source - */ - if (source == 3) - { - disp_output_cntl = INREG(DISP_OUTPUT_CNTL); - source = (disp_output_cntl >> 12) & 0x3; - } - } - else - source = (fp2_gen_cntl >> 13) & 0x1; + /* Not all chip revs have the same format for this register, + * extract the source selection + */ + if (rinfo->family == CHIP_FAMILY_R200 || rinfo->family == CHIP_FAMILY_R300 + || rinfo->family == CHIP_FAMILY_R350 || rinfo->family == CHIP_FAMILY_RV350) + { + source = (fp2_gen_cntl >> 10) & 0x3; + /* sourced from transform unit, check for transform unit + * own source + */ + if (source == 3) + { + disp_output_cntl = INREG(DISP_OUTPUT_CNTL); + source = (disp_output_cntl >> 12) & 0x3; + } + } + else + source = (fp2_gen_cntl >> 13) & 0x1; - /* sourced from CRTC2 -> exit */ - if (source == 1) - break; + /* sourced from CRTC2 -> exit */ + if (source == 1) + break; - /* so we end up on CRTC1, let's set uses_dvo to 1 now */ - uses_dvo = 1; - break; - } + /* so we end up on CRTC1, let's set uses_dvo to 1 now */ + uses_dvo = 1; + break; + } #else - uses_dvo = 1; + uses_dvo = 1; #endif - if (freq > rinfo->pll.ppll_max) - freq = rinfo->pll.ppll_max; - if (freq * 12 < rinfo->pll.ppll_min) - freq = rinfo->pll.ppll_min / 12; - for (post_div = &post_divs[0]; post_div->divider; ++post_div) - { - pll_output_freq = post_div->divider * freq; + if (freq > rinfo->pll.ppll_max) + freq = rinfo->pll.ppll_max; + if (freq * 12 < rinfo->pll.ppll_min) + freq = rinfo->pll.ppll_min / 12; + for (post_div = &post_divs[0]; post_div->divider; ++post_div) + { + pll_output_freq = post_div->divider * freq; - /* - * If we output to the DVO port (external TMDS), we don't allow an - * odd PLL divider as those aren't supported on this path - */ - if (uses_dvo && (post_div->divider & 1)) - continue; + /* + * If we output to the DVO port (external TMDS), we don't allow an + * odd PLL divider as those aren't supported on this path + */ + if (uses_dvo && (post_div->divider & 1)) + continue; - if (pll_output_freq >= rinfo->pll.ppll_min && - pll_output_freq <= rinfo->pll.ppll_max) - break; - } + if (pll_output_freq >= rinfo->pll.ppll_min && + pll_output_freq <= rinfo->pll.ppll_max) + break; + } - /* If we fall through the bottom, try the "default value" - given by the terminal post_div->bitvalue */ - if (!post_div->divider) - { - post_div = &post_divs[post_div->bitvalue]; - pll_output_freq = post_div->divider * freq; - } + /* If we fall through the bottom, try the "default value" + given by the terminal post_div->bitvalue */ + if (!post_div->divider) + { + post_div = &post_divs[post_div->bitvalue]; + pll_output_freq = post_div->divider * freq; + } - /* If we fall through the bottom, try the "default value" - given by the terminal post_div->bitvalue */ - if ( !post_div->divider ) - { - post_div = &post_divs[post_div->bitvalue]; - pll_output_freq = post_div->divider * freq; - } - fb_div = round_div(rinfo->pll.ref_div*pll_output_freq,rinfo->pll.ref_clk); - regs->ppll_ref_div = rinfo->pll.ref_div; - regs->ppll_div_3 = fb_div | (post_div->bitvalue << 16); + /* If we fall through the bottom, try the "default value" + given by the terminal post_div->bitvalue */ + if ( !post_div->divider ) + { + post_div = &post_divs[post_div->bitvalue]; + pll_output_freq = post_div->divider * freq; + } + fb_div = round_div(rinfo->pll.ref_div*pll_output_freq,rinfo->pll.ref_clk); + regs->ppll_ref_div = rinfo->pll.ref_div; + regs->ppll_div_3 = fb_div | (post_div->bitvalue << 16); } int radeonfb_set_par(struct fb_info *info) { - struct radeonfb_info *rinfo = info->par; - struct fb_var_screeninfo *mode = &info->var; - struct radeon_regs *newmode; - int hTotal, vTotal, hSyncStart, hSyncEnd, vSyncStart, vSyncEnd; - // FIXME: int hSyncPol; this is not used anywhere - // FIXME: int vSyncPol; this is not used anywhere - // FIXME: int cSync; this is not used anywhere - static uint8_t hsync_adj_tab[] = {0, 0x12, 9, 9, 6, 5}; - static uint8_t hsync_fudge_fp[] = {2, 2, 0, 0, 5, 5}; - uint32_t sync, h_sync_pol, v_sync_pol, dotClock, pixClock; - int i, freq; - int format = 0; - int nopllcalc = 0; - int hsync_start; - int hsync_fudge; - // int bytpp; FIXME: this doesn't seem to be used anywhere - int hsync_wid, vsync_wid; - int primary_mon = PRIMARY_MONITOR(rinfo); - int depth = var_to_depth(mode); - int use_rmx = 0; + struct radeonfb_info *rinfo = info->par; + struct fb_var_screeninfo *mode = &info->var; + struct radeon_regs *newmode; + int hTotal, vTotal, hSyncStart, hSyncEnd, vSyncStart, vSyncEnd; + // FIXME: int hSyncPol; this is not used anywhere + // FIXME: int vSyncPol; this is not used anywhere + // FIXME: int cSync; this is not used anywhere + static uint8_t hsync_adj_tab[] = {0, 0x12, 9, 9, 6, 5}; + static uint8_t hsync_fudge_fp[] = {2, 2, 0, 0, 5, 5}; + uint32_t sync, h_sync_pol, v_sync_pol, dotClock, pixClock; + int i, freq; + int format = 0; + int nopllcalc = 0; + int hsync_start; + int hsync_fudge; + // int bytpp; FIXME: this doesn't seem to be used anywhere + int hsync_wid, vsync_wid; + int primary_mon = PRIMARY_MONITOR(rinfo); + int depth = var_to_depth(mode); + int use_rmx = 0; - newmode = (struct radeon_regs *) driver_mem_alloc(sizeof(struct radeon_regs)); - if (!newmode) - return -1; //-ENOMEM; + newmode = (struct radeon_regs *) driver_mem_alloc(sizeof(struct radeon_regs)); + if (!newmode) + return -1; //-ENOMEM; - /* We always want engine to be idle on a mode switch, even - * if we won't actually change the mode - */ - dbg("radeonfb: radeonfb_set_par\r\n"); - radeon_engine_idle(); - hSyncStart = mode->xres + mode->right_margin; - hSyncEnd = hSyncStart + mode->hsync_len; - hTotal = hSyncEnd + mode->left_margin; + /* We always want engine to be idle on a mode switch, even + * if we won't actually change the mode + */ + dbg("radeonfb: radeonfb_set_par\r\n"); + radeon_engine_idle(); + hSyncStart = mode->xres + mode->right_margin; + hSyncEnd = hSyncStart + mode->hsync_len; + hTotal = hSyncEnd + mode->left_margin; - vSyncStart = mode->yres + mode->lower_margin; - vSyncEnd = vSyncStart + mode->vsync_len; - vTotal = vSyncEnd + mode->upper_margin; + vSyncStart = mode->yres + mode->lower_margin; + vSyncEnd = vSyncStart + mode->vsync_len; + vTotal = vSyncEnd + mode->upper_margin; - pixClock = mode->pixclock; - sync = mode->sync; + pixClock = mode->pixclock; + sync = mode->sync; - h_sync_pol = sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1; - v_sync_pol = sync & FB_SYNC_VERT_HIGH_ACT ? 0 : 1; + h_sync_pol = sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1; + v_sync_pol = sync & FB_SYNC_VERT_HIGH_ACT ? 0 : 1; - if (primary_mon == MT_DFP || primary_mon == MT_LCD) - { - if (rinfo->panel_info.xres < mode->xres) - mode->xres = rinfo->panel_info.xres; + if (primary_mon == MT_DFP || primary_mon == MT_LCD) + { + if (rinfo->panel_info.xres < mode->xres) + mode->xres = rinfo->panel_info.xres; - if (rinfo->panel_info.yres < mode->yres) - mode->yres = rinfo->panel_info.yres; + if (rinfo->panel_info.yres < mode->yres) + mode->yres = rinfo->panel_info.yres; - hTotal = mode->xres + rinfo->panel_info.hblank; - hSyncStart = mode->xres + rinfo->panel_info.hOver_plus; - hSyncEnd = hSyncStart + rinfo->panel_info.hSync_width; + hTotal = mode->xres + rinfo->panel_info.hblank; + hSyncStart = mode->xres + rinfo->panel_info.hOver_plus; + hSyncEnd = hSyncStart + rinfo->panel_info.hSync_width; - vTotal = mode->yres + rinfo->panel_info.vblank; - vSyncStart = mode->yres + rinfo->panel_info.vOver_plus; - vSyncEnd = vSyncStart + rinfo->panel_info.vSync_width; + vTotal = mode->yres + rinfo->panel_info.vblank; + vSyncStart = mode->yres + rinfo->panel_info.vOver_plus; + vSyncEnd = vSyncStart + rinfo->panel_info.vSync_width; - h_sync_pol = !rinfo->panel_info.hAct_high; - v_sync_pol = !rinfo->panel_info.vAct_high; + h_sync_pol = !rinfo->panel_info.hAct_high; + v_sync_pol = !rinfo->panel_info.vAct_high; - pixClock = 100000000 / rinfo->panel_info.clock; + pixClock = 100000000 / rinfo->panel_info.clock; - if (rinfo->panel_info.use_bios_dividers) - { - nopllcalc = 1; - newmode->ppll_div_3 = rinfo->panel_info.fbk_divider | (rinfo->panel_info.post_divider << 16); - newmode->ppll_ref_div = rinfo->panel_info.ref_divider; - } - } + if (rinfo->panel_info.use_bios_dividers) + { + nopllcalc = 1; + newmode->ppll_div_3 = rinfo->panel_info.fbk_divider | (rinfo->panel_info.post_divider << 16); + newmode->ppll_ref_div = rinfo->panel_info.ref_divider; + } + } - dotClock = 1000000000 / pixClock; - freq = dotClock / 10; /* x100 */ - hsync_wid = (hSyncEnd - hSyncStart) / 8; + dotClock = 1000000000 / pixClock; + freq = dotClock / 10; /* x100 */ + hsync_wid = (hSyncEnd - hSyncStart) / 8; - if (hsync_wid == 0) - hsync_wid = 1; - else if (hsync_wid > 0x3f) /* max */ - hsync_wid = 0x3f; + if (hsync_wid == 0) + hsync_wid = 1; + else if (hsync_wid > 0x3f) /* max */ + hsync_wid = 0x3f; - if (mode->vmode & FB_VMODE_DOUBLE) - { - vSyncStart <<= 1; - vSyncEnd <<= 1; - vTotal <<= 1; - } + if (mode->vmode & FB_VMODE_DOUBLE) + { + vSyncStart <<= 1; + vSyncEnd <<= 1; + vTotal <<= 1; + } - vsync_wid = vSyncEnd - vSyncStart; - if (vsync_wid == 0) - vsync_wid = 1; - else if (vsync_wid > 0x1f) /* max */ - vsync_wid = 0x1f; + vsync_wid = vSyncEnd - vSyncStart; + if (vsync_wid == 0) + vsync_wid = 1; + else if (vsync_wid > 0x1f) /* max */ + vsync_wid = 0x1f; - // FIXME: this doesn't seem to be used anywhere hSyncPol = mode->sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1; - // FIXME: this doesn't seem to be used anywhere vSyncPol = mode->sync & FB_SYNC_VERT_HIGH_ACT ? 0 : 1; - // FIXME: this doesn't seem to be used anywhere cSync = mode->sync & FB_SYNC_COMP_HIGH_ACT ? (1 << 4) : 0; - format = radeon_get_dstbpp(depth); - // FIXME: this doesn't seem to be used anywhere bytpp = mode->bits_per_pixel >> 3; + // FIXME: this doesn't seem to be used anywhere hSyncPol = mode->sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1; + // FIXME: this doesn't seem to be used anywhere vSyncPol = mode->sync & FB_SYNC_VERT_HIGH_ACT ? 0 : 1; + // FIXME: this doesn't seem to be used anywhere cSync = mode->sync & FB_SYNC_COMP_HIGH_ACT ? (1 << 4) : 0; + format = radeon_get_dstbpp(depth); + // FIXME: this doesn't seem to be used anywhere bytpp = mode->bits_per_pixel >> 3; - if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD)) - hsync_fudge = hsync_fudge_fp[format-1]; - else - hsync_fudge = hsync_adj_tab[format-1]; + if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD)) + hsync_fudge = hsync_fudge_fp[format-1]; + else + hsync_fudge = hsync_adj_tab[format-1]; - if (mode->vmode & FB_VMODE_DOUBLE) - hsync_fudge = 0; /* todo: need adjust */ + if (mode->vmode & FB_VMODE_DOUBLE) + hsync_fudge = 0; /* todo: need adjust */ - hsync_start = hSyncStart - 8 + hsync_fudge; - newmode->crtc_gen_cntl = CRTC_EXT_DISP_EN | CRTC_EN | (format << 8); - if (mode->vmode & FB_VMODE_DOUBLE) - newmode->crtc_gen_cntl |= CRTC_DBL_SCAN_EN; - if (mode->vmode & FB_VMODE_INTERLACED) - newmode->crtc_gen_cntl |= CRTC_INTERLACE_EN; + hsync_start = hSyncStart - 8 + hsync_fudge; + newmode->crtc_gen_cntl = CRTC_EXT_DISP_EN | CRTC_EN | (format << 8); + if (mode->vmode & FB_VMODE_DOUBLE) + newmode->crtc_gen_cntl |= CRTC_DBL_SCAN_EN; + if (mode->vmode & FB_VMODE_INTERLACED) + newmode->crtc_gen_cntl |= CRTC_INTERLACE_EN; - /* Clear auto-center etc... */ - newmode->crtc_more_cntl = rinfo->init_state.crtc_more_cntl; - newmode->crtc_more_cntl &= 0xfffffff0; + /* Clear auto-center etc... */ + newmode->crtc_more_cntl = rinfo->init_state.crtc_more_cntl; + newmode->crtc_more_cntl &= 0xfffffff0; - if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD)) - { - newmode->crtc_ext_cntl = VGA_ATI_LINEAR | XCRT_CNT_EN; - if (mirror) - newmode->crtc_ext_cntl |= CRTC_CRT_ON; - newmode->crtc_gen_cntl &= ~(CRTC_DBL_SCAN_EN | CRTC_INTERLACE_EN); - } - else - newmode->crtc_ext_cntl = VGA_ATI_LINEAR | XCRT_CNT_EN | CRTC_CRT_ON; + if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD)) + { + newmode->crtc_ext_cntl = VGA_ATI_LINEAR | XCRT_CNT_EN; + if (mirror) + newmode->crtc_ext_cntl |= CRTC_CRT_ON; + newmode->crtc_gen_cntl &= ~(CRTC_DBL_SCAN_EN | CRTC_INTERLACE_EN); + } + else + newmode->crtc_ext_cntl = VGA_ATI_LINEAR | XCRT_CNT_EN | CRTC_CRT_ON; - newmode->dac_cntl = /* INREG(DAC_CNTL) | */ DAC_MASK_ALL | DAC_VGA_ADR_EN | DAC_8BIT_EN; - newmode->crtc_h_total_disp = ((((hTotal / 8) - 1) & 0x3ff) | (((mode->xres / 8) - 1) << 16)); - newmode->crtc_h_sync_strt_wid = ((hsync_start & 0x1fff) | (hsync_wid << 16) | (h_sync_pol << 23)); + newmode->dac_cntl = /* INREG(DAC_CNTL) | */ DAC_MASK_ALL | DAC_VGA_ADR_EN | DAC_8BIT_EN; + newmode->crtc_h_total_disp = ((((hTotal / 8) - 1) & 0x3ff) | (((mode->xres / 8) - 1) << 16)); + newmode->crtc_h_sync_strt_wid = ((hsync_start & 0x1fff) | (hsync_wid << 16) | (h_sync_pol << 23)); - if (mode->vmode & FB_VMODE_DOUBLE) - newmode->crtc_v_total_disp = ((vTotal - 1) & 0xffff) | (((mode->yres << 1) - 1) << 16); - else - newmode->crtc_v_total_disp = ((vTotal - 1) & 0xffff) | ((mode->yres - 1) << 16); + if (mode->vmode & FB_VMODE_DOUBLE) + newmode->crtc_v_total_disp = ((vTotal - 1) & 0xffff) | (((mode->yres << 1) - 1) << 16); + else + newmode->crtc_v_total_disp = ((vTotal - 1) & 0xffff) | ((mode->yres - 1) << 16); - newmode->crtc_v_sync_strt_wid = (((vSyncStart - 1) & 0xfff) | (vsync_wid << 16) | (v_sync_pol << 23)); - /* We first calculate the engine pitch */ - rinfo->pitch = ((mode->xres_virtual * ((mode->bits_per_pixel + 1) / 8) + 0x3f) & ~(0x3f)) >> 6; - /* Then, re-multiply it to get the CRTC pitch */ - newmode->crtc_pitch = (rinfo->pitch << 3) / ((mode->bits_per_pixel + 1) / 8); - newmode->crtc_pitch |= (newmode->crtc_pitch << 16); + newmode->crtc_v_sync_strt_wid = (((vSyncStart - 1) & 0xfff) | (vsync_wid << 16) | (v_sync_pol << 23)); + /* We first calculate the engine pitch */ + rinfo->pitch = ((mode->xres_virtual * ((mode->bits_per_pixel + 1) / 8) + 0x3f) & ~(0x3f)) >> 6; + /* Then, re-multiply it to get the CRTC pitch */ + newmode->crtc_pitch = (rinfo->pitch << 3) / ((mode->bits_per_pixel + 1) / 8); + newmode->crtc_pitch |= (newmode->crtc_pitch << 16); - /* - * It looks like recent chips have a problem with SURFACE_CNTL, - * setting SURF_TRANSLATION_DIS completely disables the - * swapper as well, so we leave it unset now. - */ - newmode->surface_cntl = 0; + /* + * It looks like recent chips have a problem with SURFACE_CNTL, + * setting SURF_TRANSLATION_DIS completely disables the + * swapper as well, so we leave it unset now. + */ + newmode->surface_cntl = 0; - if (rinfo->big_endian) - { - /* Setup swapping on both apertures, though we currently - * only use aperture 0, enabling swapper on aperture 1 - * won't harm - */ - switch(mode->bits_per_pixel) - { - case 16: - newmode->surface_cntl |= NONSURF_AP0_SWP_16BPP; - newmode->surface_cntl |= NONSURF_AP1_SWP_16BPP; - break; - case 24: - case 32: - newmode->surface_cntl |= NONSURF_AP0_SWP_32BPP; - newmode->surface_cntl |= NONSURF_AP1_SWP_32BPP; - break; - } - } + if (rinfo->big_endian) + { + /* Setup swapping on both apertures, though we currently + * only use aperture 0, enabling swapper on aperture 1 + * won't harm + */ + switch(mode->bits_per_pixel) + { + case 16: + newmode->surface_cntl |= NONSURF_AP0_SWP_16BPP; + newmode->surface_cntl |= NONSURF_AP1_SWP_16BPP; + break; + case 24: + case 32: + newmode->surface_cntl |= NONSURF_AP0_SWP_32BPP; + newmode->surface_cntl |= NONSURF_AP1_SWP_32BPP; + break; + } + } - /* Clear surface registers */ - for (i = 0; i < 8; i++) - { - newmode->surf_lower_bound[i] = 0; - newmode->surf_upper_bound[i] = 0x1f; - newmode->surf_info[i] = 0; - } + /* Clear surface registers */ + for (i = 0; i < 8; i++) + { + newmode->surf_lower_bound[i] = 0; + newmode->surf_upper_bound[i] = 0x1f; + newmode->surf_info[i] = 0; + } - rinfo->bpp = mode->bits_per_pixel; - rinfo->depth = depth; + rinfo->bpp = mode->bits_per_pixel; + rinfo->depth = depth; - /* We use PPLL_DIV_3 */ - newmode->clk_cntl_index = 0x300; + /* We use PPLL_DIV_3 */ + newmode->clk_cntl_index = 0x300; - /* Calculate PPLL value if necessary */ - if (!nopllcalc) - radeon_calc_pll_regs(rinfo, newmode, freq); + /* Calculate PPLL value if necessary */ + if (!nopllcalc) + radeon_calc_pll_regs(rinfo, newmode, freq); - newmode->vclk_ecp_cntl = rinfo->init_state.vclk_ecp_cntl; - if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD)) - { - int hRatio, vRatio; - if (mode->xres > rinfo->panel_info.xres) - mode->xres = rinfo->panel_info.xres; - if (mode->yres > rinfo->panel_info.yres) - mode->yres = rinfo->panel_info.yres; - newmode->fp_horz_stretch = (((rinfo->panel_info.xres / 8) - 1) << HORZ_PANEL_SHIFT); - newmode->fp_vert_stretch = ((rinfo->panel_info.yres - 1) << VERT_PANEL_SHIFT); + newmode->vclk_ecp_cntl = rinfo->init_state.vclk_ecp_cntl; + if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD)) + { + int hRatio, vRatio; + if (mode->xres > rinfo->panel_info.xres) + mode->xres = rinfo->panel_info.xres; + if (mode->yres > rinfo->panel_info.yres) + mode->yres = rinfo->panel_info.yres; + newmode->fp_horz_stretch = (((rinfo->panel_info.xres / 8) - 1) << HORZ_PANEL_SHIFT); + newmode->fp_vert_stretch = ((rinfo->panel_info.yres - 1) << VERT_PANEL_SHIFT); - if (mode->xres != rinfo->panel_info.xres) - { - hRatio = round_div(mode->xres * HORZ_STRETCH_RATIO_MAX, rinfo->panel_info.xres); - newmode->fp_horz_stretch = (((hRatio & HORZ_STRETCH_RATIO_MASK)) - | (newmode->fp_horz_stretch & (HORZ_PANEL_SIZE | HORZ_FP_LOOP_STRETCH | HORZ_AUTO_RATIO_INC))); - newmode->fp_horz_stretch |= (HORZ_STRETCH_BLEND | HORZ_STRETCH_ENABLE); - use_rmx = 1; - } + if (mode->xres != rinfo->panel_info.xres) + { + hRatio = round_div(mode->xres * HORZ_STRETCH_RATIO_MAX, rinfo->panel_info.xres); + newmode->fp_horz_stretch = (((hRatio & HORZ_STRETCH_RATIO_MASK)) + | (newmode->fp_horz_stretch & (HORZ_PANEL_SIZE | HORZ_FP_LOOP_STRETCH | HORZ_AUTO_RATIO_INC))); + newmode->fp_horz_stretch |= (HORZ_STRETCH_BLEND | HORZ_STRETCH_ENABLE); + use_rmx = 1; + } - newmode->fp_horz_stretch &= ~HORZ_AUTO_RATIO; - if (mode->yres != rinfo->panel_info.yres) - { - vRatio = round_div(mode->yres * VERT_STRETCH_RATIO_MAX, rinfo->panel_info.yres); - newmode->fp_vert_stretch = (((((uint32_t)vRatio) & VERT_STRETCH_RATIO_MASK)) - | (newmode->fp_vert_stretch & (VERT_PANEL_SIZE | VERT_STRETCH_RESERVED))); - newmode->fp_vert_stretch |= (VERT_STRETCH_BLEND | VERT_STRETCH_ENABLE); - use_rmx = 1; - } - newmode->fp_vert_stretch &= ~VERT_AUTO_RATIO_EN; - newmode->fp_gen_cntl = (rinfo->init_state.fp_gen_cntl - & ~(FP_SEL_CRTC2 | FP_RMX_HVSYNC_CONTROL_EN | FP_DFP_SYNC_SEL | FP_CRT_SYNC_SEL - | FP_CRTC_LOCK_8DOT | FP_USE_SHADOW_EN | FP_CRTC_USE_SHADOW_VEND | FP_CRT_SYNC_ALT)); - newmode->fp_gen_cntl |= (FP_CRTC_DONT_SHADOW_VPAR | FP_CRTC_DONT_SHADOW_HEND | FP_PANEL_FORMAT); + newmode->fp_horz_stretch &= ~HORZ_AUTO_RATIO; + if (mode->yres != rinfo->panel_info.yres) + { + vRatio = round_div(mode->yres * VERT_STRETCH_RATIO_MAX, rinfo->panel_info.yres); + newmode->fp_vert_stretch = (((((uint32_t)vRatio) & VERT_STRETCH_RATIO_MASK)) + | (newmode->fp_vert_stretch & (VERT_PANEL_SIZE | VERT_STRETCH_RESERVED))); + newmode->fp_vert_stretch |= (VERT_STRETCH_BLEND | VERT_STRETCH_ENABLE); + use_rmx = 1; + } + newmode->fp_vert_stretch &= ~VERT_AUTO_RATIO_EN; + newmode->fp_gen_cntl = (rinfo->init_state.fp_gen_cntl + & ~(FP_SEL_CRTC2 | FP_RMX_HVSYNC_CONTROL_EN | FP_DFP_SYNC_SEL | FP_CRT_SYNC_SEL + | FP_CRTC_LOCK_8DOT | FP_USE_SHADOW_EN | FP_CRTC_USE_SHADOW_VEND | FP_CRT_SYNC_ALT)); + newmode->fp_gen_cntl |= (FP_CRTC_DONT_SHADOW_VPAR | FP_CRTC_DONT_SHADOW_HEND | FP_PANEL_FORMAT); - if (IS_R300_VARIANT(rinfo) || (rinfo->family == CHIP_FAMILY_R200)) - { - newmode->fp_gen_cntl &= ~R200_FP_SOURCE_SEL_MASK; - if (use_rmx) - newmode->fp_gen_cntl |= R200_FP_SOURCE_SEL_RMX; - else - newmode->fp_gen_cntl |= R200_FP_SOURCE_SEL_CRTC1; - } - else - newmode->fp_gen_cntl |= FP_SEL_CRTC1; + if (IS_R300_VARIANT(rinfo) || (rinfo->family == CHIP_FAMILY_R200)) + { + newmode->fp_gen_cntl &= ~R200_FP_SOURCE_SEL_MASK; + if (use_rmx) + newmode->fp_gen_cntl |= R200_FP_SOURCE_SEL_RMX; + else + newmode->fp_gen_cntl |= R200_FP_SOURCE_SEL_CRTC1; + } + else + newmode->fp_gen_cntl |= FP_SEL_CRTC1; - newmode->lvds_gen_cntl = rinfo->init_state.lvds_gen_cntl; - newmode->lvds_pll_cntl = rinfo->init_state.lvds_pll_cntl; - newmode->tmds_crc = rinfo->init_state.tmds_crc; - newmode->tmds_transmitter_cntl = rinfo->init_state.tmds_transmitter_cntl; + newmode->lvds_gen_cntl = rinfo->init_state.lvds_gen_cntl; + newmode->lvds_pll_cntl = rinfo->init_state.lvds_pll_cntl; + newmode->tmds_crc = rinfo->init_state.tmds_crc; + newmode->tmds_transmitter_cntl = rinfo->init_state.tmds_transmitter_cntl; - if (primary_mon == MT_LCD) - { - newmode->lvds_gen_cntl |= (LVDS_ON | LVDS_BLON); - newmode->fp_gen_cntl &= ~(FP_FPON | FP_TMDS_EN); - } - else - { - /* DFP */ - newmode->fp_gen_cntl |= (FP_FPON | FP_TMDS_EN); - newmode->tmds_transmitter_cntl &= ~(TMDS_PLLRST); - /* TMDS_PLL_EN bit is reversed on RV (and mobility) chips */ - if (IS_R300_VARIANT(rinfo) || (rinfo->family == CHIP_FAMILY_R200) || !rinfo->has_CRTC2) - newmode->tmds_transmitter_cntl &= ~TMDS_PLL_EN; - else - newmode->tmds_transmitter_cntl |= TMDS_PLL_EN; - newmode->crtc_ext_cntl &= ~CRTC_CRT_ON; - } + if (primary_mon == MT_LCD) + { + newmode->lvds_gen_cntl |= (LVDS_ON | LVDS_BLON); + newmode->fp_gen_cntl &= ~(FP_FPON | FP_TMDS_EN); + } + else + { + /* DFP */ + newmode->fp_gen_cntl |= (FP_FPON | FP_TMDS_EN); + newmode->tmds_transmitter_cntl &= ~(TMDS_PLLRST); + /* TMDS_PLL_EN bit is reversed on RV (and mobility) chips */ + if (IS_R300_VARIANT(rinfo) || (rinfo->family == CHIP_FAMILY_R200) || !rinfo->has_CRTC2) + newmode->tmds_transmitter_cntl &= ~TMDS_PLL_EN; + else + newmode->tmds_transmitter_cntl |= TMDS_PLL_EN; + newmode->crtc_ext_cntl &= ~CRTC_CRT_ON; + } - newmode->fp_crtc_h_total_disp = (((rinfo->panel_info.hblank / 8) & 0x3ff) | (((mode->xres / 8) - 1) << 16)); - newmode->fp_crtc_v_total_disp = (rinfo->panel_info.vblank & 0xffff) | ((mode->yres - 1) << 16); - newmode->fp_h_sync_strt_wid = ((rinfo->panel_info.hOver_plus & 0x1fff) | (hsync_wid << 16) | (h_sync_pol << 23)); - newmode->fp_v_sync_strt_wid = ((rinfo->panel_info.vOver_plus & 0xfff) | (vsync_wid << 16) | (v_sync_pol << 23)); - } + newmode->fp_crtc_h_total_disp = (((rinfo->panel_info.hblank / 8) & 0x3ff) | (((mode->xres / 8) - 1) << 16)); + newmode->fp_crtc_v_total_disp = (rinfo->panel_info.vblank & 0xffff) | ((mode->yres - 1) << 16); + newmode->fp_h_sync_strt_wid = ((rinfo->panel_info.hOver_plus & 0x1fff) | (hsync_wid << 16) | (h_sync_pol << 23)); + newmode->fp_v_sync_strt_wid = ((rinfo->panel_info.vOver_plus & 0xfff) | (vsync_wid << 16) | (v_sync_pol << 23)); + } - /* do it! */ - if (!rinfo->asleep) - { + /* do it! */ + if (!rinfo->asleep) + { #if 0 - if (debug) - { - dbg("Press a key for write the video mode...\r\n"); - Bconin(2); - } + if (debug) + { + dbg("Press a key for write the video mode...\r\n"); + Bconin(2); + } #endif - memcpy(&rinfo->state, newmode, sizeof(*newmode)); + memcpy(&rinfo->state, newmode, sizeof(*newmode)); #ifdef RADEON_TILING - rinfo->tilingEnabled = (mode->vmode & (FB_VMODE_DOUBLE | FB_VMODE_INTERLACED)) ? FALSE : TRUE; + rinfo->tilingEnabled = (mode->vmode & (FB_VMODE_DOUBLE | FB_VMODE_INTERLACED)) ? FALSE : TRUE; #endif - radeon_write_mode(rinfo, newmode, 0); - /* (re)initialize the engine */ - radeon_engine_init(rinfo); - } + radeon_write_mode(rinfo, newmode, 0); + /* (re)initialize the engine */ + radeon_engine_init(rinfo); + } - /* Update fix */ - info->fix.line_length = rinfo->pitch*64; - info->fix.visual = rinfo->depth == 8 ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR; - driver_mem_free(newmode); + /* Update fix */ + info->fix.line_length = rinfo->pitch*64; + info->fix.visual = rinfo->depth == 8 ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR; + driver_mem_free(newmode); - return 0; + return 0; } static void radeonfb_check_modes(struct fb_info *info, struct mode_option *resolution) { - struct radeonfb_info *rinfo = info->par; + struct radeonfb_info *rinfo = info->par; - radeon_check_modes(rinfo, resolution); + radeon_check_modes(rinfo, resolution); } static struct fb_ops radeonfb_ops = { - .fb_check_var = radeonfb_check_var, - .fb_set_par = radeonfb_set_par, - .fb_setcolreg = radeonfb_setcolreg, - .fb_pan_display = radeonfb_pan_display, - .fb_blank = radeonfb_blank, - .fb_sync = radeonfb_sync, - .fb_ioctl = radeonfb_ioctl, - .fb_check_modes = radeonfb_check_modes, - .SetupForSolidFill = radeon_setup_for_solid_fill, - .SubsequentSolidFillRect = radeon_subsequent_solid_fill_rect_mmio, - .SetupForSolidLine = radeon_setup_for_solid_line_mmio, - .SubsequentSolidHorVertLine = radeon_subsequent_solid_hor_vert_line_mmio, - .SubsequentSolidTwoPointLine = radeon_subsequent_solid_two_point_line_mmio, - .SetupForDashedLine = radeon_setup_for_dashed_line_mmio, - .SubsequentDashedTwoPointLine = radeon_subsequent_dashed_two_point_line_mmio, - .SetupForScreenToScreenCopy = radeon_setup_for_screen_to_screen_copy_mmio, - .SubsequentScreenToScreenCopy = radeon_subsequent_screen_to_screen_copy_mmio, - .ScreenToScreenCopy = radeon_screen_to_screen_copy_mmio, - .SetupForMono8x8PatternFill = radeon_setup_for_mono_8x8_pattern_fill_mmio, - .SubsequentMono8x8PatternFillRect = radeon_subsequent_mono_8x8_pattern_fill_rect_mmio, - .SetupForScanlineCPUToScreenColorExpandFill = radeon_setup_for_scanline_cpu_to_screen_color_expand_fill_mmio, - .SubsequentScanlineCPUToScreenColorExpandFill = radeon_subsequent_scanline_cpu_to_screen_color_expand_fill_mmio, - .SubsequentScanline = radeon_subsequent_scanline_mmio, - .SetupForScanlineImageWrite = radeon_setup_for_scanline_image_write_mmio, - .SubsequentScanlineImageWriteRect = radeon_subsequent_scanline_image_write_rect_mmio, - .SetClippingRectangle = radeon_set_clipping_rectangle_mmio, - .DisableClipping = radeon_disable_clipping_mmio, + .fb_check_var = radeonfb_check_var, + .fb_set_par = radeonfb_set_par, + .fb_setcolreg = radeonfb_setcolreg, + .fb_pan_display = radeonfb_pan_display, + .fb_blank = radeonfb_blank, + .fb_sync = radeonfb_sync, + .fb_ioctl = radeonfb_ioctl, + .fb_check_modes = radeonfb_check_modes, + .SetupForSolidFill = radeon_setup_for_solid_fill, + .SubsequentSolidFillRect = radeon_subsequent_solid_fill_rect_mmio, + .SetupForSolidLine = radeon_setup_for_solid_line_mmio, + .SubsequentSolidHorVertLine = radeon_subsequent_solid_hor_vert_line_mmio, + .SubsequentSolidTwoPointLine = radeon_subsequent_solid_two_point_line_mmio, + .SetupForDashedLine = radeon_setup_for_dashed_line_mmio, + .SubsequentDashedTwoPointLine = radeon_subsequent_dashed_two_point_line_mmio, + .SetupForScreenToScreenCopy = radeon_setup_for_screen_to_screen_copy_mmio, + .SubsequentScreenToScreenCopy = radeon_subsequent_screen_to_screen_copy_mmio, + .ScreenToScreenCopy = radeon_screen_to_screen_copy_mmio, + .SetupForMono8x8PatternFill = radeon_setup_for_mono_8x8_pattern_fill_mmio, + .SubsequentMono8x8PatternFillRect = radeon_subsequent_mono_8x8_pattern_fill_rect_mmio, + .SetupForScanlineCPUToScreenColorExpandFill = radeon_setup_for_scanline_cpu_to_screen_color_expand_fill_mmio, + .SubsequentScanlineCPUToScreenColorExpandFill = radeon_subsequent_scanline_cpu_to_screen_color_expand_fill_mmio, + .SubsequentScanline = radeon_subsequent_scanline_mmio, + .SetupForScanlineImageWrite = radeon_setup_for_scanline_image_write_mmio, + .SubsequentScanlineImageWriteRect = radeon_subsequent_scanline_image_write_rect_mmio, + .SetClippingRectangle = radeon_set_clipping_rectangle_mmio, + .DisableClipping = radeon_disable_clipping_mmio, #ifdef RADEON_RENDER - .SetupForCPUToScreenAlphaTexture = radeon_setup_for_cpu_to_screen_alpha_texture_mmio, - .SetupForCPUToScreenTexture = radeon_setup_for_cpu_to_screen_texture_mmio, - .SubsequentCPUToScreenTexture = radeon_subsequent_cpu_to_screen_texture_mmio, + .SetupForCPUToScreenAlphaTexture = radeon_setup_for_cpu_to_screen_alpha_texture_mmio, + .SetupForCPUToScreenTexture = radeon_setup_for_cpu_to_screen_texture_mmio, + .SubsequentCPUToScreenTexture = radeon_subsequent_cpu_to_screen_texture_mmio, #else - .SetupForCPUToScreenAlphaTexture = NULL, - .SetupForCPUToScreenTexture = NULL, - .SubsequentCPUToScreenTexture = NULL, + .SetupForCPUToScreenAlphaTexture = NULL, + .SetupForCPUToScreenTexture = NULL, + .SubsequentCPUToScreenTexture = NULL, #endif /* RADEON_RENDER */ - .SetCursorColors = radeon_set_cursor_colors, - .SetCursorPosition = radeon_set_cursor_position, - .LoadCursorImage = radeon_load_cursor_image, - .HideCursor = radeon_hide_cursor, - .ShowCursor = radeon_show_cursor, - .CursorInit = radeon_cursor_init, - .WaitVbl = radeon_wait_vbl, + .SetCursorColors = radeon_set_cursor_colors, + .SetCursorPosition = radeon_set_cursor_position, + .LoadCursorImage = radeon_load_cursor_image, + .HideCursor = radeon_hide_cursor, + .ShowCursor = radeon_show_cursor, + .CursorInit = radeon_cursor_init, + .WaitVbl = radeon_wait_vbl, }; static int radeon_set_fbinfo(struct radeonfb_info *rinfo) { - struct fb_info *info = rinfo->info; + struct fb_info *info = rinfo->info; - info->par = rinfo; - info->fbops = &radeonfb_ops; - info->ram_base = info->screen_base = rinfo->fb_base; - info->screen_size = rinfo->mapped_vram; - info->ram_size = rinfo->mapped_vram; - if (info->screen_size > MAX_MAPPED_VRAM) - info->screen_size = MAX_MAPPED_VRAM; - else if (info->screen_size > MIN_MAPPED_VRAM) - info->screen_size = MIN_MAPPED_VRAM; + info->par = rinfo; + info->fbops = &radeonfb_ops; + info->ram_base = info->screen_base = rinfo->fb_base; + info->screen_size = rinfo->mapped_vram; + info->ram_size = rinfo->mapped_vram; + if (info->screen_size > MAX_MAPPED_VRAM) + info->screen_size = MAX_MAPPED_VRAM; + else if (info->screen_size > MIN_MAPPED_VRAM) + info->screen_size = MIN_MAPPED_VRAM; - dbg("%s: ram_base %p\r\n", __FUNCTION__, info->screen_base); - dbg("%s: ram_size %p\r\n", __FUNCTION__, info->ram_size); + dbg("ram_base %p\r\n", info->screen_base); + dbg("ram_size %p\r\n", info->ram_size); - /* Fill fix common fields */ - memcpy(info->fix.id, rinfo->name, sizeof(info->fix.id)); - info->fix.smem_start = rinfo->fb_base_phys; - info->fix.smem_len = rinfo->video_ram; - info->fix.type = FB_TYPE_PACKED_PIXELS; - info->fix.visual = FB_VISUAL_PSEUDOCOLOR; - info->fix.xpanstep = 8; - info->fix.ypanstep = 1; - info->fix.ywrapstep = 0; - info->fix.type_aux = 0; - info->fix.mmio_start = rinfo->mmio_base_phys; - info->fix.mmio_len = RADEON_REGSIZE; - info->fix.accel = FB_ACCEL_ATI_RADEON; - return 0; + /* Fill fix common fields */ + memcpy(info->fix.id, rinfo->name, sizeof(info->fix.id)); + info->fix.smem_start = rinfo->fb_base_phys; + info->fix.smem_len = rinfo->video_ram; + info->fix.type = FB_TYPE_PACKED_PIXELS; + info->fix.visual = FB_VISUAL_PSEUDOCOLOR; + info->fix.xpanstep = 8; + info->fix.ypanstep = 1; + info->fix.ywrapstep = 0; + info->fix.type_aux = 0; + info->fix.mmio_start = rinfo->mmio_base_phys; + info->fix.mmio_len = RADEON_REGSIZE; + info->fix.accel = FB_ACCEL_ATI_RADEON; + return 0; } static void radeon_identify_vram(struct radeonfb_info *rinfo) { - uint32_t tmp; - /* framebuffer size */ - if ((rinfo->family == CHIP_FAMILY_RS100) - || (rinfo->family == CHIP_FAMILY_RS200) - || (rinfo->family == CHIP_FAMILY_RS300)) - { - uint32_t tom = INREG(NB_TOM); - tmp = ((((tom >> 16) - (tom & 0xffff) + 1) << 6) * 1024); - radeon_wait_for_fifo(rinfo, 6); - OUTREG(MC_FB_LOCATION, tom); - OUTREG(DISPLAY_BASE_ADDR, (tom & 0xffff) << 16); - OUTREG(CRTC2_DISPLAY_BASE_ADDR, (tom & 0xffff) << 16); - OUTREG(OV0_BASE_ADDR, (tom & 0xffff) << 16); - /* This is supposed to fix the crtc2 noise problem. */ - OUTREG(GRPH2_BUFFER_CNTL, INREG(GRPH2_BUFFER_CNTL) & ~0x7f0000); - if ((rinfo->family == CHIP_FAMILY_RS100) || (rinfo->family == CHIP_FAMILY_RS200)) - { - /* This is to workaround the asic bug for RMX, some versions - of BIOS dosen't have this register initialized correctly. */ - OUTREGP(CRTC_MORE_CNTL, CRTC_H_CUTOFF_ACTIVE_EN, ~CRTC_H_CUTOFF_ACTIVE_EN); - } - } - else - tmp = INREG(CONFIG_MEMSIZE); - /* mem size is bits [28:0], mask off the rest */ - rinfo->video_ram = tmp & CONFIG_MEMSIZE_MASK; - /* - * Hack to get around some busted production M6's - * reporting no ram - */ - if (rinfo->video_ram == 0) - { - switch(rinfo->chipset) - { - case PCI_CHIP_RADEON_LY: - case PCI_CHIP_RADEON_LZ: rinfo->video_ram = 8192 * 1024; break; - default: break; - } - } - /* - * Now try to identify VRAM type - */ - if (rinfo->is_IGP || (rinfo->family >= CHIP_FAMILY_R300) - || (INREG(MEM_SDRAM_MODE_REG) & (1<<30))) - rinfo->vram_ddr = 1; - else - rinfo->vram_ddr = 0; - tmp = INREG(MEM_CNTL); - if (IS_R300_VARIANT(rinfo)) - { - tmp &= R300_MEM_NUM_CHANNELS_MASK; - switch(tmp) - { - case 0: rinfo->vram_width = 64; break; - case 1: rinfo->vram_width = 128; break; - case 2: rinfo->vram_width = 256; break; - default: rinfo->vram_width = 128; break; - } - } - else if ((rinfo->family == CHIP_FAMILY_RV100) - || (rinfo->family == CHIP_FAMILY_RS100) - || (rinfo->family == CHIP_FAMILY_RS200)) - { - if (tmp & RV100_MEM_HALF_MODE) - rinfo->vram_width = 32; - else - rinfo->vram_width = 64; - } - else - { - if (tmp & MEM_NUM_CHANNELS_MASK) - rinfo->vram_width = 128; - else - rinfo->vram_width = 64; - } + uint32_t tmp; + /* framebuffer size */ + if ((rinfo->family == CHIP_FAMILY_RS100) + || (rinfo->family == CHIP_FAMILY_RS200) + || (rinfo->family == CHIP_FAMILY_RS300)) + { + uint32_t tom = INREG(NB_TOM); + tmp = ((((tom >> 16) - (tom & 0xffff) + 1) << 6) * 1024); + radeon_wait_for_fifo(rinfo, 6); + OUTREG(MC_FB_LOCATION, tom); + OUTREG(DISPLAY_BASE_ADDR, (tom & 0xffff) << 16); + OUTREG(CRTC2_DISPLAY_BASE_ADDR, (tom & 0xffff) << 16); + OUTREG(OV0_BASE_ADDR, (tom & 0xffff) << 16); + /* This is supposed to fix the crtc2 noise problem. */ + OUTREG(GRPH2_BUFFER_CNTL, INREG(GRPH2_BUFFER_CNTL) & ~0x7f0000); + if ((rinfo->family == CHIP_FAMILY_RS100) || (rinfo->family == CHIP_FAMILY_RS200)) + { + /* This is to workaround the asic bug for RMX, some versions + of BIOS dosen't have this register initialized correctly. */ + OUTREGP(CRTC_MORE_CNTL, CRTC_H_CUTOFF_ACTIVE_EN, ~CRTC_H_CUTOFF_ACTIVE_EN); + } + } + else + tmp = INREG(CONFIG_MEMSIZE); + /* mem size is bits [28:0], mask off the rest */ + rinfo->video_ram = tmp & CONFIG_MEMSIZE_MASK; + /* + * Hack to get around some busted production M6's + * reporting no ram + */ + if (rinfo->video_ram == 0) + { + switch(rinfo->chipset) + { + case PCI_CHIP_RADEON_LY: + case PCI_CHIP_RADEON_LZ: rinfo->video_ram = 8192 * 1024; break; + default: break; + } + } + /* + * Now try to identify VRAM type + */ + if (rinfo->is_IGP || (rinfo->family >= CHIP_FAMILY_R300) + || (INREG(MEM_SDRAM_MODE_REG) & (1<<30))) + rinfo->vram_ddr = 1; + else + rinfo->vram_ddr = 0; + tmp = INREG(MEM_CNTL); + if (IS_R300_VARIANT(rinfo)) + { + tmp &= R300_MEM_NUM_CHANNELS_MASK; + switch(tmp) + { + case 0: rinfo->vram_width = 64; break; + case 1: rinfo->vram_width = 128; break; + case 2: rinfo->vram_width = 256; break; + default: rinfo->vram_width = 128; break; + } + } + else if ((rinfo->family == CHIP_FAMILY_RV100) + || (rinfo->family == CHIP_FAMILY_RS100) + || (rinfo->family == CHIP_FAMILY_RS200)) + { + if (tmp & RV100_MEM_HALF_MODE) + rinfo->vram_width = 32; + else + rinfo->vram_width = 64; + } + else + { + if (tmp & MEM_NUM_CHANNELS_MASK) + rinfo->vram_width = 128; + else + rinfo->vram_width = 64; + } - /* - * This may not be correct, as some cards can have half of channel disabled - * ToDo: identify these cases - */ - switch(rinfo->family) - { - case CHIP_FAMILY_LEGACY: dbg("%s chip type: %s\r\n", __FUNCTION__, "LEGACY"); break; - case CHIP_FAMILY_RADEON: dbg("%s chip type: %s\r\n", __FUNCTION__, "RADEON"); break; - case CHIP_FAMILY_RV100: dbg("%s chip type: %s\r\n", __FUNCTION__, "RV100"); break; - case CHIP_FAMILY_RS100: dbg("%s chip type: %s\r\n", __FUNCTION__, "RS100"); break; - case CHIP_FAMILY_RV200: dbg("%s chip type: %s\r\n", __FUNCTION__, "RV200"); break; - case CHIP_FAMILY_RS200: dbg("%s chip type: %s\r\n", __FUNCTION__, "RS200"); break; - case CHIP_FAMILY_R200: dbg("%s chip type: %s\r\n", __FUNCTION__, "R200"); break; - case CHIP_FAMILY_RV250: dbg("%s chip type: %s\r\n", __FUNCTION__, "RV250"); break; - case CHIP_FAMILY_RS300: dbg("%s chip type: %s\r\n", __FUNCTION__, "RS300"); break; - case CHIP_FAMILY_RV280: dbg("%s chip type: %s\r\n", __FUNCTION__, "RV280"); break; - case CHIP_FAMILY_R300: dbg("%s chip type: %s\r\n", __FUNCTION__, "R300"); break; - case CHIP_FAMILY_R350: dbg("%s chip type: %s\r\n", __FUNCTION__, "R350"); break; - case CHIP_FAMILY_RV350: dbg("%s chip type: %s\r\n", __FUNCTION__, "RV350"); break; - case CHIP_FAMILY_RV380: dbg("%s chip type: %s\r\n", __FUNCTION__, "RV380"); break; - case CHIP_FAMILY_R420: dbg("%s chip type: %s\r\n", __FUNCTION__, "R420"); break; - default: dbg("%s chip type: %s\r\n", "UNKNOW"); break; - } - dbg("%s: found %d KB of %d bits wide %s video RAM\r\n", __FUNCTION__, rinfo->video_ram / 1024, - rinfo->vram_width, rinfo->vram_ddr ? "DDR " : "SDRAM "); + /* + * This may not be correct, as some cards can have half of channel disabled + * ToDo: identify these cases + */ + switch(rinfo->family) + { + case CHIP_FAMILY_LEGACY: dbg("chip type: %s\r\n", "LEGACY"); break; + case CHIP_FAMILY_RADEON: dbg("chip type: %s\r\n", "RADEON"); break; + case CHIP_FAMILY_RV100: dbg("chip type: %s\r\n", "RV100"); break; + case CHIP_FAMILY_RS100: dbg("chip type: %s\r\n", "RS100"); break; + case CHIP_FAMILY_RV200: dbg("chip type: %s\r\n", "RV200"); break; + case CHIP_FAMILY_RS200: dbg("chip type: %s\r\n", "RS200"); break; + case CHIP_FAMILY_R200: dbg("chip type: %s\r\n", "R200"); break; + case CHIP_FAMILY_RV250: dbg("chip type: %s\r\n", "RV250"); break; + case CHIP_FAMILY_RS300: dbg("chip type: %s\r\n", "RS300"); break; + case CHIP_FAMILY_RV280: dbg("chip type: %s\r\n", "RV280"); break; + case CHIP_FAMILY_R300: dbg("chip type: %s\r\n", "R300"); break; + case CHIP_FAMILY_R350: dbg("chip type: %s\r\n", "R350"); break; + case CHIP_FAMILY_RV350: dbg("chip type: %s\r\n", "RV350"); break; + case CHIP_FAMILY_RV380: dbg("chip type: %s\r\n", "RV380"); break; + case CHIP_FAMILY_R420: dbg("chip type: %s\r\n", "R420"); break; + default: dbg("chip type: %s\r\n", "UNKNOW"); break; + } + dbg("found %d KB of %d bits wide %s video RAM\r\n", rinfo->video_ram / 1024, + rinfo->vram_width, rinfo->vram_ddr ? "DDR " : "SDRAM "); } int32_t radeonfb_pci_register(int32_t handle, const struct pci_device_id *ent) { - struct fb_info *info; - struct radeonfb_info *rinfo; - struct pci_rd *pci_rsc_desc; + struct fb_info *info; + struct radeonfb_info *rinfo; + struct pci_rd *pci_rsc_desc; - dbg("%s:\r\n", __FUNCTION__); - info = framebuffer_alloc(sizeof(struct radeonfb_info)); - if (!info) - { - dbg("%s: could not allocate frame buffer\r\n", __FUNCTION__); - return -1; // -ENOMEM; - } + dbg("\r\n"); + info = framebuffer_alloc(sizeof(struct radeonfb_info)); + if (!info) + { + dbg("could not allocate frame buffer\r\n"); + return -1; // -ENOMEM; + } - rinfo = info->par; + rinfo = info->par; - rinfo->info = info; - rinfo->handle = handle; - rinfo->name[11] = (char) (ent->device >> 8); - rinfo->name[12] = (char) ent->device; - rinfo->family = ent->driver_data & CHIP_FAMILY_MASK; - rinfo->chipset = ent->device; - rinfo->has_CRTC2 = (ent->driver_data & CHIP_HAS_CRTC2) != 0; - rinfo->is_mobility = (ent->driver_data & CHIP_IS_MOBILITY) != 0; - rinfo->is_IGP = (ent->driver_data & CHIP_IS_IGP) != 0; + rinfo->info = info; + rinfo->handle = handle; - /* Set base addrs */ - dbg("%s: Set base addrs\r\n", __FUNCTION__); - rinfo->fb_base_phys = rinfo->mmio_base_phys = rinfo->io_base_phys = 0xFFFFFFFF; - rinfo->mapped_vram = 0; - rinfo->mmio_base = rinfo->io_base = NULL; - rinfo->bios_seg = NULL; + strcpy((char *) rinfo->name, "ATI Radeon XX "); + rinfo->name[11] = (char) (ent->device >> 8); + rinfo->name[12] = (char) ent->device; - pci_rsc_desc = pci_get_resource(handle); - if ((int32_t) pci_rsc_desc >= 0) - { - uint16_t flags; - do - { - dbg("%s: flags %p\r\n", __FUNCTION__, pci_rsc_desc->flags); - dbg("%s: start %p\r\n", __FUNCTION__, pci_rsc_desc->start); - dbg("%s: offset 0x%x\r\n", __FUNCTION__, pci_rsc_desc->offset); - dbg("%s: length 0x%x\r\n", __FUNCTION__, pci_rsc_desc->length); + rinfo->family = ent->driver_data & CHIP_FAMILY_MASK; + rinfo->chipset = ent->device; + rinfo->has_CRTC2 = (ent->driver_data & CHIP_HAS_CRTC2) != 0; + rinfo->is_mobility = (ent->driver_data & CHIP_IS_MOBILITY) != 0; + rinfo->is_IGP = (ent->driver_data & CHIP_IS_IGP) != 0; - if (!(pci_rsc_desc->flags & FLG_IO)) - { - if ((rinfo->fb_base_phys == 0xFFFFFFFF) && (pci_rsc_desc->length >= 0x100000)) - { - rinfo->fb_base = (void *)(pci_rsc_desc->offset + pci_rsc_desc->start); - rinfo->fb_base_phys = pci_rsc_desc->start; - rinfo->mapped_vram = pci_rsc_desc->length; -// rinfo->dma_offset = pci_rsc_desc->dmaoffset; - if ((pci_rsc_desc->flags & FLG_ENDMASK) == ORD_MOTOROLA) - { - rinfo->big_endian = 0; /* host bridge make swapping intel -> motorola */ - dbg("%s: host bridge is big endian\r\n", __FUNCTION__); - } - else - { - rinfo->big_endian = 1; /* radeon make swapping intel -> motorola */ - dbg("%s: host bridge is little endian\r\n", __FUNCTION__); - } - } - else if ((pci_rsc_desc->length >= RADEON_REGSIZE) && (pci_rsc_desc->length < 0x100000)) - { - if (pci_rsc_desc->flags & FLG_ROM) - { - dbg("%s: FLG_ROM resource descriptor found\r\n", __FUNCTION__); - dbg("%s: start = %p, size = 0x%x\r\n", __FUNCTION__, pci_rsc_desc->start, pci_rsc_desc->length); - dbg("%s: bios_seg = %p\r\n", __FUNCTION__, rinfo->bios_seg); - - if (rinfo->bios_seg == NULL) - { - rinfo->bios_seg_phys = pci_rsc_desc->start; - if (BIOS_IN16(0) == 0xaa55) - rinfo->bios_seg = (void *) (pci_rsc_desc->offset + pci_rsc_desc->start); - else - { - dbg("%s: BIOS_IN16(0) was %x (expected 0xaa55)\r\n", __FUNCTION__, BIOS_IN16(0)); - rinfo->bios_seg_phys = 0; - } - } - } - else - { - if (rinfo->mmio_base_phys == 0xFFFFFFFF) - { - rinfo->mmio_base = (void *)(pci_rsc_desc->offset + pci_rsc_desc->start); - rinfo->mmio_base_phys = pci_rsc_desc->start; - } - } - } - } - else - { - if (rinfo->io_base_phys == 0xFFFFFFFF) - { - rinfo->io_base = (void *)(pci_rsc_desc->offset + pci_rsc_desc->start); - rinfo->io_base_phys = pci_rsc_desc->start; - } - } - flags = pci_rsc_desc->flags; - pci_rsc_desc = (struct pci_rd *) ((uint32_t) pci_rsc_desc->next + (uint32_t) pci_rsc_desc); - } while (!(flags & FLG_LAST)); - } - else - dbg("%s: get_resource error\r\n", __FUNCTION__); + /* Set base addrs */ + dbg("Set base addrs\r\n"); + rinfo->fb_base_phys = rinfo->mmio_base_phys = rinfo->io_base_phys = 0xFFFFFFFF; + rinfo->mapped_vram = 0; + rinfo->mmio_base = rinfo->io_base = NULL; + rinfo->bios_seg = NULL; - /* map the regions */ - dbg("%s: map memory regions\r\n", __FUNCTION__); - if (rinfo->mmio_base == NULL) - { - dbg("%s: cannot map MMIO\r\n", __FUNCTION__); - framebuffer_release(info); - return -2; //(-EIO); - } - dbg("%s: mmio_base_phys %p, mmio_base %p\r\n", __FUNCTION__, rinfo->mmio_base_phys, rinfo->mmio_base); - dbg("%s: io_base_phys %p, io_base %p\r\n", __FUNCTION__, rinfo->io_base_phys, rinfo->io_base); - dbg("%s: fb_base_phys %p, fb_base %p\r\n", __FUNCTION__, rinfo->fb_base_phys, rinfo->fb_base); + pci_rsc_desc = pci_get_resource(handle); + if ((int32_t) pci_rsc_desc >= 0) + { + uint16_t flags; + do + { + dbg("flags %p\r\n", pci_rsc_desc->flags); + dbg(" start %p\r\n", pci_rsc_desc->start); + dbg(" offset 0x%x\r\n", pci_rsc_desc->offset); + dbg(" length 0x%x\r\n", pci_rsc_desc->length); - /* - * Check for errata - */ - dbg("%s: check for errata\r\n", __FUNCTION__); - rinfo->errata = 0; - if (rinfo->family == CHIP_FAMILY_R300 - && (INREG(CONFIG_CNTL) & CFG_ATI_REV_ID_MASK) == CFG_ATI_REV_A11) - rinfo->errata |= CHIP_ERRATA_R300_CG; - if (rinfo->family == CHIP_FAMILY_RV200 || rinfo->family == CHIP_FAMILY_RS200) - rinfo->errata |= CHIP_ERRATA_PLL_DUMMYREADS; - if (rinfo->family == CHIP_FAMILY_RV100 - || rinfo->family == CHIP_FAMILY_RS100 - || rinfo->family == CHIP_FAMILY_RS200) - rinfo->errata |= CHIP_ERRATA_PLL_DELAY; + if (!(pci_rsc_desc->flags & FLG_IO)) + { + if ((rinfo->fb_base_phys == 0xFFFFFFFF) && (pci_rsc_desc->length >= 0x100000)) + { + rinfo->fb_base = (void *)(pci_rsc_desc->offset + pci_rsc_desc->start); + rinfo->fb_base_phys = pci_rsc_desc->start; + rinfo->mapped_vram = pci_rsc_desc->length; +// rinfo->dma_offset = pci_rsc_desc->dmaoffset; + if ((pci_rsc_desc->flags & FLG_ENDMASK) == ORD_MOTOROLA) + { + rinfo->big_endian = 0; /* host bridge make swapping intel -> motorola */ + dbg("host bridge is big endian\r\n"); + } + else + { + rinfo->big_endian = 1; /* radeon make swapping intel -> motorola */ + dbg("host bridge is little endian\r\n"); + } - /* - * Map the BIOS ROM if any and retreive PLL parameters from - * the BIOS. - */ - dbg("%s: bios_seg_phys %p\r\n", __FUNCTION__, rinfo->bios_seg_phys); - dbg("%s: map the BIOS ROM\r\n", __FUNCTION__); - radeon_map_ROM(rinfo); + xprintf("framebuffer dump:\r\n"); + hexdump((uint8_t *) rinfo->fb_base_phys, 0x10); + xprintf("change framebuffer contents\r\n"); + * (uint32_t *) rinfo->fb_base_phys = 0x01234567; + * (uint32_t *) (rinfo->fb_base_phys + 8) = 0x89abcdef; + hexdump((uint8_t *) rinfo->fb_base_phys, 0x10); - /* Run VGA BIOS */ - if ((rinfo->bios_seg != NULL)) - { - dbg("%s: run VGA BIOS\r\n", __FUNCTION__); - run_bios(rinfo); - } - else - { - dbg("%s: could not run VGA bios - rinfo->bios_seg is NULL\r\n", __FUNCTION__); - } + } + else if ((pci_rsc_desc->length >= RADEON_REGSIZE) && (pci_rsc_desc->length < 0x100000)) + { + if (pci_rsc_desc->flags & FLG_ROM) + { + dbg("FLG_ROM resource descriptor found\r\n"); + dbg(" start = %p, size = 0x%x\r\n", pci_rsc_desc->start, pci_rsc_desc->length); + dbg(" bios_seg = %p\r\n", rinfo->bios_seg); - dbg("%s: fixup display base address \r\n", __FUNCTION__); + if (rinfo->bios_seg == NULL) + { + rinfo->bios_seg_phys = pci_rsc_desc->start; + if (BIOS_IN16(0) == 0xaa55) + { + rinfo->bios_seg = (void *) (pci_rsc_desc->offset + pci_rsc_desc->start); + } + else + { + dbg("rinfo->bios_seg[0] (%p) was %x (expected 0xaa55)\r\n", + rinfo->bios_seg_phys, * (uint16_t *) rinfo->bios_seg_phys); + xprintf("bios_seg_phys dump:\r\n"); + hexdump((uint8_t *) rinfo->bios_seg_phys, 0x100); - OUTREG(MC_FB_LOCATION, 0x7fff0000); - rinfo->fb_local_base = 0; + rinfo->bios_seg_phys = 0; + } + } + } + else + { + if (rinfo->mmio_base_phys == 0xFFFFFFFF) + { + rinfo->mmio_base = (void *)(pci_rsc_desc->offset + pci_rsc_desc->start); + rinfo->mmio_base_phys = pci_rsc_desc->start; - /* Fixup the display base addresses & engine offsets while we - * are at it as well - */ - OUTREG(DISPLAY_BASE_ADDR, 0); - if (rinfo->has_CRTC2) - OUTREG(CRTC2_DISPLAY_BASE_ADDR, 0); + xprintf("mmio_base dump:\r\n"); + hexdump((uint8_t *) rinfo->mmio_base_phys, 0x100); + } + } + } + } + else + { + if (rinfo->io_base_phys == 0xFFFFFFFF) + { + rinfo->io_base = (void *)(pci_rsc_desc->offset + pci_rsc_desc->start); + rinfo->io_base_phys = pci_rsc_desc->start; - OUTREG(OV0_BASE_ADDR, 0); + xprintf("io_base dump:\r\n"); + hexdump((uint8_t *) rinfo->io_base_phys, 0x100); + } + } + flags = pci_rsc_desc->flags; + pci_rsc_desc = (struct pci_rd *) ((uint32_t) pci_rsc_desc->next + (uint32_t) pci_rsc_desc); + } while (!(flags & FLG_LAST)); + } + else + dbg("get_resource error\r\n"); - /* Get VRAM size and type */ - dbg("%s: get VRAM size\r\n", __FUNCTION__); - radeon_identify_vram(rinfo); + /* map the regions */ + dbg("map memory regions\r\n"); + if (rinfo->mmio_base == NULL) + { + dbg("cannot map MMIO\r\n"); + framebuffer_release(info); + return -2; //(-EIO); + } + dbg("mmio_base_phys %p, mmio_base %p\r\n", rinfo->mmio_base_phys, rinfo->mmio_base); + dbg("io_base_phys %p, io_base %p\r\n", rinfo->io_base_phys, rinfo->io_base); + dbg("fb_base_phys %p, fb_base %p\r\n", rinfo->fb_base_phys, rinfo->fb_base); - if ((rinfo->fb_base == NULL) - || ((rinfo->video_ram > rinfo->mapped_vram) && (rinfo->mapped_vram < MIN_MAPPED_VRAM * 2))) - { - dbg("%s: cannot map FB, video ram: %d KB\r\n", __FUNCTION__, rinfo->mapped_vram / 1024); - framebuffer_release(info); - return -2; //(-EIO); - } - else - { - dbg("%s: %d KB of VRAM mapped to %p\r\n", __FUNCTION__, rinfo->mapped_vram / 1024, rinfo->fb_base); - } - - /* Get informations about the board's PLL */ - dbg("%s: get informations about the board's PLL\r\n", __FUNCTION__); - radeon_get_pllinfo(rinfo); + /* + * Check for errata + */ + dbg("check for errata\r\n"); + rinfo->errata = 0; + if (rinfo->family == CHIP_FAMILY_R300 + && (INREG(CONFIG_CNTL) & CFG_ATI_REV_ID_MASK) == CFG_ATI_REV_A11) + rinfo->errata |= CHIP_ERRATA_R300_CG; + if (rinfo->family == CHIP_FAMILY_RV200 || rinfo->family == CHIP_FAMILY_RS200) + rinfo->errata |= CHIP_ERRATA_PLL_DUMMYREADS; + if (rinfo->family == CHIP_FAMILY_RV100 + || rinfo->family == CHIP_FAMILY_RS100 + || rinfo->family == CHIP_FAMILY_RS200) + rinfo->errata |= CHIP_ERRATA_PLL_DELAY; + + /* + * Map the BIOS ROM if any and retreive PLL parameters from + * the BIOS. + */ + dbg("bios_seg_phys %p\r\n", rinfo->bios_seg_phys); + dbg("map the BIOS ROM\r\n"); + radeon_map_ROM(rinfo); + + /* Run VGA BIOS */ + if ((rinfo->bios_seg != NULL)) + { + dbg("run VGA BIOS\r\n"); + run_bios(rinfo); + } + else + { + dbg("could not run VGA bios - rinfo->bios_seg is NULL\r\n"); + } + + dbg("fixup display base address \r\n"); + + OUTREG(MC_FB_LOCATION, 0x7fff0000); + rinfo->fb_local_base = 0; + + /* Fixup the display base addresses & engine offsets while we + * are at it as well + */ + OUTREG(DISPLAY_BASE_ADDR, 0); + if (rinfo->has_CRTC2) + OUTREG(CRTC2_DISPLAY_BASE_ADDR, 0); + + OUTREG(OV0_BASE_ADDR, 0); + + /* Get VRAM size and type */ + dbg("get VRAM size\r\n"); + radeon_identify_vram(rinfo); + + if ((rinfo->fb_base == NULL) + || ((rinfo->video_ram > rinfo->mapped_vram) && (rinfo->mapped_vram < MIN_MAPPED_VRAM * 2))) + { + dbg("cannot map FB, video ram: %d KB\r\n", rinfo->mapped_vram / 1024); + framebuffer_release(info); + return -2; //(-EIO); + } + else + { + dbg("%d KB of VRAM mapped to %p\r\n", rinfo->mapped_vram / 1024, rinfo->fb_base); + } + + /* Get informations about the board's PLL */ + dbg("get informations about the board's PLL\r\n"); + radeon_get_pllinfo(rinfo); #ifdef CONFIG_FB_RADEON_I2C - /* Register I2C bus */ - dbg("%s: register I2C bus\r\n", __FUNCTION__); - radeon_create_i2c_busses(rinfo); + /* Register I2C bus */ + dbg("register I2C bus\r\n"); + radeon_create_i2c_busses(rinfo); #endif /* CONFIG_FB_RADEON_I2C */ - /* set all the vital stuff */ - dbg("%s: set all the vital stuff\r\n", __FUNCTION__); - radeon_set_fbinfo(rinfo); + /* set all the vital stuff */ + dbg("set all the vital stuff\r\n"); + radeon_set_fbinfo(rinfo); - /* set offscreen memory descriptor */ - dbg("%s: set offscreen memory descriptor\r\n", __FUNCTION__); - offscreen_init(info); + /* set offscreen memory descriptor */ + dbg("set offscreen memory descriptor\r\n"); + offscreen_init(info); - /* Probe screen types */ - dbg("%s: probe screen types, monitor_layout: 0x%x\r\n", __FUNCTION__, monitor_layout); - radeon_probe_screens(rinfo, monitor_layout, (int) ignore_edid); + /* Probe screen types */ + dbg("probe screen types, monitor_layout: 0x%x\r\n", monitor_layout); + radeon_probe_screens(rinfo, monitor_layout, (int) ignore_edid); - /* Build mode list, check out panel native model */ - dbg("%s: build mode list\r\n", __FUNCTION__); - radeon_check_modes(rinfo, &resolution); + /* Build mode list, check out panel native model */ + dbg("build mode list\r\n"); + radeon_check_modes(rinfo, &resolution); - /* - * save current mode regs before we switch into the new one - * so we can restore this upon exit - */ - dbg("%s: save current mode\r\n", __FUNCTION__); - radeon_save_state(rinfo, &rinfo->init_state); - memcpy(&rinfo->state, &rinfo->init_state, sizeof(struct radeon_regs)); + /* + * save current mode regs before we switch into the new one + * so we can restore this upon exit + */ + dbg("save current mode\r\n"); + radeon_save_state(rinfo, &rinfo->init_state); + memcpy(&rinfo->state, &rinfo->init_state, sizeof(struct radeon_regs)); - /* Setup Power Management capabilities */ + /* Setup Power Management capabilities */ // DPRINT("radeonfb: radeonfb_pci_register: setup power management\r\n"); // radeonfb_pm_init(rinfo, (int)default_dynclk); - dbg("%s: install VBL timer\r\n", __FUNCTION__); - rinfo->lvds_timer = 0; + dbg("install VBL timer\r\n"); + rinfo->lvds_timer = 0; #ifndef DRIVER_IN_ROM - install_vbl_timer(radeon_timer_func, 1); /* remove old vector */ + install_vbl_timer(radeon_timer_func, 1); /* remove old vector */ #else - install_vbl_timer(radeon_timer_func, 0); + install_vbl_timer(radeon_timer_func, 0); #endif - //rinfo->RageTheatreCrystal = rinfo->RageTheatreTunerPort=rinfo->RageTheatreCompositePort = rinfo->RageTheatreSVideoPort = -1; - //rinfo->tunerType = -1; - return(0); + //rinfo->RageTheatreCrystal = rinfo->RageTheatreTunerPort=rinfo->RageTheatreCompositePort = rinfo->RageTheatreSVideoPort = -1; + //rinfo->tunerType = -1; + return(0); } #if 0 void radeonfb_pci_unregister(void) { - struct fb_info *info = info_fb; - struct radeonfb_info *rinfo = info->par; + struct fb_info *info = info_fb; + struct radeonfb_info *rinfo = info->par; // radeonfb_pm_exit(rinfo); - uninstall_vbl_timer(radeon_timer_func); - if (rinfo->mon1_EDID!=NULL) - driver_mem_free(rinfo->mon1_EDID); - if (rinfo->mon2_EDID!=NULL) - driver_mem_free(rinfo->mon2_EDID); - if (rinfo->mon1_modedb) - fb_destroy_modedb(rinfo->mon1_modedb); + uninstall_vbl_timer(radeon_timer_func); + if (rinfo->mon1_EDID!=NULL) + driver_mem_free(rinfo->mon1_EDID); + if (rinfo->mon2_EDID!=NULL) + driver_mem_free(rinfo->mon2_EDID); + if (rinfo->mon1_modedb) + fb_destroy_modedb(rinfo->mon1_modedb); #ifdef CONFIG_FB_RADEON_I2C - radeon_delete_i2c_busses(rinfo); -#endif - framebuffer_release(info); + radeon_delete_i2c_busses(rinfo); +#endif + framebuffer_release(info); } #endif diff --git a/BaS_gcc/sys/BaS.c b/BaS_gcc/sys/BaS.c index 3a0c58d..6e51572 100644 --- a/BaS_gcc/sys/BaS.c +++ b/BaS_gcc/sys/BaS.c @@ -79,12 +79,12 @@ extern uint8_t _EMUTOS_SIZE[]; */ static inline bool pic_txready(void) { - if (MCF_PSC3_PSCSR & MCF_PSC_PSCSR_TXRDY) - { - return true; - } + if (MCF_PSC3_PSCSR & MCF_PSC_PSCSR_TXRDY) + { + return true; + } - return false; + return false; } /* @@ -92,98 +92,98 @@ static inline bool pic_txready(void) */ static inline bool pic_rxready(void) { - if (MCF_PSC3_PSCSR & MCF_PSC_PSCSR_RXRDY) - { - return true; - } + if (MCF_PSC3_PSCSR & MCF_PSC_PSCSR_RXRDY) + { + return true; + } - return false; + return false; } void write_pic_byte(uint8_t value) { - /* - * Wait until the transmitter is ready or 1000us are passed - */ - waitfor(1000, pic_txready); + /* + * Wait until the transmitter is ready or 1000us are passed + */ + waitfor(1000, pic_txready); - /* - * Transmit the byte - */ - *(volatile uint8_t*)(&MCF_PSC3_PSCTB_8BIT) = value; // Really 8-bit + /* + * Transmit the byte + */ + *(volatile uint8_t*)(&MCF_PSC3_PSCTB_8BIT) = value; // Really 8-bit } uint8_t read_pic_byte(void) { - /* - * Wait until a byte has been received or 1000us are passed - */ - waitfor(1000, pic_rxready); + /* + * Wait until a byte has been received or 1000us are passed + */ + waitfor(1000, pic_rxready); - /* - * Return the received byte - */ - return * (volatile uint8_t *) (&MCF_PSC3_PSCTB_8BIT); // Really 8-bit + /* + * Return the received byte + */ + return * (volatile uint8_t *) (&MCF_PSC3_PSCTB_8BIT); // Really 8-bit } void pic_init(void) { - char answer[4] = "OLD"; + char answer[4] = "OLD"; - xprintf("initialize the PIC: "); + xprintf("initialize the PIC: "); - /* - * Send the PIC initialization string - */ - write_pic_byte('A'); - write_pic_byte('C'); - write_pic_byte('P'); - write_pic_byte('F'); + /* + * Send the PIC initialization string + */ + write_pic_byte('A'); + write_pic_byte('C'); + write_pic_byte('P'); + write_pic_byte('F'); - /* - * Read the 3-char answer string. Should be "OK!". - */ - answer[0] = read_pic_byte(); - answer[1] = read_pic_byte(); - answer[2] = read_pic_byte(); - answer[3] = '\0'; + /* + * Read the 3-char answer string. Should be "OK!". + */ + answer[0] = read_pic_byte(); + answer[1] = read_pic_byte(); + answer[2] = read_pic_byte(); + answer[3] = '\0'; - if (answer[0] != 'O' || answer[1] != 'K' || answer[2] != '!') - { - dbg("PIC initialization failed. Already initialized?\r\n"); - } - else - { - xprintf("%s\r\n", answer); - } + if (answer[0] != 'O' || answer[1] != 'K' || answer[2] != '!') + { + dbg("PIC initialization failed. Already initialized?\r\n"); + } + else + { + xprintf("%s\r\n", answer); + } } void nvram_init(void) { - int i; + int i; - xprintf("Restore the NVRAM data: "); + xprintf("Restore the NVRAM data: "); - /* Request for NVRAM backup data */ - write_pic_byte(0x01); + /* Request for NVRAM backup data */ + write_pic_byte(0x01); - /* Check answer type */ - if (read_pic_byte() != 0x81) - { - // FIXME: PIC protocol error - xprintf("FAILED\r\n"); - return; - } + /* Check answer type */ + if (read_pic_byte() != 0x81) + { + // FIXME: PIC protocol error + xprintf("FAILED\r\n"); + return; + } - /* Restore the NVRAM backup to the FPGA */ - for (i = 0; i < 64; i++) - { - uint8_t data = read_pic_byte(); - *(volatile uint8_t*)0xffff8961 = i; - *(volatile uint8_t*)0xffff8963 = data; - } + /* Restore the NVRAM backup to the FPGA */ + for (i = 0; i < 64; i++) + { + uint8_t data = read_pic_byte(); + *(volatile uint8_t*)0xffff8961 = i; + *(volatile uint8_t*)0xffff8963 = data; + } - xprintf("finished\r\n"); + xprintf("finished\r\n"); } #define KBD_ACIA_CONTROL * ((uint8_t *) 0xfffffc00) @@ -193,74 +193,74 @@ void nvram_init(void) void acia_init() { - xprintf("init ACIA: "); - /* init ACIA */ - KBD_ACIA_CONTROL = 3; /* master reset */ - NOP(); + xprintf("init ACIA: "); + /* init ACIA */ + KBD_ACIA_CONTROL = 3; /* master reset */ + NOP(); - MIDI_ACIA_CONTROL = 3; /* master reset */ - NOP(); + MIDI_ACIA_CONTROL = 3; /* master reset */ + NOP(); - KBD_ACIA_CONTROL = 0x96; /* clock div = 64, 8N1, RTS low, TX int disable, RX int enable */ - NOP(); + KBD_ACIA_CONTROL = 0x96; /* clock div = 64, 8N1, RTS low, TX int disable, RX int enable */ + NOP(); - MFP_INTR_IN_SERVICE_A = 0xff; - NOP(); + MFP_INTR_IN_SERVICE_A = 0xff; + NOP(); - MFP_INTR_IN_SERVICE_B = 0xff; - NOP(); + MFP_INTR_IN_SERVICE_B = 0xff; + NOP(); - xprintf("finished\r\n"); + xprintf("finished\r\n"); } void enable_coldfire_interrupts() { - xprintf("enable interrupts: "); + xprintf("enable interrupts: "); #if defined(MACHINE_FIREBEE) - FBEE_INTR_CONTROL = 0L; /* disable all interrupts */ + FBEE_INTR_CONTROL = 0L; /* disable all interrupts */ #endif /* MACHINE_FIREBEE */ - MCF_EPORT_EPPAR = 0xaaa8; /* all interrupts on falling edge */ + MCF_EPORT_EPPAR = 0xaaa8; /* all interrupts on falling edge */ #if defined(MACHINE_FIREBEE) - /* - * TIN0 on the Coldfire is connected to the FPGA. TIN0 triggers every write - * access to 0xff8201 (vbasehi), i.e. everytime the video base address is written - */ - MCF_GPT0_GMS = MCF_GPT_GMS_ICT(1) | /* timer 0 on, video change capture on rising edge */ - MCF_GPT_GMS_IEN | - MCF_GPT_GMS_TMS(1); /* route GPT0 interrupt on interrupt controller */ - MCF_INTC_ICR62 = MCF_INTC_ICR_IL(7) | - MCF_INTC_ICR_IP(6); /* interrupt level 7, interrupt priority 7 */ + /* + * TIN0 on the Coldfire is connected to the FPGA. TIN0 triggers every write + * access to 0xff8201 (vbasehi), i.e. everytime the video base address is written + */ + MCF_GPT0_GMS = MCF_GPT_GMS_ICT(1) | /* timer 0 on, video change capture on rising edge */ + MCF_GPT_GMS_IEN | + MCF_GPT_GMS_TMS(1); /* route GPT0 interrupt on interrupt controller */ + MCF_INTC_ICR62 = MCF_INTC_ICR_IL(7) | + MCF_INTC_ICR_IP(6); /* interrupt level 7, interrupt priority 7 */ - MCF_EPORT_EPIER = 0xfe; /* int 1-7 on */ - MCF_EPORT_EPFR = 0xff; /* clear all pending interrupts */ - MCF_INTC_IMRL = 0xffffff00; /* int 1-7 on */ - //MCF_INTC_IMRH = 0xbffffffe; /* psc3 and timer 0 int on */ - MCF_INTC_IMRH = 0; - FBEE_INTR_ENABLE = FBEE_INTR_INT_IRQ7 | /* enable pseudo bus error */ - FBEE_INTR_INT_MFP_IRQ6 | /* enable MFP interrupts */ - FBEE_INTR_INT_FPGA_IRQ5 | /* enable Firebee (PIC, PCI, ETH PHY, DVI, DSP) interrupts */ - FBEE_INTR_INT_VSYNC_IRQ4 | /* enable vsync interrupts */ - FBEE_INTR_PCI_INTA | /* enable PCI interrupts */ - FBEE_INTR_PCI_INTB | - FBEE_INTR_PCI_INTC | - FBEE_INTR_PCI_INTD; + MCF_EPORT_EPIER = 0xfe; /* int 1-7 on */ + MCF_EPORT_EPFR = 0xff; /* clear all pending interrupts */ + MCF_INTC_IMRL = 0xffffff00; /* int 1-7 on */ + //MCF_INTC_IMRH = 0xbffffffe; /* psc3 and timer 0 int on */ + MCF_INTC_IMRH = 0; + FBEE_INTR_ENABLE = FBEE_INTR_INT_IRQ7 | /* enable pseudo bus error */ + FBEE_INTR_INT_MFP_IRQ6 | /* enable MFP interrupts */ + FBEE_INTR_INT_FPGA_IRQ5 | /* enable Firebee (PIC, PCI, ETH PHY, DVI, DSP) interrupts */ + FBEE_INTR_INT_VSYNC_IRQ4 | /* enable vsync interrupts */ + FBEE_INTR_PCI_INTA | /* enable PCI interrupts */ + FBEE_INTR_PCI_INTB | + FBEE_INTR_PCI_INTC | + FBEE_INTR_PCI_INTD; #endif - xprintf("finished\r\n"); + xprintf("finished\r\n"); } void disable_coldfire_interrupts() { #if defined(MACHINE_FIREBEE) - FBEE_INTR_ENABLE = 0; /* disable all interrupts */ + FBEE_INTR_ENABLE = 0; /* disable all interrupts */ #endif /* MACHINE_FIREBEE */ - MCF_EPORT_EPIER = 0x0; - MCF_INTC_IMRL = 0xfffffffe; - MCF_INTC_IMRH = 0xffffffff; + MCF_EPORT_EPIER = 0x0; + MCF_INTC_IMRL = 0xfffffffe; + MCF_INTC_IMRH = 0xffffffff; } @@ -272,11 +272,11 @@ NIF nif2; bool spurious_interrupt_handler(void *arg1, void *arg2) { - dbg("IMRH=%lx, IMRL=%lx\r\n", MCF_INTC_IMRH, MCF_INTC_IMRL); - dbg("IPRH=%lx, IPRL=%lx\r\n", MCF_INTC_IPRH, MCF_INTC_IPRL); - dbg("IRLR=%x\r\n", MCF_INTC_IRLR); + dbg("IMRH=%lx, IMRL=%lx\r\n", MCF_INTC_IMRH, MCF_INTC_IMRL); + dbg("IPRH=%lx, IPRL=%lx\r\n", MCF_INTC_IPRH, MCF_INTC_IPRL); + dbg("IRLR=%x\r\n", MCF_INTC_IRLR); - return true; + return true; } /* @@ -284,195 +284,195 @@ bool spurious_interrupt_handler(void *arg1, void *arg2) */ void init_isr(void) { - isr_init(); /* need to call that explicitely, otherwise isr table might be full */ + isr_init(); /* need to call that explicitely, otherwise isr table might be full */ - /* - * register spurious interrupt handler - */ - if (!isr_register_handler(24, 6, 6, spurious_interrupt_handler, NULL, NULL)) - { - dbg("unable to register spurious interrupt handler\r\n"); - } + /* + * register spurious interrupt handler + */ + if (!isr_register_handler(24, 6, 6, spurious_interrupt_handler, NULL, NULL)) + { + dbg("unable to register spurious interrupt handler\r\n"); + } - /* - * register the FEC interrupt handler - */ - if (!isr_register_handler(64 + INT_SOURCE_FEC0, 5, 1, fec0_interrupt_handler, NULL, (void *) &nif1)) - { - dbg("unable to register isr for FEC0\r\n"); - } + /* + * register the FEC interrupt handler + */ + if (!isr_register_handler(64 + INT_SOURCE_FEC0, 5, 1, fec0_interrupt_handler, NULL, (void *) &nif1)) + { + dbg("unable to register isr for FEC0\r\n"); + } - /* - * Register the DMA interrupt handler - */ + /* + * Register the DMA interrupt handler + */ - if (!isr_register_handler(64 + INT_SOURCE_DMA, 5, 3, dma_interrupt_handler, NULL, NULL)) - { - dbg("unable to register isr for DMA\r\n"); - } + if (!isr_register_handler(64 + INT_SOURCE_DMA, 5, 3, dma_interrupt_handler, NULL, NULL)) + { + dbg("unable to register isr for DMA\r\n"); + } #ifdef MACHINE_FIREBEE - /* - * register GPT0 timer interrupt vector - */ - if (!isr_register_handler(64 + INT_SOURCE_GPT0, 5, 2, gpt0_interrupt_handler, NULL, NULL)) - { - dbg("unable to register isr for GPT0 timer\r\n"); - } + /* + * register GPT0 timer interrupt vector + */ + if (!isr_register_handler(64 + INT_SOURCE_GPT0, 5, 2, gpt0_interrupt_handler, NULL, NULL)) + { + dbg("unable to register isr for GPT0 timer\r\n"); + } - /* - * register the PIC interrupt handler - */ - if (!isr_register_handler(64 + INT_SOURCE_PSC3, 5, 5, pic_interrupt_handler, NULL, NULL)) - { - dbg("Error: unable to register ISR for PSC3\r\n"); - } + /* + * register the PIC interrupt handler + */ + if (!isr_register_handler(64 + INT_SOURCE_PSC3, 5, 5, pic_interrupt_handler, NULL, NULL)) + { + dbg("Error: unable to register ISR for PSC3\r\n"); + } #endif /* MACHINE_FIREBEE */ - /* - * register the XLB PCI interrupt handler - */ - if (!isr_register_handler(64 + INT_SOURCE_XLBPCI, 7, 0, xlbpci_interrupt_handler, NULL, NULL)) - { - dbg("Error: unable to register isr for XLB PCI interrupts\r\n"); - } + /* + * register the XLB PCI interrupt handler + */ + if (!isr_register_handler(64 + INT_SOURCE_XLBPCI, 7, 0, xlbpci_interrupt_handler, NULL, NULL)) + { + dbg("Error: unable to register isr for XLB PCI interrupts\r\n"); + } - MCF_XLB_XARB_IMR = MCF_XLB_XARB_IMR_SEAE | /* slave error acknowledge interrupt */ - MCF_XLB_XARB_IMR_MME | /* multiple master at prio 0 interrupt */ - MCF_XLB_XARB_IMR_TTAE | /* TT address only interrupt */ - MCF_XLB_XARB_IMR_TTRE | /* TT reserved interrupt enable */ - MCF_XLB_XARB_IMR_ECWE | /* external control word interrupt */ - MCF_XLB_XARB_IMR_TTME | /* TBST/TSIZ mismatch interrupt */ - MCF_XLB_XARB_IMR_BAE; /* bus activity tenure timeout interrupt */ + MCF_XLB_XARB_IMR = MCF_XLB_XARB_IMR_SEAE | /* slave error acknowledge interrupt */ + MCF_XLB_XARB_IMR_MME | /* multiple master at prio 0 interrupt */ + MCF_XLB_XARB_IMR_TTAE | /* TT address only interrupt */ + MCF_XLB_XARB_IMR_TTRE | /* TT reserved interrupt enable */ + MCF_XLB_XARB_IMR_ECWE | /* external control word interrupt */ + MCF_XLB_XARB_IMR_TTME | /* TBST/TSIZ mismatch interrupt */ + MCF_XLB_XARB_IMR_BAE; /* bus activity tenure timeout interrupt */ - if (!isr_register_handler(64 + INT_SOURCE_PCIARB, 7, 1, pciarb_interrupt_handler, NULL, NULL)) - { - dbg("Error: unable to register isr for PCIARB interrupts\r\n"); + if (!isr_register_handler(64 + INT_SOURCE_PCIARB, 7, 1, pciarb_interrupt_handler, NULL, NULL)) + { + dbg("Error: unable to register isr for PCIARB interrupts\r\n"); - return; - } - MCF_PCIARB_PACR = MCF_PCIARB_PACR_EXTMINTEN(0x1f) | /* external master broken interrupt */ - MCF_PCIARB_PACR_INTMINTEN; /* internal master broken interrupt */ + return; + } + MCF_PCIARB_PACR = MCF_PCIARB_PACR_EXTMINTEN(0x1f) | /* external master broken interrupt */ + MCF_PCIARB_PACR_INTMINTEN; /* internal master broken interrupt */ } void BaS(void) { - uint8_t *src; - uint8_t *dst = (uint8_t *) TOS; + uint8_t *src; + uint8_t *dst = (uint8_t *) TOS; #if defined(MACHINE_FIREBEE) /* LITE board has no pic and (currently) no nvram */ - pic_init(); - nvram_init(); + pic_init(); + nvram_init(); #endif /* MACHINE_FIREBEE */ - xprintf("initialize MMU: "); - mmu_init(); - xprintf("finished\r\n"); + xprintf("initialize MMU: "); + mmu_init(); + xprintf("finished\r\n"); - xprintf("copy EmuTOS: "); + xprintf("copy EmuTOS: "); - dma_init(); + dma_init(); - /* copy EMUTOS */ - src = (uint8_t *) EMUTOS; - dma_memcpy(dst, src, EMUTOS_SIZE); - xprintf("finished\r\n"); + /* copy EMUTOS */ + src = (uint8_t *) EMUTOS; + dma_memcpy(dst, src, EMUTOS_SIZE); + xprintf("finished\r\n"); - xprintf("initialize exception vector table: "); - vec_init(); - xprintf("finished\r\n"); + xprintf("initialize exception vector table: "); + vec_init(); + xprintf("finished\r\n"); - xprintf("flush caches: "); - flush_and_invalidate_caches(); - xprintf("finished\r\n"); - xprintf("enable MMU: "); - MCF_MMU_MMUCR = MCF_MMU_MMUCR_EN; /* MMU on */ - NOP(); /* force pipeline sync */ - xprintf("finished\r\n"); + xprintf("flush caches: "); + flush_and_invalidate_caches(); + xprintf("finished\r\n"); + xprintf("enable MMU: "); + MCF_MMU_MMUCR = MCF_MMU_MMUCR_EN; /* MMU on */ + NOP(); /* force pipeline sync */ + xprintf("finished\r\n"); #ifdef MACHINE_FIREBEE - xprintf("IDE reset: "); - /* IDE reset */ - * (volatile uint8_t *) (0xffff8802 - 2) = 14; - * (volatile uint8_t *) (0xffff8802 - 0) = 0x80; - wait(1); + xprintf("IDE reset: "); + /* IDE reset */ + * (volatile uint8_t *) (0xffff8802 - 2) = 14; + * (volatile uint8_t *) (0xffff8802 - 0) = 0x80; + wait(1); - * (volatile uint8_t *) (0xffff8802 - 0) = 0; + * (volatile uint8_t *) (0xffff8802 - 0) = 0; - xprintf("finished\r\n"); - xprintf("enable video: "); - /* - * video setup (25MHz) - */ - * (volatile uint32_t *) (0xf0000410 + 0) = 0x032002ba; /* horizontal 640x480 */ - * (volatile uint32_t *) (0xf0000410 + 4) = 0x020c020a; /* vertical 640x480 */ - * (volatile uint32_t *) (0xf0000410 + 8) = 0x0190015d; /* horizontal 320x240 */ - * (volatile uint32_t *) (0xf0000410 + 12) = 0x020C020A; /* vertical 320x230 */ + xprintf("finished\r\n"); + xprintf("enable video: "); + /* + * video setup (25MHz) + */ + * (volatile uint32_t *) (0xf0000410 + 0) = 0x032002ba; /* horizontal 640x480 */ + * (volatile uint32_t *) (0xf0000410 + 4) = 0x020c020a; /* vertical 640x480 */ + * (volatile uint32_t *) (0xf0000410 + 8) = 0x0190015d; /* horizontal 320x240 */ + * (volatile uint32_t *) (0xf0000410 + 12) = 0x020C020A; /* vertical 320x230 */ - /* fifo on, refresh on, ddrcs and cke on, video dac on */ - * (volatile uint32_t *) (0xf0000410 - 0x20) = 0x01070002; + /* fifo on, refresh on, ddrcs and cke on, video dac on */ + * (volatile uint32_t *) (0xf0000410 - 0x20) = 0x01070002; - xprintf("finished\r\n"); + xprintf("finished\r\n"); #endif /* MACHINE_FIREBEE */ - sd_card_init(); + sd_card_init(); - /* - * memory setup - */ - memset((void *) 0x400, 0, 0x400); + /* + * memory setup + */ + memset((void *) 0x400, 0, 0x400); #if defined(MACHINE_FIREBEE) - /* set Falcon bus control register */ - /* sets bit 3 and 6. Both are undefined on an original Falcon? */ + /* set Falcon bus control register */ + /* sets bit 3 and 6. Both are undefined on an original Falcon? */ - * (volatile uint8_t *) 0xffff8007 = 0x48; + * (volatile uint8_t *) 0xffff8007 = 0x48; #endif /* MACHINE_FIREBEE */ - /* ST RAM */ + /* ST RAM */ - * (uint32_t *) 0x42e = STRAM_END; /* phystop TOS system variable */ - * (uint32_t *) 0x420 = 0x752019f3; /* memvalid TOS system variable */ - * (uint32_t *) 0x43a = 0x237698aa; /* memval2 TOS system variable */ - * (uint32_t *) 0x51a = 0x5555aaaa; /* memval3 TOS system variable */ + * (uint32_t *) 0x42e = STRAM_END; /* phystop TOS system variable */ + * (uint32_t *) 0x420 = 0x752019f3; /* memvalid TOS system variable */ + * (uint32_t *) 0x43a = 0x237698aa; /* memval2 TOS system variable */ + * (uint32_t *) 0x51a = 0x5555aaaa; /* memval3 TOS system variable */ - /* TT-RAM */ + /* TT-RAM */ - * (uint32_t *) 0x5a4 = FASTRAM_END; /* ramtop TOS system variable */ - * (uint32_t *) 0x5a8 = 0x1357bd13; /* ramvalid TOS system variable */ + * (uint32_t *) 0x5a4 = FASTRAM_END; /* ramtop TOS system variable */ + * (uint32_t *) 0x5a8 = 0x1357bd13; /* ramvalid TOS system variable */ #if defined(MACHINE_FIREBEE) /* m5484lite has no ACIA and no dip switch... */ - acia_init(); + acia_init(); #endif /* MACHINE_FIREBEE */ - srec_execute("BASFLASH.S19"); + srec_execute("BASFLASH.S19"); - /* Jump into the OS */ - typedef void void_func(void); - struct rom_header - { - void *initial_sp; - void_func *initial_pc; - }; + /* Jump into the OS */ + typedef void void_func(void); + struct rom_header + { + void *initial_sp; + void_func *initial_pc; + }; - xprintf("BaS initialization finished, enable interrupts\r\n"); - init_isr(); + xprintf("BaS initialization finished, enable interrupts\r\n"); + init_isr(); - enable_coldfire_interrupts(); - MCF_INTC_IMRH = 0; - MCF_INTC_IMRL = 0; - dma_irq_enable(); - fec_irq_enable(0, 5, 1); + enable_coldfire_interrupts(); + MCF_INTC_IMRH = 0; + MCF_INTC_IMRL = 0; + dma_irq_enable(); + fec_irq_enable(0, 5, 1); - init_pci(); - // video_init(); + init_pci(); + video_init(); - /* initialize USB devices */ - //init_usb(); + /* initialize USB devices */ + //init_usb(); - set_ipl(7); /* disable interrupts */ + set_ipl(7); /* disable interrupts */ - xprintf("call EmuTOS\r\n"); - struct rom_header *os_header = (struct rom_header *) TOS; - os_header->initial_pc(); + xprintf("call EmuTOS\r\n"); + struct rom_header *os_header = (struct rom_header *) TOS; + os_header->initial_pc(); } diff --git a/BaS_gcc/sys/interrupts.c b/BaS_gcc/sys/interrupts.c index d8e328b..8450492 100644 --- a/BaS_gcc/sys/interrupts.c +++ b/BaS_gcc/sys/interrupts.c @@ -37,7 +37,7 @@ #include "dma.h" #include "pci.h" -//#define IRQ_DEBUG +// #define IRQ_DEBUG #if defined(IRQ_DEBUG) #define dbg(format, arg...) do { xprintf("DEBUG %s(): " format, __FUNCTION__, ##arg); } while (0) #else diff --git a/BaS_gcc/sys/mmu.c b/BaS_gcc/sys/mmu.c index c2c89df..63dab07 100644 --- a/BaS_gcc/sys/mmu.c +++ b/BaS_gcc/sys/mmu.c @@ -1,6 +1,7 @@ #include "mmu.h" #include "acia.h" #include "exceptions.h" +#include "pci.h" #if defined(MACHINE_FIREBEE) #include "firebee.h" @@ -626,7 +627,7 @@ void mmu_init(void) ACR_BA(0x80000000)); /* (equals area from 3 to 4 GB */ #elif defined(MACHINE_M5484LITE) ACR_ADMSK(0x7f) | /* cover 2 GB area from 0x80000000 to 0xffffffff */ - ACR_BA(0x80000000)); + ACR_BA(PCI_MEMORY_OFFSET)); #elif defined(MACHINE_M54455) ACR_ADMSK(0x7f) | ACR_BA(0x80000000)); /* FIXME: not determined yet */ @@ -634,8 +635,6 @@ void mmu_init(void) #error unknown machine! #endif /* MACHINE_FIREBEE */ - // set_acr1(0x601fc000); - /* data access attributes for BaS in flash */ set_acr1(ACR_W(0) | diff --git a/BaS_gcc/sys/sysinit.c b/BaS_gcc/sys/sysinit.c index 53f41ce..ad96192 100644 --- a/BaS_gcc/sys/sysinit.c +++ b/BaS_gcc/sys/sysinit.c @@ -425,7 +425,7 @@ void init_fbcs() MCF_FBCS2_CSAR = MCF_FBCS_CSAR_BA(0xF0000000); /* Firebee new I/O address range */ MCF_FBCS2_CSCR = MCF_FBCS_CSCR_PS_32 /* 32BIT PORT */ - | MCF_FBCS_CSCR_WS(8) /* DEFAULT 4WS */ + | MCF_FBCS_CSCR_WS(4) /* DEFAULT 4WS */ | MCF_FBCS_CSCR_AA; /* AA */ MCF_FBCS2_CSMR = (MCF_FBCS_CSMR_BAM_128M /* F000'0000-F7FF'FFFF */ | MCF_FBCS_CSMR_V); diff --git a/BaS_gcc/util/bas_printf.c b/BaS_gcc/util/bas_printf.c index bfe67ac..04f08b9 100644 --- a/BaS_gcc/util/bas_printf.c +++ b/BaS_gcc/util/bas_printf.c @@ -61,148 +61,148 @@ static char snil[] = "(nil)"; void xputchar(int c) { - __asm__ __volatile__ - ( - ".extern printf_helper\n\t" - "move.b %0,d0\n\t" - "bsr printf_helper\n\t" - /* output */: - /* input */: "r" (c) - /* clobber */: "d0","d2","a0","memory" - ); + __asm__ __volatile__ + ( + ".extern printf_helper\n\t" + "move.b %0,d0\n\t" + "bsr printf_helper\n\t" + /* output */: + /* input */: "r" (c) + /* clobber */: "d0","d2","a0","memory" + ); } static void doprnt(void (*addchar)(int), const char *sfmt, va_list ap) { - char buf[128]; - char *bp; - const char *f; - float flt; - long l; - unsigned long u; - int i; - int fmt; - unsigned char pad = ' '; - int flush_left = 0; - int f_width = 0; - int prec = INF; - int hash = 0; - int do_long = 0; - int sign = 0; - int attributes = 0; + char buf[128]; + char *bp; + const char *f; + float flt; + long l; + unsigned long u; + int i; + int fmt; + unsigned char pad = ' '; + int flush_left = 0; + int f_width = 0; + int prec = INF; + int hash = 0; + int do_long = 0; + int sign = 0; + int attributes = 0; - f = sfmt; - for (; *f; f++) - { - if (*f != '%') - { - /* then just out the char */ - (*addchar)((int) (((unsigned char) *f) | attributes)); - } - else - { - f++; /* skip the % */ + f = sfmt; + for (; *f; f++) + { + if (*f != '%') + { + /* then just out the char */ + (*addchar)((int) (((unsigned char) *f) | attributes)); + } + else + { + f++; /* skip the % */ - if (*f == '-') - { /* minus: flush left */ - flush_left = 1; - f++; - } + if (*f == '-') + { /* minus: flush left */ + flush_left = 1; + f++; + } - if (*f == '0' || *f == '.') - { - /* padding with 0 rather than blank */ - pad = '0'; - f++; - } - if (*f == '*') - { - /* field width */ - f_width = va_arg(ap, int); - f++; - } - else if (isdigit((unsigned char)*f)) - { - f_width = atoi(f); - while (isdigit((unsigned char)*f)) - f++; /* skip the digits */ - } + if (*f == '0' || *f == '.') + { + /* padding with 0 rather than blank */ + pad = '0'; + f++; + } + if (*f == '*') + { + /* field width */ + f_width = va_arg(ap, int); + f++; + } + else if (isdigit((unsigned char)*f)) + { + f_width = atoi(f); + while (isdigit((unsigned char)*f)) + f++; /* skip the digits */ + } - if (*f == '.') - { /* precision */ - f++; - if (*f == '*') - { - prec = va_arg(ap, int); - f++; - } - else if (isdigit((unsigned char)*f)) - { - prec = atoi(f); - while (isdigit((unsigned char)*f)) - f++; /* skip the digits */ - } - } + if (*f == '.') + { /* precision */ + f++; + if (*f == '*') + { + prec = va_arg(ap, int); + f++; + } + else if (isdigit((unsigned char)*f)) + { + prec = atoi(f); + while (isdigit((unsigned char)*f)) + f++; /* skip the digits */ + } + } - if (*f == '#') - { /* alternate form */ - hash = 1; - f++; - } + if (*f == '#') + { /* alternate form */ + hash = 1; + f++; + } - if (*f == 'l') - { /* long format */ - do_long++; - f++; - if (*f == 'l') - { - do_long++; - f++; - } - } + if (*f == 'l') + { /* long format */ + do_long++; + f++; + if (*f == 'l') + { + do_long++; + f++; + } + } - fmt = (unsigned char) *f; - if (fmt != 'S' && fmt != 'Q' && isupper(fmt)) - { - do_long = 1; - fmt = tolower(fmt); - } - bp = buf; - switch (fmt) - { /* do the format */ - case 'd': - switch (do_long) - { - case 0: - l = (long) (va_arg(ap, int)); - break; - case 1: - default: - l = va_arg(ap, long); - break; - } + fmt = (unsigned char) *f; + if (fmt != 'S' && fmt != 'Q' && isupper(fmt)) + { + do_long = 1; + fmt = tolower(fmt); + } + bp = buf; + switch (fmt) + { /* do the format */ + case 'd': + switch (do_long) + { + case 0: + l = (long) (va_arg(ap, int)); + break; + case 1: + default: + l = va_arg(ap, long); + break; + } - if (l < 0) - { - sign = 1; - l = -l; - } - do - { - *bp++ = (char) (l % 10) + '0'; - } while ((l /= 10) > 0); - if (sign) - *bp++ = '-'; - f_width = f_width - (int) (bp - buf); - if (!flush_left) - while (f_width-- > 0) - (*addchar)((int) (pad | attributes)); - for (bp--; bp >= buf; bp--) - (*addchar)((int) (((unsigned char) *bp) | attributes)); - if (flush_left) - while (f_width-- > 0) - (*addchar)((int) (' ' | attributes)); - break; + if (l < 0) + { + sign = 1; + l = -l; + } + do + { + *bp++ = (char) (l % 10) + '0'; + } while ((l /= 10) > 0); + if (sign) + *bp++ = '-'; + f_width = f_width - (int) (bp - buf); + if (!flush_left) + while (f_width-- > 0) + (*addchar)((int) (pad | attributes)); + for (bp--; bp >= buf; bp--) + (*addchar)((int) (((unsigned char) *bp) | attributes)); + if (flush_left) + while (f_width-- > 0) + (*addchar)((int) (' ' | attributes)); + break; case 'f': /* this is actually more than stupid, but does work for now */ @@ -242,179 +242,179 @@ static void doprnt(void (*addchar)(int), const char *sfmt, va_list ap) } break; - case 'p': - do_long = 1; - hash = 1; - fmt = 'x'; - /* no break */ - case 'o': - case 'x': - case 'u': - switch (do_long) - { - case 0: - u = (unsigned long) (va_arg(ap, unsigned int)); - break; - case 1: - default: - u = va_arg(ap, unsigned long); - break; - } - if (fmt == 'u') - { /* unsigned decimal */ - do - { - *bp++ = (char) (u % 10) + '0'; - } while ((u /= 10) > 0); - } - else if (fmt == 'o') - { /* octal */ - do - { - *bp++ = (char) (u % 8) + '0'; - } while ((u /= 8) > 0); - if (hash) - *bp++ = '0'; - } - else if (fmt == 'x') - { /* hex */ - do - { - i = (int) (u % 16); - if (i < 10) - *bp++ = i + '0'; - else - *bp++ = i - 10 + 'a'; - } while ((u /= 16) > 0); - if (hash) - { - *bp++ = 'x'; - *bp++ = '0'; - } - } - i = f_width - (int) (bp - buf); - if (!flush_left) - while (i-- > 0) - (*addchar)((int) (pad | attributes)); - for (bp--; bp >= buf; bp--) - (*addchar)((int) (((unsigned char) *bp) | attributes)); - if (flush_left) - while (i-- > 0) - (*addchar)((int) (' ' | attributes)); - break; + case 'p': + do_long = 1; + hash = 1; + fmt = 'x'; + /* no break */ + case 'o': + case 'x': + case 'u': + switch (do_long) + { + case 0: + u = (unsigned long) (va_arg(ap, unsigned int)); + break; + case 1: + default: + u = va_arg(ap, unsigned long); + break; + } + if (fmt == 'u') + { /* unsigned decimal */ + do + { + *bp++ = (char) (u % 10) + '0'; + } while ((u /= 10) > 0); + } + else if (fmt == 'o') + { /* octal */ + do + { + *bp++ = (char) (u % 8) + '0'; + } while ((u /= 8) > 0); + if (hash) + *bp++ = '0'; + } + else if (fmt == 'x') + { /* hex */ + do + { + i = (int) (u % 16); + if (i < 10) + *bp++ = i + '0'; + else + *bp++ = i - 10 + 'a'; + } while ((u /= 16) > 0); + if (hash) + { + *bp++ = 'x'; + *bp++ = '0'; + } + } + i = f_width - (int) (bp - buf); + if (!flush_left) + while (i-- > 0) + (*addchar)((int) (pad | attributes)); + for (bp--; bp >= buf; bp--) + (*addchar)((int) (((unsigned char) *bp) | attributes)); + if (flush_left) + while (i-- > 0) + (*addchar)((int) (' ' | attributes)); + break; - case 'c': - i = va_arg(ap, int); - (*addchar)((int) (i | attributes)); - break; + case 'c': + i = va_arg(ap, int); + (*addchar)((int) (i | attributes)); + break; - case 'S': - case 'Q': - case 's': - case 'q': - bp = va_arg(ap, char *); - if (!bp) - bp = snil; - f_width = f_width - strlen((char *) bp); - if (!flush_left) - while (f_width-- > 0) - (*addchar)((int) (pad | attributes)); - for (i = 0; *bp && i < prec; i++) - { - if (fmt == 'q' && (*bp & QUOTE)) - (*addchar)((int) ('\\' | attributes)); - (*addchar)( - (int) (((unsigned char) *bp & TRIM) | attributes)); - bp++; - } - if (flush_left) - while (f_width-- > 0) - (*addchar)((int) (' ' | attributes)); - break; + case 'S': + case 'Q': + case 's': + case 'q': + bp = va_arg(ap, char *); + if (!bp) + bp = snil; + f_width = f_width - strlen((char *) bp); + if (!flush_left) + while (f_width-- > 0) + (*addchar)((int) (pad | attributes)); + for (i = 0; *bp && i < prec; i++) + { + if (fmt == 'q' && (*bp & QUOTE)) + (*addchar)((int) ('\\' | attributes)); + (*addchar)( + (int) (((unsigned char) *bp & TRIM) | attributes)); + bp++; + } + if (flush_left) + while (f_width-- > 0) + (*addchar)((int) (' ' | attributes)); + break; - case 'a': - attributes = va_arg(ap, int); - break; + case 'a': + attributes = va_arg(ap, int); + break; - case '%': - (*addchar)((int) ('%' | attributes)); - break; + case '%': + (*addchar)((int) ('%' | attributes)); + break; - default: - break; - } - flush_left = 0, f_width = 0, prec = INF, hash = 0, do_long = 0; - sign = 0; - pad = ' '; - } - } + default: + break; + } + flush_left = 0, f_width = 0, prec = INF, hash = 0, do_long = 0; + sign = 0; + pad = ' '; + } + } } static char *xstring, *xestring; void xaddchar(int c) { - if (xestring == xstring) - *xstring = '\0'; - else - *xstring++ = (char) c; + if (xestring == xstring) + *xstring = '\0'; + else + *xstring++ = (char) c; } int sprintf(char *str, const char *format, ...) { - va_list va; - va_start(va, format); + va_list va; + va_start(va, format); - xstring = str; + xstring = str; - doprnt(xaddchar, format, va); - va_end(va); - *xstring++ = '\0'; + doprnt(xaddchar, format, va); + va_end(va); + *xstring++ = '\0'; - return 0; + return 0; } void xsnprintf(char *str, size_t size, const char *fmt, ...) { - va_list va; - va_start(va, fmt); + va_list va; + va_start(va, fmt); - xstring = str; - xestring = str + size - 1; - doprnt(xaddchar, fmt, va); - va_end(va); - *xstring++ = '\0'; + xstring = str; + xestring = str + size - 1; + doprnt(xaddchar, fmt, va); + va_end(va); + *xstring++ = '\0'; } void xprintf(const char *fmt, ...) { - va_list va; - va_start(va, fmt); - doprnt(xputchar, fmt, va); - va_end(va); + va_list va; + va_start(va, fmt); + doprnt(xputchar, fmt, va); + va_end(va); } void xvprintf(const char *fmt, va_list va) { - doprnt(xputchar, fmt, va); + doprnt(xputchar, fmt, va); } void xvsnprintf(char *str, size_t size, const char *fmt, va_list va) { - xstring = str; - xestring = str + size - 1; - doprnt(xaddchar, fmt, va); - *xstring++ = '\0'; + xstring = str; + xestring = str + size - 1; + doprnt(xaddchar, fmt, va); + *xstring++ = '\0'; } void display_progress() { - static int _progress_index; - char progress_char[] = "|/-\\"; + static int _progress_index; + char progress_char[] = "|/-\\"; - xputchar(progress_char[_progress_index++ % strlen(progress_char)]); - xputchar('\r'); + xputchar(progress_char[_progress_index++ % strlen(progress_char)]); + xputchar('\r'); } void hexdump(uint8_t buffer[], int size) @@ -426,7 +426,7 @@ void hexdump(uint8_t buffer[], int size) while (bp < buffer + size) { uint8_t *lbp = bp; - xprintf("%08x ", line); + xprintf("%08x ", bp); for (i = 0; i < 16; i++) { if (bp + i > buffer + size) { diff --git a/BaS_gcc/video/video.c b/BaS_gcc/video/video.c index 20b6ae4..c4a9a56 100644 --- a/BaS_gcc/video/video.c +++ b/BaS_gcc/video/video.c @@ -7,12 +7,13 @@ #include "fb.h" #include "radeonfb.h" -//#define DBG_VIDEO +#define DBG_VIDEO #ifdef DBG_VIDEO -#define dbg(format, arg...) do { xprintf("DEBUG: " format, ##arg); } while (0) +#define dbg(format, arg...) do { xprintf("DEBUG (%s()): " format, __FUNCTION__, ##arg);} while(0) #else -#define dbg(format, arg...) do { ; } while (0) +#define dbg(format, arg...) do {;} while (0) #endif /* DBG_VIDEO */ +#define err(format, arg...) do { xprintf("ERROR (%s()): " format, __FUNCTION__, ##arg); } while(0) #ifdef _USE_VIDEL_ #define MON_ALL -1 /* code used in VMODE_ENTRY for match on mode only */ @@ -206,9 +207,9 @@ int16_t current_video_mode; static void setphys(int32_t addr,int checkaddr) { - *(volatile uint8_t *) VIDEOBASE_ADDR_HI = ((uint32_t) addr) >> 16; - *(volatile uint8_t *) VIDEOBASE_ADDR_MID = ((uint32_t) addr) >> 8; - *(volatile uint8_t *) VIDEOBASE_ADDR_LOW = ((uint32_t) addr); + *(volatile uint8_t *) VIDEOBASE_ADDR_HI = ((uint32_t) addr) >> 16; + *(volatile uint8_t *) VIDEOBASE_ADDR_MID = ((uint32_t) addr) >> 8; + *(volatile uint8_t *) VIDEOBASE_ADDR_LOW = ((uint32_t) addr); } /* @@ -219,57 +220,57 @@ static void setphys(int32_t addr,int checkaddr) void videl_screen_init(void) { - uint32_t screen_start; - uint16_t boot_resolution = FALCON_DEFAULT_BOOT; - int16_t monitor_type, sync_mode; - int16_t rez = 0; /* avoid 'may be uninitialized' warning */ + uint32_t screen_start; + uint16_t boot_resolution = FALCON_DEFAULT_BOOT; + int16_t monitor_type, sync_mode; + int16_t rez = 0; /* avoid 'may be uninitialized' warning */ - /* Initialize the interrupt handlers. - * It is important to do this first because the initialization code below - * may call vsync(), which temporarily enables the interrupts. */ + /* Initialize the interrupt handlers. + * It is important to do this first because the initialization code below + * may call vsync(), which temporarily enables the interrupts. */ - /* TODO: VEC_HBL = int_hbl; */ - /* TODO: VEC_VBL = int_vbl; */ + /* TODO: VEC_HBL = int_hbl; */ + /* TODO: VEC_VBL = int_vbl; */ /* * first, see what we're connected to, and set the * resolution / video mode appropriately */ - monitor_type = MON_COLOR; - xprintf("monitor_type = %d\r\n", monitor_type); + monitor_type = MON_COLOR; + xprintf("monitor_type = %d\r\n", monitor_type); - /* reset VIDEL on boot-up */ - /* first set the physbase to a safe memory */ - setphys(0xd00000, 0); + /* reset VIDEL on boot-up */ + /* first set the physbase to a safe memory */ + setphys(0xd00000, 0); - if (!lookup_videl_mode(boot_resolution, monitor_type)) { /* mode isn't in table */ - xprintf("Invalid video mode 0x%04x changed to 0x%04x\r\n", - boot_resolution, FALCON_DEFAULT_BOOT); - boot_resolution = FALCON_DEFAULT_BOOT; /* so pick one that is */ - } + if (!lookup_videl_mode(boot_resolution, monitor_type)) { /* mode isn't in table */ + xprintf("Invalid video mode 0x%04x changed to 0x%04x\r\n", + boot_resolution, FALCON_DEFAULT_BOOT); + boot_resolution = FALCON_DEFAULT_BOOT; /* so pick one that is */ + } - if (!VALID_VDI_BPP(boot_resolution)) { /* mustn't confuse VDI */ - xprintf("VDI doesn't support video mode 0x%04x, changed to 0x%04x\r\n", - boot_resolution, FALCON_DEFAULT_BOOT); - boot_resolution = FALCON_DEFAULT_BOOT; /* so use default */ - } + if (!VALID_VDI_BPP(boot_resolution)) { /* mustn't confuse VDI */ + xprintf("VDI doesn't support video mode 0x%04x, changed to 0x%04x\r\n", + boot_resolution, FALCON_DEFAULT_BOOT); + boot_resolution = FALCON_DEFAULT_BOOT; /* so use default */ + } - vsetmode(boot_resolution); - rez = FALCON_REZ; /* fake value indicates Falcon/Videl */ - sync_mode = (boot_resolution & VIDEL_PAL) ? 0x02 : 0x00; - *(volatile uint8_t *) SYNCMODE = sync_mode; + vsetmode(boot_resolution); + rez = FALCON_REZ; /* fake value indicates Falcon/Videl */ + sync_mode = (boot_resolution & VIDEL_PAL) ? 0x02 : 0x00; + *(volatile uint8_t *) SYNCMODE = sync_mode; - /* - * next, set up the palette(s) - */ - initialise_palette_registers(rez, boot_resolution); - /* FIXME: sshiftmod = rez; */ + /* + * next, set up the palette(s) + */ + initialise_palette_registers(rez, boot_resolution); + /* FIXME: sshiftmod = rez; */ - /* videoram is placed just below the phystop */ - screen_start = 0xd00000; + /* videoram is placed just below the phystop */ + screen_start = 0xd00000; - /* correct physical address */ - setphys(screen_start, 1); + /* correct physical address */ + setphys(screen_start, 1); } #endif /* _USE_VIDEL_ */ @@ -280,20 +281,20 @@ struct fb_info *info_fb = &fb; const char monitor_layout[1024] = "CRT,CRT"; int16_t ignore_edid; -struct mode_option resolution = +struct mode_option resolution = { - .used = 0, - .width = 640, - .height = 480, - .bpp = 8, - .freq = 60, - .flags = 0 + .used = 0, + .width = 640, + .height = 480, + .bpp = 8, + .freq = 60, + .flags = 0 }; int16_t force_measure_pll; void install_vbl_timer(void *func, int remove) { - dbg("%s: not implemented\r\n", __FUNCTION__); + dbg("not implemented\r\n"); } /* @@ -301,58 +302,63 @@ void install_vbl_timer(void *func, int remove) */ void video_init(void) { - /* - * detect PCI video card - */ - - int index = 0; - int32_t handle; - struct pci_device_id *board; - int32_t id; - bool radeon_found = false; - - dbg("%s\r\n", __FUNCTION__); - do - { - /* - * scan PCI bus for graphics cards - */ - handle = pci_find_classcode(PCI_BASE_CLASS_DISPLAY | PCI_FIND_BASE_CLASS, index); - if (handle > 0) /* found a display device */ - { - dbg("%s: handle = 0x%x\r\n", __FUNCTION__, handle); + /* + * detect PCI video card + */ - id = swpl(pci_read_config_longword(handle, PCIIDR)); /* get vendor + device id */ - dbg("%s: PCIIDR=0x%x\r\n", __FUNCTION__, id); + int index = 0; + int32_t handle; + struct pci_device_id *board; + int32_t id; + bool radeon_found = false; - board = &radeonfb_pci_table[0]; + dbg("\r\n"); - do - { - /* check it against elements of table */ - dbg("%s: check %x %x against %08x\r\n", __FUNCTION__, board->device, board->vendor, id); - if ((board->device == (id >> 16)) && (board->vendor == (id & 0xffff))) - { - radeon_found = true; + /* FIXME: we currently just return here because the PCI configuration of ATI cards does not (yet) work */ + return; - dbg("%s: matched\r\n", __FUNCTION__); - if (radeonfb_pci_register(handle, board) >= 0) - { - xprintf("RADEON video card found and registered\r\n"); - } - else - { - dbg("%s: failed to register RADEON PCI video card\r\n", __FUNCTION__); - } - return; - } - board++; - } while (board->vendor); - } - index++; - } while (handle > 0); - xprintf("%s: RADEON video card %sfound and %sregistered\r\n", __FUNCTION__, - (radeon_found ? "" : "not "), (radeon_found ? "" : "not ")); + do + { + /* + * scan PCI bus for graphics cards + */ + handle = pci_find_classcode(PCI_BASE_CLASS_DISPLAY | PCI_FIND_BASE_CLASS, index); + dbg("handle=%d\r\n", handle); + if (handle > 0) /* found a display device */ + { + dbg("handle = 0x%x\r\n", handle); + + id = swpl(pci_read_config_longword(handle, PCIIDR)); /* get vendor + device id */ + dbg("PCIIDR=0x%x\r\n", id); + + board = &radeonfb_pci_table[0]; + + do + { + /* check it against elements of table */ + dbg("check %x %x against %08x\r\n", board->device, board->vendor, id); + if ((board->device == (id >> 16)) && (board->vendor == (id & 0xffff))) + { + radeon_found = true; + + dbg("matched\r\n"); + if (radeonfb_pci_register(handle, board) >= 0) + { + xprintf("RADEON video card found and registered\r\n"); + } + else + { + dbg("failed to register RADEON PCI video card\r\n"); + } + return; + } + board++; + } while (board->vendor); + } + index++; + } while (handle > 0); + xprintf("%s: RADEON video card %sfound and %sregistered\r\n", __FUNCTION__, + (radeon_found ? "" : "not "), (radeon_found ? "" : "not ")); }