Enabling overlay requires a command ring buffer, and we're setting one (very

small) up for this specific task - this will later be used for the acceleration
engine as well.
Some more work on overlay initialization, doesn't do anything yet, though.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@17254 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2006-04-28 16:50:39 +00:00
parent d7424bc790
commit 7740a4c15b
6 changed files with 161 additions and 14 deletions
@@ -9,6 +9,8 @@
#define INTEL_EXTREME_H
#include "lock.h"
#include <memory_manager.h>
#include <Accelerant.h>
@@ -38,6 +40,16 @@ struct pll_info {
uint32 divisor_register;
};
struct ring_buffer {
struct lock lock;
uint32 register_base;
uint32 handle;
uint32 offset;
uint32 size;
uint32 position;
uint8 *base;
};
struct overlay_registers;
struct intel_shared_info {
@@ -57,6 +69,8 @@ struct intel_shared_info {
uint32 frame_buffer_offset;
ring_buffer primary_ring_buffer;
int32 overlay_channel_used;
uint32 overlay_token;
uint8* physical_overlay_registers;
@@ -124,6 +138,21 @@ struct intel_free_graphics_memory {
//----------------------------------------------------------
// Register definitions, taken from X driver
#define INTEL_PAGE_TABLE_CONTROL 0x02020
#define INTEL_PAGE_TABLE_ERROR 0x02024
#define INTEL_HARDWARE_STATUS_PAGE 0x02080
#define INTEL_PRIMARY_RING_BUFFER 0x02030
#define INTEL_SECONDARY_RING_BUFFER_0 0x02100
#define INTEL_SECONDARY_RING_BUFFER_1 0x02110
// offsets for the ring buffer base registers above
#define RING_BUFFER_TAIL 0x0
#define RING_BUFFER_HEAD 0x4
#define RING_BUFFER_START 0x8
#define RING_BUFFER_CONTROL 0xc
#define INTEL_RING_BUFFER_SIZE_MASK 0x000ff800
#define INTEL_RING_BUFFER_ENABLED 1
#define INTEL_DISPLAY_HTOTAL 0x60000
#define INTEL_DISPLAY_HBLANK 0x60004
#define INTEL_DISPLAY_HSYNC 0x60008
@@ -175,6 +204,22 @@ struct intel_free_graphics_memory {
#define DISPLAY_MONITOR_POSITIVE_HSYNC (1UL << 3)
#define DISPLAY_MONITOR_POSITIVE_VSYNC (2UL << 3)
// ring buffer commands
#define COMMAND_NOOP 0x00
#define COMMAND_WAIT_FOR_EVENT (0x03 << 23)
#define COMMAND_WAIT_FOR_OVERLAY_FLIP (1 << 16)
#define COMMAND_FLUSH (0x04 << 23)
// overlay flip
#define COMMAND_OVERLAY_FLIP (0x11 << 23)
#define COMMAND_OVERLAY_CONTINUE (0 << 21)
#define COMMAND_OVERLAY_ON (1 << 21)
#define COMMAND_OVERLAY_OFF (2 << 21)
// overlay
#define INTEL_OVERLAY_UPDATE 0x30000
#define INTEL_OVERLAY_TEST 0x30004
#define INTEL_OVERLAY_STATUS 0x30008
@@ -232,14 +277,14 @@ struct overlay_registers {
overlay_scale scale_uv;
// (0x48) OCLRC0 - overlay color correction 0
uint32 _reserved1 : 5;
uint32 contrast_correction : 9;
uint32 contrast_correction : 9; // fixed point: 3.6 bits
uint32 _reserved2 : 10;
uint32 brightness_correction : 8;
uint32 brightness_correction : 8; // signed, -128 to 127
// (0x4c) OCLRC1 - overlay color correction 1
uint32 _reserved3 : 5;
uint32 saturation_sin_correction : 11;
uint32 saturation_sin_correction : 11; // signed fixed point: 3.7 bits
uint32 _reserved4 : 6;
uint32 saturation_cos_correction : 10;
uint32 saturation_cos_correction : 10; // fixed point: 3.7 bits
// (0x50) DCLRKV - destination color key value
uint32 _reserved5 : 8;
uint32 color_key_red : 8;
@@ -169,6 +169,8 @@ intel_init_accelerant(int device)
if (status != B_OK)
return status;
setup_ring_buffer(gInfo->shared_info->primary_ring_buffer, "intel primary ring buffer");
status = create_mode_list();
if (status != B_OK) {
uninit_common();
@@ -57,6 +57,9 @@ write32(uint32 offset, uint32 value)
extern void enable_display_plane(bool enable);
extern void set_display_power_mode(uint32 mode);
// engine.cpp
extern void setup_ring_buffer(ring_buffer &ringBuffer, const char *name);
// modes.cpp
extern status_t create_mode_list(void);
@@ -7,11 +7,11 @@
*/
#include "accelerant.h"
#include "accelerant_protos.h"
#include "intel_extreme.h"
//#define TRACE_ENGINE
#define TRACE_ENGINE
#ifdef TRACE_ENGINE
extern "C" void _sPrintf(const char *format, ...);
# define TRACE(x) _sPrintf x
@@ -23,6 +23,56 @@ extern "C" void _sPrintf(const char *format, ...);
static engine_token sEngineToken = {1, 0 /*B_2D_ACCELERATION*/, NULL};
/** The ring buffer must be locked when calling this function */
static inline void
write_to_ring(ring_buffer &ring, uint32 value)
{
uint32 *target = (uint32 *)(ring.base + ring.position);
*target = value;
ring.position = (ring.position + sizeof(uint32)) & (ring.size - 1);
}
/** The ring buffer must be locked when calling this function */
static inline void
ring_command_complete(ring_buffer &ring)
{
if (ring.position & 0x07) {
// make sure the command is properly aligned
write_to_ring(ring, COMMAND_NOOP);
}
write32(ring.register_base + RING_BUFFER_TAIL, ring.position);
}
void
setup_ring_buffer(ring_buffer &ringBuffer, const char *name)
{
TRACE(("Setup ring buffer %s, offset %lx, size %lx\n", name, ringBuffer.offset,
ringBuffer.size));
if (init_lock(&ringBuffer.lock, name) < B_OK) {
// disable ring buffer
ringBuffer.size = 0;
return;
}
uint32 ring = ringBuffer.register_base;
write32(ring + RING_BUFFER_TAIL, 0);
write32(ring + RING_BUFFER_START, ringBuffer.offset);
write32(ring + RING_BUFFER_CONTROL,
((ringBuffer.size - B_PAGE_SIZE) & INTEL_RING_BUFFER_SIZE_MASK)
| INTEL_RING_BUFFER_ENABLED);
}
// #pragma mark -
/** Return number of hardware engines */
uint32
@@ -22,6 +22,15 @@ extern "C" void _sPrintf(const char *format, ...);
#endif
static void
hide_overlay(void)
{
}
// #pragma mark -
uint32
intel_overlay_count(const display_mode *mode)
{
@@ -33,7 +42,8 @@ intel_overlay_count(const display_mode *mode)
const uint32 *
intel_overlay_supported_spaces(const display_mode *mode)
{
static const uint32 kSupportedSpaces[] = {B_YCbCr422, 0};
static const uint32 kSupportedSpaces[] = {B_RGB15, B_RGB16, B_RGB32,
/*B_YCbCr411,*/ B_YCbCr422, 0};
return kSupportedSpaces;
}
@@ -52,20 +62,20 @@ const overlay_buffer *
intel_allocate_overlay_buffer(color_space colorSpace, uint16 width,
uint16 height)
{
uint32 bpp;
uint32 bytesPerPixel;
switch (colorSpace) {
case B_RGB15:
bpp = 2;
bytesPerPixel = 2;
break;
case B_RGB16:
bpp = 2;
bytesPerPixel = 2;
break;
case B_RGB32:
bpp = 4;
bytesPerPixel = 4;
break;
case B_YCbCr422:
bpp = 2;
bytesPerPixel = 2;
break;
default:
return NULL;
@@ -83,7 +93,7 @@ intel_allocate_overlay_buffer(color_space colorSpace, uint16 width,
buffer->space = colorSpace;
buffer->width = width;
buffer->height = height;
buffer->bytes_per_row = (width * bpp + 0xf) & ~0xf;
buffer->bytes_per_row = (width * bytesPerPixel + 0xf) & ~0xf;
status_t status = intel_allocate_memory(buffer->bytes_per_row * height,
overlay->buffer_handle, overlay->buffer_offset);
@@ -204,6 +214,15 @@ status_t
intel_configure_overlay(overlay_token overlayToken, const overlay_buffer *buffer,
const overlay_window *window, const overlay_view *view)
{
if (overlayToken != (overlay_token)gInfo->shared_info->overlay_token)
return B_BAD_VALUE;
if (window == NULL && view == NULL) {
hide_overlay();
return B_OK;
}
return B_OK;
}
@@ -71,6 +71,20 @@ PhysicalMemoryMapper::Keep()
// #pragma mark -
static void
init_overlay_registers(overlay_registers *registers)
{
memset(registers, 0, B_PAGE_SIZE);
registers->contrast_correction = 0x20;
registers->saturation_cos_correction = 0x40;
// this by-passes contrast and saturation correction
}
// #pragma mark -
status_t
intel_extreme_init(intel_info &info)
{
@@ -130,6 +144,17 @@ intel_extreme_init(intel_info &info)
if (info.memory_manager == NULL)
return B_NO_MEMORY;
// reserve ring buffer memory (currently, this memory is placed in
// the graphics memory), but this could bring us problems with
// write combining...
ring_buffer &primary = info.shared_info->primary_ring_buffer;
if (mem_alloc(info.memory_manager, B_PAGE_SIZE, &info,
&primary.handle, &primary.offset) == B_OK) {
primary.register_base = INTEL_PRIMARY_RING_BUFFER;
primary.size = B_PAGE_SIZE;
primary.base = info.shared_info->graphics_memory + primary.offset;
}
// no errors, so keep mappings
graphicsMapper.Keep();
mmioMapper.Keep();
@@ -156,7 +181,10 @@ intel_extreme_init(intel_info &info)
#endif
// setup overlay registers
info.overlay_registers = (overlay_registers *)((addr_t)info.shared_info + B_PAGE_SIZE);
info.overlay_registers = (overlay_registers *)((uint8 *)info.shared_info
+ ROUND_TO_PAGE_SIZE(sizeof(intel_shared_info)));
init_overlay_registers(info.overlay_registers);
physical_entry physicalEntry;
get_memory_map(info.overlay_registers, sizeof(overlay_registers), &physicalEntry, 1);