Commit fcec570b authored by Alex Deucher's avatar Alex Deucher Committed by Dave Airlie

drm/radeon/kms: add support for external tmds on legacy boards

This enables initialization of external tmds chips on pre-atom
and mac systems.  Macs are untested.  Also, some macs have single
link tmds chips while others have dual link tmds chips.  We need
to figure out which ones have which.

This gets external TMDS working on my RS485 and RV380.
Signed-off-by: default avatarAlex Deucher <alexdeucher@gmail.com>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent 9b9fe724
...@@ -993,8 +993,8 @@ static const struct radeon_tmds_pll default_tmds_pll[CHIP_LAST][4] = { ...@@ -993,8 +993,8 @@ static const struct radeon_tmds_pll default_tmds_pll[CHIP_LAST][4] = {
{{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, /* CHIP_R420 */ {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, /* CHIP_R420 */
{{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, /* CHIP_R423 */ {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, /* CHIP_R423 */
{{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, /* CHIP_RV410 */ {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, /* CHIP_RV410 */
{{15000, 0xb0155}, {0xffffffff, 0xb01cb}, {0, 0}, {0, 0}}, /* CHIP_RS400 */ { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, /* CHIP_RS400 */
{{15000, 0xb0155}, {0xffffffff, 0xb01cb}, {0, 0}, {0, 0}}, /* CHIP_RS480 */ { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, /* CHIP_RS480 */
}; };
bool radeon_legacy_get_tmds_info_from_table(struct radeon_encoder *encoder, bool radeon_legacy_get_tmds_info_from_table(struct radeon_encoder *encoder,
...@@ -1028,7 +1028,6 @@ bool radeon_legacy_get_tmds_info_from_combios(struct radeon_encoder *encoder, ...@@ -1028,7 +1028,6 @@ bool radeon_legacy_get_tmds_info_from_combios(struct radeon_encoder *encoder,
tmds_info = combios_get_table_offset(dev, COMBIOS_DFP_INFO_TABLE); tmds_info = combios_get_table_offset(dev, COMBIOS_DFP_INFO_TABLE);
if (tmds_info) { if (tmds_info) {
ver = RBIOS8(tmds_info); ver = RBIOS8(tmds_info);
DRM_INFO("DFP table revision: %d\n", ver); DRM_INFO("DFP table revision: %d\n", ver);
if (ver == 3) { if (ver == 3) {
...@@ -1063,45 +1062,132 @@ bool radeon_legacy_get_tmds_info_from_combios(struct radeon_encoder *encoder, ...@@ -1063,45 +1062,132 @@ bool radeon_legacy_get_tmds_info_from_combios(struct radeon_encoder *encoder,
tmds->tmds_pll[i].value); tmds->tmds_pll[i].value);
} }
} }
} else } else {
DRM_INFO("No TMDS info found in BIOS\n"); DRM_INFO("No TMDS info found in BIOS\n");
return false;
}
return true; return true;
} }
struct radeon_encoder_int_tmds *radeon_combios_get_tmds_info(struct radeon_encoder *encoder) bool radeon_legacy_get_ext_tmds_info_from_table(struct radeon_encoder *encoder,
struct radeon_encoder_ext_tmds *tmds)
{ {
struct radeon_encoder_int_tmds *tmds = NULL; struct drm_device *dev = encoder->base.dev;
bool ret; struct radeon_device *rdev = dev->dev_private;
struct radeon_i2c_bus_rec i2c_bus;
tmds = kzalloc(sizeof(struct radeon_encoder_int_tmds), GFP_KERNEL);
if (!tmds) /* default for macs */
return NULL; i2c_bus = combios_setup_i2c_bus(RADEON_GPIO_MONID);
tmds->i2c_bus = radeon_i2c_create(dev, &i2c_bus, "DVO");
ret = radeon_legacy_get_tmds_info_from_combios(encoder, tmds); /* XXX some macs have duallink chips */
if (ret == false) switch (rdev->mode_info.connector_table) {
radeon_legacy_get_tmds_info_from_table(encoder, tmds); case CT_POWERBOOK_EXTERNAL:
case CT_MINI_EXTERNAL:
default:
tmds->dvo_chip = DVO_SIL164;
tmds->slave_addr = 0x70 >> 1; /* 7 bit addressing */
break;
}
return tmds; return true;
} }
void radeon_combios_get_ext_tmds_info(struct radeon_encoder *encoder) bool radeon_legacy_get_ext_tmds_info_from_combios(struct radeon_encoder *encoder,
struct radeon_encoder_ext_tmds *tmds)
{ {
struct drm_device *dev = encoder->base.dev; struct drm_device *dev = encoder->base.dev;
struct radeon_device *rdev = dev->dev_private; struct radeon_device *rdev = dev->dev_private;
uint16_t ext_tmds_info; uint16_t offset;
uint8_t ver; uint8_t ver, id, blocks, clk, data;
int i;
enum radeon_combios_ddc gpio;
struct radeon_i2c_bus_rec i2c_bus;
if (rdev->bios == NULL) if (rdev->bios == NULL)
return; return false;
ext_tmds_info = tmds->i2c_bus = NULL;
combios_get_table_offset(dev, COMBIOS_EXT_TMDS_INFO_TABLE); if (rdev->flags & RADEON_IS_IGP) {
if (ext_tmds_info) { offset = combios_get_table_offset(dev, COMBIOS_I2C_INFO_TABLE);
ver = RBIOS8(ext_tmds_info); if (offset) {
ver = RBIOS8(offset);
DRM_INFO("GPIO Table revision: %d\n", ver);
blocks = RBIOS8(offset + 2);
for (i = 0; i < blocks; i++) {
id = RBIOS8(offset + 3 + (i * 5) + 0);
if (id == 136) {
clk = RBIOS8(offset + 3 + (i * 5) + 3);
data = RBIOS8(offset + 3 + (i * 5) + 4);
i2c_bus.valid = true;
i2c_bus.mask_clk_mask = (1 << clk);
i2c_bus.mask_data_mask = (1 << data);
i2c_bus.a_clk_mask = (1 << clk);
i2c_bus.a_data_mask = (1 << data);
i2c_bus.en_clk_mask = (1 << clk);
i2c_bus.en_data_mask = (1 << data);
i2c_bus.y_clk_mask = (1 << clk);
i2c_bus.y_data_mask = (1 << data);
i2c_bus.mask_clk_reg = RADEON_GPIOPAD_MASK;
i2c_bus.mask_data_reg = RADEON_GPIOPAD_MASK;
i2c_bus.a_clk_reg = RADEON_GPIOPAD_A;
i2c_bus.a_data_reg = RADEON_GPIOPAD_A;
i2c_bus.en_clk_reg = RADEON_GPIOPAD_EN;
i2c_bus.en_data_reg = RADEON_GPIOPAD_EN;
i2c_bus.y_clk_reg = RADEON_GPIOPAD_Y;
i2c_bus.y_data_reg = RADEON_GPIOPAD_Y;
tmds->i2c_bus = radeon_i2c_create(dev, &i2c_bus, "DVO");
tmds->dvo_chip = DVO_SIL164;
tmds->slave_addr = 0x70 >> 1; /* 7 bit addressing */
break;
}
}
}
} else {
offset = combios_get_table_offset(dev, COMBIOS_EXT_TMDS_INFO_TABLE);
if (offset) {
ver = RBIOS8(offset);
DRM_INFO("External TMDS Table revision: %d\n", ver); DRM_INFO("External TMDS Table revision: %d\n", ver);
// TODO tmds->slave_addr = RBIOS8(offset + 4 + 2);
tmds->slave_addr >>= 1; /* 7 bit addressing */
gpio = RBIOS8(offset + 4 + 3);
switch (gpio) {
case DDC_MONID:
i2c_bus = combios_setup_i2c_bus(RADEON_GPIO_MONID);
tmds->i2c_bus = radeon_i2c_create(dev, &i2c_bus, "DVO");
break;
case DDC_DVI:
i2c_bus = combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
tmds->i2c_bus = radeon_i2c_create(dev, &i2c_bus, "DVO");
break;
case DDC_VGA:
i2c_bus = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
tmds->i2c_bus = radeon_i2c_create(dev, &i2c_bus, "DVO");
break;
case DDC_CRT2:
/* R3xx+ chips don't have GPIO_CRT2_DDC gpio pad */
if (rdev->family >= CHIP_R300)
i2c_bus = combios_setup_i2c_bus(RADEON_GPIO_MONID);
else
i2c_bus = combios_setup_i2c_bus(RADEON_GPIO_CRT2_DDC);
tmds->i2c_bus = radeon_i2c_create(dev, &i2c_bus, "DVO");
break;
case DDC_LCD: /* MM i2c */
DRM_ERROR("MM i2c requires hw i2c engine\n");
break;
default:
DRM_ERROR("Unsupported gpio %d\n", gpio);
break;
} }
}
}
if (!tmds->i2c_bus) {
DRM_INFO("No valid Ext TMDS info found in BIOS\n");
return false;
}
return true;
} }
bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
...@@ -1577,10 +1663,15 @@ static bool radeon_apply_legacy_quirks(struct drm_device *dev, ...@@ -1577,10 +1663,15 @@ static bool radeon_apply_legacy_quirks(struct drm_device *dev,
ddc_i2c->a_data_reg = RADEON_GPIOPAD_A; ddc_i2c->a_data_reg = RADEON_GPIOPAD_A;
ddc_i2c->en_clk_reg = RADEON_GPIOPAD_EN; ddc_i2c->en_clk_reg = RADEON_GPIOPAD_EN;
ddc_i2c->en_data_reg = RADEON_GPIOPAD_EN; ddc_i2c->en_data_reg = RADEON_GPIOPAD_EN;
ddc_i2c->y_clk_reg = RADEON_LCD_GPIO_Y_REG; ddc_i2c->y_clk_reg = RADEON_GPIOPAD_Y;
ddc_i2c->y_data_reg = RADEON_LCD_GPIO_Y_REG; ddc_i2c->y_data_reg = RADEON_GPIOPAD_Y;
} }
/* R3xx+ chips don't have GPIO_CRT2_DDC gpio pad */
if ((rdev->family >= CHIP_R300) &&
ddc_i2c->mask_clk_reg == RADEON_GPIO_CRT2_DDC)
*ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
/* Certain IBM chipset RN50s have a BIOS reporting two VGAs, /* Certain IBM chipset RN50s have a BIOS reporting two VGAs,
one with VGA DDC and one with CRT2 DDC. - kill the CRT2 DDC one */ one with VGA DDC and one with CRT2 DDC. - kill the CRT2 DDC one */
if (dev->pdev->device == 0x515e && if (dev->pdev->device == 0x515e &&
...@@ -2014,6 +2105,193 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) ...@@ -2014,6 +2105,193 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev)
return true; return true;
} }
void radeon_external_tmds_setup(struct drm_encoder *encoder)
{
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
struct radeon_encoder_ext_tmds *tmds = radeon_encoder->enc_priv;
if (!tmds)
return;
switch (tmds->dvo_chip) {
case DVO_SIL164:
/* sil 164 */
radeon_i2c_do_lock(tmds->i2c_bus, 1);
radeon_i2c_sw_put_byte(tmds->i2c_bus,
tmds->slave_addr,
0x08, 0x30);
radeon_i2c_sw_put_byte(tmds->i2c_bus,
tmds->slave_addr,
0x09, 0x00);
radeon_i2c_sw_put_byte(tmds->i2c_bus,
tmds->slave_addr,
0x0a, 0x90);
radeon_i2c_sw_put_byte(tmds->i2c_bus,
tmds->slave_addr,
0x0c, 0x89);
radeon_i2c_sw_put_byte(tmds->i2c_bus,
tmds->slave_addr,
0x08, 0x3b);
radeon_i2c_do_lock(tmds->i2c_bus, 0);
break;
case DVO_SIL1178:
/* sil 1178 - untested */
/*
* 0x0f, 0x44
* 0x0f, 0x4c
* 0x0e, 0x01
* 0x0a, 0x80
* 0x09, 0x30
* 0x0c, 0xc9
* 0x0d, 0x70
* 0x08, 0x32
* 0x08, 0x33
*/
break;
default:
break;
}
}
bool radeon_combios_external_tmds_setup(struct drm_encoder *encoder)
{
struct drm_device *dev = encoder->dev;
struct radeon_device *rdev = dev->dev_private;
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
uint16_t offset;
uint8_t blocks, slave_addr, rev;
uint32_t index, id;
uint32_t reg, val, and_mask, or_mask;
struct radeon_encoder_ext_tmds *tmds = radeon_encoder->enc_priv;
if (rdev->bios == NULL)
return false;
if (!tmds)
return false;
if (rdev->flags & RADEON_IS_IGP) {
offset = combios_get_table_offset(dev, COMBIOS_TMDS_POWER_ON_TABLE);
rev = RBIOS8(offset);
if (offset) {
rev = RBIOS8(offset);
if (rev > 1) {
blocks = RBIOS8(offset + 3);
index = offset + 4;
while (blocks > 0) {
id = RBIOS16(index);
index += 2;
switch (id >> 13) {
case 0:
reg = (id & 0x1fff) * 4;
val = RBIOS32(index);
index += 4;
WREG32(reg, val);
break;
case 2:
reg = (id & 0x1fff) * 4;
and_mask = RBIOS32(index);
index += 4;
or_mask = RBIOS32(index);
index += 4;
val = RREG32(reg);
val = (val & and_mask) | or_mask;
WREG32(reg, val);
break;
case 3:
val = RBIOS16(index);
index += 2;
udelay(val);
break;
case 4:
val = RBIOS16(index);
index += 2;
udelay(val * 1000);
break;
case 6:
slave_addr = id & 0xff;
slave_addr >>= 1; /* 7 bit addressing */
index++;
reg = RBIOS8(index);
index++;
val = RBIOS8(index);
index++;
radeon_i2c_do_lock(tmds->i2c_bus, 1);
radeon_i2c_sw_put_byte(tmds->i2c_bus,
slave_addr,
reg, val);
radeon_i2c_do_lock(tmds->i2c_bus, 0);
break;
default:
DRM_ERROR("Unknown id %d\n", id >> 13);
break;
}
blocks--;
}
return true;
}
}
} else {
offset = combios_get_table_offset(dev, COMBIOS_EXT_TMDS_INFO_TABLE);
if (offset) {
index = offset + 10;
id = RBIOS16(index);
while (id != 0xffff) {
index += 2;
switch (id >> 13) {
case 0:
reg = (id & 0x1fff) * 4;
val = RBIOS32(index);
WREG32(reg, val);
break;
case 2:
reg = (id & 0x1fff) * 4;
and_mask = RBIOS32(index);
index += 4;
or_mask = RBIOS32(index);
index += 4;
val = RREG32(reg);
val = (val & and_mask) | or_mask;
WREG32(reg, val);
break;
case 4:
val = RBIOS16(index);
index += 2;
udelay(val);
break;
case 5:
reg = id & 0x1fff;
and_mask = RBIOS32(index);
index += 4;
or_mask = RBIOS32(index);
index += 4;
val = RREG32_PLL(reg);
val = (val & and_mask) | or_mask;
WREG32_PLL(reg, val);
break;
case 6:
reg = id & 0x1fff;
val = RBIOS8(index);
index += 1;
radeon_i2c_do_lock(tmds->i2c_bus, 1);
radeon_i2c_sw_put_byte(tmds->i2c_bus,
tmds->slave_addr,
reg, val);
radeon_i2c_do_lock(tmds->i2c_bus, 0);
break;
default:
DRM_ERROR("Unknown id %d\n", id >> 13);
break;
}
id = RBIOS16(index);
}
return true;
}
}
return false;
}
static void combios_parse_mmio_table(struct drm_device *dev, uint16_t offset) static void combios_parse_mmio_table(struct drm_device *dev, uint16_t offset)
{ {
struct radeon_device *rdev = dev->dev_private; struct radeon_device *rdev = dev->dev_private;
......
...@@ -212,3 +212,59 @@ struct drm_encoder *radeon_best_encoder(struct drm_connector *connector) ...@@ -212,3 +212,59 @@ struct drm_encoder *radeon_best_encoder(struct drm_connector *connector)
{ {
return NULL; return NULL;
} }
void radeon_i2c_sw_get_byte(struct radeon_i2c_chan *i2c_bus,
u8 slave_addr,
u8 addr,
u8 *val)
{
u8 out_buf[2];
u8 in_buf[2];
struct i2c_msg msgs[] = {
{
.addr = slave_addr,
.flags = 0,
.len = 1,
.buf = out_buf,
},
{
.addr = slave_addr,
.flags = I2C_M_RD,
.len = 1,
.buf = in_buf,
}
};
out_buf[0] = addr;
out_buf[1] = 0;
if (i2c_transfer(&i2c_bus->adapter, msgs, 2) == 2) {
*val = in_buf[0];
DRM_DEBUG("val = 0x%02x\n", *val);
} else {
DRM_ERROR("i2c 0x%02x 0x%02x read failed\n",
addr, *val);
}
}
void radeon_i2c_sw_put_byte(struct radeon_i2c_chan *i2c_bus,
u8 slave_addr,
u8 addr,
u8 val)
{
uint8_t out_buf[2];
struct i2c_msg msg = {
.addr = slave_addr,
.flags = 0,
.len = 2,
.buf = out_buf,
};
out_buf[0] = addr;
out_buf[1] = val;
if (i2c_transfer(&i2c_bus->adapter, &msg, 1) != 1)
DRM_ERROR("i2c 0x%02x 0x%02x write failed\n",
addr, val);
}
...@@ -697,6 +697,8 @@ static void radeon_legacy_tmds_ext_mode_set(struct drm_encoder *encoder, ...@@ -697,6 +697,8 @@ static void radeon_legacy_tmds_ext_mode_set(struct drm_encoder *encoder,
/*if (mode->clock > 165000) /*if (mode->clock > 165000)
fp2_gen_cntl |= R300_FP2_DVO_DUAL_CHANNEL_EN;*/ fp2_gen_cntl |= R300_FP2_DVO_DUAL_CHANNEL_EN;*/
} }
if (!radeon_combios_external_tmds_setup(encoder))
radeon_external_tmds_setup(encoder);
} }
if (radeon_crtc->crtc_id == 0) { if (radeon_crtc->crtc_id == 0) {
...@@ -724,6 +726,19 @@ static void radeon_legacy_tmds_ext_mode_set(struct drm_encoder *encoder, ...@@ -724,6 +726,19 @@ static void radeon_legacy_tmds_ext_mode_set(struct drm_encoder *encoder,
radeon_combios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id); radeon_combios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id);
} }
static void radeon_ext_tmds_enc_destroy(struct drm_encoder *encoder)
{
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
struct radeon_encoder_ext_tmds *tmds = radeon_encoder->enc_priv;
if (tmds) {
if (tmds->i2c_bus)
radeon_i2c_destroy(tmds->i2c_bus);
}
kfree(radeon_encoder->enc_priv);
drm_encoder_cleanup(encoder);
kfree(radeon_encoder);
}
static const struct drm_encoder_helper_funcs radeon_legacy_tmds_ext_helper_funcs = { static const struct drm_encoder_helper_funcs radeon_legacy_tmds_ext_helper_funcs = {
.dpms = radeon_legacy_tmds_ext_dpms, .dpms = radeon_legacy_tmds_ext_dpms,
.mode_fixup = radeon_legacy_tmds_ext_mode_fixup, .mode_fixup = radeon_legacy_tmds_ext_mode_fixup,
...@@ -735,7 +750,7 @@ static const struct drm_encoder_helper_funcs radeon_legacy_tmds_ext_helper_funcs ...@@ -735,7 +750,7 @@ static const struct drm_encoder_helper_funcs radeon_legacy_tmds_ext_helper_funcs
static const struct drm_encoder_funcs radeon_legacy_tmds_ext_enc_funcs = { static const struct drm_encoder_funcs radeon_legacy_tmds_ext_enc_funcs = {
.destroy = radeon_enc_destroy, .destroy = radeon_ext_tmds_enc_destroy,
}; };
static bool radeon_legacy_tv_dac_mode_fixup(struct drm_encoder *encoder, static bool radeon_legacy_tv_dac_mode_fixup(struct drm_encoder *encoder,
...@@ -1302,6 +1317,29 @@ static struct radeon_encoder_int_tmds *radeon_legacy_get_tmds_info(struct radeon ...@@ -1302,6 +1317,29 @@ static struct radeon_encoder_int_tmds *radeon_legacy_get_tmds_info(struct radeon
return tmds; return tmds;
} }
static struct radeon_encoder_ext_tmds *radeon_legacy_get_ext_tmds_info(struct radeon_encoder *encoder)
{
struct drm_device *dev = encoder->base.dev;
struct radeon_device *rdev = dev->dev_private;
struct radeon_encoder_ext_tmds *tmds = NULL;
bool ret;
if (rdev->is_atom_bios)
return NULL;
tmds = kzalloc(sizeof(struct radeon_encoder_ext_tmds), GFP_KERNEL);
if (!tmds)
return NULL;
ret = radeon_legacy_get_ext_tmds_info_from_combios(encoder, tmds);
if (ret == false)
radeon_legacy_get_ext_tmds_info_from_table(encoder, tmds);
return tmds;
}
void void
radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t supported_device) radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t supported_device)
{ {
...@@ -1373,7 +1411,7 @@ radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t ...@@ -1373,7 +1411,7 @@ radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t
drm_encoder_init(dev, encoder, &radeon_legacy_tmds_ext_enc_funcs, DRM_MODE_ENCODER_TMDS); drm_encoder_init(dev, encoder, &radeon_legacy_tmds_ext_enc_funcs, DRM_MODE_ENCODER_TMDS);
drm_encoder_helper_add(encoder, &radeon_legacy_tmds_ext_helper_funcs); drm_encoder_helper_add(encoder, &radeon_legacy_tmds_ext_helper_funcs);
if (!rdev->is_atom_bios) if (!rdev->is_atom_bios)
radeon_combios_get_ext_tmds_info(radeon_encoder); radeon_encoder->enc_priv = radeon_legacy_get_ext_tmds_info(radeon_encoder);
break; break;
} }
} }
...@@ -184,6 +184,11 @@ enum radeon_connector_table { ...@@ -184,6 +184,11 @@ enum radeon_connector_table {
CT_EMAC, CT_EMAC,
}; };
enum radeon_dvo_chip {
DVO_SIL164,
DVO_SIL1178,
};
struct radeon_mode_info { struct radeon_mode_info {
struct atom_context *atom_context; struct atom_context *atom_context;
struct card_info *atom_card_info; struct card_info *atom_card_info;
...@@ -275,6 +280,13 @@ struct radeon_encoder_int_tmds { ...@@ -275,6 +280,13 @@ struct radeon_encoder_int_tmds {
struct radeon_tmds_pll tmds_pll[4]; struct radeon_tmds_pll tmds_pll[4];
}; };
struct radeon_encoder_ext_tmds {
/* tmds over dvo */
struct radeon_i2c_chan *i2c_bus;
uint8_t slave_addr;
enum radeon_dvo_chip dvo_chip;
};
/* spread spectrum */ /* spread spectrum */
struct radeon_atom_ss { struct radeon_atom_ss {
uint16_t percentage; uint16_t percentage;
...@@ -343,6 +355,14 @@ extern struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev, ...@@ -343,6 +355,14 @@ extern struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev,
struct radeon_i2c_bus_rec *rec, struct radeon_i2c_bus_rec *rec,
const char *name); const char *name);
extern void radeon_i2c_destroy(struct radeon_i2c_chan *i2c); extern void radeon_i2c_destroy(struct radeon_i2c_chan *i2c);
extern void radeon_i2c_sw_get_byte(struct radeon_i2c_chan *i2c_bus,
u8 slave_addr,
u8 addr,
u8 *val);
extern void radeon_i2c_sw_put_byte(struct radeon_i2c_chan *i2c,
u8 slave_addr,
u8 addr,
u8 val);
extern bool radeon_ddc_probe(struct radeon_connector *radeon_connector); extern bool radeon_ddc_probe(struct radeon_connector *radeon_connector);
extern int radeon_ddc_get_modes(struct radeon_connector *radeon_connector); extern int radeon_ddc_get_modes(struct radeon_connector *radeon_connector);
...@@ -392,12 +412,16 @@ extern bool radeon_atom_get_clock_info(struct drm_device *dev); ...@@ -392,12 +412,16 @@ extern bool radeon_atom_get_clock_info(struct drm_device *dev);
extern bool radeon_combios_get_clock_info(struct drm_device *dev); extern bool radeon_combios_get_clock_info(struct drm_device *dev);
extern struct radeon_encoder_atom_dig * extern struct radeon_encoder_atom_dig *
radeon_atombios_get_lvds_info(struct radeon_encoder *encoder); radeon_atombios_get_lvds_info(struct radeon_encoder *encoder);
bool radeon_atombios_get_tmds_info(struct radeon_encoder *encoder, extern bool radeon_atombios_get_tmds_info(struct radeon_encoder *encoder,
struct radeon_encoder_int_tmds *tmds); struct radeon_encoder_int_tmds *tmds);
bool radeon_legacy_get_tmds_info_from_combios(struct radeon_encoder *encoder, extern bool radeon_legacy_get_tmds_info_from_combios(struct radeon_encoder *encoder,
struct radeon_encoder_int_tmds *tmds); struct radeon_encoder_int_tmds *tmds);
bool radeon_legacy_get_tmds_info_from_table(struct radeon_encoder *encoder, extern bool radeon_legacy_get_tmds_info_from_table(struct radeon_encoder *encoder,
struct radeon_encoder_int_tmds *tmds); struct radeon_encoder_int_tmds *tmds);
extern bool radeon_legacy_get_ext_tmds_info_from_combios(struct radeon_encoder *encoder,
struct radeon_encoder_ext_tmds *tmds);
extern bool radeon_legacy_get_ext_tmds_info_from_table(struct radeon_encoder *encoder,
struct radeon_encoder_ext_tmds *tmds);
extern struct radeon_encoder_primary_dac * extern struct radeon_encoder_primary_dac *
radeon_atombios_get_primary_dac_info(struct radeon_encoder *encoder); radeon_atombios_get_primary_dac_info(struct radeon_encoder *encoder);
extern struct radeon_encoder_tv_dac * extern struct radeon_encoder_tv_dac *
...@@ -409,6 +433,8 @@ extern struct radeon_encoder_tv_dac * ...@@ -409,6 +433,8 @@ extern struct radeon_encoder_tv_dac *
radeon_combios_get_tv_dac_info(struct radeon_encoder *encoder); radeon_combios_get_tv_dac_info(struct radeon_encoder *encoder);
extern struct radeon_encoder_primary_dac * extern struct radeon_encoder_primary_dac *
radeon_combios_get_primary_dac_info(struct radeon_encoder *encoder); radeon_combios_get_primary_dac_info(struct radeon_encoder *encoder);
extern bool radeon_combios_external_tmds_setup(struct drm_encoder *encoder);
extern void radeon_external_tmds_setup(struct drm_encoder *encoder);
extern void radeon_combios_output_lock(struct drm_encoder *encoder, bool lock); extern void radeon_combios_output_lock(struct drm_encoder *encoder, bool lock);
extern void radeon_combios_initialize_bios_scratch_regs(struct drm_device *dev); extern void radeon_combios_initialize_bios_scratch_regs(struct drm_device *dev);
extern void radeon_atom_output_lock(struct drm_encoder *encoder, bool lock); extern void radeon_atom_output_lock(struct drm_encoder *encoder, bool lock);
......
...@@ -1051,20 +1051,25 @@ ...@@ -1051,20 +1051,25 @@
/* Multimedia I2C bus */ /* Multimedia I2C bus */
#define RADEON_I2C_CNTL_0 0x0090 #define RADEON_I2C_CNTL_0 0x0090
#define RADEON_I2C_DONE (1<<0) #define RADEON_I2C_DONE (1 << 0)
#define RADEON_I2C_NACK (1<<1) #define RADEON_I2C_NACK (1 << 1)
#define RADEON_I2C_HALT (1<<2) #define RADEON_I2C_HALT (1 << 2)
#define RADEON_I2C_SOFT_RST (1<<5) #define RADEON_I2C_SOFT_RST (1 << 5)
#define RADEON_I2C_DRIVE_EN (1<<6) #define RADEON_I2C_DRIVE_EN (1 << 6)
#define RADEON_I2C_DRIVE_SEL (1<<7) #define RADEON_I2C_DRIVE_SEL (1 << 7)
#define RADEON_I2C_START (1<<8) #define RADEON_I2C_START (1 << 8)
#define RADEON_I2C_STOP (1<<9) #define RADEON_I2C_STOP (1 << 9)
#define RADEON_I2C_RECEIVE (1<<10) #define RADEON_I2C_RECEIVE (1 << 10)
#define RADEON_I2C_ABORT (1<<11) #define RADEON_I2C_ABORT (1 << 11)
#define RADEON_I2C_GO (1<<12) #define RADEON_I2C_GO (1 << 12)
#define RADEON_I2C_PRESCALE_SHIFT 16
#define RADEON_I2C_CNTL_1 0x0094 #define RADEON_I2C_CNTL_1 0x0094
#define RADEON_I2C_SEL (1<<16) #define RADEON_I2C_DATA_COUNT_SHIFT 0
#define RADEON_I2C_EN (1<<17) #define RADEON_I2C_ADDR_COUNT_SHIFT 4
#define RADEON_I2C_INTRA_BYTE_DELAY_SHIFT 8
#define RADEON_I2C_SEL (1 << 16)
#define RADEON_I2C_EN (1 << 17)
#define RADEON_I2C_TIME_LIMIT_SHIFT 24
#define RADEON_I2C_DATA 0x0098 #define RADEON_I2C_DATA 0x0098
#define RADEON_DVI_I2C_CNTL_0 0x02e0 #define RADEON_DVI_I2C_CNTL_0 0x02e0
...@@ -1072,7 +1077,7 @@ ...@@ -1072,7 +1077,7 @@
# define R200_SEL_DDC1 0 /* 0x60 - VGA_DDC */ # define R200_SEL_DDC1 0 /* 0x60 - VGA_DDC */
# define R200_SEL_DDC2 1 /* 0x64 - DVI_DDC */ # define R200_SEL_DDC2 1 /* 0x64 - DVI_DDC */
# define R200_SEL_DDC3 2 /* 0x68 - MONID_DDC */ # define R200_SEL_DDC3 2 /* 0x68 - MONID_DDC */
#define RADEON_DVI_I2C_CNTL_1 0x02e4 /* ? */ #define RADEON_DVI_I2C_CNTL_1 0x02e4
#define RADEON_DVI_I2C_DATA 0x02e8 #define RADEON_DVI_I2C_DATA 0x02e8
#define RADEON_INTERRUPT_LINE 0x0f3c /* PCI */ #define RADEON_INTERRUPT_LINE 0x0f3c /* PCI */
...@@ -1143,14 +1148,15 @@ ...@@ -1143,14 +1148,15 @@
# define RADEON_IO_MCLK_MAX_DYN_STOP_LAT (1 << 13) # define RADEON_IO_MCLK_MAX_DYN_STOP_LAT (1 << 13)
# define RADEON_MC_MCLK_DYN_ENABLE (1 << 14) # define RADEON_MC_MCLK_DYN_ENABLE (1 << 14)
# define RADEON_IO_MCLK_DYN_ENABLE (1 << 15) # define RADEON_IO_MCLK_DYN_ENABLE (1 << 15)
#define RADEON_LCD_GPIO_MASK 0x01a0 #define RADEON_GPIOPAD_MASK 0x0198
#define RADEON_GPIOPAD_A 0x019c
#define RADEON_GPIOPAD_EN 0x01a0 #define RADEON_GPIOPAD_EN 0x01a0
#define RADEON_GPIOPAD_Y 0x01a4
#define RADEON_LCD_GPIO_MASK 0x01a0
#define RADEON_LCD_GPIO_Y_REG 0x01a4 #define RADEON_LCD_GPIO_Y_REG 0x01a4
#define RADEON_MDGPIO_A_REG 0x01ac #define RADEON_MDGPIO_A_REG 0x01ac
#define RADEON_MDGPIO_EN_REG 0x01b0 #define RADEON_MDGPIO_EN_REG 0x01b0
#define RADEON_MDGPIO_MASK 0x0198 #define RADEON_MDGPIO_MASK 0x0198
#define RADEON_GPIOPAD_MASK 0x0198
#define RADEON_GPIOPAD_A 0x019c
#define RADEON_MDGPIO_Y_REG 0x01b4 #define RADEON_MDGPIO_Y_REG 0x01b4
#define RADEON_MEM_ADDR_CONFIG 0x0148 #define RADEON_MEM_ADDR_CONFIG 0x0148
#define RADEON_MEM_BASE 0x0f10 /* PCI */ #define RADEON_MEM_BASE 0x0f10 /* PCI */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment