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:
@@ -9,6 +9,8 @@
|
|||||||
#define INTEL_EXTREME_H
|
#define INTEL_EXTREME_H
|
||||||
|
|
||||||
|
|
||||||
|
#include "lock.h"
|
||||||
|
|
||||||
#include <memory_manager.h>
|
#include <memory_manager.h>
|
||||||
|
|
||||||
#include <Accelerant.h>
|
#include <Accelerant.h>
|
||||||
@@ -38,6 +40,16 @@ struct pll_info {
|
|||||||
uint32 divisor_register;
|
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 overlay_registers;
|
||||||
|
|
||||||
struct intel_shared_info {
|
struct intel_shared_info {
|
||||||
@@ -57,6 +69,8 @@ struct intel_shared_info {
|
|||||||
|
|
||||||
uint32 frame_buffer_offset;
|
uint32 frame_buffer_offset;
|
||||||
|
|
||||||
|
ring_buffer primary_ring_buffer;
|
||||||
|
|
||||||
int32 overlay_channel_used;
|
int32 overlay_channel_used;
|
||||||
uint32 overlay_token;
|
uint32 overlay_token;
|
||||||
uint8* physical_overlay_registers;
|
uint8* physical_overlay_registers;
|
||||||
@@ -124,6 +138,21 @@ struct intel_free_graphics_memory {
|
|||||||
//----------------------------------------------------------
|
//----------------------------------------------------------
|
||||||
// Register definitions, taken from X driver
|
// 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_HTOTAL 0x60000
|
||||||
#define INTEL_DISPLAY_HBLANK 0x60004
|
#define INTEL_DISPLAY_HBLANK 0x60004
|
||||||
#define INTEL_DISPLAY_HSYNC 0x60008
|
#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_HSYNC (1UL << 3)
|
||||||
#define DISPLAY_MONITOR_POSITIVE_VSYNC (2UL << 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_UPDATE 0x30000
|
||||||
#define INTEL_OVERLAY_TEST 0x30004
|
#define INTEL_OVERLAY_TEST 0x30004
|
||||||
#define INTEL_OVERLAY_STATUS 0x30008
|
#define INTEL_OVERLAY_STATUS 0x30008
|
||||||
@@ -232,14 +277,14 @@ struct overlay_registers {
|
|||||||
overlay_scale scale_uv;
|
overlay_scale scale_uv;
|
||||||
// (0x48) OCLRC0 - overlay color correction 0
|
// (0x48) OCLRC0 - overlay color correction 0
|
||||||
uint32 _reserved1 : 5;
|
uint32 _reserved1 : 5;
|
||||||
uint32 contrast_correction : 9;
|
uint32 contrast_correction : 9; // fixed point: 3.6 bits
|
||||||
uint32 _reserved2 : 10;
|
uint32 _reserved2 : 10;
|
||||||
uint32 brightness_correction : 8;
|
uint32 brightness_correction : 8; // signed, -128 to 127
|
||||||
// (0x4c) OCLRC1 - overlay color correction 1
|
// (0x4c) OCLRC1 - overlay color correction 1
|
||||||
uint32 _reserved3 : 5;
|
uint32 _reserved3 : 5;
|
||||||
uint32 saturation_sin_correction : 11;
|
uint32 saturation_sin_correction : 11; // signed fixed point: 3.7 bits
|
||||||
uint32 _reserved4 : 6;
|
uint32 _reserved4 : 6;
|
||||||
uint32 saturation_cos_correction : 10;
|
uint32 saturation_cos_correction : 10; // fixed point: 3.7 bits
|
||||||
// (0x50) DCLRKV - destination color key value
|
// (0x50) DCLRKV - destination color key value
|
||||||
uint32 _reserved5 : 8;
|
uint32 _reserved5 : 8;
|
||||||
uint32 color_key_red : 8;
|
uint32 color_key_red : 8;
|
||||||
|
|||||||
@@ -169,6 +169,8 @@ intel_init_accelerant(int device)
|
|||||||
if (status != B_OK)
|
if (status != B_OK)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
|
setup_ring_buffer(gInfo->shared_info->primary_ring_buffer, "intel primary ring buffer");
|
||||||
|
|
||||||
status = create_mode_list();
|
status = create_mode_list();
|
||||||
if (status != B_OK) {
|
if (status != B_OK) {
|
||||||
uninit_common();
|
uninit_common();
|
||||||
|
|||||||
@@ -57,6 +57,9 @@ write32(uint32 offset, uint32 value)
|
|||||||
extern void enable_display_plane(bool enable);
|
extern void enable_display_plane(bool enable);
|
||||||
extern void set_display_power_mode(uint32 mode);
|
extern void set_display_power_mode(uint32 mode);
|
||||||
|
|
||||||
|
// engine.cpp
|
||||||
|
extern void setup_ring_buffer(ring_buffer &ringBuffer, const char *name);
|
||||||
|
|
||||||
// modes.cpp
|
// modes.cpp
|
||||||
extern status_t create_mode_list(void);
|
extern status_t create_mode_list(void);
|
||||||
|
|
||||||
|
|||||||
@@ -7,11 +7,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "accelerant.h"
|
||||||
#include "accelerant_protos.h"
|
#include "accelerant_protos.h"
|
||||||
#include "intel_extreme.h"
|
|
||||||
|
|
||||||
|
|
||||||
//#define TRACE_ENGINE
|
#define TRACE_ENGINE
|
||||||
#ifdef TRACE_ENGINE
|
#ifdef TRACE_ENGINE
|
||||||
extern "C" void _sPrintf(const char *format, ...);
|
extern "C" void _sPrintf(const char *format, ...);
|
||||||
# define TRACE(x) _sPrintf x
|
# 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};
|
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 */
|
/** Return number of hardware engines */
|
||||||
|
|
||||||
uint32
|
uint32
|
||||||
|
|||||||
@@ -22,6 +22,15 @@ extern "C" void _sPrintf(const char *format, ...);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
hide_overlay(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
uint32
|
uint32
|
||||||
intel_overlay_count(const display_mode *mode)
|
intel_overlay_count(const display_mode *mode)
|
||||||
{
|
{
|
||||||
@@ -33,7 +42,8 @@ intel_overlay_count(const display_mode *mode)
|
|||||||
const uint32 *
|
const uint32 *
|
||||||
intel_overlay_supported_spaces(const display_mode *mode)
|
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;
|
return kSupportedSpaces;
|
||||||
}
|
}
|
||||||
@@ -52,20 +62,20 @@ const overlay_buffer *
|
|||||||
intel_allocate_overlay_buffer(color_space colorSpace, uint16 width,
|
intel_allocate_overlay_buffer(color_space colorSpace, uint16 width,
|
||||||
uint16 height)
|
uint16 height)
|
||||||
{
|
{
|
||||||
uint32 bpp;
|
uint32 bytesPerPixel;
|
||||||
|
|
||||||
switch (colorSpace) {
|
switch (colorSpace) {
|
||||||
case B_RGB15:
|
case B_RGB15:
|
||||||
bpp = 2;
|
bytesPerPixel = 2;
|
||||||
break;
|
break;
|
||||||
case B_RGB16:
|
case B_RGB16:
|
||||||
bpp = 2;
|
bytesPerPixel = 2;
|
||||||
break;
|
break;
|
||||||
case B_RGB32:
|
case B_RGB32:
|
||||||
bpp = 4;
|
bytesPerPixel = 4;
|
||||||
break;
|
break;
|
||||||
case B_YCbCr422:
|
case B_YCbCr422:
|
||||||
bpp = 2;
|
bytesPerPixel = 2;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -83,7 +93,7 @@ intel_allocate_overlay_buffer(color_space colorSpace, uint16 width,
|
|||||||
buffer->space = colorSpace;
|
buffer->space = colorSpace;
|
||||||
buffer->width = width;
|
buffer->width = width;
|
||||||
buffer->height = height;
|
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,
|
status_t status = intel_allocate_memory(buffer->bytes_per_row * height,
|
||||||
overlay->buffer_handle, overlay->buffer_offset);
|
overlay->buffer_handle, overlay->buffer_offset);
|
||||||
@@ -204,6 +214,15 @@ status_t
|
|||||||
intel_configure_overlay(overlay_token overlayToken, const overlay_buffer *buffer,
|
intel_configure_overlay(overlay_token overlayToken, const overlay_buffer *buffer,
|
||||||
const overlay_window *window, const overlay_view *view)
|
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;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -71,6 +71,20 @@ PhysicalMemoryMapper::Keep()
|
|||||||
// #pragma mark -
|
// #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
|
status_t
|
||||||
intel_extreme_init(intel_info &info)
|
intel_extreme_init(intel_info &info)
|
||||||
{
|
{
|
||||||
@@ -130,6 +144,17 @@ intel_extreme_init(intel_info &info)
|
|||||||
if (info.memory_manager == NULL)
|
if (info.memory_manager == NULL)
|
||||||
return B_NO_MEMORY;
|
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
|
// no errors, so keep mappings
|
||||||
graphicsMapper.Keep();
|
graphicsMapper.Keep();
|
||||||
mmioMapper.Keep();
|
mmioMapper.Keep();
|
||||||
@@ -156,7 +181,10 @@ intel_extreme_init(intel_info &info)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// setup overlay registers
|
// 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;
|
physical_entry physicalEntry;
|
||||||
get_memory_map(info.overlay_registers, sizeof(overlay_registers), &physicalEntry, 1);
|
get_memory_map(info.overlay_registers, sizeof(overlay_registers), &physicalEntry, 1);
|
||||||
|
|||||||
Reference in New Issue
Block a user