ensure framebuffer doesn't exceed PCI bar; add basic monitoring of frame buffer memory allocation; fix return of framebuffer to OS to be the correct area

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@41586 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Alexander von Gluck IV 2011-05-19 17:39:07 +00:00
parent f1abcf7879
commit 51a43d0ff4
5 changed files with 54 additions and 7 deletions

View File

@ -79,7 +79,8 @@ struct radeon_shared_info {
addr_t frame_buffer_phys; // card PCI BAR address of FB
uint32 frame_buffer_int; // card internal offset of FB
uint32 frame_buffer_size; // card internal FB aperture size
uint32 frame_buffer_offset; // offset within FB (pri vs sec)
uint32 frame_buffer_offset; // current offset within FB
uint32 frame_buffer_free; // free space in framebuffer
bool has_edid;
edid1_info edid_info;

View File

@ -15,7 +15,7 @@
#undef TRACE
//#define TRACE_ENGINE
#define TRACE_ENGINE
#ifdef TRACE_ENGINE
# define TRACE(x) _sPrintf x
#else

View File

@ -129,6 +129,34 @@ get_color_space_format(const display_mode &mode, uint32 &colorMode,
}
uint32
AllocateFB(uint32 size, const char *description)
{
uint32 chunk;
// TODO : Kernel AreaMapper?
// Is there any framebuffer left to allocate?
if (gInfo->shared_info->frame_buffer_free < size) {
TRACE("%s was unable to allocate a framebuffer - memory shortage\n",
__func__);
return 0;
}
// assign requested "chunk" of framebuffer memory
chunk = gInfo->shared_info->frame_buffer_offset;
// retally framebuffer memory status
gInfo->shared_info->frame_buffer_offset += size;
gInfo->shared_info->frame_buffer_free -= size;
TRACE("%s allocated framebuffer %s at offset 0x%08X (size: 0x%08X)\n",
__func__, description, chunk, size);
return chunk;
}
// Blacks the screen out, useful for mode setting
static void
CardBlankSet(int crtNumber, bool blank)
@ -165,6 +193,7 @@ CardFBSet(int crtNumber, display_mode *mode)
write32AtMask(regOffset + gRegister->grphEnable, 1, 0x00000001);
write32(regOffset + gRegister->grphControl, 0);
// set color mode on video card
switch (mode->space) {
case B_CMAP8:
write32AtMask(regOffset + gRegister->grphControl,
@ -190,8 +219,11 @@ CardFBSet(int crtNumber, display_mode *mode)
// only for chipsets > r600
// R5xx - RS690 case is GRPH_CONTROL bit 16
uint32 neededFrameBuffer = mode->timing.h_display
* bitsPerPixel * mode->virtual_height / 8;
uint32 fbIntAddress = gInfo->shared_info->frame_buffer_int;
uint32 fbOffset = gInfo->shared_info->frame_buffer_offset;
uint32 fbOffset = AllocateFB(neededFrameBuffer, "DisplayFramebuffer");
write32(regOffset + gRegister->grphPrimarySurfaceAddr,
fbIntAddress + fbOffset);
@ -343,11 +375,15 @@ radeon_get_frame_buffer_config(frame_buffer_config *config)
{
TRACE("%s\n", __func__);
uint32 offset = gInfo->shared_info->frame_buffer_offset;
// TODO : This returns the location of the last allocated fb
config->frame_buffer = gInfo->shared_info->graphics_memory
+ gInfo->shared_info->frame_buffer_int
+ gInfo->shared_info->frame_buffer_offset;
config->frame_buffer_dma = (uint8 *)gInfo->shared_info->frame_buffer_phys
+ gInfo->shared_info->frame_buffer_offset;
config->frame_buffer = gInfo->shared_info->graphics_memory + offset;
config->frame_buffer_dma
= (uint8 *)gInfo->shared_info->frame_buffer_phys + offset;
config->bytes_per_row = gInfo->shared_info->bytes_per_row;
return B_OK;

View File

@ -25,6 +25,7 @@
status_t create_mode_list(void);
bool is_mode_supported(display_mode* mode);
status_t is_mode_sane(display_mode *mode);
uint32 AllocateFB(uint32 size, const char *description);
#endif /*RADEON_HD_MODE_H*/

View File

@ -128,6 +128,15 @@ radeon_hd_init(radeon_info &info)
= read32(info.registers + R6XX_CONFIG_APER_SIZE) / 1024;
}
uint32 barSize = info.pci->u.h0.base_register_sizes[RHD_FB_BAR] / 1024;
// if graphics memory is larger then PCI bar, just map bar
if (info.shared_info->graphics_memory_size > barSize)
info.shared_info->frame_buffer_size = barSize;
else
info.shared_info->frame_buffer_size
= info.shared_info->graphics_memory_size;
int32 memory_size = info.shared_info->graphics_memory_size / 1024;
int32 frame_buffer_size = info.shared_info->frame_buffer_size / 1024;