Commit 6a93cb25 authored by Alex Deucher's avatar Alex Deucher Committed by Dave Airlie

drm/radeon/kms: i2c reorg

- keep the atom i2c id in the i2c rec
- fix gpio regs for GPIO and MDGPIO on pre-avivo chips
- track whether the i2c line is hw capable
- track whether the i2c line uses the multimedia i2c block
Signed-off-by: default avatarAlex Deucher <alexdeucher@gmail.com>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent 1a66c95a
......@@ -52,7 +52,7 @@ bool radeon_process_aux_ch(struct radeon_i2c_chan *chan, u8 *req_bytes,
args.lpAuxRequest = 0;
args.lpDataOut = 16;
args.ucDataOutLen = 0;
args.ucChannelID = chan->i2c_id;
args.ucChannelID = chan->rec.i2c_id;
args.ucDelay = delay / 10;
atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
......@@ -60,7 +60,7 @@ bool radeon_process_aux_ch(struct radeon_i2c_chan *chan, u8 *req_bytes,
if (args.ucReplyStatus) {
DRM_ERROR("failed to get auxch %02x%02x %02x %02x 0x%02x %02x\n",
req_bytes[1], req_bytes[0], req_bytes[2], req_bytes[3],
chan->i2c_id, args.ucReplyStatus);
chan->rec.i2c_id, args.ucReplyStatus);
return false;
}
......@@ -102,7 +102,7 @@ int radeon_dp_getsinktype(struct radeon_connector *radeon_connector)
struct radeon_device *rdev = dev->dev_private;
return radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_GET_SINK_TYPE, 0,
radeon_dig_connector->uc_i2c_id, 0);
radeon_dig_connector->dp_i2c_bus->rec.i2c_id, 0);
}
union dig_transmitter_control {
......
......@@ -47,7 +47,7 @@ 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, uint8_t uc_i2c_id);
uint16_t connector_object_id);
/* from radeon_legacy_encoder.c */
extern void
......@@ -65,7 +65,7 @@ static inline struct radeon_i2c_bus_rec radeon_lookup_gpio(struct drm_device *de
{
struct radeon_device *rdev = dev->dev_private;
struct atom_context *ctx = rdev->mode_info.atom_context;
ATOM_GPIO_I2C_ASSIGMENT gpio;
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;
......@@ -78,24 +78,37 @@ static inline struct radeon_i2c_bus_rec radeon_lookup_gpio(struct drm_device *de
i2c_info = (struct _ATOM_GPIO_I2C_INFO *)(ctx->bios + data_offset);
gpio = i2c_info->asGPIO_Info[id];
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);
gpio = &i2c_info->asGPIO_Info[id];
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;
i2c.valid = true;
return i2c;
......@@ -276,7 +289,6 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev)
uint16_t igp_lane_info, conn_id, connector_object_id;
bool linkb;
struct radeon_i2c_bus_rec ddc_bus;
ATOM_I2C_ID_CONFIG_ACCESS i2c_id;
atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset);
if (data_offset == 0)
......@@ -302,7 +314,6 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev)
path = (ATOM_DISPLAY_OBJECT_PATH *) addr;
path_size += le16_to_cpu(path->usSize);
linkb = false;
i2c_id.ucAccess = 0;
if (device_support & le16_to_cpu(path->usDeviceTag)) {
uint8_t con_obj_id, con_obj_num, con_obj_type;
......@@ -420,7 +431,7 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev)
asObjects[j].
usRecordOffset));
ATOM_I2C_RECORD *i2c_record;
while (record->ucRecordType > 0
&& record->
ucRecordType <=
......@@ -431,7 +442,6 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev)
i2c_record =
(ATOM_I2C_RECORD
*) record;
i2c_id.sbfAccess = i2c_record->sucI2cId;
line_mux =
i2c_record->
sucI2cId.
......@@ -474,7 +484,7 @@ 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, i2c_id.ucAccess);
connector_object_id);
}
}
......@@ -693,7 +703,7 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct
connector_type,
&bios_connectors[i].ddc_bus,
false, 0,
connector_object_id, 0);
connector_object_id);
}
}
......
This diff is collapsed.
......@@ -952,7 +952,7 @@ radeon_add_atom_connector(struct drm_device *dev,
struct radeon_i2c_bus_rec *i2c_bus,
bool linkb,
uint32_t igp_lane_info,
uint16_t connector_object_id, uint8_t uc_i2c_id)
uint16_t connector_object_id)
{
struct radeon_device *rdev = dev->dev_private;
struct drm_connector *connector;
......@@ -1083,8 +1083,7 @@ radeon_add_atom_connector(struct drm_device *dev,
if (ret)
goto failed;
/* add DP i2c bus */
radeon_dig_connector->uc_i2c_id = uc_i2c_id;
radeon_dig_connector->dp_i2c_bus = radeon_i2c_create_dp(dev, "DP-auxch", true, uc_i2c_id);
radeon_dig_connector->dp_i2c_bus = radeon_i2c_create_dp(dev, i2c_bus, "DP-auxch");
if (i2c_bus->valid) {
radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DP");
if (!radeon_connector->ddc_bus)
......
......@@ -69,13 +69,15 @@ void radeon_i2c_do_lock(struct radeon_i2c_chan *i2c, int lock_state)
* holds the i2c port in a bad state - switch hw i2c away before
* doing DDC - do this for all r200s/r300s/r400s for safety sake
*/
if ((rdev->family >= CHIP_R200) && !ASIC_IS_AVIVO(rdev)) {
if (rec->a_clk_reg == RADEON_GPIO_MONID) {
WREG32(RADEON_DVI_I2C_CNTL_0, (RADEON_I2C_SOFT_RST |
R200_DVI_I2C_PIN_SEL(R200_SEL_DDC1)));
} else {
WREG32(RADEON_DVI_I2C_CNTL_0, (RADEON_I2C_SOFT_RST |
R200_DVI_I2C_PIN_SEL(R200_SEL_DDC3)));
if (rec->hw_capable) {
if ((rdev->family >= CHIP_R200) && !ASIC_IS_AVIVO(rdev)) {
if (rec->a_clk_reg == RADEON_GPIO_MONID) {
WREG32(RADEON_DVI_I2C_CNTL_0, (RADEON_I2C_SOFT_RST |
R200_DVI_I2C_PIN_SEL(R200_SEL_DDC1)));
} else {
WREG32(RADEON_DVI_I2C_CNTL_0, (RADEON_I2C_SOFT_RST |
R200_DVI_I2C_PIN_SEL(R200_SEL_DDC3)));
}
}
}
......@@ -86,6 +88,12 @@ void radeon_i2c_do_lock(struct radeon_i2c_chan *i2c, int lock_state)
temp = RREG32(rec->a_data_reg) & ~rec->a_data_mask;
WREG32(rec->a_data_reg, temp);
/* set the pins to input */
temp = RREG32(rec->en_clk_reg) & ~rec->en_clk_mask;
WREG32(rec->en_clk_reg, temp);
temp = RREG32(rec->en_data_reg) & ~rec->en_data_mask;
WREG32(rec->en_data_reg, temp);
/* mask the gpio pins for software use */
temp = RREG32(rec->mask_clk_reg);
......@@ -199,7 +207,8 @@ struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev,
}
struct radeon_i2c_chan *radeon_i2c_create_dp(struct drm_device *dev,
const char *name, bool dp, u8 i2c_id)
struct radeon_i2c_bus_rec *rec,
const char *name)
{
struct radeon_i2c_chan *i2c;
int ret;
......@@ -208,7 +217,7 @@ struct radeon_i2c_chan *radeon_i2c_create_dp(struct drm_device *dev,
if (i2c == NULL)
return NULL;
i2c->i2c_id = i2c_id;
i2c->rec = *rec;
i2c->adapter.owner = THIS_MODULE;
i2c->dev = dev;
i2c_set_adapdata(&i2c->adapter, i2c);
......
......@@ -106,6 +106,13 @@ enum radeon_tv_std {
*/
struct radeon_i2c_bus_rec {
bool valid;
/* id used by atom */
uint8_t i2c_id;
/* can be used with hw i2c engine */
bool hw_capable;
/* uses multi-media i2c engine */
bool mm_i2c;
/* regs and bits */
uint32_t mask_clk_reg;
uint32_t mask_data_reg;
uint32_t a_clk_reg;
......@@ -172,7 +179,6 @@ struct radeon_i2c_chan {
struct i2c_algo_bit_data bit;
} algo;
struct radeon_i2c_bus_rec rec;
uint8_t i2c_id;
};
/* mostly for macs, but really any system without connector tables */
......@@ -333,7 +339,6 @@ struct radeon_encoder {
struct radeon_connector_atom_dig {
uint32_t igp_lane_info;
bool linkb;
uint16_t uc_i2c_id;
struct radeon_i2c_chan *dp_i2c_bus;
u8 dpcd[8];
};
......@@ -352,8 +357,6 @@ struct radeon_connector {
void *con_priv;
bool dac_load_detect;
uint16_t connector_object_id;
/* need to keep this for display port */
//
};
struct radeon_framebuffer {
......@@ -362,12 +365,13 @@ struct radeon_framebuffer {
};
extern int radeon_dp_getsinktype(struct radeon_connector *radeon_connector);
extern void radeon_dp_getdpcd(struct radeon_connector *connector);
extern void radeon_dp_getdpcd(struct radeon_connector *radeon_connector);
extern int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
uint8_t write_byte, uint8_t *read_byte);
extern struct radeon_i2c_chan *radeon_i2c_create_dp(struct drm_device *dev,
const char *name, bool dp, u8 i2c_id);
struct radeon_i2c_bus_rec *rec,
const char *name);
extern struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev,
struct radeon_i2c_bus_rec *rec,
const char *name);
......
......@@ -1148,16 +1148,16 @@
# define RADEON_IO_MCLK_MAX_DYN_STOP_LAT (1 << 13)
# define RADEON_MC_MCLK_DYN_ENABLE (1 << 14)
# define RADEON_IO_MCLK_DYN_ENABLE (1 << 15)
#define RADEON_GPIOPAD_MASK 0x0198
#define RADEON_GPIOPAD_A 0x019c
#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_MDGPIO_A_REG 0x01ac
#define RADEON_MDGPIO_EN_REG 0x01b0
#define RADEON_MDGPIO_MASK 0x0198
#define RADEON_MDGPIO_Y_REG 0x01b4
#define RADEON_MDGPIO_MASK 0x01a8
#define RADEON_MDGPIO_A 0x01ac
#define RADEON_MDGPIO_EN 0x01b0
#define RADEON_MDGPIO_Y 0x01b4
#define RADEON_MEM_ADDR_CONFIG 0x0148
#define RADEON_MEM_BASE 0x0f10 /* PCI */
#define RADEON_MEM_CNTL 0x0140
......
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