4484 lines · c
1/*2 * Copyright 2007-8 Advanced Micro Devices, Inc.3 * Copyright 2008 Red Hat Inc.4 *5 * Permission is hereby granted, free of charge, to any person obtaining a6 * copy of this software and associated documentation files (the "Software"),7 * to deal in the Software without restriction, including without limitation8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,9 * and/or sell copies of the Software, and to permit persons to whom the10 * Software is furnished to do so, subject to the following conditions:11 *12 * The above copyright notice and this permission notice shall be included in13 * all copies or substantial portions of the Software.14 *15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL18 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR19 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,20 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR21 * OTHER DEALINGS IN THE SOFTWARE.22 *23 * Authors: Dave Airlie24 * Alex Deucher25 */26 27#include <linux/pci.h>28 29#include <drm/drm_device.h>30#include <drm/drm_edid.h>31#include <drm/radeon_drm.h>32 33#include "radeon.h"34 35#include "atom.h"36#include "atom-bits.h"37#include "radeon_asic.h"38#include "radeon_atombios.h"39#include "radeon_legacy_encoders.h"40 41union atom_supported_devices {42 struct _ATOM_SUPPORTED_DEVICES_INFO info;43 struct _ATOM_SUPPORTED_DEVICES_INFO_2 info_2;44 struct _ATOM_SUPPORTED_DEVICES_INFO_2d1 info_2d1;45};46 47static void radeon_lookup_i2c_gpio_quirks(struct radeon_device *rdev,48 ATOM_GPIO_I2C_ASSIGMENT *gpio,49 u8 index)50{51 /* r4xx mask is technically not used by the hw, so patch in the legacy mask bits */52 if ((rdev->family == CHIP_R420) ||53 (rdev->family == CHIP_R423) ||54 (rdev->family == CHIP_RV410)) {55 if ((le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x0018) ||56 (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x0019) ||57 (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x001a)) {58 gpio->ucClkMaskShift = 0x19;59 gpio->ucDataMaskShift = 0x18;60 }61 }62 63 /* some evergreen boards have bad data for this entry */64 if (ASIC_IS_DCE4(rdev)) {65 if ((index == 7) &&66 (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x1936) &&67 (gpio->sucI2cId.ucAccess == 0)) {68 gpio->sucI2cId.ucAccess = 0x97;69 gpio->ucDataMaskShift = 8;70 gpio->ucDataEnShift = 8;71 gpio->ucDataY_Shift = 8;72 gpio->ucDataA_Shift = 8;73 }74 }75 76 /* some DCE3 boards have bad data for this entry */77 if (ASIC_IS_DCE3(rdev)) {78 if ((index == 4) &&79 (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x1fda) &&80 (gpio->sucI2cId.ucAccess == 0x94))81 gpio->sucI2cId.ucAccess = 0x14;82 }83}84 85static struct radeon_i2c_bus_rec radeon_get_bus_rec_for_i2c_gpio(ATOM_GPIO_I2C_ASSIGMENT *gpio)86{87 struct radeon_i2c_bus_rec i2c;88 89 memset(&i2c, 0, sizeof(struct radeon_i2c_bus_rec));90 91 i2c.mask_clk_reg = le16_to_cpu(gpio->usClkMaskRegisterIndex) * 4;92 i2c.mask_data_reg = le16_to_cpu(gpio->usDataMaskRegisterIndex) * 4;93 i2c.en_clk_reg = le16_to_cpu(gpio->usClkEnRegisterIndex) * 4;94 i2c.en_data_reg = le16_to_cpu(gpio->usDataEnRegisterIndex) * 4;95 i2c.y_clk_reg = le16_to_cpu(gpio->usClkY_RegisterIndex) * 4;96 i2c.y_data_reg = le16_to_cpu(gpio->usDataY_RegisterIndex) * 4;97 i2c.a_clk_reg = le16_to_cpu(gpio->usClkA_RegisterIndex) * 4;98 i2c.a_data_reg = le16_to_cpu(gpio->usDataA_RegisterIndex) * 4;99 i2c.mask_clk_mask = (1 << gpio->ucClkMaskShift);100 i2c.mask_data_mask = (1 << gpio->ucDataMaskShift);101 i2c.en_clk_mask = (1 << gpio->ucClkEnShift);102 i2c.en_data_mask = (1 << gpio->ucDataEnShift);103 i2c.y_clk_mask = (1 << gpio->ucClkY_Shift);104 i2c.y_data_mask = (1 << gpio->ucDataY_Shift);105 i2c.a_clk_mask = (1 << gpio->ucClkA_Shift);106 i2c.a_data_mask = (1 << gpio->ucDataA_Shift);107 108 if (gpio->sucI2cId.sbfAccess.bfHW_Capable)109 i2c.hw_capable = true;110 else111 i2c.hw_capable = false;112 113 if (gpio->sucI2cId.ucAccess == 0xa0)114 i2c.mm_i2c = true;115 else116 i2c.mm_i2c = false;117 118 i2c.i2c_id = gpio->sucI2cId.ucAccess;119 120 if (i2c.mask_clk_reg)121 i2c.valid = true;122 else123 i2c.valid = false;124 125 return i2c;126}127 128static struct radeon_i2c_bus_rec radeon_lookup_i2c_gpio(struct radeon_device *rdev,129 uint8_t id)130{131 struct atom_context *ctx = rdev->mode_info.atom_context;132 ATOM_GPIO_I2C_ASSIGMENT *gpio;133 struct radeon_i2c_bus_rec i2c;134 int index = GetIndexIntoMasterTable(DATA, GPIO_I2C_Info);135 struct _ATOM_GPIO_I2C_INFO *i2c_info;136 uint16_t data_offset, size;137 int i, num_indices;138 139 memset(&i2c, 0, sizeof(struct radeon_i2c_bus_rec));140 i2c.valid = false;141 142 if (atom_parse_data_header(ctx, index, &size, NULL, NULL, &data_offset)) {143 i2c_info = (struct _ATOM_GPIO_I2C_INFO *)(ctx->bios + data_offset);144 145 num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) /146 sizeof(ATOM_GPIO_I2C_ASSIGMENT);147 148 gpio = &i2c_info->asGPIO_Info[0];149 for (i = 0; i < num_indices; i++) {150 151 radeon_lookup_i2c_gpio_quirks(rdev, gpio, i);152 153 if (gpio->sucI2cId.ucAccess == id) {154 i2c = radeon_get_bus_rec_for_i2c_gpio(gpio);155 break;156 }157 gpio = (ATOM_GPIO_I2C_ASSIGMENT *)158 ((u8 *)gpio + sizeof(ATOM_GPIO_I2C_ASSIGMENT));159 }160 }161 162 return i2c;163}164 165void radeon_atombios_i2c_init(struct radeon_device *rdev)166{167 struct atom_context *ctx = rdev->mode_info.atom_context;168 ATOM_GPIO_I2C_ASSIGMENT *gpio;169 struct radeon_i2c_bus_rec i2c;170 int index = GetIndexIntoMasterTable(DATA, GPIO_I2C_Info);171 struct _ATOM_GPIO_I2C_INFO *i2c_info;172 uint16_t data_offset, size;173 int i, num_indices;174 char stmp[32];175 176 if (atom_parse_data_header(ctx, index, &size, NULL, NULL, &data_offset)) {177 i2c_info = (struct _ATOM_GPIO_I2C_INFO *)(ctx->bios + data_offset);178 179 num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) /180 sizeof(ATOM_GPIO_I2C_ASSIGMENT);181 182 gpio = &i2c_info->asGPIO_Info[0];183 for (i = 0; i < num_indices; i++) {184 radeon_lookup_i2c_gpio_quirks(rdev, gpio, i);185 186 i2c = radeon_get_bus_rec_for_i2c_gpio(gpio);187 188 if (i2c.valid) {189 sprintf(stmp, "0x%x", i2c.i2c_id);190 rdev->i2c_bus[i] = radeon_i2c_create(rdev_to_drm(rdev), &i2c, stmp);191 }192 gpio = (ATOM_GPIO_I2C_ASSIGMENT *)193 ((u8 *)gpio + sizeof(ATOM_GPIO_I2C_ASSIGMENT));194 }195 }196}197 198struct radeon_gpio_rec radeon_atombios_lookup_gpio(struct radeon_device *rdev,199 u8 id)200{201 struct atom_context *ctx = rdev->mode_info.atom_context;202 struct radeon_gpio_rec gpio;203 int index = GetIndexIntoMasterTable(DATA, GPIO_Pin_LUT);204 struct _ATOM_GPIO_PIN_LUT *gpio_info;205 ATOM_GPIO_PIN_ASSIGNMENT *pin;206 u16 data_offset, size;207 int i, num_indices;208 209 memset(&gpio, 0, sizeof(struct radeon_gpio_rec));210 gpio.valid = false;211 212 if (atom_parse_data_header(ctx, index, &size, NULL, NULL, &data_offset)) {213 gpio_info = (struct _ATOM_GPIO_PIN_LUT *)(ctx->bios + data_offset);214 215 num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) /216 sizeof(ATOM_GPIO_PIN_ASSIGNMENT);217 218 pin = gpio_info->asGPIO_Pin;219 for (i = 0; i < num_indices; i++) {220 if (id == pin->ucGPIO_ID) {221 gpio.id = pin->ucGPIO_ID;222 gpio.reg = le16_to_cpu(pin->usGpioPin_AIndex) * 4;223 gpio.shift = pin->ucGpioPinBitShift;224 gpio.mask = (1 << pin->ucGpioPinBitShift);225 gpio.valid = true;226 break;227 }228 pin = (ATOM_GPIO_PIN_ASSIGNMENT *)229 ((u8 *)pin + sizeof(ATOM_GPIO_PIN_ASSIGNMENT));230 }231 }232 233 return gpio;234}235 236static struct radeon_hpd radeon_atom_get_hpd_info_from_gpio(struct radeon_device *rdev,237 struct radeon_gpio_rec *gpio)238{239 struct radeon_hpd hpd;240 u32 reg;241 242 memset(&hpd, 0, sizeof(struct radeon_hpd));243 244 if (ASIC_IS_DCE6(rdev))245 reg = SI_DC_GPIO_HPD_A;246 else if (ASIC_IS_DCE4(rdev))247 reg = EVERGREEN_DC_GPIO_HPD_A;248 else249 reg = AVIVO_DC_GPIO_HPD_A;250 251 hpd.gpio = *gpio;252 if (gpio->reg == reg) {253 switch(gpio->mask) {254 case (1 << 0):255 hpd.hpd = RADEON_HPD_1;256 break;257 case (1 << 8):258 hpd.hpd = RADEON_HPD_2;259 break;260 case (1 << 16):261 hpd.hpd = RADEON_HPD_3;262 break;263 case (1 << 24):264 hpd.hpd = RADEON_HPD_4;265 break;266 case (1 << 26):267 hpd.hpd = RADEON_HPD_5;268 break;269 case (1 << 28):270 hpd.hpd = RADEON_HPD_6;271 break;272 default:273 hpd.hpd = RADEON_HPD_NONE;274 break;275 }276 } else277 hpd.hpd = RADEON_HPD_NONE;278 return hpd;279}280 281static bool radeon_atom_apply_quirks(struct drm_device *dev,282 uint32_t supported_device,283 int *connector_type,284 struct radeon_i2c_bus_rec *i2c_bus,285 uint16_t *line_mux,286 struct radeon_hpd *hpd)287{288 struct pci_dev *pdev = to_pci_dev(dev->dev);289 290 /* Asus M2A-VM HDMI board lists the DVI port as HDMI */291 if ((pdev->device == 0x791e) &&292 (pdev->subsystem_vendor == 0x1043) &&293 (pdev->subsystem_device == 0x826d)) {294 if ((*connector_type == DRM_MODE_CONNECTOR_HDMIA) &&295 (supported_device == ATOM_DEVICE_DFP3_SUPPORT))296 *connector_type = DRM_MODE_CONNECTOR_DVID;297 }298 299 /* Asrock RS600 board lists the DVI port as HDMI */300 if ((pdev->device == 0x7941) &&301 (pdev->subsystem_vendor == 0x1849) &&302 (pdev->subsystem_device == 0x7941)) {303 if ((*connector_type == DRM_MODE_CONNECTOR_HDMIA) &&304 (supported_device == ATOM_DEVICE_DFP3_SUPPORT))305 *connector_type = DRM_MODE_CONNECTOR_DVID;306 }307 308 /* MSI K9A2GM V2/V3 board has no HDMI or DVI */309 if ((pdev->device == 0x796e) &&310 (pdev->subsystem_vendor == 0x1462) &&311 (pdev->subsystem_device == 0x7302)) {312 if ((supported_device == ATOM_DEVICE_DFP2_SUPPORT) ||313 (supported_device == ATOM_DEVICE_DFP3_SUPPORT))314 return false;315 }316 317 /* a-bit f-i90hd - ciaranm on #radeonhd - this board has no DVI */318 if ((pdev->device == 0x7941) &&319 (pdev->subsystem_vendor == 0x147b) &&320 (pdev->subsystem_device == 0x2412)) {321 if (*connector_type == DRM_MODE_CONNECTOR_DVII)322 return false;323 }324 325 /* Falcon NW laptop lists vga ddc line for LVDS */326 if ((pdev->device == 0x5653) &&327 (pdev->subsystem_vendor == 0x1462) &&328 (pdev->subsystem_device == 0x0291)) {329 if (*connector_type == DRM_MODE_CONNECTOR_LVDS) {330 i2c_bus->valid = false;331 *line_mux = 53;332 }333 }334 335 /* HIS X1300 is DVI+VGA, not DVI+DVI */336 if ((pdev->device == 0x7146) &&337 (pdev->subsystem_vendor == 0x17af) &&338 (pdev->subsystem_device == 0x2058)) {339 if (supported_device == ATOM_DEVICE_DFP1_SUPPORT)340 return false;341 }342 343 /* Gigabyte X1300 is DVI+VGA, not DVI+DVI */344 if ((pdev->device == 0x7142) &&345 (pdev->subsystem_vendor == 0x1458) &&346 (pdev->subsystem_device == 0x2134)) {347 if (supported_device == ATOM_DEVICE_DFP1_SUPPORT)348 return false;349 }350 351 352 /* Funky macbooks */353 if ((pdev->device == 0x71C5) &&354 (pdev->subsystem_vendor == 0x106b) &&355 (pdev->subsystem_device == 0x0080)) {356 if ((supported_device == ATOM_DEVICE_CRT1_SUPPORT) ||357 (supported_device == ATOM_DEVICE_DFP2_SUPPORT))358 return false;359 if (supported_device == ATOM_DEVICE_CRT2_SUPPORT)360 *line_mux = 0x90;361 }362 363 /* mac rv630, rv730, others */364 if ((supported_device == ATOM_DEVICE_TV1_SUPPORT) &&365 (*connector_type == DRM_MODE_CONNECTOR_DVII)) {366 *connector_type = DRM_MODE_CONNECTOR_9PinDIN;367 *line_mux = CONNECTOR_7PIN_DIN_ENUM_ID1;368 }369 370 /* ASUS HD 3600 XT board lists the DVI port as HDMI */371 if ((pdev->device == 0x9598) &&372 (pdev->subsystem_vendor == 0x1043) &&373 (pdev->subsystem_device == 0x01da)) {374 if (*connector_type == DRM_MODE_CONNECTOR_HDMIA) {375 *connector_type = DRM_MODE_CONNECTOR_DVII;376 }377 }378 379 /* ASUS HD 3600 board lists the DVI port as HDMI */380 if ((pdev->device == 0x9598) &&381 (pdev->subsystem_vendor == 0x1043) &&382 (pdev->subsystem_device == 0x01e4)) {383 if (*connector_type == DRM_MODE_CONNECTOR_HDMIA) {384 *connector_type = DRM_MODE_CONNECTOR_DVII;385 }386 }387 388 /* ASUS HD 3450 board lists the DVI port as HDMI */389 if ((pdev->device == 0x95C5) &&390 (pdev->subsystem_vendor == 0x1043) &&391 (pdev->subsystem_device == 0x01e2)) {392 if (*connector_type == DRM_MODE_CONNECTOR_HDMIA) {393 *connector_type = DRM_MODE_CONNECTOR_DVII;394 }395 }396 397 /* some BIOSes seem to report DAC on HDMI - usually this is a board with398 * HDMI + VGA reporting as HDMI399 */400 if (*connector_type == DRM_MODE_CONNECTOR_HDMIA) {401 if (supported_device & (ATOM_DEVICE_CRT_SUPPORT)) {402 *connector_type = DRM_MODE_CONNECTOR_VGA;403 *line_mux = 0;404 }405 }406 407 /* Acer laptop (Acer TravelMate 5730/5730G) has an HDMI port408 * on the laptop and a DVI port on the docking station and409 * both share the same encoder, hpd pin, and ddc line.410 * So while the bios table is technically correct,411 * we drop the DVI port here since xrandr has no concept of412 * encoders and will try and drive both connectors413 * with different crtcs which isn't possible on the hardware414 * side and leaves no crtcs for LVDS or VGA.415 */416 if (((pdev->device == 0x95c4) || (pdev->device == 0x9591)) &&417 (pdev->subsystem_vendor == 0x1025) &&418 (pdev->subsystem_device == 0x013c)) {419 if ((*connector_type == DRM_MODE_CONNECTOR_DVII) &&420 (supported_device == ATOM_DEVICE_DFP1_SUPPORT)) {421 /* actually it's a DVI-D port not DVI-I */422 *connector_type = DRM_MODE_CONNECTOR_DVID;423 return false;424 }425 }426 427 /* XFX Pine Group device rv730 reports no VGA DDC lines428 * even though they are wired up to record 0x93429 */430 if ((pdev->device == 0x9498) &&431 (pdev->subsystem_vendor == 0x1682) &&432 (pdev->subsystem_device == 0x2452) &&433 (i2c_bus->valid == false) &&434 !(supported_device & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT))) {435 struct radeon_device *rdev = dev->dev_private;436 *i2c_bus = radeon_lookup_i2c_gpio(rdev, 0x93);437 }438 439 /* Fujitsu D3003-S2 board lists DVI-I as DVI-D and VGA */440 if (((pdev->device == 0x9802) ||441 (pdev->device == 0x9805) ||442 (pdev->device == 0x9806)) &&443 (pdev->subsystem_vendor == 0x1734) &&444 (pdev->subsystem_device == 0x11bd)) {445 if (*connector_type == DRM_MODE_CONNECTOR_VGA) {446 *connector_type = DRM_MODE_CONNECTOR_DVII;447 *line_mux = 0x3103;448 } else if (*connector_type == DRM_MODE_CONNECTOR_DVID) {449 *connector_type = DRM_MODE_CONNECTOR_DVII;450 }451 }452 453 return true;454}455 456static const int supported_devices_connector_convert[] = {457 DRM_MODE_CONNECTOR_Unknown,458 DRM_MODE_CONNECTOR_VGA,459 DRM_MODE_CONNECTOR_DVII,460 DRM_MODE_CONNECTOR_DVID,461 DRM_MODE_CONNECTOR_DVIA,462 DRM_MODE_CONNECTOR_SVIDEO,463 DRM_MODE_CONNECTOR_Composite,464 DRM_MODE_CONNECTOR_LVDS,465 DRM_MODE_CONNECTOR_Unknown,466 DRM_MODE_CONNECTOR_Unknown,467 DRM_MODE_CONNECTOR_HDMIA,468 DRM_MODE_CONNECTOR_HDMIB,469 DRM_MODE_CONNECTOR_Unknown,470 DRM_MODE_CONNECTOR_Unknown,471 DRM_MODE_CONNECTOR_9PinDIN,472 DRM_MODE_CONNECTOR_DisplayPort473};474 475static const uint16_t supported_devices_connector_object_id_convert[] = {476 CONNECTOR_OBJECT_ID_NONE,477 CONNECTOR_OBJECT_ID_VGA,478 CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I, /* not all boards support DL */479 CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D, /* not all boards support DL */480 CONNECTOR_OBJECT_ID_VGA, /* technically DVI-A */481 CONNECTOR_OBJECT_ID_COMPOSITE,482 CONNECTOR_OBJECT_ID_SVIDEO,483 CONNECTOR_OBJECT_ID_LVDS,484 CONNECTOR_OBJECT_ID_9PIN_DIN,485 CONNECTOR_OBJECT_ID_9PIN_DIN,486 CONNECTOR_OBJECT_ID_DISPLAYPORT,487 CONNECTOR_OBJECT_ID_HDMI_TYPE_A,488 CONNECTOR_OBJECT_ID_HDMI_TYPE_B,489 CONNECTOR_OBJECT_ID_SVIDEO490};491 492static const int object_connector_convert[] = {493 DRM_MODE_CONNECTOR_Unknown,494 DRM_MODE_CONNECTOR_DVII,495 DRM_MODE_CONNECTOR_DVII,496 DRM_MODE_CONNECTOR_DVID,497 DRM_MODE_CONNECTOR_DVID,498 DRM_MODE_CONNECTOR_VGA,499 DRM_MODE_CONNECTOR_Composite,500 DRM_MODE_CONNECTOR_SVIDEO,501 DRM_MODE_CONNECTOR_Unknown,502 DRM_MODE_CONNECTOR_Unknown,503 DRM_MODE_CONNECTOR_9PinDIN,504 DRM_MODE_CONNECTOR_Unknown,505 DRM_MODE_CONNECTOR_HDMIA,506 DRM_MODE_CONNECTOR_HDMIB,507 DRM_MODE_CONNECTOR_LVDS,508 DRM_MODE_CONNECTOR_9PinDIN,509 DRM_MODE_CONNECTOR_Unknown,510 DRM_MODE_CONNECTOR_Unknown,511 DRM_MODE_CONNECTOR_Unknown,512 DRM_MODE_CONNECTOR_DisplayPort,513 DRM_MODE_CONNECTOR_eDP,514 DRM_MODE_CONNECTOR_Unknown515};516 517bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev)518{519 struct radeon_device *rdev = dev->dev_private;520 struct radeon_mode_info *mode_info = &rdev->mode_info;521 struct atom_context *ctx = mode_info->atom_context;522 int index = GetIndexIntoMasterTable(DATA, Object_Header);523 u16 size, data_offset;524 u8 frev, crev;525 ATOM_CONNECTOR_OBJECT_TABLE *con_obj;526 ATOM_ENCODER_OBJECT_TABLE *enc_obj;527 ATOM_OBJECT_TABLE *router_obj;528 ATOM_DISPLAY_OBJECT_PATH_TABLE *path_obj;529 ATOM_OBJECT_HEADER *obj_header;530 int i, j, k, path_size, device_support;531 int connector_type;532 u16 igp_lane_info, conn_id, connector_object_id;533 struct radeon_i2c_bus_rec ddc_bus;534 struct radeon_router router;535 struct radeon_gpio_rec gpio;536 struct radeon_hpd hpd;537 538 if (!atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset))539 return false;540 541 if (crev < 2)542 return false;543 544 obj_header = (ATOM_OBJECT_HEADER *) (ctx->bios + data_offset);545 path_obj = (ATOM_DISPLAY_OBJECT_PATH_TABLE *)546 (ctx->bios + data_offset +547 le16_to_cpu(obj_header->usDisplayPathTableOffset));548 con_obj = (ATOM_CONNECTOR_OBJECT_TABLE *)549 (ctx->bios + data_offset +550 le16_to_cpu(obj_header->usConnectorObjectTableOffset));551 enc_obj = (ATOM_ENCODER_OBJECT_TABLE *)552 (ctx->bios + data_offset +553 le16_to_cpu(obj_header->usEncoderObjectTableOffset));554 router_obj = (ATOM_OBJECT_TABLE *)555 (ctx->bios + data_offset +556 le16_to_cpu(obj_header->usRouterObjectTableOffset));557 device_support = le16_to_cpu(obj_header->usDeviceSupport);558 559 path_size = 0;560 for (i = 0; i < path_obj->ucNumOfDispPath; i++) {561 uint8_t *addr = (uint8_t *) path_obj->asDispPath;562 ATOM_DISPLAY_OBJECT_PATH *path;563 addr += path_size;564 path = (ATOM_DISPLAY_OBJECT_PATH *) addr;565 path_size += le16_to_cpu(path->usSize);566 567 if (device_support & le16_to_cpu(path->usDeviceTag)) {568 uint8_t con_obj_id, con_obj_num;569 570 con_obj_id =571 (le16_to_cpu(path->usConnObjectId) & OBJECT_ID_MASK)572 >> OBJECT_ID_SHIFT;573 con_obj_num =574 (le16_to_cpu(path->usConnObjectId) & ENUM_ID_MASK)575 >> ENUM_ID_SHIFT;576 577 /* TODO CV support */578 if (le16_to_cpu(path->usDeviceTag) ==579 ATOM_DEVICE_CV_SUPPORT)580 continue;581 582 /* IGP chips */583 if ((rdev->flags & RADEON_IS_IGP) &&584 (con_obj_id ==585 CONNECTOR_OBJECT_ID_PCIE_CONNECTOR)) {586 uint16_t igp_offset = 0;587 ATOM_INTEGRATED_SYSTEM_INFO_V2 *igp_obj;588 589 index =590 GetIndexIntoMasterTable(DATA,591 IntegratedSystemInfo);592 593 if (atom_parse_data_header(ctx, index, &size, &frev,594 &crev, &igp_offset)) {595 596 if (crev >= 2) {597 igp_obj =598 (ATOM_INTEGRATED_SYSTEM_INFO_V2599 *) (ctx->bios + igp_offset);600 601 if (igp_obj) {602 uint32_t slot_config, ct;603 604 if (con_obj_num == 1)605 slot_config =606 igp_obj->607 ulDDISlot1Config;608 else609 slot_config =610 igp_obj->611 ulDDISlot2Config;612 613 ct = (slot_config >> 16) & 0xff;614 connector_type =615 object_connector_convert616 [ct];617 connector_object_id = ct;618 igp_lane_info =619 slot_config & 0xffff;620 } else621 continue;622 } else623 continue;624 } else {625 igp_lane_info = 0;626 connector_type =627 object_connector_convert[con_obj_id];628 connector_object_id = con_obj_id;629 }630 } else {631 igp_lane_info = 0;632 connector_type =633 object_connector_convert[con_obj_id];634 connector_object_id = con_obj_id;635 }636 637 if (connector_type == DRM_MODE_CONNECTOR_Unknown)638 continue;639 640 router.ddc_valid = false;641 router.cd_valid = false;642 for (j = 0; j < ((le16_to_cpu(path->usSize) - 8) / 2); j++) {643 uint8_t grph_obj_type =644 (le16_to_cpu(path->usGraphicObjIds[j]) &645 OBJECT_TYPE_MASK) >> OBJECT_TYPE_SHIFT;646 647 if (grph_obj_type == GRAPH_OBJECT_TYPE_ENCODER) {648 for (k = 0; k < enc_obj->ucNumberOfObjects; k++) {649 u16 encoder_obj = le16_to_cpu(enc_obj->asObjects[k].usObjectID);650 if (le16_to_cpu(path->usGraphicObjIds[j]) == encoder_obj) {651 ATOM_COMMON_RECORD_HEADER *record = (ATOM_COMMON_RECORD_HEADER *)652 (ctx->bios + data_offset +653 le16_to_cpu(enc_obj->asObjects[k].usRecordOffset));654 ATOM_ENCODER_CAP_RECORD *cap_record;655 u16 caps = 0;656 657 while (record->ucRecordSize > 0 &&658 record->ucRecordType > 0 &&659 record->ucRecordType <= ATOM_MAX_OBJECT_RECORD_NUMBER) {660 switch (record->ucRecordType) {661 case ATOM_ENCODER_CAP_RECORD_TYPE:662 cap_record =(ATOM_ENCODER_CAP_RECORD *)663 record;664 caps = le16_to_cpu(cap_record->usEncoderCap);665 break;666 }667 record = (ATOM_COMMON_RECORD_HEADER *)668 ((char *)record + record->ucRecordSize);669 }670 radeon_add_atom_encoder(dev,671 encoder_obj,672 le16_to_cpu673 (path->674 usDeviceTag),675 caps);676 }677 }678 } else if (grph_obj_type == GRAPH_OBJECT_TYPE_ROUTER) {679 for (k = 0; k < router_obj->ucNumberOfObjects; k++) {680 u16 router_obj_id = le16_to_cpu(router_obj->asObjects[k].usObjectID);681 if (le16_to_cpu(path->usGraphicObjIds[j]) == router_obj_id) {682 ATOM_COMMON_RECORD_HEADER *record = (ATOM_COMMON_RECORD_HEADER *)683 (ctx->bios + data_offset +684 le16_to_cpu(router_obj->asObjects[k].usRecordOffset));685 ATOM_I2C_RECORD *i2c_record;686 ATOM_I2C_ID_CONFIG_ACCESS *i2c_config;687 ATOM_ROUTER_DDC_PATH_SELECT_RECORD *ddc_path;688 ATOM_ROUTER_DATA_CLOCK_PATH_SELECT_RECORD *cd_path;689 ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT *router_src_dst_table =690 (ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT *)691 (ctx->bios + data_offset +692 le16_to_cpu(router_obj->asObjects[k].usSrcDstTableOffset));693 u8 *num_dst_objs = (u8 *)694 ((u8 *)router_src_dst_table + 1 +695 (router_src_dst_table->ucNumberOfSrc * 2));696 u16 *dst_objs = (u16 *)(num_dst_objs + 1);697 int enum_id;698 699 router.router_id = router_obj_id;700 for (enum_id = 0; enum_id < (*num_dst_objs); enum_id++) {701 if (le16_to_cpu(path->usConnObjectId) ==702 le16_to_cpu(dst_objs[enum_id]))703 break;704 }705 706 while (record->ucRecordSize > 0 &&707 record->ucRecordType > 0 &&708 record->ucRecordType <= ATOM_MAX_OBJECT_RECORD_NUMBER) {709 switch (record->ucRecordType) {710 case ATOM_I2C_RECORD_TYPE:711 i2c_record =712 (ATOM_I2C_RECORD *)713 record;714 i2c_config =715 (ATOM_I2C_ID_CONFIG_ACCESS *)716 &i2c_record->sucI2cId;717 router.i2c_info =718 radeon_lookup_i2c_gpio(rdev,719 i2c_config->720 ucAccess);721 router.i2c_addr = i2c_record->ucI2CAddr >> 1;722 break;723 case ATOM_ROUTER_DDC_PATH_SELECT_RECORD_TYPE:724 ddc_path = (ATOM_ROUTER_DDC_PATH_SELECT_RECORD *)725 record;726 router.ddc_valid = true;727 router.ddc_mux_type = ddc_path->ucMuxType;728 router.ddc_mux_control_pin = ddc_path->ucMuxControlPin;729 router.ddc_mux_state = ddc_path->ucMuxState[enum_id];730 break;731 case ATOM_ROUTER_DATA_CLOCK_PATH_SELECT_RECORD_TYPE:732 cd_path = (ATOM_ROUTER_DATA_CLOCK_PATH_SELECT_RECORD *)733 record;734 router.cd_valid = true;735 router.cd_mux_type = cd_path->ucMuxType;736 router.cd_mux_control_pin = cd_path->ucMuxControlPin;737 router.cd_mux_state = cd_path->ucMuxState[enum_id];738 break;739 }740 record = (ATOM_COMMON_RECORD_HEADER *)741 ((char *)record + record->ucRecordSize);742 }743 }744 }745 }746 }747 748 /* look up gpio for ddc, hpd */749 ddc_bus.valid = false;750 hpd.hpd = RADEON_HPD_NONE;751 if ((le16_to_cpu(path->usDeviceTag) &752 (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) == 0) {753 for (j = 0; j < con_obj->ucNumberOfObjects; j++) {754 if (le16_to_cpu(path->usConnObjectId) ==755 le16_to_cpu(con_obj->asObjects[j].756 usObjectID)) {757 ATOM_COMMON_RECORD_HEADER758 *record =759 (ATOM_COMMON_RECORD_HEADER760 *)761 (ctx->bios + data_offset +762 le16_to_cpu(con_obj->763 asObjects[j].764 usRecordOffset));765 ATOM_I2C_RECORD *i2c_record;766 ATOM_HPD_INT_RECORD *hpd_record;767 ATOM_I2C_ID_CONFIG_ACCESS *i2c_config;768 769 while (record->ucRecordSize > 0 &&770 record->ucRecordType > 0 &&771 record->ucRecordType <= ATOM_MAX_OBJECT_RECORD_NUMBER) {772 switch (record->ucRecordType) {773 case ATOM_I2C_RECORD_TYPE:774 i2c_record =775 (ATOM_I2C_RECORD *)776 record;777 i2c_config =778 (ATOM_I2C_ID_CONFIG_ACCESS *)779 &i2c_record->sucI2cId;780 ddc_bus = radeon_lookup_i2c_gpio(rdev,781 i2c_config->782 ucAccess);783 break;784 case ATOM_HPD_INT_RECORD_TYPE:785 hpd_record =786 (ATOM_HPD_INT_RECORD *)787 record;788 gpio = radeon_atombios_lookup_gpio(rdev,789 hpd_record->ucHPDIntGPIOID);790 hpd = radeon_atom_get_hpd_info_from_gpio(rdev, &gpio);791 hpd.plugged_state = hpd_record->ucPlugged_PinState;792 break;793 }794 record =795 (ATOM_COMMON_RECORD_HEADER796 *) ((char *)record797 +798 record->799 ucRecordSize);800 }801 break;802 }803 }804 }805 806 /* needed for aux chan transactions */807 ddc_bus.hpd = hpd.hpd;808 809 conn_id = le16_to_cpu(path->usConnObjectId);810 811 if (!radeon_atom_apply_quirks812 (dev, le16_to_cpu(path->usDeviceTag), &connector_type,813 &ddc_bus, &conn_id, &hpd))814 continue;815 816 radeon_add_atom_connector(dev,817 conn_id,818 le16_to_cpu(path->819 usDeviceTag),820 connector_type, &ddc_bus,821 igp_lane_info,822 connector_object_id,823 &hpd,824 &router);825 826 }827 }828 829 radeon_link_encoder_connector(dev);830 return true;831}832 833static uint16_t atombios_get_connector_object_id(struct drm_device *dev,834 int connector_type,835 uint16_t devices)836{837 struct radeon_device *rdev = dev->dev_private;838 839 if (rdev->flags & RADEON_IS_IGP) {840 return supported_devices_connector_object_id_convert841 [connector_type];842 } else if (((connector_type == DRM_MODE_CONNECTOR_DVII) ||843 (connector_type == DRM_MODE_CONNECTOR_DVID)) &&844 (devices & ATOM_DEVICE_DFP2_SUPPORT)) {845 struct radeon_mode_info *mode_info = &rdev->mode_info;846 struct atom_context *ctx = mode_info->atom_context;847 int index = GetIndexIntoMasterTable(DATA, XTMDS_Info);848 uint16_t size, data_offset;849 uint8_t frev, crev;850 ATOM_XTMDS_INFO *xtmds;851 852 if (atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset)) {853 xtmds = (ATOM_XTMDS_INFO *)(ctx->bios + data_offset);854 855 if (xtmds->ucSupportedLink & ATOM_XTMDS_SUPPORTED_DUALLINK) {856 if (connector_type == DRM_MODE_CONNECTOR_DVII)857 return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I;858 else859 return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D;860 } else {861 if (connector_type == DRM_MODE_CONNECTOR_DVII)862 return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I;863 else864 return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D;865 }866 } else867 return supported_devices_connector_object_id_convert868 [connector_type];869 } else {870 return supported_devices_connector_object_id_convert871 [connector_type];872 }873}874 875struct bios_connector {876 bool valid;877 uint16_t line_mux;878 uint16_t devices;879 int connector_type;880 struct radeon_i2c_bus_rec ddc_bus;881 struct radeon_hpd hpd;882};883 884bool radeon_get_atom_connector_info_from_supported_devices_table(struct885 drm_device886 *dev)887{888 struct radeon_device *rdev = dev->dev_private;889 struct radeon_mode_info *mode_info = &rdev->mode_info;890 struct atom_context *ctx = mode_info->atom_context;891 int index = GetIndexIntoMasterTable(DATA, SupportedDevicesInfo);892 uint16_t size, data_offset;893 uint8_t frev, crev;894 uint16_t device_support;895 uint8_t dac;896 union atom_supported_devices *supported_devices;897 int i, j, max_device;898 struct bios_connector *bios_connectors;899 size_t bc_size = sizeof(*bios_connectors) * ATOM_MAX_SUPPORTED_DEVICE;900 struct radeon_router router;901 902 router.ddc_valid = false;903 router.cd_valid = false;904 905 bios_connectors = kzalloc(bc_size, GFP_KERNEL);906 if (!bios_connectors)907 return false;908 909 if (!atom_parse_data_header(ctx, index, &size, &frev, &crev,910 &data_offset)) {911 kfree(bios_connectors);912 return false;913 }914 915 supported_devices =916 (union atom_supported_devices *)(ctx->bios + data_offset);917 918 device_support = le16_to_cpu(supported_devices->info.usDeviceSupport);919 920 if (frev > 1)921 max_device = ATOM_MAX_SUPPORTED_DEVICE;922 else923 max_device = ATOM_MAX_SUPPORTED_DEVICE_INFO;924 925 for (i = 0; i < max_device; i++) {926 ATOM_CONNECTOR_INFO_I2C ci;927 928 if (frev > 1)929 ci = supported_devices->info_2d1.asConnInfo[i];930 else931 ci = supported_devices->info.asConnInfo[i];932 933 bios_connectors[i].valid = false;934 935 if (!(device_support & (1 << i))) {936 continue;937 }938 939 if (i == ATOM_DEVICE_CV_INDEX) {940 DRM_DEBUG_KMS("Skipping Component Video\n");941 continue;942 }943 944 bios_connectors[i].connector_type =945 supported_devices_connector_convert[ci.sucConnectorInfo.946 sbfAccess.947 bfConnectorType];948 949 if (bios_connectors[i].connector_type ==950 DRM_MODE_CONNECTOR_Unknown)951 continue;952 953 dac = ci.sucConnectorInfo.sbfAccess.bfAssociatedDAC;954 955 bios_connectors[i].line_mux =956 ci.sucI2cId.ucAccess;957 958 /* give tv unique connector ids */959 if (i == ATOM_DEVICE_TV1_INDEX) {960 bios_connectors[i].ddc_bus.valid = false;961 bios_connectors[i].line_mux = 50;962 } else if (i == ATOM_DEVICE_TV2_INDEX) {963 bios_connectors[i].ddc_bus.valid = false;964 bios_connectors[i].line_mux = 51;965 } else if (i == ATOM_DEVICE_CV_INDEX) {966 bios_connectors[i].ddc_bus.valid = false;967 bios_connectors[i].line_mux = 52;968 } else969 bios_connectors[i].ddc_bus =970 radeon_lookup_i2c_gpio(rdev,971 bios_connectors[i].line_mux);972 973 if ((crev > 1) && (frev > 1)) {974 u8 isb = supported_devices->info_2d1.asIntSrcInfo[i].ucIntSrcBitmap;975 switch (isb) {976 case 0x4:977 bios_connectors[i].hpd.hpd = RADEON_HPD_1;978 break;979 case 0xa:980 bios_connectors[i].hpd.hpd = RADEON_HPD_2;981 break;982 default:983 bios_connectors[i].hpd.hpd = RADEON_HPD_NONE;984 break;985 }986 } else {987 if (i == ATOM_DEVICE_DFP1_INDEX)988 bios_connectors[i].hpd.hpd = RADEON_HPD_1;989 else if (i == ATOM_DEVICE_DFP2_INDEX)990 bios_connectors[i].hpd.hpd = RADEON_HPD_2;991 else992 bios_connectors[i].hpd.hpd = RADEON_HPD_NONE;993 }994 995 /* Always set the connector type to VGA for CRT1/CRT2. if they are996 * shared with a DVI port, we'll pick up the DVI connector when we997 * merge the outputs. Some bioses incorrectly list VGA ports as DVI.998 */999 if (i == ATOM_DEVICE_CRT1_INDEX || i == ATOM_DEVICE_CRT2_INDEX)1000 bios_connectors[i].connector_type =1001 DRM_MODE_CONNECTOR_VGA;1002 1003 if (!radeon_atom_apply_quirks1004 (dev, (1 << i), &bios_connectors[i].connector_type,1005 &bios_connectors[i].ddc_bus, &bios_connectors[i].line_mux,1006 &bios_connectors[i].hpd))1007 continue;1008 1009 bios_connectors[i].valid = true;1010 bios_connectors[i].devices = (1 << i);1011 1012 if (ASIC_IS_AVIVO(rdev) || radeon_r4xx_atom)1013 radeon_add_atom_encoder(dev,1014 radeon_get_encoder_enum(dev,1015 (1 << i),1016 dac),1017 (1 << i),1018 0);1019 else1020 radeon_add_legacy_encoder(dev,1021 radeon_get_encoder_enum(dev,1022 (1 << i),1023 dac),1024 (1 << i));1025 }1026 1027 /* combine shared connectors */1028 for (i = 0; i < max_device; i++) {1029 if (bios_connectors[i].valid) {1030 for (j = 0; j < max_device; j++) {1031 if (bios_connectors[j].valid && (i != j)) {1032 if (bios_connectors[i].line_mux ==1033 bios_connectors[j].line_mux) {1034 /* make sure not to combine LVDS */1035 if (bios_connectors[i].devices & (ATOM_DEVICE_LCD_SUPPORT)) {1036 bios_connectors[i].line_mux = 53;1037 bios_connectors[i].ddc_bus.valid = false;1038 continue;1039 }1040 if (bios_connectors[j].devices & (ATOM_DEVICE_LCD_SUPPORT)) {1041 bios_connectors[j].line_mux = 53;1042 bios_connectors[j].ddc_bus.valid = false;1043 continue;1044 }1045 /* combine analog and digital for DVI-I */1046 if (((bios_connectors[i].devices & (ATOM_DEVICE_DFP_SUPPORT)) &&1047 (bios_connectors[j].devices & (ATOM_DEVICE_CRT_SUPPORT))) ||1048 ((bios_connectors[j].devices & (ATOM_DEVICE_DFP_SUPPORT)) &&1049 (bios_connectors[i].devices & (ATOM_DEVICE_CRT_SUPPORT)))) {1050 bios_connectors[i].devices |=1051 bios_connectors[j].devices;1052 bios_connectors[i].connector_type =1053 DRM_MODE_CONNECTOR_DVII;1054 if (bios_connectors[j].devices & (ATOM_DEVICE_DFP_SUPPORT))1055 bios_connectors[i].hpd =1056 bios_connectors[j].hpd;1057 bios_connectors[j].valid = false;1058 }1059 }1060 }1061 }1062 }1063 }1064 1065 /* add the connectors */1066 for (i = 0; i < max_device; i++) {1067 if (bios_connectors[i].valid) {1068 uint16_t connector_object_id =1069 atombios_get_connector_object_id(dev,1070 bios_connectors[i].connector_type,1071 bios_connectors[i].devices);1072 radeon_add_atom_connector(dev,1073 bios_connectors[i].line_mux,1074 bios_connectors[i].devices,1075 bios_connectors[i].1076 connector_type,1077 &bios_connectors[i].ddc_bus,1078 0,1079 connector_object_id,1080 &bios_connectors[i].hpd,1081 &router);1082 }1083 }1084 1085 radeon_link_encoder_connector(dev);1086 1087 kfree(bios_connectors);1088 return true;1089}1090 1091union firmware_info {1092 ATOM_FIRMWARE_INFO info;1093 ATOM_FIRMWARE_INFO_V1_2 info_12;1094 ATOM_FIRMWARE_INFO_V1_3 info_13;1095 ATOM_FIRMWARE_INFO_V1_4 info_14;1096 ATOM_FIRMWARE_INFO_V2_1 info_21;1097 ATOM_FIRMWARE_INFO_V2_2 info_22;1098};1099 1100union igp_info {1101 struct _ATOM_INTEGRATED_SYSTEM_INFO info;1102 struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 info_2;1103 struct _ATOM_INTEGRATED_SYSTEM_INFO_V6 info_6;1104 struct _ATOM_INTEGRATED_SYSTEM_INFO_V1_7 info_7;1105 struct _ATOM_INTEGRATED_SYSTEM_INFO_V1_8 info_8;1106};1107 1108static void radeon_atombios_get_dentist_vco_freq(struct radeon_device *rdev)1109{1110 struct radeon_mode_info *mode_info = &rdev->mode_info;1111 int index = GetIndexIntoMasterTable(DATA, IntegratedSystemInfo);1112 union igp_info *igp_info;1113 u8 frev, crev;1114 u16 data_offset;1115 1116 if (atom_parse_data_header(mode_info->atom_context, index, NULL,1117 &frev, &crev, &data_offset)) {1118 igp_info = (union igp_info *)(mode_info->atom_context->bios +1119 data_offset);1120 rdev->clock.vco_freq =1121 le32_to_cpu(igp_info->info_6.ulDentistVCOFreq);1122 }1123}1124 1125bool radeon_atom_get_clock_info(struct drm_device *dev)1126{1127 struct radeon_device *rdev = dev->dev_private;1128 struct radeon_mode_info *mode_info = &rdev->mode_info;1129 int index = GetIndexIntoMasterTable(DATA, FirmwareInfo);1130 union firmware_info *firmware_info;1131 uint8_t frev, crev;1132 struct radeon_pll *p1pll = &rdev->clock.p1pll;1133 struct radeon_pll *p2pll = &rdev->clock.p2pll;1134 struct radeon_pll *dcpll = &rdev->clock.dcpll;1135 struct radeon_pll *spll = &rdev->clock.spll;1136 struct radeon_pll *mpll = &rdev->clock.mpll;1137 uint16_t data_offset;1138 1139 if (atom_parse_data_header(mode_info->atom_context, index, NULL,1140 &frev, &crev, &data_offset)) {1141 firmware_info =1142 (union firmware_info *)(mode_info->atom_context->bios +1143 data_offset);1144 /* pixel clocks */1145 p1pll->reference_freq =1146 le16_to_cpu(firmware_info->info.usReferenceClock);1147 p1pll->reference_div = 0;1148 1149 if ((frev < 2) && (crev < 2))1150 p1pll->pll_out_min =1151 le16_to_cpu(firmware_info->info.usMinPixelClockPLL_Output);1152 else1153 p1pll->pll_out_min =1154 le32_to_cpu(firmware_info->info_12.ulMinPixelClockPLL_Output);1155 p1pll->pll_out_max =1156 le32_to_cpu(firmware_info->info.ulMaxPixelClockPLL_Output);1157 1158 if (((frev < 2) && (crev >= 4)) || (frev >= 2)) {1159 p1pll->lcd_pll_out_min =1160 le16_to_cpu(firmware_info->info_14.usLcdMinPixelClockPLL_Output) * 100;1161 if (p1pll->lcd_pll_out_min == 0)1162 p1pll->lcd_pll_out_min = p1pll->pll_out_min;1163 p1pll->lcd_pll_out_max =1164 le16_to_cpu(firmware_info->info_14.usLcdMaxPixelClockPLL_Output) * 100;1165 if (p1pll->lcd_pll_out_max == 0)1166 p1pll->lcd_pll_out_max = p1pll->pll_out_max;1167 } else {1168 p1pll->lcd_pll_out_min = p1pll->pll_out_min;1169 p1pll->lcd_pll_out_max = p1pll->pll_out_max;1170 }1171 1172 if (p1pll->pll_out_min == 0) {1173 if (ASIC_IS_AVIVO(rdev))1174 p1pll->pll_out_min = 64800;1175 else1176 p1pll->pll_out_min = 20000;1177 }1178 1179 p1pll->pll_in_min =1180 le16_to_cpu(firmware_info->info.usMinPixelClockPLL_Input);1181 p1pll->pll_in_max =1182 le16_to_cpu(firmware_info->info.usMaxPixelClockPLL_Input);1183 1184 *p2pll = *p1pll;1185 1186 /* system clock */1187 if (ASIC_IS_DCE4(rdev))1188 spll->reference_freq =1189 le16_to_cpu(firmware_info->info_21.usCoreReferenceClock);1190 else1191 spll->reference_freq =1192 le16_to_cpu(firmware_info->info.usReferenceClock);1193 spll->reference_div = 0;1194 1195 spll->pll_out_min =1196 le16_to_cpu(firmware_info->info.usMinEngineClockPLL_Output);1197 spll->pll_out_max =1198 le32_to_cpu(firmware_info->info.ulMaxEngineClockPLL_Output);1199 1200 /* ??? */1201 if (spll->pll_out_min == 0) {1202 if (ASIC_IS_AVIVO(rdev))1203 spll->pll_out_min = 64800;1204 else1205 spll->pll_out_min = 20000;1206 }1207 1208 spll->pll_in_min =1209 le16_to_cpu(firmware_info->info.usMinEngineClockPLL_Input);1210 spll->pll_in_max =1211 le16_to_cpu(firmware_info->info.usMaxEngineClockPLL_Input);1212 1213 /* memory clock */1214 if (ASIC_IS_DCE4(rdev))1215 mpll->reference_freq =1216 le16_to_cpu(firmware_info->info_21.usMemoryReferenceClock);1217 else1218 mpll->reference_freq =1219 le16_to_cpu(firmware_info->info.usReferenceClock);1220 mpll->reference_div = 0;1221 1222 mpll->pll_out_min =1223 le16_to_cpu(firmware_info->info.usMinMemoryClockPLL_Output);1224 mpll->pll_out_max =1225 le32_to_cpu(firmware_info->info.ulMaxMemoryClockPLL_Output);1226 1227 /* ??? */1228 if (mpll->pll_out_min == 0) {1229 if (ASIC_IS_AVIVO(rdev))1230 mpll->pll_out_min = 64800;1231 else1232 mpll->pll_out_min = 20000;1233 }1234 1235 mpll->pll_in_min =1236 le16_to_cpu(firmware_info->info.usMinMemoryClockPLL_Input);1237 mpll->pll_in_max =1238 le16_to_cpu(firmware_info->info.usMaxMemoryClockPLL_Input);1239 1240 rdev->clock.default_sclk =1241 le32_to_cpu(firmware_info->info.ulDefaultEngineClock);1242 rdev->clock.default_mclk =1243 le32_to_cpu(firmware_info->info.ulDefaultMemoryClock);1244 1245 if (ASIC_IS_DCE4(rdev)) {1246 rdev->clock.default_dispclk =1247 le32_to_cpu(firmware_info->info_21.ulDefaultDispEngineClkFreq);1248 if (rdev->clock.default_dispclk == 0) {1249 if (ASIC_IS_DCE6(rdev))1250 rdev->clock.default_dispclk = 60000; /* 600 Mhz */1251 else if (ASIC_IS_DCE5(rdev))1252 rdev->clock.default_dispclk = 54000; /* 540 Mhz */1253 else1254 rdev->clock.default_dispclk = 60000; /* 600 Mhz */1255 }1256 /* set a reasonable default for DP */1257 if (ASIC_IS_DCE6(rdev) && (rdev->clock.default_dispclk < 53900)) {1258 DRM_INFO("Changing default dispclk from %dMhz to 600Mhz\n",1259 rdev->clock.default_dispclk / 100);1260 rdev->clock.default_dispclk = 60000;1261 }1262 rdev->clock.dp_extclk =1263 le16_to_cpu(firmware_info->info_21.usUniphyDPModeExtClkFreq);1264 rdev->clock.current_dispclk = rdev->clock.default_dispclk;1265 }1266 *dcpll = *p1pll;1267 1268 rdev->clock.max_pixel_clock = le16_to_cpu(firmware_info->info.usMaxPixelClock);1269 if (rdev->clock.max_pixel_clock == 0)1270 rdev->clock.max_pixel_clock = 40000;1271 1272 /* not technically a clock, but... */1273 rdev->mode_info.firmware_flags =1274 le16_to_cpu(firmware_info->info.usFirmwareCapability.susAccess);1275 1276 if (ASIC_IS_DCE8(rdev))1277 rdev->clock.vco_freq =1278 le32_to_cpu(firmware_info->info_22.ulGPUPLL_OutputFreq);1279 else if (ASIC_IS_DCE5(rdev))1280 rdev->clock.vco_freq = rdev->clock.current_dispclk;1281 else if (ASIC_IS_DCE41(rdev))1282 radeon_atombios_get_dentist_vco_freq(rdev);1283 else1284 rdev->clock.vco_freq = rdev->clock.current_dispclk;1285 1286 if (rdev->clock.vco_freq == 0)1287 rdev->clock.vco_freq = 360000; /* 3.6 GHz */1288 1289 return true;1290 }1291 1292 return false;1293}1294 1295bool radeon_atombios_sideport_present(struct radeon_device *rdev)1296{1297 struct radeon_mode_info *mode_info = &rdev->mode_info;1298 int index = GetIndexIntoMasterTable(DATA, IntegratedSystemInfo);1299 union igp_info *igp_info;1300 u8 frev, crev;1301 u16 data_offset;1302 1303 /* sideport is AMD only */1304 if (rdev->family == CHIP_RS600)1305 return false;1306 1307 if (atom_parse_data_header(mode_info->atom_context, index, NULL,1308 &frev, &crev, &data_offset)) {1309 igp_info = (union igp_info *)(mode_info->atom_context->bios +1310 data_offset);1311 switch (crev) {1312 case 1:1313 if (le32_to_cpu(igp_info->info.ulBootUpMemoryClock))1314 return true;1315 break;1316 case 2:1317 if (le32_to_cpu(igp_info->info_2.ulBootUpSidePortClock))1318 return true;1319 break;1320 default:1321 DRM_ERROR("Unsupported IGP table: %d %d\n", frev, crev);1322 break;1323 }1324 }1325 return false;1326}1327 1328bool radeon_atombios_get_tmds_info(struct radeon_encoder *encoder,1329 struct radeon_encoder_int_tmds *tmds)1330{1331 struct drm_device *dev = encoder->base.dev;1332 struct radeon_device *rdev = dev->dev_private;1333 struct radeon_mode_info *mode_info = &rdev->mode_info;1334 int index = GetIndexIntoMasterTable(DATA, TMDS_Info);1335 uint16_t data_offset;1336 struct _ATOM_TMDS_INFO *tmds_info;1337 uint8_t frev, crev;1338 uint16_t maxfreq;1339 int i;1340 1341 if (atom_parse_data_header(mode_info->atom_context, index, NULL,1342 &frev, &crev, &data_offset)) {1343 tmds_info =1344 (struct _ATOM_TMDS_INFO *)(mode_info->atom_context->bios +1345 data_offset);1346 1347 maxfreq = le16_to_cpu(tmds_info->usMaxFrequency);1348 for (i = 0; i < 4; i++) {1349 tmds->tmds_pll[i].freq =1350 le16_to_cpu(tmds_info->asMiscInfo[i].usFrequency);1351 tmds->tmds_pll[i].value =1352 tmds_info->asMiscInfo[i].ucPLL_ChargePump & 0x3f;1353 tmds->tmds_pll[i].value |=1354 (tmds_info->asMiscInfo[i].1355 ucPLL_VCO_Gain & 0x3f) << 6;1356 tmds->tmds_pll[i].value |=1357 (tmds_info->asMiscInfo[i].1358 ucPLL_DutyCycle & 0xf) << 12;1359 tmds->tmds_pll[i].value |=1360 (tmds_info->asMiscInfo[i].1361 ucPLL_VoltageSwing & 0xf) << 16;1362 1363 DRM_DEBUG_KMS("TMDS PLL From ATOMBIOS %u %x\n",1364 tmds->tmds_pll[i].freq,1365 tmds->tmds_pll[i].value);1366 1367 if (maxfreq == tmds->tmds_pll[i].freq) {1368 tmds->tmds_pll[i].freq = 0xffffffff;1369 break;1370 }1371 }1372 return true;1373 }1374 return false;1375}1376 1377bool radeon_atombios_get_ppll_ss_info(struct radeon_device *rdev,1378 struct radeon_atom_ss *ss,1379 int id)1380{1381 struct radeon_mode_info *mode_info = &rdev->mode_info;1382 int index = GetIndexIntoMasterTable(DATA, PPLL_SS_Info);1383 uint16_t data_offset, size;1384 struct _ATOM_SPREAD_SPECTRUM_INFO *ss_info;1385 struct _ATOM_SPREAD_SPECTRUM_ASSIGNMENT *ss_assign;1386 uint8_t frev, crev;1387 int i, num_indices;1388 1389 memset(ss, 0, sizeof(struct radeon_atom_ss));1390 if (atom_parse_data_header(mode_info->atom_context, index, &size,1391 &frev, &crev, &data_offset)) {1392 ss_info =1393 (struct _ATOM_SPREAD_SPECTRUM_INFO *)(mode_info->atom_context->bios + data_offset);1394 1395 num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) /1396 sizeof(ATOM_SPREAD_SPECTRUM_ASSIGNMENT);1397 ss_assign = (struct _ATOM_SPREAD_SPECTRUM_ASSIGNMENT *)1398 ((u8 *)&ss_info->asSS_Info[0]);1399 for (i = 0; i < num_indices; i++) {1400 if (ss_assign->ucSS_Id == id) {1401 ss->percentage =1402 le16_to_cpu(ss_assign->usSpreadSpectrumPercentage);1403 ss->type = ss_assign->ucSpreadSpectrumType;1404 ss->step = ss_assign->ucSS_Step;1405 ss->delay = ss_assign->ucSS_Delay;1406 ss->range = ss_assign->ucSS_Range;1407 ss->refdiv = ss_assign->ucRecommendedRef_Div;1408 return true;1409 }1410 ss_assign = (struct _ATOM_SPREAD_SPECTRUM_ASSIGNMENT *)1411 ((u8 *)ss_assign + sizeof(struct _ATOM_SPREAD_SPECTRUM_ASSIGNMENT));1412 }1413 }1414 return false;1415}1416 1417static void radeon_atombios_get_igp_ss_overrides(struct radeon_device *rdev,1418 struct radeon_atom_ss *ss,1419 int id)1420{1421 struct radeon_mode_info *mode_info = &rdev->mode_info;1422 int index = GetIndexIntoMasterTable(DATA, IntegratedSystemInfo);1423 u16 data_offset, size;1424 union igp_info *igp_info;1425 u8 frev, crev;1426 u16 percentage = 0, rate = 0;1427 1428 /* get any igp specific overrides */1429 if (atom_parse_data_header(mode_info->atom_context, index, &size,1430 &frev, &crev, &data_offset)) {1431 igp_info = (union igp_info *)1432 (mode_info->atom_context->bios + data_offset);1433 switch (crev) {1434 case 6:1435 switch (id) {1436 case ASIC_INTERNAL_SS_ON_TMDS:1437 percentage = le16_to_cpu(igp_info->info_6.usDVISSPercentage);1438 rate = le16_to_cpu(igp_info->info_6.usDVISSpreadRateIn10Hz);1439 break;1440 case ASIC_INTERNAL_SS_ON_HDMI:1441 percentage = le16_to_cpu(igp_info->info_6.usHDMISSPercentage);1442 rate = le16_to_cpu(igp_info->info_6.usHDMISSpreadRateIn10Hz);1443 break;1444 case ASIC_INTERNAL_SS_ON_LVDS:1445 percentage = le16_to_cpu(igp_info->info_6.usLvdsSSPercentage);1446 rate = le16_to_cpu(igp_info->info_6.usLvdsSSpreadRateIn10Hz);1447 break;1448 }1449 break;1450 case 7:1451 switch (id) {1452 case ASIC_INTERNAL_SS_ON_TMDS:1453 percentage = le16_to_cpu(igp_info->info_7.usDVISSPercentage);1454 rate = le16_to_cpu(igp_info->info_7.usDVISSpreadRateIn10Hz);1455 break;1456 case ASIC_INTERNAL_SS_ON_HDMI:1457 percentage = le16_to_cpu(igp_info->info_7.usHDMISSPercentage);1458 rate = le16_to_cpu(igp_info->info_7.usHDMISSpreadRateIn10Hz);1459 break;1460 case ASIC_INTERNAL_SS_ON_LVDS:1461 percentage = le16_to_cpu(igp_info->info_7.usLvdsSSPercentage);1462 rate = le16_to_cpu(igp_info->info_7.usLvdsSSpreadRateIn10Hz);1463 break;1464 }1465 break;1466 case 8:1467 switch (id) {1468 case ASIC_INTERNAL_SS_ON_TMDS:1469 percentage = le16_to_cpu(igp_info->info_8.usDVISSPercentage);1470 rate = le16_to_cpu(igp_info->info_8.usDVISSpreadRateIn10Hz);1471 break;1472 case ASIC_INTERNAL_SS_ON_HDMI:1473 percentage = le16_to_cpu(igp_info->info_8.usHDMISSPercentage);1474 rate = le16_to_cpu(igp_info->info_8.usHDMISSpreadRateIn10Hz);1475 break;1476 case ASIC_INTERNAL_SS_ON_LVDS:1477 percentage = le16_to_cpu(igp_info->info_8.usLvdsSSPercentage);1478 rate = le16_to_cpu(igp_info->info_8.usLvdsSSpreadRateIn10Hz);1479 break;1480 }1481 break;1482 default:1483 DRM_ERROR("Unsupported IGP table: %d %d\n", frev, crev);1484 break;1485 }1486 if (percentage)1487 ss->percentage = percentage;1488 if (rate)1489 ss->rate = rate;1490 }1491}1492 1493union asic_ss_info {1494 struct _ATOM_ASIC_INTERNAL_SS_INFO info;1495 struct _ATOM_ASIC_INTERNAL_SS_INFO_V2 info_2;1496 struct _ATOM_ASIC_INTERNAL_SS_INFO_V3 info_3;1497};1498 1499union asic_ss_assignment {1500 struct _ATOM_ASIC_SS_ASSIGNMENT v1;1501 struct _ATOM_ASIC_SS_ASSIGNMENT_V2 v2;1502 struct _ATOM_ASIC_SS_ASSIGNMENT_V3 v3;1503};1504 1505bool radeon_atombios_get_asic_ss_info(struct radeon_device *rdev,1506 struct radeon_atom_ss *ss,1507 int id, u32 clock)1508{1509 struct radeon_mode_info *mode_info = &rdev->mode_info;1510 int index = GetIndexIntoMasterTable(DATA, ASIC_InternalSS_Info);1511 uint16_t data_offset, size;1512 union asic_ss_info *ss_info;1513 union asic_ss_assignment *ss_assign;1514 uint8_t frev, crev;1515 int i, num_indices;1516 1517 if (id == ASIC_INTERNAL_MEMORY_SS) {1518 if (!(rdev->mode_info.firmware_flags & ATOM_BIOS_INFO_MEMORY_CLOCK_SS_SUPPORT))1519 return false;1520 }1521 if (id == ASIC_INTERNAL_ENGINE_SS) {1522 if (!(rdev->mode_info.firmware_flags & ATOM_BIOS_INFO_ENGINE_CLOCK_SS_SUPPORT))1523 return false;1524 }1525 1526 memset(ss, 0, sizeof(struct radeon_atom_ss));1527 if (atom_parse_data_header(mode_info->atom_context, index, &size,1528 &frev, &crev, &data_offset)) {1529 1530 ss_info =1531 (union asic_ss_info *)(mode_info->atom_context->bios + data_offset);1532 1533 switch (frev) {1534 case 1:1535 num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) /1536 sizeof(ATOM_ASIC_SS_ASSIGNMENT);1537 1538 ss_assign = (union asic_ss_assignment *)((u8 *)&ss_info->info.asSpreadSpectrum[0]);1539 for (i = 0; i < num_indices; i++) {1540 if ((ss_assign->v1.ucClockIndication == id) &&1541 (clock <= le32_to_cpu(ss_assign->v1.ulTargetClockRange))) {1542 ss->percentage =1543 le16_to_cpu(ss_assign->v1.usSpreadSpectrumPercentage);1544 ss->type = ss_assign->v1.ucSpreadSpectrumMode;1545 ss->rate = le16_to_cpu(ss_assign->v1.usSpreadRateInKhz);1546 ss->percentage_divider = 100;1547 return true;1548 }1549 ss_assign = (union asic_ss_assignment *)1550 ((u8 *)ss_assign + sizeof(ATOM_ASIC_SS_ASSIGNMENT));1551 }1552 break;1553 case 2:1554 num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) /1555 sizeof(ATOM_ASIC_SS_ASSIGNMENT_V2);1556 ss_assign = (union asic_ss_assignment *)((u8 *)&ss_info->info_2.asSpreadSpectrum[0]);1557 for (i = 0; i < num_indices; i++) {1558 if ((ss_assign->v2.ucClockIndication == id) &&1559 (clock <= le32_to_cpu(ss_assign->v2.ulTargetClockRange))) {1560 ss->percentage =1561 le16_to_cpu(ss_assign->v2.usSpreadSpectrumPercentage);1562 ss->type = ss_assign->v2.ucSpreadSpectrumMode;1563 ss->rate = le16_to_cpu(ss_assign->v2.usSpreadRateIn10Hz);1564 ss->percentage_divider = 100;1565 if ((crev == 2) &&1566 ((id == ASIC_INTERNAL_ENGINE_SS) ||1567 (id == ASIC_INTERNAL_MEMORY_SS)))1568 ss->rate /= 100;1569 return true;1570 }1571 ss_assign = (union asic_ss_assignment *)1572 ((u8 *)ss_assign + sizeof(ATOM_ASIC_SS_ASSIGNMENT_V2));1573 }1574 break;1575 case 3:1576 num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) /1577 sizeof(ATOM_ASIC_SS_ASSIGNMENT_V3);1578 ss_assign = (union asic_ss_assignment *)((u8 *)&ss_info->info_3.asSpreadSpectrum[0]);1579 for (i = 0; i < num_indices; i++) {1580 if ((ss_assign->v3.ucClockIndication == id) &&1581 (clock <= le32_to_cpu(ss_assign->v3.ulTargetClockRange))) {1582 ss->percentage =1583 le16_to_cpu(ss_assign->v3.usSpreadSpectrumPercentage);1584 ss->type = ss_assign->v3.ucSpreadSpectrumMode;1585 ss->rate = le16_to_cpu(ss_assign->v3.usSpreadRateIn10Hz);1586 if (ss_assign->v3.ucSpreadSpectrumMode &1587 SS_MODE_V3_PERCENTAGE_DIV_BY_1000_MASK)1588 ss->percentage_divider = 1000;1589 else1590 ss->percentage_divider = 100;1591 if ((id == ASIC_INTERNAL_ENGINE_SS) ||1592 (id == ASIC_INTERNAL_MEMORY_SS))1593 ss->rate /= 100;1594 if (rdev->flags & RADEON_IS_IGP)1595 radeon_atombios_get_igp_ss_overrides(rdev, ss, id);1596 return true;1597 }1598 ss_assign = (union asic_ss_assignment *)1599 ((u8 *)ss_assign + sizeof(ATOM_ASIC_SS_ASSIGNMENT_V3));1600 }1601 break;1602 default:1603 DRM_ERROR("Unsupported ASIC_InternalSS_Info table: %d %d\n", frev, crev);1604 break;1605 }1606 1607 }1608 return false;1609}1610 1611union lvds_info {1612 struct _ATOM_LVDS_INFO info;1613 struct _ATOM_LVDS_INFO_V12 info_12;1614};1615 1616struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct1617 radeon_encoder1618 *encoder)1619{1620 struct drm_device *dev = encoder->base.dev;1621 struct radeon_device *rdev = dev->dev_private;1622 struct radeon_mode_info *mode_info = &rdev->mode_info;1623 int index = GetIndexIntoMasterTable(DATA, LVDS_Info);1624 uint16_t data_offset, misc;1625 union lvds_info *lvds_info;1626 uint8_t frev, crev;1627 struct radeon_encoder_atom_dig *lvds = NULL;1628 int encoder_enum = (encoder->encoder_enum & ENUM_ID_MASK) >> ENUM_ID_SHIFT;1629 1630 if (atom_parse_data_header(mode_info->atom_context, index, NULL,1631 &frev, &crev, &data_offset)) {1632 lvds_info =1633 (union lvds_info *)(mode_info->atom_context->bios + data_offset);1634 lvds =1635 kzalloc(sizeof(struct radeon_encoder_atom_dig), GFP_KERNEL);1636 1637 if (!lvds)1638 return NULL;1639 1640 lvds->native_mode.clock =1641 le16_to_cpu(lvds_info->info.sLCDTiming.usPixClk) * 10;1642 lvds->native_mode.hdisplay =1643 le16_to_cpu(lvds_info->info.sLCDTiming.usHActive);1644 lvds->native_mode.vdisplay =1645 le16_to_cpu(lvds_info->info.sLCDTiming.usVActive);1646 lvds->native_mode.htotal = lvds->native_mode.hdisplay +1647 le16_to_cpu(lvds_info->info.sLCDTiming.usHBlanking_Time);1648 lvds->native_mode.hsync_start = lvds->native_mode.hdisplay +1649 le16_to_cpu(lvds_info->info.sLCDTiming.usHSyncOffset);1650 lvds->native_mode.hsync_end = lvds->native_mode.hsync_start +1651 le16_to_cpu(lvds_info->info.sLCDTiming.usHSyncWidth);1652 lvds->native_mode.vtotal = lvds->native_mode.vdisplay +1653 le16_to_cpu(lvds_info->info.sLCDTiming.usVBlanking_Time);1654 lvds->native_mode.vsync_start = lvds->native_mode.vdisplay +1655 le16_to_cpu(lvds_info->info.sLCDTiming.usVSyncOffset);1656 lvds->native_mode.vsync_end = lvds->native_mode.vsync_start +1657 le16_to_cpu(lvds_info->info.sLCDTiming.usVSyncWidth);1658 lvds->panel_pwr_delay =1659 le16_to_cpu(lvds_info->info.usOffDelayInMs);1660 lvds->lcd_misc = lvds_info->info.ucLVDS_Misc;1661 1662 misc = le16_to_cpu(lvds_info->info.sLCDTiming.susModeMiscInfo.usAccess);1663 if (misc & ATOM_VSYNC_POLARITY)1664 lvds->native_mode.flags |= DRM_MODE_FLAG_NVSYNC;1665 if (misc & ATOM_HSYNC_POLARITY)1666 lvds->native_mode.flags |= DRM_MODE_FLAG_NHSYNC;1667 if (misc & ATOM_COMPOSITESYNC)1668 lvds->native_mode.flags |= DRM_MODE_FLAG_CSYNC;1669 if (misc & ATOM_INTERLACE)1670 lvds->native_mode.flags |= DRM_MODE_FLAG_INTERLACE;1671 if (misc & ATOM_DOUBLE_CLOCK_MODE)1672 lvds->native_mode.flags |= DRM_MODE_FLAG_DBLSCAN;1673 1674 lvds->native_mode.width_mm = le16_to_cpu(lvds_info->info.sLCDTiming.usImageHSize);1675 lvds->native_mode.height_mm = le16_to_cpu(lvds_info->info.sLCDTiming.usImageVSize);1676 1677 /* set crtc values */1678 drm_mode_set_crtcinfo(&lvds->native_mode, CRTC_INTERLACE_HALVE_V);1679 1680 lvds->lcd_ss_id = lvds_info->info.ucSS_Id;1681 1682 encoder->native_mode = lvds->native_mode;1683 1684 if (encoder_enum == 2)1685 lvds->linkb = true;1686 else1687 lvds->linkb = false;1688 1689 /* parse the lcd record table */1690 if (le16_to_cpu(lvds_info->info.usModePatchTableOffset)) {1691 ATOM_FAKE_EDID_PATCH_RECORD *fake_edid_record;1692 ATOM_PANEL_RESOLUTION_PATCH_RECORD *panel_res_record;1693 bool bad_record = false;1694 u8 *record;1695 1696 if ((frev == 1) && (crev < 2))1697 /* absolute */1698 record = (u8 *)(mode_info->atom_context->bios +1699 le16_to_cpu(lvds_info->info.usModePatchTableOffset));1700 else1701 /* relative */1702 record = (u8 *)(mode_info->atom_context->bios +1703 data_offset +1704 le16_to_cpu(lvds_info->info.usModePatchTableOffset));1705 while (*record != ATOM_RECORD_END_TYPE) {1706 switch (*record) {1707 case LCD_MODE_PATCH_RECORD_MODE_TYPE:1708 record += sizeof(ATOM_PATCH_RECORD_MODE);1709 break;1710 case LCD_RTS_RECORD_TYPE:1711 record += sizeof(ATOM_LCD_RTS_RECORD);1712 break;1713 case LCD_CAP_RECORD_TYPE:1714 record += sizeof(ATOM_LCD_MODE_CONTROL_CAP);1715 break;1716 case LCD_FAKE_EDID_PATCH_RECORD_TYPE:1717 fake_edid_record = (ATOM_FAKE_EDID_PATCH_RECORD *)record;1718 if (fake_edid_record->ucFakeEDIDLength) {1719 const struct drm_edid *edid;1720 int edid_size;1721 1722 if (fake_edid_record->ucFakeEDIDLength == 128)1723 edid_size = fake_edid_record->ucFakeEDIDLength;1724 else1725 edid_size = fake_edid_record->ucFakeEDIDLength * 128;1726 edid = drm_edid_alloc(fake_edid_record->ucFakeEDIDString, edid_size);1727 if (drm_edid_valid(edid))1728 rdev->mode_info.bios_hardcoded_edid = edid;1729 else1730 drm_edid_free(edid);1731 record += struct_size(fake_edid_record,1732 ucFakeEDIDString,1733 edid_size);1734 } else {1735 /* empty fake edid record must be 3 bytes long */1736 record += sizeof(ATOM_FAKE_EDID_PATCH_RECORD) + 1;1737 }1738 break;1739 case LCD_PANEL_RESOLUTION_RECORD_TYPE:1740 panel_res_record = (ATOM_PANEL_RESOLUTION_PATCH_RECORD *)record;1741 lvds->native_mode.width_mm = panel_res_record->usHSize;1742 lvds->native_mode.height_mm = panel_res_record->usVSize;1743 record += sizeof(ATOM_PANEL_RESOLUTION_PATCH_RECORD);1744 break;1745 default:1746 DRM_ERROR("Bad LCD record %d\n", *record);1747 bad_record = true;1748 break;1749 }1750 if (bad_record)1751 break;1752 }1753 }1754 }1755 return lvds;1756}1757 1758struct radeon_encoder_primary_dac *1759radeon_atombios_get_primary_dac_info(struct radeon_encoder *encoder)1760{1761 struct drm_device *dev = encoder->base.dev;1762 struct radeon_device *rdev = dev->dev_private;1763 struct radeon_mode_info *mode_info = &rdev->mode_info;1764 int index = GetIndexIntoMasterTable(DATA, CompassionateData);1765 uint16_t data_offset;1766 struct _COMPASSIONATE_DATA *dac_info;1767 uint8_t frev, crev;1768 uint8_t bg, dac;1769 struct radeon_encoder_primary_dac *p_dac = NULL;1770 1771 if (atom_parse_data_header(mode_info->atom_context, index, NULL,1772 &frev, &crev, &data_offset)) {1773 dac_info = (struct _COMPASSIONATE_DATA *)1774 (mode_info->atom_context->bios + data_offset);1775 1776 p_dac = kzalloc(sizeof(struct radeon_encoder_primary_dac), GFP_KERNEL);1777 1778 if (!p_dac)1779 return NULL;1780 1781 bg = dac_info->ucDAC1_BG_Adjustment;1782 dac = dac_info->ucDAC1_DAC_Adjustment;1783 p_dac->ps2_pdac_adj = (bg << 8) | (dac);1784 1785 }1786 return p_dac;1787}1788 1789bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index,1790 struct drm_display_mode *mode)1791{1792 struct radeon_mode_info *mode_info = &rdev->mode_info;1793 ATOM_ANALOG_TV_INFO *tv_info;1794 ATOM_ANALOG_TV_INFO_V1_2 *tv_info_v1_2;1795 ATOM_DTD_FORMAT *dtd_timings;1796 int data_index = GetIndexIntoMasterTable(DATA, AnalogTV_Info);1797 u8 frev, crev;1798 u16 data_offset, misc;1799 1800 if (!atom_parse_data_header(mode_info->atom_context, data_index, NULL,1801 &frev, &crev, &data_offset))1802 return false;1803 1804 switch (crev) {1805 case 1:1806 tv_info = (ATOM_ANALOG_TV_INFO *)(mode_info->atom_context->bios + data_offset);1807 if (index >= MAX_SUPPORTED_TV_TIMING)1808 return false;1809 1810 mode->crtc_htotal = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_Total);1811 mode->crtc_hdisplay = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_Disp);1812 mode->crtc_hsync_start = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_SyncStart);1813 mode->crtc_hsync_end = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_SyncStart) +1814 le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_SyncWidth);1815 1816 mode->crtc_vtotal = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_Total);1817 mode->crtc_vdisplay = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_Disp);1818 mode->crtc_vsync_start = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_SyncStart);1819 mode->crtc_vsync_end = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_SyncStart) +1820 le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_SyncWidth);1821 1822 mode->flags = 0;1823 misc = le16_to_cpu(tv_info->aModeTimings[index].susModeMiscInfo.usAccess);1824 if (misc & ATOM_VSYNC_POLARITY)1825 mode->flags |= DRM_MODE_FLAG_NVSYNC;1826 if (misc & ATOM_HSYNC_POLARITY)1827 mode->flags |= DRM_MODE_FLAG_NHSYNC;1828 if (misc & ATOM_COMPOSITESYNC)1829 mode->flags |= DRM_MODE_FLAG_CSYNC;1830 if (misc & ATOM_INTERLACE)1831 mode->flags |= DRM_MODE_FLAG_INTERLACE;1832 if (misc & ATOM_DOUBLE_CLOCK_MODE)1833 mode->flags |= DRM_MODE_FLAG_DBLSCAN;1834 1835 mode->crtc_clock = mode->clock =1836 le16_to_cpu(tv_info->aModeTimings[index].usPixelClock) * 10;1837 1838 if (index == 1) {1839 /* PAL timings appear to have wrong values for totals */1840 mode->crtc_htotal -= 1;1841 mode->crtc_vtotal -= 1;1842 }1843 break;1844 case 2:1845 tv_info_v1_2 = (ATOM_ANALOG_TV_INFO_V1_2 *)(mode_info->atom_context->bios + data_offset);1846 if (index >= MAX_SUPPORTED_TV_TIMING_V1_2)1847 return false;1848 1849 dtd_timings = &tv_info_v1_2->aModeTimings[index];1850 mode->crtc_htotal = le16_to_cpu(dtd_timings->usHActive) +1851 le16_to_cpu(dtd_timings->usHBlanking_Time);1852 mode->crtc_hdisplay = le16_to_cpu(dtd_timings->usHActive);1853 mode->crtc_hsync_start = le16_to_cpu(dtd_timings->usHActive) +1854 le16_to_cpu(dtd_timings->usHSyncOffset);1855 mode->crtc_hsync_end = mode->crtc_hsync_start +1856 le16_to_cpu(dtd_timings->usHSyncWidth);1857 1858 mode->crtc_vtotal = le16_to_cpu(dtd_timings->usVActive) +1859 le16_to_cpu(dtd_timings->usVBlanking_Time);1860 mode->crtc_vdisplay = le16_to_cpu(dtd_timings->usVActive);1861 mode->crtc_vsync_start = le16_to_cpu(dtd_timings->usVActive) +1862 le16_to_cpu(dtd_timings->usVSyncOffset);1863 mode->crtc_vsync_end = mode->crtc_vsync_start +1864 le16_to_cpu(dtd_timings->usVSyncWidth);1865 1866 mode->flags = 0;1867 misc = le16_to_cpu(dtd_timings->susModeMiscInfo.usAccess);1868 if (misc & ATOM_VSYNC_POLARITY)1869 mode->flags |= DRM_MODE_FLAG_NVSYNC;1870 if (misc & ATOM_HSYNC_POLARITY)1871 mode->flags |= DRM_MODE_FLAG_NHSYNC;1872 if (misc & ATOM_COMPOSITESYNC)1873 mode->flags |= DRM_MODE_FLAG_CSYNC;1874 if (misc & ATOM_INTERLACE)1875 mode->flags |= DRM_MODE_FLAG_INTERLACE;1876 if (misc & ATOM_DOUBLE_CLOCK_MODE)1877 mode->flags |= DRM_MODE_FLAG_DBLSCAN;1878 1879 mode->crtc_clock = mode->clock =1880 le16_to_cpu(dtd_timings->usPixClk) * 10;1881 break;1882 }1883 return true;1884}1885 1886enum radeon_tv_std1887radeon_atombios_get_tv_info(struct radeon_device *rdev)1888{1889 struct radeon_mode_info *mode_info = &rdev->mode_info;1890 int index = GetIndexIntoMasterTable(DATA, AnalogTV_Info);1891 uint16_t data_offset;1892 uint8_t frev, crev;1893 struct _ATOM_ANALOG_TV_INFO *tv_info;1894 enum radeon_tv_std tv_std = TV_STD_NTSC;1895 1896 if (atom_parse_data_header(mode_info->atom_context, index, NULL,1897 &frev, &crev, &data_offset)) {1898 1899 tv_info = (struct _ATOM_ANALOG_TV_INFO *)1900 (mode_info->atom_context->bios + data_offset);1901 1902 switch (tv_info->ucTV_BootUpDefaultStandard) {1903 case ATOM_TV_NTSC:1904 tv_std = TV_STD_NTSC;1905 DRM_DEBUG_KMS("Default TV standard: NTSC\n");1906 break;1907 case ATOM_TV_NTSCJ:1908 tv_std = TV_STD_NTSC_J;1909 DRM_DEBUG_KMS("Default TV standard: NTSC-J\n");1910 break;1911 case ATOM_TV_PAL:1912 tv_std = TV_STD_PAL;1913 DRM_DEBUG_KMS("Default TV standard: PAL\n");1914 break;1915 case ATOM_TV_PALM:1916 tv_std = TV_STD_PAL_M;1917 DRM_DEBUG_KMS("Default TV standard: PAL-M\n");1918 break;1919 case ATOM_TV_PALN:1920 tv_std = TV_STD_PAL_N;1921 DRM_DEBUG_KMS("Default TV standard: PAL-N\n");1922 break;1923 case ATOM_TV_PALCN:1924 tv_std = TV_STD_PAL_CN;1925 DRM_DEBUG_KMS("Default TV standard: PAL-CN\n");1926 break;1927 case ATOM_TV_PAL60:1928 tv_std = TV_STD_PAL_60;1929 DRM_DEBUG_KMS("Default TV standard: PAL-60\n");1930 break;1931 case ATOM_TV_SECAM:1932 tv_std = TV_STD_SECAM;1933 DRM_DEBUG_KMS("Default TV standard: SECAM\n");1934 break;1935 default:1936 tv_std = TV_STD_NTSC;1937 DRM_DEBUG_KMS("Unknown TV standard; defaulting to NTSC\n");1938 break;1939 }1940 }1941 return tv_std;1942}1943 1944struct radeon_encoder_tv_dac *1945radeon_atombios_get_tv_dac_info(struct radeon_encoder *encoder)1946{1947 struct drm_device *dev = encoder->base.dev;1948 struct radeon_device *rdev = dev->dev_private;1949 struct radeon_mode_info *mode_info = &rdev->mode_info;1950 int index = GetIndexIntoMasterTable(DATA, CompassionateData);1951 uint16_t data_offset;1952 struct _COMPASSIONATE_DATA *dac_info;1953 uint8_t frev, crev;1954 uint8_t bg, dac;1955 struct radeon_encoder_tv_dac *tv_dac = NULL;1956 1957 if (atom_parse_data_header(mode_info->atom_context, index, NULL,1958 &frev, &crev, &data_offset)) {1959 1960 dac_info = (struct _COMPASSIONATE_DATA *)1961 (mode_info->atom_context->bios + data_offset);1962 1963 tv_dac = kzalloc(sizeof(struct radeon_encoder_tv_dac), GFP_KERNEL);1964 1965 if (!tv_dac)1966 return NULL;1967 1968 bg = dac_info->ucDAC2_CRT2_BG_Adjustment;1969 dac = dac_info->ucDAC2_CRT2_DAC_Adjustment;1970 tv_dac->ps2_tvdac_adj = (bg << 16) | (dac << 20);1971 1972 bg = dac_info->ucDAC2_PAL_BG_Adjustment;1973 dac = dac_info->ucDAC2_PAL_DAC_Adjustment;1974 tv_dac->pal_tvdac_adj = (bg << 16) | (dac << 20);1975 1976 bg = dac_info->ucDAC2_NTSC_BG_Adjustment;1977 dac = dac_info->ucDAC2_NTSC_DAC_Adjustment;1978 tv_dac->ntsc_tvdac_adj = (bg << 16) | (dac << 20);1979 1980 tv_dac->tv_std = radeon_atombios_get_tv_info(rdev);1981 }1982 return tv_dac;1983}1984 1985static const char *thermal_controller_names[] = {1986 "NONE",1987 "lm63",1988 "adm1032",1989 "adm1030",1990 "max6649",1991 "lm63", /* lm64 */1992 "f75375",1993 "asc7xxx",1994};1995 1996static const char *pp_lib_thermal_controller_names[] = {1997 "NONE",1998 "lm63",1999 "adm1032",2000 "adm1030",2001 "max6649",2002 "lm63", /* lm64 */2003 "f75375",2004 "RV6xx",2005 "RV770",2006 "adt7473",2007 "NONE",2008 "External GPIO",2009 "Evergreen",2010 "emc2103",2011 "Sumo",2012 "Northern Islands",2013 "Southern Islands",2014 "lm96163",2015 "Sea Islands",2016};2017 2018union power_info {2019 struct _ATOM_POWERPLAY_INFO info;2020 struct _ATOM_POWERPLAY_INFO_V2 info_2;2021 struct _ATOM_POWERPLAY_INFO_V3 info_3;2022 struct _ATOM_PPLIB_POWERPLAYTABLE pplib;2023 struct _ATOM_PPLIB_POWERPLAYTABLE2 pplib2;2024 struct _ATOM_PPLIB_POWERPLAYTABLE3 pplib3;2025};2026 2027union pplib_clock_info {2028 struct _ATOM_PPLIB_R600_CLOCK_INFO r600;2029 struct _ATOM_PPLIB_RS780_CLOCK_INFO rs780;2030 struct _ATOM_PPLIB_EVERGREEN_CLOCK_INFO evergreen;2031 struct _ATOM_PPLIB_SUMO_CLOCK_INFO sumo;2032 struct _ATOM_PPLIB_SI_CLOCK_INFO si;2033 struct _ATOM_PPLIB_CI_CLOCK_INFO ci;2034};2035 2036union pplib_power_state {2037 struct _ATOM_PPLIB_STATE v1;2038 struct _ATOM_PPLIB_STATE_V2 v2;2039};2040 2041static void radeon_atombios_parse_misc_flags_1_3(struct radeon_device *rdev,2042 int state_index,2043 u32 misc, u32 misc2)2044{2045 rdev->pm.power_state[state_index].misc = misc;2046 rdev->pm.power_state[state_index].misc2 = misc2;2047 /* order matters! */2048 if (misc & ATOM_PM_MISCINFO_POWER_SAVING_MODE)2049 rdev->pm.power_state[state_index].type =2050 POWER_STATE_TYPE_POWERSAVE;2051 if (misc & ATOM_PM_MISCINFO_DEFAULT_DC_STATE_ENTRY_TRUE)2052 rdev->pm.power_state[state_index].type =2053 POWER_STATE_TYPE_BATTERY;2054 if (misc & ATOM_PM_MISCINFO_DEFAULT_LOW_DC_STATE_ENTRY_TRUE)2055 rdev->pm.power_state[state_index].type =2056 POWER_STATE_TYPE_BATTERY;2057 if (misc & ATOM_PM_MISCINFO_LOAD_BALANCE_EN)2058 rdev->pm.power_state[state_index].type =2059 POWER_STATE_TYPE_BALANCED;2060 if (misc & ATOM_PM_MISCINFO_3D_ACCELERATION_EN) {2061 rdev->pm.power_state[state_index].type =2062 POWER_STATE_TYPE_PERFORMANCE;2063 rdev->pm.power_state[state_index].flags &=2064 ~RADEON_PM_STATE_SINGLE_DISPLAY_ONLY;2065 }2066 if (misc2 & ATOM_PM_MISCINFO2_SYSTEM_AC_LITE_MODE)2067 rdev->pm.power_state[state_index].type =2068 POWER_STATE_TYPE_BALANCED;2069 if (misc & ATOM_PM_MISCINFO_DRIVER_DEFAULT_MODE) {2070 rdev->pm.power_state[state_index].type =2071 POWER_STATE_TYPE_DEFAULT;2072 rdev->pm.default_power_state_index = state_index;2073 rdev->pm.power_state[state_index].default_clock_mode =2074 &rdev->pm.power_state[state_index].clock_info[0];2075 } else if (state_index == 0) {2076 rdev->pm.power_state[state_index].clock_info[0].flags |=2077 RADEON_PM_MODE_NO_DISPLAY;2078 }2079}2080 2081static int radeon_atombios_parse_power_table_1_3(struct radeon_device *rdev)2082{2083 struct radeon_mode_info *mode_info = &rdev->mode_info;2084 u32 misc, misc2 = 0;2085 int num_modes = 0, i;2086 int state_index = 0;2087 struct radeon_i2c_bus_rec i2c_bus;2088 union power_info *power_info;2089 int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo);2090 u16 data_offset;2091 u8 frev, crev;2092 2093 if (!atom_parse_data_header(mode_info->atom_context, index, NULL,2094 &frev, &crev, &data_offset))2095 return state_index;2096 power_info = (union power_info *)(mode_info->atom_context->bios + data_offset);2097 2098 /* add the i2c bus for thermal/fan chip */2099 if ((power_info->info.ucOverdriveThermalController > 0) &&2100 (power_info->info.ucOverdriveThermalController < ARRAY_SIZE(thermal_controller_names))) {2101 DRM_INFO("Possible %s thermal controller at 0x%02x\n",2102 thermal_controller_names[power_info->info.ucOverdriveThermalController],2103 power_info->info.ucOverdriveControllerAddress >> 1);2104 i2c_bus = radeon_lookup_i2c_gpio(rdev, power_info->info.ucOverdriveI2cLine);2105 rdev->pm.i2c_bus = radeon_i2c_lookup(rdev, &i2c_bus);2106 if (rdev->pm.i2c_bus) {2107 struct i2c_board_info info = { };2108 const char *name = thermal_controller_names[power_info->info.2109 ucOverdriveThermalController];2110 info.addr = power_info->info.ucOverdriveControllerAddress >> 1;2111 strscpy(info.type, name, sizeof(info.type));2112 i2c_new_client_device(&rdev->pm.i2c_bus->adapter, &info);2113 }2114 }2115 num_modes = power_info->info.ucNumOfPowerModeEntries;2116 if (num_modes > ATOM_MAX_NUMBEROF_POWER_BLOCK)2117 num_modes = ATOM_MAX_NUMBEROF_POWER_BLOCK;2118 if (num_modes == 0)2119 return state_index;2120 rdev->pm.power_state = kcalloc(num_modes,2121 sizeof(struct radeon_power_state),2122 GFP_KERNEL);2123 if (!rdev->pm.power_state)2124 return state_index;2125 /* last mode is usually default, array is low to high */2126 for (i = 0; i < num_modes; i++) {2127 /* avoid memory leaks from invalid modes or unknown frev. */2128 if (!rdev->pm.power_state[state_index].clock_info) {2129 rdev->pm.power_state[state_index].clock_info =2130 kzalloc(sizeof(struct radeon_pm_clock_info),2131 GFP_KERNEL);2132 }2133 if (!rdev->pm.power_state[state_index].clock_info)2134 goto out;2135 rdev->pm.power_state[state_index].num_clock_modes = 1;2136 rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE;2137 switch (frev) {2138 case 1:2139 rdev->pm.power_state[state_index].clock_info[0].mclk =2140 le16_to_cpu(power_info->info.asPowerPlayInfo[i].usMemoryClock);2141 rdev->pm.power_state[state_index].clock_info[0].sclk =2142 le16_to_cpu(power_info->info.asPowerPlayInfo[i].usEngineClock);2143 /* skip invalid modes */2144 if ((rdev->pm.power_state[state_index].clock_info[0].mclk == 0) ||2145 (rdev->pm.power_state[state_index].clock_info[0].sclk == 0))2146 continue;2147 rdev->pm.power_state[state_index].pcie_lanes =2148 power_info->info.asPowerPlayInfo[i].ucNumPciELanes;2149 misc = le32_to_cpu(power_info->info.asPowerPlayInfo[i].ulMiscInfo);2150 if ((misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) ||2151 (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH)) {2152 rdev->pm.power_state[state_index].clock_info[0].voltage.type =2153 VOLTAGE_GPIO;2154 rdev->pm.power_state[state_index].clock_info[0].voltage.gpio =2155 radeon_atombios_lookup_gpio(rdev,2156 power_info->info.asPowerPlayInfo[i].ucVoltageDropIndex);2157 if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH)2158 rdev->pm.power_state[state_index].clock_info[0].voltage.active_high =2159 true;2160 else2161 rdev->pm.power_state[state_index].clock_info[0].voltage.active_high =2162 false;2163 } else if (misc & ATOM_PM_MISCINFO_PROGRAM_VOLTAGE) {2164 rdev->pm.power_state[state_index].clock_info[0].voltage.type =2165 VOLTAGE_VDDC;2166 rdev->pm.power_state[state_index].clock_info[0].voltage.vddc_id =2167 power_info->info.asPowerPlayInfo[i].ucVoltageDropIndex;2168 }2169 rdev->pm.power_state[state_index].flags = RADEON_PM_STATE_SINGLE_DISPLAY_ONLY;2170 radeon_atombios_parse_misc_flags_1_3(rdev, state_index, misc, 0);2171 state_index++;2172 break;2173 case 2:2174 rdev->pm.power_state[state_index].clock_info[0].mclk =2175 le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMemoryClock);2176 rdev->pm.power_state[state_index].clock_info[0].sclk =2177 le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulEngineClock);2178 /* skip invalid modes */2179 if ((rdev->pm.power_state[state_index].clock_info[0].mclk == 0) ||2180 (rdev->pm.power_state[state_index].clock_info[0].sclk == 0))2181 continue;2182 rdev->pm.power_state[state_index].pcie_lanes =2183 power_info->info_2.asPowerPlayInfo[i].ucNumPciELanes;2184 misc = le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMiscInfo);2185 misc2 = le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMiscInfo2);2186 if ((misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) ||2187 (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH)) {2188 rdev->pm.power_state[state_index].clock_info[0].voltage.type =2189 VOLTAGE_GPIO;2190 rdev->pm.power_state[state_index].clock_info[0].voltage.gpio =2191 radeon_atombios_lookup_gpio(rdev,2192 power_info->info_2.asPowerPlayInfo[i].ucVoltageDropIndex);2193 if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH)2194 rdev->pm.power_state[state_index].clock_info[0].voltage.active_high =2195 true;2196 else2197 rdev->pm.power_state[state_index].clock_info[0].voltage.active_high =2198 false;2199 } else if (misc & ATOM_PM_MISCINFO_PROGRAM_VOLTAGE) {2200 rdev->pm.power_state[state_index].clock_info[0].voltage.type =2201 VOLTAGE_VDDC;2202 rdev->pm.power_state[state_index].clock_info[0].voltage.vddc_id =2203 power_info->info_2.asPowerPlayInfo[i].ucVoltageDropIndex;2204 }2205 rdev->pm.power_state[state_index].flags = RADEON_PM_STATE_SINGLE_DISPLAY_ONLY;2206 radeon_atombios_parse_misc_flags_1_3(rdev, state_index, misc, misc2);2207 state_index++;2208 break;2209 case 3:2210 rdev->pm.power_state[state_index].clock_info[0].mclk =2211 le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMemoryClock);2212 rdev->pm.power_state[state_index].clock_info[0].sclk =2213 le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulEngineClock);2214 /* skip invalid modes */2215 if ((rdev->pm.power_state[state_index].clock_info[0].mclk == 0) ||2216 (rdev->pm.power_state[state_index].clock_info[0].sclk == 0))2217 continue;2218 rdev->pm.power_state[state_index].pcie_lanes =2219 power_info->info_3.asPowerPlayInfo[i].ucNumPciELanes;2220 misc = le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMiscInfo);2221 misc2 = le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMiscInfo2);2222 if ((misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) ||2223 (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH)) {2224 rdev->pm.power_state[state_index].clock_info[0].voltage.type =2225 VOLTAGE_GPIO;2226 rdev->pm.power_state[state_index].clock_info[0].voltage.gpio =2227 radeon_atombios_lookup_gpio(rdev,2228 power_info->info_3.asPowerPlayInfo[i].ucVoltageDropIndex);2229 if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH)2230 rdev->pm.power_state[state_index].clock_info[0].voltage.active_high =2231 true;2232 else2233 rdev->pm.power_state[state_index].clock_info[0].voltage.active_high =2234 false;2235 } else if (misc & ATOM_PM_MISCINFO_PROGRAM_VOLTAGE) {2236 rdev->pm.power_state[state_index].clock_info[0].voltage.type =2237 VOLTAGE_VDDC;2238 rdev->pm.power_state[state_index].clock_info[0].voltage.vddc_id =2239 power_info->info_3.asPowerPlayInfo[i].ucVoltageDropIndex;2240 if (misc2 & ATOM_PM_MISCINFO2_VDDCI_DYNAMIC_VOLTAGE_EN) {2241 rdev->pm.power_state[state_index].clock_info[0].voltage.vddci_enabled =2242 true;2243 rdev->pm.power_state[state_index].clock_info[0].voltage.vddci_id =2244 power_info->info_3.asPowerPlayInfo[i].ucVDDCI_VoltageDropIndex;2245 }2246 }2247 rdev->pm.power_state[state_index].flags = RADEON_PM_STATE_SINGLE_DISPLAY_ONLY;2248 radeon_atombios_parse_misc_flags_1_3(rdev, state_index, misc, misc2);2249 state_index++;2250 break;2251 }2252 }2253out:2254 /* free any unused clock_info allocation. */2255 if (state_index && state_index < num_modes) {2256 kfree(rdev->pm.power_state[state_index].clock_info);2257 rdev->pm.power_state[state_index].clock_info = NULL;2258 }2259 2260 /* last mode is usually default */2261 if (state_index && rdev->pm.default_power_state_index == -1) {2262 rdev->pm.power_state[state_index - 1].type =2263 POWER_STATE_TYPE_DEFAULT;2264 rdev->pm.default_power_state_index = state_index - 1;2265 rdev->pm.power_state[state_index - 1].default_clock_mode =2266 &rdev->pm.power_state[state_index - 1].clock_info[0];2267 rdev->pm.power_state[state_index - 1].flags &=2268 ~RADEON_PM_STATE_SINGLE_DISPLAY_ONLY;2269 rdev->pm.power_state[state_index - 1].misc = 0;2270 rdev->pm.power_state[state_index - 1].misc2 = 0;2271 }2272 return state_index;2273}2274 2275static void radeon_atombios_add_pplib_thermal_controller(struct radeon_device *rdev,2276 ATOM_PPLIB_THERMALCONTROLLER *controller)2277{2278 struct radeon_i2c_bus_rec i2c_bus;2279 2280 /* add the i2c bus for thermal/fan chip */2281 if (controller->ucType > 0) {2282 if (controller->ucFanParameters & ATOM_PP_FANPARAMETERS_NOFAN)2283 rdev->pm.no_fan = true;2284 rdev->pm.fan_pulses_per_revolution =2285 controller->ucFanParameters & ATOM_PP_FANPARAMETERS_TACHOMETER_PULSES_PER_REVOLUTION_MASK;2286 if (rdev->pm.fan_pulses_per_revolution) {2287 rdev->pm.fan_min_rpm = controller->ucFanMinRPM;2288 rdev->pm.fan_max_rpm = controller->ucFanMaxRPM;2289 }2290 if (controller->ucType == ATOM_PP_THERMALCONTROLLER_RV6xx) {2291 DRM_INFO("Internal thermal controller %s fan control\n",2292 (controller->ucFanParameters &2293 ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");2294 rdev->pm.int_thermal_type = THERMAL_TYPE_RV6XX;2295 } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_RV770) {2296 DRM_INFO("Internal thermal controller %s fan control\n",2297 (controller->ucFanParameters &2298 ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");2299 rdev->pm.int_thermal_type = THERMAL_TYPE_RV770;2300 } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_EVERGREEN) {2301 DRM_INFO("Internal thermal controller %s fan control\n",2302 (controller->ucFanParameters &2303 ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");2304 rdev->pm.int_thermal_type = THERMAL_TYPE_EVERGREEN;2305 } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_SUMO) {2306 DRM_INFO("Internal thermal controller %s fan control\n",2307 (controller->ucFanParameters &2308 ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");2309 rdev->pm.int_thermal_type = THERMAL_TYPE_SUMO;2310 } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_NISLANDS) {2311 DRM_INFO("Internal thermal controller %s fan control\n",2312 (controller->ucFanParameters &2313 ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");2314 rdev->pm.int_thermal_type = THERMAL_TYPE_NI;2315 } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_SISLANDS) {2316 DRM_INFO("Internal thermal controller %s fan control\n",2317 (controller->ucFanParameters &2318 ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");2319 rdev->pm.int_thermal_type = THERMAL_TYPE_SI;2320 } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_CISLANDS) {2321 DRM_INFO("Internal thermal controller %s fan control\n",2322 (controller->ucFanParameters &2323 ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");2324 rdev->pm.int_thermal_type = THERMAL_TYPE_CI;2325 } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_KAVERI) {2326 DRM_INFO("Internal thermal controller %s fan control\n",2327 (controller->ucFanParameters &2328 ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");2329 rdev->pm.int_thermal_type = THERMAL_TYPE_KV;2330 } else if (controller->ucType ==2331 ATOM_PP_THERMALCONTROLLER_EXTERNAL_GPIO) {2332 DRM_INFO("External GPIO thermal controller %s fan control\n",2333 (controller->ucFanParameters &2334 ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");2335 rdev->pm.int_thermal_type = THERMAL_TYPE_EXTERNAL_GPIO;2336 } else if (controller->ucType ==2337 ATOM_PP_THERMALCONTROLLER_ADT7473_WITH_INTERNAL) {2338 DRM_INFO("ADT7473 with internal thermal controller %s fan control\n",2339 (controller->ucFanParameters &2340 ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");2341 rdev->pm.int_thermal_type = THERMAL_TYPE_ADT7473_WITH_INTERNAL;2342 } else if (controller->ucType ==2343 ATOM_PP_THERMALCONTROLLER_EMC2103_WITH_INTERNAL) {2344 DRM_INFO("EMC2103 with internal thermal controller %s fan control\n",2345 (controller->ucFanParameters &2346 ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");2347 rdev->pm.int_thermal_type = THERMAL_TYPE_EMC2103_WITH_INTERNAL;2348 } else if (controller->ucType < ARRAY_SIZE(pp_lib_thermal_controller_names)) {2349 DRM_INFO("Possible %s thermal controller at 0x%02x %s fan control\n",2350 pp_lib_thermal_controller_names[controller->ucType],2351 controller->ucI2cAddress >> 1,2352 (controller->ucFanParameters &2353 ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");2354 rdev->pm.int_thermal_type = THERMAL_TYPE_EXTERNAL;2355 i2c_bus = radeon_lookup_i2c_gpio(rdev, controller->ucI2cLine);2356 rdev->pm.i2c_bus = radeon_i2c_lookup(rdev, &i2c_bus);2357 if (rdev->pm.i2c_bus) {2358 struct i2c_board_info info = { };2359 const char *name = pp_lib_thermal_controller_names[controller->ucType];2360 info.addr = controller->ucI2cAddress >> 1;2361 strscpy(info.type, name, sizeof(info.type));2362 i2c_new_client_device(&rdev->pm.i2c_bus->adapter, &info);2363 }2364 } else {2365 DRM_INFO("Unknown thermal controller type %d at 0x%02x %s fan control\n",2366 controller->ucType,2367 controller->ucI2cAddress >> 1,2368 (controller->ucFanParameters &2369 ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");2370 }2371 }2372}2373 2374void radeon_atombios_get_default_voltages(struct radeon_device *rdev,2375 u16 *vddc, u16 *vddci, u16 *mvdd)2376{2377 struct radeon_mode_info *mode_info = &rdev->mode_info;2378 int index = GetIndexIntoMasterTable(DATA, FirmwareInfo);2379 u8 frev, crev;2380 u16 data_offset;2381 union firmware_info *firmware_info;2382 2383 *vddc = 0;2384 *vddci = 0;2385 *mvdd = 0;2386 2387 if (atom_parse_data_header(mode_info->atom_context, index, NULL,2388 &frev, &crev, &data_offset)) {2389 firmware_info =2390 (union firmware_info *)(mode_info->atom_context->bios +2391 data_offset);2392 *vddc = le16_to_cpu(firmware_info->info_14.usBootUpVDDCVoltage);2393 if ((frev == 2) && (crev >= 2)) {2394 *vddci = le16_to_cpu(firmware_info->info_22.usBootUpVDDCIVoltage);2395 *mvdd = le16_to_cpu(firmware_info->info_22.usBootUpMVDDCVoltage);2396 }2397 }2398}2399 2400static void radeon_atombios_parse_pplib_non_clock_info(struct radeon_device *rdev,2401 int state_index, int mode_index,2402 struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info)2403{2404 int j;2405 u32 misc = le32_to_cpu(non_clock_info->ulCapsAndSettings);2406 u32 misc2 = le16_to_cpu(non_clock_info->usClassification);2407 u16 vddc, vddci, mvdd;2408 2409 radeon_atombios_get_default_voltages(rdev, &vddc, &vddci, &mvdd);2410 2411 rdev->pm.power_state[state_index].misc = misc;2412 rdev->pm.power_state[state_index].misc2 = misc2;2413 rdev->pm.power_state[state_index].pcie_lanes =2414 ((misc & ATOM_PPLIB_PCIE_LINK_WIDTH_MASK) >>2415 ATOM_PPLIB_PCIE_LINK_WIDTH_SHIFT) + 1;2416 switch (misc2 & ATOM_PPLIB_CLASSIFICATION_UI_MASK) {2417 case ATOM_PPLIB_CLASSIFICATION_UI_BATTERY:2418 rdev->pm.power_state[state_index].type =2419 POWER_STATE_TYPE_BATTERY;2420 break;2421 case ATOM_PPLIB_CLASSIFICATION_UI_BALANCED:2422 rdev->pm.power_state[state_index].type =2423 POWER_STATE_TYPE_BALANCED;2424 break;2425 case ATOM_PPLIB_CLASSIFICATION_UI_PERFORMANCE:2426 rdev->pm.power_state[state_index].type =2427 POWER_STATE_TYPE_PERFORMANCE;2428 break;2429 case ATOM_PPLIB_CLASSIFICATION_UI_NONE:2430 if (misc2 & ATOM_PPLIB_CLASSIFICATION_3DPERFORMANCE)2431 rdev->pm.power_state[state_index].type =2432 POWER_STATE_TYPE_PERFORMANCE;2433 break;2434 }2435 rdev->pm.power_state[state_index].flags = 0;2436 if (misc & ATOM_PPLIB_SINGLE_DISPLAY_ONLY)2437 rdev->pm.power_state[state_index].flags |=2438 RADEON_PM_STATE_SINGLE_DISPLAY_ONLY;2439 if (misc2 & ATOM_PPLIB_CLASSIFICATION_BOOT) {2440 rdev->pm.power_state[state_index].type =2441 POWER_STATE_TYPE_DEFAULT;2442 rdev->pm.default_power_state_index = state_index;2443 rdev->pm.power_state[state_index].default_clock_mode =2444 &rdev->pm.power_state[state_index].clock_info[mode_index - 1];2445 if ((rdev->family >= CHIP_BARTS) && !(rdev->flags & RADEON_IS_IGP)) {2446 /* NI chips post without MC ucode, so default clocks are strobe mode only */2447 rdev->pm.default_sclk = rdev->pm.power_state[state_index].clock_info[0].sclk;2448 rdev->pm.default_mclk = rdev->pm.power_state[state_index].clock_info[0].mclk;2449 rdev->pm.default_vddc = rdev->pm.power_state[state_index].clock_info[0].voltage.voltage;2450 rdev->pm.default_vddci = rdev->pm.power_state[state_index].clock_info[0].voltage.vddci;2451 } else {2452 u16 max_vddci = 0;2453 2454 if (ASIC_IS_DCE4(rdev))2455 radeon_atom_get_max_voltage(rdev,2456 SET_VOLTAGE_TYPE_ASIC_VDDCI,2457 &max_vddci);2458 /* patch the table values with the default sclk/mclk from firmware info */2459 for (j = 0; j < mode_index; j++) {2460 rdev->pm.power_state[state_index].clock_info[j].mclk =2461 rdev->clock.default_mclk;2462 rdev->pm.power_state[state_index].clock_info[j].sclk =2463 rdev->clock.default_sclk;2464 if (vddc)2465 rdev->pm.power_state[state_index].clock_info[j].voltage.voltage =2466 vddc;2467 if (max_vddci)2468 rdev->pm.power_state[state_index].clock_info[j].voltage.vddci =2469 max_vddci;2470 }2471 }2472 }2473}2474 2475static bool radeon_atombios_parse_pplib_clock_info(struct radeon_device *rdev,2476 int state_index, int mode_index,2477 union pplib_clock_info *clock_info)2478{2479 u32 sclk, mclk;2480 u16 vddc;2481 2482 if (rdev->flags & RADEON_IS_IGP) {2483 if (rdev->family >= CHIP_PALM) {2484 sclk = le16_to_cpu(clock_info->sumo.usEngineClockLow);2485 sclk |= clock_info->sumo.ucEngineClockHigh << 16;2486 rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk;2487 } else {2488 sclk = le16_to_cpu(clock_info->rs780.usLowEngineClockLow);2489 sclk |= clock_info->rs780.ucLowEngineClockHigh << 16;2490 rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk;2491 }2492 } else if (rdev->family >= CHIP_BONAIRE) {2493 sclk = le16_to_cpu(clock_info->ci.usEngineClockLow);2494 sclk |= clock_info->ci.ucEngineClockHigh << 16;2495 mclk = le16_to_cpu(clock_info->ci.usMemoryClockLow);2496 mclk |= clock_info->ci.ucMemoryClockHigh << 16;2497 rdev->pm.power_state[state_index].clock_info[mode_index].mclk = mclk;2498 rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk;2499 rdev->pm.power_state[state_index].clock_info[mode_index].voltage.type =2500 VOLTAGE_NONE;2501 } else if (rdev->family >= CHIP_TAHITI) {2502 sclk = le16_to_cpu(clock_info->si.usEngineClockLow);2503 sclk |= clock_info->si.ucEngineClockHigh << 16;2504 mclk = le16_to_cpu(clock_info->si.usMemoryClockLow);2505 mclk |= clock_info->si.ucMemoryClockHigh << 16;2506 rdev->pm.power_state[state_index].clock_info[mode_index].mclk = mclk;2507 rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk;2508 rdev->pm.power_state[state_index].clock_info[mode_index].voltage.type =2509 VOLTAGE_SW;2510 rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage =2511 le16_to_cpu(clock_info->si.usVDDC);2512 rdev->pm.power_state[state_index].clock_info[mode_index].voltage.vddci =2513 le16_to_cpu(clock_info->si.usVDDCI);2514 } else if (rdev->family >= CHIP_CEDAR) {2515 sclk = le16_to_cpu(clock_info->evergreen.usEngineClockLow);2516 sclk |= clock_info->evergreen.ucEngineClockHigh << 16;2517 mclk = le16_to_cpu(clock_info->evergreen.usMemoryClockLow);2518 mclk |= clock_info->evergreen.ucMemoryClockHigh << 16;2519 rdev->pm.power_state[state_index].clock_info[mode_index].mclk = mclk;2520 rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk;2521 rdev->pm.power_state[state_index].clock_info[mode_index].voltage.type =2522 VOLTAGE_SW;2523 rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage =2524 le16_to_cpu(clock_info->evergreen.usVDDC);2525 rdev->pm.power_state[state_index].clock_info[mode_index].voltage.vddci =2526 le16_to_cpu(clock_info->evergreen.usVDDCI);2527 } else {2528 sclk = le16_to_cpu(clock_info->r600.usEngineClockLow);2529 sclk |= clock_info->r600.ucEngineClockHigh << 16;2530 mclk = le16_to_cpu(clock_info->r600.usMemoryClockLow);2531 mclk |= clock_info->r600.ucMemoryClockHigh << 16;2532 rdev->pm.power_state[state_index].clock_info[mode_index].mclk = mclk;2533 rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk;2534 rdev->pm.power_state[state_index].clock_info[mode_index].voltage.type =2535 VOLTAGE_SW;2536 rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage =2537 le16_to_cpu(clock_info->r600.usVDDC);2538 }2539 2540 /* patch up vddc if necessary */2541 switch (rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage) {2542 case ATOM_VIRTUAL_VOLTAGE_ID0:2543 case ATOM_VIRTUAL_VOLTAGE_ID1:2544 case ATOM_VIRTUAL_VOLTAGE_ID2:2545 case ATOM_VIRTUAL_VOLTAGE_ID3:2546 case ATOM_VIRTUAL_VOLTAGE_ID4:2547 case ATOM_VIRTUAL_VOLTAGE_ID5:2548 case ATOM_VIRTUAL_VOLTAGE_ID6:2549 case ATOM_VIRTUAL_VOLTAGE_ID7:2550 if (radeon_atom_get_max_vddc(rdev, VOLTAGE_TYPE_VDDC,2551 rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage,2552 &vddc) == 0)2553 rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage = vddc;2554 break;2555 default:2556 break;2557 }2558 2559 if (rdev->flags & RADEON_IS_IGP) {2560 /* skip invalid modes */2561 if (rdev->pm.power_state[state_index].clock_info[mode_index].sclk == 0)2562 return false;2563 } else {2564 /* skip invalid modes */2565 if ((rdev->pm.power_state[state_index].clock_info[mode_index].mclk == 0) ||2566 (rdev->pm.power_state[state_index].clock_info[mode_index].sclk == 0))2567 return false;2568 }2569 return true;2570}2571 2572static int radeon_atombios_parse_power_table_4_5(struct radeon_device *rdev)2573{2574 struct radeon_mode_info *mode_info = &rdev->mode_info;2575 struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info;2576 union pplib_power_state *power_state;2577 int i, j;2578 int state_index = 0, mode_index = 0;2579 union pplib_clock_info *clock_info;2580 bool valid;2581 union power_info *power_info;2582 int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo);2583 u16 data_offset;2584 u8 frev, crev;2585 2586 if (!atom_parse_data_header(mode_info->atom_context, index, NULL,2587 &frev, &crev, &data_offset))2588 return state_index;2589 power_info = (union power_info *)(mode_info->atom_context->bios + data_offset);2590 2591 radeon_atombios_add_pplib_thermal_controller(rdev, &power_info->pplib.sThermalController);2592 if (power_info->pplib.ucNumStates == 0)2593 return state_index;2594 rdev->pm.power_state = kcalloc(power_info->pplib.ucNumStates,2595 sizeof(struct radeon_power_state),2596 GFP_KERNEL);2597 if (!rdev->pm.power_state)2598 return state_index;2599 /* first mode is usually default, followed by low to high */2600 for (i = 0; i < power_info->pplib.ucNumStates; i++) {2601 mode_index = 0;2602 power_state = (union pplib_power_state *)2603 (mode_info->atom_context->bios + data_offset +2604 le16_to_cpu(power_info->pplib.usStateArrayOffset) +2605 i * power_info->pplib.ucStateEntrySize);2606 non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *)2607 (mode_info->atom_context->bios + data_offset +2608 le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset) +2609 (power_state->v1.ucNonClockStateIndex *2610 power_info->pplib.ucNonClockSize));2611 rdev->pm.power_state[i].clock_info =2612 kcalloc((power_info->pplib.ucStateEntrySize - 1) ?2613 (power_info->pplib.ucStateEntrySize - 1) : 1,2614 sizeof(struct radeon_pm_clock_info),2615 GFP_KERNEL);2616 if (!rdev->pm.power_state[i].clock_info)2617 return state_index;2618 if (power_info->pplib.ucStateEntrySize - 1) {2619 for (j = 0; j < (power_info->pplib.ucStateEntrySize - 1); j++) {2620 clock_info = (union pplib_clock_info *)2621 (mode_info->atom_context->bios + data_offset +2622 le16_to_cpu(power_info->pplib.usClockInfoArrayOffset) +2623 (power_state->v1.ucClockStateIndices[j] *2624 power_info->pplib.ucClockInfoSize));2625 valid = radeon_atombios_parse_pplib_clock_info(rdev,2626 state_index, mode_index,2627 clock_info);2628 if (valid)2629 mode_index++;2630 }2631 } else {2632 rdev->pm.power_state[state_index].clock_info[0].mclk =2633 rdev->clock.default_mclk;2634 rdev->pm.power_state[state_index].clock_info[0].sclk =2635 rdev->clock.default_sclk;2636 mode_index++;2637 }2638 rdev->pm.power_state[state_index].num_clock_modes = mode_index;2639 if (mode_index) {2640 radeon_atombios_parse_pplib_non_clock_info(rdev, state_index, mode_index,2641 non_clock_info);2642 state_index++;2643 }2644 }2645 /* if multiple clock modes, mark the lowest as no display */2646 for (i = 0; i < state_index; i++) {2647 if (rdev->pm.power_state[i].num_clock_modes > 1)2648 rdev->pm.power_state[i].clock_info[0].flags |=2649 RADEON_PM_MODE_NO_DISPLAY;2650 }2651 /* first mode is usually default */2652 if (rdev->pm.default_power_state_index == -1) {2653 rdev->pm.power_state[0].type =2654 POWER_STATE_TYPE_DEFAULT;2655 rdev->pm.default_power_state_index = 0;2656 rdev->pm.power_state[0].default_clock_mode =2657 &rdev->pm.power_state[0].clock_info[0];2658 }2659 return state_index;2660}2661 2662static int radeon_atombios_parse_power_table_6(struct radeon_device *rdev)2663{2664 struct radeon_mode_info *mode_info = &rdev->mode_info;2665 struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info;2666 union pplib_power_state *power_state;2667 int i, j, non_clock_array_index, clock_array_index;2668 int state_index = 0, mode_index = 0;2669 union pplib_clock_info *clock_info;2670 struct _StateArray *state_array;2671 struct _ClockInfoArray *clock_info_array;2672 struct _NonClockInfoArray *non_clock_info_array;2673 bool valid;2674 union power_info *power_info;2675 int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo);2676 u16 data_offset;2677 u8 frev, crev;2678 u8 *power_state_offset;2679 2680 if (!atom_parse_data_header(mode_info->atom_context, index, NULL,2681 &frev, &crev, &data_offset))2682 return state_index;2683 power_info = (union power_info *)(mode_info->atom_context->bios + data_offset);2684 2685 radeon_atombios_add_pplib_thermal_controller(rdev, &power_info->pplib.sThermalController);2686 state_array = (struct _StateArray *)2687 (mode_info->atom_context->bios + data_offset +2688 le16_to_cpu(power_info->pplib.usStateArrayOffset));2689 clock_info_array = (struct _ClockInfoArray *)2690 (mode_info->atom_context->bios + data_offset +2691 le16_to_cpu(power_info->pplib.usClockInfoArrayOffset));2692 non_clock_info_array = (struct _NonClockInfoArray *)2693 (mode_info->atom_context->bios + data_offset +2694 le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset));2695 if (state_array->ucNumEntries == 0)2696 return state_index;2697 rdev->pm.power_state = kcalloc(state_array->ucNumEntries,2698 sizeof(struct radeon_power_state),2699 GFP_KERNEL);2700 if (!rdev->pm.power_state)2701 return state_index;2702 power_state_offset = (u8 *)state_array->states;2703 for (i = 0; i < state_array->ucNumEntries; i++) {2704 mode_index = 0;2705 power_state = (union pplib_power_state *)power_state_offset;2706 non_clock_array_index = power_state->v2.nonClockInfoIndex;2707 non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *)2708 &non_clock_info_array->nonClockInfo[non_clock_array_index];2709 rdev->pm.power_state[i].clock_info =2710 kcalloc(power_state->v2.ucNumDPMLevels ?2711 power_state->v2.ucNumDPMLevels : 1,2712 sizeof(struct radeon_pm_clock_info),2713 GFP_KERNEL);2714 if (!rdev->pm.power_state[i].clock_info)2715 return state_index;2716 if (power_state->v2.ucNumDPMLevels) {2717 for (j = 0; j < power_state->v2.ucNumDPMLevels; j++) {2718 clock_array_index = power_state->v2.clockInfoIndex[j];2719 clock_info = (union pplib_clock_info *)2720 &clock_info_array->clockInfo[clock_array_index * clock_info_array->ucEntrySize];2721 valid = radeon_atombios_parse_pplib_clock_info(rdev,2722 state_index, mode_index,2723 clock_info);2724 if (valid)2725 mode_index++;2726 }2727 } else {2728 rdev->pm.power_state[state_index].clock_info[0].mclk =2729 rdev->clock.default_mclk;2730 rdev->pm.power_state[state_index].clock_info[0].sclk =2731 rdev->clock.default_sclk;2732 mode_index++;2733 }2734 rdev->pm.power_state[state_index].num_clock_modes = mode_index;2735 if (mode_index) {2736 radeon_atombios_parse_pplib_non_clock_info(rdev, state_index, mode_index,2737 non_clock_info);2738 state_index++;2739 }2740 power_state_offset += 2 + power_state->v2.ucNumDPMLevels;2741 }2742 /* if multiple clock modes, mark the lowest as no display */2743 for (i = 0; i < state_index; i++) {2744 if (rdev->pm.power_state[i].num_clock_modes > 1)2745 rdev->pm.power_state[i].clock_info[0].flags |=2746 RADEON_PM_MODE_NO_DISPLAY;2747 }2748 /* first mode is usually default */2749 if (rdev->pm.default_power_state_index == -1) {2750 rdev->pm.power_state[0].type =2751 POWER_STATE_TYPE_DEFAULT;2752 rdev->pm.default_power_state_index = 0;2753 rdev->pm.power_state[0].default_clock_mode =2754 &rdev->pm.power_state[0].clock_info[0];2755 }2756 return state_index;2757}2758 2759void radeon_atombios_get_power_modes(struct radeon_device *rdev)2760{2761 struct radeon_mode_info *mode_info = &rdev->mode_info;2762 int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo);2763 u16 data_offset;2764 u8 frev, crev;2765 int state_index = 0;2766 2767 rdev->pm.default_power_state_index = -1;2768 2769 if (atom_parse_data_header(mode_info->atom_context, index, NULL,2770 &frev, &crev, &data_offset)) {2771 switch (frev) {2772 case 1:2773 case 2:2774 case 3:2775 state_index = radeon_atombios_parse_power_table_1_3(rdev);2776 break;2777 case 4:2778 case 5:2779 state_index = radeon_atombios_parse_power_table_4_5(rdev);2780 break;2781 case 6:2782 state_index = radeon_atombios_parse_power_table_6(rdev);2783 break;2784 default:2785 break;2786 }2787 }2788 2789 if (state_index == 0) {2790 rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state), GFP_KERNEL);2791 if (rdev->pm.power_state) {2792 rdev->pm.power_state[0].clock_info =2793 kcalloc(1,2794 sizeof(struct radeon_pm_clock_info),2795 GFP_KERNEL);2796 if (rdev->pm.power_state[0].clock_info) {2797 /* add the default mode */2798 rdev->pm.power_state[state_index].type =2799 POWER_STATE_TYPE_DEFAULT;2800 rdev->pm.power_state[state_index].num_clock_modes = 1;2801 rdev->pm.power_state[state_index].clock_info[0].mclk = rdev->clock.default_mclk;2802 rdev->pm.power_state[state_index].clock_info[0].sclk = rdev->clock.default_sclk;2803 rdev->pm.power_state[state_index].default_clock_mode =2804 &rdev->pm.power_state[state_index].clock_info[0];2805 rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE;2806 rdev->pm.power_state[state_index].pcie_lanes = 16;2807 rdev->pm.default_power_state_index = state_index;2808 rdev->pm.power_state[state_index].flags = 0;2809 state_index++;2810 }2811 }2812 }2813 2814 rdev->pm.num_power_states = state_index;2815 2816 rdev->pm.current_power_state_index = rdev->pm.default_power_state_index;2817 rdev->pm.current_clock_mode_index = 0;2818 if (rdev->pm.default_power_state_index >= 0)2819 rdev->pm.current_vddc =2820 rdev->pm.power_state[rdev->pm.default_power_state_index].clock_info[0].voltage.voltage;2821 else2822 rdev->pm.current_vddc = 0;2823}2824 2825union get_clock_dividers {2826 struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS v1;2827 struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V2 v2;2828 struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V3 v3;2829 struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V4 v4;2830 struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V5 v5;2831 struct _COMPUTE_GPU_CLOCK_INPUT_PARAMETERS_V1_6 v6_in;2832 struct _COMPUTE_GPU_CLOCK_OUTPUT_PARAMETERS_V1_6 v6_out;2833};2834 2835int radeon_atom_get_clock_dividers(struct radeon_device *rdev,2836 u8 clock_type,2837 u32 clock,2838 bool strobe_mode,2839 struct atom_clock_dividers *dividers)2840{2841 union get_clock_dividers args;2842 int index = GetIndexIntoMasterTable(COMMAND, ComputeMemoryEnginePLL);2843 u8 frev, crev;2844 2845 memset(&args, 0, sizeof(args));2846 memset(dividers, 0, sizeof(struct atom_clock_dividers));2847 2848 if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))2849 return -EINVAL;2850 2851 switch (crev) {2852 case 1:2853 /* r4xx, r5xx */2854 args.v1.ucAction = clock_type;2855 args.v1.ulClock = cpu_to_le32(clock); /* 10 khz */2856 2857 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args, sizeof(args));2858 2859 dividers->post_div = args.v1.ucPostDiv;2860 dividers->fb_div = args.v1.ucFbDiv;2861 dividers->enable_post_div = true;2862 break;2863 case 2:2864 case 3:2865 case 5:2866 /* r6xx, r7xx, evergreen, ni, si */2867 if (rdev->family <= CHIP_RV770) {2868 args.v2.ucAction = clock_type;2869 args.v2.ulClock = cpu_to_le32(clock); /* 10 khz */2870 2871 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args, sizeof(args));2872 2873 dividers->post_div = args.v2.ucPostDiv;2874 dividers->fb_div = le16_to_cpu(args.v2.usFbDiv);2875 dividers->ref_div = args.v2.ucAction;2876 if (rdev->family == CHIP_RV770) {2877 dividers->enable_post_div = (le32_to_cpu(args.v2.ulClock) & (1 << 24)) ?2878 true : false;2879 dividers->vco_mode = (le32_to_cpu(args.v2.ulClock) & (1 << 25)) ? 1 : 0;2880 } else2881 dividers->enable_post_div = (dividers->fb_div & 1) ? true : false;2882 } else {2883 if (clock_type == COMPUTE_ENGINE_PLL_PARAM) {2884 args.v3.ulClockParams = cpu_to_le32((clock_type << 24) | clock);2885 2886 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args, sizeof(args));2887 2888 dividers->post_div = args.v3.ucPostDiv;2889 dividers->enable_post_div = (args.v3.ucCntlFlag &2890 ATOM_PLL_CNTL_FLAG_PLL_POST_DIV_EN) ? true : false;2891 dividers->enable_dithen = (args.v3.ucCntlFlag &2892 ATOM_PLL_CNTL_FLAG_FRACTION_DISABLE) ? false : true;2893 dividers->whole_fb_div = le16_to_cpu(args.v3.ulFbDiv.usFbDiv);2894 dividers->frac_fb_div = le16_to_cpu(args.v3.ulFbDiv.usFbDivFrac);2895 dividers->ref_div = args.v3.ucRefDiv;2896 dividers->vco_mode = (args.v3.ucCntlFlag &2897 ATOM_PLL_CNTL_FLAG_MPLL_VCO_MODE) ? 1 : 0;2898 } else {2899 /* for SI we use ComputeMemoryClockParam for memory plls */2900 if (rdev->family >= CHIP_TAHITI)2901 return -EINVAL;2902 args.v5.ulClockParams = cpu_to_le32((clock_type << 24) | clock);2903 if (strobe_mode)2904 args.v5.ucInputFlag = ATOM_PLL_INPUT_FLAG_PLL_STROBE_MODE_EN;2905 2906 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args, sizeof(args));2907 2908 dividers->post_div = args.v5.ucPostDiv;2909 dividers->enable_post_div = (args.v5.ucCntlFlag &2910 ATOM_PLL_CNTL_FLAG_PLL_POST_DIV_EN) ? true : false;2911 dividers->enable_dithen = (args.v5.ucCntlFlag &2912 ATOM_PLL_CNTL_FLAG_FRACTION_DISABLE) ? false : true;2913 dividers->whole_fb_div = le16_to_cpu(args.v5.ulFbDiv.usFbDiv);2914 dividers->frac_fb_div = le16_to_cpu(args.v5.ulFbDiv.usFbDivFrac);2915 dividers->ref_div = args.v5.ucRefDiv;2916 dividers->vco_mode = (args.v5.ucCntlFlag &2917 ATOM_PLL_CNTL_FLAG_MPLL_VCO_MODE) ? 1 : 0;2918 }2919 }2920 break;2921 case 4:2922 /* fusion */2923 args.v4.ulClock = cpu_to_le32(clock); /* 10 khz */2924 2925 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args, sizeof(args));2926 2927 dividers->post_divider = dividers->post_div = args.v4.ucPostDiv;2928 dividers->real_clock = le32_to_cpu(args.v4.ulClock);2929 break;2930 case 6:2931 /* CI */2932 /* COMPUTE_GPUCLK_INPUT_FLAG_DEFAULT_GPUCLK, COMPUTE_GPUCLK_INPUT_FLAG_SCLK */2933 args.v6_in.ulClock.ulComputeClockFlag = clock_type;2934 args.v6_in.ulClock.ulClockFreq = cpu_to_le32(clock); /* 10 khz */2935 2936 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args, sizeof(args));2937 2938 dividers->whole_fb_div = le16_to_cpu(args.v6_out.ulFbDiv.usFbDiv);2939 dividers->frac_fb_div = le16_to_cpu(args.v6_out.ulFbDiv.usFbDivFrac);2940 dividers->ref_div = args.v6_out.ucPllRefDiv;2941 dividers->post_div = args.v6_out.ucPllPostDiv;2942 dividers->flags = args.v6_out.ucPllCntlFlag;2943 dividers->real_clock = le32_to_cpu(args.v6_out.ulClock.ulClock);2944 dividers->post_divider = args.v6_out.ulClock.ucPostDiv;2945 break;2946 default:2947 return -EINVAL;2948 }2949 return 0;2950}2951 2952int radeon_atom_get_memory_pll_dividers(struct radeon_device *rdev,2953 u32 clock,2954 bool strobe_mode,2955 struct atom_mpll_param *mpll_param)2956{2957 COMPUTE_MEMORY_CLOCK_PARAM_PARAMETERS_V2_1 args;2958 int index = GetIndexIntoMasterTable(COMMAND, ComputeMemoryClockParam);2959 u8 frev, crev;2960 2961 memset(&args, 0, sizeof(args));2962 memset(mpll_param, 0, sizeof(struct atom_mpll_param));2963 2964 if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))2965 return -EINVAL;2966 2967 switch (frev) {2968 case 2:2969 switch (crev) {2970 case 1:2971 /* SI */2972 args.ulClock = cpu_to_le32(clock); /* 10 khz */2973 args.ucInputFlag = 0;2974 if (strobe_mode)2975 args.ucInputFlag |= MPLL_INPUT_FLAG_STROBE_MODE_EN;2976 2977 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args, sizeof(args));2978 2979 mpll_param->clkfrac = le16_to_cpu(args.ulFbDiv.usFbDivFrac);2980 mpll_param->clkf = le16_to_cpu(args.ulFbDiv.usFbDiv);2981 mpll_param->post_div = args.ucPostDiv;2982 mpll_param->dll_speed = args.ucDllSpeed;2983 mpll_param->bwcntl = args.ucBWCntl;2984 mpll_param->vco_mode =2985 (args.ucPllCntlFlag & MPLL_CNTL_FLAG_VCO_MODE_MASK);2986 mpll_param->yclk_sel =2987 (args.ucPllCntlFlag & MPLL_CNTL_FLAG_BYPASS_DQ_PLL) ? 1 : 0;2988 mpll_param->qdr =2989 (args.ucPllCntlFlag & MPLL_CNTL_FLAG_QDR_ENABLE) ? 1 : 0;2990 mpll_param->half_rate =2991 (args.ucPllCntlFlag & MPLL_CNTL_FLAG_AD_HALF_RATE) ? 1 : 0;2992 break;2993 default:2994 return -EINVAL;2995 }2996 break;2997 default:2998 return -EINVAL;2999 }3000 return 0;3001}3002 3003void radeon_atom_set_clock_gating(struct radeon_device *rdev, int enable)3004{3005 DYNAMIC_CLOCK_GATING_PS_ALLOCATION args;3006 int index = GetIndexIntoMasterTable(COMMAND, DynamicClockGating);3007 3008 args.ucEnable = enable;3009 3010 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args, sizeof(args));3011}3012 3013uint32_t radeon_atom_get_engine_clock(struct radeon_device *rdev)3014{3015 GET_ENGINE_CLOCK_PS_ALLOCATION args;3016 int index = GetIndexIntoMasterTable(COMMAND, GetEngineClock);3017 3018 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args, sizeof(args));3019 return le32_to_cpu(args.ulReturnEngineClock);3020}3021 3022uint32_t radeon_atom_get_memory_clock(struct radeon_device *rdev)3023{3024 GET_MEMORY_CLOCK_PS_ALLOCATION args;3025 int index = GetIndexIntoMasterTable(COMMAND, GetMemoryClock);3026 3027 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args, sizeof(args));3028 return le32_to_cpu(args.ulReturnMemoryClock);3029}3030 3031void radeon_atom_set_engine_clock(struct radeon_device *rdev,3032 uint32_t eng_clock)3033{3034 SET_ENGINE_CLOCK_PS_ALLOCATION args;3035 int index = GetIndexIntoMasterTable(COMMAND, SetEngineClock);3036 3037 args.ulTargetEngineClock = cpu_to_le32(eng_clock); /* 10 khz */3038 3039 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args, sizeof(args));3040}3041 3042void radeon_atom_set_memory_clock(struct radeon_device *rdev,3043 uint32_t mem_clock)3044{3045 SET_MEMORY_CLOCK_PS_ALLOCATION args;3046 int index = GetIndexIntoMasterTable(COMMAND, SetMemoryClock);3047 3048 if (rdev->flags & RADEON_IS_IGP)3049 return;3050 3051 args.ulTargetMemoryClock = cpu_to_le32(mem_clock); /* 10 khz */3052 3053 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args, sizeof(args));3054}3055 3056void radeon_atom_set_engine_dram_timings(struct radeon_device *rdev,3057 u32 eng_clock, u32 mem_clock)3058{3059 SET_ENGINE_CLOCK_PS_ALLOCATION args;3060 int index = GetIndexIntoMasterTable(COMMAND, DynamicMemorySettings);3061 u32 tmp;3062 3063 memset(&args, 0, sizeof(args));3064 3065 tmp = eng_clock & SET_CLOCK_FREQ_MASK;3066 tmp |= (COMPUTE_ENGINE_PLL_PARAM << 24);3067 3068 args.ulTargetEngineClock = cpu_to_le32(tmp);3069 if (mem_clock)3070 args.sReserved.ulClock = cpu_to_le32(mem_clock & SET_CLOCK_FREQ_MASK);3071 3072 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args, sizeof(args));3073}3074 3075void radeon_atom_update_memory_dll(struct radeon_device *rdev,3076 u32 mem_clock)3077{3078 u32 args;3079 int index = GetIndexIntoMasterTable(COMMAND, DynamicMemorySettings);3080 3081 args = cpu_to_le32(mem_clock); /* 10 khz */3082 3083 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args, sizeof(args));3084}3085 3086void radeon_atom_set_ac_timing(struct radeon_device *rdev,3087 u32 mem_clock)3088{3089 SET_MEMORY_CLOCK_PS_ALLOCATION args;3090 int index = GetIndexIntoMasterTable(COMMAND, DynamicMemorySettings);3091 u32 tmp = mem_clock | (COMPUTE_MEMORY_PLL_PARAM << 24);3092 3093 args.ulTargetMemoryClock = cpu_to_le32(tmp); /* 10 khz */3094 3095 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args, sizeof(args));3096}3097 3098union set_voltage {3099 struct _SET_VOLTAGE_PS_ALLOCATION alloc;3100 struct _SET_VOLTAGE_PARAMETERS v1;3101 struct _SET_VOLTAGE_PARAMETERS_V2 v2;3102 struct _SET_VOLTAGE_PARAMETERS_V1_3 v3;3103};3104 3105void radeon_atom_set_voltage(struct radeon_device *rdev, u16 voltage_level, u8 voltage_type)3106{3107 union set_voltage args;3108 int index = GetIndexIntoMasterTable(COMMAND, SetVoltage);3109 u8 frev, crev, volt_index = voltage_level;3110 3111 if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))3112 return;3113 3114 /* 0xff01 is a flag rather then an actual voltage */3115 if (voltage_level == 0xff01)3116 return;3117 3118 switch (crev) {3119 case 1:3120 args.v1.ucVoltageType = voltage_type;3121 args.v1.ucVoltageMode = SET_ASIC_VOLTAGE_MODE_ALL_SOURCE;3122 args.v1.ucVoltageIndex = volt_index;3123 break;3124 case 2:3125 args.v2.ucVoltageType = voltage_type;3126 args.v2.ucVoltageMode = SET_ASIC_VOLTAGE_MODE_SET_VOLTAGE;3127 args.v2.usVoltageLevel = cpu_to_le16(voltage_level);3128 break;3129 case 3:3130 args.v3.ucVoltageType = voltage_type;3131 args.v3.ucVoltageMode = ATOM_SET_VOLTAGE;3132 args.v3.usVoltageLevel = cpu_to_le16(voltage_level);3133 break;3134 default:3135 DRM_ERROR("Unknown table version %d, %d\n", frev, crev);3136 return;3137 }3138 3139 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args, sizeof(args));3140}3141 3142int radeon_atom_get_max_vddc(struct radeon_device *rdev, u8 voltage_type,3143 u16 voltage_id, u16 *voltage)3144{3145 union set_voltage args;3146 int index = GetIndexIntoMasterTable(COMMAND, SetVoltage);3147 u8 frev, crev;3148 3149 if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))3150 return -EINVAL;3151 3152 switch (crev) {3153 case 1:3154 return -EINVAL;3155 case 2:3156 args.v2.ucVoltageType = SET_VOLTAGE_GET_MAX_VOLTAGE;3157 args.v2.ucVoltageMode = 0;3158 args.v2.usVoltageLevel = 0;3159 3160 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args, sizeof(args));3161 3162 *voltage = le16_to_cpu(args.v2.usVoltageLevel);3163 break;3164 case 3:3165 args.v3.ucVoltageType = voltage_type;3166 args.v3.ucVoltageMode = ATOM_GET_VOLTAGE_LEVEL;3167 args.v3.usVoltageLevel = cpu_to_le16(voltage_id);3168 3169 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args, sizeof(args));3170 3171 *voltage = le16_to_cpu(args.v3.usVoltageLevel);3172 break;3173 default:3174 DRM_ERROR("Unknown table version %d, %d\n", frev, crev);3175 return -EINVAL;3176 }3177 3178 return 0;3179}3180 3181int radeon_atom_get_leakage_vddc_based_on_leakage_idx(struct radeon_device *rdev,3182 u16 *voltage,3183 u16 leakage_idx)3184{3185 return radeon_atom_get_max_vddc(rdev, VOLTAGE_TYPE_VDDC, leakage_idx, voltage);3186}3187 3188int radeon_atom_get_leakage_id_from_vbios(struct radeon_device *rdev,3189 u16 *leakage_id)3190{3191 union set_voltage args;3192 int index = GetIndexIntoMasterTable(COMMAND, SetVoltage);3193 u8 frev, crev;3194 3195 if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))3196 return -EINVAL;3197 3198 switch (crev) {3199 case 3:3200 case 4:3201 args.v3.ucVoltageType = 0;3202 args.v3.ucVoltageMode = ATOM_GET_LEAKAGE_ID;3203 args.v3.usVoltageLevel = 0;3204 3205 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args, sizeof(args));3206 3207 *leakage_id = le16_to_cpu(args.v3.usVoltageLevel);3208 break;3209 default:3210 DRM_ERROR("Unknown table version %d, %d\n", frev, crev);3211 return -EINVAL;3212 }3213 3214 return 0;3215}3216 3217int radeon_atom_get_leakage_vddc_based_on_leakage_params(struct radeon_device *rdev,3218 u16 *vddc, u16 *vddci,3219 u16 virtual_voltage_id,3220 u16 vbios_voltage_id)3221{3222 int index = GetIndexIntoMasterTable(DATA, ASIC_ProfilingInfo);3223 u8 frev, crev;3224 u16 data_offset, size;3225 int i, j;3226 ATOM_ASIC_PROFILING_INFO_V2_1 *profile;3227 u16 *leakage_bin, *vddc_id_buf, *vddc_buf, *vddci_id_buf, *vddci_buf;3228 3229 *vddc = 0;3230 *vddci = 0;3231 3232 if (!atom_parse_data_header(rdev->mode_info.atom_context, index, &size,3233 &frev, &crev, &data_offset))3234 return -EINVAL;3235 3236 profile = (ATOM_ASIC_PROFILING_INFO_V2_1 *)3237 (rdev->mode_info.atom_context->bios + data_offset);3238 3239 switch (frev) {3240 case 1:3241 return -EINVAL;3242 case 2:3243 switch (crev) {3244 case 1:3245 if (size < sizeof(ATOM_ASIC_PROFILING_INFO_V2_1))3246 return -EINVAL;3247 leakage_bin = (u16 *)3248 (rdev->mode_info.atom_context->bios + data_offset +3249 le16_to_cpu(profile->usLeakageBinArrayOffset));3250 vddc_id_buf = (u16 *)3251 (rdev->mode_info.atom_context->bios + data_offset +3252 le16_to_cpu(profile->usElbVDDC_IdArrayOffset));3253 vddc_buf = (u16 *)3254 (rdev->mode_info.atom_context->bios + data_offset +3255 le16_to_cpu(profile->usElbVDDC_LevelArrayOffset));3256 vddci_id_buf = (u16 *)3257 (rdev->mode_info.atom_context->bios + data_offset +3258 le16_to_cpu(profile->usElbVDDCI_IdArrayOffset));3259 vddci_buf = (u16 *)3260 (rdev->mode_info.atom_context->bios + data_offset +3261 le16_to_cpu(profile->usElbVDDCI_LevelArrayOffset));3262 3263 if (profile->ucElbVDDC_Num > 0) {3264 for (i = 0; i < profile->ucElbVDDC_Num; i++) {3265 if (vddc_id_buf[i] == virtual_voltage_id) {3266 for (j = 0; j < profile->ucLeakageBinNum; j++) {3267 if (vbios_voltage_id <= leakage_bin[j]) {3268 *vddc = vddc_buf[j * profile->ucElbVDDC_Num + i];3269 break;3270 }3271 }3272 break;3273 }3274 }3275 }3276 if (profile->ucElbVDDCI_Num > 0) {3277 for (i = 0; i < profile->ucElbVDDCI_Num; i++) {3278 if (vddci_id_buf[i] == virtual_voltage_id) {3279 for (j = 0; j < profile->ucLeakageBinNum; j++) {3280 if (vbios_voltage_id <= leakage_bin[j]) {3281 *vddci = vddci_buf[j * profile->ucElbVDDCI_Num + i];3282 break;3283 }3284 }3285 break;3286 }3287 }3288 }3289 break;3290 default:3291 DRM_ERROR("Unknown table version %d, %d\n", frev, crev);3292 return -EINVAL;3293 }3294 break;3295 default:3296 DRM_ERROR("Unknown table version %d, %d\n", frev, crev);3297 return -EINVAL;3298 }3299 3300 return 0;3301}3302 3303union get_voltage_info {3304 struct _GET_VOLTAGE_INFO_INPUT_PARAMETER_V1_2 in;3305 struct _GET_EVV_VOLTAGE_INFO_OUTPUT_PARAMETER_V1_2 evv_out;3306};3307 3308int radeon_atom_get_voltage_evv(struct radeon_device *rdev,3309 u16 virtual_voltage_id,3310 u16 *voltage)3311{3312 int index = GetIndexIntoMasterTable(COMMAND, GetVoltageInfo);3313 u32 entry_id;3314 u32 count = rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk.count;3315 union get_voltage_info args;3316 3317 for (entry_id = 0; entry_id < count; entry_id++) {3318 if (rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk.entries[entry_id].v ==3319 virtual_voltage_id)3320 break;3321 }3322 3323 if (entry_id >= count)3324 return -EINVAL;3325 3326 args.in.ucVoltageType = VOLTAGE_TYPE_VDDC;3327 args.in.ucVoltageMode = ATOM_GET_VOLTAGE_EVV_VOLTAGE;3328 args.in.usVoltageLevel = cpu_to_le16(virtual_voltage_id);3329 args.in.ulSCLKFreq =3330 cpu_to_le32(rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk.entries[entry_id].clk);3331 3332 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args, sizeof(args));3333 3334 *voltage = le16_to_cpu(args.evv_out.usVoltageLevel);3335 3336 return 0;3337}3338 3339int radeon_atom_get_voltage_gpio_settings(struct radeon_device *rdev,3340 u16 voltage_level, u8 voltage_type,3341 u32 *gpio_value, u32 *gpio_mask)3342{3343 union set_voltage args;3344 int index = GetIndexIntoMasterTable(COMMAND, SetVoltage);3345 u8 frev, crev;3346 3347 if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))3348 return -EINVAL;3349 3350 switch (crev) {3351 case 1:3352 return -EINVAL;3353 case 2:3354 args.v2.ucVoltageType = voltage_type;3355 args.v2.ucVoltageMode = SET_ASIC_VOLTAGE_MODE_GET_GPIOMASK;3356 args.v2.usVoltageLevel = cpu_to_le16(voltage_level);3357 3358 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args, sizeof(args));3359 3360 *gpio_mask = le32_to_cpu(*(u32 *)&args.v2);3361 3362 args.v2.ucVoltageType = voltage_type;3363 args.v2.ucVoltageMode = SET_ASIC_VOLTAGE_MODE_GET_GPIOVAL;3364 args.v2.usVoltageLevel = cpu_to_le16(voltage_level);3365 3366 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args, sizeof(args));3367 3368 *gpio_value = le32_to_cpu(*(u32 *)&args.v2);3369 break;3370 default:3371 DRM_ERROR("Unknown table version %d, %d\n", frev, crev);3372 return -EINVAL;3373 }3374 3375 return 0;3376}3377 3378union voltage_object_info {3379 struct _ATOM_VOLTAGE_OBJECT_INFO v1;3380 struct _ATOM_VOLTAGE_OBJECT_INFO_V2 v2;3381 struct _ATOM_VOLTAGE_OBJECT_INFO_V3_1 v3;3382};3383 3384union voltage_object {3385 struct _ATOM_VOLTAGE_OBJECT v1;3386 struct _ATOM_VOLTAGE_OBJECT_V2 v2;3387 union _ATOM_VOLTAGE_OBJECT_V3 v3;3388};3389 3390static ATOM_VOLTAGE_OBJECT *atom_lookup_voltage_object_v1(ATOM_VOLTAGE_OBJECT_INFO *v1,3391 u8 voltage_type)3392{3393 u32 size = le16_to_cpu(v1->sHeader.usStructureSize);3394 u32 offset = offsetof(ATOM_VOLTAGE_OBJECT_INFO, asVoltageObj[0]);3395 u8 *start = (u8 *)v1;3396 3397 while (offset < size) {3398 ATOM_VOLTAGE_OBJECT *vo = (ATOM_VOLTAGE_OBJECT *)(start + offset);3399 if (vo->ucVoltageType == voltage_type)3400 return vo;3401 offset += offsetof(ATOM_VOLTAGE_OBJECT, asFormula.ucVIDAdjustEntries) +3402 vo->asFormula.ucNumOfVoltageEntries;3403 }3404 return NULL;3405}3406 3407static ATOM_VOLTAGE_OBJECT_V2 *atom_lookup_voltage_object_v2(ATOM_VOLTAGE_OBJECT_INFO_V2 *v2,3408 u8 voltage_type)3409{3410 u32 size = le16_to_cpu(v2->sHeader.usStructureSize);3411 u32 offset = offsetof(ATOM_VOLTAGE_OBJECT_INFO_V2, asVoltageObj[0]);3412 u8 *start = (u8 *)v2;3413 3414 while (offset < size) {3415 ATOM_VOLTAGE_OBJECT_V2 *vo = (ATOM_VOLTAGE_OBJECT_V2 *)(start + offset);3416 if (vo->ucVoltageType == voltage_type)3417 return vo;3418 offset += offsetof(ATOM_VOLTAGE_OBJECT_V2, asFormula.asVIDAdjustEntries) +3419 (vo->asFormula.ucNumOfVoltageEntries * sizeof(VOLTAGE_LUT_ENTRY));3420 }3421 return NULL;3422}3423 3424static ATOM_VOLTAGE_OBJECT_V3 *atom_lookup_voltage_object_v3(ATOM_VOLTAGE_OBJECT_INFO_V3_1 *v3,3425 u8 voltage_type, u8 voltage_mode)3426{3427 u32 size = le16_to_cpu(v3->sHeader.usStructureSize);3428 u32 offset = offsetof(ATOM_VOLTAGE_OBJECT_INFO_V3_1, asVoltageObj[0]);3429 u8 *start = (u8 *)v3;3430 3431 while (offset < size) {3432 ATOM_VOLTAGE_OBJECT_V3 *vo = (ATOM_VOLTAGE_OBJECT_V3 *)(start + offset);3433 if ((vo->asGpioVoltageObj.sHeader.ucVoltageType == voltage_type) &&3434 (vo->asGpioVoltageObj.sHeader.ucVoltageMode == voltage_mode))3435 return vo;3436 offset += le16_to_cpu(vo->asGpioVoltageObj.sHeader.usSize);3437 }3438 return NULL;3439}3440 3441bool3442radeon_atom_is_voltage_gpio(struct radeon_device *rdev,3443 u8 voltage_type, u8 voltage_mode)3444{3445 int index = GetIndexIntoMasterTable(DATA, VoltageObjectInfo);3446 u8 frev, crev;3447 u16 data_offset, size;3448 union voltage_object_info *voltage_info;3449 union voltage_object *voltage_object = NULL;3450 3451 if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size,3452 &frev, &crev, &data_offset)) {3453 voltage_info = (union voltage_object_info *)3454 (rdev->mode_info.atom_context->bios + data_offset);3455 3456 switch (frev) {3457 case 1:3458 case 2:3459 switch (crev) {3460 case 1:3461 voltage_object = (union voltage_object *)3462 atom_lookup_voltage_object_v1(&voltage_info->v1, voltage_type);3463 if (voltage_object &&3464 (voltage_object->v1.asControl.ucVoltageControlId == VOLTAGE_CONTROLLED_BY_GPIO))3465 return true;3466 break;3467 case 2:3468 voltage_object = (union voltage_object *)3469 atom_lookup_voltage_object_v2(&voltage_info->v2, voltage_type);3470 if (voltage_object &&3471 (voltage_object->v2.asControl.ucVoltageControlId == VOLTAGE_CONTROLLED_BY_GPIO))3472 return true;3473 break;3474 default:3475 DRM_ERROR("unknown voltage object table\n");3476 return false;3477 }3478 break;3479 case 3:3480 switch (crev) {3481 case 1:3482 if (atom_lookup_voltage_object_v3(&voltage_info->v3,3483 voltage_type, voltage_mode))3484 return true;3485 break;3486 default:3487 DRM_ERROR("unknown voltage object table\n");3488 return false;3489 }3490 break;3491 default:3492 DRM_ERROR("unknown voltage object table\n");3493 return false;3494 }3495 3496 }3497 return false;3498}3499 3500int radeon_atom_get_svi2_info(struct radeon_device *rdev,3501 u8 voltage_type,3502 u8 *svd_gpio_id, u8 *svc_gpio_id)3503{3504 int index = GetIndexIntoMasterTable(DATA, VoltageObjectInfo);3505 u8 frev, crev;3506 u16 data_offset, size;3507 union voltage_object_info *voltage_info;3508 union voltage_object *voltage_object = NULL;3509 3510 if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size,3511 &frev, &crev, &data_offset)) {3512 voltage_info = (union voltage_object_info *)3513 (rdev->mode_info.atom_context->bios + data_offset);3514 3515 switch (frev) {3516 case 3:3517 switch (crev) {3518 case 1:3519 voltage_object = (union voltage_object *)3520 atom_lookup_voltage_object_v3(&voltage_info->v3,3521 voltage_type,3522 VOLTAGE_OBJ_SVID2);3523 if (voltage_object) {3524 *svd_gpio_id = voltage_object->v3.asSVID2Obj.ucSVDGpioId;3525 *svc_gpio_id = voltage_object->v3.asSVID2Obj.ucSVCGpioId;3526 } else {3527 return -EINVAL;3528 }3529 break;3530 default:3531 DRM_ERROR("unknown voltage object table\n");3532 return -EINVAL;3533 }3534 break;3535 default:3536 DRM_ERROR("unknown voltage object table\n");3537 return -EINVAL;3538 }3539 3540 }3541 return 0;3542}3543 3544int radeon_atom_get_max_voltage(struct radeon_device *rdev,3545 u8 voltage_type, u16 *max_voltage)3546{3547 int index = GetIndexIntoMasterTable(DATA, VoltageObjectInfo);3548 u8 frev, crev;3549 u16 data_offset, size;3550 union voltage_object_info *voltage_info;3551 union voltage_object *voltage_object = NULL;3552 3553 if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size,3554 &frev, &crev, &data_offset)) {3555 voltage_info = (union voltage_object_info *)3556 (rdev->mode_info.atom_context->bios + data_offset);3557 3558 switch (crev) {3559 case 1:3560 voltage_object = (union voltage_object *)3561 atom_lookup_voltage_object_v1(&voltage_info->v1, voltage_type);3562 if (voltage_object) {3563 ATOM_VOLTAGE_FORMULA *formula =3564 &voltage_object->v1.asFormula;3565 if (formula->ucFlag & 1)3566 *max_voltage =3567 le16_to_cpu(formula->usVoltageBaseLevel) +3568 formula->ucNumOfVoltageEntries / 2 *3569 le16_to_cpu(formula->usVoltageStep);3570 else3571 *max_voltage =3572 le16_to_cpu(formula->usVoltageBaseLevel) +3573 (formula->ucNumOfVoltageEntries - 1) *3574 le16_to_cpu(formula->usVoltageStep);3575 return 0;3576 }3577 break;3578 case 2:3579 voltage_object = (union voltage_object *)3580 atom_lookup_voltage_object_v2(&voltage_info->v2, voltage_type);3581 if (voltage_object) {3582 ATOM_VOLTAGE_FORMULA_V2 *formula =3583 &voltage_object->v2.asFormula;3584 if (formula->ucNumOfVoltageEntries) {3585 VOLTAGE_LUT_ENTRY *lut = (VOLTAGE_LUT_ENTRY *)3586 ((u8 *)&formula->asVIDAdjustEntries[0] +3587 (sizeof(VOLTAGE_LUT_ENTRY) * (formula->ucNumOfVoltageEntries - 1)));3588 *max_voltage =3589 le16_to_cpu(lut->usVoltageValue);3590 return 0;3591 }3592 }3593 break;3594 default:3595 DRM_ERROR("unknown voltage object table\n");3596 return -EINVAL;3597 }3598 3599 }3600 return -EINVAL;3601}3602 3603int radeon_atom_get_min_voltage(struct radeon_device *rdev,3604 u8 voltage_type, u16 *min_voltage)3605{3606 int index = GetIndexIntoMasterTable(DATA, VoltageObjectInfo);3607 u8 frev, crev;3608 u16 data_offset, size;3609 union voltage_object_info *voltage_info;3610 union voltage_object *voltage_object = NULL;3611 3612 if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size,3613 &frev, &crev, &data_offset)) {3614 voltage_info = (union voltage_object_info *)3615 (rdev->mode_info.atom_context->bios + data_offset);3616 3617 switch (crev) {3618 case 1:3619 voltage_object = (union voltage_object *)3620 atom_lookup_voltage_object_v1(&voltage_info->v1, voltage_type);3621 if (voltage_object) {3622 ATOM_VOLTAGE_FORMULA *formula =3623 &voltage_object->v1.asFormula;3624 *min_voltage =3625 le16_to_cpu(formula->usVoltageBaseLevel);3626 return 0;3627 }3628 break;3629 case 2:3630 voltage_object = (union voltage_object *)3631 atom_lookup_voltage_object_v2(&voltage_info->v2, voltage_type);3632 if (voltage_object) {3633 ATOM_VOLTAGE_FORMULA_V2 *formula =3634 &voltage_object->v2.asFormula;3635 if (formula->ucNumOfVoltageEntries) {3636 *min_voltage =3637 le16_to_cpu(formula->asVIDAdjustEntries[3638 03639 ].usVoltageValue);3640 return 0;3641 }3642 }3643 break;3644 default:3645 DRM_ERROR("unknown voltage object table\n");3646 return -EINVAL;3647 }3648 3649 }3650 return -EINVAL;3651}3652 3653int radeon_atom_get_voltage_step(struct radeon_device *rdev,3654 u8 voltage_type, u16 *voltage_step)3655{3656 int index = GetIndexIntoMasterTable(DATA, VoltageObjectInfo);3657 u8 frev, crev;3658 u16 data_offset, size;3659 union voltage_object_info *voltage_info;3660 union voltage_object *voltage_object = NULL;3661 3662 if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size,3663 &frev, &crev, &data_offset)) {3664 voltage_info = (union voltage_object_info *)3665 (rdev->mode_info.atom_context->bios + data_offset);3666 3667 switch (crev) {3668 case 1:3669 voltage_object = (union voltage_object *)3670 atom_lookup_voltage_object_v1(&voltage_info->v1, voltage_type);3671 if (voltage_object) {3672 ATOM_VOLTAGE_FORMULA *formula =3673 &voltage_object->v1.asFormula;3674 if (formula->ucFlag & 1)3675 *voltage_step =3676 (le16_to_cpu(formula->usVoltageStep) + 1) / 2;3677 else3678 *voltage_step =3679 le16_to_cpu(formula->usVoltageStep);3680 return 0;3681 }3682 break;3683 case 2:3684 return -EINVAL;3685 default:3686 DRM_ERROR("unknown voltage object table\n");3687 return -EINVAL;3688 }3689 3690 }3691 return -EINVAL;3692}3693 3694int radeon_atom_round_to_true_voltage(struct radeon_device *rdev,3695 u8 voltage_type,3696 u16 nominal_voltage,3697 u16 *true_voltage)3698{3699 u16 min_voltage, max_voltage, voltage_step;3700 3701 if (radeon_atom_get_max_voltage(rdev, voltage_type, &max_voltage))3702 return -EINVAL;3703 if (radeon_atom_get_min_voltage(rdev, voltage_type, &min_voltage))3704 return -EINVAL;3705 if (radeon_atom_get_voltage_step(rdev, voltage_type, &voltage_step))3706 return -EINVAL;3707 3708 if (nominal_voltage <= min_voltage)3709 *true_voltage = min_voltage;3710 else if (nominal_voltage >= max_voltage)3711 *true_voltage = max_voltage;3712 else3713 *true_voltage = min_voltage +3714 ((nominal_voltage - min_voltage) / voltage_step) *3715 voltage_step;3716 3717 return 0;3718}3719 3720int radeon_atom_get_voltage_table(struct radeon_device *rdev,3721 u8 voltage_type, u8 voltage_mode,3722 struct atom_voltage_table *voltage_table)3723{3724 int index = GetIndexIntoMasterTable(DATA, VoltageObjectInfo);3725 u8 frev, crev;3726 u16 data_offset, size;3727 int i, ret;3728 union voltage_object_info *voltage_info;3729 union voltage_object *voltage_object = NULL;3730 3731 if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size,3732 &frev, &crev, &data_offset)) {3733 voltage_info = (union voltage_object_info *)3734 (rdev->mode_info.atom_context->bios + data_offset);3735 3736 switch (frev) {3737 case 1:3738 case 2:3739 switch (crev) {3740 case 1:3741 DRM_ERROR("old table version %d, %d\n", frev, crev);3742 return -EINVAL;3743 case 2:3744 voltage_object = (union voltage_object *)3745 atom_lookup_voltage_object_v2(&voltage_info->v2, voltage_type);3746 if (voltage_object) {3747 ATOM_VOLTAGE_FORMULA_V2 *formula =3748 &voltage_object->v2.asFormula;3749 VOLTAGE_LUT_ENTRY *lut;3750 if (formula->ucNumOfVoltageEntries > MAX_VOLTAGE_ENTRIES)3751 return -EINVAL;3752 lut = &formula->asVIDAdjustEntries[0];3753 for (i = 0; i < formula->ucNumOfVoltageEntries; i++) {3754 voltage_table->entries[i].value =3755 le16_to_cpu(lut->usVoltageValue);3756 ret = radeon_atom_get_voltage_gpio_settings(rdev,3757 voltage_table->entries[i].value,3758 voltage_type,3759 &voltage_table->entries[i].smio_low,3760 &voltage_table->mask_low);3761 if (ret)3762 return ret;3763 lut = (VOLTAGE_LUT_ENTRY *)3764 ((u8 *)lut + sizeof(VOLTAGE_LUT_ENTRY));3765 }3766 voltage_table->count = formula->ucNumOfVoltageEntries;3767 return 0;3768 }3769 break;3770 default:3771 DRM_ERROR("unknown voltage object table\n");3772 return -EINVAL;3773 }3774 break;3775 case 3:3776 switch (crev) {3777 case 1:3778 voltage_object = (union voltage_object *)3779 atom_lookup_voltage_object_v3(&voltage_info->v3,3780 voltage_type, voltage_mode);3781 if (voltage_object) {3782 ATOM_GPIO_VOLTAGE_OBJECT_V3 *gpio =3783 &voltage_object->v3.asGpioVoltageObj;3784 VOLTAGE_LUT_ENTRY_V2 *lut;3785 if (gpio->ucGpioEntryNum > MAX_VOLTAGE_ENTRIES)3786 return -EINVAL;3787 lut = &gpio->asVolGpioLut[0];3788 for (i = 0; i < gpio->ucGpioEntryNum; i++) {3789 voltage_table->entries[i].value =3790 le16_to_cpu(lut->usVoltageValue);3791 voltage_table->entries[i].smio_low =3792 le32_to_cpu(lut->ulVoltageId);3793 lut = (VOLTAGE_LUT_ENTRY_V2 *)3794 ((u8 *)lut + sizeof(VOLTAGE_LUT_ENTRY_V2));3795 }3796 voltage_table->mask_low = le32_to_cpu(gpio->ulGpioMaskVal);3797 voltage_table->count = gpio->ucGpioEntryNum;3798 voltage_table->phase_delay = gpio->ucPhaseDelay;3799 return 0;3800 }3801 break;3802 default:3803 DRM_ERROR("unknown voltage object table\n");3804 return -EINVAL;3805 }3806 break;3807 default:3808 DRM_ERROR("unknown voltage object table\n");3809 return -EINVAL;3810 }3811 }3812 return -EINVAL;3813}3814 3815union vram_info {3816 struct _ATOM_VRAM_INFO_V3 v1_3;3817 struct _ATOM_VRAM_INFO_V4 v1_4;3818 struct _ATOM_VRAM_INFO_HEADER_V2_1 v2_1;3819};3820 3821int radeon_atom_get_memory_info(struct radeon_device *rdev,3822 u8 module_index, struct atom_memory_info *mem_info)3823{3824 int index = GetIndexIntoMasterTable(DATA, VRAM_Info);3825 u8 frev, crev, i;3826 u16 data_offset, size;3827 union vram_info *vram_info;3828 3829 memset(mem_info, 0, sizeof(struct atom_memory_info));3830 3831 if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size,3832 &frev, &crev, &data_offset)) {3833 vram_info = (union vram_info *)3834 (rdev->mode_info.atom_context->bios + data_offset);3835 switch (frev) {3836 case 1:3837 switch (crev) {3838 case 3:3839 /* r6xx */3840 if (module_index < vram_info->v1_3.ucNumOfVRAMModule) {3841 ATOM_VRAM_MODULE_V3 *vram_module =3842 (ATOM_VRAM_MODULE_V3 *)vram_info->v1_3.aVramInfo;3843 3844 for (i = 0; i < module_index; i++) {3845 if (le16_to_cpu(vram_module->usSize) == 0)3846 return -EINVAL;3847 vram_module = (ATOM_VRAM_MODULE_V3 *)3848 ((u8 *)vram_module + le16_to_cpu(vram_module->usSize));3849 }3850 mem_info->mem_vendor = vram_module->asMemory.ucMemoryVenderID & 0xf;3851 mem_info->mem_type = vram_module->asMemory.ucMemoryType & 0xf0;3852 } else3853 return -EINVAL;3854 break;3855 case 4:3856 /* r7xx, evergreen */3857 if (module_index < vram_info->v1_4.ucNumOfVRAMModule) {3858 ATOM_VRAM_MODULE_V4 *vram_module =3859 (ATOM_VRAM_MODULE_V4 *)vram_info->v1_4.aVramInfo;3860 3861 for (i = 0; i < module_index; i++) {3862 if (le16_to_cpu(vram_module->usModuleSize) == 0)3863 return -EINVAL;3864 vram_module = (ATOM_VRAM_MODULE_V4 *)3865 ((u8 *)vram_module + le16_to_cpu(vram_module->usModuleSize));3866 }3867 mem_info->mem_vendor = vram_module->ucMemoryVenderID & 0xf;3868 mem_info->mem_type = vram_module->ucMemoryType & 0xf0;3869 } else3870 return -EINVAL;3871 break;3872 default:3873 DRM_ERROR("Unknown table version %d, %d\n", frev, crev);3874 return -EINVAL;3875 }3876 break;3877 case 2:3878 switch (crev) {3879 case 1:3880 /* ni */3881 if (module_index < vram_info->v2_1.ucNumOfVRAMModule) {3882 ATOM_VRAM_MODULE_V7 *vram_module =3883 (ATOM_VRAM_MODULE_V7 *)vram_info->v2_1.aVramInfo;3884 3885 for (i = 0; i < module_index; i++) {3886 if (le16_to_cpu(vram_module->usModuleSize) == 0)3887 return -EINVAL;3888 vram_module = (ATOM_VRAM_MODULE_V7 *)3889 ((u8 *)vram_module + le16_to_cpu(vram_module->usModuleSize));3890 }3891 mem_info->mem_vendor = vram_module->ucMemoryVenderID & 0xf;3892 mem_info->mem_type = vram_module->ucMemoryType & 0xf0;3893 } else3894 return -EINVAL;3895 break;3896 default:3897 DRM_ERROR("Unknown table version %d, %d\n", frev, crev);3898 return -EINVAL;3899 }3900 break;3901 default:3902 DRM_ERROR("Unknown table version %d, %d\n", frev, crev);3903 return -EINVAL;3904 }3905 return 0;3906 }3907 return -EINVAL;3908}3909 3910int radeon_atom_get_mclk_range_table(struct radeon_device *rdev,3911 bool gddr5, u8 module_index,3912 struct atom_memory_clock_range_table *mclk_range_table)3913{3914 int index = GetIndexIntoMasterTable(DATA, VRAM_Info);3915 u8 frev, crev, i;3916 u16 data_offset, size;3917 union vram_info *vram_info;3918 u32 mem_timing_size = gddr5 ?3919 sizeof(ATOM_MEMORY_TIMING_FORMAT_V2) : sizeof(ATOM_MEMORY_TIMING_FORMAT);3920 3921 memset(mclk_range_table, 0, sizeof(struct atom_memory_clock_range_table));3922 3923 if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size,3924 &frev, &crev, &data_offset)) {3925 vram_info = (union vram_info *)3926 (rdev->mode_info.atom_context->bios + data_offset);3927 switch (frev) {3928 case 1:3929 switch (crev) {3930 case 3:3931 DRM_ERROR("old table version %d, %d\n", frev, crev);3932 return -EINVAL;3933 case 4:3934 /* r7xx, evergreen */3935 if (module_index < vram_info->v1_4.ucNumOfVRAMModule) {3936 ATOM_VRAM_MODULE_V4 *vram_module =3937 (ATOM_VRAM_MODULE_V4 *)vram_info->v1_4.aVramInfo;3938 ATOM_MEMORY_TIMING_FORMAT *format;3939 3940 for (i = 0; i < module_index; i++) {3941 if (le16_to_cpu(vram_module->usModuleSize) == 0)3942 return -EINVAL;3943 vram_module = (ATOM_VRAM_MODULE_V4 *)3944 ((u8 *)vram_module + le16_to_cpu(vram_module->usModuleSize));3945 }3946 mclk_range_table->num_entries = (u8)3947 ((le16_to_cpu(vram_module->usModuleSize) - offsetof(ATOM_VRAM_MODULE_V4, asMemTiming)) /3948 mem_timing_size);3949 format = &vram_module->asMemTiming[0];3950 for (i = 0; i < mclk_range_table->num_entries; i++) {3951 mclk_range_table->mclk[i] = le32_to_cpu(format->ulClkRange);3952 format = (ATOM_MEMORY_TIMING_FORMAT *)3953 ((u8 *)format + mem_timing_size);3954 }3955 } else3956 return -EINVAL;3957 break;3958 default:3959 DRM_ERROR("Unknown table version %d, %d\n", frev, crev);3960 return -EINVAL;3961 }3962 break;3963 case 2:3964 DRM_ERROR("new table version %d, %d\n", frev, crev);3965 return -EINVAL;3966 default:3967 DRM_ERROR("Unknown table version %d, %d\n", frev, crev);3968 return -EINVAL;3969 }3970 return 0;3971 }3972 return -EINVAL;3973}3974 3975#define MEM_ID_MASK 0xff0000003976#define MEM_ID_SHIFT 243977#define CLOCK_RANGE_MASK 0x00ffffff3978#define CLOCK_RANGE_SHIFT 03979#define LOW_NIBBLE_MASK 0xf3980#define DATA_EQU_PREV 03981#define DATA_FROM_TABLE 43982 3983int radeon_atom_init_mc_reg_table(struct radeon_device *rdev,3984 u8 module_index,3985 struct atom_mc_reg_table *reg_table)3986{3987 int index = GetIndexIntoMasterTable(DATA, VRAM_Info);3988 u8 frev, crev, num_entries, t_mem_id, num_ranges = 0;3989 u32 i = 0, j;3990 u16 data_offset, size;3991 union vram_info *vram_info;3992 3993 memset(reg_table, 0, sizeof(struct atom_mc_reg_table));3994 3995 if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size,3996 &frev, &crev, &data_offset)) {3997 vram_info = (union vram_info *)3998 (rdev->mode_info.atom_context->bios + data_offset);3999 switch (frev) {4000 case 1:4001 DRM_ERROR("old table version %d, %d\n", frev, crev);4002 return -EINVAL;4003 case 2:4004 switch (crev) {4005 case 1:4006 if (module_index < vram_info->v2_1.ucNumOfVRAMModule) {4007 ATOM_INIT_REG_BLOCK *reg_block =4008 (ATOM_INIT_REG_BLOCK *)4009 ((u8 *)vram_info + le16_to_cpu(vram_info->v2_1.usMemClkPatchTblOffset));4010 ATOM_MEMORY_SETTING_DATA_BLOCK *reg_data =4011 (ATOM_MEMORY_SETTING_DATA_BLOCK *)4012 ((u8 *)reg_block + (2 * sizeof(u16)) +4013 le16_to_cpu(reg_block->usRegIndexTblSize));4014 ATOM_INIT_REG_INDEX_FORMAT *format = ®_block->asRegIndexBuf[0];4015 num_entries = (u8)((le16_to_cpu(reg_block->usRegIndexTblSize)) /4016 sizeof(ATOM_INIT_REG_INDEX_FORMAT)) - 1;4017 if (num_entries > VBIOS_MC_REGISTER_ARRAY_SIZE)4018 return -EINVAL;4019 while (i < num_entries) {4020 if (format->ucPreRegDataLength & ACCESS_PLACEHOLDER)4021 break;4022 reg_table->mc_reg_address[i].s1 =4023 (u16)(le16_to_cpu(format->usRegIndex));4024 reg_table->mc_reg_address[i].pre_reg_data =4025 (u8)(format->ucPreRegDataLength);4026 i++;4027 format = (ATOM_INIT_REG_INDEX_FORMAT *)4028 ((u8 *)format + sizeof(ATOM_INIT_REG_INDEX_FORMAT));4029 }4030 reg_table->last = i;4031 while ((le32_to_cpu(*(u32 *)reg_data) != END_OF_REG_DATA_BLOCK) &&4032 (num_ranges < VBIOS_MAX_AC_TIMING_ENTRIES)) {4033 t_mem_id = (u8)((le32_to_cpu(*(u32 *)reg_data) & MEM_ID_MASK)4034 >> MEM_ID_SHIFT);4035 if (module_index == t_mem_id) {4036 reg_table->mc_reg_table_entry[num_ranges].mclk_max =4037 (u32)((le32_to_cpu(*(u32 *)reg_data) & CLOCK_RANGE_MASK)4038 >> CLOCK_RANGE_SHIFT);4039 for (i = 0, j = 1; i < reg_table->last; i++) {4040 if ((reg_table->mc_reg_address[i].pre_reg_data & LOW_NIBBLE_MASK) == DATA_FROM_TABLE) {4041 reg_table->mc_reg_table_entry[num_ranges].mc_data[i] =4042 (u32)le32_to_cpu(*((u32 *)reg_data + j));4043 j++;4044 } else if ((reg_table->mc_reg_address[i].pre_reg_data & LOW_NIBBLE_MASK) == DATA_EQU_PREV) {4045 reg_table->mc_reg_table_entry[num_ranges].mc_data[i] =4046 reg_table->mc_reg_table_entry[num_ranges].mc_data[i - 1];4047 }4048 }4049 num_ranges++;4050 }4051 reg_data = (ATOM_MEMORY_SETTING_DATA_BLOCK *)4052 ((u8 *)reg_data + le16_to_cpu(reg_block->usRegDataBlkSize));4053 }4054 if (le32_to_cpu(*(u32 *)reg_data) != END_OF_REG_DATA_BLOCK)4055 return -EINVAL;4056 reg_table->num_entries = num_ranges;4057 } else4058 return -EINVAL;4059 break;4060 default:4061 DRM_ERROR("Unknown table version %d, %d\n", frev, crev);4062 return -EINVAL;4063 }4064 break;4065 default:4066 DRM_ERROR("Unknown table version %d, %d\n", frev, crev);4067 return -EINVAL;4068 }4069 return 0;4070 }4071 return -EINVAL;4072}4073 4074void radeon_atom_initialize_bios_scratch_regs(struct drm_device *dev)4075{4076 struct radeon_device *rdev = dev->dev_private;4077 uint32_t bios_2_scratch, bios_6_scratch;4078 4079 if (rdev->family >= CHIP_R600) {4080 bios_2_scratch = RREG32(R600_BIOS_2_SCRATCH);4081 bios_6_scratch = RREG32(R600_BIOS_6_SCRATCH);4082 } else {4083 bios_2_scratch = RREG32(RADEON_BIOS_2_SCRATCH);4084 bios_6_scratch = RREG32(RADEON_BIOS_6_SCRATCH);4085 }4086 4087 /* let the bios control the backlight */4088 bios_2_scratch &= ~ATOM_S2_VRI_BRIGHT_ENABLE;4089 4090 /* tell the bios not to handle mode switching */4091 bios_6_scratch |= ATOM_S6_ACC_BLOCK_DISPLAY_SWITCH;4092 4093 /* clear the vbios dpms state */4094 if (ASIC_IS_DCE4(rdev))4095 bios_2_scratch &= ~ATOM_S2_DEVICE_DPMS_STATE;4096 4097 if (rdev->family >= CHIP_R600) {4098 WREG32(R600_BIOS_2_SCRATCH, bios_2_scratch);4099 WREG32(R600_BIOS_6_SCRATCH, bios_6_scratch);4100 } else {4101 WREG32(RADEON_BIOS_2_SCRATCH, bios_2_scratch);4102 WREG32(RADEON_BIOS_6_SCRATCH, bios_6_scratch);4103 }4104 4105}4106 4107void radeon_save_bios_scratch_regs(struct radeon_device *rdev)4108{4109 uint32_t scratch_reg;4110 int i;4111 4112 if (rdev->family >= CHIP_R600)4113 scratch_reg = R600_BIOS_0_SCRATCH;4114 else4115 scratch_reg = RADEON_BIOS_0_SCRATCH;4116 4117 for (i = 0; i < RADEON_BIOS_NUM_SCRATCH; i++)4118 rdev->bios_scratch[i] = RREG32(scratch_reg + (i * 4));4119}4120 4121void radeon_restore_bios_scratch_regs(struct radeon_device *rdev)4122{4123 uint32_t scratch_reg;4124 int i;4125 4126 if (rdev->family >= CHIP_R600)4127 scratch_reg = R600_BIOS_0_SCRATCH;4128 else4129 scratch_reg = RADEON_BIOS_0_SCRATCH;4130 4131 for (i = 0; i < RADEON_BIOS_NUM_SCRATCH; i++)4132 WREG32(scratch_reg + (i * 4), rdev->bios_scratch[i]);4133}4134 4135void radeon_atom_output_lock(struct drm_encoder *encoder, bool lock)4136{4137 struct drm_device *dev = encoder->dev;4138 struct radeon_device *rdev = dev->dev_private;4139 uint32_t bios_6_scratch;4140 4141 if (rdev->family >= CHIP_R600)4142 bios_6_scratch = RREG32(R600_BIOS_6_SCRATCH);4143 else4144 bios_6_scratch = RREG32(RADEON_BIOS_6_SCRATCH);4145 4146 if (lock) {4147 bios_6_scratch |= ATOM_S6_CRITICAL_STATE;4148 bios_6_scratch &= ~ATOM_S6_ACC_MODE;4149 } else {4150 bios_6_scratch &= ~ATOM_S6_CRITICAL_STATE;4151 bios_6_scratch |= ATOM_S6_ACC_MODE;4152 }4153 4154 if (rdev->family >= CHIP_R600)4155 WREG32(R600_BIOS_6_SCRATCH, bios_6_scratch);4156 else4157 WREG32(RADEON_BIOS_6_SCRATCH, bios_6_scratch);4158}4159 4160/* at some point we may want to break this out into individual functions */4161void4162radeon_atombios_connected_scratch_regs(struct drm_connector *connector,4163 struct drm_encoder *encoder,4164 bool connected)4165{4166 struct drm_device *dev = connector->dev;4167 struct radeon_device *rdev = dev->dev_private;4168 struct radeon_connector *radeon_connector =4169 to_radeon_connector(connector);4170 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);4171 uint32_t bios_0_scratch, bios_3_scratch, bios_6_scratch;4172 4173 if (rdev->family >= CHIP_R600) {4174 bios_0_scratch = RREG32(R600_BIOS_0_SCRATCH);4175 bios_3_scratch = RREG32(R600_BIOS_3_SCRATCH);4176 bios_6_scratch = RREG32(R600_BIOS_6_SCRATCH);4177 } else {4178 bios_0_scratch = RREG32(RADEON_BIOS_0_SCRATCH);4179 bios_3_scratch = RREG32(RADEON_BIOS_3_SCRATCH);4180 bios_6_scratch = RREG32(RADEON_BIOS_6_SCRATCH);4181 }4182 4183 if ((radeon_encoder->devices & ATOM_DEVICE_TV1_SUPPORT) &&4184 (radeon_connector->devices & ATOM_DEVICE_TV1_SUPPORT)) {4185 if (connected) {4186 DRM_DEBUG_KMS("TV1 connected\n");4187 bios_3_scratch |= ATOM_S3_TV1_ACTIVE;4188 bios_6_scratch |= ATOM_S6_ACC_REQ_TV1;4189 } else {4190 DRM_DEBUG_KMS("TV1 disconnected\n");4191 bios_0_scratch &= ~ATOM_S0_TV1_MASK;4192 bios_3_scratch &= ~ATOM_S3_TV1_ACTIVE;4193 bios_6_scratch &= ~ATOM_S6_ACC_REQ_TV1;4194 }4195 }4196 if ((radeon_encoder->devices & ATOM_DEVICE_CV_SUPPORT) &&4197 (radeon_connector->devices & ATOM_DEVICE_CV_SUPPORT)) {4198 if (connected) {4199 DRM_DEBUG_KMS("CV connected\n");4200 bios_3_scratch |= ATOM_S3_CV_ACTIVE;4201 bios_6_scratch |= ATOM_S6_ACC_REQ_CV;4202 } else {4203 DRM_DEBUG_KMS("CV disconnected\n");4204 bios_0_scratch &= ~ATOM_S0_CV_MASK;4205 bios_3_scratch &= ~ATOM_S3_CV_ACTIVE;4206 bios_6_scratch &= ~ATOM_S6_ACC_REQ_CV;4207 }4208 }4209 if ((radeon_encoder->devices & ATOM_DEVICE_LCD1_SUPPORT) &&4210 (radeon_connector->devices & ATOM_DEVICE_LCD1_SUPPORT)) {4211 if (connected) {4212 DRM_DEBUG_KMS("LCD1 connected\n");4213 bios_0_scratch |= ATOM_S0_LCD1;4214 bios_3_scratch |= ATOM_S3_LCD1_ACTIVE;4215 bios_6_scratch |= ATOM_S6_ACC_REQ_LCD1;4216 } else {4217 DRM_DEBUG_KMS("LCD1 disconnected\n");4218 bios_0_scratch &= ~ATOM_S0_LCD1;4219 bios_3_scratch &= ~ATOM_S3_LCD1_ACTIVE;4220 bios_6_scratch &= ~ATOM_S6_ACC_REQ_LCD1;4221 }4222 }4223 if ((radeon_encoder->devices & ATOM_DEVICE_CRT1_SUPPORT) &&4224 (radeon_connector->devices & ATOM_DEVICE_CRT1_SUPPORT)) {4225 if (connected) {4226 DRM_DEBUG_KMS("CRT1 connected\n");4227 bios_0_scratch |= ATOM_S0_CRT1_COLOR;4228 bios_3_scratch |= ATOM_S3_CRT1_ACTIVE;4229 bios_6_scratch |= ATOM_S6_ACC_REQ_CRT1;4230 } else {4231 DRM_DEBUG_KMS("CRT1 disconnected\n");4232 bios_0_scratch &= ~ATOM_S0_CRT1_MASK;4233 bios_3_scratch &= ~ATOM_S3_CRT1_ACTIVE;4234 bios_6_scratch &= ~ATOM_S6_ACC_REQ_CRT1;4235 }4236 }4237 if ((radeon_encoder->devices & ATOM_DEVICE_CRT2_SUPPORT) &&4238 (radeon_connector->devices & ATOM_DEVICE_CRT2_SUPPORT)) {4239 if (connected) {4240 DRM_DEBUG_KMS("CRT2 connected\n");4241 bios_0_scratch |= ATOM_S0_CRT2_COLOR;4242 bios_3_scratch |= ATOM_S3_CRT2_ACTIVE;4243 bios_6_scratch |= ATOM_S6_ACC_REQ_CRT2;4244 } else {4245 DRM_DEBUG_KMS("CRT2 disconnected\n");4246 bios_0_scratch &= ~ATOM_S0_CRT2_MASK;4247 bios_3_scratch &= ~ATOM_S3_CRT2_ACTIVE;4248 bios_6_scratch &= ~ATOM_S6_ACC_REQ_CRT2;4249 }4250 }4251 if ((radeon_encoder->devices & ATOM_DEVICE_DFP1_SUPPORT) &&4252 (radeon_connector->devices & ATOM_DEVICE_DFP1_SUPPORT)) {4253 if (connected) {4254 DRM_DEBUG_KMS("DFP1 connected\n");4255 bios_0_scratch |= ATOM_S0_DFP1;4256 bios_3_scratch |= ATOM_S3_DFP1_ACTIVE;4257 bios_6_scratch |= ATOM_S6_ACC_REQ_DFP1;4258 } else {4259 DRM_DEBUG_KMS("DFP1 disconnected\n");4260 bios_0_scratch &= ~ATOM_S0_DFP1;4261 bios_3_scratch &= ~ATOM_S3_DFP1_ACTIVE;4262 bios_6_scratch &= ~ATOM_S6_ACC_REQ_DFP1;4263 }4264 }4265 if ((radeon_encoder->devices & ATOM_DEVICE_DFP2_SUPPORT) &&4266 (radeon_connector->devices & ATOM_DEVICE_DFP2_SUPPORT)) {4267 if (connected) {4268 DRM_DEBUG_KMS("DFP2 connected\n");4269 bios_0_scratch |= ATOM_S0_DFP2;4270 bios_3_scratch |= ATOM_S3_DFP2_ACTIVE;4271 bios_6_scratch |= ATOM_S6_ACC_REQ_DFP2;4272 } else {4273 DRM_DEBUG_KMS("DFP2 disconnected\n");4274 bios_0_scratch &= ~ATOM_S0_DFP2;4275 bios_3_scratch &= ~ATOM_S3_DFP2_ACTIVE;4276 bios_6_scratch &= ~ATOM_S6_ACC_REQ_DFP2;4277 }4278 }4279 if ((radeon_encoder->devices & ATOM_DEVICE_DFP3_SUPPORT) &&4280 (radeon_connector->devices & ATOM_DEVICE_DFP3_SUPPORT)) {4281 if (connected) {4282 DRM_DEBUG_KMS("DFP3 connected\n");4283 bios_0_scratch |= ATOM_S0_DFP3;4284 bios_3_scratch |= ATOM_S3_DFP3_ACTIVE;4285 bios_6_scratch |= ATOM_S6_ACC_REQ_DFP3;4286 } else {4287 DRM_DEBUG_KMS("DFP3 disconnected\n");4288 bios_0_scratch &= ~ATOM_S0_DFP3;4289 bios_3_scratch &= ~ATOM_S3_DFP3_ACTIVE;4290 bios_6_scratch &= ~ATOM_S6_ACC_REQ_DFP3;4291 }4292 }4293 if ((radeon_encoder->devices & ATOM_DEVICE_DFP4_SUPPORT) &&4294 (radeon_connector->devices & ATOM_DEVICE_DFP4_SUPPORT)) {4295 if (connected) {4296 DRM_DEBUG_KMS("DFP4 connected\n");4297 bios_0_scratch |= ATOM_S0_DFP4;4298 bios_3_scratch |= ATOM_S3_DFP4_ACTIVE;4299 bios_6_scratch |= ATOM_S6_ACC_REQ_DFP4;4300 } else {4301 DRM_DEBUG_KMS("DFP4 disconnected\n");4302 bios_0_scratch &= ~ATOM_S0_DFP4;4303 bios_3_scratch &= ~ATOM_S3_DFP4_ACTIVE;4304 bios_6_scratch &= ~ATOM_S6_ACC_REQ_DFP4;4305 }4306 }4307 if ((radeon_encoder->devices & ATOM_DEVICE_DFP5_SUPPORT) &&4308 (radeon_connector->devices & ATOM_DEVICE_DFP5_SUPPORT)) {4309 if (connected) {4310 DRM_DEBUG_KMS("DFP5 connected\n");4311 bios_0_scratch |= ATOM_S0_DFP5;4312 bios_3_scratch |= ATOM_S3_DFP5_ACTIVE;4313 bios_6_scratch |= ATOM_S6_ACC_REQ_DFP5;4314 } else {4315 DRM_DEBUG_KMS("DFP5 disconnected\n");4316 bios_0_scratch &= ~ATOM_S0_DFP5;4317 bios_3_scratch &= ~ATOM_S3_DFP5_ACTIVE;4318 bios_6_scratch &= ~ATOM_S6_ACC_REQ_DFP5;4319 }4320 }4321 if ((radeon_encoder->devices & ATOM_DEVICE_DFP6_SUPPORT) &&4322 (radeon_connector->devices & ATOM_DEVICE_DFP6_SUPPORT)) {4323 if (connected) {4324 DRM_DEBUG_KMS("DFP6 connected\n");4325 bios_0_scratch |= ATOM_S0_DFP6;4326 bios_3_scratch |= ATOM_S3_DFP6_ACTIVE;4327 bios_6_scratch |= ATOM_S6_ACC_REQ_DFP6;4328 } else {4329 DRM_DEBUG_KMS("DFP6 disconnected\n");4330 bios_0_scratch &= ~ATOM_S0_DFP6;4331 bios_3_scratch &= ~ATOM_S3_DFP6_ACTIVE;4332 bios_6_scratch &= ~ATOM_S6_ACC_REQ_DFP6;4333 }4334 }4335 4336 if (rdev->family >= CHIP_R600) {4337 WREG32(R600_BIOS_0_SCRATCH, bios_0_scratch);4338 WREG32(R600_BIOS_3_SCRATCH, bios_3_scratch);4339 WREG32(R600_BIOS_6_SCRATCH, bios_6_scratch);4340 } else {4341 WREG32(RADEON_BIOS_0_SCRATCH, bios_0_scratch);4342 WREG32(RADEON_BIOS_3_SCRATCH, bios_3_scratch);4343 WREG32(RADEON_BIOS_6_SCRATCH, bios_6_scratch);4344 }4345}4346 4347void4348radeon_atombios_encoder_crtc_scratch_regs(struct drm_encoder *encoder, int crtc)4349{4350 struct drm_device *dev = encoder->dev;4351 struct radeon_device *rdev = dev->dev_private;4352 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);4353 uint32_t bios_3_scratch;4354 4355 if (ASIC_IS_DCE4(rdev))4356 return;4357 4358 if (rdev->family >= CHIP_R600)4359 bios_3_scratch = RREG32(R600_BIOS_3_SCRATCH);4360 else4361 bios_3_scratch = RREG32(RADEON_BIOS_3_SCRATCH);4362 4363 if (radeon_encoder->devices & ATOM_DEVICE_TV1_SUPPORT) {4364 bios_3_scratch &= ~ATOM_S3_TV1_CRTC_ACTIVE;4365 bios_3_scratch |= (crtc << 18);4366 }4367 if (radeon_encoder->devices & ATOM_DEVICE_CV_SUPPORT) {4368 bios_3_scratch &= ~ATOM_S3_CV_CRTC_ACTIVE;4369 bios_3_scratch |= (crtc << 24);4370 }4371 if (radeon_encoder->devices & ATOM_DEVICE_CRT1_SUPPORT) {4372 bios_3_scratch &= ~ATOM_S3_CRT1_CRTC_ACTIVE;4373 bios_3_scratch |= (crtc << 16);4374 }4375 if (radeon_encoder->devices & ATOM_DEVICE_CRT2_SUPPORT) {4376 bios_3_scratch &= ~ATOM_S3_CRT2_CRTC_ACTIVE;4377 bios_3_scratch |= (crtc << 20);4378 }4379 if (radeon_encoder->devices & ATOM_DEVICE_LCD1_SUPPORT) {4380 bios_3_scratch &= ~ATOM_S3_LCD1_CRTC_ACTIVE;4381 bios_3_scratch |= (crtc << 17);4382 }4383 if (radeon_encoder->devices & ATOM_DEVICE_DFP1_SUPPORT) {4384 bios_3_scratch &= ~ATOM_S3_DFP1_CRTC_ACTIVE;4385 bios_3_scratch |= (crtc << 19);4386 }4387 if (radeon_encoder->devices & ATOM_DEVICE_DFP2_SUPPORT) {4388 bios_3_scratch &= ~ATOM_S3_DFP2_CRTC_ACTIVE;4389 bios_3_scratch |= (crtc << 23);4390 }4391 if (radeon_encoder->devices & ATOM_DEVICE_DFP3_SUPPORT) {4392 bios_3_scratch &= ~ATOM_S3_DFP3_CRTC_ACTIVE;4393 bios_3_scratch |= (crtc << 25);4394 }4395 4396 if (rdev->family >= CHIP_R600)4397 WREG32(R600_BIOS_3_SCRATCH, bios_3_scratch);4398 else4399 WREG32(RADEON_BIOS_3_SCRATCH, bios_3_scratch);4400}4401 4402void4403radeon_atombios_encoder_dpms_scratch_regs(struct drm_encoder *encoder, bool on)4404{4405 struct drm_device *dev = encoder->dev;4406 struct radeon_device *rdev = dev->dev_private;4407 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);4408 uint32_t bios_2_scratch;4409 4410 if (ASIC_IS_DCE4(rdev))4411 return;4412 4413 if (rdev->family >= CHIP_R600)4414 bios_2_scratch = RREG32(R600_BIOS_2_SCRATCH);4415 else4416 bios_2_scratch = RREG32(RADEON_BIOS_2_SCRATCH);4417 4418 if (radeon_encoder->devices & ATOM_DEVICE_TV1_SUPPORT) {4419 if (on)4420 bios_2_scratch &= ~ATOM_S2_TV1_DPMS_STATE;4421 else4422 bios_2_scratch |= ATOM_S2_TV1_DPMS_STATE;4423 }4424 if (radeon_encoder->devices & ATOM_DEVICE_CV_SUPPORT) {4425 if (on)4426 bios_2_scratch &= ~ATOM_S2_CV_DPMS_STATE;4427 else4428 bios_2_scratch |= ATOM_S2_CV_DPMS_STATE;4429 }4430 if (radeon_encoder->devices & ATOM_DEVICE_CRT1_SUPPORT) {4431 if (on)4432 bios_2_scratch &= ~ATOM_S2_CRT1_DPMS_STATE;4433 else4434 bios_2_scratch |= ATOM_S2_CRT1_DPMS_STATE;4435 }4436 if (radeon_encoder->devices & ATOM_DEVICE_CRT2_SUPPORT) {4437 if (on)4438 bios_2_scratch &= ~ATOM_S2_CRT2_DPMS_STATE;4439 else4440 bios_2_scratch |= ATOM_S2_CRT2_DPMS_STATE;4441 }4442 if (radeon_encoder->devices & ATOM_DEVICE_LCD1_SUPPORT) {4443 if (on)4444 bios_2_scratch &= ~ATOM_S2_LCD1_DPMS_STATE;4445 else4446 bios_2_scratch |= ATOM_S2_LCD1_DPMS_STATE;4447 }4448 if (radeon_encoder->devices & ATOM_DEVICE_DFP1_SUPPORT) {4449 if (on)4450 bios_2_scratch &= ~ATOM_S2_DFP1_DPMS_STATE;4451 else4452 bios_2_scratch |= ATOM_S2_DFP1_DPMS_STATE;4453 }4454 if (radeon_encoder->devices & ATOM_DEVICE_DFP2_SUPPORT) {4455 if (on)4456 bios_2_scratch &= ~ATOM_S2_DFP2_DPMS_STATE;4457 else4458 bios_2_scratch |= ATOM_S2_DFP2_DPMS_STATE;4459 }4460 if (radeon_encoder->devices & ATOM_DEVICE_DFP3_SUPPORT) {4461 if (on)4462 bios_2_scratch &= ~ATOM_S2_DFP3_DPMS_STATE;4463 else4464 bios_2_scratch |= ATOM_S2_DFP3_DPMS_STATE;4465 }4466 if (radeon_encoder->devices & ATOM_DEVICE_DFP4_SUPPORT) {4467 if (on)4468 bios_2_scratch &= ~ATOM_S2_DFP4_DPMS_STATE;4469 else4470 bios_2_scratch |= ATOM_S2_DFP4_DPMS_STATE;4471 }4472 if (radeon_encoder->devices & ATOM_DEVICE_DFP5_SUPPORT) {4473 if (on)4474 bios_2_scratch &= ~ATOM_S2_DFP5_DPMS_STATE;4475 else4476 bios_2_scratch |= ATOM_S2_DFP5_DPMS_STATE;4477 }4478 4479 if (rdev->family >= CHIP_R600)4480 WREG32(R600_BIOS_2_SCRATCH, bios_2_scratch);4481 else4482 WREG32(RADEON_BIOS_2_SCRATCH, bios_2_scratch);4483}4484