LCOV - code coverage report
Current view: top level - dev/pci/drm/radeon - radeon_atombios.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 2544 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 68 0.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13