* lots of changes

* add missing header for some radeon registers
* begin removing now un-needed direct register calls
* move and refactor crtc functions
* fix function naming to be clearer
* create more AtomBIOS style calls
* this will eat your cat at the moment, don't bother testing


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@42582 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Alexander von Gluck IV 2011-08-05 22:24:57 +00:00
parent 812f1e5bb8
commit 6da3f7d4c1
11 changed files with 4144 additions and 304 deletions

View File

@ -12,7 +12,9 @@
#include "lock.h"
#include "rhd_regs.h"
#include "radeon_reg.h"
#include "rhd_regs.h" // to phase out
#include "r500_reg.h"
#include "r600_reg.h"
#include "r800_reg.h"

File diff suppressed because it is too large Load Diff

View File

@ -19,6 +19,7 @@
#include "lvds.h"
#include <ByteOrder.h>
#include <edid.h>
@ -57,8 +58,8 @@ struct register_info {
uint16 grphControl;
uint16 grphSwapControl;
uint16 grphPrimarySurfaceAddr;
uint16 grphPrimarySurfaceAddrHigh;
uint16 grphSecondarySurfaceAddr;
uint16 grphPrimarySurfaceAddrHigh;
uint16 grphSecondarySurfaceAddrHigh;
uint16 grphPitch;
uint16 grphSurfaceOffsetX;
@ -78,6 +79,7 @@ struct register_info {
uint16 crtVBlank;
uint16 crtHTotal;
uint16 crtVTotal;
uint16 crtcOffset;
uint16 modeDesktopHeight;
uint16 modeDataFormat;
uint16 modeCenter;

View File

@ -22,7 +22,7 @@
* Author: Stanislaw Skowronek
*/
/* Reworked for the Haiku Operating System Radeon HD driver
/* Rewritten for the Haiku Operating System Radeon HD driver
* Author:
* Alexander von Gluck, kallisti5@unixzen.com
*/

View File

@ -28,21 +28,6 @@
atom_context *gAtomContext;
void
atombios_crtc_power(uint8 crt_id, int state)
{
int index = GetIndexIntoMasterTable(COMMAND, EnableCRTC);
ENABLE_CRTC_PS_ALLOCATION args;
memset(&args, 0, sizeof(args));
args.ucCRTC = crt_id;
args.ucEnable = state;
atom_execute_table(gAtomContext, index, (uint32*)&args);
}
void
radeon_bios_init_scratch()
{
@ -115,6 +100,9 @@ radeon_init_bios(uint8* bios)
return B_ERROR;
}
atom_asic_init(gAtomContext);
// Post card
// mutex_init(&rdev->mode_info.atom_context->mutex);
radeon_bios_init_scratch();

View File

@ -14,7 +14,6 @@
#include "atom.h"
void atombios_crtc_power(uint8 crt_id, int state);
status_t radeon_init_bios(uint8* bios);

View File

@ -9,6 +9,7 @@
#include "accelerant_protos.h"
#include "accelerant.h"
#include "bios.h"
#include "display.h"
#include <stdlib.h>
@ -56,15 +57,17 @@ init_registers(register_info* regs, uint8 crtid)
regs->vgaControl = D1VGA_CONTROL;
}
regs->crtcOffset = offset;
// Evergreen+ is crtoffset + register
regs->grphEnable = offset + EVERGREEN_GRPH_ENABLE;
regs->grphControl = offset + EVERGREEN_GRPH_CONTROL;
regs->grphSwapControl = offset + EVERGREEN_GRPH_SWAP_CONTROL;
regs->grphPrimarySurfaceAddr
= offset + EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS;
regs->grphSecondarySurfaceAddr
= offset + EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS;
regs->grphPrimarySurfaceAddrHigh
= offset + EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH;
regs->grphSecondarySurfaceAddrHigh
@ -104,6 +107,9 @@ init_registers(register_info* regs, uint8 crtid)
= crtid == 1 ? D2GRPH_SECONDARY_SURFACE_ADDRESS
: D1GRPH_SECONDARY_SURFACE_ADDRESS;
regs->crtcOffset
= crtid == 1 ? (D2GRPH_X_END - D1GRPH_X_END) : 0;
// Surface Address high only used on r770+
regs->grphPrimarySurfaceAddrHigh
= crtid == 1 ? R700_D2GRPH_PRIMARY_SURFACE_ADDRESS_HIGH
@ -303,28 +309,335 @@ debug_displays()
void
display_power(uint8 crtid, int command)
display_crtc_lock(uint8 crtc_id, int command)
{
register_info* regs = gDisplay[crtid]->regs;
ENABLE_CRTC_PS_ALLOCATION args;
int index
= GetIndexIntoMasterTable(COMMAND, UpdateCRTC_DoubleBufferRegisters);
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;
}
memset(&args, 0, sizeof(args));
args.ucCRTC = crtc_id;
args.ucEnable = command;
atom_execute_table(gAtomContext, index, (uint32 *)&args);
}
void
display_crtc_blank(uint8 crtc_id, int command)
{
int index = GetIndexIntoMasterTable(COMMAND, BlankCRTC);
BLANK_CRTC_PS_ALLOCATION args;
memset(&args, 0, sizeof(args));
args.ucCRTC = crtc_id;
args.ucBlanking = command;
atom_execute_table(gAtomContext, index, (uint32 *)&args);
}
void
display_crtc_scale(uint8 crtc_id, display_mode *mode)
{
ENABLE_SCALER_PS_ALLOCATION args;
int index = GetIndexIntoMasterTable(COMMAND, EnableScaler);
memset(&args, 0, sizeof(args));
args.ucScaler = crtc_id;
args.ucEnable = ATOM_SCALER_EXPANSION;
atom_execute_table(gAtomContext, index, (uint32 *)&args);
}
void
display_crtc_fb_set_dce1(uint8 crtc_id, display_mode *mode)
{
radeon_shared_info &info = *gInfo->shared_info;
register_info* regs = gDisplay[crtc_id]->regs;
uint32 fb_swap = R600_D1GRPH_SWAP_ENDIAN_NONE;
uint32 fb_format;
uint32 bytesPerPixel;
uint32 bitsPerPixel;
switch (mode->space) {
case B_CMAP8:
bytesPerPixel = 1;
bitsPerPixel = 8;
fb_format = AVIVO_D1GRPH_CONTROL_DEPTH_8BPP
| AVIVO_D1GRPH_CONTROL_8BPP_INDEXED;
break;
case B_RGB15_LITTLE:
bytesPerPixel = 2;
bitsPerPixel = 15;
fb_format = AVIVO_D1GRPH_CONTROL_DEPTH_16BPP
| AVIVO_D1GRPH_CONTROL_16BPP_ARGB1555;
break;
case B_RGB16_LITTLE:
bytesPerPixel = 2;
bitsPerPixel = 16;
fb_format = AVIVO_D1GRPH_CONTROL_DEPTH_16BPP
| AVIVO_D1GRPH_CONTROL_16BPP_RGB565;
#ifdef __POWERPC__
fb_swap = R600_D1GRPH_SWAP_ENDIAN_16BIT;
#endif
break;
case B_RGB24_LITTLE:
case B_RGB32_LITTLE:
default:
bytesPerPixel = 4;
bitsPerPixel = 32;
fb_format = AVIVO_D1GRPH_CONTROL_DEPTH_32BPP
| AVIVO_D1GRPH_CONTROL_32BPP_ARGB8888;
#ifdef __POWERPC__
fb_swap = R600_D1GRPH_SWAP_ENDIAN_32BIT;
#endif
break;
}
uint32 bytesPerRow = mode->virtual_width * bytesPerPixel;
Write32(OUT, regs->vgaControl, 0);
uint64 fbAddressInt = gInfo->shared_info->frame_buffer_int;
Write32(OUT, regs->grphPrimarySurfaceAddr, (fbAddressInt & 0xFFFFFFFF));
Write32(OUT, regs->grphSecondarySurfaceAddr, (fbAddressInt & 0xFFFFFFFF));
if (info.device_chipset >= (RADEON_R700 | 0x70)) {
Write32(OUT, regs->grphPrimarySurfaceAddrHigh,
(fbAddressInt >> 32) & 0xf);
Write32(OUT, regs->grphSecondarySurfaceAddrHigh,
(fbAddressInt >> 32) & 0xf);
}
if (info.device_chipset >= RADEON_R600)
Write32(CRT, regs->grphSwapControl, fb_swap);
Write32(CRT, regs->grphSurfaceOffsetX, 0);
Write32(CRT, regs->grphSurfaceOffsetY, 0);
Write32(CRT, regs->grphXStart, 0);
Write32(CRT, regs->grphYStart, 0);
Write32(CRT, regs->grphXEnd, mode->virtual_width);
Write32(CRT, regs->grphYEnd, mode->virtual_height);
Write32(CRT, regs->grphPitch, bytesPerRow / 4);
Write32(CRT, regs->grphEnable, 1);
// Enable Frame buffer
Write32(CRT, regs->modeDesktopHeight, mode->virtual_height);
Write32(CRT, regs->viewportStart, 0);
Write32(CRT, regs->viewportSize,
mode->timing.v_display | (mode->timing.h_display << 16));
uint32 tmp = Read32(CRT, AVIVO_D1GRPH_FLIP_CONTROL + regs->crtcOffset);
tmp &= ~AVIVO_D1GRPH_SURFACE_UPDATE_H_RETRACE_EN;
Write32(OUT, AVIVO_D1GRPH_FLIP_CONTROL + regs->crtcOffset, tmp);
Write32(OUT, AVIVO_D1MODE_MASTER_UPDATE_MODE + regs->crtcOffset, 0);
// Pageflip to happen anywhere in vblank
}
void
display_crtc_fb_set_legacy(uint8 crtc_id, display_mode *mode)
{
register_info* regs = gDisplay[crtc_id]->regs;
uint64 fbAddressInt = gInfo->shared_info->frame_buffer_int;
Write32(CRT, regs->grphUpdate, (1<<16));
// Lock for update (isn't this normally the other way around on VGA?
Write32Mask(CRT, regs->grphEnable, 1, 0x00000001);
// Enable Frame buffer
Write32(CRT, regs->grphControl, 0);
// Reset stored depth, format, etc
uint32 bytesPerPixel;
uint32 bitsPerPixel;
// set color mode on video card
switch (mode->space) {
case B_CMAP8:
bytesPerPixel = 1;
bitsPerPixel = 8;
Write32Mask(CRT, regs->grphControl,
0, 0x00000703);
break;
case B_RGB15_LITTLE:
bytesPerPixel = 2;
bitsPerPixel = 15;
Write32Mask(CRT, regs->grphControl,
0x000001, 0x00000703);
break;
case B_RGB16_LITTLE:
bytesPerPixel = 2;
bitsPerPixel = 16;
Write32Mask(CRT, regs->grphControl,
0x000101, 0x00000703);
break;
case B_RGB24_LITTLE:
bytesPerPixel = 4;
bitsPerPixel = 24;
Write32Mask(CRT, regs->grphControl,
0x000002, 0x00000703);
break;
case B_RGB32_LITTLE:
default:
bytesPerPixel = 4;
bitsPerPixel = 32;
Write32Mask(CRT, regs->grphControl,
0x000002, 0x00000703);
break;
}
uint32 bytesPerRow = mode->virtual_width * bytesPerPixel;
Write32(CRT, regs->grphSwapControl, 0);
// only for chipsets > r600
// Tell GPU which frame buffer address to draw from
Write32(CRT, regs->grphPrimarySurfaceAddr, fbAddressInt & 0xFFFFFFFF);
Write32(CRT, regs->grphSecondarySurfaceAddr, fbAddressInt & 0xFFFFFFFF);
Write32(CRT, regs->grphSurfaceOffsetX, 0);
Write32(CRT, regs->grphSurfaceOffsetY, 0);
Write32(CRT, regs->grphXStart, 0);
Write32(CRT, regs->grphYStart, 0);
Write32(CRT, regs->grphXEnd, mode->virtual_width);
Write32(CRT, regs->grphYEnd, mode->virtual_height);
Write32(CRT, regs->grphPitch, bytesPerRow / 4);
Write32(CRT, regs->modeDesktopHeight, mode->virtual_height);
Write32(CRT, regs->grphUpdate, 0);
// Unlock changed registers
// update shared info
gInfo->shared_info->bytes_per_row = bytesPerRow;
gInfo->shared_info->current_mode = *mode;
gInfo->shared_info->bits_per_pixel = bitsPerPixel;
// TODO : recompute bandwidth via rv515_bandwidth_avivo_update
}
void
display_crtc_set(uint8 crtc_id, display_mode *mode)
{
display_timing& displayTiming = mode->timing;
TRACE("%s called to do %dx%d\n",
__func__, displayTiming.h_display, displayTiming.v_display);
SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION args;
int index = GetIndexIntoMasterTable(COMMAND, SetCRTC_Timing);
uint16 misc = 0;
memset(&args, 0, sizeof(args));
args.usH_Total = B_HOST_TO_LENDIAN_INT16(displayTiming.h_total);
args.usH_Disp = B_HOST_TO_LENDIAN_INT16(displayTiming.h_display);
args.usH_SyncStart = B_HOST_TO_LENDIAN_INT16(displayTiming.h_sync_start);
args.usH_SyncWidth = B_HOST_TO_LENDIAN_INT16(displayTiming.h_sync_end
- displayTiming.h_sync_start);
args.usV_Total = B_HOST_TO_LENDIAN_INT16(displayTiming.v_total);
args.usV_Disp = B_HOST_TO_LENDIAN_INT16(displayTiming.v_display);
args.usV_SyncStart = B_HOST_TO_LENDIAN_INT16(displayTiming.v_sync_start);
args.usV_SyncWidth = B_HOST_TO_LENDIAN_INT16(displayTiming.v_sync_end
- displayTiming.v_sync_start);
args.ucOverscanRight = 0;
args.ucOverscanLeft = 0;
args.ucOverscanBottom = 0;
args.ucOverscanTop = 0;
if ((displayTiming.flags & B_POSITIVE_HSYNC) == 0)
misc |= ATOM_HSYNC_POLARITY;
if ((displayTiming.flags & B_POSITIVE_VSYNC) == 0)
misc |= ATOM_VSYNC_POLARITY;
args.susModeMiscInfo.usAccess = B_HOST_TO_LENDIAN_INT16(misc);
args.ucCRTC = crtc_id;
atom_execute_table(gAtomContext, index, (uint32 *)&args);
}
void
display_crtc_set_dtd(uint8 crtc_id, display_mode *mode)
{
display_timing& displayTiming = mode->timing;
TRACE("%s called to do %dx%d\n",
__func__, displayTiming.h_display, displayTiming.v_display);
SET_CRTC_USING_DTD_TIMING_PARAMETERS args;
int index = GetIndexIntoMasterTable(COMMAND, SetCRTC_UsingDTDTiming);
uint16 misc = 0;
memset(&args, 0, sizeof(args));
uint16 blankStart
= MIN(displayTiming.h_sync_start, displayTiming.h_display);
uint16 blankEnd
= MAX(displayTiming.h_sync_end, displayTiming.h_total);
args.usH_Size = B_HOST_TO_LENDIAN_INT16(displayTiming.h_display);
args.usH_Blanking_Time = B_HOST_TO_LENDIAN_INT16(blankEnd - blankStart);
blankStart = MIN(displayTiming.v_sync_start, displayTiming.v_display);
blankEnd = MAX(displayTiming.v_sync_end, displayTiming.v_total);
args.usV_Size = B_HOST_TO_LENDIAN_INT16(displayTiming.v_display);
args.usV_Blanking_Time = B_HOST_TO_LENDIAN_INT16(blankEnd - blankStart);
args.usH_SyncOffset = B_HOST_TO_LENDIAN_INT16(displayTiming.h_sync_start
- displayTiming.h_display);
args.usH_SyncWidth = B_HOST_TO_LENDIAN_INT16(displayTiming.h_sync_end
- displayTiming.h_sync_start);
args.usV_SyncOffset = B_HOST_TO_LENDIAN_INT16(displayTiming.v_sync_start
- displayTiming.v_display);
args.usV_SyncWidth = B_HOST_TO_LENDIAN_INT16(displayTiming.v_sync_end
- displayTiming.v_sync_start);
args.ucH_Border = 0;
args.ucV_Border = 0;
if ((displayTiming.flags & B_POSITIVE_HSYNC) == 0)
misc |= ATOM_HSYNC_POLARITY;
if ((displayTiming.flags & B_POSITIVE_VSYNC) == 0)
misc |= ATOM_VSYNC_POLARITY;
args.susModeMiscInfo.usAccess = B_HOST_TO_LENDIAN_INT16(misc);
args.ucCRTC = crtc_id;
atom_execute_table(gAtomContext, index, (uint32 *)&args);
}
void
display_crtc_power(uint8 crt_id, int command)
{
int index = GetIndexIntoMasterTable(COMMAND, EnableCRTC);
ENABLE_CRTC_PS_ALLOCATION args;
memset(&args, 0, sizeof(args));
args.ucCRTC = crt_id;
args.ucEnable = command;
atom_execute_table(gAtomContext, index, (uint32*)&args);
}

View File

@ -13,7 +13,15 @@ status_t init_registers(register_info* reg, uint8 crtid);
status_t detect_crt_ranges(uint32 crtid);
status_t detect_displays();
void debug_displays();
void display_power(uint8 crtid, int command);
void display_crtc_lock(uint8 crtc_id, int command);
void display_crtc_blank(uint8 crtc_id, int command);
void display_crtc_scale(uint8 crtc_id, display_mode *mode);
void display_crtc_fb_set_legacy(uint8 crtc_id, display_mode *mode);
void display_crtc_fb_set_dce1(uint8 crtc_id, display_mode *mode);
void display_crtc_set(uint8 crtc_id, display_mode *mode);
void display_crtc_set_dtd(uint8 crtc_id, display_mode *mode);
void display_crtc_power(uint8 crt_id, int command);
#endif /* RADEON_HD_DISPLAY_H */

View File

@ -92,275 +92,34 @@ radeon_get_edid_info(void* info, size_t size, uint32* edid_version)
}
static void
get_color_space_format(const display_mode &mode, uint32 &colorMode,
uint32 &bytesPerRow, uint32 &bitsPerPixel)
{
uint32 bytesPerPixel;
switch (mode.space) {
case B_RGB32_LITTLE:
colorMode = DISPLAY_CONTROL_RGB32;
bytesPerPixel = 4;
bitsPerPixel = 32;
break;
case B_RGB16_LITTLE:
colorMode = DISPLAY_CONTROL_RGB16;
bytesPerPixel = 2;
bitsPerPixel = 16;
break;
case B_RGB15_LITTLE:
colorMode = DISPLAY_CONTROL_RGB15;
bytesPerPixel = 2;
bitsPerPixel = 15;
break;
case B_CMAP8:
default:
colorMode = DISPLAY_CONTROL_CMAP8;
bytesPerPixel = 1;
bitsPerPixel = 8;
break;
}
bytesPerRow = mode.virtual_width * bytesPerPixel;
}
// Blacks the screen out, useful for mode setting
static void
CardBlankSet(uint8 crtid, bool blank)
{
int blackColorReg
= crtid == 1 ? D2CRTC_BLACK_COLOR : D1CRTC_BLACK_COLOR;
int blankControlReg
= crtid == 1 ? D2CRTC_BLANK_CONTROL : D1CRTC_BLANK_CONTROL;
Write32(CRT, blackColorReg, 0);
Write32Mask(CRT, blankControlReg, blank ? 1 << 8 : 0, 1 << 8);
}
static void
CardFBSet(uint8 crtid, display_mode *mode)
{
register_info* regs = gDisplay[crtid]->regs;
uint32 colorMode;
uint32 bytesPerRow;
uint32 bitsPerPixel;
get_color_space_format(*mode, colorMode, bytesPerRow, bitsPerPixel);
LVDSAllIdle();
// DVI / HDMI / LCD
TMDSAllIdle();
// DVI / HDMI
DACAllIdle();
// VGA
// framebuffersize = w * h * bpp = fb bits / 8 = bytes needed
uint64 fbAddressInt = gInfo->shared_info->frame_buffer_int;
MCFBSetup();
Write32(CRT, regs->grphUpdate, (1<<16));
// Lock for update (isn't this normally the other way around on VGA?
// Tell GPU which frame buffer address to draw from
Write32(CRT, regs->grphPrimarySurfaceAddr, fbAddressInt & 0xFFFFFFFF);
//Write32(CRT, regs->grphSecondarySurfaceAddr, fbAddressInt);
if (gInfo->shared_info->device_chipset >= (RADEON_R700 | 0x70)) {
Write32(CRT, regs->grphPrimarySurfaceAddrHigh,
(fbAddressInt >> 32) & 0xf);
Write32(CRT, regs->grphSecondarySurfaceAddrHigh,
(fbAddressInt >> 32) & 0xf);
}
Write32(CRT, regs->grphControl, 0);
// Reset stored depth, format, etc
// set color mode on video card
switch (mode->space) {
case B_CMAP8:
Write32Mask(CRT, regs->grphControl,
0, 0x00000703);
break;
case B_RGB15_LITTLE:
Write32Mask(CRT, regs->grphControl,
0x000001, 0x00000703);
break;
case B_RGB16_LITTLE:
Write32Mask(CRT, regs->grphControl,
0x000101, 0x00000703);
break;
case B_RGB24_LITTLE:
case B_RGB32_LITTLE:
default:
Write32Mask(CRT, regs->grphControl,
0x000002, 0x00000703);
break;
}
Write32(CRT, regs->grphSwapControl, 0);
// only for chipsets > r600
// R5xx - RS690 case is GRPH_CONTROL bit 16
Write32Mask(CRT, regs->grphEnable, 1, 0x00000001);
// Enable graphics
Write32(CRT, regs->grphSurfaceOffsetX, 0);
Write32(CRT, regs->grphSurfaceOffsetY, 0);
Write32(CRT, regs->grphXStart, 0);
Write32(CRT, regs->grphYStart, 0);
Write32(CRT, regs->grphXEnd, mode->virtual_width);
Write32(CRT, regs->grphYEnd, mode->virtual_height);
Write32(CRT, regs->grphPitch, bytesPerRow / 4);
Write32(CRT, regs->modeDesktopHeight, mode->virtual_height);
Write32(CRT, regs->grphUpdate, 0);
// Unlock changed registers
// update shared info
gInfo->shared_info->bytes_per_row = bytesPerRow;
gInfo->shared_info->current_mode = *mode;
gInfo->shared_info->bits_per_pixel = bitsPerPixel;
}
static void
CardModeSet(uint8 crtid, display_mode *mode)
{
display_timing& displayTiming = mode->timing;
register_info* regs = gDisplay[crtid]->regs;
TRACE("%s called to do %dx%d\n",
__func__, displayTiming.h_display, displayTiming.v_display);
// enable read requests
Write32Mask(CRT, regs->grphControl, 0, 0x01000000);
// *** Horizontal
Write32(CRT, regs->crtHTotal,
displayTiming.h_total - 1);
/*
// Blanking
uint16 blankStart = displayTiming.h_total
+ displayTiming.h_display - displayTiming.h_sync_start;
uint16 blankEnd = displayTiming.h_total - displayTiming.h_sync_start;
Write32(CRT, regs->crtHBlank,
blankStart | (blankEnd << 16));
*/
Write32(CRT, regs->crtHSync,
(displayTiming.h_sync_end - displayTiming.h_sync_start) << 16);
// set flag for neg. H sync. M76 Register Reference Guide 2-256
Write32Mask(CRT, regs->crtHPolarity,
displayTiming.flags & B_POSITIVE_HSYNC ? 0 : 1, 0x1);
// *** Vertical
Write32(CRT, regs->crtVTotal,
displayTiming.v_total - 1);
/*
// Blanking
blankStart = displayTiming.v_total
+ displayTiming.v_display - displayTiming.v_sync_start;
blankEnd = displayTiming.v_total - displayTiming.v_sync_start;
Write32(CRT, regs->crtVBlank,
blankStart | (blankEnd << 16));
*/
// Set Interlace if specified within mode line
if (displayTiming.flags & B_TIMING_INTERLACED) {
Write32(CRT, regs->crtInterlace, 0x1);
Write32(CRT, regs->modeDataFormat, 0x1);
} else {
Write32(CRT, regs->crtInterlace, 0x0);
Write32(CRT, regs->modeDataFormat, 0x0);
}
Write32(CRT, regs->crtVSync,
(displayTiming.v_sync_end - displayTiming.v_sync_start) << 16);
// set flag for neg. V sync. M76 Register Reference Guide 2-258
Write32Mask(CRT, regs->crtVPolarity,
displayTiming.flags & B_POSITIVE_VSYNC ? 0 : 1, 0x1);
// TODO : for now fixed non-interlace
Write32(OUT, D1CRTC_INTERLACE_CONTROL, 0x0);
Write32(OUT, D1MODE_DATA_FORMAT, 0x0);
/* set D1CRTC_HORZ_COUNT_BY2_EN to 0;
should only be set to 1 on 30bpp DVI modes
*/
Write32Mask(CRT, regs->crtCountControl, 0x0, 0x1);
}
static void
CardModeScale(uint8 crtid, display_mode *mode)
{
register_info* regs = gDisplay[crtid]->regs;
// No scaling
#if 0
Write32(CRT, D1MODE_EXT_OVERSCAN_LEFT_RIGHT,
(OVERSCAN << 16) | OVERSCAN); // LEFT | RIGHT
Write32(CRT, D1MODE_EXT_OVERSCAN_TOP_BOTTOM,
(OVERSCAN << 16) | OVERSCAN); // TOP | BOTTOM
#endif
Write32(CRT, regs->viewportStart, 0);
Write32(CRT, regs->viewportSize,
mode->timing.v_display | (mode->timing.h_display << 16));
Write32(CRT, regs->sclEnable, 0);
Write32(CRT, regs->sclTapControl, 0);
Write32(CRT, regs->modeCenter, 2);
}
status_t
radeon_set_display_mode(display_mode *mode)
{
// 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);
// TODO : We set the same VESA EDID mode on each display
// Set mode on each display
for (uint8 id = 0; id < MAX_DISPLAY; id++) {
display_crtc_lock(id, ATOM_ENABLE);
// Skip if display is inactive
if (gDisplay[id]->active == false) {
CardBlankSet(id, true);
// LEGACY : display_power(id, RHD_POWER_SHUTDOWN);
atombios_crtc_power(id, ATOM_DISABLE);
display_crtc_blank(id, ATOM_ENABLE);
display_crtc_power(id, ATOM_DISABLE);
display_crtc_lock(id, ATOM_DISABLE);
continue;
}
// Program CRT Controller
CardFBSet(id, mode);
CardModeSet(id, mode);
CardModeScale(id, mode);
//pll_set(gDisplay[id]->connection_id,
// mode->timing.pixel_clock, id);
// LEGACY : display_power(id, RHD_POWER_RESET);
// Program CRT Controller
display_crtc_set_dtd(id, mode);
//display_crtc_fb_set_dce1(id, mode);
display_crtc_fb_set_legacy(id, mode);
display_crtc_scale(id, mode);
// Program connector controllers
switch (gDisplay[id]->connection_type) {
case CONNECTION_DAC:
PLLSet(gDisplay[id]->connection_id,
mode->timing.pixel_clock);
DACSet(gDisplay[id]->connection_id, id);
break;
case CONNECTION_TMDS:
@ -372,14 +131,14 @@ radeon_set_display_mode(display_mode *mode)
}
// Power CRT Controller
// LEGACY : display_power(id, RHD_POWER_ON);
atombios_crtc_power(id, ATOM_ENABLE);
CardBlankSet(id, false);
display_crtc_blank(id, ATOM_DISABLE);
display_crtc_power(id, ATOM_ENABLE);
PLLPower(gDisplay[id]->connection_id, RHD_POWER_ON);
// 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:
@ -389,6 +148,9 @@ radeon_set_display_mode(display_mode *mode)
LVDSPower(gDisplay[id]->connection_id, RHD_POWER_ON);
break;
}
display_crtc_lock(id, ATOM_DISABLE);
// commit
}
int32 crtstatus = Read32(CRT, D1CRTC_STATUS);

View File

@ -9,6 +9,7 @@
#include "accelerant_protos.h"
#include "accelerant.h"
#include "bios.h"
#include "utility.h"
#include "pll.h"
@ -27,6 +28,17 @@ extern "C" void _sPrintf(const char *format, ...);
#endif
// For AtomBIOS PLLSet
union set_pixel_clock {
SET_PIXEL_CLOCK_PS_ALLOCATION base;
PIXEL_CLOCK_PARAMETERS v1;
PIXEL_CLOCK_PARAMETERS_V2 v2;
PIXEL_CLOCK_PARAMETERS_V3 v3;
PIXEL_CLOCK_PARAMETERS_V5 v5;
PIXEL_CLOCK_PARAMETERS_V6 v6;
};
/* From hardcoded values. */
static struct PLL_Control RV610PLLControl[] =
{
@ -221,16 +233,70 @@ PLLPower(uint8 pllIndex, int command)
status_t
PLLSet(uint8 pllIndex, uint32 pixelClock)
pll_set(uint8 pll_id, uint32 pixelClock, uint8 crtc_id)
{
radeon_shared_info &info = *gInfo->shared_info;
uint16 reference = 0;
uint16 feedback = 0;
uint16 post = 0;
PLLCalculate(pixelClock, &reference, &feedback, &post);
int index = GetIndexIntoMasterTable(COMMAND, SetPixelClock);
union set_pixel_clock args;
memset(&args, 0, sizeof(args));
//uint8 frev;
//uint8 crev;
//atom_parse_cmd_header(gAtomContext, index, &frev, &crev);
uint8 frev = 1;
uint8 crev = 1;
switch (crev) {
case 1:
args.v1.usPixelClock = B_HOST_TO_LENDIAN_INT16(pixelClock / 10);
args.v1.usRefDiv = B_HOST_TO_LENDIAN_INT16(reference);
args.v1.usFbDiv = B_HOST_TO_LENDIAN_INT16(feedback);
// args.v1.ucFracFbDiv = frac_fb_div;
args.v1.ucFracFbDiv = 0;
args.v1.ucPostDiv = post;
args.v1.ucPpll = pll_id;
args.v1.ucCRTC = crtc_id;
args.v1.ucRefDivSrc = 1;
break;
case 2:
args.v2.usPixelClock = B_HOST_TO_LENDIAN_INT16(pixelClock / 10);
args.v2.usRefDiv = B_HOST_TO_LENDIAN_INT16(reference);
args.v2.usFbDiv = B_HOST_TO_LENDIAN_INT16(feedback);
// args.v2.ucFracFbDiv = frac_fb_div;
args.v2.ucPostDiv = post;
args.v2.ucPpll = pll_id;
args.v2.ucCRTC = crtc_id;
args.v2.ucRefDivSrc = 1;
break;
#if 0
case 3:
args.v3.usPixelClock = B_HOST_TO_LENDIAN_INT16(pixelClock / 10);
args.v3.usRefDiv = B_HOST_TO_LENDIAN_INT16(reference);
args.v3.usFbDiv = B_HOST_TO_LENDIAN_INT16(feedback);
// args.v3.ucFracFbDiv = frac_fb_div;
args.v3.ucPostDiv = post;
args.v3.ucPpll = pll_id;
args.v3.ucMiscInfo = (pll_id << 2);
if (ss_enabled && (ss->type & ATOM_EXTERNAL_SS_MASK))
args.v3.ucMiscInfo |= PIXEL_CLOCK_MISC_REF_DIV_SRC;
args.v3.ucTransmitterId = encoder_id;
args.v3.ucEncoderMode = encoder_mode;
break;
#endif
default:
TRACE("%s: TODO: table version %d %d\n", __func__, frev, crev);
return B_ERROR;
}
atom_execute_table(gAtomContext, index, (uint32 *)&args);
#if 0
if (info.device_chipset >= (RADEON_R600 | 0x20)) {
TRACE("%s : setting pixel clock %d on r620+\n", __func__,
(int)pixelClock);
@ -242,6 +308,7 @@ PLLSet(uint8 pllIndex, uint32 pixelClock)
PLLSetLowLegacy(pllIndex, pixelClock, reference,
feedback, post);
}
#endif
return B_OK;
}
@ -617,4 +684,3 @@ DCCGCLKSet(uint8 pllIndex, int set)
break;
}
}

View File

@ -35,7 +35,7 @@ struct PLL_Control {
status_t PLLCalculate(uint32 pixelClock, uint16 *reference, uint16 *feedback,
uint16 *post);
status_t PLLSet(uint8 pllIndex, uint32 pixelClock);
status_t pll_set(uint8 pll_id, uint32 pixelClock, uint8 crtc_id);
void PLLSetLowLegacy(uint8 pllIndex, uint32 pixelClock, uint16 reference,
uint16 feedback, uint16 post);
void PLLSetLowR620(uint8 pllIndex, uint32 pixelClock, uint16 reference,