mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-23 17:30:02 +00:00
drm/radeon/kms: unify i2c handling
Previously we added i2c buses as needed when enumerating connectors power management, etc. This only exposed the actual buses used and could have lead to the same buse getting created more than once if one buses was used for more than one purpose. This patch sets up all i2c buses on the card in one place and users of the buses just point back to the one instance. Signed-off-by: Alex Deucher <alexdeucher@gmail.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
parent
1729dd33d2
commit
f376b94fbc
7 changed files with 214 additions and 32 deletions
|
@ -1100,6 +1100,8 @@ struct radeon_device {
|
|||
struct notifier_block acpi_nb;
|
||||
/* only one userspace can use Hyperz features at a time */
|
||||
struct drm_file *hyperz_filp;
|
||||
/* i2c buses */
|
||||
struct radeon_i2c_chan *i2c_bus[RADEON_MAX_I2C_BUS];
|
||||
};
|
||||
|
||||
int radeon_device_init(struct radeon_device *rdev,
|
||||
|
|
|
@ -114,7 +114,8 @@ static inline struct radeon_i2c_bus_rec radeon_lookup_i2c_gpio(struct radeon_dev
|
|||
|
||||
i2c.i2c_id = gpio->sucI2cId.ucAccess;
|
||||
|
||||
i2c.valid = true;
|
||||
if (i2c.mask_clk_reg)
|
||||
i2c.valid = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -123,6 +124,66 @@ static inline struct radeon_i2c_bus_rec radeon_lookup_i2c_gpio(struct radeon_dev
|
|||
return i2c;
|
||||
}
|
||||
|
||||
void radeon_atombios_i2c_init(struct radeon_device *rdev)
|
||||
{
|
||||
struct atom_context *ctx = rdev->mode_info.atom_context;
|
||||
ATOM_GPIO_I2C_ASSIGMENT *gpio;
|
||||
struct radeon_i2c_bus_rec i2c;
|
||||
int index = GetIndexIntoMasterTable(DATA, GPIO_I2C_Info);
|
||||
struct _ATOM_GPIO_I2C_INFO *i2c_info;
|
||||
uint16_t data_offset, size;
|
||||
int i, num_indices;
|
||||
char stmp[32];
|
||||
|
||||
memset(&i2c, 0, sizeof(struct radeon_i2c_bus_rec));
|
||||
|
||||
if (atom_parse_data_header(ctx, index, &size, NULL, NULL, &data_offset)) {
|
||||
i2c_info = (struct _ATOM_GPIO_I2C_INFO *)(ctx->bios + data_offset);
|
||||
|
||||
num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) /
|
||||
sizeof(ATOM_GPIO_I2C_ASSIGMENT);
|
||||
|
||||
for (i = 0; i < num_indices; i++) {
|
||||
gpio = &i2c_info->asGPIO_Info[i];
|
||||
i2c.valid = false;
|
||||
i2c.mask_clk_reg = le16_to_cpu(gpio->usClkMaskRegisterIndex) * 4;
|
||||
i2c.mask_data_reg = le16_to_cpu(gpio->usDataMaskRegisterIndex) * 4;
|
||||
i2c.en_clk_reg = le16_to_cpu(gpio->usClkEnRegisterIndex) * 4;
|
||||
i2c.en_data_reg = le16_to_cpu(gpio->usDataEnRegisterIndex) * 4;
|
||||
i2c.y_clk_reg = le16_to_cpu(gpio->usClkY_RegisterIndex) * 4;
|
||||
i2c.y_data_reg = le16_to_cpu(gpio->usDataY_RegisterIndex) * 4;
|
||||
i2c.a_clk_reg = le16_to_cpu(gpio->usClkA_RegisterIndex) * 4;
|
||||
i2c.a_data_reg = le16_to_cpu(gpio->usDataA_RegisterIndex) * 4;
|
||||
i2c.mask_clk_mask = (1 << gpio->ucClkMaskShift);
|
||||
i2c.mask_data_mask = (1 << gpio->ucDataMaskShift);
|
||||
i2c.en_clk_mask = (1 << gpio->ucClkEnShift);
|
||||
i2c.en_data_mask = (1 << gpio->ucDataEnShift);
|
||||
i2c.y_clk_mask = (1 << gpio->ucClkY_Shift);
|
||||
i2c.y_data_mask = (1 << gpio->ucDataY_Shift);
|
||||
i2c.a_clk_mask = (1 << gpio->ucClkA_Shift);
|
||||
i2c.a_data_mask = (1 << gpio->ucDataA_Shift);
|
||||
|
||||
if (gpio->sucI2cId.sbfAccess.bfHW_Capable)
|
||||
i2c.hw_capable = true;
|
||||
else
|
||||
i2c.hw_capable = false;
|
||||
|
||||
if (gpio->sucI2cId.ucAccess == 0xa0)
|
||||
i2c.mm_i2c = true;
|
||||
else
|
||||
i2c.mm_i2c = false;
|
||||
|
||||
i2c.i2c_id = gpio->sucI2cId.ucAccess;
|
||||
|
||||
if (i2c.mask_clk_reg) {
|
||||
i2c.valid = true;
|
||||
sprintf(stmp, "0x%x", i2c.i2c_id);
|
||||
rdev->i2c_bus[i] = radeon_i2c_create(rdev->ddev, &i2c, stmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline struct radeon_gpio_rec radeon_lookup_gpio(struct radeon_device *rdev,
|
||||
u8 id)
|
||||
{
|
||||
|
@ -1521,7 +1582,7 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev)
|
|||
thermal_controller_names[power_info->info.ucOverdriveThermalController],
|
||||
power_info->info.ucOverdriveControllerAddress >> 1);
|
||||
i2c_bus = radeon_lookup_i2c_gpio(rdev, power_info->info.ucOverdriveI2cLine);
|
||||
rdev->pm.i2c_bus = radeon_i2c_create(rdev->ddev, &i2c_bus, "Thermal");
|
||||
rdev->pm.i2c_bus = radeon_i2c_lookup(rdev, &i2c_bus);
|
||||
if (rdev->pm.i2c_bus) {
|
||||
struct i2c_board_info info = { };
|
||||
const char *name = thermal_controller_names[power_info->info.
|
||||
|
@ -1814,7 +1875,7 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev)
|
|||
(controller->ucFanParameters &
|
||||
ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
|
||||
i2c_bus = radeon_lookup_i2c_gpio(rdev, controller->ucI2cLine);
|
||||
rdev->pm.i2c_bus = radeon_i2c_create(rdev->ddev, &i2c_bus, "Thermal");
|
||||
rdev->pm.i2c_bus = radeon_i2c_lookup(rdev, &i2c_bus);
|
||||
if (rdev->pm.i2c_bus) {
|
||||
struct i2c_board_info info = { };
|
||||
const char *name = pp_lib_thermal_controller_names[controller->ucType];
|
||||
|
|
|
@ -479,6 +479,17 @@ radeon_combios_get_hardcoded_edid(struct radeon_device *rdev)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* standard i2c gpio lines */
|
||||
#define RADEON_I2C_MONID_ID 0
|
||||
#define RADEON_I2C_DVI_ID 1
|
||||
#define RADEON_I2C_VGA_ID 2
|
||||
#define RADEON_I2C_CRT2_ID 3
|
||||
#define RADEON_I2C_MM_ID 4
|
||||
/* custom defined gpio lines */
|
||||
#define RADEON_I2C_LCD_ID 5 /* ddc for laptop panels */
|
||||
#define RADEON_I2C_GPIO_ID 6 /* rs4xx gpio ddc */
|
||||
#define RADEON_I2C_DVO_ID 7 /* i2c bus for dvo */
|
||||
|
||||
static struct radeon_i2c_bus_rec combios_setup_i2c_bus(struct radeon_device *rdev,
|
||||
int ddc_line)
|
||||
{
|
||||
|
@ -599,7 +610,24 @@ static struct radeon_i2c_bus_rec combios_setup_i2c_bus(struct radeon_device *rde
|
|||
break;
|
||||
}
|
||||
i2c.mm_i2c = false;
|
||||
i2c.i2c_id = 0;
|
||||
|
||||
switch (ddc_line) {
|
||||
case RADEON_GPIO_MONID:
|
||||
i2c.i2c_id = RADEON_I2C_MONID_ID;
|
||||
break;
|
||||
case RADEON_GPIO_DVI_DDC:
|
||||
i2c.i2c_id = RADEON_I2C_DVI_ID;
|
||||
break;
|
||||
case RADEON_GPIO_VGA_DDC:
|
||||
i2c.i2c_id = RADEON_I2C_VGA_ID;
|
||||
break;
|
||||
case RADEON_GPIO_CRT2_DDC:
|
||||
i2c.i2c_id = RADEON_I2C_CRT2_ID;
|
||||
break;
|
||||
default:
|
||||
i2c.i2c_id = 0xff;
|
||||
break;
|
||||
}
|
||||
i2c.hpd = RADEON_HPD_NONE;
|
||||
|
||||
if (ddc_line)
|
||||
|
@ -610,6 +638,30 @@ static struct radeon_i2c_bus_rec combios_setup_i2c_bus(struct radeon_device *rde
|
|||
return i2c;
|
||||
}
|
||||
|
||||
void radeon_combios_i2c_init(struct radeon_device *rdev)
|
||||
{
|
||||
struct drm_device *dev = rdev->ddev;
|
||||
struct radeon_i2c_bus_rec i2c;
|
||||
|
||||
i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_MONID);
|
||||
rdev->i2c_bus[0] = radeon_i2c_create(dev, &i2c, "MONID");
|
||||
|
||||
i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC);
|
||||
rdev->i2c_bus[1] = radeon_i2c_create(dev, &i2c, "DVI_DDC");
|
||||
|
||||
i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC);
|
||||
rdev->i2c_bus[2] = radeon_i2c_create(dev, &i2c, "VGA_DDC");
|
||||
|
||||
i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_CRT2_DDC);
|
||||
rdev->i2c_bus[3] = radeon_i2c_create(dev, &i2c, "CRT2_DDC");
|
||||
|
||||
i2c.valid = true;
|
||||
i2c.hw_capable = true;
|
||||
i2c.mm_i2c = true;
|
||||
i2c.i2c_id = RADEON_I2C_MM_ID;
|
||||
rdev->i2c_bus[4] = radeon_i2c_create(dev, &i2c, "MM_I2C");
|
||||
}
|
||||
|
||||
bool radeon_combios_get_clock_info(struct drm_device *dev)
|
||||
{
|
||||
struct radeon_device *rdev = dev->dev_private;
|
||||
|
@ -1248,7 +1300,7 @@ bool radeon_legacy_get_ext_tmds_info_from_table(struct radeon_encoder *encoder,
|
|||
|
||||
/* default for macs */
|
||||
i2c_bus = combios_setup_i2c_bus(rdev, RADEON_GPIO_MONID);
|
||||
tmds->i2c_bus = radeon_i2c_create(dev, &i2c_bus, "DVO");
|
||||
tmds->i2c_bus = radeon_i2c_lookup(rdev, &i2c_bus);
|
||||
|
||||
/* XXX some macs have duallink chips */
|
||||
switch (rdev->mode_info.connector_table) {
|
||||
|
@ -1303,7 +1355,9 @@ bool radeon_legacy_get_ext_tmds_info_from_combios(struct radeon_encoder *encoder
|
|||
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");
|
||||
i2c_bus.i2c_id = RADEON_I2C_DVO_ID;
|
||||
radeon_i2c_add(rdev, &i2c_bus, "DVO");
|
||||
tmds->i2c_bus = radeon_i2c_lookup(rdev, &i2c_bus);
|
||||
tmds->dvo_chip = DVO_SIL164;
|
||||
tmds->slave_addr = 0x70 >> 1; /* 7 bit addressing */
|
||||
break;
|
||||
|
@ -1321,15 +1375,15 @@ bool radeon_legacy_get_ext_tmds_info_from_combios(struct radeon_encoder *encoder
|
|||
switch (gpio) {
|
||||
case DDC_MONID:
|
||||
i2c_bus = combios_setup_i2c_bus(rdev, RADEON_GPIO_MONID);
|
||||
tmds->i2c_bus = radeon_i2c_create(dev, &i2c_bus, "DVO");
|
||||
tmds->i2c_bus = radeon_i2c_lookup(rdev, &i2c_bus);
|
||||
break;
|
||||
case DDC_DVI:
|
||||
i2c_bus = combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC);
|
||||
tmds->i2c_bus = radeon_i2c_create(dev, &i2c_bus, "DVO");
|
||||
tmds->i2c_bus = radeon_i2c_lookup(rdev, &i2c_bus);
|
||||
break;
|
||||
case DDC_VGA:
|
||||
i2c_bus = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC);
|
||||
tmds->i2c_bus = radeon_i2c_create(dev, &i2c_bus, "DVO");
|
||||
tmds->i2c_bus = radeon_i2c_lookup(rdev, &i2c_bus);
|
||||
break;
|
||||
case DDC_CRT2:
|
||||
/* R3xx+ chips don't have GPIO_CRT2_DDC gpio pad */
|
||||
|
@ -1337,13 +1391,14 @@ bool radeon_legacy_get_ext_tmds_info_from_combios(struct radeon_encoder *encoder
|
|||
i2c_bus = combios_setup_i2c_bus(rdev, RADEON_GPIO_MONID);
|
||||
else
|
||||
i2c_bus = combios_setup_i2c_bus(rdev, RADEON_GPIO_CRT2_DDC);
|
||||
tmds->i2c_bus = radeon_i2c_create(dev, &i2c_bus, "DVO");
|
||||
tmds->i2c_bus = radeon_i2c_lookup(rdev, &i2c_bus);
|
||||
break;
|
||||
case DDC_LCD: /* MM i2c */
|
||||
i2c_bus.valid = true;
|
||||
i2c_bus.hw_capable = true;
|
||||
i2c_bus.mm_i2c = true;
|
||||
tmds->i2c_bus = radeon_i2c_create(dev, &i2c_bus, "DVO");
|
||||
i2c_bus.i2c_id = RADEON_I2C_MM_ID;
|
||||
tmds->i2c_bus = radeon_i2c_lookup(rdev, &i2c_bus);
|
||||
break;
|
||||
default:
|
||||
DRM_ERROR("Unsupported gpio %d\n", gpio);
|
||||
|
@ -1926,6 +1981,8 @@ static bool radeon_apply_legacy_quirks(struct drm_device *dev,
|
|||
ddc_i2c->en_data_mask = 0x80;
|
||||
ddc_i2c->y_clk_mask = (0x20 << 8);
|
||||
ddc_i2c->y_data_mask = 0x80;
|
||||
ddc_i2c->i2c_id = RADEON_I2C_GPIO_ID;
|
||||
radeon_i2c_add(rdev, ddc_i2c, "GPIO_DDC");
|
||||
}
|
||||
|
||||
/* R3xx+ chips don't have GPIO_CRT2_DDC gpio pad */
|
||||
|
@ -2318,6 +2375,8 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev)
|
|||
RBIOS32(lcd_ddc_info + 3);
|
||||
ddc_i2c.y_data_mask =
|
||||
RBIOS32(lcd_ddc_info + 7);
|
||||
ddc_i2c.i2c_id = RADEON_I2C_LCD_ID;
|
||||
radeon_i2c_add(rdev, &ddc_i2c, "LCD");
|
||||
break;
|
||||
case DDC_GPIO:
|
||||
ddc_i2c =
|
||||
|
@ -2339,6 +2398,8 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev)
|
|||
RBIOS32(lcd_ddc_info + 3);
|
||||
ddc_i2c.y_data_mask =
|
||||
RBIOS32(lcd_ddc_info + 7);
|
||||
ddc_i2c.i2c_id = RADEON_I2C_LCD_ID;
|
||||
radeon_i2c_add(rdev, &ddc_i2c, "LCD");
|
||||
break;
|
||||
default:
|
||||
ddc_i2c.valid = false;
|
||||
|
|
|
@ -518,8 +518,6 @@ static void radeon_connector_destroy(struct drm_connector *connector)
|
|||
{
|
||||
struct radeon_connector *radeon_connector = to_radeon_connector(connector);
|
||||
|
||||
if (radeon_connector->ddc_bus)
|
||||
radeon_i2c_destroy(radeon_connector->ddc_bus);
|
||||
if (radeon_connector->edid)
|
||||
kfree(radeon_connector->edid);
|
||||
kfree(radeon_connector->con_priv);
|
||||
|
@ -955,8 +953,6 @@ static void radeon_dp_connector_destroy(struct drm_connector *connector)
|
|||
struct radeon_connector *radeon_connector = to_radeon_connector(connector);
|
||||
struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv;
|
||||
|
||||
if (radeon_connector->ddc_bus)
|
||||
radeon_i2c_destroy(radeon_connector->ddc_bus);
|
||||
if (radeon_connector->edid)
|
||||
kfree(radeon_connector->edid);
|
||||
if (radeon_dig_connector->dp_i2c_bus)
|
||||
|
@ -1088,7 +1084,7 @@ radeon_add_atom_connector(struct drm_device *dev,
|
|||
drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type);
|
||||
drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs);
|
||||
if (i2c_bus->valid) {
|
||||
radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "VGA");
|
||||
radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus);
|
||||
if (!radeon_connector->ddc_bus)
|
||||
goto failed;
|
||||
}
|
||||
|
@ -1104,7 +1100,7 @@ radeon_add_atom_connector(struct drm_device *dev,
|
|||
drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type);
|
||||
drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs);
|
||||
if (i2c_bus->valid) {
|
||||
radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI");
|
||||
radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus);
|
||||
if (!radeon_connector->ddc_bus)
|
||||
goto failed;
|
||||
}
|
||||
|
@ -1126,7 +1122,7 @@ radeon_add_atom_connector(struct drm_device *dev,
|
|||
drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type);
|
||||
drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs);
|
||||
if (i2c_bus->valid) {
|
||||
radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI");
|
||||
radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus);
|
||||
if (!radeon_connector->ddc_bus)
|
||||
goto failed;
|
||||
}
|
||||
|
@ -1156,7 +1152,7 @@ radeon_add_atom_connector(struct drm_device *dev,
|
|||
drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type);
|
||||
drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs);
|
||||
if (i2c_bus->valid) {
|
||||
radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "HDMI");
|
||||
radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus);
|
||||
if (!radeon_connector->ddc_bus)
|
||||
goto failed;
|
||||
}
|
||||
|
@ -1187,10 +1183,7 @@ radeon_add_atom_connector(struct drm_device *dev,
|
|||
radeon_dig_connector->dp_i2c_bus = radeon_i2c_create_dp(dev, i2c_bus, "DP-auxch");
|
||||
if (!radeon_dig_connector->dp_i2c_bus)
|
||||
goto failed;
|
||||
if (connector_type == DRM_MODE_CONNECTOR_eDP)
|
||||
radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "eDP");
|
||||
else
|
||||
radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DP");
|
||||
radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus);
|
||||
if (!radeon_connector->ddc_bus)
|
||||
goto failed;
|
||||
}
|
||||
|
@ -1230,7 +1223,7 @@ radeon_add_atom_connector(struct drm_device *dev,
|
|||
drm_connector_init(dev, &radeon_connector->base, &radeon_lvds_connector_funcs, connector_type);
|
||||
drm_connector_helper_add(&radeon_connector->base, &radeon_lvds_connector_helper_funcs);
|
||||
if (i2c_bus->valid) {
|
||||
radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "LVDS");
|
||||
radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus);
|
||||
if (!radeon_connector->ddc_bus)
|
||||
goto failed;
|
||||
}
|
||||
|
@ -1252,8 +1245,6 @@ radeon_add_atom_connector(struct drm_device *dev,
|
|||
return;
|
||||
|
||||
failed:
|
||||
if (radeon_connector->ddc_bus)
|
||||
radeon_i2c_destroy(radeon_connector->ddc_bus);
|
||||
drm_connector_cleanup(connector);
|
||||
kfree(connector);
|
||||
}
|
||||
|
@ -1300,7 +1291,7 @@ radeon_add_legacy_connector(struct drm_device *dev,
|
|||
drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type);
|
||||
drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs);
|
||||
if (i2c_bus->valid) {
|
||||
radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "VGA");
|
||||
radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus);
|
||||
if (!radeon_connector->ddc_bus)
|
||||
goto failed;
|
||||
}
|
||||
|
@ -1316,7 +1307,7 @@ radeon_add_legacy_connector(struct drm_device *dev,
|
|||
drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type);
|
||||
drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs);
|
||||
if (i2c_bus->valid) {
|
||||
radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI");
|
||||
radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus);
|
||||
if (!radeon_connector->ddc_bus)
|
||||
goto failed;
|
||||
}
|
||||
|
@ -1332,7 +1323,7 @@ radeon_add_legacy_connector(struct drm_device *dev,
|
|||
drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type);
|
||||
drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs);
|
||||
if (i2c_bus->valid) {
|
||||
radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI");
|
||||
radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus);
|
||||
if (!radeon_connector->ddc_bus)
|
||||
goto failed;
|
||||
}
|
||||
|
@ -1372,7 +1363,7 @@ radeon_add_legacy_connector(struct drm_device *dev,
|
|||
drm_connector_init(dev, &radeon_connector->base, &radeon_lvds_connector_funcs, connector_type);
|
||||
drm_connector_helper_add(&radeon_connector->base, &radeon_lvds_connector_helper_funcs);
|
||||
if (i2c_bus->valid) {
|
||||
radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "LVDS");
|
||||
radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus);
|
||||
if (!radeon_connector->ddc_bus)
|
||||
goto failed;
|
||||
}
|
||||
|
@ -1393,8 +1384,6 @@ radeon_add_legacy_connector(struct drm_device *dev,
|
|||
return;
|
||||
|
||||
failed:
|
||||
if (radeon_connector->ddc_bus)
|
||||
radeon_i2c_destroy(radeon_connector->ddc_bus);
|
||||
drm_connector_cleanup(connector);
|
||||
kfree(connector);
|
||||
}
|
||||
|
|
|
@ -1040,6 +1040,9 @@ int radeon_modeset_init(struct radeon_device *rdev)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/* init i2c buses */
|
||||
radeon_i2c_init(rdev);
|
||||
|
||||
/* check combios for a valid hardcoded EDID - Sun servers */
|
||||
if (!rdev->is_atom_bios) {
|
||||
/* check for hardcoded EDID in BIOS */
|
||||
|
@ -1080,6 +1083,8 @@ void radeon_modeset_fini(struct radeon_device *rdev)
|
|||
drm_mode_config_cleanup(rdev->ddev);
|
||||
rdev->mode_info.mode_config_initialized = false;
|
||||
}
|
||||
/* free i2c buses */
|
||||
radeon_i2c_fini(rdev);
|
||||
}
|
||||
|
||||
bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc,
|
||||
|
|
|
@ -960,6 +960,59 @@ void radeon_i2c_destroy(struct radeon_i2c_chan *i2c)
|
|||
kfree(i2c);
|
||||
}
|
||||
|
||||
/* Add the default buses */
|
||||
void radeon_i2c_init(struct radeon_device *rdev)
|
||||
{
|
||||
if (rdev->is_atom_bios)
|
||||
radeon_atombios_i2c_init(rdev);
|
||||
else
|
||||
radeon_combios_i2c_init(rdev);
|
||||
}
|
||||
|
||||
/* remove all the buses */
|
||||
void radeon_i2c_fini(struct radeon_device *rdev)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < RADEON_MAX_I2C_BUS; i++) {
|
||||
if (rdev->i2c_bus[i]) {
|
||||
radeon_i2c_destroy(rdev->i2c_bus[i]);
|
||||
rdev->i2c_bus[i] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Add additional buses */
|
||||
void radeon_i2c_add(struct radeon_device *rdev,
|
||||
struct radeon_i2c_bus_rec *rec,
|
||||
const char *name)
|
||||
{
|
||||
struct drm_device *dev = rdev->ddev;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < RADEON_MAX_I2C_BUS; i++) {
|
||||
if (!rdev->i2c_bus[i]) {
|
||||
rdev->i2c_bus[i] = radeon_i2c_create(dev, rec, name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* looks up bus based on id */
|
||||
struct radeon_i2c_chan *radeon_i2c_lookup(struct radeon_device *rdev,
|
||||
struct radeon_i2c_bus_rec *i2c_bus)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < RADEON_MAX_I2C_BUS; i++) {
|
||||
if (rdev->i2c_bus[i] &&
|
||||
(rdev->i2c_bus[i]->rec.i2c_id == i2c_bus->i2c_id)) {
|
||||
return rdev->i2c_bus[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct drm_encoder *radeon_best_encoder(struct drm_connector *connector)
|
||||
{
|
||||
return NULL;
|
||||
|
|
|
@ -82,6 +82,8 @@ enum radeon_hpd_id {
|
|||
RADEON_HPD_NONE = 0xff,
|
||||
};
|
||||
|
||||
#define RADEON_MAX_I2C_BUS 16
|
||||
|
||||
/* radeon gpio-based i2c
|
||||
* 1. "mask" reg and bits
|
||||
* grabs the gpio pins for software use
|
||||
|
@ -445,6 +447,15 @@ extern void atombios_dig_transmitter_setup(struct drm_encoder *encoder,
|
|||
extern int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
|
||||
uint8_t write_byte, uint8_t *read_byte);
|
||||
|
||||
extern void radeon_i2c_init(struct radeon_device *rdev);
|
||||
extern void radeon_i2c_fini(struct radeon_device *rdev);
|
||||
extern void radeon_combios_i2c_init(struct radeon_device *rdev);
|
||||
extern void radeon_atombios_i2c_init(struct radeon_device *rdev);
|
||||
extern void radeon_i2c_add(struct radeon_device *rdev,
|
||||
struct radeon_i2c_bus_rec *rec,
|
||||
const char *name);
|
||||
extern struct radeon_i2c_chan *radeon_i2c_lookup(struct radeon_device *rdev,
|
||||
struct radeon_i2c_bus_rec *i2c_bus);
|
||||
extern struct radeon_i2c_chan *radeon_i2c_create_dp(struct drm_device *dev,
|
||||
struct radeon_i2c_bus_rec *rec,
|
||||
const char *name);
|
||||
|
|
Loading…
Reference in a new issue