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)); | ||
| 173 | |||
| 174 | if (atom_parse_data_header(ctx, index, &size, NULL, NULL, &data_offset)) { | 192 | if (atom_parse_data_header(ctx, index, &size, NULL, NULL, &data_offset)) { |
| 175 | i2c_info = (struct _ATOM_GPIO_I2C_INFO *)(ctx->bios + data_offset); | 193 | i2c_info = (struct _ATOM_GPIO_I2C_INFO *)(ctx->bios + data_offset); |
| 176 | 194 | ||
| @@ -179,72 +197,12 @@ void radeon_atombios_i2c_init(struct radeon_device *rdev) | |||
| 179 | 197 | ||
| 180 | for (i = 0; i < num_indices; i++) { | 198 | for (i = 0; i < num_indices; i++) { |
| 181 | gpio = &i2c_info->asGPIO_Info[i]; | 199 | gpio = &i2c_info->asGPIO_Info[i]; |
| 182 | i2c.valid = false; | ||
| 183 | |||
| 184 | /* r4xx mask is technically not used by the hw, so patch in the legacy mask bits */ | ||
| 185 | if ((rdev->family == CHIP_R420) || | ||
| 186 | (rdev->family == CHIP_R423) || | ||
| 187 | (rdev->family == CHIP_RV410)) { | ||
| 188 | if ((le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x0018) || | ||
| 189 | (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x0019) || | ||
| 190 | (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x001a)) { | ||
| 191 | gpio->ucClkMaskShift = 0x19; | ||
| 192 | gpio->ucDataMaskShift = 0x18; | ||
| 193 | } | ||
| 194 | } | ||
| 195 | |||
| 196 | /* some evergreen boards have bad data for this entry */ | ||
| 197 | if (ASIC_IS_DCE4(rdev)) { | ||
| 198 | if ((i == 7) && | ||
| 199 | (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x1936) && | ||
| 200 | (gpio->sucI2cId.ucAccess == 0)) { | ||
| 201 | gpio->sucI2cId.ucAccess = 0x97; | ||
| 202 | gpio->ucDataMaskShift = 8; | ||
| 203 | gpio->ucDataEnShift = 8; | ||
| 204 | gpio->ucDataY_Shift = 8; | ||
| 205 | gpio->ucDataA_Shift = 8; | ||
| 206 | } | ||
| 207 | } | ||
| 208 | |||
| 209 | /* some DCE3 boards have bad data for this entry */ | ||
| 210 | if (ASIC_IS_DCE3(rdev)) { | ||
| 211 | if ((i == 4) && | ||
| 212 | (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x1fda) && | ||
| 213 | (gpio->sucI2cId.ucAccess == 0x94)) | ||
| 214 | gpio->sucI2cId.ucAccess = 0x14; | ||
| 215 | } | ||
| 216 | 200 | ||
| 217 | i2c.mask_clk_reg = le16_to_cpu(gpio->usClkMaskRegisterIndex) * 4; | 201 | radeon_lookup_i2c_gpio_quirks(rdev, gpio, i); |
| 218 | i2c.mask_data_reg = le16_to_cpu(gpio->usDataMaskRegisterIndex) * 4; | ||
| 219 | i2c.en_clk_reg = le16_to_cpu(gpio->usClkEnRegisterIndex) * 4; | ||
| 220 | i2c.en_data_reg = le16_to_cpu(gpio->usDataEnRegisterIndex) * 4; | ||
| 221 | i2c.y_clk_reg = le16_to_cpu(gpio->usClkY_RegisterIndex) * 4; | ||
| 222 | i2c.y_data_reg = le16_to_cpu(gpio->usDataY_RegisterIndex) * 4; | ||
| 223 | i2c.a_clk_reg = le16_to_cpu(gpio->usClkA_RegisterIndex) * 4; | ||
| 224 | i2c.a_data_reg = le16_to_cpu(gpio->usDataA_RegisterIndex) * 4; | ||
| 225 | i2c.mask_clk_mask = (1 << gpio->ucClkMaskShift); | ||
| 226 | i2c.mask_data_mask = (1 << gpio->ucDataMaskShift); | ||
| 227 | i2c.en_clk_mask = (1 << gpio->ucClkEnShift); | ||
| 228 | i2c.en_data_mask = (1 << gpio->ucDataEnShift); | ||
| 229 | i2c.y_clk_mask = (1 << gpio->ucClkY_Shift); | ||
| 230 | i2c.y_data_mask = (1 << gpio->ucDataY_Shift); | ||
| 231 | i2c.a_clk_mask = (1 << gpio->ucClkA_Shift); | ||
| 232 | i2c.a_data_mask = (1 << gpio->ucDataA_Shift); | ||
| 233 | |||
| 234 | if (gpio->sucI2cId.sbfAccess.bfHW_Capable) | ||
| 235 | i2c.hw_capable = true; | ||
| 236 | else | ||
| 237 | i2c.hw_capable = false; | ||
| 238 | |||
| 239 | if (gpio->sucI2cId.ucAccess == 0xa0) | ||
| 240 | i2c.mm_i2c = true; | ||
| 241 | else | ||
| 242 | i2c.mm_i2c = false; | ||
| 243 | 202 | ||
| 244 | i2c.i2c_id = gpio->sucI2cId.ucAccess; | 203 | i2c = radeon_get_bus_rec_for_i2c_gpio(gpio); |
| 245 | 204 | ||
| 246 | if (i2c.mask_clk_reg) { | 205 | if (i2c.valid) { |
| 247 | i2c.valid = true; | ||
| 248 | sprintf(stmp, "0x%x", i2c.i2c_id); | 206 | sprintf(stmp, "0x%x", i2c.i2c_id); |
| 249 | rdev->i2c_bus[i] = radeon_i2c_create(rdev->ddev, &i2c, stmp); | 207 | rdev->i2c_bus[i] = radeon_i2c_create(rdev->ddev, &i2c, stmp); |
| 250 | } | 208 | } |
