* 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:
parent
812f1e5bb8
commit
6da3f7d4c1
@ -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"
|
||||
|
3700
headers/private/graphics/radeon_hd/radeon_reg.h
Normal file
3700
headers/private/graphics/radeon_hd/radeon_reg.h
Normal file
File diff suppressed because it is too large
Load Diff
@ -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;
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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();
|
||||
|
||||
|
@ -14,7 +14,6 @@
|
||||
#include "atom.h"
|
||||
|
||||
|
||||
void atombios_crtc_power(uint8 crt_id, int state);
|
||||
status_t radeon_init_bios(uint8* bios);
|
||||
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user