diff --git a/src/add-ons/accelerants/radeon_hd/Jamfile b/src/add-ons/accelerants/radeon_hd/Jamfile index f72e18bd76..91a46e6092 100644 --- a/src/add-ons/accelerants/radeon_hd/Jamfile +++ b/src/add-ons/accelerants/radeon_hd/Jamfile @@ -12,8 +12,9 @@ UsePrivateHeaders [ FDirName graphics common ] ; Addon radeon_hd.accelerant : accelerant.cpp atom.cpp - create_display_modes.cpp bios.cpp + connector.cpp + create_display_modes.cpp display.cpp encoder.cpp engine.cpp diff --git a/src/add-ons/accelerants/radeon_hd/accelerant.cpp b/src/add-ons/accelerants/radeon_hd/accelerant.cpp index 94d50f319c..f8df10428a 100644 --- a/src/add-ons/accelerants/radeon_hd/accelerant.cpp +++ b/src/add-ons/accelerants/radeon_hd/accelerant.cpp @@ -12,6 +12,7 @@ #include "accelerant.h" #include "bios.h" +#include "connector.h" #include "display.h" #include "gpu.h" #include "pll.h" @@ -252,7 +253,7 @@ radeon_init_accelerant(int device) radeon_init_bios(gInfo->rom); // detect GPIO pins - radeon_gpu_gpio_setup(); + gpio_probe(); // detect physical connectors status = detect_connectors(); diff --git a/src/add-ons/accelerants/radeon_hd/connector.cpp b/src/add-ons/accelerants/radeon_hd/connector.cpp new file mode 100644 index 0000000000..64f726a278 --- /dev/null +++ b/src/add-ons/accelerants/radeon_hd/connector.cpp @@ -0,0 +1,357 @@ +/* + * Copyright 2006-2011, Haiku, Inc. All Rights Reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Alexander von Gluck, kallisti5@unixzen.com + */ + + +#include "accelerant_protos.h" +#include "accelerant.h" +#include "bios.h" +#include "connector.h" +#include "gpu.h" +#include "utility.h" + +#include + + +#undef TRACE + +#define TRACE_CONNECTOR +#ifdef TRACE_CONNECTOR +# define TRACE(x...) _sPrintf("radeon_hd: " x) +#else +# define TRACE(x...) ; +#endif + +#define ERROR(x...) _sPrintf("radeon_hd: " x) + + +static void +gpio_lock_i2c(void* cookie, bool lock) +{ + gpio_info *info = (gpio_info*)cookie; + radeon_shared_info &sinfo = *gInfo->shared_info; + + uint32 buffer = 0; + + if (lock == true) { + // hw_capable and > DCE3 + if (info->hw_capable == true + && sinfo.dceMajor >= 3) { + // Switch GPIO pads to ddc mode + buffer = Read32(OUT, info->mask_scl_reg); + buffer &= ~(1 << 16); + Write32(OUT, info->mask_scl_reg, buffer); + } + + // Clear pins + buffer = Read32(OUT, info->a_scl_reg) & ~info->a_scl_mask; + Write32(OUT, info->a_scl_reg, buffer); + buffer = Read32(OUT, info->a_sda_reg) & ~info->a_sda_mask; + Write32(OUT, info->a_sda_reg, buffer); + } + + // Set pins to input + buffer = Read32(OUT, info->en_scl_reg) & ~info->en_scl_mask; + Write32(OUT, info->en_scl_reg, buffer); + buffer = Read32(OUT, info->en_sda_reg) & ~info->en_sda_mask; + Write32(OUT, info->en_sda_reg, buffer); + + // mask GPIO pins for software use + buffer = Read32(OUT, info->mask_scl_reg); + if (lock == true) { + buffer |= info->mask_scl_mask; + } else { + buffer &= ~info->mask_scl_mask; + } + Write32(OUT, info->mask_scl_reg, buffer); + Read32(OUT, info->mask_scl_reg); + + buffer = Read32(OUT, info->mask_sda_reg); + if (lock == true) { + buffer |= info->mask_sda_mask; + } else { + buffer &= ~info->mask_sda_mask; + } + Write32(OUT, info->mask_sda_reg, buffer); + Read32(OUT, info->mask_sda_reg); +} + + +static status_t +gpio_get_i2c_bit(void* cookie, int* _clock, int* _data) +{ + gpio_info *info = (gpio_info*)cookie; + + uint32 scl = Read32(OUT, info->y_scl_reg) + & info->y_scl_mask; + uint32 sda = Read32(OUT, info->y_sda_reg) + & info->y_sda_mask; + + *_clock = (scl != 0); + *_data = (sda != 0); + + return B_OK; +} + + +static status_t +gpio_set_i2c_bit(void* cookie, int clock, int data) +{ + gpio_info* info = (gpio_info*)cookie; + + uint32 scl = Read32(OUT, info->en_scl_reg) + & ~info->en_scl_mask; + scl |= clock ? 0 : info->en_scl_mask; + Write32(OUT, info->en_scl_reg, scl); + Read32(OUT, info->en_scl_reg); + + uint32 sda = Read32(OUT, info->en_sda_reg) + & ~info->en_sda_mask; + sda |= data ? 0 : info->en_sda_mask; + Write32(OUT, info->en_sda_reg, sda); + Read32(OUT, info->en_sda_reg); + + return B_OK; +} + + +bool +connector_read_edid(uint32 connector, edid1_info *edid) +{ + // ensure things are sane + uint32 gpioID = gConnector[connector]->gpioID; + if (gGPIOInfo[gpioID]->valid == false) + return false; + + if (gConnector[connector]->type == VIDEO_CONNECTOR_LVDS) { + // we should call connector_read_edid_lvds at some point + ERROR("%s: LCD panel detected (LVDS), sending VESA EDID!\n", + __func__); + memcpy(edid, &gInfo->shared_info->edid_info, sizeof(struct edid1_info)); + return true; + } + + i2c_bus bus; + + ddc2_init_timing(&bus); + bus.cookie = (void*)gGPIOInfo[gpioID]; + bus.set_signals = &gpio_set_i2c_bit; + bus.get_signals = &gpio_get_i2c_bit; + + gpio_lock_i2c(bus.cookie, true); + status_t edid_result = ddc2_read_edid1(&bus, edid, NULL, NULL); + gpio_lock_i2c(bus.cookie, false); + + if (edid_result != B_OK) + return false; + + TRACE("%s: found edid monitor on connector #%" B_PRId32 "\n", + __func__, connector); + + return true; +} + + +#if 0 +bool +connector_read_edid_lvds(uint32 connector, edid1_info *edid) +{ + uint8 dceMajor; + uint8 dceMinor; + int index = GetIndexIntoMasterTable(DATA, LVDS_Info); + uint16 offset; + + if (atom_parse_data_header(gAtomContexg, index, NULL, + &dceMajor, &dceMinor, &offset) == B_OK) { + lvdsInfo = (union lvds_info *)(gAtomContext->bios + offset); + + display_timing timing; + // Pixel Clock + timing.pixel_clock + = B_LENDIAN_TO_HOST_INT16(lvdsInfo->info.sLCDTiming.usPixClk) * 10; + // Horizontal + timing.h_display + = B_LENDIAN_TO_HOST_INT16(lvdsInfo->info.sLCDTiming.usHActive); + timing.h_total = timing.h_display + B_LENDIAN_TO_HOST_INT16( + lvdsInfo->info.sLCDTiming.usHBlanking_Time); + timing.h_sync_start = timing.h_display + + B_LENDIAN_TO_HOST_INT16(lvdsInfo->info.sLCDTiming.usHSyncOffset); + timing.h_sync_end = timing.h_sync_start + + B_LENDIAN_TO_HOST_INT16(lvdsInfo->info.sLCDTiming.usHSyncWidth); + // Vertical + timing.v_display + = B_LENDIAN_TO_HOST_INT16(lvdsInfo->info.sLCDTiming.usVActive); + timing.v_total = timing.v_display + B_LENDIAN_TO_HOST_INT16( + lvdsInfo->info.sLCDTiming.usVBlanking_Time); + timing.v_sync_start = timing.v_display + + B_LENDIAN_TO_HOST_INT16(lvdsInfo->info.sLCDTiming.usVSyncOffset); + timing.v_sync_end = timing.v_sync_start + + B_LENDIAN_TO_HOST_INT16(lvdsInfo->info.sLCDTiming.usVSyncWidth); + + #if 0 + // Who cares. + uint32 powerDelay + = B_LENDIAN_TO_HOST_INT16(lvdsInfo->info.usOffDelayInMs); + uint32 lcdMisc = lvdsInfo->info.ucLVDS_Misc; + #endif + + uint16 flags = B_LENDIAN_TO_HOST_INT16( + lvdsInfo->info.sLCDTiming.susModeMiscInfo.usAccess); + + if ((flags & ATOM_VSYNC_POLARITY) == 0) + timing.flags |= B_POSITIVE_VSYNC; + if ((flags & ATOM_HSYNC_POLARITY) == 0) + timing.flags |= B_POSITIVE_HSYNC; + + // Extra flags + if ((flags & ATOM_INTERLACE) != 0) + timing.flags |= B_TIMING_INTERLACED; + + #if 0 + // We don't use these timing flags at the moment + if ((flags & ATOM_COMPOSITESYNC) != 0) + timing.flags |= MODE_FLAG_CSYNC; + if ((flags & ATOM_DOUBLE_CLOCK_MODE) != 0) + timing.flags |= MODE_FLAG_DBLSCAN; + #endif + + // TODO: generate a fake EDID with information above + } +} +#endif + + +status_t +connector_attach_gpio(uint32 id, uint8 hw_line) +{ + gConnector[id]->gpioID = 0; + for (uint32 i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) { + if (gGPIOInfo[i]->hw_line != hw_line) + continue; + gConnector[id]->gpioID = i; + return B_OK; + } + + TRACE("%s: couldn't find GPIO for connector %" B_PRIu32 "\n", + __func__, id); + return B_ERROR; +} + + +status_t +gpio_probe() +{ + radeon_shared_info &info = *gInfo->shared_info; + + int index = GetIndexIntoMasterTable(DATA, GPIO_I2C_Info); + + uint8 tableMajor; + uint8 tableMinor; + uint16 tableOffset; + uint16 tableSize; + + if (atom_parse_data_header(gAtomContext, index, &tableSize, + &tableMajor, &tableMinor, &tableOffset) != B_OK) { + ERROR("%s: could't read GPIO_I2C_Info table from AtomBIOS index %d!\n", + __func__, index); + return B_ERROR; + } + + struct _ATOM_GPIO_I2C_INFO *i2c_info + = (struct _ATOM_GPIO_I2C_INFO *)(gAtomContext->bios + tableOffset); + + uint32 numIndices = (tableSize - sizeof(ATOM_COMMON_TABLE_HEADER)) + / sizeof(ATOM_GPIO_I2C_ASSIGMENT); + + if (numIndices > ATOM_MAX_SUPPORTED_DEVICE) { + ERROR("%s: ERROR: AtomBIOS contains more GPIO_Info items then I" + "was prepared for! (seen: %" B_PRIu32 "; max: %" B_PRIu32 ")\n", + __func__, numIndices, (uint32)ATOM_MAX_SUPPORTED_DEVICE); + return B_ERROR; + } + + for (uint32 i = 0; i < numIndices; i++) { + ATOM_GPIO_I2C_ASSIGMENT *gpio = &i2c_info->asGPIO_Info[i]; + + if (info.dceMajor >= 3) { + if (i == 4 && B_LENDIAN_TO_HOST_INT16(gpio->usClkMaskRegisterIndex) + == 0x1fda && gpio->sucI2cId.ucAccess == 0x94) { + gpio->sucI2cId.ucAccess = 0x14; + TRACE("%s: BUG: GPIO override for DCE 3 occured\n", __func__); + } + } + + if (info.dceMajor >= 4) { + if (i == 7 && B_LENDIAN_TO_HOST_INT16(gpio->usClkMaskRegisterIndex) + == 0x1936 && gpio->sucI2cId.ucAccess == 0) { + gpio->sucI2cId.ucAccess = 0x97; + gpio->ucDataMaskShift = 8; + gpio->ucDataEnShift = 8; + gpio->ucDataY_Shift = 8; + gpio->ucDataA_Shift = 8; + TRACE("%s: BUG: GPIO override for DCE 4 occured\n", __func__); + } + } + + // populate gpio information + gGPIOInfo[i]->hw_line + = gpio->sucI2cId.ucAccess; + gGPIOInfo[i]->hw_capable + = (gpio->sucI2cId.sbfAccess.bfHW_Capable) ? true : false; + + // GPIO mask (Allows software to control the GPIO pad) + // 0 = chip access; 1 = only software; + gGPIOInfo[i]->mask_scl_reg + = B_LENDIAN_TO_HOST_INT16(gpio->usClkMaskRegisterIndex) * 4; + gGPIOInfo[i]->mask_sda_reg + = B_LENDIAN_TO_HOST_INT16(gpio->usDataMaskRegisterIndex) * 4; + gGPIOInfo[i]->mask_scl_mask + = (1 << gpio->ucClkMaskShift); + gGPIOInfo[i]->mask_sda_mask + = (1 << gpio->ucDataMaskShift); + + // GPIO output / write (A) enable + // 0 = GPIO input (Y); 1 = GPIO output (A); + gGPIOInfo[i]->en_scl_reg + = B_LENDIAN_TO_HOST_INT16(gpio->usClkEnRegisterIndex) * 4; + gGPIOInfo[i]->en_sda_reg + = B_LENDIAN_TO_HOST_INT16(gpio->usDataEnRegisterIndex) * 4; + gGPIOInfo[i]->en_scl_mask + = (1 << gpio->ucClkEnShift); + gGPIOInfo[i]->en_sda_mask + = (1 << gpio->ucDataEnShift); + + // GPIO output / write (A) + gGPIOInfo[i]->a_scl_reg + = B_LENDIAN_TO_HOST_INT16(gpio->usClkA_RegisterIndex) * 4; + gGPIOInfo[i]->a_sda_reg + = B_LENDIAN_TO_HOST_INT16(gpio->usDataA_RegisterIndex) * 4; + gGPIOInfo[i]->a_scl_mask + = (1 << gpio->ucClkA_Shift); + gGPIOInfo[i]->a_sda_mask + = (1 << gpio->ucDataA_Shift); + + // GPIO input / read (Y) + gGPIOInfo[i]->y_scl_reg + = B_LENDIAN_TO_HOST_INT16(gpio->usClkY_RegisterIndex) * 4; + gGPIOInfo[i]->y_sda_reg + = B_LENDIAN_TO_HOST_INT16(gpio->usDataY_RegisterIndex) * 4; + gGPIOInfo[i]->y_scl_mask + = (1 << gpio->ucClkY_Shift); + gGPIOInfo[i]->y_sda_mask + = (1 << gpio->ucDataY_Shift); + + // ensure data is valid + gGPIOInfo[i]->valid = (gGPIOInfo[i]->mask_scl_reg) ? true : false; + + TRACE("%s: GPIO @ %" B_PRIu32 ", valid: %s, hw_line: 0x%" B_PRIX32 "\n", + __func__, i, gGPIOInfo[i]->valid ? "true" : "false", + gGPIOInfo[i]->hw_line); + } + + return B_OK; +} diff --git a/src/add-ons/accelerants/radeon_hd/connector.h b/src/add-ons/accelerants/radeon_hd/connector.h new file mode 100644 index 0000000000..6f24ab8386 --- /dev/null +++ b/src/add-ons/accelerants/radeon_hd/connector.h @@ -0,0 +1,15 @@ +/* + * Copyright 2006-2011, Haiku, Inc. All Rights Reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Alexander von Gluck, kallisti5@unixzen.com + */ +#ifndef RADEON_HD_CONNECTOR_H +#define RADEON_HD_CONNECTOR_H + +status_t gpio_probe(); +status_t connector_attach_gpio(uint32 id, uint8 hw_line); +bool connector_read_edid(uint32 connector, edid1_info *edid); + +#endif diff --git a/src/add-ons/accelerants/radeon_hd/display.cpp b/src/add-ons/accelerants/radeon_hd/display.cpp index 221cbb2c88..f1f0a37eae 100644 --- a/src/add-ons/accelerants/radeon_hd/display.cpp +++ b/src/add-ons/accelerants/radeon_hd/display.cpp @@ -15,6 +15,7 @@ #include "accelerant_protos.h" #include "accelerant.h" #include "bios.h" +#include "connector.h" #include "display.h" #include @@ -322,7 +323,7 @@ detect_connectors_legacy() gConnector[connectorIndex]->encoder.isExternal = encoder_is_external(encoderID); - radeon_gpu_i2c_attach(connectorIndex, ci.sucI2cId.ucAccess); + connector_attach_gpio(connectorIndex, ci.sucI2cId.ucAccess); pll_limit_probe(&gConnector[connectorIndex]->encoder.pll); @@ -558,7 +559,7 @@ detect_connectors() = (ATOM_I2C_ID_CONFIG_ACCESS *) &i2c_record->sucI2cId; // attach i2c gpio information for connector - radeon_gpu_i2c_attach(connectorIndex, + connector_attach_gpio(connectorIndex, i2c_config->ucAccess); break; case ATOM_HPD_INT_RECORD_TYPE: @@ -625,7 +626,7 @@ detect_displays() if (displayIndex >= MAX_DISPLAY) continue; - if (radeon_gpu_read_edid(id, &gDisplay[displayIndex]->edid_info)) { + if (connector_read_edid(id, &gDisplay[displayIndex]->edid_info)) { if (gConnector[id]->encoder.type == VIDEO_ENCODER_TVDAC || gConnector[id]->encoder.type == VIDEO_ENCODER_DAC) { diff --git a/src/add-ons/accelerants/radeon_hd/gpu.cpp b/src/add-ons/accelerants/radeon_hd/gpu.cpp index 12e80aadaf..5fec816013 100644 --- a/src/add-ons/accelerants/radeon_hd/gpu.cpp +++ b/src/add-ons/accelerants/radeon_hd/gpu.cpp @@ -523,331 +523,3 @@ radeon_gpu_irq_setup() return B_ERROR; } - - -static void -lock_i2c(void* cookie, bool lock) -{ - gpio_info *info = (gpio_info*)cookie; - radeon_shared_info &sinfo = *gInfo->shared_info; - - uint32 buffer = 0; - - if (lock == true) { - // hw_capable and > DCE3 - if (info->hw_capable == true - && sinfo.dceMajor >= 3) { - // Switch GPIO pads to ddc mode - buffer = Read32(OUT, info->mask_scl_reg); - buffer &= ~(1 << 16); - Write32(OUT, info->mask_scl_reg, buffer); - } - - // Clear pins - buffer = Read32(OUT, info->a_scl_reg) & ~info->a_scl_mask; - Write32(OUT, info->a_scl_reg, buffer); - buffer = Read32(OUT, info->a_sda_reg) & ~info->a_sda_mask; - Write32(OUT, info->a_sda_reg, buffer); - } - - // Set pins to input - buffer = Read32(OUT, info->en_scl_reg) & ~info->en_scl_mask; - Write32(OUT, info->en_scl_reg, buffer); - buffer = Read32(OUT, info->en_sda_reg) & ~info->en_sda_mask; - Write32(OUT, info->en_sda_reg, buffer); - - // mask GPIO pins for software use - buffer = Read32(OUT, info->mask_scl_reg); - if (lock == true) { - buffer |= info->mask_scl_mask; - } else { - buffer &= ~info->mask_scl_mask; - } - Write32(OUT, info->mask_scl_reg, buffer); - Read32(OUT, info->mask_scl_reg); - - buffer = Read32(OUT, info->mask_sda_reg); - if (lock == true) { - buffer |= info->mask_sda_mask; - } else { - buffer &= ~info->mask_sda_mask; - } - Write32(OUT, info->mask_sda_reg, buffer); - Read32(OUT, info->mask_sda_reg); -} - - -static status_t -get_i2c_signals(void* cookie, int* _clock, int* _data) -{ - gpio_info *info = (gpio_info*)cookie; - - uint32 scl = Read32(OUT, info->y_scl_reg) - & info->y_scl_mask; - uint32 sda = Read32(OUT, info->y_sda_reg) - & info->y_sda_mask; - - *_clock = (scl != 0); - *_data = (sda != 0); - - return B_OK; -} - - -static status_t -set_i2c_signals(void* cookie, int clock, int data) -{ - gpio_info* info = (gpio_info*)cookie; - - uint32 scl = Read32(OUT, info->en_scl_reg) - & ~info->en_scl_mask; - scl |= clock ? 0 : info->en_scl_mask; - Write32(OUT, info->en_scl_reg, scl); - Read32(OUT, info->en_scl_reg); - - uint32 sda = Read32(OUT, info->en_sda_reg) - & ~info->en_sda_mask; - sda |= data ? 0 : info->en_sda_mask; - Write32(OUT, info->en_sda_reg, sda); - Read32(OUT, info->en_sda_reg); - - return B_OK; -} - - -bool -radeon_gpu_read_edid(uint32 connector, edid1_info *edid) -{ - // ensure things are sane - uint32 gpioID = gConnector[connector]->gpioID; - if (gGPIOInfo[gpioID]->valid == false) - return false; - - if (gConnector[connector]->type == VIDEO_CONNECTOR_LVDS) { - // we should call radeon_gpu_read_edid_lvds at some point - ERROR("%s: LCD panel detected (LVDS), sending VESA EDID!\n", - __func__); - memcpy(edid, &gInfo->shared_info->edid_info, sizeof(struct edid1_info)); - return true; - } - - i2c_bus bus; - - ddc2_init_timing(&bus); - bus.cookie = (void*)gGPIOInfo[gpioID]; - bus.set_signals = &set_i2c_signals; - bus.get_signals = &get_i2c_signals; - - lock_i2c(bus.cookie, true); - status_t edid_result = ddc2_read_edid1(&bus, edid, NULL, NULL); - lock_i2c(bus.cookie, false); - - if (edid_result != B_OK) - return false; - - TRACE("%s: found edid monitor on connector #%" B_PRId32 "\n", - __func__, connector); - - return true; -} - - -#if 0 -bool -radeon_gpu_read_edid_lvds(uint32 connector, edid1_info *edid) -{ - uint8 dceMajor; - uint8 dceMinor; - int index = GetIndexIntoMasterTable(DATA, LVDS_Info); - uint16 offset; - - if (atom_parse_data_header(gAtomContexg, index, NULL, - &dceMajor, &dceMinor, &offset) == B_OK) { - lvdsInfo = (union lvds_info *)(gAtomContext->bios + offset); - - display_timing timing; - // Pixel Clock - timing.pixel_clock - = B_LENDIAN_TO_HOST_INT16(lvdsInfo->info.sLCDTiming.usPixClk) * 10; - // Horizontal - timing.h_display - = B_LENDIAN_TO_HOST_INT16(lvdsInfo->info.sLCDTiming.usHActive); - timing.h_total = timing.h_display + B_LENDIAN_TO_HOST_INT16( - lvdsInfo->info.sLCDTiming.usHBlanking_Time); - timing.h_sync_start = timing.h_display - + B_LENDIAN_TO_HOST_INT16(lvdsInfo->info.sLCDTiming.usHSyncOffset); - timing.h_sync_end = timing.h_sync_start - + B_LENDIAN_TO_HOST_INT16(lvdsInfo->info.sLCDTiming.usHSyncWidth); - // Vertical - timing.v_display - = B_LENDIAN_TO_HOST_INT16(lvdsInfo->info.sLCDTiming.usVActive); - timing.v_total = timing.v_display + B_LENDIAN_TO_HOST_INT16( - lvdsInfo->info.sLCDTiming.usVBlanking_Time); - timing.v_sync_start = timing.v_display - + B_LENDIAN_TO_HOST_INT16(lvdsInfo->info.sLCDTiming.usVSyncOffset); - timing.v_sync_end = timing.v_sync_start - + B_LENDIAN_TO_HOST_INT16(lvdsInfo->info.sLCDTiming.usVSyncWidth); - - #if 0 - // Who cares. - uint32 powerDelay - = B_LENDIAN_TO_HOST_INT16(lvdsInfo->info.usOffDelayInMs); - uint32 lcdMisc = lvdsInfo->info.ucLVDS_Misc; - #endif - - uint16 flags = B_LENDIAN_TO_HOST_INT16( - lvdsInfo->info.sLCDTiming.susModeMiscInfo.usAccess); - - if ((flags & ATOM_VSYNC_POLARITY) == 0) - timing.flags |= B_POSITIVE_VSYNC; - if ((flags & ATOM_HSYNC_POLARITY) == 0) - timing.flags |= B_POSITIVE_HSYNC; - - // Extra flags - if ((flags & ATOM_INTERLACE) != 0) - timing.flags |= B_TIMING_INTERLACED; - - #if 0 - // We don't use these timing flags at the moment - if ((flags & ATOM_COMPOSITESYNC) != 0) - timing.flags |= MODE_FLAG_CSYNC; - if ((flags & ATOM_DOUBLE_CLOCK_MODE) != 0) - timing.flags |= MODE_FLAG_DBLSCAN; - #endif - - // TODO: generate a fake EDID with information above - } -} -#endif - - -status_t -radeon_gpu_i2c_attach(uint32 id, uint8 hw_line) -{ - gConnector[id]->gpioID = 0; - for (uint32 i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) { - if (gGPIOInfo[i]->hw_line != hw_line) - continue; - gConnector[id]->gpioID = i; - return B_OK; - } - - TRACE("%s: couldn't find GPIO for connector %" B_PRIu32 "\n", - __func__, id); - return B_ERROR; -} - - -status_t -radeon_gpu_gpio_setup() -{ - radeon_shared_info &info = *gInfo->shared_info; - - int index = GetIndexIntoMasterTable(DATA, GPIO_I2C_Info); - - uint8 tableMajor; - uint8 tableMinor; - uint16 tableOffset; - uint16 tableSize; - - if (atom_parse_data_header(gAtomContext, index, &tableSize, - &tableMajor, &tableMinor, &tableOffset) != B_OK) { - ERROR("%s: could't read GPIO_I2C_Info table from AtomBIOS index %d!\n", - __func__, index); - return B_ERROR; - } - - struct _ATOM_GPIO_I2C_INFO *i2c_info - = (struct _ATOM_GPIO_I2C_INFO *)(gAtomContext->bios + tableOffset); - - uint32 numIndices = (tableSize - sizeof(ATOM_COMMON_TABLE_HEADER)) - / sizeof(ATOM_GPIO_I2C_ASSIGMENT); - - if (numIndices > ATOM_MAX_SUPPORTED_DEVICE) { - ERROR("%s: ERROR: AtomBIOS contains more GPIO_Info items then I" - "was prepared for! (seen: %" B_PRIu32 "; max: %" B_PRIu32 ")\n", - __func__, numIndices, (uint32)ATOM_MAX_SUPPORTED_DEVICE); - return B_ERROR; - } - - for (uint32 i = 0; i < numIndices; i++) { - ATOM_GPIO_I2C_ASSIGMENT *gpio = &i2c_info->asGPIO_Info[i]; - - if (info.dceMajor >= 3) { - if (i == 4 && B_LENDIAN_TO_HOST_INT16(gpio->usClkMaskRegisterIndex) - == 0x1fda && gpio->sucI2cId.ucAccess == 0x94) { - gpio->sucI2cId.ucAccess = 0x14; - TRACE("%s: BUG: GPIO override for DCE 3 occured\n", __func__); - } - } - - if (info.dceMajor >= 4) { - if (i == 7 && B_LENDIAN_TO_HOST_INT16(gpio->usClkMaskRegisterIndex) - == 0x1936 && gpio->sucI2cId.ucAccess == 0) { - gpio->sucI2cId.ucAccess = 0x97; - gpio->ucDataMaskShift = 8; - gpio->ucDataEnShift = 8; - gpio->ucDataY_Shift = 8; - gpio->ucDataA_Shift = 8; - TRACE("%s: BUG: GPIO override for DCE 4 occured\n", __func__); - } - } - - // populate gpio information - gGPIOInfo[i]->hw_line - = gpio->sucI2cId.ucAccess; - gGPIOInfo[i]->hw_capable - = (gpio->sucI2cId.sbfAccess.bfHW_Capable) ? true : false; - - // GPIO mask (Allows software to control the GPIO pad) - // 0 = chip access; 1 = only software; - gGPIOInfo[i]->mask_scl_reg - = B_LENDIAN_TO_HOST_INT16(gpio->usClkMaskRegisterIndex) * 4; - gGPIOInfo[i]->mask_sda_reg - = B_LENDIAN_TO_HOST_INT16(gpio->usDataMaskRegisterIndex) * 4; - gGPIOInfo[i]->mask_scl_mask - = (1 << gpio->ucClkMaskShift); - gGPIOInfo[i]->mask_sda_mask - = (1 << gpio->ucDataMaskShift); - - // GPIO output / write (A) enable - // 0 = GPIO input (Y); 1 = GPIO output (A); - gGPIOInfo[i]->en_scl_reg - = B_LENDIAN_TO_HOST_INT16(gpio->usClkEnRegisterIndex) * 4; - gGPIOInfo[i]->en_sda_reg - = B_LENDIAN_TO_HOST_INT16(gpio->usDataEnRegisterIndex) * 4; - gGPIOInfo[i]->en_scl_mask - = (1 << gpio->ucClkEnShift); - gGPIOInfo[i]->en_sda_mask - = (1 << gpio->ucDataEnShift); - - // GPIO output / write (A) - gGPIOInfo[i]->a_scl_reg - = B_LENDIAN_TO_HOST_INT16(gpio->usClkA_RegisterIndex) * 4; - gGPIOInfo[i]->a_sda_reg - = B_LENDIAN_TO_HOST_INT16(gpio->usDataA_RegisterIndex) * 4; - gGPIOInfo[i]->a_scl_mask - = (1 << gpio->ucClkA_Shift); - gGPIOInfo[i]->a_sda_mask - = (1 << gpio->ucDataA_Shift); - - // GPIO input / read (Y) - gGPIOInfo[i]->y_scl_reg - = B_LENDIAN_TO_HOST_INT16(gpio->usClkY_RegisterIndex) * 4; - gGPIOInfo[i]->y_sda_reg - = B_LENDIAN_TO_HOST_INT16(gpio->usDataY_RegisterIndex) * 4; - gGPIOInfo[i]->y_scl_mask - = (1 << gpio->ucClkY_Shift); - gGPIOInfo[i]->y_sda_mask - = (1 << gpio->ucDataY_Shift); - - // ensure data is valid - gGPIOInfo[i]->valid = (gGPIOInfo[i]->mask_scl_reg) ? true : false; - - TRACE("%s: GPIO @ %" B_PRIu32 ", valid: %s, hw_line: 0x%" B_PRIX32 "\n", - __func__, i, gGPIOInfo[i]->valid ? "true" : "false", - gGPIOInfo[i]->hw_line); - } - - return B_OK; -} diff --git a/src/add-ons/accelerants/radeon_hd/gpu.h b/src/add-ons/accelerants/radeon_hd/gpu.h index 66940b3160..6ca5087c57 100644 --- a/src/add-ons/accelerants/radeon_hd/gpu.h +++ b/src/add-ons/accelerants/radeon_hd/gpu.h @@ -176,9 +176,6 @@ void radeon_gpu_mc_resume(struct gpu_state *gpuState); uint32 radeon_gpu_mc_idlecheck(); status_t radeon_gpu_mc_setup(); status_t radeon_gpu_irq_setup(); -status_t radeon_gpu_gpio_setup(); -status_t radeon_gpu_i2c_attach(uint32 id, uint8 hw_line); -bool radeon_gpu_read_edid(uint32 connector, edid1_info *edid); #endif