From dd295058932cfb721aff7b714256dd9e5c334952 Mon Sep 17 00:00:00 2001 From: Alexander von Gluck IV Date: Tue, 27 Sep 2011 21:34:28 +0000 Subject: [PATCH] * remap GPIO pin storage to global struct as they really aren't tied to a connector. (thus allowing for future non-ddc gpio devices like fan speed) * map all i2c gpio pins on accelerant init * use a smaller sub function to attach gpio info to connector i2c info git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@42773 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../accelerants/radeon_hd/accelerant.cpp | 22 ++++- .../accelerants/radeon_hd/accelerant.h | 11 +-- src/add-ons/accelerants/radeon_hd/display.cpp | 14 +-- src/add-ons/accelerants/radeon_hd/gpu.cpp | 87 +++++++++++-------- src/add-ons/accelerants/radeon_hd/gpu.h | 3 +- 5 files changed, 87 insertions(+), 50 deletions(-) diff --git a/src/add-ons/accelerants/radeon_hd/accelerant.cpp b/src/add-ons/accelerants/radeon_hd/accelerant.cpp index 2114052968..64a0da7a13 100644 --- a/src/add-ons/accelerants/radeon_hd/accelerant.cpp +++ b/src/add-ons/accelerants/radeon_hd/accelerant.cpp @@ -42,6 +42,7 @@ struct accelerant_info *gInfo; display_info *gDisplay[MAX_DISPLAY]; connector_info *gConnector[ATOM_MAX_SUPPORTED_DEVICE]; +gpio_info *gGPIOInfo[ATOM_MAX_SUPPORTED_DEVICE]; class AreaCloner { @@ -133,6 +134,14 @@ init_common(int device, bool isClone) memset(gConnector[id], 0, sizeof(connector_info)); } + // malloc for card gpio pin information + for (uint32 id = 0; id < ATOM_MAX_SUPPORTED_DEVICE; id++) { + gGPIOInfo[id] = (gpio_info *)malloc(sizeof(gpio_info)); + + if (gGPIOInfo[id] == NULL) + return B_NO_MEMORY; + memset(gGPIOInfo[id], 0, sizeof(gpio_info)); + } gInfo->is_clone = isClone; gInfo->device = device; @@ -218,8 +227,10 @@ uninit_common(void) } } - for (uint32 id = 0; id < ATOM_MAX_SUPPORTED_DEVICE; id++) + for (uint32 id = 0; id < ATOM_MAX_SUPPORTED_DEVICE; id++) { free(gConnector[id]); + free(gGPIOInfo[id]); + } } @@ -243,19 +254,28 @@ radeon_init_accelerant(int device) radeon_init_bios(gInfo->rom); + // detect GPIO pins + radeon_gpu_gpio_setup(); + + // detect physical connectors status = detect_connectors(); if (status != B_OK) { TRACE("%s: couldn't detect supported connectors!\n", __func__); return status; } + // print found connectors debug_connectors(); + // detect attached displays status = detect_displays(); //if (status != B_OK) // return status; + + // print found displays debug_displays(); + // create initial list of video modes status = create_mode_list(); //if (status != B_OK) { // radeon_uninit_accelerant(); diff --git a/src/add-ons/accelerants/radeon_hd/accelerant.h b/src/add-ons/accelerants/radeon_hd/accelerant.h index 348beca362..6f228c4bc5 100644 --- a/src/add-ons/accelerants/radeon_hd/accelerant.h +++ b/src/add-ons/accelerants/radeon_hd/accelerant.h @@ -138,11 +138,11 @@ struct pll_info { }; -struct gpio_info { +typedef struct { bool valid; - bool hw_capable; - uint8 i2c_slave_addr; + bool hw_capable; + uint32 hw_line; uint32 mask_scl_reg; uint32 mask_sda_reg; @@ -163,7 +163,7 @@ struct gpio_info { uint32 a_sda_reg; uint32 a_scl_mask; uint32 a_sda_mask; -}; +} gpio_info; typedef struct { @@ -172,7 +172,7 @@ typedef struct { uint16 connector_flags; uint32 connector_type; uint16 connector_object_id; - gpio_info connector_gpio; + uint16 connector_gpio_id; uint32 encoder_type; uint16 encoder_object_id; // TODO struct radeon_hpd hpd; @@ -205,6 +205,7 @@ extern accelerant_info *gInfo; extern atom_context *gAtomContext; extern display_info *gDisplay[MAX_DISPLAY]; extern connector_info *gConnector[ATOM_MAX_SUPPORTED_DEVICE]; +extern gpio_info *gGPIOInfo[ATOM_MAX_SUPPORTED_DEVICE]; // register access diff --git a/src/add-ons/accelerants/radeon_hd/display.cpp b/src/add-ons/accelerants/radeon_hd/display.cpp index adfde16b88..faaa8eb5a5 100644 --- a/src/add-ons/accelerants/radeon_hd/display.cpp +++ b/src/add-ons/accelerants/radeon_hd/display.cpp @@ -563,11 +563,9 @@ detect_connectors() i2c_config = (ATOM_I2C_ID_CONFIG_ACCESS *) &i2c_record->sucI2cId; - - // set up i2c gpio information for connector - radeon_gpu_i2c_setup(connector_index, + // attach i2c gpio information for connector + radeon_gpu_i2c_attach(connector_index, i2c_config->ucAccess); - break; case ATOM_HPD_INT_RECORD_TYPE: // TODO : HPD (Hot Plug) @@ -702,13 +700,15 @@ debug_connectors() if (gConnector[id]->valid == true) { uint32 connector_type = gConnector[id]->connector_type; uint32 encoder_type = gConnector[id]->encoder_type; + uint16 gpio_id = gConnector[id]->connector_gpio_id; ERROR("Connector #%" B_PRIu32 ")\n", id); ERROR(" + connector: %s\n", get_connector_name(connector_type)); ERROR(" + encoder: %s\n", get_encoder_name(encoder_type)); - ERROR(" + i2c slave address: 0x%" B_PRIX8 "\n", - gConnector[id]->connector_gpio.i2c_slave_addr); + ERROR(" + gpio id: %" B_PRIu16 "\n", gpio_id); ERROR(" + gpio valid: %s\n", - (gConnector[id]->connector_gpio.valid) ? "true" : "false"); + gGPIOInfo[gpio_id]->valid ? "true" : "false"); + ERROR(" + hw line: 0x%" B_PRIX32 "\n", + gGPIOInfo[gpio_id]->hw_line); } } ERROR("==========================================\n"); diff --git a/src/add-ons/accelerants/radeon_hd/gpu.cpp b/src/add-ons/accelerants/radeon_hd/gpu.cpp index 242431f5c2..d54f2fca9d 100644 --- a/src/add-ons/accelerants/radeon_hd/gpu.cpp +++ b/src/add-ons/accelerants/radeon_hd/gpu.cpp @@ -371,13 +371,15 @@ bool radeon_gpu_read_edid(uint32 connector, edid1_info *edid) { // ensure things are sane - if (gConnector[connector]->connector_gpio.valid == false) + uint32 gpio_id = gConnector[connector]->connector_gpio_id; + if (gGPIOInfo[gpio_id]->valid == false) return false; i2c_bus bus; ddc2_init_timing(&bus); - bus.cookie = (void*)&gConnector[connector]->connector_gpio; + //bus.cookie = (void*)&gConnector[connector]->connector_gpio; + bus.cookie = (void*)gGPIOInfo[gpio_id]; bus.set_signals = &set_i2c_signals; bus.get_signals = &get_i2c_signals; @@ -396,12 +398,25 @@ radeon_gpu_read_edid(uint32 connector, edid1_info *edid) status_t -radeon_gpu_i2c_setup(uint32 id, uint8 i2c_slave_addr) +radeon_gpu_i2c_attach(uint32 id, uint8 hw_line) { - // aka radeon_lookup_i2c_gpio - TRACE("%s: Path #%" B_PRId32 ": i2c slave: 0x%" B_PRIx8 "\n", __func__, - id, i2c_slave_addr); + gConnector[id]->connector_gpio_id = 0; + for (uint32 i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) { + if (gGPIOInfo[i]->hw_line != hw_line) + continue; + gConnector[id]->connector_gpio_id = 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() +{ int index = GetIndexIntoMasterTable(DATA, GPIO_I2C_Info); uint8 frev; uint8 crev; @@ -412,7 +427,6 @@ radeon_gpu_i2c_setup(uint32 id, uint8 i2c_slave_addr) &offset) != B_OK) { ERROR("%s: could't read GPIO_I2C_Info table from AtomBIOS index %d!\n", __func__, index); - gConnector[id]->connector_gpio.valid = false; return B_ERROR; } @@ -422,72 +436,73 @@ radeon_gpu_i2c_setup(uint32 id, uint8 i2c_slave_addr) uint32 num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) / sizeof(ATOM_GPIO_I2C_ASSIGMENT); + if (num_indices > 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__, num_indices, (uint32)ATOM_MAX_SUPPORTED_DEVICE); + return B_ERROR; + } + for (uint32 i = 0; i < num_indices; i++) { ATOM_GPIO_I2C_ASSIGMENT *gpio = &i2c_info->asGPIO_Info[i]; // TODO : if DCE 4 and i == 7 ... manual override for evergreen // TODO : if DCE 3 and i == 4 ... manual override - if (gpio->sucI2cId.ucAccess != i2c_slave_addr) - continue; - // populate gpio information - // TODO : what is hw_capable? - gConnector[id]->connector_gpio.hw_capable + gGPIOInfo[i]->hw_line + = gpio->sucI2cId.ucAccess; + gGPIOInfo[i]->hw_capable = (gpio->sucI2cId.sbfAccess.bfHW_Capable) ? true : false; - // slave address of i2c endpoint - gConnector[id]->connector_gpio.i2c_slave_addr = i2c_slave_addr; - // GPIO mask (Allows software to control the GPIO pad) // 0 = chip access; 1 = only software; - gConnector[id]->connector_gpio.mask_scl_reg + gGPIOInfo[i]->mask_scl_reg = B_LENDIAN_TO_HOST_INT16(gpio->usClkMaskRegisterIndex) * 4; - gConnector[id]->connector_gpio.mask_sda_reg + gGPIOInfo[i]->mask_sda_reg = B_LENDIAN_TO_HOST_INT16(gpio->usDataMaskRegisterIndex) * 4; - gConnector[id]->connector_gpio.mask_scl_mask + gGPIOInfo[i]->mask_scl_mask = (1 << gpio->ucClkMaskShift); - gConnector[id]->connector_gpio.mask_sda_mask + gGPIOInfo[i]->mask_sda_mask = (1 << gpio->ucDataMaskShift); // GPIO output / write (A) enable // 0 = GPIO input (Y); 1 = GPIO output (A); - gConnector[id]->connector_gpio.en_scl_reg + gGPIOInfo[i]->en_scl_reg = B_LENDIAN_TO_HOST_INT16(gpio->usClkEnRegisterIndex) * 4; - gConnector[id]->connector_gpio.en_sda_reg + gGPIOInfo[i]->en_sda_reg = B_LENDIAN_TO_HOST_INT16(gpio->usDataEnRegisterIndex) * 4; - gConnector[id]->connector_gpio.en_scl_mask + gGPIOInfo[i]->en_scl_mask = (1 << gpio->ucClkEnShift); - gConnector[id]->connector_gpio.en_sda_mask + gGPIOInfo[i]->en_sda_mask = (1 << gpio->ucDataEnShift); // GPIO output / write (A) - gConnector[id]->connector_gpio.a_scl_reg + gGPIOInfo[i]->a_scl_reg = B_LENDIAN_TO_HOST_INT16(gpio->usClkA_RegisterIndex) * 4; - gConnector[id]->connector_gpio.a_sda_reg + gGPIOInfo[i]->a_sda_reg = B_LENDIAN_TO_HOST_INT16(gpio->usDataA_RegisterIndex) * 4; - gConnector[id]->connector_gpio.a_scl_mask + gGPIOInfo[i]->a_scl_mask = (1 << gpio->ucClkA_Shift); - gConnector[id]->connector_gpio.a_sda_mask + gGPIOInfo[i]->a_sda_mask = (1 << gpio->ucDataA_Shift); // GPIO input / read (Y) - gConnector[id]->connector_gpio.y_scl_reg + gGPIOInfo[i]->y_scl_reg = B_LENDIAN_TO_HOST_INT16(gpio->usClkY_RegisterIndex) * 4; - gConnector[id]->connector_gpio.y_sda_reg + gGPIOInfo[i]->y_sda_reg = B_LENDIAN_TO_HOST_INT16(gpio->usDataY_RegisterIndex) * 4; - gConnector[id]->connector_gpio.y_scl_mask + gGPIOInfo[i]->y_scl_mask = (1 << gpio->ucClkY_Shift); - gConnector[id]->connector_gpio.y_sda_mask + gGPIOInfo[i]->y_sda_mask = (1 << gpio->ucDataY_Shift); // ensure data is valid - gConnector[id]->connector_gpio.valid - = (gConnector[id]->connector_gpio.mask_scl_reg) ? true : false; + gGPIOInfo[i]->valid = (gGPIOInfo[i]->mask_scl_reg) ? true : false; - // see if we found what we were looking for - if (gConnector[id]->connector_gpio.valid == true) - break; + 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 9102d560b6..1de75e582b 100644 --- a/src/add-ons/accelerants/radeon_hd/gpu.h +++ b/src/add-ons/accelerants/radeon_hd/gpu.h @@ -168,8 +168,9 @@ void radeon_gpu_mc_resume(); 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); -status_t radeon_gpu_i2c_setup(uint32 id, uint8 i2c_slave_addr); #endif