* move bios functions into bios.cpp
* implement various methods to pull AtomBIOS from card * add some missing registers to headers from linux drm driver git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@42553 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
1c1415732d
commit
1d5cfc649a
@ -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,
|
||||
|
@ -41,6 +41,7 @@
|
||||
|
||||
struct accelerant_info *gInfo;
|
||||
display_info *gDisplay[MAX_DISPLAY];
|
||||
void *gAtomBIOS;
|
||||
|
||||
|
||||
class AreaCloner {
|
||||
@ -162,15 +163,21 @@ init_common(int device, bool isClone)
|
||||
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 @@ uninit_common(void)
|
||||
free(gInfo);
|
||||
}
|
||||
|
||||
free(gAtomBIOS);
|
||||
|
||||
for (uint32 id = 0; id < MAX_DISPLAY; id++) {
|
||||
if (gDisplay[id] != NULL) {
|
||||
free(gDisplay[id]->regs);
|
||||
@ -208,52 +217,6 @@ uninit_common(void)
|
||||
}
|
||||
|
||||
|
||||
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 @@ radeon_init_accelerant(int device)
|
||||
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)
|
||||
|
@ -116,7 +116,8 @@ typedef struct {
|
||||
|
||||
|
||||
extern accelerant_info *gInfo;
|
||||
extern atom_context *gAtomBIOS;
|
||||
extern void *gAtomBIOS;
|
||||
extern atom_context *gAtomContext;
|
||||
extern display_info *gDisplay[MAX_DISPLAY];
|
||||
|
||||
|
||||
|
@ -25,18 +25,218 @@
|
||||
#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 @@ bios_init(void* bios)
|
||||
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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user