* 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:
@@ -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");
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user