* Pass device name into shared info
* Refactor MCFBsetup to be a little simpler for now * Implement radeon accelerant_device_info for screen preflet * Re-add CRT Power calls to display code. * Disable blanking setting for now... just can't figure out what AMD wants for this. * Remove some un-needed locking in the scaling code * Be sure to disable VGA when set_display_mode is called * Refactor mode setting code to loop over all possible displays and set the provided mode on the attached ones. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@42515 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -244,3 +244,16 @@ radeon_uninit_accelerant(void)
|
|||||||
TRACE("%s done\n", __func__);
|
TRACE("%s done\n", __func__);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
radeon_get_accelerant_device_info(accelerant_device_info *di)
|
||||||
|
{
|
||||||
|
di->version = B_ACCELERANT_VERSION;
|
||||||
|
strcpy(di->name, gInfo->shared_info->device_identifier);
|
||||||
|
strcpy(di->chipset, "radeon_hd");
|
||||||
|
// TODO : Give chipset, ex: r600
|
||||||
|
strcpy(di->serial_no, "None" );
|
||||||
|
|
||||||
|
di->memory = gInfo->shared_info->graphics_memory_size;
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|||||||
@@ -18,11 +18,13 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
void spin(bigtime_t delay);
|
void spin(bigtime_t delay);
|
||||||
|
|
||||||
// general
|
// general
|
||||||
status_t radeon_init_accelerant(int fd);
|
status_t radeon_init_accelerant(int fd);
|
||||||
void radeon_uninit_accelerant(void);
|
void radeon_uninit_accelerant(void);
|
||||||
|
status_t radeon_get_accelerant_device_info(accelerant_device_info *di);
|
||||||
|
|
||||||
// modes & constraints
|
// modes & constraints
|
||||||
uint32 radeon_accelerant_mode_count(void);
|
uint32 radeon_accelerant_mode_count(void);
|
||||||
|
|||||||
@@ -301,3 +301,30 @@ debug_displays()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
display_power(uint8 crtid, int command)
|
||||||
|
{
|
||||||
|
register_info* regs = gDisplay[crtid]->regs;
|
||||||
|
|
||||||
|
switch (command) {
|
||||||
|
case RHD_POWER_ON:
|
||||||
|
Write32Mask(OUT, regs->grphEnable, 0x00000001, 0x00000001);
|
||||||
|
snooze(2);
|
||||||
|
Write32Mask(OUT, regs->crtControl, 0, 0x01000000);
|
||||||
|
// Enable read requests
|
||||||
|
Write32Mask(OUT, regs->crtControl, 1, 1);
|
||||||
|
return;
|
||||||
|
case RHD_POWER_RESET:
|
||||||
|
Write32Mask(OUT, regs->crtControl, 0x01000000, 0x01000000);
|
||||||
|
// Disable read requestes
|
||||||
|
//D1CRTCDisable?
|
||||||
|
return;
|
||||||
|
case RHD_POWER_SHUTDOWN:
|
||||||
|
Write32Mask(OUT, regs->crtControl, 0x01000000, 0x01000000);
|
||||||
|
// Disable read requests
|
||||||
|
//D1CRTCDisable?
|
||||||
|
Write32Mask(OUT, regs->grphEnable, 0x00000001, 0x00000001);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ status_t init_registers(register_info* reg, uint8 crtid);
|
|||||||
status_t detect_crt_ranges(uint32 crtid);
|
status_t detect_crt_ranges(uint32 crtid);
|
||||||
status_t detect_displays();
|
status_t detect_displays();
|
||||||
void debug_displays();
|
void debug_displays();
|
||||||
|
void display_power(uint8 crtid, int command);
|
||||||
|
|
||||||
|
|
||||||
#endif /* RADEON_HD_DISPLAY_H */
|
#endif /* RADEON_HD_DISPLAY_H */
|
||||||
|
|||||||
@@ -26,11 +26,14 @@ get_accelerant_hook(uint32 feature, void *data)
|
|||||||
return (void*)radeon_accelerant_clone_info_size;
|
return (void*)radeon_accelerant_clone_info_size;
|
||||||
case B_GET_ACCELERANT_CLONE_INFO:
|
case B_GET_ACCELERANT_CLONE_INFO:
|
||||||
return (void*)radeon_get_accelerant_clone_info;
|
return (void*)radeon_get_accelerant_clone_info;
|
||||||
|
*/
|
||||||
case B_GET_ACCELERANT_DEVICE_INFO:
|
case B_GET_ACCELERANT_DEVICE_INFO:
|
||||||
return (void*)radeon_get_accelerant_device_info;
|
return (void*)radeon_get_accelerant_device_info;
|
||||||
|
/*
|
||||||
case B_ACCELERANT_RETRACE_SEMAPHORE:
|
case B_ACCELERANT_RETRACE_SEMAPHORE:
|
||||||
return (void*)radeon_accelerant_retrace_semaphore;
|
return (void*)radeon_accelerant_retrace_semaphore;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* mode configuration */
|
/* mode configuration */
|
||||||
case B_ACCELERANT_MODE_COUNT:
|
case B_ACCELERANT_MODE_COUNT:
|
||||||
return (void*)radeon_accelerant_mode_count;
|
return (void*)radeon_accelerant_mode_count;
|
||||||
|
|||||||
@@ -28,17 +28,6 @@ extern "C" void _sPrintf(const char *format, ...);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
uint64
|
|
||||||
MCFBLocation(uint16 chipset, uint32* size)
|
|
||||||
{
|
|
||||||
// TODO : R800 : This is only valid for all R6xx and R7xx?
|
|
||||||
uint32 fbLocationReg = Read32(MC, R7XX_MC_VM_FB_LOCATION);
|
|
||||||
*size = (((fbLocationReg & 0xFFFF0000)
|
|
||||||
- ((fbLocationReg & 0xFFFF) << 16))) << 8;
|
|
||||||
return (fbLocationReg & 0xFFFF) << 24;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint32
|
uint32
|
||||||
MCIdle()
|
MCIdle()
|
||||||
{
|
{
|
||||||
@@ -53,22 +42,15 @@ MCIdle()
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
MCFBSetup(uint32 newFbLocation, uint32 newFbSize)
|
MCFBSetup()
|
||||||
{
|
{
|
||||||
uint32 oldFbSize;
|
uint32 fb_location_int = gInfo->shared_info->frame_buffer_int;
|
||||||
uint64 oldFbLocation = MCFBLocation(0, &oldFbSize);
|
|
||||||
|
|
||||||
if (oldFbLocation == newFbLocation
|
uint32 fb_location = Read32(OUT, R6XX_MC_VM_FB_LOCATION);
|
||||||
&& oldFbSize == newFbSize) {
|
uint16 fb_size = (fb_location >> 16) - (fb_location & 0xFFFF);
|
||||||
TRACE("%s: not adjusting frame buffer as it is already correct\n",
|
uint32 fb_location_tmp = fb_location_int >> 24;
|
||||||
__func__);
|
fb_location_tmp |= (fb_location_tmp + fb_size) << 16;
|
||||||
return B_OK;
|
uint32 fb_offset_tmp = (fb_location_int >> 8) & 0xff0000;
|
||||||
}
|
|
||||||
|
|
||||||
if (oldFbLocation >> 32) {
|
|
||||||
TRACE("%s: board claims to use a frame buffer address > 32-bits\n",
|
|
||||||
__func__);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32 idleState = MCIdle();
|
uint32 idleState = MCIdle();
|
||||||
if (idleState > 0) {
|
if (idleState > 0) {
|
||||||
@@ -77,13 +59,12 @@ MCFBSetup(uint32 newFbLocation, uint32 newFbSize)
|
|||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE("%s: Setting MC/FB from 0x%08X to 0x%08X [size 0x%08X]\n",
|
TRACE("%s: Setting frame buffer from 0x%08X to 0x%08X [size 0x%08X]\n",
|
||||||
__func__, oldFbLocation, newFbLocation, newFbSize);
|
__func__, fb_location, fb_location_tmp, fb_size);
|
||||||
|
|
||||||
// The MC Write32 will handle cards needing a special MC read/write register
|
// The MC Write32 will handle cards needing a special MC read/write register
|
||||||
Write32(MC, R6XX_MC_VM_FB_LOCATION,
|
Write32(MC, R6XX_MC_VM_FB_LOCATION, fb_location_tmp);
|
||||||
R6XX_FB_LOCATION(newFbLocation, newFbSize));
|
Write32(MC, R6XX_HDP_NONSURFACE_BASE, fb_offset_tmp);
|
||||||
Write32(MC, R6XX_HDP_NONSURFACE_BASE, R6XX_HDP_LOCATION(newFbLocation));
|
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,14 +9,8 @@
|
|||||||
#define RADEON_HD_MC_H
|
#define RADEON_HD_MC_H
|
||||||
|
|
||||||
|
|
||||||
#define R6XX_FB_LOCATION(address, size) \
|
uint32 MCIdle();
|
||||||
(((((address) + (size)) >> 8) & 0xFFFF0000) | (((address) >> 24) & 0xFFFF))
|
status_t MCFBSetup();
|
||||||
#define R6XX_HDP_LOCATION(address) \
|
|
||||||
((((address) >> 8) & 0x00FF0000))
|
|
||||||
|
|
||||||
|
|
||||||
uint64 MCFBLocation(uint16 chipset, uint32* size);
|
|
||||||
status_t MCFBSetup(uint32 newFbLocation, uint32 newFbSize);
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
#include "accelerant.h"
|
#include "accelerant.h"
|
||||||
#include "utility.h"
|
#include "utility.h"
|
||||||
#include "mode.h"
|
#include "mode.h"
|
||||||
|
#include "display.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -157,20 +158,16 @@ CardFBSet(uint8 crtid, display_mode *mode)
|
|||||||
// VGA
|
// VGA
|
||||||
|
|
||||||
// framebuffersize = w * h * bpp = fb bits / 8 = bytes needed
|
// framebuffersize = w * h * bpp = fb bits / 8 = bytes needed
|
||||||
//uint64 fbAddress = gInfo->shared_info->frame_buffer_phys;
|
|
||||||
uint64 fbAddressInt = gInfo->shared_info->frame_buffer_int;
|
uint64 fbAddressInt = gInfo->shared_info->frame_buffer_int;
|
||||||
|
|
||||||
// Set the inital frame buffer location in the memory controler
|
MCFBSetup();
|
||||||
uint32 mcFbSize;
|
|
||||||
MCFBLocation(fbAddressInt, &mcFbSize);
|
|
||||||
//MCFBSetup(gInfo->shared_info->frame_buffer_int, mcFbSize);
|
|
||||||
|
|
||||||
Write32(CRT, regs->grphUpdate, (1<<16));
|
Write32(CRT, regs->grphUpdate, (1<<16));
|
||||||
// Lock for update (isn't this normally the other way around on VGA?
|
// Lock for update (isn't this normally the other way around on VGA?
|
||||||
|
|
||||||
// Tell GPU which frame buffer address to draw from
|
// Tell GPU which frame buffer address to draw from
|
||||||
Write32(CRT, regs->grphPrimarySurfaceAddr, fbAddressInt & 0xffffffff);
|
Write32(CRT, regs->grphPrimarySurfaceAddr, fbAddressInt & 0xFFFFFFFF);
|
||||||
Write32(CRT, regs->grphSecondarySurfaceAddr, fbAddressInt & 0xffffffff);
|
//Write32(CRT, regs->grphSecondarySurfaceAddr, fbAddressInt);
|
||||||
|
|
||||||
if (gInfo->shared_info->device_chipset >= (RADEON_R700 | 0x70)) {
|
if (gInfo->shared_info->device_chipset >= (RADEON_R700 | 0x70)) {
|
||||||
Write32(CRT, regs->grphPrimarySurfaceAddrHigh,
|
Write32(CRT, regs->grphPrimarySurfaceAddrHigh,
|
||||||
@@ -247,13 +244,15 @@ CardModeSet(uint8 crtid, display_mode *mode)
|
|||||||
Write32(CRT, regs->crtHTotal,
|
Write32(CRT, regs->crtHTotal,
|
||||||
displayTiming.h_total - 1);
|
displayTiming.h_total - 1);
|
||||||
|
|
||||||
|
/*
|
||||||
// Blanking
|
// Blanking
|
||||||
uint16 blankStart = displayTiming.h_total - displayTiming.h_sync_start;
|
uint16 blankStart = displayTiming.h_total
|
||||||
uint16 blankEnd = displayTiming.h_total
|
|
||||||
+ displayTiming.h_display - displayTiming.h_sync_start;
|
+ displayTiming.h_display - displayTiming.h_sync_start;
|
||||||
|
uint16 blankEnd = displayTiming.h_total - displayTiming.h_sync_start;
|
||||||
|
|
||||||
Write32(CRT, regs->crtHBlank,
|
Write32(CRT, regs->crtHBlank,
|
||||||
blankStart | (blankEnd << 16));
|
blankStart | (blankEnd << 16));
|
||||||
|
*/
|
||||||
|
|
||||||
Write32(CRT, regs->crtHSync,
|
Write32(CRT, regs->crtHSync,
|
||||||
(displayTiming.h_sync_end - displayTiming.h_sync_start) << 16);
|
(displayTiming.h_sync_end - displayTiming.h_sync_start) << 16);
|
||||||
@@ -266,13 +265,15 @@ CardModeSet(uint8 crtid, display_mode *mode)
|
|||||||
Write32(CRT, regs->crtVTotal,
|
Write32(CRT, regs->crtVTotal,
|
||||||
displayTiming.v_total - 1);
|
displayTiming.v_total - 1);
|
||||||
|
|
||||||
|
/*
|
||||||
// Blanking
|
// Blanking
|
||||||
blankStart = displayTiming.v_total - displayTiming.v_sync_start;
|
blankStart = displayTiming.v_total
|
||||||
blankEnd = displayTiming.v_total
|
|
||||||
+ displayTiming.v_display - displayTiming.v_sync_start;
|
+ displayTiming.v_display - displayTiming.v_sync_start;
|
||||||
|
blankEnd = displayTiming.v_total - displayTiming.v_sync_start;
|
||||||
|
|
||||||
Write32(CRT, regs->crtVBlank,
|
Write32(CRT, regs->crtVBlank,
|
||||||
blankStart | (blankEnd << 16));
|
blankStart | (blankEnd << 16));
|
||||||
|
*/
|
||||||
|
|
||||||
// Set Interlace if specified within mode line
|
// Set Interlace if specified within mode line
|
||||||
if (displayTiming.flags & B_TIMING_INTERLACED) {
|
if (displayTiming.flags & B_TIMING_INTERLACED) {
|
||||||
@@ -303,7 +304,6 @@ CardModeScale(uint8 crtid, display_mode *mode)
|
|||||||
register_info* regs = gDisplay[crtid]->regs;
|
register_info* regs = gDisplay[crtid]->regs;
|
||||||
|
|
||||||
// No scaling
|
// No scaling
|
||||||
Write32(CRT, regs->sclUpdate, (1<<16));// Lock
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
Write32(CRT, D1MODE_EXT_OVERSCAN_LEFT_RIGHT,
|
Write32(CRT, D1MODE_EXT_OVERSCAN_LEFT_RIGHT,
|
||||||
@@ -315,44 +315,76 @@ CardModeScale(uint8 crtid, display_mode *mode)
|
|||||||
Write32(CRT, regs->viewportStart, 0);
|
Write32(CRT, regs->viewportStart, 0);
|
||||||
Write32(CRT, regs->viewportSize,
|
Write32(CRT, regs->viewportSize,
|
||||||
mode->timing.v_display | (mode->timing.h_display << 16));
|
mode->timing.v_display | (mode->timing.h_display << 16));
|
||||||
|
|
||||||
Write32(CRT, regs->sclEnable, 0);
|
Write32(CRT, regs->sclEnable, 0);
|
||||||
Write32(CRT, regs->sclTapControl, 0);
|
Write32(CRT, regs->sclTapControl, 0);
|
||||||
Write32(CRT, regs->modeCenter, 2);
|
Write32(CRT, regs->modeCenter, 2);
|
||||||
// D1MODE_DATA_FORMAT?
|
// D1MODE_DATA_FORMAT?
|
||||||
Write32(CRT, regs->sclUpdate, 0); // Unlock
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
radeon_set_display_mode(display_mode *mode)
|
radeon_set_display_mode(display_mode *mode)
|
||||||
{
|
{
|
||||||
uint8 display_id = 0;
|
// Disable VGA (boo, hiss)
|
||||||
|
Write32Mask(OUT, VGA_RENDER_CONTROL, 0, 0x00030000);
|
||||||
|
Write32Mask(OUT, VGA_MODE_CONTROL, 0, 0x00000030);
|
||||||
|
Write32Mask(OUT, VGA_HDP_CONTROL, 0x00010010, 0x00010010);
|
||||||
|
Write32(OUT, D1VGA_CONTROL, 0);
|
||||||
|
Write32(OUT, D2VGA_CONTROL, 0);
|
||||||
|
|
||||||
CardFBSet(display_id, mode);
|
// TODO : We set the same VESA EDID mode on each display
|
||||||
CardModeSet(display_id, mode);
|
|
||||||
CardModeScale(display_id, mode);
|
|
||||||
|
|
||||||
// If this is DAC, set our PLL
|
// Set mode on each display
|
||||||
if ((gDisplay[display_id]->connection_type & CONNECTION_DAC) != 0) {
|
for (uint8 id = 0; id < MAX_DISPLAY; id++) {
|
||||||
PLLSet(gDisplay[display_id]->connection_id, mode->timing.pixel_clock);
|
// Skip if display is inactive
|
||||||
DACSet(gDisplay[display_id]->connection_id, display_id);
|
if (gDisplay[id]->active == false) {
|
||||||
|
CardBlankSet(id, true);
|
||||||
|
display_power(id, RHD_POWER_ON);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO : Shutdown unused PLL/DAC
|
// Program CRT Controller
|
||||||
|
CardFBSet(id, mode);
|
||||||
|
CardModeSet(id, mode);
|
||||||
|
CardModeScale(id, mode);
|
||||||
|
|
||||||
// Power up the output
|
display_power(id, RHD_POWER_RESET);
|
||||||
PLLPower(gDisplay[display_id]->connection_id, RHD_POWER_ON);
|
|
||||||
DACPower(gDisplay[display_id]->connection_id, RHD_POWER_ON);
|
// Program connector controllers
|
||||||
} else if ((gDisplay[display_id]->connection_type & CONNECTION_TMDS) != 0) {
|
switch (gDisplay[id]->connection_type) {
|
||||||
TMDSSet(gDisplay[display_id]->connection_id, mode);
|
case CONNECTION_DAC:
|
||||||
TMDSPower(gDisplay[display_id]->connection_id, RHD_POWER_ON);
|
PLLSet(gDisplay[id]->connection_id,
|
||||||
} else if ((gDisplay[display_id]->connection_type & CONNECTION_LVDS) != 0) {
|
mode->timing.pixel_clock);
|
||||||
LVDSSet(gDisplay[display_id]->connection_id, mode);
|
DACSet(gDisplay[id]->connection_id, id);
|
||||||
LVDSPower(gDisplay[display_id]->connection_id, RHD_POWER_ON);
|
break;
|
||||||
|
case CONNECTION_TMDS:
|
||||||
|
TMDSSet(gDisplay[id]->connection_id, mode);
|
||||||
|
break;
|
||||||
|
case CONNECTION_LVDS:
|
||||||
|
LVDSSet(gDisplay[id]->connection_id, mode);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Power CRT Controller
|
||||||
|
display_power(id, RHD_POWER_ON);
|
||||||
|
CardBlankSet(id, false);
|
||||||
|
|
||||||
|
// Power connector controllers
|
||||||
|
switch (gDisplay[id]->connection_type) {
|
||||||
|
case CONNECTION_DAC:
|
||||||
|
PLLPower(gDisplay[id]->connection_id, RHD_POWER_ON);
|
||||||
|
DACPower(gDisplay[id]->connection_id, RHD_POWER_ON);
|
||||||
|
break;
|
||||||
|
case CONNECTION_TMDS:
|
||||||
|
TMDSPower(gDisplay[id]->connection_id, RHD_POWER_ON);
|
||||||
|
break;
|
||||||
|
case CONNECTION_LVDS:
|
||||||
|
LVDSPower(gDisplay[id]->connection_id, RHD_POWER_ON);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure screen isn't blanked
|
|
||||||
CardBlankSet(display_id, false);
|
|
||||||
|
|
||||||
int32 crtstatus = Read32(CRT, D1CRTC_STATUS);
|
int32 crtstatus = Read32(CRT, D1CRTC_STATUS);
|
||||||
TRACE("CRT0 Status: 0x%X\n", crtstatus);
|
TRACE("CRT0 Status: 0x%X\n", crtstatus);
|
||||||
crtstatus = Read32(CRT, D2CRTC_STATUS);
|
crtstatus = Read32(CRT, D2CRTC_STATUS);
|
||||||
|
|||||||
@@ -102,6 +102,8 @@ radeon_hd_init(radeon_info &info)
|
|||||||
info.shared_info->frame_buffer_int
|
info.shared_info->frame_buffer_int
|
||||||
= read32(info.registers + R6XX_CONFIG_FB_BASE);
|
= read32(info.registers + R6XX_CONFIG_FB_BASE);
|
||||||
|
|
||||||
|
strcpy(info.shared_info->device_identifier, info.device_identifier);
|
||||||
|
|
||||||
// Pull active monitor VESA EDID from boot loader
|
// Pull active monitor VESA EDID from boot loader
|
||||||
edid1_info* edidInfo = (edid1_info*)get_boot_item(EDID_BOOT_INFO,
|
edid1_info* edidInfo = (edid1_info*)get_boot_item(EDID_BOOT_INFO,
|
||||||
NULL);
|
NULL);
|
||||||
|
|||||||
Reference in New Issue
Block a user