* 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
This commit is contained in:
Alexander von Gluck IV
2011-09-27 21:34:28 +00:00
parent 4a0f028c4d
commit dd29505893
5 changed files with 87 additions and 50 deletions
@@ -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();
@@ -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
@@ -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");
+51 -36
View File
@@ -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;
+2 -1
View File
@@ -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