提交 36868bda 编写于 作者: A Alex Deucher 提交者: Dave Airlie

drm/radeon/kms: parse DCE5 encoder caps when setting up encoders

Needed to tell which DIG encoders are HBR2 capable for DP 1.2.
Signed-off-by: NAlex Deucher <alexdeucher@gmail.com>
Signed-off-by: NDave Airlie <airlied@redhat.com>
上级 d07f4e83
...@@ -37,7 +37,7 @@ radeon_get_encoder_enum(struct drm_device *dev, uint32_t supported_device, ...@@ -37,7 +37,7 @@ radeon_get_encoder_enum(struct drm_device *dev, uint32_t supported_device,
extern void radeon_link_encoder_connector(struct drm_device *dev); extern void radeon_link_encoder_connector(struct drm_device *dev);
extern void extern void
radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_enum, radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_enum,
uint32_t supported_device); uint32_t supported_device, u16 caps);
/* from radeon_connector.c */ /* from radeon_connector.c */
extern void extern void
...@@ -537,6 +537,7 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) ...@@ -537,6 +537,7 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev)
u16 size, data_offset; u16 size, data_offset;
u8 frev, crev; u8 frev, crev;
ATOM_CONNECTOR_OBJECT_TABLE *con_obj; ATOM_CONNECTOR_OBJECT_TABLE *con_obj;
ATOM_ENCODER_OBJECT_TABLE *enc_obj;
ATOM_OBJECT_TABLE *router_obj; ATOM_OBJECT_TABLE *router_obj;
ATOM_DISPLAY_OBJECT_PATH_TABLE *path_obj; ATOM_DISPLAY_OBJECT_PATH_TABLE *path_obj;
ATOM_OBJECT_HEADER *obj_header; ATOM_OBJECT_HEADER *obj_header;
...@@ -561,6 +562,9 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) ...@@ -561,6 +562,9 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev)
con_obj = (ATOM_CONNECTOR_OBJECT_TABLE *) con_obj = (ATOM_CONNECTOR_OBJECT_TABLE *)
(ctx->bios + data_offset + (ctx->bios + data_offset +
le16_to_cpu(obj_header->usConnectorObjectTableOffset)); le16_to_cpu(obj_header->usConnectorObjectTableOffset));
enc_obj = (ATOM_ENCODER_OBJECT_TABLE *)
(ctx->bios + data_offset +
le16_to_cpu(obj_header->usEncoderObjectTableOffset));
router_obj = (ATOM_OBJECT_TABLE *) router_obj = (ATOM_OBJECT_TABLE *)
(ctx->bios + data_offset + (ctx->bios + data_offset +
le16_to_cpu(obj_header->usRouterObjectTableOffset)); le16_to_cpu(obj_header->usRouterObjectTableOffset));
...@@ -666,14 +670,35 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) ...@@ -666,14 +670,35 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev)
OBJECT_TYPE_MASK) >> OBJECT_TYPE_SHIFT; OBJECT_TYPE_MASK) >> OBJECT_TYPE_SHIFT;
if (grph_obj_type == GRAPH_OBJECT_TYPE_ENCODER) { if (grph_obj_type == GRAPH_OBJECT_TYPE_ENCODER) {
u16 encoder_obj = le16_to_cpu(path->usGraphicObjIds[j]); for (k = 0; k < enc_obj->ucNumberOfObjects; k++) {
u16 encoder_obj = le16_to_cpu(enc_obj->asObjects[k].usObjectID);
radeon_add_atom_encoder(dev, if (le16_to_cpu(path->usGraphicObjIds[j]) == encoder_obj) {
encoder_obj, ATOM_COMMON_RECORD_HEADER *record = (ATOM_COMMON_RECORD_HEADER *)
le16_to_cpu (ctx->bios + data_offset +
(path-> le16_to_cpu(enc_obj->asObjects[k].usRecordOffset));
usDeviceTag)); ATOM_ENCODER_CAP_RECORD *cap_record;
u16 caps = 0;
while (record->ucRecordType > 0 &&
record->ucRecordType <= ATOM_MAX_OBJECT_RECORD_NUMBER) {
switch (record->ucRecordType) {
case ATOM_ENCODER_CAP_RECORD_TYPE:
cap_record =(ATOM_ENCODER_CAP_RECORD *)
record;
caps = le16_to_cpu(cap_record->usEncoderCap);
break;
}
record = (ATOM_COMMON_RECORD_HEADER *)
((char *)record + record->ucRecordSize);
}
radeon_add_atom_encoder(dev,
encoder_obj,
le16_to_cpu
(path->
usDeviceTag),
caps);
}
}
} else if (grph_obj_type == GRAPH_OBJECT_TYPE_ROUTER) { } else if (grph_obj_type == GRAPH_OBJECT_TYPE_ROUTER) {
for (k = 0; k < router_obj->ucNumberOfObjects; k++) { for (k = 0; k < router_obj->ucNumberOfObjects; k++) {
u16 router_obj_id = le16_to_cpu(router_obj->asObjects[k].usObjectID); u16 router_obj_id = le16_to_cpu(router_obj->asObjects[k].usObjectID);
...@@ -1007,7 +1032,8 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct ...@@ -1007,7 +1032,8 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct
radeon_get_encoder_enum(dev, radeon_get_encoder_enum(dev,
(1 << i), (1 << i),
dac), dac),
(1 << i)); (1 << i),
0);
else else
radeon_add_legacy_encoder(dev, radeon_add_legacy_encoder(dev,
radeon_get_encoder_enum(dev, radeon_get_encoder_enum(dev,
......
...@@ -2046,7 +2046,10 @@ radeon_atombios_set_dig_info(struct radeon_encoder *radeon_encoder) ...@@ -2046,7 +2046,10 @@ radeon_atombios_set_dig_info(struct radeon_encoder *radeon_encoder)
} }
void void
radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_enum, uint32_t supported_device) radeon_add_atom_encoder(struct drm_device *dev,
uint32_t encoder_enum,
uint32_t supported_device,
u16 caps)
{ {
struct radeon_device *rdev = dev->dev_private; struct radeon_device *rdev = dev->dev_private;
struct drm_encoder *encoder; struct drm_encoder *encoder;
...@@ -2089,6 +2092,7 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_enum, uint32_t ...@@ -2089,6 +2092,7 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_enum, uint32_t
radeon_encoder->rmx_type = RMX_OFF; radeon_encoder->rmx_type = RMX_OFF;
radeon_encoder->underscan_type = UNDERSCAN_OFF; radeon_encoder->underscan_type = UNDERSCAN_OFF;
radeon_encoder->is_ext_encoder = false; radeon_encoder->is_ext_encoder = false;
radeon_encoder->caps = caps;
switch (radeon_encoder->encoder_id) { switch (radeon_encoder->encoder_id) {
case ENCODER_OBJECT_ID_INTERNAL_LVDS: case ENCODER_OBJECT_ID_INTERNAL_LVDS:
......
...@@ -379,6 +379,7 @@ struct radeon_encoder { ...@@ -379,6 +379,7 @@ struct radeon_encoder {
int hdmi_audio_workaround; int hdmi_audio_workaround;
int hdmi_buffer_status; int hdmi_buffer_status;
bool is_ext_encoder; bool is_ext_encoder;
u16 caps;
}; };
struct radeon_connector_atom_dig { struct radeon_connector_atom_dig {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册