diff --git a/headers/private/graphics/intel_extreme/intel_extreme.h b/headers/private/graphics/intel_extreme/intel_extreme.h index 964695e8e9..b83c8cc1b5 100644 --- a/headers/private/graphics/intel_extreme/intel_extreme.h +++ b/headers/private/graphics/intel_extreme/intel_extreme.h @@ -308,6 +308,29 @@ struct intel_free_graphics_memory { #define COMMAND_MODE_RGB16 0x01 #define COMMAND_MODE_RGB32 0x03 +// i2c + +#define INTEL_I2C_IO_A 0x5010 +#define INTEL_I2C_IO_B 0x5014 +#define INTEL_I2C_IO_C 0x5018 +#define INTEL_I2C_IO_D 0x501c +#define INTEL_I2C_IO_E 0x5020 +#define INTEL_I2C_IO_F 0x5024 +#define INTEL_I2C_IO_G 0x5028 +#define INTEL_I2C_IO_H 0x502c + +#define I2C_CLOCK_DIRECTION_MASK (1 << 0) +#define I2C_CLOCK_DIRECTION_OUT (1 << 1) +#define I2C_CLOCK_VALUE_MASK (1 << 2) +#define I2C_CLOCK_VALUE_OUT (1 << 3) +#define I2C_CLOCK_VALUE_IN (1 << 4) +#define I2C_DATA_DIRECTION_MASK (1 << 8) +#define I2C_DATA_DIRECTION_OUT (1 << 9) +#define I2C_DATA_VALUE_MASK (1 << 10) +#define I2C_DATA_VALUE_OUT (1 << 11) +#define I2C_DATA_VALUE_IN (1 << 12) +#define I2C_RESERVED ((1 << 13) | (1 << 5)) + // overlay #define INTEL_OVERLAY_UPDATE 0x30000 diff --git a/src/add-ons/accelerants/intel_extreme/Jamfile b/src/add-ons/accelerants/intel_extreme/Jamfile index 3bd9b9a0c4..e350fefd10 100644 --- a/src/add-ons/accelerants/intel_extreme/Jamfile +++ b/src/add-ons/accelerants/intel_extreme/Jamfile @@ -15,7 +15,7 @@ Addon intel_extreme.accelerant : memory.cpp mode.cpp overlay.cpp - : be + : be libaccelerantscommon.a ; Package haiku-intel_extreme-cvs : diff --git a/src/add-ons/accelerants/intel_extreme/mode.cpp b/src/add-ons/accelerants/intel_extreme/mode.cpp index 18cf7ede48..704af90413 100644 --- a/src/add-ons/accelerants/intel_extreme/mode.cpp +++ b/src/add-ons/accelerants/intel_extreme/mode.cpp @@ -18,6 +18,10 @@ #include #include +#include +#include + + #define TRACE_MODE #ifdef TRACE_MODE extern "C" void _sPrintf(const char *format, ...); @@ -107,6 +111,51 @@ static const uint32 kNumBaseModes = sizeof(kBaseModeList) / sizeof(display_mode) static const uint32 kMaxNumModes = kNumBaseModes * 4; +static status_t +get_i2c_signals(void* cookie, int* _clock, int* _data) +{ + uint32 ioRegister = (uint32)cookie; + uint32 value = read32(ioRegister); + + *_clock = (value & I2C_CLOCK_VALUE_IN) != 0; + *_data = (value & I2C_DATA_VALUE_IN) != 0; + + return B_OK; +} + + +static status_t +set_i2c_signals(void* cookie, int clock, int data) +{ + uint32 ioRegister = (uint32)cookie; + uint32 value; + + if (gInfo->shared_info->device_type == (INTEL_TYPE_8xx | INTEL_TYPE_83x)) { + // on these chips, the reserved values are fixed + value = 0; + } else { + // on all others, we have to preserve them manually + value = read32(ioRegister) & I2C_RESERVED; + } + + if (data != 0) + value |= I2C_DATA_DIRECTION_MASK; + else + value |= I2C_DATA_DIRECTION_MASK | I2C_DATA_DIRECTION_OUT | I2C_DATA_VALUE_MASK; + + if (clock != 0) + value |= I2C_CLOCK_DIRECTION_MASK; + else + value |= I2C_CLOCK_DIRECTION_MASK | I2C_CLOCK_DIRECTION_OUT | I2C_CLOCK_VALUE_MASK; + + write32(ioRegister, value); + read32(ioRegister); + // make sure the PCI bus has flushed the write + + return B_OK; +} + + /*! Creates the initial mode list of the primary accelerant. It's called from intel_init_accelerant(). @@ -143,6 +192,19 @@ create_mode_list(void) gInfo->shared_info->mode_list_area = gInfo->mode_list_area; gInfo->shared_info->mode_count = count; + edid1_info edid; + i2c_bus bus; + bus.cookie = (void*)INTEL_I2C_IO_A; + bus.set_signals = &set_i2c_signals; + bus.get_signals = &get_i2c_signals; + ddc2_init_timing(&bus); + + if (ddc2_read_edid1(&bus, &edid, NULL, NULL) == B_OK) { + edid_dump(&edid); + } else { + TRACE(("intel_extreme: getting EDID failed!\n")); + } + return B_OK; }