radeon_hd: Add handling of connector routing

* A first attempt at improving on #17377
* We haven't actually seen any cards using this
  routing stuff yet pre-navi.
* We don't use the router information yet... but this might
  improve things a bit on new cards.

Change-Id: I17962dfd8bb09e619a6084cd9571ccb9832fb19a
Reviewed-on: https://review.haiku-os.org/c/haiku/+/4697
Tested-by: Commit checker robot <no-reply+buildbot@haiku-os.org>
Reviewed-by: Alex von Gluck IV <kallisti5@unixzen.com>
Reviewed-by: Adrien Destugues <pulkomandy@gmail.com>
This commit is contained in:
Alexander von Gluck IV 2021-11-06 09:13:19 -05:00 committed by Adrien Destugues
parent 6e28efbb5f
commit e87cba3470
3 changed files with 128 additions and 2 deletions

View File

@ -88,6 +88,9 @@ init_common(int device, bool isClone)
return B_NO_MEMORY;
memset(gConnector[id], 0, sizeof(connector_info));
// Init a few things
gConnector[id]->router.ddcValid = false;
gConnector[id]->router.cdValid = false;
gConnector[id]->encoder.pll.id = ATOM_PPLL_INVALID;
}

View File

@ -152,6 +152,24 @@ struct encoder_info {
};
typedef struct {
uint32 objectID;
// i2c info
uint16 i2cPinIndex; // id of gpio pin for i2c router
uint32 i2cAddr; // ?? hwPin??
// i2c pin mux
bool ddcValid;
uint8 ddcMuxType;
uint8 ddcMuxControlPin;
uint8 ddcMuxState;
// clk / data pin mux
bool cdValid;
uint8 cdMuxType;
uint8 cdMuxControlPin;
uint8 cdMuxState;
} router_info;
typedef struct {
bool valid;
uint16 objectID;
@ -163,6 +181,7 @@ typedef struct {
struct encoder_info encoder;
struct encoder_info encoderExternal;
dp_info dpInfo;
router_info router;
} connector_info;

View File

@ -319,7 +319,25 @@ connector_attach_gpio_i2c(uint32 connectorIndex, uint8 hwPin)
}
// We couldnt find the GPIO pin in the known GPIO pins.
TRACE("%s: can't find GPIO pin 0x%" B_PRIX8 " for connector %" B_PRIu32 "\n",
TRACE("%s: can't find GPIO pin 0x%" B_PRIX8 " for connector %" B_PRIu32 "\n",
__func__, hwPin, connectorIndex);
return B_ERROR;
}
static status_t
connector_attach_gpio_router(uint32 connectorIndex, uint8 hwPin)
{
gConnector[connectorIndex]->router.i2cPinIndex = 0;
for (uint32 i = 0; i < MAX_GPIO_PINS; i++) {
if (gGPIOInfo[i]->hwPin != hwPin)
continue;
gConnector[connectorIndex]->router.i2cPinIndex = i;
return B_OK;
}
// We couldnt find the GPIO pin in the known GPIO pins.
TRACE("%s: can't find GPIO pin 0x%" B_PRIX8 " for connector %" B_PRIu32 "\n",
__func__, hwPin, connectorIndex);
return B_ERROR;
}
@ -833,7 +851,71 @@ connector_probe()
}
// END if object is encoder
} else if (graphicObjectType == GRAPH_OBJECT_TYPE_ROUTER) {
ERROR("%s: TODO: Found router object?\n", __func__);
int32 k;
for (k = 0; k < routerObject->ucNumberOfObjects; k++) {
uint16 routerObjectID
= B_LENDIAN_TO_HOST_INT16(routerObject->asObjects[k].usObjectID);
if (B_LENDIAN_TO_HOST_INT16(path->usGraphicObjIds[j]) == routerObjectID) {
ATOM_COMMON_RECORD_HEADER* record = (ATOM_COMMON_RECORD_HEADER*)
((uint16*)gAtomContext->bios + tableOffset
+ B_LENDIAN_TO_HOST_INT16(
routerObject->asObjects[k].usRecordOffset));
ATOM_I2C_RECORD* i2cRecord;
ATOM_I2C_ID_CONFIG_ACCESS* i2cConfig;
ATOM_ROUTER_DDC_PATH_SELECT_RECORD* ddcPath;
ATOM_ROUTER_DATA_CLOCK_PATH_SELECT_RECORD* cdPath;
ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT* routerConnTable =
(ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT *)
((uint16*)gAtomContext->bios + tableOffset +
+ B_LENDIAN_TO_HOST_INT16(
routerObject->asObjects[k].usSrcDstTableOffset));
uint8* destObjCount = (uint8*)((uint8*)routerConnTable + 1
+ (routerConnTable->ucNumberOfSrc * 2));
uint16 *dstObjs = (uint16 *)(destObjCount + 1);
int enumId;
router_info* router = &connector->router;
router->objectID = routerObjectID;
for (enumId = 0; enumId < (*destObjCount); enumId++) {
if (B_LENDIAN_TO_HOST_INT16(path->usConnObjectId) ==
B_LENDIAN_TO_HOST_INT16(dstObjs[enumId]))
break;
}
while (record->ucRecordSize > 0 &&
record->ucRecordType > 0 &&
record->ucRecordType <= ATOM_MAX_OBJECT_RECORD_NUMBER) {
switch (record->ucRecordType) {
case ATOM_I2C_RECORD_TYPE:
i2cRecord = (ATOM_I2C_RECORD*)record;
i2cConfig
= (ATOM_I2C_ID_CONFIG_ACCESS*)&i2cRecord->sucI2cId;
connector_attach_gpio_router(connectorIndex,
i2cConfig->ucAccess);
router->i2cAddr = i2cRecord->ucI2CAddr >> 1; // ??
break;
case ATOM_ROUTER_DDC_PATH_SELECT_RECORD_TYPE:
ddcPath = (ATOM_ROUTER_DDC_PATH_SELECT_RECORD*)record;
router->ddcValid = true;
router->ddcMuxType = ddcPath->ucMuxType;
router->ddcMuxControlPin = ddcPath->ucMuxControlPin;
router->ddcMuxState = ddcPath->ucMuxState[enumId];
break;
case ATOM_ROUTER_DATA_CLOCK_PATH_SELECT_RECORD_TYPE:
cdPath
= (ATOM_ROUTER_DATA_CLOCK_PATH_SELECT_RECORD *)record;
router->cdValid = true;
router->cdMuxType = cdPath->ucMuxType;
router->cdMuxControlPin = cdPath->ucMuxControlPin;
router->cdMuxState = cdPath->ucMuxState[enumId];
break;
}
// move to next record
record = (ATOM_COMMON_RECORD_HEADER*)
((char *)record + record->ucRecordSize);
}
}
}
} // END if object is router
}
@ -935,11 +1017,33 @@ debug_connectors()
gGPIOInfo[i2cPinIndex]->valid ? "true" : "false");
ERROR(" - i2c valid: %s\n",
gGPIOInfo[i2cPinIndex]->i2c.valid ? "true" : "false");
// hot plug detection info
ERROR(" + hpd gpio table id: %" B_PRIu16 "\n", hpdPinIndex);
ERROR(" - gpio hw pin: 0x%" B_PRIX32 "\n",
gGPIOInfo[hpdPinIndex]->hwPin);
ERROR(" - gpio valid: %s\n",
gGPIOInfo[hpdPinIndex]->valid ? "true" : "false");
// router info
router_info* router = &gConnector[id]->router;
ERROR(" + router gpio table id: %" B_PRIu16 "\n", router->i2cPinIndex);
ERROR(" + router (ddc): %s\n",
router->ddcValid ? "true" : "false");
if (router->ddcValid) {
ERROR(" - mux type: 0x%" B_PRIX8 "\n", router->ddcMuxType);
ERROR(" - mux pin: 0x%" B_PRIX8 "\n", router->ddcMuxControlPin);
ERROR(" - mux state: 0x%" B_PRIX8 "\n", router->ddcMuxState);
}
ERROR(" + router (c/d): %s\n",
router->cdValid ? "true" : "false");
if (router->cdValid) {
ERROR(" - mux type: 0x%" B_PRIX8 "\n", router->cdMuxType);
ERROR(" - mux pin: 0x%" B_PRIX8 "\n", router->cdMuxControlPin);
ERROR(" - mux state: 0x%" B_PRIX8 "\n", router->cdMuxState);
}
// encoder info
encoder_info* encoder = &gConnector[id]->encoder;
ERROR(" + encoder: %s\n",
get_encoder_name(encoder->type));