* as we are doing a lot of math on bios in gAtomContext, lets make it a
uint8 vs a void pointer. * guys at AMD confirmed that the method looking directly at the object table should be the only method used on modern cards (r600 or later) git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@42683 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -143,6 +143,7 @@ typedef struct {
|
|||||||
uint16 line_mux;
|
uint16 line_mux;
|
||||||
uint16 devices;
|
uint16 devices;
|
||||||
uint32 connector_type;
|
uint32 connector_type;
|
||||||
|
uint16 connector_object_id;
|
||||||
// TODO struct radeon_i2c_bus_rec ddc_bus;
|
// TODO struct radeon_i2c_bus_rec ddc_bus;
|
||||||
// TODO struct radeon_hpd hpd;
|
// TODO struct radeon_hpd hpd;
|
||||||
} connector_info;
|
} connector_info;
|
||||||
|
|||||||
@@ -1206,7 +1206,7 @@ atom_index_iio(atom_context *ctx, int base)
|
|||||||
|
|
||||||
|
|
||||||
atom_context*
|
atom_context*
|
||||||
atom_parse(card_info *card, void *bios)
|
atom_parse(card_info *card, uint8 *bios)
|
||||||
{
|
{
|
||||||
atom_context *ctx = (atom_context*)malloc(sizeof(atom_context));
|
atom_context *ctx = (atom_context*)malloc(sizeof(atom_context));
|
||||||
|
|
||||||
@@ -1301,7 +1301,7 @@ atom_parse_data_header(atom_context *ctx, int index, uint16 *size,
|
|||||||
{
|
{
|
||||||
int offset = index * 2 + 4;
|
int offset = index * 2 + 4;
|
||||||
int idx = CU16(ctx->data_table + offset);
|
int idx = CU16(ctx->data_table + offset);
|
||||||
uint16 *mdt = (uint16 *)ctx->bios + ctx->data_table + 4;
|
uint8 *mdt = ctx->bios + ctx->data_table + 4;
|
||||||
|
|
||||||
if (!mdt[index])
|
if (!mdt[index])
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
@@ -1323,7 +1323,7 @@ atom_parse_cmd_header(atom_context *ctx, int index, uint8 * frev,
|
|||||||
{
|
{
|
||||||
int offset = index * 2 + 4;
|
int offset = index * 2 + 4;
|
||||||
int idx = CU16(ctx->cmd_table + offset);
|
int idx = CU16(ctx->cmd_table + offset);
|
||||||
uint16 *mct = (uint16 *)ctx->bios + ctx->cmd_table + 4;
|
uint8 *mct = ctx->bios + ctx->cmd_table + 4;
|
||||||
|
|
||||||
if (!mct[index])
|
if (!mct[index])
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
@@ -1346,8 +1346,7 @@ atom_allocate_fb_scratch(atom_context *ctx)
|
|||||||
|
|
||||||
if (atom_parse_data_header(ctx, index, NULL, NULL, NULL, &data_offset)
|
if (atom_parse_data_header(ctx, index, NULL, NULL, NULL, &data_offset)
|
||||||
== B_OK) {
|
== B_OK) {
|
||||||
firmware = (_ATOM_VRAM_USAGE_BY_FIRMWARE *)
|
firmware = (_ATOM_VRAM_USAGE_BY_FIRMWARE *)(ctx->bios + data_offset);
|
||||||
((uint16*)ctx->bios + data_offset);
|
|
||||||
|
|
||||||
TRACE("Atom firmware requested 0x%" B_PRIX32 " %" B_PRIu16 "kb\n",
|
TRACE("Atom firmware requested 0x%" B_PRIX32 " %" B_PRIu16 "kb\n",
|
||||||
firmware->asFirmwareVramReserveInfo[0].ulStartAddrUsedByFirmware,
|
firmware->asFirmwareVramReserveInfo[0].ulStartAddrUsedByFirmware,
|
||||||
|
|||||||
@@ -129,7 +129,7 @@ struct card_info {
|
|||||||
|
|
||||||
typedef struct atom_context_s {
|
typedef struct atom_context_s {
|
||||||
card_info *card;
|
card_info *card;
|
||||||
void *bios;
|
uint8 *bios;
|
||||||
uint32 cmd_table, data_table;
|
uint32 cmd_table, data_table;
|
||||||
uint16 *iio;
|
uint16 *iio;
|
||||||
|
|
||||||
@@ -147,8 +147,8 @@ typedef struct atom_context_s {
|
|||||||
|
|
||||||
extern int atom_debug;
|
extern int atom_debug;
|
||||||
|
|
||||||
atom_context *atom_parse(card_info *, void *);
|
atom_context *atom_parse(card_info *card, uint8 *bios);
|
||||||
status_t atom_execute_table(atom_context *, int, uint32 *);
|
status_t atom_execute_table(atom_context *ctx, int index, uint32 *params);
|
||||||
status_t atom_parse_data_header(atom_context *ctx, int index, uint16 *size,
|
status_t atom_parse_data_header(atom_context *ctx, int index, uint16 *size,
|
||||||
uint8 *frev, uint8 *crev, uint16 *data_start);
|
uint8 *frev, uint8 *crev, uint16 *data_start);
|
||||||
status_t atom_parse_cmd_header(atom_context *ctx, int index, uint8 * frev,
|
status_t atom_parse_cmd_header(atom_context *ctx, int index, uint8 * frev,
|
||||||
|
|||||||
@@ -227,8 +227,9 @@ union atom_supported_devices {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// only used on r4xx, r5xx, and rs600/rs690/rs740
|
||||||
status_t
|
status_t
|
||||||
detect_connectors()
|
detect_connectors_legacy()
|
||||||
{
|
{
|
||||||
int index = GetIndexIntoMasterTable(DATA, SupportedDevicesInfo);
|
int index = GetIndexIntoMasterTable(DATA, SupportedDevicesInfo);
|
||||||
uint8 frev;
|
uint8 frev;
|
||||||
@@ -245,18 +246,17 @@ detect_connectors()
|
|||||||
union atom_supported_devices *supported_devices;
|
union atom_supported_devices *supported_devices;
|
||||||
supported_devices
|
supported_devices
|
||||||
= (union atom_supported_devices *)
|
= (union atom_supported_devices *)
|
||||||
((uint16 *)gAtomContext->bios + data_offset);
|
(gAtomContext->bios + data_offset);
|
||||||
|
|
||||||
uint16 device_support
|
uint16 device_support
|
||||||
= B_LENDIAN_TO_HOST_INT16(supported_devices->info.usDeviceSupport);
|
= B_LENDIAN_TO_HOST_INT16(supported_devices->info.usDeviceSupport);
|
||||||
|
|
||||||
int32 i;
|
int32 i;
|
||||||
for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) {
|
for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) {
|
||||||
ATOM_CONNECTOR_INFO_I2C ci
|
|
||||||
= supported_devices->info.asConnInfo[i];
|
|
||||||
|
|
||||||
gConnector[i]->valid = false;
|
gConnector[i]->valid = false;
|
||||||
|
|
||||||
|
// check if this connector is used
|
||||||
if (!(device_support & (1 << i)))
|
if (!(device_support & (1 << i)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@@ -266,13 +266,16 @@ detect_connectors()
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
gConnector[i]->connector_type
|
ATOM_CONNECTOR_INFO_I2C ci
|
||||||
= connector_convert[ci.sucConnectorInfo.sbfAccess.bfConnectorType];
|
= supported_devices->info.asConnInfo[i];
|
||||||
|
|
||||||
if (gConnector[i]->connector_type
|
gConnector[i]->connector_type
|
||||||
== VIDEO_CONNECTOR_UNKNOWN) {
|
= connector_convert_legacy[
|
||||||
|
ci.sucConnectorInfo.sbfAccess.bfConnectorType];
|
||||||
|
|
||||||
|
if (gConnector[i]->connector_type == VIDEO_CONNECTOR_UNKNOWN) {
|
||||||
TRACE("%s: skipping unknown connector at %" B_PRId32
|
TRACE("%s: skipping unknown connector at %" B_PRId32
|
||||||
" of 0x%" B_PRIX8"\n", __func__, i,
|
" of 0x%" B_PRIX8 "\n", __func__, i,
|
||||||
ci.sucConnectorInfo.sbfAccess.bfConnectorType);
|
ci.sucConnectorInfo.sbfAccess.bfConnectorType);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -317,9 +320,9 @@ detect_connectors()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// TODO : this gets connectors from object table
|
// r600+
|
||||||
status_t
|
status_t
|
||||||
detect_connectors_manual()
|
detect_connectors()
|
||||||
{
|
{
|
||||||
int index = GetIndexIntoMasterTable(DATA, Object_Header);
|
int index = GetIndexIntoMasterTable(DATA, Object_Header);
|
||||||
|
|
||||||
@@ -345,19 +348,18 @@ detect_connectors_manual()
|
|||||||
ATOM_DISPLAY_OBJECT_PATH_TABLE *path_obj;
|
ATOM_DISPLAY_OBJECT_PATH_TABLE *path_obj;
|
||||||
ATOM_OBJECT_HEADER *obj_header;
|
ATOM_OBJECT_HEADER *obj_header;
|
||||||
|
|
||||||
obj_header = (ATOM_OBJECT_HEADER *)
|
obj_header = (ATOM_OBJECT_HEADER *)(gAtomContext->bios + data_offset);
|
||||||
((uint16 *)gAtomContext->bios + data_offset);
|
|
||||||
path_obj = (ATOM_DISPLAY_OBJECT_PATH_TABLE *)
|
path_obj = (ATOM_DISPLAY_OBJECT_PATH_TABLE *)
|
||||||
((uint16 *)gAtomContext->bios + data_offset
|
(gAtomContext->bios + data_offset
|
||||||
+ B_LENDIAN_TO_HOST_INT16(obj_header->usDisplayPathTableOffset));
|
+ B_LENDIAN_TO_HOST_INT16(obj_header->usDisplayPathTableOffset));
|
||||||
con_obj = (ATOM_CONNECTOR_OBJECT_TABLE *)
|
con_obj = (ATOM_CONNECTOR_OBJECT_TABLE *)
|
||||||
((uint16 *)gAtomContext->bios + data_offset
|
(gAtomContext->bios + data_offset
|
||||||
+ B_LENDIAN_TO_HOST_INT16(obj_header->usConnectorObjectTableOffset));
|
+ B_LENDIAN_TO_HOST_INT16(obj_header->usConnectorObjectTableOffset));
|
||||||
enc_obj = (ATOM_ENCODER_OBJECT_TABLE *)
|
enc_obj = (ATOM_ENCODER_OBJECT_TABLE *)
|
||||||
((uint16 *)gAtomContext->bios + data_offset
|
(gAtomContext->bios + data_offset
|
||||||
+ B_LENDIAN_TO_HOST_INT16(obj_header->usEncoderObjectTableOffset));
|
+ B_LENDIAN_TO_HOST_INT16(obj_header->usEncoderObjectTableOffset));
|
||||||
router_obj = (ATOM_OBJECT_TABLE *)
|
router_obj = (ATOM_OBJECT_TABLE *)
|
||||||
((uint16 *)gAtomContext->bios + data_offset
|
(gAtomContext->bios + data_offset
|
||||||
+ B_LENDIAN_TO_HOST_INT16(obj_header->usRouterObjectTableOffset));
|
+ B_LENDIAN_TO_HOST_INT16(obj_header->usRouterObjectTableOffset));
|
||||||
int device_support = B_LENDIAN_TO_HOST_INT16(obj_header->usDeviceSupport);
|
int device_support = B_LENDIAN_TO_HOST_INT16(obj_header->usDeviceSupport);
|
||||||
|
|
||||||
@@ -367,24 +369,25 @@ detect_connectors_manual()
|
|||||||
TRACE("%s: found %" B_PRIu8 " potential display paths.\n", __func__,
|
TRACE("%s: found %" B_PRIu8 " potential display paths.\n", __func__,
|
||||||
path_obj->ucNumOfDispPath);
|
path_obj->ucNumOfDispPath);
|
||||||
|
|
||||||
|
uint32 connector_index = 0;
|
||||||
for (i = 0; i < path_obj->ucNumOfDispPath; i++) {
|
for (i = 0; i < path_obj->ucNumOfDispPath; i++) {
|
||||||
|
|
||||||
|
if (connector_index >= ATOM_MAX_SUPPORTED_DEVICE)
|
||||||
|
continue;
|
||||||
|
|
||||||
uint8 *addr = (uint8*)path_obj->asDispPath;
|
uint8 *addr = (uint8*)path_obj->asDispPath;
|
||||||
ATOM_DISPLAY_OBJECT_PATH *path;
|
ATOM_DISPLAY_OBJECT_PATH *path;
|
||||||
addr += path_size;
|
addr += path_size;
|
||||||
path = (ATOM_DISPLAY_OBJECT_PATH *) addr;
|
path = (ATOM_DISPLAY_OBJECT_PATH *)addr;
|
||||||
path_size += B_LENDIAN_TO_HOST_INT16(path->usSize);
|
path_size += B_LENDIAN_TO_HOST_INT16(path->usSize);
|
||||||
|
|
||||||
int connector_type;
|
uint32 connector_type;
|
||||||
uint16 connector_object_id;
|
uint16 connector_object_id;
|
||||||
|
|
||||||
if (device_support & B_LENDIAN_TO_HOST_INT16(path->usDeviceTag)) {
|
if (device_support & B_LENDIAN_TO_HOST_INT16(path->usDeviceTag)) {
|
||||||
TRACE("%s: Display Path #%" B_PRId32 "\n", __func__, i);
|
uint8 con_obj_id = (B_LENDIAN_TO_HOST_INT16(path->usConnObjectId)
|
||||||
|
|
||||||
uint16 igp_lane_info;
|
|
||||||
|
|
||||||
uint8 con_obj_id
|
|
||||||
= (B_LENDIAN_TO_HOST_INT16(path->usConnObjectId)
|
|
||||||
& OBJECT_ID_MASK) >> OBJECT_ID_SHIFT;
|
& OBJECT_ID_MASK) >> OBJECT_ID_SHIFT;
|
||||||
|
|
||||||
//uint8 con_obj_num
|
//uint8 con_obj_num
|
||||||
// = (B_LENDIAN_TO_HOST_INT16(path->usConnObjectId)
|
// = (B_LENDIAN_TO_HOST_INT16(path->usConnObjectId)
|
||||||
// & ENUM_ID_MASK) >> ENUM_ID_SHIFT;
|
// & ENUM_ID_MASK) >> ENUM_ID_SHIFT;
|
||||||
@@ -392,30 +395,31 @@ detect_connectors_manual()
|
|||||||
// = (B_LENDIAN_TO_HOST_INT16(path->usConnObjectId)
|
// = (B_LENDIAN_TO_HOST_INT16(path->usConnObjectId)
|
||||||
// & OBJECT_TYPE_MASK) >> OBJECT_TYPE_SHIFT;
|
// & OBJECT_TYPE_MASK) >> OBJECT_TYPE_SHIFT;
|
||||||
|
|
||||||
// TODO : CV support
|
|
||||||
if (B_LENDIAN_TO_HOST_INT16(path->usDeviceTag)
|
if (B_LENDIAN_TO_HOST_INT16(path->usDeviceTag)
|
||||||
== ATOM_DEVICE_CV_SUPPORT) {
|
== ATOM_DEVICE_CV_SUPPORT) {
|
||||||
|
TRACE("%s: Path #%" B_PRId32 ": skipping component video.\n",
|
||||||
|
__func__, i);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint16 igp_lane_info;
|
||||||
if (0)
|
if (0)
|
||||||
ERROR("%s: TODO : IGP chip connector detection\n", __func__);
|
ERROR("%s: TODO : IGP chip connector detection\n", __func__);
|
||||||
else {
|
else {
|
||||||
igp_lane_info = 0;
|
igp_lane_info = 0;
|
||||||
connector_type = manual_connector_convert[con_obj_id];
|
connector_type = connector_convert[con_obj_id];
|
||||||
connector_object_id = con_obj_id;
|
connector_object_id = con_obj_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (connector_type == VIDEO_CONNECTOR_UNKNOWN) {
|
if (connector_type == VIDEO_CONNECTOR_UNKNOWN) {
|
||||||
TRACE("%s: Unknown connector, skipping\n", __func__);
|
TRACE("%s: Path #%" B_PRId32 ": skipping unknown connector.\n",
|
||||||
|
__func__, i);
|
||||||
continue;
|
continue;
|
||||||
} else {
|
|
||||||
TRACE("%s: Found connector %s\n", __func__,
|
|
||||||
decode_connector_name(connector_type));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// We have to go deeper! -AMD
|
// TODO : to find encoder for connector
|
||||||
// (find encoder for connector)
|
#if 0
|
||||||
int32 j;
|
int32 j;
|
||||||
for (j = 0; j < ((B_LENDIAN_TO_HOST_INT16(path->usSize) - 8) / 2);
|
for (j = 0; j < ((B_LENDIAN_TO_HOST_INT16(path->usSize) - 8) / 2);
|
||||||
j++) {
|
j++) {
|
||||||
@@ -473,13 +477,21 @@ detect_connectors_manual()
|
|||||||
ERROR("%s: TODO : Router object?\n", __func__);
|
ERROR("%s: TODO : Router object?\n", __func__);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// TODO : look up gpio for ddc, hpd
|
// TODO : look up gpio for ddc, hpd
|
||||||
|
|
||||||
// TODO : aux chan transactions
|
// TODO : aux chan transactions
|
||||||
|
|
||||||
// TODO : add connector
|
TRACE("%s: Path #%" B_PRId32 ": Found %s (0x%" B_PRIX32 ")\n",
|
||||||
TRACE("%s: add connector\n", __func__);
|
__func__, i, decode_connector_name(connector_type),
|
||||||
|
connector_type);
|
||||||
|
gConnector[connector_index]->valid = true;
|
||||||
|
gConnector[connector_index]->connector_type = connector_type;
|
||||||
|
gConnector[connector_index]->connector_object_id
|
||||||
|
= connector_object_id;
|
||||||
|
connector_index++;
|
||||||
|
|
||||||
// radeon_add_atom_connector(dev,
|
// radeon_add_atom_connector(dev,
|
||||||
// conn_id,
|
// conn_id,
|
||||||
// le16_to_cpu(path-> usDeviceTag),
|
// le16_to_cpu(path-> usDeviceTag),
|
||||||
@@ -489,7 +501,7 @@ detect_connectors_manual()
|
|||||||
// &hpd,
|
// &hpd,
|
||||||
// &router);
|
// &router);
|
||||||
}
|
}
|
||||||
}
|
} // end for each display path
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
|
|
||||||
// convert radeon connector to common connector type
|
// convert radeon connector to common connector type
|
||||||
const int connector_convert[] = {
|
const int connector_convert_legacy[] = {
|
||||||
VIDEO_CONNECTOR_UNKNOWN,
|
VIDEO_CONNECTOR_UNKNOWN,
|
||||||
VIDEO_CONNECTOR_VGA,
|
VIDEO_CONNECTOR_VGA,
|
||||||
VIDEO_CONNECTOR_DVII,
|
VIDEO_CONNECTOR_DVII,
|
||||||
@@ -32,7 +32,7 @@ const int connector_convert[] = {
|
|||||||
VIDEO_CONNECTOR_DP
|
VIDEO_CONNECTOR_DP
|
||||||
};
|
};
|
||||||
|
|
||||||
const int manual_connector_convert[] = {
|
const int connector_convert[] = {
|
||||||
VIDEO_CONNECTOR_UNKNOWN,
|
VIDEO_CONNECTOR_UNKNOWN,
|
||||||
VIDEO_CONNECTOR_DVII,
|
VIDEO_CONNECTOR_DVII,
|
||||||
VIDEO_CONNECTOR_DVII,
|
VIDEO_CONNECTOR_DVII,
|
||||||
@@ -58,8 +58,9 @@ const int manual_connector_convert[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
status_t init_registers(register_info* reg, uint8 crtid);
|
status_t init_registers(register_info* reg, uint8 crtid);
|
||||||
status_t detect_crt_ranges(uint32 crtid);
|
status_t detect_connectors_legacy();
|
||||||
status_t detect_connectors();
|
status_t detect_connectors();
|
||||||
|
status_t detect_crt_ranges(uint32 crtid);
|
||||||
status_t detect_displays();
|
status_t detect_displays();
|
||||||
void debug_displays();
|
void debug_displays();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user