[haiku-commits] r42553 - in haiku/trunk: headers/private/graphics/radeon_hd src/add-ons/accelerants/radeon_hd

  • From: kallisti5@xxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Wed, 3 Aug 2011 05:02:59 +0200 (CEST)

Author: kallisti5
Date: 2011-08-03 05:02:57 +0200 (Wed, 03 Aug 2011)
New Revision: 42553
Changeset: https://dev.haiku-os.org/changeset/42553

Modified:
   haiku/trunk/headers/private/graphics/radeon_hd/r600_reg.h
   haiku/trunk/src/add-ons/accelerants/radeon_hd/accelerant.cpp
   haiku/trunk/src/add-ons/accelerants/radeon_hd/accelerant.h
   haiku/trunk/src/add-ons/accelerants/radeon_hd/bios.cpp
   haiku/trunk/src/add-ons/accelerants/radeon_hd/bios.h
Log:
* move bios functions into bios.cpp
* implement various methods to pull AtomBIOS from card
* add some missing registers to headers from linux drm driver


Modified: haiku/trunk/headers/private/graphics/radeon_hd/r600_reg.h
===================================================================
--- haiku/trunk/headers/private/graphics/radeon_hd/r600_reg.h   2011-08-03 
01:36:50 UTC (rev 42552)
+++ haiku/trunk/headers/private/graphics/radeon_hd/r600_reg.h   2011-08-03 
03:02:57 UTC (rev 42553)
@@ -34,14 +34,39 @@
 #include "r600_reg_r7xx.h"
 
 
+/* From Linux DRM Radeon driver for AtomBIOS */
+#define RADEON_SEPROM_CNTL1                    0x01c0
+#define RADEON_SCK_PRESCALE_SHIFT      24
+#define RADEON_SCK_PRESCALE_MASK       (0xff << 24)
+
+#define RADEON_VIPH_CONTROL                    0x0c40
+#define RADEON_VIPH_EN                         (1 << 21)
+
+#define RADEON_GPIOPAD_MASK                    0x0198
+#define RADEON_GPIOPAD_A            0x019c
+#define RADEON_GPIOPAD_EN                      0x01a0
+#define RADEON_GPIOPAD_Y                       0x01a4
+#define RADEON_MDGPIO_MASK                     0x01a8
+#define RADEON_MDGPIO_A                                0x01ac
+#define RADEON_MDGPIO_EN                       0x01b0
+#define RADEON_MDGPIO_Y                                0x01b4
+
+#define RV370_BUS_CNTL                         0x004c
+
+#define R600_CG_SPLL_FUNC_CNTL         0x600
+#define R600_CG_SPLL_STATUS                    0x60c
 #define R600_ROM_CNTL                          0x1600
 #define R600_BUS_CNTL                          0x5420
+
 #define R600_BIOS_ROM_DIS                      (1 << 1)
 #define R600_SCK_OVERWRITE                     (1 << 1)
+#define R600_SPLL_CHG_STATUS           (1 << 1)
+#define R600_SPLL_BYPASS_EN                    (1 << 3)
 #define DVGA_CONTROL_MODE_ENABLE       (1 << 0)
 #define DVGA_CONTROL_TIMING_SELECT     (1 << 8)
 #define VGA_VSTATUS_CNTL_MASK          (3 << 16)
 
+
 /* SET_*_REG offsets + ends */
 enum {
     SET_CONFIG_REG_offset          = 0x00008000,

Modified: haiku/trunk/src/add-ons/accelerants/radeon_hd/accelerant.cpp
===================================================================
--- haiku/trunk/src/add-ons/accelerants/radeon_hd/accelerant.cpp        
2011-08-03 01:36:50 UTC (rev 42552)
+++ haiku/trunk/src/add-ons/accelerants/radeon_hd/accelerant.cpp        
2011-08-03 03:02:57 UTC (rev 42553)
@@ -41,6 +41,7 @@
 
 struct accelerant_info *gInfo;
 display_info *gDisplay[MAX_DISPLAY];
+void *gAtomBIOS;
 
 
 class AreaCloner {
@@ -162,15 +163,21 @@
                gInfo->shared_info->rom_area);
        status = romCloner.InitCheck();
        if (status < B_OK) {
-               //free(gInfo);
+               free(gInfo);
                TRACE("%s, failed to create rom area\n", __func__);
-               //return status;
+               return status;
        }
 
        sharedCloner.Keep();
        regsCloner.Keep();
        romCloner.Keep();
 
+       gAtomBIOS = (void*)malloc(gInfo->shared_info->rom_size);
+
+       if (gAtomBIOS == NULL) {
+               TRACE("%s, failed to malloc AtomBIOS pointer of holding\n", 
__func__);
+       }
+
        // Define Radeon PLL default ranges
        gInfo->shared_info->pll_info.reference_frequency
                = RHD_PLL_REFERENCE_DEFAULT;
@@ -199,6 +206,8 @@
                free(gInfo);
        }
 
+       free(gAtomBIOS);
+
        for (uint32 id = 0; id < MAX_DISPLAY; id++) {
                if (gDisplay[id] != NULL) {
                        free(gDisplay[id]->regs);
@@ -208,52 +217,6 @@
 }
 
 
-status_t
-radeon_init_bios()
-{
-       radeon_shared_info &info = *gInfo->shared_info;
-
-       uint32 bus_cntl = Read32(OUT, R600_BUS_CNTL);
-       uint32 d1vga_control = Read32(OUT, D1VGA_CONTROL);
-       uint32 d2vga_control = Read32(OUT, D2VGA_CONTROL);
-       uint32 vga_render_control = Read32(OUT, VGA_RENDER_CONTROL);
-       uint32 rom_cntl = Read32(OUT, R600_ROM_CNTL);
-
-       // Enable rom access
-       Write32(OUT, R600_BUS_CNTL, (bus_cntl & ~R600_BIOS_ROM_DIS));
-       /* Disable VGA mode */
-       Write32(OUT, D1VGA_CONTROL, (d1vga_control
-               & ~(DVGA_CONTROL_MODE_ENABLE
-                       | DVGA_CONTROL_TIMING_SELECT)));
-       Write32(OUT, D2VGA_CONTROL, (d2vga_control
-               & ~(DVGA_CONTROL_MODE_ENABLE
-                       | DVGA_CONTROL_TIMING_SELECT)));
-       Write32(OUT, VGA_RENDER_CONTROL, (vga_render_control
-               & ~VGA_VSTATUS_CNTL_MASK));
-       Write32(OUT, R600_ROM_CNTL, rom_cntl | R600_SCK_OVERWRITE);
-
-       void* atomBIOS = (void*)malloc(info.rom_size);
-       if (atomBIOS == NULL)
-               return B_NO_MEMORY;
-
-       snooze(2);
-
-       memcpy(atomBIOS, gInfo->rom, info.rom_size);
-
-       /* restore regs */
-       Write32(OUT, R600_BUS_CNTL, bus_cntl);
-       Write32(OUT, D1VGA_CONTROL, d1vga_control);
-       Write32(OUT, D2VGA_CONTROL, d2vga_control);
-       Write32(OUT, VGA_RENDER_CONTROL, vga_render_control);
-       Write32(OUT, R600_ROM_CNTL, rom_cntl);
-
-       // Init AtomBIOS
-       bios_init(atomBIOS);
-
-       return B_OK;
-}
-
-
 //     #pragma mark - public accelerant functions
 
 
@@ -272,7 +235,7 @@
        init_lock(&info.accelerant_lock, "radeon hd accelerant");
        init_lock(&info.engine_lock, "radeon hd engine");
 
-       radeon_init_bios();
+       radeon_init_bios(gAtomBIOS);
 
        status = detect_displays();
        //if (status != B_OK)

Modified: haiku/trunk/src/add-ons/accelerants/radeon_hd/accelerant.h
===================================================================
--- haiku/trunk/src/add-ons/accelerants/radeon_hd/accelerant.h  2011-08-03 
01:36:50 UTC (rev 42552)
+++ haiku/trunk/src/add-ons/accelerants/radeon_hd/accelerant.h  2011-08-03 
03:02:57 UTC (rev 42553)
@@ -116,7 +116,8 @@
 
 
 extern accelerant_info *gInfo;
-extern atom_context *gAtomBIOS;
+extern void *gAtomBIOS;
+extern atom_context *gAtomContext;
 extern display_info *gDisplay[MAX_DISPLAY];
 
 

Modified: haiku/trunk/src/add-ons/accelerants/radeon_hd/bios.cpp
===================================================================
--- haiku/trunk/src/add-ons/accelerants/radeon_hd/bios.cpp      2011-08-03 
01:36:50 UTC (rev 42552)
+++ haiku/trunk/src/add-ons/accelerants/radeon_hd/bios.cpp      2011-08-03 
03:02:57 UTC (rev 42553)
@@ -25,19 +25,219 @@
 #endif
 
 
-atom_context *gAtomBIOS;
+atom_context *gAtomContext;
 
 
 status_t
-bios_init(void* bios)
+bios_read_enabled(void* bios, size_t size)
 {
-       if (gInfo->rom == NULL) {
-               // just incase, this prevents a crash
-               TRACE("%s: called even though VGA rom hasn't been mapped!\n",
-                       __func__);
-               return B_ERROR;
+       status_t result = B_ERROR;
+       if (gInfo->rom[0] == 0x55 && gInfo->rom[1] == 0xaa) {
+               TRACE("%s: found AtomBIOS signature!\n", __func__);
+               bios = gInfo->rom;
+               result = B_OK;
+       } else
+               TRACE("%s: didn't find valid AtomBIOS\n", __func__);
+
+       return result;
+}
+
+
+status_t
+bios_read_disabled_northern(void* bios, size_t size)
+{
+       uint32 bus_cntl = Read32(OUT, R600_BUS_CNTL);
+       uint32 d1vga_control = Read32(OUT, D1VGA_CONTROL);
+       uint32 d2vga_control = Read32(OUT, D2VGA_CONTROL);
+       uint32 vga_render_control = Read32(OUT, VGA_RENDER_CONTROL);
+       uint32 rom_cntl = Read32(OUT, R600_ROM_CNTL);
+
+       // Enable rom access
+       Write32(OUT, R600_BUS_CNTL, (bus_cntl & ~R600_BIOS_ROM_DIS));
+       // Disable VGA mode
+       Write32(OUT, D1VGA_CONTROL, (d1vga_control
+               & ~(DVGA_CONTROL_MODE_ENABLE
+                       | DVGA_CONTROL_TIMING_SELECT)));
+       Write32(OUT, D2VGA_CONTROL, (d2vga_control
+               & ~(DVGA_CONTROL_MODE_ENABLE
+                       | DVGA_CONTROL_TIMING_SELECT)));
+       Write32(OUT, VGA_RENDER_CONTROL, (vga_render_control
+               & ~VGA_VSTATUS_CNTL_MASK));
+       Write32(OUT, R600_ROM_CNTL, rom_cntl | R600_SCK_OVERWRITE);
+
+       snooze(2);
+
+       status_t result = B_ERROR;
+       if (gInfo->rom[0] == 0x55 && gInfo->rom[1] == 0xaa) {
+               TRACE("%s: found AtomBIOS signature!\n", __func__);
+               memcpy(&bios, gInfo->rom, size);
+                       // grab it while we can
+               result = B_OK;
+       } else
+               TRACE("%s: didn't find valid AtomBIOS\n", __func__);
+
+       // restore regs
+       Write32(OUT, R600_BUS_CNTL, bus_cntl);
+       Write32(OUT, D1VGA_CONTROL, d1vga_control);
+       Write32(OUT, D2VGA_CONTROL, d2vga_control);
+       Write32(OUT, VGA_RENDER_CONTROL, vga_render_control);
+       Write32(OUT, R600_ROM_CNTL, rom_cntl);
+
+       return result;
+}
+
+
+status_t
+bios_read_disabled_avivo(void* bios, size_t size)
+{
+       uint32 seprom_cntl1 = Read32(OUT, RADEON_SEPROM_CNTL1);
+       uint32 viph_control = Read32(OUT, RADEON_VIPH_CONTROL);
+       uint32 bus_cntl = Read32(OUT, RV370_BUS_CNTL);
+       uint32 d1vga_control = Read32(OUT, D1VGA_CONTROL);
+       uint32 d2vga_control = Read32(OUT, D2VGA_CONTROL);
+       uint32 vga_render_control = Read32(OUT, VGA_RENDER_CONTROL);
+       uint32 gpiopad_a = Read32(OUT, RADEON_GPIOPAD_A);
+       uint32 gpiopad_en = Read32(OUT, RADEON_GPIOPAD_EN);
+       uint32 gpiopad_mask = Read32(OUT, RADEON_GPIOPAD_MASK);
+
+       Write32(OUT, RADEON_SEPROM_CNTL1, ((seprom_cntl1 &
+               ~RADEON_SCK_PRESCALE_MASK) | (0xc << 
RADEON_SCK_PRESCALE_SHIFT)));
+       Write32(OUT, RADEON_GPIOPAD_A, 0);
+       Write32(OUT, RADEON_GPIOPAD_EN, 0);
+       Write32(OUT, RADEON_GPIOPAD_MASK, 0);
+
+       // Disable VIP
+       Write32(OUT, RADEON_VIPH_CONTROL, (viph_control & ~RADEON_VIPH_EN));
+       // Disable VGA mode
+       Write32(OUT, D1VGA_CONTROL, (d1vga_control
+               & ~(DVGA_CONTROL_MODE_ENABLE
+                       | DVGA_CONTROL_TIMING_SELECT)));
+       Write32(OUT, D2VGA_CONTROL, (d2vga_control
+               & ~(DVGA_CONTROL_MODE_ENABLE
+                       | DVGA_CONTROL_TIMING_SELECT)));
+       Write32(OUT, VGA_RENDER_CONTROL, (vga_render_control
+               & ~VGA_VSTATUS_CNTL_MASK));
+
+       snooze(2);
+
+       status_t result = B_ERROR;
+       if (gInfo->rom[0] == 0x55 && gInfo->rom[1] == 0xaa) {
+               TRACE("%s: found AtomBIOS signature!\n", __func__);
+               memcpy(&bios, gInfo->rom, size);
+                       // grab it while we can
+               result = B_OK;
+       } else
+               TRACE("%s: didn't find valid AtomBIOS\n", __func__);
+
+       /* restore regs */
+       Write32(OUT, RADEON_SEPROM_CNTL1, seprom_cntl1);
+       Write32(OUT, RADEON_VIPH_CONTROL, viph_control);
+       Write32(OUT, RV370_BUS_CNTL, bus_cntl);
+       Write32(OUT, D1VGA_CONTROL, d1vga_control);
+       Write32(OUT, D2VGA_CONTROL, d2vga_control);
+       Write32(OUT, VGA_RENDER_CONTROL, vga_render_control);
+       Write32(OUT, RADEON_GPIOPAD_A, gpiopad_a);
+       Write32(OUT, RADEON_GPIOPAD_EN, gpiopad_en);
+       Write32(OUT, RADEON_GPIOPAD_MASK, gpiopad_mask);
+
+
+       return result;
+}
+
+
+status_t
+bios_read_disabled_r700(void* bios, size_t size)
+{
+       uint32 viph_control = Read32(OUT, RADEON_VIPH_CONTROL);
+       uint32 bus_cntl = Read32(OUT, R600_BUS_CNTL);
+       uint32 d1vga_control = Read32(OUT, D1VGA_CONTROL);
+       uint32 d2vga_control = Read32(OUT, D2VGA_CONTROL);
+       uint32 vga_render_control = Read32(OUT, VGA_RENDER_CONTROL);
+       uint32 rom_cntl = Read32(OUT, R600_ROM_CNTL);
+
+       // Disable VIP
+       Write32(OUT, RADEON_VIPH_CONTROL, (viph_control & ~RADEON_VIPH_EN));
+       // Enable rom access
+       Write32(OUT, R600_BUS_CNTL, (bus_cntl & ~R600_BIOS_ROM_DIS));
+       // Disable VGA mode
+       Write32(OUT, D1VGA_CONTROL, (d1vga_control
+               & ~(DVGA_CONTROL_MODE_ENABLE
+                       | DVGA_CONTROL_TIMING_SELECT)));
+       Write32(OUT, D2VGA_CONTROL, (d2vga_control
+               & ~(DVGA_CONTROL_MODE_ENABLE
+                       | DVGA_CONTROL_TIMING_SELECT)));
+       Write32(OUT, VGA_RENDER_CONTROL, (vga_render_control
+               & ~VGA_VSTATUS_CNTL_MASK));
+
+       uint32 cg_spll_func_cntl = 0;
+       radeon_shared_info &info = *gInfo->shared_info;
+       if (info.device_chipset == (RADEON_R700 | 0x30)) {
+               cg_spll_func_cntl = Read32(OUT, R600_CG_SPLL_FUNC_CNTL);
+
+               // Enable bypass mode
+               Write32(OUT, R600_CG_SPLL_FUNC_CNTL, cg_spll_func_cntl
+                       | R600_SPLL_BYPASS_EN);
+
+               // wait for SPLL_CHG_STATUS to change to 1
+               uint32 cg_spll_status = 0;
+               while (!(cg_spll_status & R600_SPLL_CHG_STATUS))
+                       cg_spll_status = Read32(OUT, R600_CG_SPLL_STATUS);
+
+               Write32(OUT, R600_ROM_CNTL, (rom_cntl & ~R600_SCK_OVERWRITE));
+       } else
+               Write32(OUT, R600_ROM_CNTL, rom_cntl | R600_SCK_OVERWRITE);
+
+       snooze(2);
+
+       status_t result = B_ERROR;
+       if (gInfo->rom[0] == 0x55 && gInfo->rom[1] == 0xaa) {
+               TRACE("%s: found AtomBIOS signature!\n", __func__);
+               memcpy(&bios, gInfo->rom, size);
+                       // grab it while we can
+               result = B_OK;
+       } else
+               TRACE("%s: didn't find valid AtomBIOS\n", __func__);
+
+       // restore regs
+       if (info.device_chipset == (RADEON_R700 | 0x30)) {
+               Write32(OUT, R600_CG_SPLL_FUNC_CNTL, cg_spll_func_cntl);
+
+               // wait for SPLL_CHG_STATUS to change to 1
+               uint32 cg_spll_status = 0;
+               while (!(cg_spll_status & R600_SPLL_CHG_STATUS))
+                       cg_spll_status = Read32(OUT, R600_CG_SPLL_STATUS);
        }
+       Write32(OUT, RADEON_VIPH_CONTROL, viph_control);
+       Write32(OUT, R600_BUS_CNTL, bus_cntl);
+       Write32(OUT, D1VGA_CONTROL, d1vga_control);
+       Write32(OUT, D2VGA_CONTROL, d2vga_control);
+       Write32(OUT, VGA_RENDER_CONTROL, vga_render_control);
+       Write32(OUT, R600_ROM_CNTL, rom_cntl);
 
+       return result;
+}
+
+
+status_t
+radeon_init_bios(void* bios)
+{
+       radeon_shared_info &info = *gInfo->shared_info;
+
+       status_t bios_status;
+       if (bios_read_enabled(bios, info.rom_size) != B_OK) {
+               if (info.device_chipset > RADEON_R800) // TODO : >= BARTS
+                       bios_status = bios_read_disabled_northern(bios, 
info.rom_size);
+               else if (info.device_chipset >= (RADEON_R700 | 0x70))
+                       bios_status = bios_read_disabled_r700(bios, 
info.rom_size);
+               else if (info.device_chipset >= RADEON_R600)
+                       bios_status = bios_read_disabled_avivo(bios, 
info.rom_size);
+               else
+                       bios_status = B_ERROR;
+       }
+
+       if (bios_status != B_OK)
+               return bios_status;
+
        struct card_info *atom_card_info
                = (card_info*)malloc(sizeof(card_info));
 
@@ -61,10 +261,10 @@
        atom_card_info->pll_read = _read32;
        atom_card_info->pll_write = _write32;
 
-       // Point AtomBIOS parser to card bios and malloc gAtomBIOS
-       gAtomBIOS = atom_parse(atom_card_info, bios);
+       // Point AtomBIOS parser to card bios and malloc gAtomContext
+       gAtomContext = atom_parse(atom_card_info, bios);
 
-       if (gAtomBIOS == NULL) {
+       if (gAtomContext == NULL) {
                TRACE("%s: couldn't parse system AtomBIOS\n", __func__);
                return B_ERROR;
        }

Modified: haiku/trunk/src/add-ons/accelerants/radeon_hd/bios.h
===================================================================
--- haiku/trunk/src/add-ons/accelerants/radeon_hd/bios.h        2011-08-03 
01:36:50 UTC (rev 42552)
+++ haiku/trunk/src/add-ons/accelerants/radeon_hd/bios.h        2011-08-03 
03:02:57 UTC (rev 42553)
@@ -14,7 +14,7 @@
 #include "atom.h"
 
 
-status_t bios_init(void* bios);
+status_t radeon_init_bios(void* bios);
 
 
 #endif /* RADEON_HD_BIOS_H */


Other related posts:

  • » [haiku-commits] r42553 - in haiku/trunk: headers/private/graphics/radeon_hd src/add-ons/accelerants/radeon_hd - kallisti5