aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Deucher <alexander.deucher@amd.com>2011-11-21 12:41:21 -0500
committerDave Airlie <airlied@redhat.com>2011-11-22 15:10:28 -0500
commit21240f9bc1b0ac925cd18b74618327a110022332 (patch)
treeef5496cbf9dbd7f5032f0a8d7d7c9646efbd58a4
parentd724502a9d7a46f4a56a1663b1f50d2dc9d1ef40 (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.c214
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
65static 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
103static 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
65static struct radeon_i2c_bus_rec radeon_lookup_i2c_gpio(struct radeon_device *rdev, 146static 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 }