Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 174644
b: refs/heads/master
c: eed45b3
h: refs/heads/master
v: v3
  • Loading branch information
Alex Deucher authored and Dave Airlie committed Dec 8, 2009
1 parent 17bd7ab commit c5349b5
Show file tree
Hide file tree
Showing 8 changed files with 331 additions and 85 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 53c1e09fea4cf3fc0ec1f735a5fcab78c43cb55d
refs/heads/master: eed45b30cd1423f8dc10b4312700773cac13c1c8
2 changes: 1 addition & 1 deletion trunk/drivers/gpu/drm/radeon/atombios.h
Original file line number Diff line number Diff line change
Expand Up @@ -2680,7 +2680,7 @@ typedef struct _ATOM_I2C_RECORD {
typedef struct _ATOM_HPD_INT_RECORD {
ATOM_COMMON_RECORD_HEADER sheader;
UCHAR ucHPDIntGPIOID; /* Corresponding block in GPIO_PIN_INFO table gives the pin info */
UCHAR ucPluggged_PinState;
UCHAR ucPlugged_PinState;
} ATOM_HPD_INT_RECORD;

typedef struct _ATOM_OUTPUT_PROTECTION_RECORD {
Expand Down
2 changes: 2 additions & 0 deletions trunk/drivers/gpu/drm/radeon/r500_reg.h
Original file line number Diff line number Diff line change
Expand Up @@ -716,6 +716,8 @@

#define AVIVO_DVOA_BIT_DEPTH_CONTROL 0x7988

#define AVIVO_DC_GPIO_HPD_A 0x7e94

#define AVIVO_GPIO_0 0x7e30
#define AVIVO_GPIO_1 0x7e40
#define AVIVO_GPIO_2 0x7e50
Expand Down
190 changes: 149 additions & 41 deletions trunk/drivers/gpu/drm/radeon/radeon_atombios.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ radeon_add_atom_connector(struct drm_device *dev,
int connector_type,
struct radeon_i2c_bus_rec *i2c_bus,
bool linkb, uint32_t igp_lane_info,
uint16_t connector_object_id);
uint16_t connector_object_id,
struct radeon_hpd *hpd);

/* from radeon_legacy_encoder.c */
extern void
Expand All @@ -60,10 +61,9 @@ union atom_supported_devices {
struct _ATOM_SUPPORTED_DEVICES_INFO_2d1 info_2d1;
};

static inline struct radeon_i2c_bus_rec radeon_lookup_gpio(struct drm_device *dev,
uint8_t id)
static inline struct radeon_i2c_bus_rec radeon_lookup_i2c_gpio(struct radeon_device *rdev,
uint8_t id)
{
struct radeon_device *rdev = dev->dev_private;
struct atom_context *ctx = rdev->mode_info.atom_context;
ATOM_GPIO_I2C_ASSIGMENT *gpio;
struct radeon_i2c_bus_rec i2c;
Expand Down Expand Up @@ -114,11 +114,80 @@ static inline struct radeon_i2c_bus_rec radeon_lookup_gpio(struct drm_device *de
return i2c;
}

static inline struct radeon_gpio_rec radeon_lookup_gpio(struct radeon_device *rdev,
u8 id)
{
struct atom_context *ctx = rdev->mode_info.atom_context;
struct radeon_gpio_rec gpio;
int index = GetIndexIntoMasterTable(DATA, GPIO_Pin_LUT);
struct _ATOM_GPIO_PIN_LUT *gpio_info;
ATOM_GPIO_PIN_ASSIGNMENT *pin;
u16 data_offset, size;
int i, num_indices;

memset(&gpio, 0, sizeof(struct radeon_gpio_rec));
gpio.valid = false;

atom_parse_data_header(ctx, index, &size, NULL, NULL, &data_offset);

gpio_info = (struct _ATOM_GPIO_PIN_LUT *)(ctx->bios + data_offset);

num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) / sizeof(ATOM_GPIO_PIN_ASSIGNMENT);

for (i = 0; i < num_indices; i++) {
pin = &gpio_info->asGPIO_Pin[i];
if (id == pin->ucGPIO_ID) {
gpio.id = pin->ucGPIO_ID;
gpio.reg = pin->usGpioPin_AIndex * 4;
gpio.mask = (1 << pin->ucGpioPinBitShift);
gpio.valid = true;
break;
}
}

return gpio;
}

static struct radeon_hpd radeon_atom_get_hpd_info_from_gpio(struct radeon_device *rdev,
struct radeon_gpio_rec *gpio)
{
struct radeon_hpd hpd;
hpd.gpio = *gpio;
if (gpio->reg == AVIVO_DC_GPIO_HPD_A) {
switch(gpio->mask) {
case (1 << 0):
hpd.hpd = RADEON_HPD_1;
break;
case (1 << 8):
hpd.hpd = RADEON_HPD_2;
break;
case (1 << 16):
hpd.hpd = RADEON_HPD_3;
break;
case (1 << 24):
hpd.hpd = RADEON_HPD_4;
break;
case (1 << 26):
hpd.hpd = RADEON_HPD_5;
break;
case (1 << 28):
hpd.hpd = RADEON_HPD_6;
break;
default:
hpd.hpd = RADEON_HPD_NONE;
break;
}
} else
hpd.hpd = RADEON_HPD_NONE;
return hpd;
}

static bool radeon_atom_apply_quirks(struct drm_device *dev,
uint32_t supported_device,
int *connector_type,
struct radeon_i2c_bus_rec *i2c_bus,
uint16_t *line_mux)
uint16_t *line_mux,
struct radeon_hpd *hpd)
{

/* Asus M2A-VM HDMI board lists the DVI port as HDMI */
Expand Down Expand Up @@ -279,16 +348,19 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev)
struct radeon_mode_info *mode_info = &rdev->mode_info;
struct atom_context *ctx = mode_info->atom_context;
int index = GetIndexIntoMasterTable(DATA, Object_Header);
uint16_t size, data_offset;
uint8_t frev, crev, line_mux = 0;
u16 size, data_offset;
u8 frev, crev;
ATOM_CONNECTOR_OBJECT_TABLE *con_obj;
ATOM_DISPLAY_OBJECT_PATH_TABLE *path_obj;
ATOM_OBJECT_HEADER *obj_header;
int i, j, path_size, device_support;
int connector_type;
uint16_t igp_lane_info, conn_id, connector_object_id;
u16 igp_lane_info, conn_id, connector_object_id;
bool linkb;
struct radeon_i2c_bus_rec ddc_bus;
struct radeon_gpio_rec gpio;
struct radeon_hpd hpd;

atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset);

if (data_offset == 0)
Expand Down Expand Up @@ -414,10 +486,9 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev)
}
}

/* look up gpio for ddc */
/* look up gpio for ddc, hpd */
if ((le16_to_cpu(path->usDeviceTag) &
(ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT))
== 0) {
(ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) == 0) {
for (j = 0; j < con_obj->ucNumberOfObjects; j++) {
if (le16_to_cpu(path->usConnObjectId) ==
le16_to_cpu(con_obj->asObjects[j].
Expand All @@ -431,21 +502,31 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev)
asObjects[j].
usRecordOffset));
ATOM_I2C_RECORD *i2c_record;
ATOM_HPD_INT_RECORD *hpd_record;
hpd.hpd = RADEON_HPD_NONE;

while (record->ucRecordType > 0
&& record->
ucRecordType <=
ATOM_MAX_OBJECT_RECORD_NUMBER) {
switch (record->
ucRecordType) {
switch (record->ucRecordType) {
case ATOM_I2C_RECORD_TYPE:
i2c_record =
(ATOM_I2C_RECORD
*) record;
line_mux =
i2c_record->
sucI2cId.
bfI2C_LineMux;
(ATOM_I2C_RECORD *)
record;
ddc_bus = radeon_lookup_i2c_gpio(rdev,
i2c_record->
sucI2cId.
bfI2C_LineMux);
break;
case ATOM_HPD_INT_RECORD_TYPE:
hpd_record =
(ATOM_HPD_INT_RECORD *)
record;
gpio = radeon_lookup_gpio(rdev,
hpd_record->ucHPDIntGPIOID);
hpd = radeon_atom_get_hpd_info_from_gpio(rdev, &gpio);
hpd.plugged_state = hpd_record->ucPlugged_PinState;
break;
}
record =
Expand All @@ -458,24 +539,16 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev)
break;
}
}
} else
line_mux = 0;

if ((le16_to_cpu(path->usDeviceTag) ==
ATOM_DEVICE_TV1_SUPPORT)
|| (le16_to_cpu(path->usDeviceTag) ==
ATOM_DEVICE_TV2_SUPPORT)
|| (le16_to_cpu(path->usDeviceTag) ==
ATOM_DEVICE_CV_SUPPORT))
} else {
hpd.hpd = RADEON_HPD_NONE;
ddc_bus.valid = false;
else
ddc_bus = radeon_lookup_gpio(dev, line_mux);
}

conn_id = le16_to_cpu(path->usConnObjectId);

if (!radeon_atom_apply_quirks
(dev, le16_to_cpu(path->usDeviceTag), &connector_type,
&ddc_bus, &conn_id))
&ddc_bus, &conn_id, &hpd))
continue;

radeon_add_atom_connector(dev,
Expand All @@ -484,7 +557,8 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev)
usDeviceTag),
connector_type, &ddc_bus,
linkb, igp_lane_info,
connector_object_id);
connector_object_id,
&hpd);

}
}
Expand Down Expand Up @@ -539,6 +613,7 @@ struct bios_connector {
uint16_t devices;
int connector_type;
struct radeon_i2c_bus_rec ddc_bus;
struct radeon_hpd hpd;
};

bool radeon_get_atom_connector_info_from_supported_devices_table(struct
Expand All @@ -554,7 +629,7 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct
uint16_t device_support;
uint8_t dac;
union atom_supported_devices *supported_devices;
int i, j;
int i, j, max_device;
struct bios_connector bios_connectors[ATOM_MAX_SUPPORTED_DEVICE];

atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset);
Expand All @@ -564,7 +639,12 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct

device_support = le16_to_cpu(supported_devices->info.usDeviceSupport);

for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) {
if (frev > 1)
max_device = ATOM_MAX_SUPPORTED_DEVICE;
else
max_device = ATOM_MAX_SUPPORTED_DEVICE_INFO;

for (i = 0; i < max_device; i++) {
ATOM_CONNECTOR_INFO_I2C ci =
supported_devices->info.asConnInfo[i];

Expand Down Expand Up @@ -619,8 +699,30 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct
bios_connectors[i].line_mux = 52;
} else
bios_connectors[i].ddc_bus =
radeon_lookup_gpio(dev,
bios_connectors[i].line_mux);
radeon_lookup_i2c_gpio(rdev,
bios_connectors[i].line_mux);

if ((crev > 1) && (frev > 1)) {
u8 isb = supported_devices->info_2d1.asIntSrcInfo[i].ucIntSrcBitmap;
switch (isb) {
case 0x4:
bios_connectors[i].hpd.hpd = RADEON_HPD_1;
break;
case 0xa:
bios_connectors[i].hpd.hpd = RADEON_HPD_2;
break;
default:
bios_connectors[i].hpd.hpd = RADEON_HPD_NONE;
break;
}
} else {
if (i == ATOM_DEVICE_DFP1_INDEX)
bios_connectors[i].hpd.hpd = RADEON_HPD_1;
else if (i == ATOM_DEVICE_DFP2_INDEX)
bios_connectors[i].hpd.hpd = RADEON_HPD_2;
else
bios_connectors[i].hpd.hpd = RADEON_HPD_NONE;
}

/* Always set the connector type to VGA for CRT1/CRT2. if they are
* shared with a DVI port, we'll pick up the DVI connector when we
Expand All @@ -632,7 +734,8 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct

if (!radeon_atom_apply_quirks
(dev, (1 << i), &bios_connectors[i].connector_type,
&bios_connectors[i].ddc_bus, &bios_connectors[i].line_mux))
&bios_connectors[i].ddc_bus, &bios_connectors[i].line_mux,
&bios_connectors[i].hpd))
continue;

bios_connectors[i].valid = true;
Expand All @@ -654,9 +757,9 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct
}

/* combine shared connectors */
for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) {
for (i = 0; i < max_device; i++) {
if (bios_connectors[i].valid) {
for (j = 0; j < ATOM_MAX_SUPPORTED_DEVICE; j++) {
for (j = 0; j < max_device; j++) {
if (bios_connectors[j].valid && (i != j)) {
if (bios_connectors[i].line_mux ==
bios_connectors[j].line_mux) {
Expand All @@ -680,6 +783,10 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct
bios_connectors[i].
connector_type =
DRM_MODE_CONNECTOR_DVII;
if (bios_connectors[j].devices &
(ATOM_DEVICE_DFP_SUPPORT))
bios_connectors[i].hpd =
bios_connectors[j].hpd;
bios_connectors[j].
valid = false;
}
Expand All @@ -690,7 +797,7 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct
}

/* add the connectors */
for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) {
for (i = 0; i < max_device; i++) {
if (bios_connectors[i].valid) {
uint16_t connector_object_id =
atombios_get_connector_object_id(dev,
Expand All @@ -703,7 +810,8 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct
connector_type,
&bios_connectors[i].ddc_bus,
false, 0,
connector_object_id);
connector_object_id,
&bios_connectors[i].hpd);
}
}

Expand Down
Loading

0 comments on commit c5349b5

Please sign in to comment.