diff options
-rw-r--r-- | drivers/gpu/drm/radeon/radeon.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_atombios.c | 67 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_combios.c | 77 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_connectors.c | 31 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_display.c | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_i2c.c | 53 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_mode.h | 11 |
7 files changed, 214 insertions, 32 deletions
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 3cd1c470b77..3dfcfa3ca42 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -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, diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index 3bc2bcdf530..a841adead1a 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c @@ -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]; diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index 5e1474cde4b..18c84cf3eaf 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c @@ -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; diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index 2395c8600cf..185a6d962b7 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c @@ -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); } diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 74dac9635d7..52ac08e9a04 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c @@ -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, diff --git a/drivers/gpu/drm/radeon/radeon_i2c.c b/drivers/gpu/drm/radeon/radeon_i2c.c index 5def6f5dff3..e71f2eb02ee 100644 --- a/drivers/gpu/drm/radeon/radeon_i2c.c +++ b/drivers/gpu/drm/radeon/radeon_i2c.c @@ -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; diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index 71aea4037e9..02d4e2af618 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h @@ -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); |