From 54c0390b901eb0606bc6c0b46fb0e0c6530f4eda Mon Sep 17 00:00:00 2001 From: Alexander von Gluck IV Date: Wed, 14 Sep 2011 15:40:30 +0000 Subject: [PATCH] * remove un-needed i2c_bus on each connector... we simply set this up each time it's needed using the gpio information * rename gpio information struct to be cleaner and shorter * add function to debug found connectors * set gpio mask to 1 vs the defined mask... this seems to get us closer to working ddc / edid per connector * change gpio_info u16's to u32's to ensure we aren't overflowing anything * fix bug always setting hw_capable true * change TRACE to ERROR to always show debug data when called git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@42751 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../accelerants/radeon_hd/accelerant.cpp | 4 +- .../accelerants/radeon_hd/accelerant.h | 39 +++-- src/add-ons/accelerants/radeon_hd/display.cpp | 31 +++- src/add-ons/accelerants/radeon_hd/display.h | 1 + src/add-ons/accelerants/radeon_hd/gpu.cpp | 143 ++++++++++-------- src/add-ons/accelerants/radeon_hd/gpu.h | 2 +- 6 files changed, 125 insertions(+), 95 deletions(-) diff --git a/src/add-ons/accelerants/radeon_hd/accelerant.cpp b/src/add-ons/accelerants/radeon_hd/accelerant.cpp index ea58efe9d5..2114052968 100644 --- a/src/add-ons/accelerants/radeon_hd/accelerant.cpp +++ b/src/add-ons/accelerants/radeon_hd/accelerant.cpp @@ -245,15 +245,15 @@ radeon_init_accelerant(int device) status = detect_connectors(); if (status != B_OK) { - // TODO : detect_connectors_manual to get from object table TRACE("%s: couldn't detect supported connectors!\n", __func__); return status; } + debug_connectors(); + status = detect_displays(); //if (status != B_OK) // return status; - debug_displays(); status = create_mode_list(); diff --git a/src/add-ons/accelerants/radeon_hd/accelerant.h b/src/add-ons/accelerants/radeon_hd/accelerant.h index 201a399154..4ee3fd3bec 100644 --- a/src/add-ons/accelerants/radeon_hd/accelerant.h +++ b/src/add-ons/accelerants/radeon_hd/accelerant.h @@ -138,31 +138,31 @@ struct pll_info { }; -struct ddc_info { +struct gpio_info { bool valid; bool hw_capable; - uint8 gpio_id; + uint8 pin; - uint16 mask_scl_reg; - uint16 mask_sda_reg; - uint16 mask_scl_mask; - uint16 mask_sda_mask; + uint32 mask_scl_reg; + uint32 mask_sda_reg; + uint32 mask_scl_mask; + uint32 mask_sda_mask; - uint16 gpio_en_scl_reg; - uint16 gpio_en_sda_reg; - uint16 gpio_en_scl_mask; - uint16 gpio_en_sda_mask; + uint32 en_scl_reg; + uint32 en_sda_reg; + uint32 en_scl_mask; + uint32 en_sda_mask; - uint16 gpio_y_scl_reg; - uint16 gpio_y_sda_reg; - uint16 gpio_y_scl_mask; - uint16 gpio_y_sda_mask; + uint32 y_scl_reg; + uint32 y_sda_reg; + uint32 y_scl_mask; + uint32 y_sda_mask; - uint16 gpio_a_scl_reg; - uint16 gpio_a_sda_reg; - uint16 gpio_a_scl_mask; - uint16 gpio_a_sda_mask; + uint32 a_scl_reg; + uint32 a_sda_reg; + uint32 a_scl_mask; + uint32 a_sda_mask; }; @@ -172,10 +172,9 @@ typedef struct { uint16 connector_flags; uint32 connector_type; uint16 connector_object_id; + gpio_info connector_gpio; uint32 encoder_type; uint16 encoder_object_id; - ddc_info connector_ddc_info; - i2c_bus connector_i2c; // TODO struct radeon_hpd hpd; } connector_info; diff --git a/src/add-ons/accelerants/radeon_hd/display.cpp b/src/add-ons/accelerants/radeon_hd/display.cpp index 7d12624c1d..c9f336bfd8 100644 --- a/src/add-ons/accelerants/radeon_hd/display.cpp +++ b/src/add-ons/accelerants/radeon_hd/display.cpp @@ -653,7 +653,7 @@ debug_displays() { TRACE("Currently detected monitors===============\n"); for (uint32 id = 0; id < MAX_DISPLAY; id++) { - TRACE("Display #%" B_PRIu32 " active = %s\n", + ERROR("Display #%" B_PRIu32 " active = %s\n", id, gDisplay[id]->active ? "true" : "false"); uint32 connector_index = gDisplay[id]->connector_index; @@ -661,12 +661,12 @@ debug_displays() if (gDisplay[id]->active) { uint32 connector_type = gConnector[connector_index]->connector_type; uint32 encoder_type = gConnector[connector_index]->encoder_type; - TRACE(" + connector: %s\n", get_connector_name(connector_type)); - TRACE(" + encoder: %s\n", get_encoder_name(encoder_type)); + ERROR(" + connector: %s\n", get_connector_name(connector_type)); + ERROR(" + encoder: %s\n", get_encoder_name(encoder_type)); - TRACE(" + limits: Vert Min/Max: %" B_PRIu32 "/%" B_PRIu32"\n", + ERROR(" + limits: Vert Min/Max: %" B_PRIu32 "/%" B_PRIu32"\n", gDisplay[id]->vfreq_min, gDisplay[id]->vfreq_max); - TRACE(" + limits: Horz Min/Max: %" B_PRIu32 "/%" B_PRIu32"\n", + ERROR(" + limits: Horz Min/Max: %" B_PRIu32 "/%" B_PRIu32"\n", gDisplay[id]->hfreq_min, gDisplay[id]->hfreq_max); } } @@ -675,6 +675,27 @@ debug_displays() } +void +debug_connectors() +{ + ERROR("Currently detected connectors=============\n"); + for (uint32 id = 0; id < ATOM_MAX_SUPPORTED_DEVICE; id++) { + if (gConnector[id]->valid == true) { + uint32 connector_type = gConnector[id]->connector_type; + uint32 encoder_type = gConnector[id]->encoder_type; + 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(" + gpio valid: %s\n", + (gConnector[id]->connector_gpio.valid) ? "true" : "false"); + ERROR(" + gpio pin: 0x%" B_PRIX8 "\n", + gConnector[id]->connector_gpio.pin); + } + } + ERROR("==========================================\n"); +} + + uint32 display_get_encoder_mode(uint32 connector_index) { diff --git a/src/add-ons/accelerants/radeon_hd/display.h b/src/add-ons/accelerants/radeon_hd/display.h index 064419359a..d0fa8b0daf 100644 --- a/src/add-ons/accelerants/radeon_hd/display.h +++ b/src/add-ons/accelerants/radeon_hd/display.h @@ -63,6 +63,7 @@ status_t detect_connectors(); status_t detect_crt_ranges(uint32 crtid); status_t detect_displays(); void debug_displays(); +void debug_connectors(); uint32 display_get_encoder_mode(uint32 connector_index); void display_crtc_lock(uint8 crtc_id, int command); diff --git a/src/add-ons/accelerants/radeon_hd/gpu.cpp b/src/add-ons/accelerants/radeon_hd/gpu.cpp index aec0830548..af1e9a053d 100644 --- a/src/add-ons/accelerants/radeon_hd/gpu.cpp +++ b/src/add-ons/accelerants/radeon_hd/gpu.cpp @@ -280,7 +280,7 @@ radeon_gpu_irq_setup() static void lock_i2c(void* cookie, bool lock) { - ddc_info *info = (ddc_info*)cookie; + gpio_info *info = (gpio_info*)cookie; uint32 buffer = 0; @@ -292,49 +292,59 @@ lock_i2c(void* cookie, bool lock) } // Clear pins - buffer = Read32(OUT, info->gpio_a_scl_reg) & ~info->gpio_a_scl_mask; - Write32(OUT, info->gpio_a_scl_reg, buffer); - buffer = Read32(OUT, info->gpio_a_sda_reg) & ~info->gpio_a_sda_mask; - Write32(OUT, info->gpio_a_sda_reg, buffer); + 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->gpio_en_scl_reg) & ~info->gpio_en_scl_mask; - Write32(OUT, info->gpio_en_scl_reg, buffer); - buffer = Read32(OUT, info->gpio_en_sda_reg) & ~info->gpio_en_sda_mask; - Write32(OUT, info->gpio_en_sda_reg, buffer); + 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; + // TODO : we should use the mask... but it doesn't work for some reason + // buffer = Read32(OUT, info->mask_scl_reg); + if (lock == true) { + buffer = 1; + //buffer |= info->mask_scl_mask; + } else { + buffer = 0; + //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; + if (lock == true) { + buffer = 1; + // buffer |= info->mask_sda_mask; + } else { + buffer = 0; + // 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) { - ddc_info *info = (ddc_info*)cookie; + gpio_info *info = (gpio_info*)cookie; - uint32 scl = Read32(OUT, info->gpio_y_scl_reg) & info->gpio_y_scl_mask; - uint32 sda = Read32(OUT, info->gpio_y_sda_reg) & info->gpio_y_sda_mask; + 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); - TRACE("%s: GPIO 0x%" B_PRIX8 ", clock: %d, data: %d\n", - __func__, info->gpio_id, *_clock, *_data); + //TRACE("%s: GPIO 0x%" B_PRIX8 ", clock: %d, data: %d\n", + // __func__, info->pin, *_clock, *_data); return B_OK; } @@ -343,21 +353,21 @@ get_i2c_signals(void* cookie, int* _clock, int* _data) static status_t set_i2c_signals(void* cookie, int clock, int data) { - ddc_info* info = (ddc_info*)cookie; + gpio_info* info = (gpio_info*)cookie; - uint32 scl = Read32(OUT, info->gpio_en_scl_reg) - & ~info->gpio_en_scl_mask; - uint32 sda = Read32(OUT, info->gpio_en_sda_reg) - & ~info->gpio_en_sda_mask; + uint32 scl = Read32(OUT, info->en_scl_reg) + & ~info->en_scl_mask; + uint32 sda = Read32(OUT, info->en_sda_reg) + & ~info->en_sda_mask; - scl |= clock ? 0 : info->gpio_en_scl_mask; - sda |= data ? 0 : info->gpio_en_sda_mask; + scl |= clock ? 0 : info->en_scl_mask; + sda |= data ? 0 : info->en_sda_mask; - Write32(OUT, info->gpio_a_scl_reg, clock); - Write32(OUT, info->gpio_a_sda_reg, data); + Write32(OUT, info->a_scl_reg, clock); + Write32(OUT, info->a_sda_reg, data); - TRACE("%s: GPIO 0x%" B_PRIX8 ", clock: %d, data: %d\n", - __func__, info->gpio_id, clock, data); + //TRACE("%s: GPIO 0x%" B_PRIX8 ", clock: %d, data: %d\n", + // __func__, info->pin, clock, data); return B_OK; } @@ -367,14 +377,13 @@ bool radeon_gpu_read_edid(uint32 connector, edid1_info *edid) { // ensure things are sane - if (gConnector[connector]->connector_ddc_info.valid == false - || gConnector[connector]->connector_ddc_info.gpio_id == 0) + if (gConnector[connector]->connector_gpio.valid == false) return false; i2c_bus bus; ddc2_init_timing(&bus); - bus.cookie = (void*)&gConnector[connector]->connector_ddc_info; + bus.cookie = (void*)&gConnector[connector]->connector_gpio; bus.set_signals = &set_i2c_signals; bus.get_signals = &get_i2c_signals; @@ -393,11 +402,11 @@ radeon_gpu_read_edid(uint32 connector, edid1_info *edid) status_t -radeon_gpu_i2c_setup(uint32 connector, uint8 gpio_id) +radeon_gpu_i2c_setup(uint32 id, uint8 gpio_pin) { // aka radeon_lookup_i2c_gpio TRACE("%s: Path #%" B_PRId32 ": GPIO Pin 0x%" B_PRIx8 "\n", __func__, - connector, gpio_id); + id, gpio_pin); int index = GetIndexIntoMasterTable(DATA, GPIO_I2C_Info); uint8 frev; @@ -409,7 +418,7 @@ radeon_gpu_i2c_setup(uint32 connector, uint8 gpio_id) &offset) != B_OK) { ERROR("%s: could't read GPIO_I2C_Info table from AtomBIOS index %d!\n", __func__, index); - gConnector[connector]->connector_ddc_info.valid = false; + gConnector[id]->connector_gpio.valid = false; return B_ERROR; } @@ -425,65 +434,65 @@ radeon_gpu_i2c_setup(uint32 connector, uint8 gpio_id) // TODO : if DCE 4 and i == 7 ... manual override for evergreen // TODO : if DCE 3 and i == 4 ... manual override - if (gpio->sucI2cId.ucAccess != gpio_id) + if (gpio->sucI2cId.ucAccess != gpio_pin) continue; - // successful lookup - TRACE("%s: successful AtomBIOS GPIO lookup\n", __func__); - // populate gpio information - gConnector[connector]->connector_ddc_info.valid = true; - // TODO : what is hw_capable? - if (gpio->sucI2cId.sbfAccess.bfHW_Capable) - gConnector[connector]->connector_ddc_info.hw_capable = true; - else - gConnector[connector]->connector_ddc_info.hw_capable = true; + gConnector[id]->connector_gpio.hw_capable + = (gpio->sucI2cId.sbfAccess.bfHW_Capable) ? true : false; - gConnector[connector]->connector_ddc_info.gpio_id = gpio_id; + gConnector[id]->connector_gpio.pin = gpio_pin; // GPIO mask (Allows software to control the GPIO pad) // 0 = chip access; 1 = only software; - gConnector[connector]->connector_ddc_info.mask_scl_reg + gConnector[id]->connector_gpio.mask_scl_reg = B_LENDIAN_TO_HOST_INT16(gpio->usClkMaskRegisterIndex) * 4; - gConnector[connector]->connector_ddc_info.mask_sda_reg + gConnector[id]->connector_gpio.mask_sda_reg = B_LENDIAN_TO_HOST_INT16(gpio->usDataMaskRegisterIndex) * 4; - gConnector[connector]->connector_ddc_info.mask_scl_mask + gConnector[id]->connector_gpio.mask_scl_mask = (1 << gpio->ucClkMaskShift); - gConnector[connector]->connector_ddc_info.mask_sda_mask + gConnector[id]->connector_gpio.mask_sda_mask = (1 << gpio->ucDataMaskShift); // GPIO output / write (A) enable // 0 = GPIO input (Y); 1 = GPIO output (A); - gConnector[connector]->connector_ddc_info.gpio_en_scl_reg + gConnector[id]->connector_gpio.en_scl_reg = B_LENDIAN_TO_HOST_INT16(gpio->usClkEnRegisterIndex) * 4; - gConnector[connector]->connector_ddc_info.gpio_en_sda_reg + gConnector[id]->connector_gpio.en_sda_reg = B_LENDIAN_TO_HOST_INT16(gpio->usDataEnRegisterIndex) * 4; - gConnector[connector]->connector_ddc_info.gpio_en_scl_mask + gConnector[id]->connector_gpio.en_scl_mask = (1 << gpio->ucClkEnShift); - gConnector[connector]->connector_ddc_info.gpio_en_sda_mask + gConnector[id]->connector_gpio.en_sda_mask = (1 << gpio->ucDataEnShift); // GPIO output / write (A) - gConnector[connector]->connector_ddc_info.gpio_a_scl_reg + gConnector[id]->connector_gpio.a_scl_reg = B_LENDIAN_TO_HOST_INT16(gpio->usClkA_RegisterIndex) * 4; - gConnector[connector]->connector_ddc_info.gpio_a_sda_reg + gConnector[id]->connector_gpio.a_sda_reg = B_LENDIAN_TO_HOST_INT16(gpio->usDataA_RegisterIndex) * 4; - gConnector[connector]->connector_ddc_info.gpio_a_scl_mask + gConnector[id]->connector_gpio.a_scl_mask = (1 << gpio->ucClkA_Shift); - gConnector[connector]->connector_ddc_info.gpio_a_sda_mask + gConnector[id]->connector_gpio.a_sda_mask = (1 << gpio->ucDataA_Shift); // GPIO input / read (Y) - gConnector[connector]->connector_ddc_info.gpio_y_scl_reg + gConnector[id]->connector_gpio.y_scl_reg = B_LENDIAN_TO_HOST_INT16(gpio->usClkY_RegisterIndex) * 4; - gConnector[connector]->connector_ddc_info.gpio_y_sda_reg + gConnector[id]->connector_gpio.y_sda_reg = B_LENDIAN_TO_HOST_INT16(gpio->usDataY_RegisterIndex) * 4; - gConnector[connector]->connector_ddc_info.gpio_y_scl_mask + gConnector[id]->connector_gpio.y_scl_mask = (1 << gpio->ucClkY_Shift); - gConnector[connector]->connector_ddc_info.gpio_y_sda_mask + gConnector[id]->connector_gpio.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; + + // see if we found what we were looking for + if (gConnector[id]->connector_gpio.valid == true) + break; } return B_OK; diff --git a/src/add-ons/accelerants/radeon_hd/gpu.h b/src/add-ons/accelerants/radeon_hd/gpu.h index ff0094f315..e79ee9fe55 100644 --- a/src/add-ons/accelerants/radeon_hd/gpu.h +++ b/src/add-ons/accelerants/radeon_hd/gpu.h @@ -169,7 +169,7 @@ uint32 radeon_gpu_mc_idlecheck(); status_t radeon_gpu_mc_setup(); status_t radeon_gpu_irq_setup(); bool radeon_gpu_read_edid(uint32 connector, edid1_info *edid); -status_t radeon_gpu_i2c_setup(uint32 connector, uint8 gpio_id); +status_t radeon_gpu_i2c_setup(uint32 id, uint8 gpio_id); #endif