* 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; struct accelerant_info *gInfo;
display_info *gDisplay[MAX_DISPLAY]; display_info *gDisplay[MAX_DISPLAY];
connector_info *gConnector[ATOM_MAX_SUPPORTED_DEVICE]; connector_info *gConnector[ATOM_MAX_SUPPORTED_DEVICE];
gpio_info *gGPIOInfo[ATOM_MAX_SUPPORTED_DEVICE];
class AreaCloner { class AreaCloner {
@@ -133,6 +134,14 @@ init_common(int device, bool isClone)
memset(gConnector[id], 0, sizeof(connector_info)); 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->is_clone = isClone;
gInfo->device = device; 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(gConnector[id]);
free(gGPIOInfo[id]);
}
} }
@@ -243,19 +254,28 @@ radeon_init_accelerant(int device)
radeon_init_bios(gInfo->rom); radeon_init_bios(gInfo->rom);
// detect GPIO pins
radeon_gpu_gpio_setup();
// detect physical connectors
status = detect_connectors(); status = detect_connectors();
if (status != B_OK) { if (status != B_OK) {
TRACE("%s: couldn't detect supported connectors!\n", __func__); TRACE("%s: couldn't detect supported connectors!\n", __func__);
return status; return status;
} }
// print found connectors
debug_connectors(); debug_connectors();
// detect attached displays
status = detect_displays(); status = detect_displays();
//if (status != B_OK) //if (status != B_OK)
// return status; // return status;
// print found displays
debug_displays(); debug_displays();
// create initial list of video modes
status = create_mode_list(); status = create_mode_list();
//if (status != B_OK) { //if (status != B_OK) {
// radeon_uninit_accelerant(); // radeon_uninit_accelerant();
@@ -138,11 +138,11 @@ struct pll_info {
}; };
struct gpio_info { typedef struct {
bool valid; bool valid;
bool hw_capable;
uint8 i2c_slave_addr; bool hw_capable;
uint32 hw_line;
uint32 mask_scl_reg; uint32 mask_scl_reg;
uint32 mask_sda_reg; uint32 mask_sda_reg;
@@ -163,7 +163,7 @@ struct gpio_info {
uint32 a_sda_reg; uint32 a_sda_reg;
uint32 a_scl_mask; uint32 a_scl_mask;
uint32 a_sda_mask; uint32 a_sda_mask;
}; } gpio_info;
typedef struct { typedef struct {
@@ -172,7 +172,7 @@ typedef struct {
uint16 connector_flags; uint16 connector_flags;
uint32 connector_type; uint32 connector_type;
uint16 connector_object_id; uint16 connector_object_id;
gpio_info connector_gpio; uint16 connector_gpio_id;
uint32 encoder_type; uint32 encoder_type;
uint16 encoder_object_id; uint16 encoder_object_id;
// TODO struct radeon_hpd hpd; // TODO struct radeon_hpd hpd;
@@ -205,6 +205,7 @@ extern accelerant_info *gInfo;
extern atom_context *gAtomContext; extern atom_context *gAtomContext;
extern display_info *gDisplay[MAX_DISPLAY]; extern display_info *gDisplay[MAX_DISPLAY];
extern connector_info *gConnector[ATOM_MAX_SUPPORTED_DEVICE]; extern connector_info *gConnector[ATOM_MAX_SUPPORTED_DEVICE];
extern gpio_info *gGPIOInfo[ATOM_MAX_SUPPORTED_DEVICE];
// register access // register access
@@ -563,11 +563,9 @@ detect_connectors()
i2c_config i2c_config
= (ATOM_I2C_ID_CONFIG_ACCESS *) = (ATOM_I2C_ID_CONFIG_ACCESS *)
&i2c_record->sucI2cId; &i2c_record->sucI2cId;
// attach i2c gpio information for connector
// set up i2c gpio information for connector radeon_gpu_i2c_attach(connector_index,
radeon_gpu_i2c_setup(connector_index,
i2c_config->ucAccess); i2c_config->ucAccess);
break; break;
case ATOM_HPD_INT_RECORD_TYPE: case ATOM_HPD_INT_RECORD_TYPE:
// TODO : HPD (Hot Plug) // TODO : HPD (Hot Plug)
@@ -702,13 +700,15 @@ debug_connectors()
if (gConnector[id]->valid == true) { if (gConnector[id]->valid == true) {
uint32 connector_type = gConnector[id]->connector_type; uint32 connector_type = gConnector[id]->connector_type;
uint32 encoder_type = gConnector[id]->encoder_type; uint32 encoder_type = gConnector[id]->encoder_type;
uint16 gpio_id = gConnector[id]->connector_gpio_id;
ERROR("Connector #%" B_PRIu32 ")\n", id); ERROR("Connector #%" B_PRIu32 ")\n", id);
ERROR(" + connector: %s\n", get_connector_name(connector_type)); ERROR(" + connector: %s\n", get_connector_name(connector_type));
ERROR(" + encoder: %s\n", get_encoder_name(encoder_type)); ERROR(" + encoder: %s\n", get_encoder_name(encoder_type));
ERROR(" + i2c slave address: 0x%" B_PRIX8 "\n", ERROR(" + gpio id: %" B_PRIu16 "\n", gpio_id);
gConnector[id]->connector_gpio.i2c_slave_addr);
ERROR(" + gpio valid: %s\n", 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"); ERROR("==========================================\n");
+51 -36
View File
@@ -371,13 +371,15 @@ bool
radeon_gpu_read_edid(uint32 connector, edid1_info *edid) radeon_gpu_read_edid(uint32 connector, edid1_info *edid)
{ {
// ensure things are sane // 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; return false;
i2c_bus bus; i2c_bus bus;
ddc2_init_timing(&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.set_signals = &set_i2c_signals;
bus.get_signals = &get_i2c_signals; bus.get_signals = &get_i2c_signals;
@@ -396,12 +398,25 @@ radeon_gpu_read_edid(uint32 connector, edid1_info *edid)
status_t 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 gConnector[id]->connector_gpio_id = 0;
TRACE("%s: Path #%" B_PRId32 ": i2c slave: 0x%" B_PRIx8 "\n", __func__, for (uint32 i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) {
id, i2c_slave_addr); 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); int index = GetIndexIntoMasterTable(DATA, GPIO_I2C_Info);
uint8 frev; uint8 frev;
uint8 crev; uint8 crev;
@@ -412,7 +427,6 @@ radeon_gpu_i2c_setup(uint32 id, uint8 i2c_slave_addr)
&offset) != B_OK) { &offset) != B_OK) {
ERROR("%s: could't read GPIO_I2C_Info table from AtomBIOS index %d!\n", ERROR("%s: could't read GPIO_I2C_Info table from AtomBIOS index %d!\n",
__func__, index); __func__, index);
gConnector[id]->connector_gpio.valid = false;
return B_ERROR; 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)) uint32 num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER))
/ sizeof(ATOM_GPIO_I2C_ASSIGMENT); / 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++) { for (uint32 i = 0; i < num_indices; i++) {
ATOM_GPIO_I2C_ASSIGMENT *gpio = &i2c_info->asGPIO_Info[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 4 and i == 7 ... manual override for evergreen
// TODO : if DCE 3 and i == 4 ... manual override // TODO : if DCE 3 and i == 4 ... manual override
if (gpio->sucI2cId.ucAccess != i2c_slave_addr)
continue;
// populate gpio information // populate gpio information
// TODO : what is hw_capable? gGPIOInfo[i]->hw_line
gConnector[id]->connector_gpio.hw_capable = gpio->sucI2cId.ucAccess;
gGPIOInfo[i]->hw_capable
= (gpio->sucI2cId.sbfAccess.bfHW_Capable) ? true : false; = (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) // GPIO mask (Allows software to control the GPIO pad)
// 0 = chip access; 1 = only software; // 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; = 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; = B_LENDIAN_TO_HOST_INT16(gpio->usDataMaskRegisterIndex) * 4;
gConnector[id]->connector_gpio.mask_scl_mask gGPIOInfo[i]->mask_scl_mask
= (1 << gpio->ucClkMaskShift); = (1 << gpio->ucClkMaskShift);
gConnector[id]->connector_gpio.mask_sda_mask gGPIOInfo[i]->mask_sda_mask
= (1 << gpio->ucDataMaskShift); = (1 << gpio->ucDataMaskShift);
// GPIO output / write (A) enable // GPIO output / write (A) enable
// 0 = GPIO input (Y); 1 = GPIO output (A); // 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; = 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; = B_LENDIAN_TO_HOST_INT16(gpio->usDataEnRegisterIndex) * 4;
gConnector[id]->connector_gpio.en_scl_mask gGPIOInfo[i]->en_scl_mask
= (1 << gpio->ucClkEnShift); = (1 << gpio->ucClkEnShift);
gConnector[id]->connector_gpio.en_sda_mask gGPIOInfo[i]->en_sda_mask
= (1 << gpio->ucDataEnShift); = (1 << gpio->ucDataEnShift);
// GPIO output / write (A) // 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; = 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; = 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); = (1 << gpio->ucClkA_Shift);
gConnector[id]->connector_gpio.a_sda_mask gGPIOInfo[i]->a_sda_mask
= (1 << gpio->ucDataA_Shift); = (1 << gpio->ucDataA_Shift);
// GPIO input / read (Y) // 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; = 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; = 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); = (1 << gpio->ucClkY_Shift);
gConnector[id]->connector_gpio.y_sda_mask gGPIOInfo[i]->y_sda_mask
= (1 << gpio->ucDataY_Shift); = (1 << gpio->ucDataY_Shift);
// ensure data is valid // ensure data is valid
gConnector[id]->connector_gpio.valid gGPIOInfo[i]->valid = (gGPIOInfo[i]->mask_scl_reg) ? true : false;
= (gConnector[id]->connector_gpio.mask_scl_reg) ? true : false;
// see if we found what we were looking for TRACE("%s: GPIO @ %" B_PRIu32 ", valid: %s, hw_line: 0x%" B_PRIX32 "\n",
if (gConnector[id]->connector_gpio.valid == true) __func__, i, gGPIOInfo[i]->valid ? "true" : "false",
break; gGPIOInfo[i]->hw_line);
} }
return B_OK; return B_OK;
+2 -1
View File
@@ -168,8 +168,9 @@ void radeon_gpu_mc_resume();
uint32 radeon_gpu_mc_idlecheck(); uint32 radeon_gpu_mc_idlecheck();
status_t radeon_gpu_mc_setup(); status_t radeon_gpu_mc_setup();
status_t radeon_gpu_irq_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); bool radeon_gpu_read_edid(uint32 connector, edid1_info *edid);
status_t radeon_gpu_i2c_setup(uint32 id, uint8 i2c_slave_addr);
#endif #endif