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 /drivers | |
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>
Diffstat (limited to 'drivers')
-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 | } |