diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_atombios.c')
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_atombios.c | 1147 |
1 files changed, 939 insertions, 208 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index 2ed88a820935..9916d825401c 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c | |||
@@ -47,7 +47,8 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
47 | int connector_type, | 47 | int connector_type, |
48 | struct radeon_i2c_bus_rec *i2c_bus, | 48 | struct radeon_i2c_bus_rec *i2c_bus, |
49 | bool linkb, uint32_t igp_lane_info, | 49 | bool linkb, uint32_t igp_lane_info, |
50 | uint16_t connector_object_id); | 50 | uint16_t connector_object_id, |
51 | struct radeon_hpd *hpd); | ||
51 | 52 | ||
52 | /* from radeon_legacy_encoder.c */ | 53 | /* from radeon_legacy_encoder.c */ |
53 | extern void | 54 | extern void |
@@ -60,52 +61,150 @@ union atom_supported_devices { | |||
60 | struct _ATOM_SUPPORTED_DEVICES_INFO_2d1 info_2d1; | 61 | struct _ATOM_SUPPORTED_DEVICES_INFO_2d1 info_2d1; |
61 | }; | 62 | }; |
62 | 63 | ||
63 | static inline struct radeon_i2c_bus_rec radeon_lookup_gpio(struct drm_device | 64 | static inline struct radeon_i2c_bus_rec radeon_lookup_i2c_gpio(struct radeon_device *rdev, |
64 | *dev, uint8_t id) | 65 | uint8_t id) |
65 | { | 66 | { |
66 | struct radeon_device *rdev = dev->dev_private; | ||
67 | struct atom_context *ctx = rdev->mode_info.atom_context; | 67 | struct atom_context *ctx = rdev->mode_info.atom_context; |
68 | ATOM_GPIO_I2C_ASSIGMENT gpio; | 68 | ATOM_GPIO_I2C_ASSIGMENT *gpio; |
69 | struct radeon_i2c_bus_rec i2c; | 69 | struct radeon_i2c_bus_rec i2c; |
70 | int index = GetIndexIntoMasterTable(DATA, GPIO_I2C_Info); | 70 | int index = GetIndexIntoMasterTable(DATA, GPIO_I2C_Info); |
71 | struct _ATOM_GPIO_I2C_INFO *i2c_info; | 71 | struct _ATOM_GPIO_I2C_INFO *i2c_info; |
72 | uint16_t data_offset; | 72 | uint16_t data_offset, size; |
73 | int i, num_indices; | ||
73 | 74 | ||
74 | memset(&i2c, 0, sizeof(struct radeon_i2c_bus_rec)); | 75 | memset(&i2c, 0, sizeof(struct radeon_i2c_bus_rec)); |
75 | i2c.valid = false; | 76 | i2c.valid = false; |
76 | 77 | ||
77 | atom_parse_data_header(ctx, index, NULL, NULL, NULL, &data_offset); | 78 | if (atom_parse_data_header(ctx, index, &size, NULL, NULL, &data_offset)) { |
78 | 79 | i2c_info = (struct _ATOM_GPIO_I2C_INFO *)(ctx->bios + data_offset); | |
79 | i2c_info = (struct _ATOM_GPIO_I2C_INFO *)(ctx->bios + data_offset); | 80 | |
80 | 81 | num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) / | |
81 | gpio = i2c_info->asGPIO_Info[id]; | 82 | sizeof(ATOM_GPIO_I2C_ASSIGMENT); |
82 | 83 | ||
83 | i2c.mask_clk_reg = le16_to_cpu(gpio.usClkMaskRegisterIndex) * 4; | 84 | for (i = 0; i < num_indices; i++) { |
84 | i2c.mask_data_reg = le16_to_cpu(gpio.usDataMaskRegisterIndex) * 4; | 85 | gpio = &i2c_info->asGPIO_Info[i]; |
85 | i2c.put_clk_reg = le16_to_cpu(gpio.usClkEnRegisterIndex) * 4; | 86 | |
86 | i2c.put_data_reg = le16_to_cpu(gpio.usDataEnRegisterIndex) * 4; | 87 | if (gpio->sucI2cId.ucAccess == id) { |
87 | i2c.get_clk_reg = le16_to_cpu(gpio.usClkY_RegisterIndex) * 4; | 88 | i2c.mask_clk_reg = le16_to_cpu(gpio->usClkMaskRegisterIndex) * 4; |
88 | i2c.get_data_reg = le16_to_cpu(gpio.usDataY_RegisterIndex) * 4; | 89 | i2c.mask_data_reg = le16_to_cpu(gpio->usDataMaskRegisterIndex) * 4; |
89 | i2c.a_clk_reg = le16_to_cpu(gpio.usClkA_RegisterIndex) * 4; | 90 | i2c.en_clk_reg = le16_to_cpu(gpio->usClkEnRegisterIndex) * 4; |
90 | i2c.a_data_reg = le16_to_cpu(gpio.usDataA_RegisterIndex) * 4; | 91 | i2c.en_data_reg = le16_to_cpu(gpio->usDataEnRegisterIndex) * 4; |
91 | i2c.mask_clk_mask = (1 << gpio.ucClkMaskShift); | 92 | i2c.y_clk_reg = le16_to_cpu(gpio->usClkY_RegisterIndex) * 4; |
92 | i2c.mask_data_mask = (1 << gpio.ucDataMaskShift); | 93 | i2c.y_data_reg = le16_to_cpu(gpio->usDataY_RegisterIndex) * 4; |
93 | i2c.put_clk_mask = (1 << gpio.ucClkEnShift); | 94 | i2c.a_clk_reg = le16_to_cpu(gpio->usClkA_RegisterIndex) * 4; |
94 | i2c.put_data_mask = (1 << gpio.ucDataEnShift); | 95 | i2c.a_data_reg = le16_to_cpu(gpio->usDataA_RegisterIndex) * 4; |
95 | i2c.get_clk_mask = (1 << gpio.ucClkY_Shift); | 96 | i2c.mask_clk_mask = (1 << gpio->ucClkMaskShift); |
96 | i2c.get_data_mask = (1 << gpio.ucDataY_Shift); | 97 | i2c.mask_data_mask = (1 << gpio->ucDataMaskShift); |
97 | i2c.a_clk_mask = (1 << gpio.ucClkA_Shift); | 98 | i2c.en_clk_mask = (1 << gpio->ucClkEnShift); |
98 | i2c.a_data_mask = (1 << gpio.ucDataA_Shift); | 99 | i2c.en_data_mask = (1 << gpio->ucDataEnShift); |
99 | i2c.valid = true; | 100 | i2c.y_clk_mask = (1 << gpio->ucClkY_Shift); |
101 | i2c.y_data_mask = (1 << gpio->ucDataY_Shift); | ||
102 | i2c.a_clk_mask = (1 << gpio->ucClkA_Shift); | ||
103 | i2c.a_data_mask = (1 << gpio->ucDataA_Shift); | ||
104 | |||
105 | if (gpio->sucI2cId.sbfAccess.bfHW_Capable) | ||
106 | i2c.hw_capable = true; | ||
107 | else | ||
108 | i2c.hw_capable = false; | ||
109 | |||
110 | if (gpio->sucI2cId.ucAccess == 0xa0) | ||
111 | i2c.mm_i2c = true; | ||
112 | else | ||
113 | i2c.mm_i2c = false; | ||
114 | |||
115 | i2c.i2c_id = gpio->sucI2cId.ucAccess; | ||
116 | |||
117 | i2c.valid = true; | ||
118 | break; | ||
119 | } | ||
120 | } | ||
121 | } | ||
100 | 122 | ||
101 | return i2c; | 123 | return i2c; |
102 | } | 124 | } |
103 | 125 | ||
126 | static inline struct radeon_gpio_rec radeon_lookup_gpio(struct radeon_device *rdev, | ||
127 | u8 id) | ||
128 | { | ||
129 | struct atom_context *ctx = rdev->mode_info.atom_context; | ||
130 | struct radeon_gpio_rec gpio; | ||
131 | int index = GetIndexIntoMasterTable(DATA, GPIO_Pin_LUT); | ||
132 | struct _ATOM_GPIO_PIN_LUT *gpio_info; | ||
133 | ATOM_GPIO_PIN_ASSIGNMENT *pin; | ||
134 | u16 data_offset, size; | ||
135 | int i, num_indices; | ||
136 | |||
137 | memset(&gpio, 0, sizeof(struct radeon_gpio_rec)); | ||
138 | gpio.valid = false; | ||
139 | |||
140 | if (atom_parse_data_header(ctx, index, &size, NULL, NULL, &data_offset)) { | ||
141 | gpio_info = (struct _ATOM_GPIO_PIN_LUT *)(ctx->bios + data_offset); | ||
142 | |||
143 | num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) / | ||
144 | sizeof(ATOM_GPIO_PIN_ASSIGNMENT); | ||
145 | |||
146 | for (i = 0; i < num_indices; i++) { | ||
147 | pin = &gpio_info->asGPIO_Pin[i]; | ||
148 | if (id == pin->ucGPIO_ID) { | ||
149 | gpio.id = pin->ucGPIO_ID; | ||
150 | gpio.reg = pin->usGpioPin_AIndex * 4; | ||
151 | gpio.mask = (1 << pin->ucGpioPinBitShift); | ||
152 | gpio.valid = true; | ||
153 | break; | ||
154 | } | ||
155 | } | ||
156 | } | ||
157 | |||
158 | return gpio; | ||
159 | } | ||
160 | |||
161 | static struct radeon_hpd radeon_atom_get_hpd_info_from_gpio(struct radeon_device *rdev, | ||
162 | struct radeon_gpio_rec *gpio) | ||
163 | { | ||
164 | struct radeon_hpd hpd; | ||
165 | u32 reg; | ||
166 | |||
167 | if (ASIC_IS_DCE4(rdev)) | ||
168 | reg = EVERGREEN_DC_GPIO_HPD_A; | ||
169 | else | ||
170 | reg = AVIVO_DC_GPIO_HPD_A; | ||
171 | |||
172 | hpd.gpio = *gpio; | ||
173 | if (gpio->reg == reg) { | ||
174 | switch(gpio->mask) { | ||
175 | case (1 << 0): | ||
176 | hpd.hpd = RADEON_HPD_1; | ||
177 | break; | ||
178 | case (1 << 8): | ||
179 | hpd.hpd = RADEON_HPD_2; | ||
180 | break; | ||
181 | case (1 << 16): | ||
182 | hpd.hpd = RADEON_HPD_3; | ||
183 | break; | ||
184 | case (1 << 24): | ||
185 | hpd.hpd = RADEON_HPD_4; | ||
186 | break; | ||
187 | case (1 << 26): | ||
188 | hpd.hpd = RADEON_HPD_5; | ||
189 | break; | ||
190 | case (1 << 28): | ||
191 | hpd.hpd = RADEON_HPD_6; | ||
192 | break; | ||
193 | default: | ||
194 | hpd.hpd = RADEON_HPD_NONE; | ||
195 | break; | ||
196 | } | ||
197 | } else | ||
198 | hpd.hpd = RADEON_HPD_NONE; | ||
199 | return hpd; | ||
200 | } | ||
201 | |||
104 | static bool radeon_atom_apply_quirks(struct drm_device *dev, | 202 | static bool radeon_atom_apply_quirks(struct drm_device *dev, |
105 | uint32_t supported_device, | 203 | uint32_t supported_device, |
106 | int *connector_type, | 204 | int *connector_type, |
107 | struct radeon_i2c_bus_rec *i2c_bus, | 205 | struct radeon_i2c_bus_rec *i2c_bus, |
108 | uint16_t *line_mux) | 206 | uint16_t *line_mux, |
207 | struct radeon_hpd *hpd) | ||
109 | { | 208 | { |
110 | 209 | ||
111 | /* Asus M2A-VM HDMI board lists the DVI port as HDMI */ | 210 | /* Asus M2A-VM HDMI board lists the DVI port as HDMI */ |
@@ -117,6 +216,15 @@ static bool radeon_atom_apply_quirks(struct drm_device *dev, | |||
117 | *connector_type = DRM_MODE_CONNECTOR_DVID; | 216 | *connector_type = DRM_MODE_CONNECTOR_DVID; |
118 | } | 217 | } |
119 | 218 | ||
219 | /* Asrock RS600 board lists the DVI port as HDMI */ | ||
220 | if ((dev->pdev->device == 0x7941) && | ||
221 | (dev->pdev->subsystem_vendor == 0x1849) && | ||
222 | (dev->pdev->subsystem_device == 0x7941)) { | ||
223 | if ((*connector_type == DRM_MODE_CONNECTOR_HDMIA) && | ||
224 | (supported_device == ATOM_DEVICE_DFP3_SUPPORT)) | ||
225 | *connector_type = DRM_MODE_CONNECTOR_DVID; | ||
226 | } | ||
227 | |||
120 | /* a-bit f-i90hd - ciaranm on #radeonhd - this board has no DVI */ | 228 | /* a-bit f-i90hd - ciaranm on #radeonhd - this board has no DVI */ |
121 | if ((dev->pdev->device == 0x7941) && | 229 | if ((dev->pdev->device == 0x7941) && |
122 | (dev->pdev->subsystem_vendor == 0x147b) && | 230 | (dev->pdev->subsystem_vendor == 0x147b) && |
@@ -135,6 +243,23 @@ static bool radeon_atom_apply_quirks(struct drm_device *dev, | |||
135 | } | 243 | } |
136 | } | 244 | } |
137 | 245 | ||
246 | /* HIS X1300 is DVI+VGA, not DVI+DVI */ | ||
247 | if ((dev->pdev->device == 0x7146) && | ||
248 | (dev->pdev->subsystem_vendor == 0x17af) && | ||
249 | (dev->pdev->subsystem_device == 0x2058)) { | ||
250 | if (supported_device == ATOM_DEVICE_DFP1_SUPPORT) | ||
251 | return false; | ||
252 | } | ||
253 | |||
254 | /* Gigabyte X1300 is DVI+VGA, not DVI+DVI */ | ||
255 | if ((dev->pdev->device == 0x7142) && | ||
256 | (dev->pdev->subsystem_vendor == 0x1458) && | ||
257 | (dev->pdev->subsystem_device == 0x2134)) { | ||
258 | if (supported_device == ATOM_DEVICE_DFP1_SUPPORT) | ||
259 | return false; | ||
260 | } | ||
261 | |||
262 | |||
138 | /* Funky macbooks */ | 263 | /* Funky macbooks */ |
139 | if ((dev->pdev->device == 0x71C5) && | 264 | if ((dev->pdev->device == 0x71C5) && |
140 | (dev->pdev->subsystem_vendor == 0x106b) && | 265 | (dev->pdev->subsystem_vendor == 0x106b) && |
@@ -142,6 +267,8 @@ static bool radeon_atom_apply_quirks(struct drm_device *dev, | |||
142 | if ((supported_device == ATOM_DEVICE_CRT1_SUPPORT) || | 267 | if ((supported_device == ATOM_DEVICE_CRT1_SUPPORT) || |
143 | (supported_device == ATOM_DEVICE_DFP2_SUPPORT)) | 268 | (supported_device == ATOM_DEVICE_DFP2_SUPPORT)) |
144 | return false; | 269 | return false; |
270 | if (supported_device == ATOM_DEVICE_CRT2_SUPPORT) | ||
271 | *line_mux = 0x90; | ||
145 | } | 272 | } |
146 | 273 | ||
147 | /* ASUS HD 3600 XT board lists the DVI port as HDMI */ | 274 | /* ASUS HD 3600 XT board lists the DVI port as HDMI */ |
@@ -172,6 +299,24 @@ static bool radeon_atom_apply_quirks(struct drm_device *dev, | |||
172 | } | 299 | } |
173 | } | 300 | } |
174 | 301 | ||
302 | /* Acer laptop reports DVI-D as DVI-I */ | ||
303 | if ((dev->pdev->device == 0x95c4) && | ||
304 | (dev->pdev->subsystem_vendor == 0x1025) && | ||
305 | (dev->pdev->subsystem_device == 0x013c)) { | ||
306 | if ((*connector_type == DRM_MODE_CONNECTOR_DVII) && | ||
307 | (supported_device == ATOM_DEVICE_DFP1_SUPPORT)) | ||
308 | *connector_type = DRM_MODE_CONNECTOR_DVID; | ||
309 | } | ||
310 | |||
311 | /* XFX Pine Group device rv730 reports no VGA DDC lines | ||
312 | * even though they are wired up to record 0x93 | ||
313 | */ | ||
314 | if ((dev->pdev->device == 0x9498) && | ||
315 | (dev->pdev->subsystem_vendor == 0x1682) && | ||
316 | (dev->pdev->subsystem_device == 0x2452)) { | ||
317 | struct radeon_device *rdev = dev->dev_private; | ||
318 | *i2c_bus = radeon_lookup_i2c_gpio(rdev, 0x93); | ||
319 | } | ||
175 | return true; | 320 | return true; |
176 | } | 321 | } |
177 | 322 | ||
@@ -231,7 +376,9 @@ const int object_connector_convert[] = { | |||
231 | DRM_MODE_CONNECTOR_Unknown, | 376 | DRM_MODE_CONNECTOR_Unknown, |
232 | DRM_MODE_CONNECTOR_Unknown, | 377 | DRM_MODE_CONNECTOR_Unknown, |
233 | DRM_MODE_CONNECTOR_Unknown, | 378 | DRM_MODE_CONNECTOR_Unknown, |
234 | DRM_MODE_CONNECTOR_DisplayPort | 379 | DRM_MODE_CONNECTOR_DisplayPort, |
380 | DRM_MODE_CONNECTOR_eDP, | ||
381 | DRM_MODE_CONNECTOR_Unknown | ||
235 | }; | 382 | }; |
236 | 383 | ||
237 | bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) | 384 | bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) |
@@ -240,20 +387,20 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) | |||
240 | struct radeon_mode_info *mode_info = &rdev->mode_info; | 387 | struct radeon_mode_info *mode_info = &rdev->mode_info; |
241 | struct atom_context *ctx = mode_info->atom_context; | 388 | struct atom_context *ctx = mode_info->atom_context; |
242 | int index = GetIndexIntoMasterTable(DATA, Object_Header); | 389 | int index = GetIndexIntoMasterTable(DATA, Object_Header); |
243 | uint16_t size, data_offset; | 390 | u16 size, data_offset; |
244 | uint8_t frev, crev, line_mux = 0; | 391 | u8 frev, crev; |
245 | ATOM_CONNECTOR_OBJECT_TABLE *con_obj; | 392 | ATOM_CONNECTOR_OBJECT_TABLE *con_obj; |
246 | ATOM_DISPLAY_OBJECT_PATH_TABLE *path_obj; | 393 | ATOM_DISPLAY_OBJECT_PATH_TABLE *path_obj; |
247 | ATOM_OBJECT_HEADER *obj_header; | 394 | ATOM_OBJECT_HEADER *obj_header; |
248 | int i, j, path_size, device_support; | 395 | int i, j, path_size, device_support; |
249 | int connector_type; | 396 | int connector_type; |
250 | uint16_t igp_lane_info, conn_id, connector_object_id; | 397 | u16 igp_lane_info, conn_id, connector_object_id; |
251 | bool linkb; | 398 | bool linkb; |
252 | struct radeon_i2c_bus_rec ddc_bus; | 399 | struct radeon_i2c_bus_rec ddc_bus; |
400 | struct radeon_gpio_rec gpio; | ||
401 | struct radeon_hpd hpd; | ||
253 | 402 | ||
254 | atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset); | 403 | if (!atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset)) |
255 | |||
256 | if (data_offset == 0) | ||
257 | return false; | 404 | return false; |
258 | 405 | ||
259 | if (crev < 2) | 406 | if (crev < 2) |
@@ -276,7 +423,6 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) | |||
276 | path = (ATOM_DISPLAY_OBJECT_PATH *) addr; | 423 | path = (ATOM_DISPLAY_OBJECT_PATH *) addr; |
277 | path_size += le16_to_cpu(path->usSize); | 424 | path_size += le16_to_cpu(path->usSize); |
278 | linkb = false; | 425 | linkb = false; |
279 | |||
280 | if (device_support & le16_to_cpu(path->usDeviceTag)) { | 426 | if (device_support & le16_to_cpu(path->usDeviceTag)) { |
281 | uint8_t con_obj_id, con_obj_num, con_obj_type; | 427 | uint8_t con_obj_id, con_obj_num, con_obj_type; |
282 | 428 | ||
@@ -306,37 +452,43 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) | |||
306 | GetIndexIntoMasterTable(DATA, | 452 | GetIndexIntoMasterTable(DATA, |
307 | IntegratedSystemInfo); | 453 | IntegratedSystemInfo); |
308 | 454 | ||
309 | atom_parse_data_header(ctx, index, &size, &frev, | 455 | if (atom_parse_data_header(ctx, index, &size, &frev, |
310 | &crev, &igp_offset); | 456 | &crev, &igp_offset)) { |
311 | 457 | ||
312 | if (crev >= 2) { | 458 | if (crev >= 2) { |
313 | igp_obj = | 459 | igp_obj = |
314 | (ATOM_INTEGRATED_SYSTEM_INFO_V2 | 460 | (ATOM_INTEGRATED_SYSTEM_INFO_V2 |
315 | *) (ctx->bios + igp_offset); | 461 | *) (ctx->bios + igp_offset); |
316 | 462 | ||
317 | if (igp_obj) { | 463 | if (igp_obj) { |
318 | uint32_t slot_config, ct; | 464 | uint32_t slot_config, ct; |
319 | 465 | ||
320 | if (con_obj_num == 1) | 466 | if (con_obj_num == 1) |
321 | slot_config = | 467 | slot_config = |
322 | igp_obj-> | 468 | igp_obj-> |
323 | ulDDISlot1Config; | 469 | ulDDISlot1Config; |
324 | else | 470 | else |
325 | slot_config = | 471 | slot_config = |
326 | igp_obj-> | 472 | igp_obj-> |
327 | ulDDISlot2Config; | 473 | ulDDISlot2Config; |
328 | 474 | ||
329 | ct = (slot_config >> 16) & 0xff; | 475 | ct = (slot_config >> 16) & 0xff; |
330 | connector_type = | 476 | connector_type = |
331 | object_connector_convert | 477 | object_connector_convert |
332 | [ct]; | 478 | [ct]; |
333 | connector_object_id = ct; | 479 | connector_object_id = ct; |
334 | igp_lane_info = | 480 | igp_lane_info = |
335 | slot_config & 0xffff; | 481 | slot_config & 0xffff; |
482 | } else | ||
483 | continue; | ||
336 | } else | 484 | } else |
337 | continue; | 485 | continue; |
338 | } else | 486 | } else { |
339 | continue; | 487 | igp_lane_info = 0; |
488 | connector_type = | ||
489 | object_connector_convert[con_obj_id]; | ||
490 | connector_object_id = con_obj_id; | ||
491 | } | ||
340 | } else { | 492 | } else { |
341 | igp_lane_info = 0; | 493 | igp_lane_info = 0; |
342 | connector_type = | 494 | connector_type = |
@@ -377,10 +529,9 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) | |||
377 | } | 529 | } |
378 | } | 530 | } |
379 | 531 | ||
380 | /* look up gpio for ddc */ | 532 | /* look up gpio for ddc, hpd */ |
381 | if ((le16_to_cpu(path->usDeviceTag) & | 533 | if ((le16_to_cpu(path->usDeviceTag) & |
382 | (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) | 534 | (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) == 0) { |
383 | == 0) { | ||
384 | for (j = 0; j < con_obj->ucNumberOfObjects; j++) { | 535 | for (j = 0; j < con_obj->ucNumberOfObjects; j++) { |
385 | if (le16_to_cpu(path->usConnObjectId) == | 536 | if (le16_to_cpu(path->usConnObjectId) == |
386 | le16_to_cpu(con_obj->asObjects[j]. | 537 | le16_to_cpu(con_obj->asObjects[j]. |
@@ -394,21 +545,34 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) | |||
394 | asObjects[j]. | 545 | asObjects[j]. |
395 | usRecordOffset)); | 546 | usRecordOffset)); |
396 | ATOM_I2C_RECORD *i2c_record; | 547 | ATOM_I2C_RECORD *i2c_record; |
548 | ATOM_HPD_INT_RECORD *hpd_record; | ||
549 | ATOM_I2C_ID_CONFIG_ACCESS *i2c_config; | ||
550 | hpd.hpd = RADEON_HPD_NONE; | ||
397 | 551 | ||
398 | while (record->ucRecordType > 0 | 552 | while (record->ucRecordType > 0 |
399 | && record-> | 553 | && record-> |
400 | ucRecordType <= | 554 | ucRecordType <= |
401 | ATOM_MAX_OBJECT_RECORD_NUMBER) { | 555 | ATOM_MAX_OBJECT_RECORD_NUMBER) { |
402 | switch (record-> | 556 | switch (record->ucRecordType) { |
403 | ucRecordType) { | ||
404 | case ATOM_I2C_RECORD_TYPE: | 557 | case ATOM_I2C_RECORD_TYPE: |
405 | i2c_record = | 558 | i2c_record = |
406 | (ATOM_I2C_RECORD | 559 | (ATOM_I2C_RECORD *) |
407 | *) record; | 560 | record; |
408 | line_mux = | 561 | i2c_config = |
409 | i2c_record-> | 562 | (ATOM_I2C_ID_CONFIG_ACCESS *) |
410 | sucI2cId. | 563 | &i2c_record->sucI2cId; |
411 | bfI2C_LineMux; | 564 | ddc_bus = radeon_lookup_i2c_gpio(rdev, |
565 | i2c_config-> | ||
566 | ucAccess); | ||
567 | break; | ||
568 | case ATOM_HPD_INT_RECORD_TYPE: | ||
569 | hpd_record = | ||
570 | (ATOM_HPD_INT_RECORD *) | ||
571 | record; | ||
572 | gpio = radeon_lookup_gpio(rdev, | ||
573 | hpd_record->ucHPDIntGPIOID); | ||
574 | hpd = radeon_atom_get_hpd_info_from_gpio(rdev, &gpio); | ||
575 | hpd.plugged_state = hpd_record->ucPlugged_PinState; | ||
412 | break; | 576 | break; |
413 | } | 577 | } |
414 | record = | 578 | record = |
@@ -421,24 +585,19 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) | |||
421 | break; | 585 | break; |
422 | } | 586 | } |
423 | } | 587 | } |
424 | } else | 588 | } else { |
425 | line_mux = 0; | 589 | hpd.hpd = RADEON_HPD_NONE; |
426 | |||
427 | if ((le16_to_cpu(path->usDeviceTag) == | ||
428 | ATOM_DEVICE_TV1_SUPPORT) | ||
429 | || (le16_to_cpu(path->usDeviceTag) == | ||
430 | ATOM_DEVICE_TV2_SUPPORT) | ||
431 | || (le16_to_cpu(path->usDeviceTag) == | ||
432 | ATOM_DEVICE_CV_SUPPORT)) | ||
433 | ddc_bus.valid = false; | 590 | ddc_bus.valid = false; |
434 | else | 591 | } |
435 | ddc_bus = radeon_lookup_gpio(dev, line_mux); | 592 | |
593 | /* needed for aux chan transactions */ | ||
594 | ddc_bus.hpd_id = hpd.hpd ? (hpd.hpd - 1) : 0; | ||
436 | 595 | ||
437 | conn_id = le16_to_cpu(path->usConnObjectId); | 596 | conn_id = le16_to_cpu(path->usConnObjectId); |
438 | 597 | ||
439 | if (!radeon_atom_apply_quirks | 598 | if (!radeon_atom_apply_quirks |
440 | (dev, le16_to_cpu(path->usDeviceTag), &connector_type, | 599 | (dev, le16_to_cpu(path->usDeviceTag), &connector_type, |
441 | &ddc_bus, &conn_id)) | 600 | &ddc_bus, &conn_id, &hpd)) |
442 | continue; | 601 | continue; |
443 | 602 | ||
444 | radeon_add_atom_connector(dev, | 603 | radeon_add_atom_connector(dev, |
@@ -447,7 +606,8 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) | |||
447 | usDeviceTag), | 606 | usDeviceTag), |
448 | connector_type, &ddc_bus, | 607 | connector_type, &ddc_bus, |
449 | linkb, igp_lane_info, | 608 | linkb, igp_lane_info, |
450 | connector_object_id); | 609 | connector_object_id, |
610 | &hpd); | ||
451 | 611 | ||
452 | } | 612 | } |
453 | } | 613 | } |
@@ -476,20 +636,23 @@ static uint16_t atombios_get_connector_object_id(struct drm_device *dev, | |||
476 | uint8_t frev, crev; | 636 | uint8_t frev, crev; |
477 | ATOM_XTMDS_INFO *xtmds; | 637 | ATOM_XTMDS_INFO *xtmds; |
478 | 638 | ||
479 | atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset); | 639 | if (atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset)) { |
480 | xtmds = (ATOM_XTMDS_INFO *)(ctx->bios + data_offset); | 640 | xtmds = (ATOM_XTMDS_INFO *)(ctx->bios + data_offset); |
481 | 641 | ||
482 | if (xtmds->ucSupportedLink & ATOM_XTMDS_SUPPORTED_DUALLINK) { | 642 | if (xtmds->ucSupportedLink & ATOM_XTMDS_SUPPORTED_DUALLINK) { |
483 | if (connector_type == DRM_MODE_CONNECTOR_DVII) | 643 | if (connector_type == DRM_MODE_CONNECTOR_DVII) |
484 | return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I; | 644 | return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I; |
485 | else | 645 | else |
486 | return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D; | 646 | return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D; |
487 | } else { | 647 | } else { |
488 | if (connector_type == DRM_MODE_CONNECTOR_DVII) | 648 | if (connector_type == DRM_MODE_CONNECTOR_DVII) |
489 | return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I; | 649 | return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I; |
490 | else | 650 | else |
491 | return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D; | 651 | return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D; |
492 | } | 652 | } |
653 | } else | ||
654 | return supported_devices_connector_object_id_convert | ||
655 | [connector_type]; | ||
493 | } else { | 656 | } else { |
494 | return supported_devices_connector_object_id_convert | 657 | return supported_devices_connector_object_id_convert |
495 | [connector_type]; | 658 | [connector_type]; |
@@ -502,6 +665,7 @@ struct bios_connector { | |||
502 | uint16_t devices; | 665 | uint16_t devices; |
503 | int connector_type; | 666 | int connector_type; |
504 | struct radeon_i2c_bus_rec ddc_bus; | 667 | struct radeon_i2c_bus_rec ddc_bus; |
668 | struct radeon_hpd hpd; | ||
505 | }; | 669 | }; |
506 | 670 | ||
507 | bool radeon_get_atom_connector_info_from_supported_devices_table(struct | 671 | bool radeon_get_atom_connector_info_from_supported_devices_table(struct |
@@ -517,17 +681,23 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct | |||
517 | uint16_t device_support; | 681 | uint16_t device_support; |
518 | uint8_t dac; | 682 | uint8_t dac; |
519 | union atom_supported_devices *supported_devices; | 683 | union atom_supported_devices *supported_devices; |
520 | int i, j; | 684 | int i, j, max_device; |
521 | struct bios_connector bios_connectors[ATOM_MAX_SUPPORTED_DEVICE]; | 685 | struct bios_connector bios_connectors[ATOM_MAX_SUPPORTED_DEVICE]; |
522 | 686 | ||
523 | atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset); | 687 | if (!atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset)) |
688 | return false; | ||
524 | 689 | ||
525 | supported_devices = | 690 | supported_devices = |
526 | (union atom_supported_devices *)(ctx->bios + data_offset); | 691 | (union atom_supported_devices *)(ctx->bios + data_offset); |
527 | 692 | ||
528 | device_support = le16_to_cpu(supported_devices->info.usDeviceSupport); | 693 | device_support = le16_to_cpu(supported_devices->info.usDeviceSupport); |
529 | 694 | ||
530 | for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) { | 695 | if (frev > 1) |
696 | max_device = ATOM_MAX_SUPPORTED_DEVICE; | ||
697 | else | ||
698 | max_device = ATOM_MAX_SUPPORTED_DEVICE_INFO; | ||
699 | |||
700 | for (i = 0; i < max_device; i++) { | ||
531 | ATOM_CONNECTOR_INFO_I2C ci = | 701 | ATOM_CONNECTOR_INFO_I2C ci = |
532 | supported_devices->info.asConnInfo[i]; | 702 | supported_devices->info.asConnInfo[i]; |
533 | 703 | ||
@@ -553,22 +723,8 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct | |||
553 | 723 | ||
554 | dac = ci.sucConnectorInfo.sbfAccess.bfAssociatedDAC; | 724 | dac = ci.sucConnectorInfo.sbfAccess.bfAssociatedDAC; |
555 | 725 | ||
556 | if ((rdev->family == CHIP_RS690) || | 726 | bios_connectors[i].line_mux = |
557 | (rdev->family == CHIP_RS740)) { | 727 | ci.sucI2cId.ucAccess; |
558 | if ((i == ATOM_DEVICE_DFP2_INDEX) | ||
559 | && (ci.sucI2cId.sbfAccess.bfI2C_LineMux == 2)) | ||
560 | bios_connectors[i].line_mux = | ||
561 | ci.sucI2cId.sbfAccess.bfI2C_LineMux + 1; | ||
562 | else if ((i == ATOM_DEVICE_DFP3_INDEX) | ||
563 | && (ci.sucI2cId.sbfAccess.bfI2C_LineMux == 1)) | ||
564 | bios_connectors[i].line_mux = | ||
565 | ci.sucI2cId.sbfAccess.bfI2C_LineMux + 1; | ||
566 | else | ||
567 | bios_connectors[i].line_mux = | ||
568 | ci.sucI2cId.sbfAccess.bfI2C_LineMux; | ||
569 | } else | ||
570 | bios_connectors[i].line_mux = | ||
571 | ci.sucI2cId.sbfAccess.bfI2C_LineMux; | ||
572 | 728 | ||
573 | /* give tv unique connector ids */ | 729 | /* give tv unique connector ids */ |
574 | if (i == ATOM_DEVICE_TV1_INDEX) { | 730 | if (i == ATOM_DEVICE_TV1_INDEX) { |
@@ -582,8 +738,30 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct | |||
582 | bios_connectors[i].line_mux = 52; | 738 | bios_connectors[i].line_mux = 52; |
583 | } else | 739 | } else |
584 | bios_connectors[i].ddc_bus = | 740 | bios_connectors[i].ddc_bus = |
585 | radeon_lookup_gpio(dev, | 741 | radeon_lookup_i2c_gpio(rdev, |
586 | bios_connectors[i].line_mux); | 742 | bios_connectors[i].line_mux); |
743 | |||
744 | if ((crev > 1) && (frev > 1)) { | ||
745 | u8 isb = supported_devices->info_2d1.asIntSrcInfo[i].ucIntSrcBitmap; | ||
746 | switch (isb) { | ||
747 | case 0x4: | ||
748 | bios_connectors[i].hpd.hpd = RADEON_HPD_1; | ||
749 | break; | ||
750 | case 0xa: | ||
751 | bios_connectors[i].hpd.hpd = RADEON_HPD_2; | ||
752 | break; | ||
753 | default: | ||
754 | bios_connectors[i].hpd.hpd = RADEON_HPD_NONE; | ||
755 | break; | ||
756 | } | ||
757 | } else { | ||
758 | if (i == ATOM_DEVICE_DFP1_INDEX) | ||
759 | bios_connectors[i].hpd.hpd = RADEON_HPD_1; | ||
760 | else if (i == ATOM_DEVICE_DFP2_INDEX) | ||
761 | bios_connectors[i].hpd.hpd = RADEON_HPD_2; | ||
762 | else | ||
763 | bios_connectors[i].hpd.hpd = RADEON_HPD_NONE; | ||
764 | } | ||
587 | 765 | ||
588 | /* Always set the connector type to VGA for CRT1/CRT2. if they are | 766 | /* Always set the connector type to VGA for CRT1/CRT2. if they are |
589 | * shared with a DVI port, we'll pick up the DVI connector when we | 767 | * shared with a DVI port, we'll pick up the DVI connector when we |
@@ -595,7 +773,8 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct | |||
595 | 773 | ||
596 | if (!radeon_atom_apply_quirks | 774 | if (!radeon_atom_apply_quirks |
597 | (dev, (1 << i), &bios_connectors[i].connector_type, | 775 | (dev, (1 << i), &bios_connectors[i].connector_type, |
598 | &bios_connectors[i].ddc_bus, &bios_connectors[i].line_mux)) | 776 | &bios_connectors[i].ddc_bus, &bios_connectors[i].line_mux, |
777 | &bios_connectors[i].hpd)) | ||
599 | continue; | 778 | continue; |
600 | 779 | ||
601 | bios_connectors[i].valid = true; | 780 | bios_connectors[i].valid = true; |
@@ -610,41 +789,42 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct | |||
610 | else | 789 | else |
611 | radeon_add_legacy_encoder(dev, | 790 | radeon_add_legacy_encoder(dev, |
612 | radeon_get_encoder_id(dev, | 791 | radeon_get_encoder_id(dev, |
613 | (1 << | 792 | (1 << i), |
614 | i), | ||
615 | dac), | 793 | dac), |
616 | (1 << i)); | 794 | (1 << i)); |
617 | } | 795 | } |
618 | 796 | ||
619 | /* combine shared connectors */ | 797 | /* combine shared connectors */ |
620 | for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) { | 798 | for (i = 0; i < max_device; i++) { |
621 | if (bios_connectors[i].valid) { | 799 | if (bios_connectors[i].valid) { |
622 | for (j = 0; j < ATOM_MAX_SUPPORTED_DEVICE; j++) { | 800 | for (j = 0; j < max_device; j++) { |
623 | if (bios_connectors[j].valid && (i != j)) { | 801 | if (bios_connectors[j].valid && (i != j)) { |
624 | if (bios_connectors[i].line_mux == | 802 | if (bios_connectors[i].line_mux == |
625 | bios_connectors[j].line_mux) { | 803 | bios_connectors[j].line_mux) { |
626 | if (((bios_connectors[i]. | 804 | /* make sure not to combine LVDS */ |
627 | devices & | 805 | if (bios_connectors[i].devices & (ATOM_DEVICE_LCD_SUPPORT)) { |
628 | (ATOM_DEVICE_DFP_SUPPORT)) | 806 | bios_connectors[i].line_mux = 53; |
629 | && (bios_connectors[j]. | 807 | bios_connectors[i].ddc_bus.valid = false; |
630 | devices & | 808 | continue; |
631 | (ATOM_DEVICE_CRT_SUPPORT))) | 809 | } |
632 | || | 810 | if (bios_connectors[j].devices & (ATOM_DEVICE_LCD_SUPPORT)) { |
633 | ((bios_connectors[j]. | 811 | bios_connectors[j].line_mux = 53; |
634 | devices & | 812 | bios_connectors[j].ddc_bus.valid = false; |
635 | (ATOM_DEVICE_DFP_SUPPORT)) | 813 | continue; |
636 | && (bios_connectors[i]. | 814 | } |
637 | devices & | 815 | /* combine analog and digital for DVI-I */ |
638 | (ATOM_DEVICE_CRT_SUPPORT)))) { | 816 | if (((bios_connectors[i].devices & (ATOM_DEVICE_DFP_SUPPORT)) && |
639 | bios_connectors[i]. | 817 | (bios_connectors[j].devices & (ATOM_DEVICE_CRT_SUPPORT))) || |
640 | devices |= | 818 | ((bios_connectors[j].devices & (ATOM_DEVICE_DFP_SUPPORT)) && |
641 | bios_connectors[j]. | 819 | (bios_connectors[i].devices & (ATOM_DEVICE_CRT_SUPPORT)))) { |
642 | devices; | 820 | bios_connectors[i].devices |= |
643 | bios_connectors[i]. | 821 | bios_connectors[j].devices; |
644 | connector_type = | 822 | bios_connectors[i].connector_type = |
645 | DRM_MODE_CONNECTOR_DVII; | 823 | DRM_MODE_CONNECTOR_DVII; |
646 | bios_connectors[j]. | 824 | if (bios_connectors[j].devices & (ATOM_DEVICE_DFP_SUPPORT)) |
647 | valid = false; | 825 | bios_connectors[i].hpd = |
826 | bios_connectors[j].hpd; | ||
827 | bios_connectors[j].valid = false; | ||
648 | } | 828 | } |
649 | } | 829 | } |
650 | } | 830 | } |
@@ -653,7 +833,7 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct | |||
653 | } | 833 | } |
654 | 834 | ||
655 | /* add the connectors */ | 835 | /* add the connectors */ |
656 | for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) { | 836 | for (i = 0; i < max_device; i++) { |
657 | if (bios_connectors[i].valid) { | 837 | if (bios_connectors[i].valid) { |
658 | uint16_t connector_object_id = | 838 | uint16_t connector_object_id = |
659 | atombios_get_connector_object_id(dev, | 839 | atombios_get_connector_object_id(dev, |
@@ -666,7 +846,8 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct | |||
666 | connector_type, | 846 | connector_type, |
667 | &bios_connectors[i].ddc_bus, | 847 | &bios_connectors[i].ddc_bus, |
668 | false, 0, | 848 | false, 0, |
669 | connector_object_id); | 849 | connector_object_id, |
850 | &bios_connectors[i].hpd); | ||
670 | } | 851 | } |
671 | } | 852 | } |
672 | 853 | ||
@@ -680,6 +861,7 @@ union firmware_info { | |||
680 | ATOM_FIRMWARE_INFO_V1_2 info_12; | 861 | ATOM_FIRMWARE_INFO_V1_2 info_12; |
681 | ATOM_FIRMWARE_INFO_V1_3 info_13; | 862 | ATOM_FIRMWARE_INFO_V1_3 info_13; |
682 | ATOM_FIRMWARE_INFO_V1_4 info_14; | 863 | ATOM_FIRMWARE_INFO_V1_4 info_14; |
864 | ATOM_FIRMWARE_INFO_V2_1 info_21; | ||
683 | }; | 865 | }; |
684 | 866 | ||
685 | bool radeon_atom_get_clock_info(struct drm_device *dev) | 867 | bool radeon_atom_get_clock_info(struct drm_device *dev) |
@@ -691,18 +873,16 @@ bool radeon_atom_get_clock_info(struct drm_device *dev) | |||
691 | uint8_t frev, crev; | 873 | uint8_t frev, crev; |
692 | struct radeon_pll *p1pll = &rdev->clock.p1pll; | 874 | struct radeon_pll *p1pll = &rdev->clock.p1pll; |
693 | struct radeon_pll *p2pll = &rdev->clock.p2pll; | 875 | struct radeon_pll *p2pll = &rdev->clock.p2pll; |
876 | struct radeon_pll *dcpll = &rdev->clock.dcpll; | ||
694 | struct radeon_pll *spll = &rdev->clock.spll; | 877 | struct radeon_pll *spll = &rdev->clock.spll; |
695 | struct radeon_pll *mpll = &rdev->clock.mpll; | 878 | struct radeon_pll *mpll = &rdev->clock.mpll; |
696 | uint16_t data_offset; | 879 | uint16_t data_offset; |
697 | 880 | ||
698 | atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, | 881 | if (atom_parse_data_header(mode_info->atom_context, index, NULL, |
699 | &crev, &data_offset); | 882 | &frev, &crev, &data_offset)) { |
700 | 883 | firmware_info = | |
701 | firmware_info = | 884 | (union firmware_info *)(mode_info->atom_context->bios + |
702 | (union firmware_info *)(mode_info->atom_context->bios + | 885 | data_offset); |
703 | data_offset); | ||
704 | |||
705 | if (firmware_info) { | ||
706 | /* pixel clocks */ | 886 | /* pixel clocks */ |
707 | p1pll->reference_freq = | 887 | p1pll->reference_freq = |
708 | le16_to_cpu(firmware_info->info.usReferenceClock); | 888 | le16_to_cpu(firmware_info->info.usReferenceClock); |
@@ -717,6 +897,20 @@ bool radeon_atom_get_clock_info(struct drm_device *dev) | |||
717 | p1pll->pll_out_max = | 897 | p1pll->pll_out_max = |
718 | le32_to_cpu(firmware_info->info.ulMaxPixelClockPLL_Output); | 898 | le32_to_cpu(firmware_info->info.ulMaxPixelClockPLL_Output); |
719 | 899 | ||
900 | if (crev >= 4) { | ||
901 | p1pll->lcd_pll_out_min = | ||
902 | le16_to_cpu(firmware_info->info_14.usLcdMinPixelClockPLL_Output) * 100; | ||
903 | if (p1pll->lcd_pll_out_min == 0) | ||
904 | p1pll->lcd_pll_out_min = p1pll->pll_out_min; | ||
905 | p1pll->lcd_pll_out_max = | ||
906 | le16_to_cpu(firmware_info->info_14.usLcdMaxPixelClockPLL_Output) * 100; | ||
907 | if (p1pll->lcd_pll_out_max == 0) | ||
908 | p1pll->lcd_pll_out_max = p1pll->pll_out_max; | ||
909 | } else { | ||
910 | p1pll->lcd_pll_out_min = p1pll->pll_out_min; | ||
911 | p1pll->lcd_pll_out_max = p1pll->pll_out_max; | ||
912 | } | ||
913 | |||
720 | if (p1pll->pll_out_min == 0) { | 914 | if (p1pll->pll_out_min == 0) { |
721 | if (ASIC_IS_AVIVO(rdev)) | 915 | if (ASIC_IS_AVIVO(rdev)) |
722 | p1pll->pll_out_min = 64800; | 916 | p1pll->pll_out_min = 64800; |
@@ -731,7 +925,8 @@ bool radeon_atom_get_clock_info(struct drm_device *dev) | |||
731 | * pre-DCE 3.0 r6xx hardware. This might need to be adjusted per | 925 | * pre-DCE 3.0 r6xx hardware. This might need to be adjusted per |
732 | * family. | 926 | * family. |
733 | */ | 927 | */ |
734 | p1pll->pll_out_min = 64800; | 928 | if (!radeon_new_pll) |
929 | p1pll->pll_out_min = 64800; | ||
735 | } | 930 | } |
736 | 931 | ||
737 | p1pll->pll_in_min = | 932 | p1pll->pll_in_min = |
@@ -792,8 +987,53 @@ bool radeon_atom_get_clock_info(struct drm_device *dev) | |||
792 | rdev->clock.default_mclk = | 987 | rdev->clock.default_mclk = |
793 | le32_to_cpu(firmware_info->info.ulDefaultMemoryClock); | 988 | le32_to_cpu(firmware_info->info.ulDefaultMemoryClock); |
794 | 989 | ||
990 | if (ASIC_IS_DCE4(rdev)) { | ||
991 | rdev->clock.default_dispclk = | ||
992 | le32_to_cpu(firmware_info->info_21.ulDefaultDispEngineClkFreq); | ||
993 | if (rdev->clock.default_dispclk == 0) | ||
994 | rdev->clock.default_dispclk = 60000; /* 600 Mhz */ | ||
995 | rdev->clock.dp_extclk = | ||
996 | le16_to_cpu(firmware_info->info_21.usUniphyDPModeExtClkFreq); | ||
997 | } | ||
998 | *dcpll = *p1pll; | ||
999 | |||
795 | return true; | 1000 | return true; |
796 | } | 1001 | } |
1002 | |||
1003 | return false; | ||
1004 | } | ||
1005 | |||
1006 | union igp_info { | ||
1007 | struct _ATOM_INTEGRATED_SYSTEM_INFO info; | ||
1008 | struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 info_2; | ||
1009 | }; | ||
1010 | |||
1011 | bool radeon_atombios_sideport_present(struct radeon_device *rdev) | ||
1012 | { | ||
1013 | struct radeon_mode_info *mode_info = &rdev->mode_info; | ||
1014 | int index = GetIndexIntoMasterTable(DATA, IntegratedSystemInfo); | ||
1015 | union igp_info *igp_info; | ||
1016 | u8 frev, crev; | ||
1017 | u16 data_offset; | ||
1018 | |||
1019 | if (atom_parse_data_header(mode_info->atom_context, index, NULL, | ||
1020 | &frev, &crev, &data_offset)) { | ||
1021 | igp_info = (union igp_info *)(mode_info->atom_context->bios + | ||
1022 | data_offset); | ||
1023 | switch (crev) { | ||
1024 | case 1: | ||
1025 | if (igp_info->info.ucMemoryType & 0xf0) | ||
1026 | return true; | ||
1027 | break; | ||
1028 | case 2: | ||
1029 | if (igp_info->info_2.ucMemoryType & 0x0f) | ||
1030 | return true; | ||
1031 | break; | ||
1032 | default: | ||
1033 | DRM_ERROR("Unsupported IGP table: %d %d\n", frev, crev); | ||
1034 | break; | ||
1035 | } | ||
1036 | } | ||
797 | return false; | 1037 | return false; |
798 | } | 1038 | } |
799 | 1039 | ||
@@ -810,14 +1050,12 @@ bool radeon_atombios_get_tmds_info(struct radeon_encoder *encoder, | |||
810 | uint16_t maxfreq; | 1050 | uint16_t maxfreq; |
811 | int i; | 1051 | int i; |
812 | 1052 | ||
813 | atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, | 1053 | if (atom_parse_data_header(mode_info->atom_context, index, NULL, |
814 | &crev, &data_offset); | 1054 | &frev, &crev, &data_offset)) { |
1055 | tmds_info = | ||
1056 | (struct _ATOM_TMDS_INFO *)(mode_info->atom_context->bios + | ||
1057 | data_offset); | ||
815 | 1058 | ||
816 | tmds_info = | ||
817 | (struct _ATOM_TMDS_INFO *)(mode_info->atom_context->bios + | ||
818 | data_offset); | ||
819 | |||
820 | if (tmds_info) { | ||
821 | maxfreq = le16_to_cpu(tmds_info->usMaxFrequency); | 1059 | maxfreq = le16_to_cpu(tmds_info->usMaxFrequency); |
822 | for (i = 0; i < 4; i++) { | 1060 | for (i = 0; i < 4; i++) { |
823 | tmds->tmds_pll[i].freq = | 1061 | tmds->tmds_pll[i].freq = |
@@ -861,29 +1099,34 @@ static struct radeon_atom_ss *radeon_atombios_get_ss_info(struct | |||
861 | struct _ATOM_SPREAD_SPECTRUM_INFO *ss_info; | 1099 | struct _ATOM_SPREAD_SPECTRUM_INFO *ss_info; |
862 | uint8_t frev, crev; | 1100 | uint8_t frev, crev; |
863 | struct radeon_atom_ss *ss = NULL; | 1101 | struct radeon_atom_ss *ss = NULL; |
1102 | int i; | ||
864 | 1103 | ||
865 | if (id > ATOM_MAX_SS_ENTRY) | 1104 | if (id > ATOM_MAX_SS_ENTRY) |
866 | return NULL; | 1105 | return NULL; |
867 | 1106 | ||
868 | atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, | 1107 | if (atom_parse_data_header(mode_info->atom_context, index, NULL, |
869 | &crev, &data_offset); | 1108 | &frev, &crev, &data_offset)) { |
870 | 1109 | ss_info = | |
871 | ss_info = | 1110 | (struct _ATOM_SPREAD_SPECTRUM_INFO *)(mode_info->atom_context->bios + data_offset); |
872 | (struct _ATOM_SPREAD_SPECTRUM_INFO *)(mode_info->atom_context->bios + data_offset); | ||
873 | 1111 | ||
874 | if (ss_info) { | ||
875 | ss = | 1112 | ss = |
876 | kzalloc(sizeof(struct radeon_atom_ss), GFP_KERNEL); | 1113 | kzalloc(sizeof(struct radeon_atom_ss), GFP_KERNEL); |
877 | 1114 | ||
878 | if (!ss) | 1115 | if (!ss) |
879 | return NULL; | 1116 | return NULL; |
880 | 1117 | ||
881 | ss->percentage = le16_to_cpu(ss_info->asSS_Info[id].usSpreadSpectrumPercentage); | 1118 | for (i = 0; i < ATOM_MAX_SS_ENTRY; i++) { |
882 | ss->type = ss_info->asSS_Info[id].ucSpreadSpectrumType; | 1119 | if (ss_info->asSS_Info[i].ucSS_Id == id) { |
883 | ss->step = ss_info->asSS_Info[id].ucSS_Step; | 1120 | ss->percentage = |
884 | ss->delay = ss_info->asSS_Info[id].ucSS_Delay; | 1121 | le16_to_cpu(ss_info->asSS_Info[i].usSpreadSpectrumPercentage); |
885 | ss->range = ss_info->asSS_Info[id].ucSS_Range; | 1122 | ss->type = ss_info->asSS_Info[i].ucSpreadSpectrumType; |
886 | ss->refdiv = ss_info->asSS_Info[id].ucRecommendedRef_Div; | 1123 | ss->step = ss_info->asSS_Info[i].ucSS_Step; |
1124 | ss->delay = ss_info->asSS_Info[i].ucSS_Delay; | ||
1125 | ss->range = ss_info->asSS_Info[i].ucSS_Range; | ||
1126 | ss->refdiv = ss_info->asSS_Info[i].ucRecommendedRef_Div; | ||
1127 | break; | ||
1128 | } | ||
1129 | } | ||
887 | } | 1130 | } |
888 | return ss; | 1131 | return ss; |
889 | } | 1132 | } |
@@ -901,18 +1144,15 @@ struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct | |||
901 | struct radeon_device *rdev = dev->dev_private; | 1144 | struct radeon_device *rdev = dev->dev_private; |
902 | struct radeon_mode_info *mode_info = &rdev->mode_info; | 1145 | struct radeon_mode_info *mode_info = &rdev->mode_info; |
903 | int index = GetIndexIntoMasterTable(DATA, LVDS_Info); | 1146 | int index = GetIndexIntoMasterTable(DATA, LVDS_Info); |
904 | uint16_t data_offset; | 1147 | uint16_t data_offset, misc; |
905 | union lvds_info *lvds_info; | 1148 | union lvds_info *lvds_info; |
906 | uint8_t frev, crev; | 1149 | uint8_t frev, crev; |
907 | struct radeon_encoder_atom_dig *lvds = NULL; | 1150 | struct radeon_encoder_atom_dig *lvds = NULL; |
908 | 1151 | ||
909 | atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, | 1152 | if (atom_parse_data_header(mode_info->atom_context, index, NULL, |
910 | &crev, &data_offset); | 1153 | &frev, &crev, &data_offset)) { |
911 | 1154 | lvds_info = | |
912 | lvds_info = | 1155 | (union lvds_info *)(mode_info->atom_context->bios + data_offset); |
913 | (union lvds_info *)(mode_info->atom_context->bios + data_offset); | ||
914 | |||
915 | if (lvds_info) { | ||
916 | lvds = | 1156 | lvds = |
917 | kzalloc(sizeof(struct radeon_encoder_atom_dig), GFP_KERNEL); | 1157 | kzalloc(sizeof(struct radeon_encoder_atom_dig), GFP_KERNEL); |
918 | 1158 | ||
@@ -940,11 +1180,36 @@ struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct | |||
940 | lvds->panel_pwr_delay = | 1180 | lvds->panel_pwr_delay = |
941 | le16_to_cpu(lvds_info->info.usOffDelayInMs); | 1181 | le16_to_cpu(lvds_info->info.usOffDelayInMs); |
942 | lvds->lvds_misc = lvds_info->info.ucLVDS_Misc; | 1182 | lvds->lvds_misc = lvds_info->info.ucLVDS_Misc; |
1183 | |||
1184 | misc = le16_to_cpu(lvds_info->info.sLCDTiming.susModeMiscInfo.usAccess); | ||
1185 | if (misc & ATOM_VSYNC_POLARITY) | ||
1186 | lvds->native_mode.flags |= DRM_MODE_FLAG_NVSYNC; | ||
1187 | if (misc & ATOM_HSYNC_POLARITY) | ||
1188 | lvds->native_mode.flags |= DRM_MODE_FLAG_NHSYNC; | ||
1189 | if (misc & ATOM_COMPOSITESYNC) | ||
1190 | lvds->native_mode.flags |= DRM_MODE_FLAG_CSYNC; | ||
1191 | if (misc & ATOM_INTERLACE) | ||
1192 | lvds->native_mode.flags |= DRM_MODE_FLAG_INTERLACE; | ||
1193 | if (misc & ATOM_DOUBLE_CLOCK_MODE) | ||
1194 | lvds->native_mode.flags |= DRM_MODE_FLAG_DBLSCAN; | ||
1195 | |||
943 | /* set crtc values */ | 1196 | /* set crtc values */ |
944 | drm_mode_set_crtcinfo(&lvds->native_mode, CRTC_INTERLACE_HALVE_V); | 1197 | drm_mode_set_crtcinfo(&lvds->native_mode, CRTC_INTERLACE_HALVE_V); |
945 | 1198 | ||
946 | lvds->ss = radeon_atombios_get_ss_info(encoder, lvds_info->info.ucSS_Id); | 1199 | lvds->ss = radeon_atombios_get_ss_info(encoder, lvds_info->info.ucSS_Id); |
947 | 1200 | ||
1201 | if (ASIC_IS_AVIVO(rdev)) { | ||
1202 | if (radeon_new_pll == 0) | ||
1203 | lvds->pll_algo = PLL_ALGO_LEGACY; | ||
1204 | else | ||
1205 | lvds->pll_algo = PLL_ALGO_NEW; | ||
1206 | } else { | ||
1207 | if (radeon_new_pll == 1) | ||
1208 | lvds->pll_algo = PLL_ALGO_NEW; | ||
1209 | else | ||
1210 | lvds->pll_algo = PLL_ALGO_LEGACY; | ||
1211 | } | ||
1212 | |||
948 | encoder->native_mode = lvds->native_mode; | 1213 | encoder->native_mode = lvds->native_mode; |
949 | } | 1214 | } |
950 | return lvds; | 1215 | return lvds; |
@@ -963,11 +1228,11 @@ radeon_atombios_get_primary_dac_info(struct radeon_encoder *encoder) | |||
963 | uint8_t bg, dac; | 1228 | uint8_t bg, dac; |
964 | struct radeon_encoder_primary_dac *p_dac = NULL; | 1229 | struct radeon_encoder_primary_dac *p_dac = NULL; |
965 | 1230 | ||
966 | atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, &crev, &data_offset); | 1231 | if (atom_parse_data_header(mode_info->atom_context, index, NULL, |
967 | 1232 | &frev, &crev, &data_offset)) { | |
968 | dac_info = (struct _COMPASSIONATE_DATA *)(mode_info->atom_context->bios + data_offset); | 1233 | dac_info = (struct _COMPASSIONATE_DATA *) |
1234 | (mode_info->atom_context->bios + data_offset); | ||
969 | 1235 | ||
970 | if (dac_info) { | ||
971 | p_dac = kzalloc(sizeof(struct radeon_encoder_primary_dac), GFP_KERNEL); | 1236 | p_dac = kzalloc(sizeof(struct radeon_encoder_primary_dac), GFP_KERNEL); |
972 | 1237 | ||
973 | if (!p_dac) | 1238 | if (!p_dac) |
@@ -992,12 +1257,14 @@ bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index, | |||
992 | u8 frev, crev; | 1257 | u8 frev, crev; |
993 | u16 data_offset, misc; | 1258 | u16 data_offset, misc; |
994 | 1259 | ||
995 | atom_parse_data_header(mode_info->atom_context, data_index, NULL, &frev, &crev, &data_offset); | 1260 | if (!atom_parse_data_header(mode_info->atom_context, data_index, NULL, |
1261 | &frev, &crev, &data_offset)) | ||
1262 | return false; | ||
996 | 1263 | ||
997 | switch (crev) { | 1264 | switch (crev) { |
998 | case 1: | 1265 | case 1: |
999 | tv_info = (ATOM_ANALOG_TV_INFO *)(mode_info->atom_context->bios + data_offset); | 1266 | tv_info = (ATOM_ANALOG_TV_INFO *)(mode_info->atom_context->bios + data_offset); |
1000 | if (index > MAX_SUPPORTED_TV_TIMING) | 1267 | if (index >= MAX_SUPPORTED_TV_TIMING) |
1001 | return false; | 1268 | return false; |
1002 | 1269 | ||
1003 | mode->crtc_htotal = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_Total); | 1270 | mode->crtc_htotal = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_Total); |
@@ -1035,7 +1302,7 @@ bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index, | |||
1035 | break; | 1302 | break; |
1036 | case 2: | 1303 | case 2: |
1037 | tv_info_v1_2 = (ATOM_ANALOG_TV_INFO_V1_2 *)(mode_info->atom_context->bios + data_offset); | 1304 | tv_info_v1_2 = (ATOM_ANALOG_TV_INFO_V1_2 *)(mode_info->atom_context->bios + data_offset); |
1038 | if (index > MAX_SUPPORTED_TV_TIMING_V1_2) | 1305 | if (index >= MAX_SUPPORTED_TV_TIMING_V1_2) |
1039 | return false; | 1306 | return false; |
1040 | 1307 | ||
1041 | dtd_timings = &tv_info_v1_2->aModeTimings[index]; | 1308 | dtd_timings = &tv_info_v1_2->aModeTimings[index]; |
@@ -1074,6 +1341,64 @@ bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index, | |||
1074 | return true; | 1341 | return true; |
1075 | } | 1342 | } |
1076 | 1343 | ||
1344 | enum radeon_tv_std | ||
1345 | radeon_atombios_get_tv_info(struct radeon_device *rdev) | ||
1346 | { | ||
1347 | struct radeon_mode_info *mode_info = &rdev->mode_info; | ||
1348 | int index = GetIndexIntoMasterTable(DATA, AnalogTV_Info); | ||
1349 | uint16_t data_offset; | ||
1350 | uint8_t frev, crev; | ||
1351 | struct _ATOM_ANALOG_TV_INFO *tv_info; | ||
1352 | enum radeon_tv_std tv_std = TV_STD_NTSC; | ||
1353 | |||
1354 | if (atom_parse_data_header(mode_info->atom_context, index, NULL, | ||
1355 | &frev, &crev, &data_offset)) { | ||
1356 | |||
1357 | tv_info = (struct _ATOM_ANALOG_TV_INFO *) | ||
1358 | (mode_info->atom_context->bios + data_offset); | ||
1359 | |||
1360 | switch (tv_info->ucTV_BootUpDefaultStandard) { | ||
1361 | case ATOM_TV_NTSC: | ||
1362 | tv_std = TV_STD_NTSC; | ||
1363 | DRM_INFO("Default TV standard: NTSC\n"); | ||
1364 | break; | ||
1365 | case ATOM_TV_NTSCJ: | ||
1366 | tv_std = TV_STD_NTSC_J; | ||
1367 | DRM_INFO("Default TV standard: NTSC-J\n"); | ||
1368 | break; | ||
1369 | case ATOM_TV_PAL: | ||
1370 | tv_std = TV_STD_PAL; | ||
1371 | DRM_INFO("Default TV standard: PAL\n"); | ||
1372 | break; | ||
1373 | case ATOM_TV_PALM: | ||
1374 | tv_std = TV_STD_PAL_M; | ||
1375 | DRM_INFO("Default TV standard: PAL-M\n"); | ||
1376 | break; | ||
1377 | case ATOM_TV_PALN: | ||
1378 | tv_std = TV_STD_PAL_N; | ||
1379 | DRM_INFO("Default TV standard: PAL-N\n"); | ||
1380 | break; | ||
1381 | case ATOM_TV_PALCN: | ||
1382 | tv_std = TV_STD_PAL_CN; | ||
1383 | DRM_INFO("Default TV standard: PAL-CN\n"); | ||
1384 | break; | ||
1385 | case ATOM_TV_PAL60: | ||
1386 | tv_std = TV_STD_PAL_60; | ||
1387 | DRM_INFO("Default TV standard: PAL-60\n"); | ||
1388 | break; | ||
1389 | case ATOM_TV_SECAM: | ||
1390 | tv_std = TV_STD_SECAM; | ||
1391 | DRM_INFO("Default TV standard: SECAM\n"); | ||
1392 | break; | ||
1393 | default: | ||
1394 | tv_std = TV_STD_NTSC; | ||
1395 | DRM_INFO("Unknown TV standard; defaulting to NTSC\n"); | ||
1396 | break; | ||
1397 | } | ||
1398 | } | ||
1399 | return tv_std; | ||
1400 | } | ||
1401 | |||
1077 | struct radeon_encoder_tv_dac * | 1402 | struct radeon_encoder_tv_dac * |
1078 | radeon_atombios_get_tv_dac_info(struct radeon_encoder *encoder) | 1403 | radeon_atombios_get_tv_dac_info(struct radeon_encoder *encoder) |
1079 | { | 1404 | { |
@@ -1087,11 +1412,12 @@ radeon_atombios_get_tv_dac_info(struct radeon_encoder *encoder) | |||
1087 | uint8_t bg, dac; | 1412 | uint8_t bg, dac; |
1088 | struct radeon_encoder_tv_dac *tv_dac = NULL; | 1413 | struct radeon_encoder_tv_dac *tv_dac = NULL; |
1089 | 1414 | ||
1090 | atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, &crev, &data_offset); | 1415 | if (atom_parse_data_header(mode_info->atom_context, index, NULL, |
1416 | &frev, &crev, &data_offset)) { | ||
1091 | 1417 | ||
1092 | dac_info = (struct _COMPASSIONATE_DATA *)(mode_info->atom_context->bios + data_offset); | 1418 | dac_info = (struct _COMPASSIONATE_DATA *) |
1419 | (mode_info->atom_context->bios + data_offset); | ||
1093 | 1420 | ||
1094 | if (dac_info) { | ||
1095 | tv_dac = kzalloc(sizeof(struct radeon_encoder_tv_dac), GFP_KERNEL); | 1421 | tv_dac = kzalloc(sizeof(struct radeon_encoder_tv_dac), GFP_KERNEL); |
1096 | 1422 | ||
1097 | if (!tv_dac) | 1423 | if (!tv_dac) |
@@ -1109,24 +1435,429 @@ radeon_atombios_get_tv_dac_info(struct radeon_encoder *encoder) | |||
1109 | dac = dac_info->ucDAC2_NTSC_DAC_Adjustment; | 1435 | dac = dac_info->ucDAC2_NTSC_DAC_Adjustment; |
1110 | tv_dac->ntsc_tvdac_adj = (bg << 16) | (dac << 20); | 1436 | tv_dac->ntsc_tvdac_adj = (bg << 16) | (dac << 20); |
1111 | 1437 | ||
1438 | tv_dac->tv_std = radeon_atombios_get_tv_info(rdev); | ||
1112 | } | 1439 | } |
1113 | return tv_dac; | 1440 | return tv_dac; |
1114 | } | 1441 | } |
1115 | 1442 | ||
1116 | void radeon_atom_set_clock_gating(struct radeon_device *rdev, int enable) | 1443 | static const char *thermal_controller_names[] = { |
1444 | "NONE", | ||
1445 | "LM63", | ||
1446 | "ADM1032", | ||
1447 | "ADM1030", | ||
1448 | "MUA6649", | ||
1449 | "LM64", | ||
1450 | "F75375", | ||
1451 | "ASC7512", | ||
1452 | }; | ||
1453 | |||
1454 | static const char *pp_lib_thermal_controller_names[] = { | ||
1455 | "NONE", | ||
1456 | "LM63", | ||
1457 | "ADM1032", | ||
1458 | "ADM1030", | ||
1459 | "MUA6649", | ||
1460 | "LM64", | ||
1461 | "F75375", | ||
1462 | "RV6xx", | ||
1463 | "RV770", | ||
1464 | "ADT7473", | ||
1465 | }; | ||
1466 | |||
1467 | union power_info { | ||
1468 | struct _ATOM_POWERPLAY_INFO info; | ||
1469 | struct _ATOM_POWERPLAY_INFO_V2 info_2; | ||
1470 | struct _ATOM_POWERPLAY_INFO_V3 info_3; | ||
1471 | struct _ATOM_PPLIB_POWERPLAYTABLE info_4; | ||
1472 | }; | ||
1473 | |||
1474 | void radeon_atombios_get_power_modes(struct radeon_device *rdev) | ||
1117 | { | 1475 | { |
1118 | DYNAMIC_CLOCK_GATING_PS_ALLOCATION args; | 1476 | struct radeon_mode_info *mode_info = &rdev->mode_info; |
1119 | int index = GetIndexIntoMasterTable(COMMAND, DynamicClockGating); | 1477 | int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo); |
1478 | u16 data_offset; | ||
1479 | u8 frev, crev; | ||
1480 | u32 misc, misc2 = 0, sclk, mclk; | ||
1481 | union power_info *power_info; | ||
1482 | struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info; | ||
1483 | struct _ATOM_PPLIB_STATE *power_state; | ||
1484 | int num_modes = 0, i, j; | ||
1485 | int state_index = 0, mode_index = 0; | ||
1486 | struct radeon_i2c_bus_rec i2c_bus; | ||
1487 | |||
1488 | rdev->pm.default_power_state = NULL; | ||
1489 | |||
1490 | if (atom_parse_data_header(mode_info->atom_context, index, NULL, | ||
1491 | &frev, &crev, &data_offset)) { | ||
1492 | power_info = (union power_info *)(mode_info->atom_context->bios + data_offset); | ||
1493 | if (frev < 4) { | ||
1494 | /* add the i2c bus for thermal/fan chip */ | ||
1495 | if (power_info->info.ucOverdriveThermalController > 0) { | ||
1496 | DRM_INFO("Possible %s thermal controller at 0x%02x\n", | ||
1497 | thermal_controller_names[power_info->info.ucOverdriveThermalController], | ||
1498 | power_info->info.ucOverdriveControllerAddress >> 1); | ||
1499 | i2c_bus = radeon_lookup_i2c_gpio(rdev, power_info->info.ucOverdriveI2cLine); | ||
1500 | rdev->pm.i2c_bus = radeon_i2c_create(rdev->ddev, &i2c_bus, "Thermal"); | ||
1501 | } | ||
1502 | num_modes = power_info->info.ucNumOfPowerModeEntries; | ||
1503 | if (num_modes > ATOM_MAX_NUMBEROF_POWER_BLOCK) | ||
1504 | num_modes = ATOM_MAX_NUMBEROF_POWER_BLOCK; | ||
1505 | for (i = 0; i < num_modes; i++) { | ||
1506 | rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE; | ||
1507 | switch (frev) { | ||
1508 | case 1: | ||
1509 | rdev->pm.power_state[state_index].num_clock_modes = 1; | ||
1510 | rdev->pm.power_state[state_index].clock_info[0].mclk = | ||
1511 | le16_to_cpu(power_info->info.asPowerPlayInfo[i].usMemoryClock); | ||
1512 | rdev->pm.power_state[state_index].clock_info[0].sclk = | ||
1513 | le16_to_cpu(power_info->info.asPowerPlayInfo[i].usEngineClock); | ||
1514 | /* skip invalid modes */ | ||
1515 | if ((rdev->pm.power_state[state_index].clock_info[0].mclk == 0) || | ||
1516 | (rdev->pm.power_state[state_index].clock_info[0].sclk == 0)) | ||
1517 | continue; | ||
1518 | /* skip overclock modes for now */ | ||
1519 | if ((rdev->pm.power_state[state_index].clock_info[0].mclk > | ||
1520 | rdev->clock.default_mclk + RADEON_MODE_OVERCLOCK_MARGIN) || | ||
1521 | (rdev->pm.power_state[state_index].clock_info[0].sclk > | ||
1522 | rdev->clock.default_sclk + RADEON_MODE_OVERCLOCK_MARGIN)) | ||
1523 | continue; | ||
1524 | rdev->pm.power_state[state_index].non_clock_info.pcie_lanes = | ||
1525 | power_info->info.asPowerPlayInfo[i].ucNumPciELanes; | ||
1526 | misc = le32_to_cpu(power_info->info.asPowerPlayInfo[i].ulMiscInfo); | ||
1527 | if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) { | ||
1528 | rdev->pm.power_state[state_index].clock_info[0].voltage.type = | ||
1529 | VOLTAGE_GPIO; | ||
1530 | rdev->pm.power_state[state_index].clock_info[0].voltage.gpio = | ||
1531 | radeon_lookup_gpio(rdev, | ||
1532 | power_info->info.asPowerPlayInfo[i].ucVoltageDropIndex); | ||
1533 | if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH) | ||
1534 | rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = | ||
1535 | true; | ||
1536 | else | ||
1537 | rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = | ||
1538 | false; | ||
1539 | } else if (misc & ATOM_PM_MISCINFO_PROGRAM_VOLTAGE) { | ||
1540 | rdev->pm.power_state[state_index].clock_info[0].voltage.type = | ||
1541 | VOLTAGE_VDDC; | ||
1542 | rdev->pm.power_state[state_index].clock_info[0].voltage.vddc_id = | ||
1543 | power_info->info.asPowerPlayInfo[i].ucVoltageDropIndex; | ||
1544 | } | ||
1545 | /* order matters! */ | ||
1546 | if (misc & ATOM_PM_MISCINFO_POWER_SAVING_MODE) | ||
1547 | rdev->pm.power_state[state_index].type = | ||
1548 | POWER_STATE_TYPE_POWERSAVE; | ||
1549 | if (misc & ATOM_PM_MISCINFO_DEFAULT_DC_STATE_ENTRY_TRUE) | ||
1550 | rdev->pm.power_state[state_index].type = | ||
1551 | POWER_STATE_TYPE_BATTERY; | ||
1552 | if (misc & ATOM_PM_MISCINFO_DEFAULT_LOW_DC_STATE_ENTRY_TRUE) | ||
1553 | rdev->pm.power_state[state_index].type = | ||
1554 | POWER_STATE_TYPE_BATTERY; | ||
1555 | if (misc & ATOM_PM_MISCINFO_LOAD_BALANCE_EN) | ||
1556 | rdev->pm.power_state[state_index].type = | ||
1557 | POWER_STATE_TYPE_BALANCED; | ||
1558 | if (misc & ATOM_PM_MISCINFO_3D_ACCELERATION_EN) | ||
1559 | rdev->pm.power_state[state_index].type = | ||
1560 | POWER_STATE_TYPE_PERFORMANCE; | ||
1561 | if (misc & ATOM_PM_MISCINFO_DRIVER_DEFAULT_MODE) { | ||
1562 | rdev->pm.power_state[state_index].type = | ||
1563 | POWER_STATE_TYPE_DEFAULT; | ||
1564 | rdev->pm.default_power_state = &rdev->pm.power_state[state_index]; | ||
1565 | rdev->pm.power_state[state_index].default_clock_mode = | ||
1566 | &rdev->pm.power_state[state_index].clock_info[0]; | ||
1567 | } | ||
1568 | state_index++; | ||
1569 | break; | ||
1570 | case 2: | ||
1571 | rdev->pm.power_state[state_index].num_clock_modes = 1; | ||
1572 | rdev->pm.power_state[state_index].clock_info[0].mclk = | ||
1573 | le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMemoryClock); | ||
1574 | rdev->pm.power_state[state_index].clock_info[0].sclk = | ||
1575 | le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulEngineClock); | ||
1576 | /* skip invalid modes */ | ||
1577 | if ((rdev->pm.power_state[state_index].clock_info[0].mclk == 0) || | ||
1578 | (rdev->pm.power_state[state_index].clock_info[0].sclk == 0)) | ||
1579 | continue; | ||
1580 | /* skip overclock modes for now */ | ||
1581 | if ((rdev->pm.power_state[state_index].clock_info[0].mclk > | ||
1582 | rdev->clock.default_mclk + RADEON_MODE_OVERCLOCK_MARGIN) || | ||
1583 | (rdev->pm.power_state[state_index].clock_info[0].sclk > | ||
1584 | rdev->clock.default_sclk + RADEON_MODE_OVERCLOCK_MARGIN)) | ||
1585 | continue; | ||
1586 | rdev->pm.power_state[state_index].non_clock_info.pcie_lanes = | ||
1587 | power_info->info_2.asPowerPlayInfo[i].ucNumPciELanes; | ||
1588 | misc = le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMiscInfo); | ||
1589 | misc2 = le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMiscInfo2); | ||
1590 | if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) { | ||
1591 | rdev->pm.power_state[state_index].clock_info[0].voltage.type = | ||
1592 | VOLTAGE_GPIO; | ||
1593 | rdev->pm.power_state[state_index].clock_info[0].voltage.gpio = | ||
1594 | radeon_lookup_gpio(rdev, | ||
1595 | power_info->info_2.asPowerPlayInfo[i].ucVoltageDropIndex); | ||
1596 | if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH) | ||
1597 | rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = | ||
1598 | true; | ||
1599 | else | ||
1600 | rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = | ||
1601 | false; | ||
1602 | } else if (misc & ATOM_PM_MISCINFO_PROGRAM_VOLTAGE) { | ||
1603 | rdev->pm.power_state[state_index].clock_info[0].voltage.type = | ||
1604 | VOLTAGE_VDDC; | ||
1605 | rdev->pm.power_state[state_index].clock_info[0].voltage.vddc_id = | ||
1606 | power_info->info_2.asPowerPlayInfo[i].ucVoltageDropIndex; | ||
1607 | } | ||
1608 | /* order matters! */ | ||
1609 | if (misc & ATOM_PM_MISCINFO_POWER_SAVING_MODE) | ||
1610 | rdev->pm.power_state[state_index].type = | ||
1611 | POWER_STATE_TYPE_POWERSAVE; | ||
1612 | if (misc & ATOM_PM_MISCINFO_DEFAULT_DC_STATE_ENTRY_TRUE) | ||
1613 | rdev->pm.power_state[state_index].type = | ||
1614 | POWER_STATE_TYPE_BATTERY; | ||
1615 | if (misc & ATOM_PM_MISCINFO_DEFAULT_LOW_DC_STATE_ENTRY_TRUE) | ||
1616 | rdev->pm.power_state[state_index].type = | ||
1617 | POWER_STATE_TYPE_BATTERY; | ||
1618 | if (misc & ATOM_PM_MISCINFO_LOAD_BALANCE_EN) | ||
1619 | rdev->pm.power_state[state_index].type = | ||
1620 | POWER_STATE_TYPE_BALANCED; | ||
1621 | if (misc & ATOM_PM_MISCINFO_3D_ACCELERATION_EN) | ||
1622 | rdev->pm.power_state[state_index].type = | ||
1623 | POWER_STATE_TYPE_PERFORMANCE; | ||
1624 | if (misc2 & ATOM_PM_MISCINFO2_SYSTEM_AC_LITE_MODE) | ||
1625 | rdev->pm.power_state[state_index].type = | ||
1626 | POWER_STATE_TYPE_BALANCED; | ||
1627 | if (misc & ATOM_PM_MISCINFO_DRIVER_DEFAULT_MODE) { | ||
1628 | rdev->pm.power_state[state_index].type = | ||
1629 | POWER_STATE_TYPE_DEFAULT; | ||
1630 | rdev->pm.default_power_state = &rdev->pm.power_state[state_index]; | ||
1631 | rdev->pm.power_state[state_index].default_clock_mode = | ||
1632 | &rdev->pm.power_state[state_index].clock_info[0]; | ||
1633 | } | ||
1634 | state_index++; | ||
1635 | break; | ||
1636 | case 3: | ||
1637 | rdev->pm.power_state[state_index].num_clock_modes = 1; | ||
1638 | rdev->pm.power_state[state_index].clock_info[0].mclk = | ||
1639 | le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMemoryClock); | ||
1640 | rdev->pm.power_state[state_index].clock_info[0].sclk = | ||
1641 | le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulEngineClock); | ||
1642 | /* skip invalid modes */ | ||
1643 | if ((rdev->pm.power_state[state_index].clock_info[0].mclk == 0) || | ||
1644 | (rdev->pm.power_state[state_index].clock_info[0].sclk == 0)) | ||
1645 | continue; | ||
1646 | /* skip overclock modes for now */ | ||
1647 | if ((rdev->pm.power_state[state_index].clock_info[0].mclk > | ||
1648 | rdev->clock.default_mclk + RADEON_MODE_OVERCLOCK_MARGIN) || | ||
1649 | (rdev->pm.power_state[state_index].clock_info[0].sclk > | ||
1650 | rdev->clock.default_sclk + RADEON_MODE_OVERCLOCK_MARGIN)) | ||
1651 | continue; | ||
1652 | rdev->pm.power_state[state_index].non_clock_info.pcie_lanes = | ||
1653 | power_info->info_3.asPowerPlayInfo[i].ucNumPciELanes; | ||
1654 | misc = le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMiscInfo); | ||
1655 | misc2 = le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMiscInfo2); | ||
1656 | if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) { | ||
1657 | rdev->pm.power_state[state_index].clock_info[0].voltage.type = | ||
1658 | VOLTAGE_GPIO; | ||
1659 | rdev->pm.power_state[state_index].clock_info[0].voltage.gpio = | ||
1660 | radeon_lookup_gpio(rdev, | ||
1661 | power_info->info_3.asPowerPlayInfo[i].ucVoltageDropIndex); | ||
1662 | if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH) | ||
1663 | rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = | ||
1664 | true; | ||
1665 | else | ||
1666 | rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = | ||
1667 | false; | ||
1668 | } else if (misc & ATOM_PM_MISCINFO_PROGRAM_VOLTAGE) { | ||
1669 | rdev->pm.power_state[state_index].clock_info[0].voltage.type = | ||
1670 | VOLTAGE_VDDC; | ||
1671 | rdev->pm.power_state[state_index].clock_info[0].voltage.vddc_id = | ||
1672 | power_info->info_3.asPowerPlayInfo[i].ucVoltageDropIndex; | ||
1673 | if (misc2 & ATOM_PM_MISCINFO2_VDDCI_DYNAMIC_VOLTAGE_EN) { | ||
1674 | rdev->pm.power_state[state_index].clock_info[0].voltage.vddci_enabled = | ||
1675 | true; | ||
1676 | rdev->pm.power_state[state_index].clock_info[0].voltage.vddci_id = | ||
1677 | power_info->info_3.asPowerPlayInfo[i].ucVDDCI_VoltageDropIndex; | ||
1678 | } | ||
1679 | } | ||
1680 | /* order matters! */ | ||
1681 | if (misc & ATOM_PM_MISCINFO_POWER_SAVING_MODE) | ||
1682 | rdev->pm.power_state[state_index].type = | ||
1683 | POWER_STATE_TYPE_POWERSAVE; | ||
1684 | if (misc & ATOM_PM_MISCINFO_DEFAULT_DC_STATE_ENTRY_TRUE) | ||
1685 | rdev->pm.power_state[state_index].type = | ||
1686 | POWER_STATE_TYPE_BATTERY; | ||
1687 | if (misc & ATOM_PM_MISCINFO_DEFAULT_LOW_DC_STATE_ENTRY_TRUE) | ||
1688 | rdev->pm.power_state[state_index].type = | ||
1689 | POWER_STATE_TYPE_BATTERY; | ||
1690 | if (misc & ATOM_PM_MISCINFO_LOAD_BALANCE_EN) | ||
1691 | rdev->pm.power_state[state_index].type = | ||
1692 | POWER_STATE_TYPE_BALANCED; | ||
1693 | if (misc & ATOM_PM_MISCINFO_3D_ACCELERATION_EN) | ||
1694 | rdev->pm.power_state[state_index].type = | ||
1695 | POWER_STATE_TYPE_PERFORMANCE; | ||
1696 | if (misc2 & ATOM_PM_MISCINFO2_SYSTEM_AC_LITE_MODE) | ||
1697 | rdev->pm.power_state[state_index].type = | ||
1698 | POWER_STATE_TYPE_BALANCED; | ||
1699 | if (misc & ATOM_PM_MISCINFO_DRIVER_DEFAULT_MODE) { | ||
1700 | rdev->pm.power_state[state_index].type = | ||
1701 | POWER_STATE_TYPE_DEFAULT; | ||
1702 | rdev->pm.default_power_state = &rdev->pm.power_state[state_index]; | ||
1703 | rdev->pm.power_state[state_index].default_clock_mode = | ||
1704 | &rdev->pm.power_state[state_index].clock_info[0]; | ||
1705 | } | ||
1706 | state_index++; | ||
1707 | break; | ||
1708 | } | ||
1709 | } | ||
1710 | } else if (frev == 4) { | ||
1711 | /* add the i2c bus for thermal/fan chip */ | ||
1712 | /* no support for internal controller yet */ | ||
1713 | if (power_info->info_4.sThermalController.ucType > 0) { | ||
1714 | if ((power_info->info_4.sThermalController.ucType == ATOM_PP_THERMALCONTROLLER_RV6xx) || | ||
1715 | (power_info->info_4.sThermalController.ucType == ATOM_PP_THERMALCONTROLLER_RV770)) { | ||
1716 | DRM_INFO("Internal thermal controller %s fan control\n", | ||
1717 | (power_info->info_4.sThermalController.ucFanParameters & | ||
1718 | ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with"); | ||
1719 | } else { | ||
1720 | DRM_INFO("Possible %s thermal controller at 0x%02x %s fan control\n", | ||
1721 | pp_lib_thermal_controller_names[power_info->info_4.sThermalController.ucType], | ||
1722 | power_info->info_4.sThermalController.ucI2cAddress >> 1, | ||
1723 | (power_info->info_4.sThermalController.ucFanParameters & | ||
1724 | ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with"); | ||
1725 | i2c_bus = radeon_lookup_i2c_gpio(rdev, power_info->info_4.sThermalController.ucI2cLine); | ||
1726 | rdev->pm.i2c_bus = radeon_i2c_create(rdev->ddev, &i2c_bus, "Thermal"); | ||
1727 | } | ||
1728 | } | ||
1729 | for (i = 0; i < power_info->info_4.ucNumStates; i++) { | ||
1730 | mode_index = 0; | ||
1731 | power_state = (struct _ATOM_PPLIB_STATE *) | ||
1732 | (mode_info->atom_context->bios + | ||
1733 | data_offset + | ||
1734 | le16_to_cpu(power_info->info_4.usStateArrayOffset) + | ||
1735 | i * power_info->info_4.ucStateEntrySize); | ||
1736 | non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *) | ||
1737 | (mode_info->atom_context->bios + | ||
1738 | data_offset + | ||
1739 | le16_to_cpu(power_info->info_4.usNonClockInfoArrayOffset) + | ||
1740 | (power_state->ucNonClockStateIndex * | ||
1741 | power_info->info_4.ucNonClockSize)); | ||
1742 | for (j = 0; j < (power_info->info_4.ucStateEntrySize - 1); j++) { | ||
1743 | if (rdev->flags & RADEON_IS_IGP) { | ||
1744 | struct _ATOM_PPLIB_RS780_CLOCK_INFO *clock_info = | ||
1745 | (struct _ATOM_PPLIB_RS780_CLOCK_INFO *) | ||
1746 | (mode_info->atom_context->bios + | ||
1747 | data_offset + | ||
1748 | le16_to_cpu(power_info->info_4.usClockInfoArrayOffset) + | ||
1749 | (power_state->ucClockStateIndices[j] * | ||
1750 | power_info->info_4.ucClockInfoSize)); | ||
1751 | sclk = le16_to_cpu(clock_info->usLowEngineClockLow); | ||
1752 | sclk |= clock_info->ucLowEngineClockHigh << 16; | ||
1753 | rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk; | ||
1754 | /* skip invalid modes */ | ||
1755 | if (rdev->pm.power_state[state_index].clock_info[mode_index].sclk == 0) | ||
1756 | continue; | ||
1757 | /* skip overclock modes for now */ | ||
1758 | if (rdev->pm.power_state[state_index].clock_info[mode_index].sclk > | ||
1759 | rdev->clock.default_sclk + RADEON_MODE_OVERCLOCK_MARGIN) | ||
1760 | continue; | ||
1761 | rdev->pm.power_state[state_index].clock_info[mode_index].voltage.type = | ||
1762 | VOLTAGE_SW; | ||
1763 | rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage = | ||
1764 | clock_info->usVDDC; | ||
1765 | mode_index++; | ||
1766 | } else { | ||
1767 | struct _ATOM_PPLIB_R600_CLOCK_INFO *clock_info = | ||
1768 | (struct _ATOM_PPLIB_R600_CLOCK_INFO *) | ||
1769 | (mode_info->atom_context->bios + | ||
1770 | data_offset + | ||
1771 | le16_to_cpu(power_info->info_4.usClockInfoArrayOffset) + | ||
1772 | (power_state->ucClockStateIndices[j] * | ||
1773 | power_info->info_4.ucClockInfoSize)); | ||
1774 | sclk = le16_to_cpu(clock_info->usEngineClockLow); | ||
1775 | sclk |= clock_info->ucEngineClockHigh << 16; | ||
1776 | mclk = le16_to_cpu(clock_info->usMemoryClockLow); | ||
1777 | mclk |= clock_info->ucMemoryClockHigh << 16; | ||
1778 | rdev->pm.power_state[state_index].clock_info[mode_index].mclk = mclk; | ||
1779 | rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk; | ||
1780 | /* skip invalid modes */ | ||
1781 | if ((rdev->pm.power_state[state_index].clock_info[mode_index].mclk == 0) || | ||
1782 | (rdev->pm.power_state[state_index].clock_info[mode_index].sclk == 0)) | ||
1783 | continue; | ||
1784 | /* skip overclock modes for now */ | ||
1785 | if ((rdev->pm.power_state[state_index].clock_info[mode_index].mclk > | ||
1786 | rdev->clock.default_mclk + RADEON_MODE_OVERCLOCK_MARGIN) || | ||
1787 | (rdev->pm.power_state[state_index].clock_info[mode_index].sclk > | ||
1788 | rdev->clock.default_sclk + RADEON_MODE_OVERCLOCK_MARGIN)) | ||
1789 | continue; | ||
1790 | rdev->pm.power_state[state_index].clock_info[mode_index].voltage.type = | ||
1791 | VOLTAGE_SW; | ||
1792 | rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage = | ||
1793 | clock_info->usVDDC; | ||
1794 | mode_index++; | ||
1795 | } | ||
1796 | } | ||
1797 | rdev->pm.power_state[state_index].num_clock_modes = mode_index; | ||
1798 | if (mode_index) { | ||
1799 | misc = le32_to_cpu(non_clock_info->ulCapsAndSettings); | ||
1800 | misc2 = le16_to_cpu(non_clock_info->usClassification); | ||
1801 | rdev->pm.power_state[state_index].non_clock_info.pcie_lanes = | ||
1802 | ((misc & ATOM_PPLIB_PCIE_LINK_WIDTH_MASK) >> | ||
1803 | ATOM_PPLIB_PCIE_LINK_WIDTH_SHIFT) + 1; | ||
1804 | switch (misc2 & ATOM_PPLIB_CLASSIFICATION_UI_MASK) { | ||
1805 | case ATOM_PPLIB_CLASSIFICATION_UI_BATTERY: | ||
1806 | rdev->pm.power_state[state_index].type = | ||
1807 | POWER_STATE_TYPE_BATTERY; | ||
1808 | break; | ||
1809 | case ATOM_PPLIB_CLASSIFICATION_UI_BALANCED: | ||
1810 | rdev->pm.power_state[state_index].type = | ||
1811 | POWER_STATE_TYPE_BALANCED; | ||
1812 | break; | ||
1813 | case ATOM_PPLIB_CLASSIFICATION_UI_PERFORMANCE: | ||
1814 | rdev->pm.power_state[state_index].type = | ||
1815 | POWER_STATE_TYPE_PERFORMANCE; | ||
1816 | break; | ||
1817 | } | ||
1818 | if (misc2 & ATOM_PPLIB_CLASSIFICATION_BOOT) { | ||
1819 | rdev->pm.power_state[state_index].type = | ||
1820 | POWER_STATE_TYPE_DEFAULT; | ||
1821 | rdev->pm.default_power_state = &rdev->pm.power_state[state_index]; | ||
1822 | rdev->pm.power_state[state_index].default_clock_mode = | ||
1823 | &rdev->pm.power_state[state_index].clock_info[mode_index - 1]; | ||
1824 | } | ||
1825 | state_index++; | ||
1826 | } | ||
1827 | } | ||
1828 | } | ||
1829 | } else { | ||
1830 | /* XXX figure out some good default low power mode for cards w/out power tables */ | ||
1831 | } | ||
1120 | 1832 | ||
1121 | args.ucEnable = enable; | 1833 | if (rdev->pm.default_power_state == NULL) { |
1834 | /* add the default mode */ | ||
1835 | rdev->pm.power_state[state_index].type = | ||
1836 | POWER_STATE_TYPE_DEFAULT; | ||
1837 | rdev->pm.power_state[state_index].num_clock_modes = 1; | ||
1838 | rdev->pm.power_state[state_index].clock_info[0].mclk = rdev->clock.default_mclk; | ||
1839 | rdev->pm.power_state[state_index].clock_info[0].sclk = rdev->clock.default_sclk; | ||
1840 | rdev->pm.power_state[state_index].default_clock_mode = | ||
1841 | &rdev->pm.power_state[state_index].clock_info[0]; | ||
1842 | rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE; | ||
1843 | if (rdev->asic->get_pcie_lanes) | ||
1844 | rdev->pm.power_state[state_index].non_clock_info.pcie_lanes = radeon_get_pcie_lanes(rdev); | ||
1845 | else | ||
1846 | rdev->pm.power_state[state_index].non_clock_info.pcie_lanes = 16; | ||
1847 | rdev->pm.default_power_state = &rdev->pm.power_state[state_index]; | ||
1848 | state_index++; | ||
1849 | } | ||
1850 | rdev->pm.num_power_states = state_index; | ||
1122 | 1851 | ||
1123 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | 1852 | rdev->pm.current_power_state = rdev->pm.default_power_state; |
1853 | rdev->pm.current_clock_mode = | ||
1854 | rdev->pm.default_power_state->default_clock_mode; | ||
1124 | } | 1855 | } |
1125 | 1856 | ||
1126 | void radeon_atom_static_pwrmgt_setup(struct radeon_device *rdev, int enable) | 1857 | void radeon_atom_set_clock_gating(struct radeon_device *rdev, int enable) |
1127 | { | 1858 | { |
1128 | ENABLE_ASIC_STATIC_PWR_MGT_PS_ALLOCATION args; | 1859 | DYNAMIC_CLOCK_GATING_PS_ALLOCATION args; |
1129 | int index = GetIndexIntoMasterTable(COMMAND, EnableASIC_StaticPwrMgt); | 1860 | int index = GetIndexIntoMasterTable(COMMAND, DynamicClockGating); |
1130 | 1861 | ||
1131 | args.ucEnable = enable; | 1862 | args.ucEnable = enable; |
1132 | 1863 | ||