diff options
| author | Alex Deucher <alexander.deucher@amd.com> | 2011-11-21 12:41:21 -0500 |
|---|---|---|
| committer | Dave Airlie <airlied@redhat.com> | 2011-11-22 15:10:28 -0500 |
| commit | 21240f9bc1b0ac925cd18b74618327a110022332 (patch) | |
| tree | ef5496cbf9dbd7f5032f0a8d7d7c9646efbd58a4 | |
| parent | d724502a9d7a46f4a56a1663b1f50d2dc9d1ef40 (diff) | |
drm/radeon/kms/atom: unify i2c gpio table handling
Split the quirks and i2c_rec assignment into separate
functions used by both radeon_lookup_i2c_gpio() and
radeon_atombios_i2c_init(). This avoids duplicating code
and cases where quirks were only added to one of the
functions.
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Cc: Jean Delvare <khali@linux-fr.org>
Signed-off-by: Dave Airlie <airlied@redhat.com>
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon_atombios.c | 214 |
1 files changed, 86 insertions, 128 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index 933a2cd7bb55..d24baf30efcb 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c | |||
| @@ -62,6 +62,87 @@ union atom_supported_devices { | |||
| 62 | struct _ATOM_SUPPORTED_DEVICES_INFO_2d1 info_2d1; | 62 | struct _ATOM_SUPPORTED_DEVICES_INFO_2d1 info_2d1; |
| 63 | }; | 63 | }; |
| 64 | 64 | ||
| 65 | static void radeon_lookup_i2c_gpio_quirks(struct radeon_device *rdev, | ||
| 66 | ATOM_GPIO_I2C_ASSIGMENT *gpio, | ||
| 67 | u8 index) | ||
| 68 | { | ||
| 69 | /* r4xx mask is technically not used by the hw, so patch in the legacy mask bits */ | ||
| 70 | if ((rdev->family == CHIP_R420) || | ||
| 71 | (rdev->family == CHIP_R423) || | ||
| 72 | (rdev->family == CHIP_RV410)) { | ||
| 73 | if ((le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x0018) || | ||
| 74 | (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x0019) || | ||
| 75 | (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x001a)) { | ||
| 76 | gpio->ucClkMaskShift = 0x19; | ||
| 77 | gpio->ucDataMaskShift = 0x18; | ||
| 78 | } | ||
| 79 | } | ||
| 80 | |||
| 81 | /* some evergreen boards have bad data for this entry */ | ||
| 82 | if (ASIC_IS_DCE4(rdev)) { | ||
| 83 | if ((index == 7) && | ||
| 84 | (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x1936) && | ||
| 85 | (gpio->sucI2cId.ucAccess == 0)) { | ||
| 86 | gpio->sucI2cId.ucAccess = 0x97; | ||
| 87 | gpio->ucDataMaskShift = 8; | ||
| 88 | gpio->ucDataEnShift = 8; | ||
| 89 | gpio->ucDataY_Shift = 8; | ||
| 90 | gpio->ucDataA_Shift = 8; | ||
| 91 | } | ||
| 92 | } | ||
| 93 | |||
| 94 | /* some DCE3 boards have bad data for this entry */ | ||
| 95 | if (ASIC_IS_DCE3(rdev)) { | ||
| 96 | if ((index == 4) && | ||
| 97 | (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x1fda) && | ||
| 98 | (gpio->sucI2cId.ucAccess == 0x94)) | ||
| 99 | gpio->sucI2cId.ucAccess = 0x14; | ||
| 100 | } | ||
| 101 | } | ||
| 102 | |||
| 103 | static struct radeon_i2c_bus_rec radeon_get_bus_rec_for_i2c_gpio(ATOM_GPIO_I2C_ASSIGMENT *gpio) | ||
| 104 | { | ||
| 105 | struct radeon_i2c_bus_rec i2c; | ||
| 106 | |||
| 107 | memset(&i2c, 0, sizeof(struct radeon_i2c_bus_rec)); | ||
| 108 | |||
| 109 | i2c.mask_clk_reg = le16_to_cpu(gpio->usClkMaskRegisterIndex) * 4; | ||
| 110 | i2c.mask_data_reg = le16_to_cpu(gpio->usDataMaskRegisterIndex) * 4; | ||
| 111 | i2c.en_clk_reg = le16_to_cpu(gpio->usClkEnRegisterIndex) * 4; | ||
| 112 | i2c.en_data_reg = le16_to_cpu(gpio->usDataEnRegisterIndex) * 4; | ||
| 113 | i2c.y_clk_reg = le16_to_cpu(gpio->usClkY_RegisterIndex) * 4; | ||
| 114 | i2c.y_data_reg = le16_to_cpu(gpio->usDataY_RegisterIndex) * 4; | ||
| 115 | i2c.a_clk_reg = le16_to_cpu(gpio->usClkA_RegisterIndex) * 4; | ||
| 116 | i2c.a_data_reg = le16_to_cpu(gpio->usDataA_RegisterIndex) * 4; | ||
| 117 | i2c.mask_clk_mask = (1 << gpio->ucClkMaskShift); | ||
| 118 | i2c.mask_data_mask = (1 << gpio->ucDataMaskShift); | ||
| 119 | i2c.en_clk_mask = (1 << gpio->ucClkEnShift); | ||
| 120 | i2c.en_data_mask = (1 << gpio->ucDataEnShift); | ||
| 121 | i2c.y_clk_mask = (1 << gpio->ucClkY_Shift); | ||
| 122 | i2c.y_data_mask = (1 << gpio->ucDataY_Shift); | ||
| 123 | i2c.a_clk_mask = (1 << gpio->ucClkA_Shift); | ||
| 124 | i2c.a_data_mask = (1 << gpio->ucDataA_Shift); | ||
| 125 | |||
| 126 | if (gpio->sucI2cId.sbfAccess.bfHW_Capable) | ||
| 127 | i2c.hw_capable = true; | ||
| 128 | else | ||
| 129 | i2c.hw_capable = false; | ||
| 130 | |||
| 131 | if (gpio->sucI2cId.ucAccess == 0xa0) | ||
| 132 | i2c.mm_i2c = true; | ||
| 133 | else | ||
| 134 | i2c.mm_i2c = false; | ||
| 135 | |||
| 136 | i2c.i2c_id = gpio->sucI2cId.ucAccess; | ||
| 137 | |||
| 138 | if (i2c.mask_clk_reg) | ||
| 139 | i2c.valid = true; | ||
| 140 | else | ||
| 141 | i2c.valid = false; | ||
| 142 | |||
| 143 | return i2c; | ||
| 144 | } | ||
| 145 | |||
| 65 | static struct radeon_i2c_bus_rec radeon_lookup_i2c_gpio(struct radeon_device *rdev, | 146 | static struct radeon_i2c_bus_rec radeon_lookup_i2c_gpio(struct radeon_device *rdev, |
| 66 | uint8_t id) | 147 | uint8_t id) |
| 67 | { | 148 | { |
| @@ -85,71 +166,10 @@ static struct radeon_i2c_bus_rec radeon_lookup_i2c_gpio(struct radeon_device *rd | |||
| 85 | for (i = 0; i < num_indices; i++) { | 166 | for (i = 0; i < num_indices; i++) { |
| 86 | gpio = &i2c_info->asGPIO_Info[i]; | 167 | gpio = &i2c_info->asGPIO_Info[i]; |
| 87 | 168 | ||
| 88 | /* r4xx mask is technically not used by the hw, so patch in the legacy mask bits */ | 169 | radeon_lookup_i2c_gpio_quirks(rdev, gpio, i); |
| 89 | if ((rdev->family == CHIP_R420) || | ||
| 90 | (rdev->family == CHIP_R423) || | ||
| 91 | (rdev->family == CHIP_RV410)) { | ||
| 92 | if ((le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x0018) || | ||
| 93 | (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x0019) || | ||
| 94 | (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x001a)) { | ||
| 95 | gpio->ucClkMaskShift = 0x19; | ||
| 96 | gpio->ucDataMaskShift = 0x18; | ||
| 97 | } | ||
| 98 | } | ||
| 99 | |||
| 100 | /* some evergreen boards have bad data for this entry */ | ||
| 101 | if (ASIC_IS_DCE4(rdev)) { | ||
| 102 | if ((i == 7) && | ||
| 103 | (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x1936) && | ||
| 104 | (gpio->sucI2cId.ucAccess == 0)) { | ||
| 105 | gpio->sucI2cId.ucAccess = 0x97; | ||
| 106 | gpio->ucDataMaskShift = 8; | ||
| 107 | gpio->ucDataEnShift = 8; | ||
| 108 | gpio->ucDataY_Shift = 8; | ||
| 109 | gpio->ucDataA_Shift = 8; | ||
| 110 | } | ||
| 111 | } | ||
| 112 | |||
| 113 | /* some DCE3 boards have bad data for this entry */ | ||
| 114 | if (ASIC_IS_DCE3(rdev)) { | ||
| 115 | if ((i == 4) && | ||
| 116 | (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x1fda) && | ||
| 117 | (gpio->sucI2cId.ucAccess == 0x94)) | ||
| 118 | gpio->sucI2cId.ucAccess = 0x14; | ||
| 119 | } | ||
| 120 | 170 | ||
| 121 | if (gpio->sucI2cId.ucAccess == id) { | 171 | if (gpio->sucI2cId.ucAccess == id) { |
| 122 | i2c.mask_clk_reg = le16_to_cpu(gpio->usClkMaskRegisterIndex) * 4; | 172 | i2c = radeon_get_bus_rec_for_i2c_gpio(gpio); |
| 123 | i2c.mask_data_reg = le16_to_cpu(gpio->usDataMaskRegisterIndex) * 4; | ||
| 124 | i2c.en_clk_reg = le16_to_cpu(gpio->usClkEnRegisterIndex) * 4; | ||
| 125 | i2c.en_data_reg = le16_to_cpu(gpio->usDataEnRegisterIndex) * 4; | ||
| 126 | i2c.y_clk_reg = le16_to_cpu(gpio->usClkY_RegisterIndex) * 4; | ||
| 127 | i2c.y_data_reg = le16_to_cpu(gpio->usDataY_RegisterIndex) * 4; | ||
| 128 | i2c.a_clk_reg = le16_to_cpu(gpio->usClkA_RegisterIndex) * 4; | ||
| 129 | i2c.a_data_reg = le16_to_cpu(gpio->usDataA_RegisterIndex) * 4; | ||
| 130 | i2c.mask_clk_mask = (1 << gpio->ucClkMaskShift); | ||
| 131 | i2c.mask_data_mask = (1 << gpio->ucDataMaskShift); | ||
| 132 | i2c.en_clk_mask = (1 << gpio->ucClkEnShift); | ||
| 133 | i2c.en_data_mask = (1 << gpio->ucDataEnShift); | ||
| 134 | i2c.y_clk_mask = (1 << gpio->ucClkY_Shift); | ||
| 135 | i2c.y_data_mask = (1 << gpio->ucDataY_Shift); | ||
| 136 | i2c.a_clk_mask = (1 << gpio->ucClkA_Shift); | ||
| 137 | i2c.a_data_mask = (1 << gpio->ucDataA_Shift); | ||
| 138 | |||
| 139 | if (gpio->sucI2cId.sbfAccess.bfHW_Capable) | ||
| 140 | i2c.hw_capable = true; | ||
| 141 | else | ||
| 142 | i2c.hw_capable = false; | ||
| 143 | |||
| 144 | if (gpio->sucI2cId.ucAccess == 0xa0) | ||
| 145 | i2c.mm_i2c = true; | ||
| 146 | else | ||
| 147 | i2c.mm_i2c = false; | ||
| 148 | |||
| 149 | i2c.i2c_id = gpio->sucI2cId.ucAccess; | ||
| 150 | |||
| 151 | if (i2c.mask_clk_reg) | ||
| 152 | i2c.valid = true; | ||
| 153 | break; | 173 | break; |
| 154 | } | 174 | } |
| 155 | } | 175 | } |
| @@ -169,8 +189,6 @@ void radeon_atombios_i2c_init(struct radeon_device *rdev) | |||
| 169 | int i, num_indices; | 189 | int i, num_indices; |
| 170 | char stmp[32]; | 190 | char stmp[32]; |
| 171 | 191 | ||
| 172 | memset(&i2c, 0, sizeof(struct radeon_i2c_bus_rec)); | ||
