cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

amdgpu_atombios.c (58207B)


      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
     27#include <drm/amdgpu_drm.h>
     28#include "amdgpu.h"
     29#include "amdgpu_atombios.h"
     30#include "amdgpu_atomfirmware.h"
     31#include "amdgpu_i2c.h"
     32#include "amdgpu_display.h"
     33
     34#include "atom.h"
     35#include "atom-bits.h"
     36#include "atombios_encoders.h"
     37#include "bif/bif_4_1_d.h"
     38
     39static void amdgpu_atombios_lookup_i2c_gpio_quirks(struct amdgpu_device *adev,
     40					  ATOM_GPIO_I2C_ASSIGMENT *gpio,
     41					  u8 index)
     42{
     43
     44}
     45
     46static struct amdgpu_i2c_bus_rec amdgpu_atombios_get_bus_rec_for_i2c_gpio(ATOM_GPIO_I2C_ASSIGMENT *gpio)
     47{
     48	struct amdgpu_i2c_bus_rec i2c;
     49
     50	memset(&i2c, 0, sizeof(struct amdgpu_i2c_bus_rec));
     51
     52	i2c.mask_clk_reg = le16_to_cpu(gpio->usClkMaskRegisterIndex);
     53	i2c.mask_data_reg = le16_to_cpu(gpio->usDataMaskRegisterIndex);
     54	i2c.en_clk_reg = le16_to_cpu(gpio->usClkEnRegisterIndex);
     55	i2c.en_data_reg = le16_to_cpu(gpio->usDataEnRegisterIndex);
     56	i2c.y_clk_reg = le16_to_cpu(gpio->usClkY_RegisterIndex);
     57	i2c.y_data_reg = le16_to_cpu(gpio->usDataY_RegisterIndex);
     58	i2c.a_clk_reg = le16_to_cpu(gpio->usClkA_RegisterIndex);
     59	i2c.a_data_reg = le16_to_cpu(gpio->usDataA_RegisterIndex);
     60	i2c.mask_clk_mask = (1 << gpio->ucClkMaskShift);
     61	i2c.mask_data_mask = (1 << gpio->ucDataMaskShift);
     62	i2c.en_clk_mask = (1 << gpio->ucClkEnShift);
     63	i2c.en_data_mask = (1 << gpio->ucDataEnShift);
     64	i2c.y_clk_mask = (1 << gpio->ucClkY_Shift);
     65	i2c.y_data_mask = (1 << gpio->ucDataY_Shift);
     66	i2c.a_clk_mask = (1 << gpio->ucClkA_Shift);
     67	i2c.a_data_mask = (1 << gpio->ucDataA_Shift);
     68
     69	if (gpio->sucI2cId.sbfAccess.bfHW_Capable)
     70		i2c.hw_capable = true;
     71	else
     72		i2c.hw_capable = false;
     73
     74	if (gpio->sucI2cId.ucAccess == 0xa0)
     75		i2c.mm_i2c = true;
     76	else
     77		i2c.mm_i2c = false;
     78
     79	i2c.i2c_id = gpio->sucI2cId.ucAccess;
     80
     81	if (i2c.mask_clk_reg)
     82		i2c.valid = true;
     83	else
     84		i2c.valid = false;
     85
     86	return i2c;
     87}
     88
     89struct amdgpu_i2c_bus_rec amdgpu_atombios_lookup_i2c_gpio(struct amdgpu_device *adev,
     90							  uint8_t id)
     91{
     92	struct atom_context *ctx = adev->mode_info.atom_context;
     93	ATOM_GPIO_I2C_ASSIGMENT *gpio;
     94	struct amdgpu_i2c_bus_rec i2c;
     95	int index = GetIndexIntoMasterTable(DATA, GPIO_I2C_Info);
     96	struct _ATOM_GPIO_I2C_INFO *i2c_info;
     97	uint16_t data_offset, size;
     98	int i, num_indices;
     99
    100	memset(&i2c, 0, sizeof(struct amdgpu_i2c_bus_rec));
    101	i2c.valid = false;
    102
    103	if (amdgpu_atom_parse_data_header(ctx, index, &size, NULL, NULL, &data_offset)) {
    104		i2c_info = (struct _ATOM_GPIO_I2C_INFO *)(ctx->bios + data_offset);
    105
    106		num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) /
    107			sizeof(ATOM_GPIO_I2C_ASSIGMENT);
    108
    109		gpio = &i2c_info->asGPIO_Info[0];
    110		for (i = 0; i < num_indices; i++) {
    111
    112			amdgpu_atombios_lookup_i2c_gpio_quirks(adev, gpio, i);
    113
    114			if (gpio->sucI2cId.ucAccess == id) {
    115				i2c = amdgpu_atombios_get_bus_rec_for_i2c_gpio(gpio);
    116				break;
    117			}
    118			gpio = (ATOM_GPIO_I2C_ASSIGMENT *)
    119				((u8 *)gpio + sizeof(ATOM_GPIO_I2C_ASSIGMENT));
    120		}
    121	}
    122
    123	return i2c;
    124}
    125
    126void amdgpu_atombios_i2c_init(struct amdgpu_device *adev)
    127{
    128	struct atom_context *ctx = adev->mode_info.atom_context;
    129	ATOM_GPIO_I2C_ASSIGMENT *gpio;
    130	struct amdgpu_i2c_bus_rec i2c;
    131	int index = GetIndexIntoMasterTable(DATA, GPIO_I2C_Info);
    132	struct _ATOM_GPIO_I2C_INFO *i2c_info;
    133	uint16_t data_offset, size;
    134	int i, num_indices;
    135	char stmp[32];
    136
    137	if (amdgpu_atom_parse_data_header(ctx, index, &size, NULL, NULL, &data_offset)) {
    138		i2c_info = (struct _ATOM_GPIO_I2C_INFO *)(ctx->bios + data_offset);
    139
    140		num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) /
    141			sizeof(ATOM_GPIO_I2C_ASSIGMENT);
    142
    143		gpio = &i2c_info->asGPIO_Info[0];
    144		for (i = 0; i < num_indices; i++) {
    145			amdgpu_atombios_lookup_i2c_gpio_quirks(adev, gpio, i);
    146
    147			i2c = amdgpu_atombios_get_bus_rec_for_i2c_gpio(gpio);
    148
    149			if (i2c.valid) {
    150				sprintf(stmp, "0x%x", i2c.i2c_id);
    151				adev->i2c_bus[i] = amdgpu_i2c_create(adev_to_drm(adev), &i2c, stmp);
    152			}
    153			gpio = (ATOM_GPIO_I2C_ASSIGMENT *)
    154				((u8 *)gpio + sizeof(ATOM_GPIO_I2C_ASSIGMENT));
    155		}
    156	}
    157}
    158
    159struct amdgpu_gpio_rec
    160amdgpu_atombios_lookup_gpio(struct amdgpu_device *adev,
    161			    u8 id)
    162{
    163	struct atom_context *ctx = adev->mode_info.atom_context;
    164	struct amdgpu_gpio_rec gpio;
    165	int index = GetIndexIntoMasterTable(DATA, GPIO_Pin_LUT);
    166	struct _ATOM_GPIO_PIN_LUT *gpio_info;
    167	ATOM_GPIO_PIN_ASSIGNMENT *pin;
    168	u16 data_offset, size;
    169	int i, num_indices;
    170
    171	memset(&gpio, 0, sizeof(struct amdgpu_gpio_rec));
    172	gpio.valid = false;
    173
    174	if (amdgpu_atom_parse_data_header(ctx, index, &size, NULL, NULL, &data_offset)) {
    175		gpio_info = (struct _ATOM_GPIO_PIN_LUT *)(ctx->bios + data_offset);
    176
    177		num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) /
    178			sizeof(ATOM_GPIO_PIN_ASSIGNMENT);
    179
    180		pin = gpio_info->asGPIO_Pin;
    181		for (i = 0; i < num_indices; i++) {
    182			if (id == pin->ucGPIO_ID) {
    183				gpio.id = pin->ucGPIO_ID;
    184				gpio.reg = le16_to_cpu(pin->usGpioPin_AIndex);
    185				gpio.shift = pin->ucGpioPinBitShift;
    186				gpio.mask = (1 << pin->ucGpioPinBitShift);
    187				gpio.valid = true;
    188				break;
    189			}
    190			pin = (ATOM_GPIO_PIN_ASSIGNMENT *)
    191				((u8 *)pin + sizeof(ATOM_GPIO_PIN_ASSIGNMENT));
    192		}
    193	}
    194
    195	return gpio;
    196}
    197
    198static struct amdgpu_hpd
    199amdgpu_atombios_get_hpd_info_from_gpio(struct amdgpu_device *adev,
    200				       struct amdgpu_gpio_rec *gpio)
    201{
    202	struct amdgpu_hpd hpd;
    203	u32 reg;
    204
    205	memset(&hpd, 0, sizeof(struct amdgpu_hpd));
    206
    207	reg = amdgpu_display_hpd_get_gpio_reg(adev);
    208
    209	hpd.gpio = *gpio;
    210	if (gpio->reg == reg) {
    211		switch(gpio->mask) {
    212		case (1 << 0):
    213			hpd.hpd = AMDGPU_HPD_1;
    214			break;
    215		case (1 << 8):
    216			hpd.hpd = AMDGPU_HPD_2;
    217			break;
    218		case (1 << 16):
    219			hpd.hpd = AMDGPU_HPD_3;
    220			break;
    221		case (1 << 24):
    222			hpd.hpd = AMDGPU_HPD_4;
    223			break;
    224		case (1 << 26):
    225			hpd.hpd = AMDGPU_HPD_5;
    226			break;
    227		case (1 << 28):
    228			hpd.hpd = AMDGPU_HPD_6;
    229			break;
    230		default:
    231			hpd.hpd = AMDGPU_HPD_NONE;
    232			break;
    233		}
    234	} else
    235		hpd.hpd = AMDGPU_HPD_NONE;
    236	return hpd;
    237}
    238
    239static const int object_connector_convert[] = {
    240	DRM_MODE_CONNECTOR_Unknown,
    241	DRM_MODE_CONNECTOR_DVII,
    242	DRM_MODE_CONNECTOR_DVII,
    243	DRM_MODE_CONNECTOR_DVID,
    244	DRM_MODE_CONNECTOR_DVID,
    245	DRM_MODE_CONNECTOR_VGA,
    246	DRM_MODE_CONNECTOR_Composite,
    247	DRM_MODE_CONNECTOR_SVIDEO,
    248	DRM_MODE_CONNECTOR_Unknown,
    249	DRM_MODE_CONNECTOR_Unknown,
    250	DRM_MODE_CONNECTOR_9PinDIN,
    251	DRM_MODE_CONNECTOR_Unknown,
    252	DRM_MODE_CONNECTOR_HDMIA,
    253	DRM_MODE_CONNECTOR_HDMIB,
    254	DRM_MODE_CONNECTOR_LVDS,
    255	DRM_MODE_CONNECTOR_9PinDIN,
    256	DRM_MODE_CONNECTOR_Unknown,
    257	DRM_MODE_CONNECTOR_Unknown,
    258	DRM_MODE_CONNECTOR_Unknown,
    259	DRM_MODE_CONNECTOR_DisplayPort,
    260	DRM_MODE_CONNECTOR_eDP,
    261	DRM_MODE_CONNECTOR_Unknown
    262};
    263
    264bool amdgpu_atombios_has_dce_engine_info(struct amdgpu_device *adev)
    265{
    266	struct amdgpu_mode_info *mode_info = &adev->mode_info;
    267	struct atom_context *ctx = mode_info->atom_context;
    268	int index = GetIndexIntoMasterTable(DATA, Object_Header);
    269	u16 size, data_offset;
    270	u8 frev, crev;
    271	ATOM_DISPLAY_OBJECT_PATH_TABLE *path_obj;
    272	ATOM_OBJECT_HEADER *obj_header;
    273
    274	if (!amdgpu_atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset))
    275		return false;
    276
    277	if (crev < 2)
    278		return false;
    279
    280	obj_header = (ATOM_OBJECT_HEADER *) (ctx->bios + data_offset);
    281	path_obj = (ATOM_DISPLAY_OBJECT_PATH_TABLE *)
    282	    (ctx->bios + data_offset +
    283	     le16_to_cpu(obj_header->usDisplayPathTableOffset));
    284
    285	if (path_obj->ucNumOfDispPath)
    286		return true;
    287	else
    288		return false;
    289}
    290
    291bool amdgpu_atombios_get_connector_info_from_object_table(struct amdgpu_device *adev)
    292{
    293	struct amdgpu_mode_info *mode_info = &adev->mode_info;
    294	struct atom_context *ctx = mode_info->atom_context;
    295	int index = GetIndexIntoMasterTable(DATA, Object_Header);
    296	u16 size, data_offset;
    297	u8 frev, crev;
    298	ATOM_CONNECTOR_OBJECT_TABLE *con_obj;
    299	ATOM_ENCODER_OBJECT_TABLE *enc_obj;
    300	ATOM_OBJECT_TABLE *router_obj;
    301	ATOM_DISPLAY_OBJECT_PATH_TABLE *path_obj;
    302	ATOM_OBJECT_HEADER *obj_header;
    303	int i, j, k, path_size, device_support;
    304	int connector_type;
    305	u16 conn_id, connector_object_id;
    306	struct amdgpu_i2c_bus_rec ddc_bus;
    307	struct amdgpu_router router;
    308	struct amdgpu_gpio_rec gpio;
    309	struct amdgpu_hpd hpd;
    310
    311	if (!amdgpu_atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset))
    312		return false;
    313
    314	if (crev < 2)
    315		return false;
    316
    317	obj_header = (ATOM_OBJECT_HEADER *) (ctx->bios + data_offset);
    318	path_obj = (ATOM_DISPLAY_OBJECT_PATH_TABLE *)
    319	    (ctx->bios + data_offset +
    320	     le16_to_cpu(obj_header->usDisplayPathTableOffset));
    321	con_obj = (ATOM_CONNECTOR_OBJECT_TABLE *)
    322	    (ctx->bios + data_offset +
    323	     le16_to_cpu(obj_header->usConnectorObjectTableOffset));
    324	enc_obj = (ATOM_ENCODER_OBJECT_TABLE *)
    325	    (ctx->bios + data_offset +
    326	     le16_to_cpu(obj_header->usEncoderObjectTableOffset));
    327	router_obj = (ATOM_OBJECT_TABLE *)
    328		(ctx->bios + data_offset +
    329		 le16_to_cpu(obj_header->usRouterObjectTableOffset));
    330	device_support = le16_to_cpu(obj_header->usDeviceSupport);
    331
    332	path_size = 0;
    333	for (i = 0; i < path_obj->ucNumOfDispPath; i++) {
    334		uint8_t *addr = (uint8_t *) path_obj->asDispPath;
    335		ATOM_DISPLAY_OBJECT_PATH *path;
    336		addr += path_size;
    337		path = (ATOM_DISPLAY_OBJECT_PATH *) addr;
    338		path_size += le16_to_cpu(path->usSize);
    339
    340		if (device_support & le16_to_cpu(path->usDeviceTag)) {
    341			uint8_t con_obj_id =
    342			    (le16_to_cpu(path->usConnObjectId) & OBJECT_ID_MASK)
    343			    >> OBJECT_ID_SHIFT;
    344
    345			/* Skip TV/CV support */
    346			if ((le16_to_cpu(path->usDeviceTag) ==
    347			     ATOM_DEVICE_TV1_SUPPORT) ||
    348			    (le16_to_cpu(path->usDeviceTag) ==
    349			     ATOM_DEVICE_CV_SUPPORT))
    350				continue;
    351
    352			if (con_obj_id >= ARRAY_SIZE(object_connector_convert)) {
    353				DRM_ERROR("invalid con_obj_id %d for device tag 0x%04x\n",
    354					  con_obj_id, le16_to_cpu(path->usDeviceTag));
    355				continue;
    356			}
    357
    358			connector_type =
    359				object_connector_convert[con_obj_id];
    360			connector_object_id = con_obj_id;
    361
    362			if (connector_type == DRM_MODE_CONNECTOR_Unknown)
    363				continue;
    364
    365			router.ddc_valid = false;
    366			router.cd_valid = false;
    367			for (j = 0; j < ((le16_to_cpu(path->usSize) - 8) / 2); j++) {
    368				uint8_t grph_obj_type =
    369				    (le16_to_cpu(path->usGraphicObjIds[j]) &
    370				     OBJECT_TYPE_MASK) >> OBJECT_TYPE_SHIFT;
    371
    372				if (grph_obj_type == GRAPH_OBJECT_TYPE_ENCODER) {
    373					for (k = 0; k < enc_obj->ucNumberOfObjects; k++) {
    374						u16 encoder_obj = le16_to_cpu(enc_obj->asObjects[k].usObjectID);
    375						if (le16_to_cpu(path->usGraphicObjIds[j]) == encoder_obj) {
    376							ATOM_COMMON_RECORD_HEADER *record = (ATOM_COMMON_RECORD_HEADER *)
    377								(ctx->bios + data_offset +
    378								 le16_to_cpu(enc_obj->asObjects[k].usRecordOffset));
    379							ATOM_ENCODER_CAP_RECORD *cap_record;
    380							u16 caps = 0;
    381
    382							while (record->ucRecordSize > 0 &&
    383							       record->ucRecordType > 0 &&
    384							       record->ucRecordType <= ATOM_MAX_OBJECT_RECORD_NUMBER) {
    385								switch (record->ucRecordType) {
    386								case ATOM_ENCODER_CAP_RECORD_TYPE:
    387									cap_record =(ATOM_ENCODER_CAP_RECORD *)
    388										record;
    389									caps = le16_to_cpu(cap_record->usEncoderCap);
    390									break;
    391								}
    392								record = (ATOM_COMMON_RECORD_HEADER *)
    393									((char *)record + record->ucRecordSize);
    394							}
    395							amdgpu_display_add_encoder(adev, encoder_obj,
    396										    le16_to_cpu(path->usDeviceTag),
    397										    caps);
    398						}
    399					}
    400				} else if (grph_obj_type == GRAPH_OBJECT_TYPE_ROUTER) {
    401					for (k = 0; k < router_obj->ucNumberOfObjects; k++) {
    402						u16 router_obj_id = le16_to_cpu(router_obj->asObjects[k].usObjectID);
    403						if (le16_to_cpu(path->usGraphicObjIds[j]) == router_obj_id) {
    404							ATOM_COMMON_RECORD_HEADER *record = (ATOM_COMMON_RECORD_HEADER *)
    405								(ctx->bios + data_offset +
    406								 le16_to_cpu(router_obj->asObjects[k].usRecordOffset));
    407							ATOM_I2C_RECORD *i2c_record;
    408							ATOM_I2C_ID_CONFIG_ACCESS *i2c_config;
    409							ATOM_ROUTER_DDC_PATH_SELECT_RECORD *ddc_path;
    410							ATOM_ROUTER_DATA_CLOCK_PATH_SELECT_RECORD *cd_path;
    411							ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT *router_src_dst_table =
    412								(ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT *)
    413								(ctx->bios + data_offset +
    414								 le16_to_cpu(router_obj->asObjects[k].usSrcDstTableOffset));
    415							u8 *num_dst_objs = (u8 *)
    416								((u8 *)router_src_dst_table + 1 +
    417								 (router_src_dst_table->ucNumberOfSrc * 2));
    418							u16 *dst_objs = (u16 *)(num_dst_objs + 1);
    419							int enum_id;
    420
    421							router.router_id = router_obj_id;
    422							for (enum_id = 0; enum_id < (*num_dst_objs); enum_id++) {
    423								if (le16_to_cpu(path->usConnObjectId) ==
    424								    le16_to_cpu(dst_objs[enum_id]))
    425									break;
    426							}
    427
    428							while (record->ucRecordSize > 0 &&
    429							       record->ucRecordType > 0 &&
    430							       record->ucRecordType <= ATOM_MAX_OBJECT_RECORD_NUMBER) {
    431								switch (record->ucRecordType) {
    432								case ATOM_I2C_RECORD_TYPE:
    433									i2c_record =
    434										(ATOM_I2C_RECORD *)
    435										record;
    436									i2c_config =
    437										(ATOM_I2C_ID_CONFIG_ACCESS *)
    438										&i2c_record->sucI2cId;
    439									router.i2c_info =
    440										amdgpu_atombios_lookup_i2c_gpio(adev,
    441												       i2c_config->
    442												       ucAccess);
    443									router.i2c_addr = i2c_record->ucI2CAddr >> 1;
    444									break;
    445								case ATOM_ROUTER_DDC_PATH_SELECT_RECORD_TYPE:
    446									ddc_path = (ATOM_ROUTER_DDC_PATH_SELECT_RECORD *)
    447										record;
    448									router.ddc_valid = true;
    449									router.ddc_mux_type = ddc_path->ucMuxType;
    450									router.ddc_mux_control_pin = ddc_path->ucMuxControlPin;
    451									router.ddc_mux_state = ddc_path->ucMuxState[enum_id];
    452									break;
    453								case ATOM_ROUTER_DATA_CLOCK_PATH_SELECT_RECORD_TYPE:
    454									cd_path = (ATOM_ROUTER_DATA_CLOCK_PATH_SELECT_RECORD *)
    455										record;
    456									router.cd_valid = true;
    457									router.cd_mux_type = cd_path->ucMuxType;
    458									router.cd_mux_control_pin = cd_path->ucMuxControlPin;
    459									router.cd_mux_state = cd_path->ucMuxState[enum_id];
    460									break;
    461								}
    462								record = (ATOM_COMMON_RECORD_HEADER *)
    463									((char *)record + record->ucRecordSize);
    464							}
    465						}
    466					}
    467				}
    468			}
    469
    470			/* look up gpio for ddc, hpd */
    471			ddc_bus.valid = false;
    472			hpd.hpd = AMDGPU_HPD_NONE;
    473			if ((le16_to_cpu(path->usDeviceTag) &
    474			     (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) == 0) {
    475				for (j = 0; j < con_obj->ucNumberOfObjects; j++) {
    476					if (le16_to_cpu(path->usConnObjectId) ==
    477					    le16_to_cpu(con_obj->asObjects[j].
    478							usObjectID)) {
    479						ATOM_COMMON_RECORD_HEADER
    480						    *record =
    481						    (ATOM_COMMON_RECORD_HEADER
    482						     *)
    483						    (ctx->bios + data_offset +
    484						     le16_to_cpu(con_obj->
    485								 asObjects[j].
    486								 usRecordOffset));
    487						ATOM_I2C_RECORD *i2c_record;
    488						ATOM_HPD_INT_RECORD *hpd_record;
    489						ATOM_I2C_ID_CONFIG_ACCESS *i2c_config;
    490
    491						while (record->ucRecordSize > 0 &&
    492						       record->ucRecordType > 0 &&
    493						       record->ucRecordType <= ATOM_MAX_OBJECT_RECORD_NUMBER) {
    494							switch (record->ucRecordType) {
    495							case ATOM_I2C_RECORD_TYPE:
    496								i2c_record =
    497								    (ATOM_I2C_RECORD *)
    498									record;
    499								i2c_config =
    500									(ATOM_I2C_ID_CONFIG_ACCESS *)
    501									&i2c_record->sucI2cId;
    502								ddc_bus = amdgpu_atombios_lookup_i2c_gpio(adev,
    503												 i2c_config->
    504												 ucAccess);
    505								break;
    506							case ATOM_HPD_INT_RECORD_TYPE:
    507								hpd_record =
    508									(ATOM_HPD_INT_RECORD *)
    509									record;
    510								gpio = amdgpu_atombios_lookup_gpio(adev,
    511											  hpd_record->ucHPDIntGPIOID);
    512								hpd = amdgpu_atombios_get_hpd_info_from_gpio(adev, &gpio);
    513								hpd.plugged_state = hpd_record->ucPlugged_PinState;
    514								break;
    515							}
    516							record =
    517							    (ATOM_COMMON_RECORD_HEADER
    518							     *) ((char *)record
    519								 +
    520								 record->
    521								 ucRecordSize);
    522						}
    523						break;
    524					}
    525				}
    526			}
    527
    528			/* needed for aux chan transactions */
    529			ddc_bus.hpd = hpd.hpd;
    530
    531			conn_id = le16_to_cpu(path->usConnObjectId);
    532
    533			amdgpu_display_add_connector(adev,
    534						      conn_id,
    535						      le16_to_cpu(path->usDeviceTag),
    536						      connector_type, &ddc_bus,
    537						      connector_object_id,
    538						      &hpd,
    539						      &router);
    540
    541		}
    542	}
    543
    544	amdgpu_link_encoder_connector(adev_to_drm(adev));
    545
    546	return true;
    547}
    548
    549union firmware_info {
    550	ATOM_FIRMWARE_INFO info;
    551	ATOM_FIRMWARE_INFO_V1_2 info_12;
    552	ATOM_FIRMWARE_INFO_V1_3 info_13;
    553	ATOM_FIRMWARE_INFO_V1_4 info_14;
    554	ATOM_FIRMWARE_INFO_V2_1 info_21;
    555	ATOM_FIRMWARE_INFO_V2_2 info_22;
    556};
    557
    558int amdgpu_atombios_get_clock_info(struct amdgpu_device *adev)
    559{
    560	struct amdgpu_mode_info *mode_info = &adev->mode_info;
    561	int index = GetIndexIntoMasterTable(DATA, FirmwareInfo);
    562	uint8_t frev, crev;
    563	uint16_t data_offset;
    564	int ret = -EINVAL;
    565
    566	if (amdgpu_atom_parse_data_header(mode_info->atom_context, index, NULL,
    567				   &frev, &crev, &data_offset)) {
    568		int i;
    569		struct amdgpu_pll *ppll = &adev->clock.ppll[0];
    570		struct amdgpu_pll *spll = &adev->clock.spll;
    571		struct amdgpu_pll *mpll = &adev->clock.mpll;
    572		union firmware_info *firmware_info =
    573			(union firmware_info *)(mode_info->atom_context->bios +
    574						data_offset);
    575		/* pixel clocks */
    576		ppll->reference_freq =
    577		    le16_to_cpu(firmware_info->info.usReferenceClock);
    578		ppll->reference_div = 0;
    579
    580		ppll->pll_out_min =
    581			le32_to_cpu(firmware_info->info_12.ulMinPixelClockPLL_Output);
    582		ppll->pll_out_max =
    583		    le32_to_cpu(firmware_info->info.ulMaxPixelClockPLL_Output);
    584
    585		ppll->lcd_pll_out_min =
    586			le16_to_cpu(firmware_info->info_14.usLcdMinPixelClockPLL_Output) * 100;
    587		if (ppll->lcd_pll_out_min == 0)
    588			ppll->lcd_pll_out_min = ppll->pll_out_min;
    589		ppll->lcd_pll_out_max =
    590			le16_to_cpu(firmware_info->info_14.usLcdMaxPixelClockPLL_Output) * 100;
    591		if (ppll->lcd_pll_out_max == 0)
    592			ppll->lcd_pll_out_max = ppll->pll_out_max;
    593
    594		if (ppll->pll_out_min == 0)
    595			ppll->pll_out_min = 64800;
    596
    597		ppll->pll_in_min =
    598		    le16_to_cpu(firmware_info->info.usMinPixelClockPLL_Input);
    599		ppll->pll_in_max =
    600		    le16_to_cpu(firmware_info->info.usMaxPixelClockPLL_Input);
    601
    602		ppll->min_post_div = 2;
    603		ppll->max_post_div = 0x7f;
    604		ppll->min_frac_feedback_div = 0;
    605		ppll->max_frac_feedback_div = 9;
    606		ppll->min_ref_div = 2;
    607		ppll->max_ref_div = 0x3ff;
    608		ppll->min_feedback_div = 4;
    609		ppll->max_feedback_div = 0xfff;
    610		ppll->best_vco = 0;
    611
    612		for (i = 1; i < AMDGPU_MAX_PPLL; i++)
    613			adev->clock.ppll[i] = *ppll;
    614
    615		/* system clock */
    616		spll->reference_freq =
    617			le16_to_cpu(firmware_info->info_21.usCoreReferenceClock);
    618		spll->reference_div = 0;
    619
    620		spll->pll_out_min =
    621		    le16_to_cpu(firmware_info->info.usMinEngineClockPLL_Output);
    622		spll->pll_out_max =
    623		    le32_to_cpu(firmware_info->info.ulMaxEngineClockPLL_Output);
    624
    625		/* ??? */
    626		if (spll->pll_out_min == 0)
    627			spll->pll_out_min = 64800;
    628
    629		spll->pll_in_min =
    630		    le16_to_cpu(firmware_info->info.usMinEngineClockPLL_Input);
    631		spll->pll_in_max =
    632		    le16_to_cpu(firmware_info->info.usMaxEngineClockPLL_Input);
    633
    634		spll->min_post_div = 1;
    635		spll->max_post_div = 1;
    636		spll->min_ref_div = 2;
    637		spll->max_ref_div = 0xff;
    638		spll->min_feedback_div = 4;
    639		spll->max_feedback_div = 0xff;
    640		spll->best_vco = 0;
    641
    642		/* memory clock */
    643		mpll->reference_freq =
    644			le16_to_cpu(firmware_info->info_21.usMemoryReferenceClock);
    645		mpll->reference_div = 0;
    646
    647		mpll->pll_out_min =
    648		    le16_to_cpu(firmware_info->info.usMinMemoryClockPLL_Output);
    649		mpll->pll_out_max =
    650		    le32_to_cpu(firmware_info->info.ulMaxMemoryClockPLL_Output);
    651
    652		/* ??? */
    653		if (mpll->pll_out_min == 0)
    654			mpll->pll_out_min = 64800;
    655
    656		mpll->pll_in_min =
    657		    le16_to_cpu(firmware_info->info.usMinMemoryClockPLL_Input);
    658		mpll->pll_in_max =
    659		    le16_to_cpu(firmware_info->info.usMaxMemoryClockPLL_Input);
    660
    661		adev->clock.default_sclk =
    662		    le32_to_cpu(firmware_info->info.ulDefaultEngineClock);
    663		adev->clock.default_mclk =
    664		    le32_to_cpu(firmware_info->info.ulDefaultMemoryClock);
    665
    666		mpll->min_post_div = 1;
    667		mpll->max_post_div = 1;
    668		mpll->min_ref_div = 2;
    669		mpll->max_ref_div = 0xff;
    670		mpll->min_feedback_div = 4;
    671		mpll->max_feedback_div = 0xff;
    672		mpll->best_vco = 0;
    673
    674		/* disp clock */
    675		adev->clock.default_dispclk =
    676			le32_to_cpu(firmware_info->info_21.ulDefaultDispEngineClkFreq);
    677		/* set a reasonable default for DP */
    678		if (adev->clock.default_dispclk < 53900) {
    679			DRM_DEBUG("Changing default dispclk from %dMhz to 600Mhz\n",
    680				  adev->clock.default_dispclk / 100);
    681			adev->clock.default_dispclk = 60000;
    682		} else if (adev->clock.default_dispclk <= 60000) {
    683			DRM_DEBUG("Changing default dispclk from %dMhz to 625Mhz\n",
    684				  adev->clock.default_dispclk / 100);
    685			adev->clock.default_dispclk = 62500;
    686		}
    687		adev->clock.dp_extclk =
    688			le16_to_cpu(firmware_info->info_21.usUniphyDPModeExtClkFreq);
    689		adev->clock.current_dispclk = adev->clock.default_dispclk;
    690
    691		adev->clock.max_pixel_clock = le16_to_cpu(firmware_info->info.usMaxPixelClock);
    692		if (adev->clock.max_pixel_clock == 0)
    693			adev->clock.max_pixel_clock = 40000;
    694
    695		/* not technically a clock, but... */
    696		adev->mode_info.firmware_flags =
    697			le16_to_cpu(firmware_info->info.usFirmwareCapability.susAccess);
    698
    699		ret = 0;
    700	}
    701
    702	adev->pm.current_sclk = adev->clock.default_sclk;
    703	adev->pm.current_mclk = adev->clock.default_mclk;
    704
    705	return ret;
    706}
    707
    708union gfx_info {
    709	ATOM_GFX_INFO_V2_1 info;
    710};
    711
    712int amdgpu_atombios_get_gfx_info(struct amdgpu_device *adev)
    713{
    714	struct amdgpu_mode_info *mode_info = &adev->mode_info;
    715	int index = GetIndexIntoMasterTable(DATA, GFX_Info);
    716	uint8_t frev, crev;
    717	uint16_t data_offset;
    718	int ret = -EINVAL;
    719
    720	if (amdgpu_atom_parse_data_header(mode_info->atom_context, index, NULL,
    721				   &frev, &crev, &data_offset)) {
    722		union gfx_info *gfx_info = (union gfx_info *)
    723			(mode_info->atom_context->bios + data_offset);
    724
    725		adev->gfx.config.max_shader_engines = gfx_info->info.max_shader_engines;
    726		adev->gfx.config.max_tile_pipes = gfx_info->info.max_tile_pipes;
    727		adev->gfx.config.max_cu_per_sh = gfx_info->info.max_cu_per_sh;
    728		adev->gfx.config.max_sh_per_se = gfx_info->info.max_sh_per_se;
    729		adev->gfx.config.max_backends_per_se = gfx_info->info.max_backends_per_se;
    730		adev->gfx.config.max_texture_channel_caches =
    731			gfx_info->info.max_texture_channel_caches;
    732
    733		ret = 0;
    734	}
    735	return ret;
    736}
    737
    738union igp_info {
    739	struct _ATOM_INTEGRATED_SYSTEM_INFO info;
    740	struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 info_2;
    741	struct _ATOM_INTEGRATED_SYSTEM_INFO_V6 info_6;
    742	struct _ATOM_INTEGRATED_SYSTEM_INFO_V1_7 info_7;
    743	struct _ATOM_INTEGRATED_SYSTEM_INFO_V1_8 info_8;
    744	struct _ATOM_INTEGRATED_SYSTEM_INFO_V1_9 info_9;
    745};
    746
    747/*
    748 * Return vram width from integrated system info table, if available,
    749 * or 0 if not.
    750 */
    751int amdgpu_atombios_get_vram_width(struct amdgpu_device *adev)
    752{
    753	struct amdgpu_mode_info *mode_info = &adev->mode_info;
    754	int index = GetIndexIntoMasterTable(DATA, IntegratedSystemInfo);
    755	u16 data_offset, size;
    756	union igp_info *igp_info;
    757	u8 frev, crev;
    758
    759	/* get any igp specific overrides */
    760	if (amdgpu_atom_parse_data_header(mode_info->atom_context, index, &size,
    761				   &frev, &crev, &data_offset)) {
    762		igp_info = (union igp_info *)
    763			(mode_info->atom_context->bios + data_offset);
    764		switch (crev) {
    765		case 8:
    766		case 9:
    767			return igp_info->info_8.ucUMAChannelNumber * 64;
    768		default:
    769			return 0;
    770		}
    771	}
    772
    773	return 0;
    774}
    775
    776static void amdgpu_atombios_get_igp_ss_overrides(struct amdgpu_device *adev,
    777						 struct amdgpu_atom_ss *ss,
    778						 int id)
    779{
    780	struct amdgpu_mode_info *mode_info = &adev->mode_info;
    781	int index = GetIndexIntoMasterTable(DATA, IntegratedSystemInfo);
    782	u16 data_offset, size;
    783	union igp_info *igp_info;
    784	u8 frev, crev;
    785	u16 percentage = 0, rate = 0;
    786
    787	/* get any igp specific overrides */
    788	if (amdgpu_atom_parse_data_header(mode_info->atom_context, index, &size,
    789				   &frev, &crev, &data_offset)) {
    790		igp_info = (union igp_info *)
    791			(mode_info->atom_context->bios + data_offset);
    792		switch (crev) {
    793		case 6:
    794			switch (id) {
    795			case ASIC_INTERNAL_SS_ON_TMDS:
    796				percentage = le16_to_cpu(igp_info->info_6.usDVISSPercentage);
    797				rate = le16_to_cpu(igp_info->info_6.usDVISSpreadRateIn10Hz);
    798				break;
    799			case ASIC_INTERNAL_SS_ON_HDMI:
    800				percentage = le16_to_cpu(igp_info->info_6.usHDMISSPercentage);
    801				rate = le16_to_cpu(igp_info->info_6.usHDMISSpreadRateIn10Hz);
    802				break;
    803			case ASIC_INTERNAL_SS_ON_LVDS:
    804				percentage = le16_to_cpu(igp_info->info_6.usLvdsSSPercentage);
    805				rate = le16_to_cpu(igp_info->info_6.usLvdsSSpreadRateIn10Hz);
    806				break;
    807			}
    808			break;
    809		case 7:
    810			switch (id) {
    811			case ASIC_INTERNAL_SS_ON_TMDS:
    812				percentage = le16_to_cpu(igp_info->info_7.usDVISSPercentage);
    813				rate = le16_to_cpu(igp_info->info_7.usDVISSpreadRateIn10Hz);
    814				break;
    815			case ASIC_INTERNAL_SS_ON_HDMI:
    816				percentage = le16_to_cpu(igp_info->info_7.usHDMISSPercentage);
    817				rate = le16_to_cpu(igp_info->info_7.usHDMISSpreadRateIn10Hz);
    818				break;
    819			case ASIC_INTERNAL_SS_ON_LVDS:
    820				percentage = le16_to_cpu(igp_info->info_7.usLvdsSSPercentage);
    821				rate = le16_to_cpu(igp_info->info_7.usLvdsSSpreadRateIn10Hz);
    822				break;
    823			}
    824			break;
    825		case 8:
    826			switch (id) {
    827			case ASIC_INTERNAL_SS_ON_TMDS:
    828				percentage = le16_to_cpu(igp_info->info_8.usDVISSPercentage);
    829				rate = le16_to_cpu(igp_info->info_8.usDVISSpreadRateIn10Hz);
    830				break;
    831			case ASIC_INTERNAL_SS_ON_HDMI:
    832				percentage = le16_to_cpu(igp_info->info_8.usHDMISSPercentage);
    833				rate = le16_to_cpu(igp_info->info_8.usHDMISSpreadRateIn10Hz);
    834				break;
    835			case ASIC_INTERNAL_SS_ON_LVDS:
    836				percentage = le16_to_cpu(igp_info->info_8.usLvdsSSPercentage);
    837				rate = le16_to_cpu(igp_info->info_8.usLvdsSSpreadRateIn10Hz);
    838				break;
    839			}
    840			break;
    841		case 9:
    842			switch (id) {
    843			case ASIC_INTERNAL_SS_ON_TMDS:
    844				percentage = le16_to_cpu(igp_info->info_9.usDVISSPercentage);
    845				rate = le16_to_cpu(igp_info->info_9.usDVISSpreadRateIn10Hz);
    846				break;
    847			case ASIC_INTERNAL_SS_ON_HDMI:
    848				percentage = le16_to_cpu(igp_info->info_9.usHDMISSPercentage);
    849				rate = le16_to_cpu(igp_info->info_9.usHDMISSpreadRateIn10Hz);
    850				break;
    851			case ASIC_INTERNAL_SS_ON_LVDS:
    852				percentage = le16_to_cpu(igp_info->info_9.usLvdsSSPercentage);
    853				rate = le16_to_cpu(igp_info->info_9.usLvdsSSpreadRateIn10Hz);
    854				break;
    855			}
    856			break;
    857		default:
    858			DRM_ERROR("Unsupported IGP table: %d %d\n", frev, crev);
    859			break;
    860		}
    861		if (percentage)
    862			ss->percentage = percentage;
    863		if (rate)
    864			ss->rate = rate;
    865	}
    866}
    867
    868union asic_ss_info {
    869	struct _ATOM_ASIC_INTERNAL_SS_INFO info;
    870	struct _ATOM_ASIC_INTERNAL_SS_INFO_V2 info_2;
    871	struct _ATOM_ASIC_INTERNAL_SS_INFO_V3 info_3;
    872};
    873
    874union asic_ss_assignment {
    875	struct _ATOM_ASIC_SS_ASSIGNMENT v1;
    876	struct _ATOM_ASIC_SS_ASSIGNMENT_V2 v2;
    877	struct _ATOM_ASIC_SS_ASSIGNMENT_V3 v3;
    878};
    879
    880bool amdgpu_atombios_get_asic_ss_info(struct amdgpu_device *adev,
    881				      struct amdgpu_atom_ss *ss,
    882				      int id, u32 clock)
    883{
    884	struct amdgpu_mode_info *mode_info = &adev->mode_info;
    885	int index = GetIndexIntoMasterTable(DATA, ASIC_InternalSS_Info);
    886	uint16_t data_offset, size;
    887	union asic_ss_info *ss_info;
    888	union asic_ss_assignment *ss_assign;
    889	uint8_t frev, crev;
    890	int i, num_indices;
    891
    892	if (id == ASIC_INTERNAL_MEMORY_SS) {
    893		if (!(adev->mode_info.firmware_flags & ATOM_BIOS_INFO_MEMORY_CLOCK_SS_SUPPORT))
    894			return false;
    895	}
    896	if (id == ASIC_INTERNAL_ENGINE_SS) {
    897		if (!(adev->mode_info.firmware_flags & ATOM_BIOS_INFO_ENGINE_CLOCK_SS_SUPPORT))
    898			return false;
    899	}
    900
    901	memset(ss, 0, sizeof(struct amdgpu_atom_ss));
    902	if (amdgpu_atom_parse_data_header(mode_info->atom_context, index, &size,
    903				   &frev, &crev, &data_offset)) {
    904
    905		ss_info =
    906			(union asic_ss_info *)(mode_info->atom_context->bios + data_offset);
    907
    908		switch (frev) {
    909		case 1:
    910			num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) /
    911				sizeof(ATOM_ASIC_SS_ASSIGNMENT);
    912
    913			ss_assign = (union asic_ss_assignment *)((u8 *)&ss_info->info.asSpreadSpectrum[0]);
    914			for (i = 0; i < num_indices; i++) {
    915				if ((ss_assign->v1.ucClockIndication == id) &&
    916				    (clock <= le32_to_cpu(ss_assign->v1.ulTargetClockRange))) {
    917					ss->percentage =
    918						le16_to_cpu(ss_assign->v1.usSpreadSpectrumPercentage);
    919					ss->type = ss_assign->v1.ucSpreadSpectrumMode;
    920					ss->rate = le16_to_cpu(ss_assign->v1.usSpreadRateInKhz);
    921					ss->percentage_divider = 100;
    922					return true;
    923				}
    924				ss_assign = (union asic_ss_assignment *)
    925					((u8 *)ss_assign + sizeof(ATOM_ASIC_SS_ASSIGNMENT));
    926			}
    927			break;
    928		case 2:
    929			num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) /
    930				sizeof(ATOM_ASIC_SS_ASSIGNMENT_V2);
    931			ss_assign = (union asic_ss_assignment *)((u8 *)&ss_info->info_2.asSpreadSpectrum[0]);
    932			for (i = 0; i < num_indices; i++) {
    933				if ((ss_assign->v2.ucClockIndication == id) &&
    934				    (clock <= le32_to_cpu(ss_assign->v2.ulTargetClockRange))) {
    935					ss->percentage =
    936						le16_to_cpu(ss_assign->v2.usSpreadSpectrumPercentage);
    937					ss->type = ss_assign->v2.ucSpreadSpectrumMode;
    938					ss->rate = le16_to_cpu(ss_assign->v2.usSpreadRateIn10Hz);
    939					ss->percentage_divider = 100;
    940					if ((crev == 2) &&
    941					    ((id == ASIC_INTERNAL_ENGINE_SS) ||
    942					     (id == ASIC_INTERNAL_MEMORY_SS)))
    943						ss->rate /= 100;
    944					return true;
    945				}
    946				ss_assign = (union asic_ss_assignment *)
    947					((u8 *)ss_assign + sizeof(ATOM_ASIC_SS_ASSIGNMENT_V2));
    948			}
    949			break;
    950		case 3:
    951			num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) /
    952				sizeof(ATOM_ASIC_SS_ASSIGNMENT_V3);
    953			ss_assign = (union asic_ss_assignment *)((u8 *)&ss_info->info_3.asSpreadSpectrum[0]);
    954			for (i = 0; i < num_indices; i++) {
    955				if ((ss_assign->v3.ucClockIndication == id) &&
    956				    (clock <= le32_to_cpu(ss_assign->v3.ulTargetClockRange))) {
    957					ss->percentage =
    958						le16_to_cpu(ss_assign->v3.usSpreadSpectrumPercentage);
    959					ss->type = ss_assign->v3.ucSpreadSpectrumMode;
    960					ss->rate = le16_to_cpu(ss_assign->v3.usSpreadRateIn10Hz);
    961					if (ss_assign->v3.ucSpreadSpectrumMode &
    962					    SS_MODE_V3_PERCENTAGE_DIV_BY_1000_MASK)
    963						ss->percentage_divider = 1000;
    964					else
    965						ss->percentage_divider = 100;
    966					if ((id == ASIC_INTERNAL_ENGINE_SS) ||
    967					    (id == ASIC_INTERNAL_MEMORY_SS))
    968						ss->rate /= 100;
    969					if (adev->flags & AMD_IS_APU)
    970						amdgpu_atombios_get_igp_ss_overrides(adev, ss, id);
    971					return true;
    972				}
    973				ss_assign = (union asic_ss_assignment *)
    974					((u8 *)ss_assign + sizeof(ATOM_ASIC_SS_ASSIGNMENT_V3));
    975			}
    976			break;
    977		default:
    978			DRM_ERROR("Unsupported ASIC_InternalSS_Info table: %d %d\n", frev, crev);
    979			break;
    980		}
    981
    982	}
    983	return false;
    984}
    985
    986union get_clock_dividers {
    987	struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS v1;
    988	struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V2 v2;
    989	struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V3 v3;
    990	struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V4 v4;
    991	struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V5 v5;
    992	struct _COMPUTE_GPU_CLOCK_INPUT_PARAMETERS_V1_6 v6_in;
    993	struct _COMPUTE_GPU_CLOCK_OUTPUT_PARAMETERS_V1_6 v6_out;
    994};
    995
    996int amdgpu_atombios_get_clock_dividers(struct amdgpu_device *adev,
    997				       u8 clock_type,
    998				       u32 clock,
    999				       bool strobe_mode,
   1000				       struct atom_clock_dividers *dividers)
   1001{
   1002	union get_clock_dividers args;
   1003	int index = GetIndexIntoMasterTable(COMMAND, ComputeMemoryEnginePLL);
   1004	u8 frev, crev;
   1005
   1006	memset(&args, 0, sizeof(args));
   1007	memset(dividers, 0, sizeof(struct atom_clock_dividers));
   1008
   1009	if (!amdgpu_atom_parse_cmd_header(adev->mode_info.atom_context, index, &frev, &crev))
   1010		return -EINVAL;
   1011
   1012	switch (crev) {
   1013	case 2:
   1014	case 3:
   1015	case 5:
   1016		/* r6xx, r7xx, evergreen, ni, si.
   1017		 * TODO: add support for asic_type <= CHIP_RV770*/
   1018		if (clock_type == COMPUTE_ENGINE_PLL_PARAM) {
   1019			args.v3.ulClockParams = cpu_to_le32((clock_type << 24) | clock);
   1020
   1021			amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args);
   1022
   1023			dividers->post_div = args.v3.ucPostDiv;
   1024			dividers->enable_post_div = (args.v3.ucCntlFlag &
   1025						     ATOM_PLL_CNTL_FLAG_PLL_POST_DIV_EN) ? true : false;
   1026			dividers->enable_dithen = (args.v3.ucCntlFlag &
   1027						   ATOM_PLL_CNTL_FLAG_FRACTION_DISABLE) ? false : true;
   1028			dividers->whole_fb_div = le16_to_cpu(args.v3.ulFbDiv.usFbDiv);
   1029			dividers->frac_fb_div = le16_to_cpu(args.v3.ulFbDiv.usFbDivFrac);
   1030			dividers->ref_div = args.v3.ucRefDiv;
   1031			dividers->vco_mode = (args.v3.ucCntlFlag &
   1032					      ATOM_PLL_CNTL_FLAG_MPLL_VCO_MODE) ? 1 : 0;
   1033		} else {
   1034			/* for SI we use ComputeMemoryClockParam for memory plls */
   1035			if (adev->asic_type >= CHIP_TAHITI)
   1036				return -EINVAL;
   1037			args.v5.ulClockParams = cpu_to_le32((clock_type << 24) | clock);
   1038			if (strobe_mode)
   1039				args.v5.ucInputFlag = ATOM_PLL_INPUT_FLAG_PLL_STROBE_MODE_EN;
   1040
   1041			amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args);
   1042
   1043			dividers->post_div = args.v5.ucPostDiv;
   1044			dividers->enable_post_div = (args.v5.ucCntlFlag &
   1045						     ATOM_PLL_CNTL_FLAG_PLL_POST_DIV_EN) ? true : false;
   1046			dividers->enable_dithen = (args.v5.ucCntlFlag &
   1047						   ATOM_PLL_CNTL_FLAG_FRACTION_DISABLE) ? false : true;
   1048			dividers->whole_fb_div = le16_to_cpu(args.v5.ulFbDiv.usFbDiv);
   1049			dividers->frac_fb_div = le16_to_cpu(args.v5.ulFbDiv.usFbDivFrac);
   1050			dividers->ref_div = args.v5.ucRefDiv;
   1051			dividers->vco_mode = (args.v5.ucCntlFlag &
   1052					      ATOM_PLL_CNTL_FLAG_MPLL_VCO_MODE) ? 1 : 0;
   1053		}
   1054		break;
   1055	case 4:
   1056		/* fusion */
   1057		args.v4.ulClock = cpu_to_le32(clock);	/* 10 khz */
   1058
   1059		amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args);
   1060
   1061		dividers->post_divider = dividers->post_div = args.v4.ucPostDiv;
   1062		dividers->real_clock = le32_to_cpu(args.v4.ulClock);
   1063		break;
   1064	case 6:
   1065		/* CI */
   1066		/* COMPUTE_GPUCLK_INPUT_FLAG_DEFAULT_GPUCLK, COMPUTE_GPUCLK_INPUT_FLAG_SCLK */
   1067		args.v6_in.ulClock.ulComputeClockFlag = clock_type;
   1068		args.v6_in.ulClock.ulClockFreq = cpu_to_le32(clock);	/* 10 khz */
   1069
   1070		amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args);
   1071
   1072		dividers->whole_fb_div = le16_to_cpu(args.v6_out.ulFbDiv.usFbDiv);
   1073		dividers->frac_fb_div = le16_to_cpu(args.v6_out.ulFbDiv.usFbDivFrac);
   1074		dividers->ref_div = args.v6_out.ucPllRefDiv;
   1075		dividers->post_div = args.v6_out.ucPllPostDiv;
   1076		dividers->flags = args.v6_out.ucPllCntlFlag;
   1077		dividers->real_clock = le32_to_cpu(args.v6_out.ulClock.ulClock);
   1078		dividers->post_divider = args.v6_out.ulClock.ucPostDiv;
   1079		break;
   1080	default:
   1081		return -EINVAL;
   1082	}
   1083	return 0;
   1084}
   1085
   1086#ifdef CONFIG_DRM_AMDGPU_SI
   1087int amdgpu_atombios_get_memory_pll_dividers(struct amdgpu_device *adev,
   1088					    u32 clock,
   1089					    bool strobe_mode,
   1090					    struct atom_mpll_param *mpll_param)
   1091{
   1092	COMPUTE_MEMORY_CLOCK_PARAM_PARAMETERS_V2_1 args;
   1093	int index = GetIndexIntoMasterTable(COMMAND, ComputeMemoryClockParam);
   1094	u8 frev, crev;
   1095
   1096	memset(&args, 0, sizeof(args));
   1097	memset(mpll_param, 0, sizeof(struct atom_mpll_param));
   1098
   1099	if (!amdgpu_atom_parse_cmd_header(adev->mode_info.atom_context, index, &frev, &crev))
   1100		return -EINVAL;
   1101
   1102	switch (frev) {
   1103	case 2:
   1104		switch (crev) {
   1105		case 1:
   1106			/* SI */
   1107			args.ulClock = cpu_to_le32(clock);	/* 10 khz */
   1108			args.ucInputFlag = 0;
   1109			if (strobe_mode)
   1110				args.ucInputFlag |= MPLL_INPUT_FLAG_STROBE_MODE_EN;
   1111
   1112			amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args);
   1113
   1114			mpll_param->clkfrac = le16_to_cpu(args.ulFbDiv.usFbDivFrac);
   1115			mpll_param->clkf = le16_to_cpu(args.ulFbDiv.usFbDiv);
   1116			mpll_param->post_div = args.ucPostDiv;
   1117			mpll_param->dll_speed = args.ucDllSpeed;
   1118			mpll_param->bwcntl = args.ucBWCntl;
   1119			mpll_param->vco_mode =
   1120				(args.ucPllCntlFlag & MPLL_CNTL_FLAG_VCO_MODE_MASK);
   1121			mpll_param->yclk_sel =
   1122				(args.ucPllCntlFlag & MPLL_CNTL_FLAG_BYPASS_DQ_PLL) ? 1 : 0;
   1123			mpll_param->qdr =
   1124				(args.ucPllCntlFlag & MPLL_CNTL_FLAG_QDR_ENABLE) ? 1 : 0;
   1125			mpll_param->half_rate =
   1126				(args.ucPllCntlFlag & MPLL_CNTL_FLAG_AD_HALF_RATE) ? 1 : 0;
   1127			break;
   1128		default:
   1129			return -EINVAL;
   1130		}
   1131		break;
   1132	default:
   1133		return -EINVAL;
   1134	}
   1135	return 0;
   1136}
   1137
   1138void amdgpu_atombios_set_engine_dram_timings(struct amdgpu_device *adev,
   1139					     u32 eng_clock, u32 mem_clock)
   1140{
   1141	SET_ENGINE_CLOCK_PS_ALLOCATION args;
   1142	int index = GetIndexIntoMasterTable(COMMAND, DynamicMemorySettings);
   1143	u32 tmp;
   1144
   1145	memset(&args, 0, sizeof(args));
   1146
   1147	tmp = eng_clock & SET_CLOCK_FREQ_MASK;
   1148	tmp |= (COMPUTE_ENGINE_PLL_PARAM << 24);
   1149
   1150	args.ulTargetEngineClock = cpu_to_le32(tmp);
   1151	if (mem_clock)
   1152		args.sReserved.ulClock = cpu_to_le32(mem_clock & SET_CLOCK_FREQ_MASK);
   1153
   1154	amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args);
   1155}
   1156
   1157void amdgpu_atombios_get_default_voltages(struct amdgpu_device *adev,
   1158					  u16 *vddc, u16 *vddci, u16 *mvdd)
   1159{
   1160	struct amdgpu_mode_info *mode_info = &adev->mode_info;
   1161	int index = GetIndexIntoMasterTable(DATA, FirmwareInfo);
   1162	u8 frev, crev;
   1163	u16 data_offset;
   1164	union firmware_info *firmware_info;
   1165
   1166	*vddc = 0;
   1167	*vddci = 0;
   1168	*mvdd = 0;
   1169
   1170	if (amdgpu_atom_parse_data_header(mode_info->atom_context, index, NULL,
   1171				   &frev, &crev, &data_offset)) {
   1172		firmware_info =
   1173			(union firmware_info *)(mode_info->atom_context->bios +
   1174						data_offset);
   1175		*vddc = le16_to_cpu(firmware_info->info_14.usBootUpVDDCVoltage);
   1176		if ((frev == 2) && (crev >= 2)) {
   1177			*vddci = le16_to_cpu(firmware_info->info_22.usBootUpVDDCIVoltage);
   1178			*mvdd = le16_to_cpu(firmware_info->info_22.usBootUpMVDDCVoltage);
   1179		}
   1180	}
   1181}
   1182
   1183union set_voltage {
   1184	struct _SET_VOLTAGE_PS_ALLOCATION alloc;
   1185	struct _SET_VOLTAGE_PARAMETERS v1;
   1186	struct _SET_VOLTAGE_PARAMETERS_V2 v2;
   1187	struct _SET_VOLTAGE_PARAMETERS_V1_3 v3;
   1188};
   1189
   1190int amdgpu_atombios_get_max_vddc(struct amdgpu_device *adev, u8 voltage_type,
   1191			     u16 voltage_id, u16 *voltage)
   1192{
   1193	union set_voltage args;
   1194	int index = GetIndexIntoMasterTable(COMMAND, SetVoltage);
   1195	u8 frev, crev;
   1196
   1197	if (!amdgpu_atom_parse_cmd_header(adev->mode_info.atom_context, index, &frev, &crev))
   1198		return -EINVAL;
   1199
   1200	switch (crev) {
   1201	case 1:
   1202		return -EINVAL;
   1203	case 2:
   1204		args.v2.ucVoltageType = SET_VOLTAGE_GET_MAX_VOLTAGE;
   1205		args.v2.ucVoltageMode = 0;
   1206		args.v2.usVoltageLevel = 0;
   1207
   1208		amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args);
   1209
   1210		*voltage = le16_to_cpu(args.v2.usVoltageLevel);
   1211		break;
   1212	case 3:
   1213		args.v3.ucVoltageType = voltage_type;
   1214		args.v3.ucVoltageMode = ATOM_GET_VOLTAGE_LEVEL;
   1215		args.v3.usVoltageLevel = cpu_to_le16(voltage_id);
   1216
   1217		amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args);
   1218
   1219		*voltage = le16_to_cpu(args.v3.usVoltageLevel);
   1220		break;
   1221	default:
   1222		DRM_ERROR("Unknown table version %d, %d\n", frev, crev);
   1223		return -EINVAL;
   1224	}
   1225
   1226	return 0;
   1227}
   1228
   1229int amdgpu_atombios_get_leakage_vddc_based_on_leakage_idx(struct amdgpu_device *adev,
   1230						      u16 *voltage,
   1231						      u16 leakage_idx)
   1232{
   1233	return amdgpu_atombios_get_max_vddc(adev, VOLTAGE_TYPE_VDDC, leakage_idx, voltage);
   1234}
   1235
   1236union voltage_object_info {
   1237	struct _ATOM_VOLTAGE_OBJECT_INFO v1;
   1238	struct _ATOM_VOLTAGE_OBJECT_INFO_V2 v2;
   1239	struct _ATOM_VOLTAGE_OBJECT_INFO_V3_1 v3;
   1240};
   1241
   1242union voltage_object {
   1243	struct _ATOM_VOLTAGE_OBJECT v1;
   1244	struct _ATOM_VOLTAGE_OBJECT_V2 v2;
   1245	union _ATOM_VOLTAGE_OBJECT_V3 v3;
   1246};
   1247
   1248
   1249static ATOM_VOLTAGE_OBJECT_V3 *amdgpu_atombios_lookup_voltage_object_v3(ATOM_VOLTAGE_OBJECT_INFO_V3_1 *v3,
   1250									u8 voltage_type, u8 voltage_mode)
   1251{
   1252	u32 size = le16_to_cpu(v3->sHeader.usStructureSize);
   1253	u32 offset = offsetof(ATOM_VOLTAGE_OBJECT_INFO_V3_1, asVoltageObj[0]);
   1254	u8 *start = (u8 *)v3;
   1255
   1256	while (offset < size) {
   1257		ATOM_VOLTAGE_OBJECT_V3 *vo = (ATOM_VOLTAGE_OBJECT_V3 *)(start + offset);
   1258		if ((vo->asGpioVoltageObj.sHeader.ucVoltageType == voltage_type) &&
   1259		    (vo->asGpioVoltageObj.sHeader.ucVoltageMode == voltage_mode))
   1260			return vo;
   1261		offset += le16_to_cpu(vo->asGpioVoltageObj.sHeader.usSize);
   1262	}
   1263	return NULL;
   1264}
   1265
   1266int amdgpu_atombios_get_svi2_info(struct amdgpu_device *adev,
   1267			      u8 voltage_type,
   1268			      u8 *svd_gpio_id, u8 *svc_gpio_id)
   1269{
   1270	int index = GetIndexIntoMasterTable(DATA, VoltageObjectInfo);
   1271	u8 frev, crev;
   1272	u16 data_offset, size;
   1273	union voltage_object_info *voltage_info;
   1274	union voltage_object *voltage_object = NULL;
   1275
   1276	if (amdgpu_atom_parse_data_header(adev->mode_info.atom_context, index, &size,
   1277				   &frev, &crev, &data_offset)) {
   1278		voltage_info = (union voltage_object_info *)
   1279			(adev->mode_info.atom_context->bios + data_offset);
   1280
   1281		switch (frev) {
   1282		case 3:
   1283			switch (crev) {
   1284			case 1:
   1285				voltage_object = (union voltage_object *)
   1286					amdgpu_atombios_lookup_voltage_object_v3(&voltage_info->v3,
   1287								      voltage_type,
   1288								      VOLTAGE_OBJ_SVID2);
   1289				if (voltage_object) {
   1290					*svd_gpio_id = voltage_object->v3.asSVID2Obj.ucSVDGpioId;
   1291					*svc_gpio_id = voltage_object->v3.asSVID2Obj.ucSVCGpioId;
   1292				} else {
   1293					return -EINVAL;
   1294				}
   1295				break;
   1296			default:
   1297				DRM_ERROR("unknown voltage object table\n");
   1298				return -EINVAL;
   1299			}
   1300			break;
   1301		default:
   1302			DRM_ERROR("unknown voltage object table\n");
   1303			return -EINVAL;
   1304		}
   1305
   1306	}
   1307	return 0;
   1308}
   1309
   1310bool
   1311amdgpu_atombios_is_voltage_gpio(struct amdgpu_device *adev,
   1312				u8 voltage_type, u8 voltage_mode)
   1313{
   1314	int index = GetIndexIntoMasterTable(DATA, VoltageObjectInfo);
   1315	u8 frev, crev;
   1316	u16 data_offset, size;
   1317	union voltage_object_info *voltage_info;
   1318
   1319	if (amdgpu_atom_parse_data_header(adev->mode_info.atom_context, index, &size,
   1320				   &frev, &crev, &data_offset)) {
   1321		voltage_info = (union voltage_object_info *)
   1322			(adev->mode_info.atom_context->bios + data_offset);
   1323
   1324		switch (frev) {
   1325		case 3:
   1326			switch (crev) {
   1327			case 1:
   1328				if (amdgpu_atombios_lookup_voltage_object_v3(&voltage_info->v3,
   1329								  voltage_type, voltage_mode))
   1330					return true;
   1331				break;
   1332			default:
   1333				DRM_ERROR("unknown voltage object table\n");
   1334				return false;
   1335			}
   1336			break;
   1337		default:
   1338			DRM_ERROR("unknown voltage object table\n");
   1339			return false;
   1340		}
   1341
   1342	}
   1343	return false;
   1344}
   1345
   1346int amdgpu_atombios_get_voltage_table(struct amdgpu_device *adev,
   1347				      u8 voltage_type, u8 voltage_mode,
   1348				      struct atom_voltage_table *voltage_table)
   1349{
   1350	int index = GetIndexIntoMasterTable(DATA, VoltageObjectInfo);
   1351	u8 frev, crev;
   1352	u16 data_offset, size;
   1353	int i;
   1354	union voltage_object_info *voltage_info;
   1355	union voltage_object *voltage_object = NULL;
   1356
   1357	if (amdgpu_atom_parse_data_header(adev->mode_info.atom_context, index, &size,
   1358				   &frev, &crev, &data_offset)) {
   1359		voltage_info = (union voltage_object_info *)
   1360			(adev->mode_info.atom_context->bios + data_offset);
   1361
   1362		switch (frev) {
   1363		case 3:
   1364			switch (crev) {
   1365			case 1:
   1366				voltage_object = (union voltage_object *)
   1367					amdgpu_atombios_lookup_voltage_object_v3(&voltage_info->v3,
   1368								      voltage_type, voltage_mode);
   1369				if (voltage_object) {
   1370					ATOM_GPIO_VOLTAGE_OBJECT_V3 *gpio =
   1371						&voltage_object->v3.asGpioVoltageObj;
   1372					VOLTAGE_LUT_ENTRY_V2 *lut;
   1373					if (gpio->ucGpioEntryNum > MAX_VOLTAGE_ENTRIES)
   1374						return -EINVAL;
   1375					lut = &gpio->asVolGpioLut[0];
   1376					for (i = 0; i < gpio->ucGpioEntryNum; i++) {
   1377						voltage_table->entries[i].value =
   1378							le16_to_cpu(lut->usVoltageValue);
   1379						voltage_table->entries[i].smio_low =
   1380							le32_to_cpu(lut->ulVoltageId);
   1381						lut = (VOLTAGE_LUT_ENTRY_V2 *)
   1382							((u8 *)lut + sizeof(VOLTAGE_LUT_ENTRY_V2));
   1383					}
   1384					voltage_table->mask_low = le32_to_cpu(gpio->ulGpioMaskVal);
   1385					voltage_table->count = gpio->ucGpioEntryNum;
   1386					voltage_table->phase_delay = gpio->ucPhaseDelay;
   1387					return 0;
   1388				}
   1389				break;
   1390			default:
   1391				DRM_ERROR("unknown voltage object table\n");
   1392				return -EINVAL;
   1393			}
   1394			break;
   1395		default:
   1396			DRM_ERROR("unknown voltage object table\n");
   1397			return -EINVAL;
   1398		}
   1399	}
   1400	return -EINVAL;
   1401}
   1402
   1403union vram_info {
   1404	struct _ATOM_VRAM_INFO_V3 v1_3;
   1405	struct _ATOM_VRAM_INFO_V4 v1_4;
   1406	struct _ATOM_VRAM_INFO_HEADER_V2_1 v2_1;
   1407};
   1408
   1409#define MEM_ID_MASK           0xff000000
   1410#define MEM_ID_SHIFT          24
   1411#define CLOCK_RANGE_MASK      0x00ffffff
   1412#define CLOCK_RANGE_SHIFT     0
   1413#define LOW_NIBBLE_MASK       0xf
   1414#define DATA_EQU_PREV         0
   1415#define DATA_FROM_TABLE       4
   1416
   1417int amdgpu_atombios_init_mc_reg_table(struct amdgpu_device *adev,
   1418				      u8 module_index,
   1419				      struct atom_mc_reg_table *reg_table)
   1420{
   1421	int index = GetIndexIntoMasterTable(DATA, VRAM_Info);
   1422	u8 frev, crev, num_entries, t_mem_id, num_ranges = 0;
   1423	u32 i = 0, j;
   1424	u16 data_offset, size;
   1425	union vram_info *vram_info;
   1426
   1427	memset(reg_table, 0, sizeof(struct atom_mc_reg_table));
   1428
   1429	if (amdgpu_atom_parse_data_header(adev->mode_info.atom_context, index, &size,
   1430				   &frev, &crev, &data_offset)) {
   1431		vram_info = (union vram_info *)
   1432			(adev->mode_info.atom_context->bios + data_offset);
   1433		switch (frev) {
   1434		case 1:
   1435			DRM_ERROR("old table version %d, %d\n", frev, crev);
   1436			return -EINVAL;
   1437		case 2:
   1438			switch (crev) {
   1439			case 1:
   1440				if (module_index < vram_info->v2_1.ucNumOfVRAMModule) {
   1441					ATOM_INIT_REG_BLOCK *reg_block =
   1442						(ATOM_INIT_REG_BLOCK *)
   1443						((u8 *)vram_info + le16_to_cpu(vram_info->v2_1.usMemClkPatchTblOffset));
   1444					ATOM_MEMORY_SETTING_DATA_BLOCK *reg_data =
   1445						(ATOM_MEMORY_SETTING_DATA_BLOCK *)
   1446						((u8 *)reg_block + (2 * sizeof(u16)) +
   1447						 le16_to_cpu(reg_block->usRegIndexTblSize));
   1448					ATOM_INIT_REG_INDEX_FORMAT *format = &reg_block->asRegIndexBuf[0];
   1449					num_entries = (u8)((le16_to_cpu(reg_block->usRegIndexTblSize)) /
   1450							   sizeof(ATOM_INIT_REG_INDEX_FORMAT)) - 1;
   1451					if (num_entries > VBIOS_MC_REGISTER_ARRAY_SIZE)
   1452						return -EINVAL;
   1453					while (i < num_entries) {
   1454						if (format->ucPreRegDataLength & ACCESS_PLACEHOLDER)
   1455							break;
   1456						reg_table->mc_reg_address[i].s1 =
   1457							(u16)(le16_to_cpu(format->usRegIndex));
   1458						reg_table->mc_reg_address[i].pre_reg_data =
   1459							(u8)(format->ucPreRegDataLength);
   1460						i++;
   1461						format = (ATOM_INIT_REG_INDEX_FORMAT *)
   1462							((u8 *)format + sizeof(ATOM_INIT_REG_INDEX_FORMAT));
   1463					}
   1464					reg_table->last = i;
   1465					while ((le32_to_cpu(*(u32 *)reg_data) != END_OF_REG_DATA_BLOCK) &&
   1466					       (num_ranges < VBIOS_MAX_AC_TIMING_ENTRIES)) {
   1467						t_mem_id = (u8)((le32_to_cpu(*(u32 *)reg_data) & MEM_ID_MASK)
   1468								>> MEM_ID_SHIFT);
   1469						if (module_index == t_mem_id) {
   1470							reg_table->mc_reg_table_entry[num_ranges].mclk_max =
   1471								(u32)((le32_to_cpu(*(u32 *)reg_data) & CLOCK_RANGE_MASK)
   1472								      >> CLOCK_RANGE_SHIFT);
   1473							for (i = 0, j = 1; i < reg_table->last; i++) {
   1474								if ((reg_table->mc_reg_address[i].pre_reg_data & LOW_NIBBLE_MASK) == DATA_FROM_TABLE) {
   1475									reg_table->mc_reg_table_entry[num_ranges].mc_data[i] =
   1476										(u32)le32_to_cpu(*((u32 *)reg_data + j));
   1477									j++;
   1478								} else if ((reg_table->mc_reg_address[i].pre_reg_data & LOW_NIBBLE_MASK) == DATA_EQU_PREV) {
   1479									reg_table->mc_reg_table_entry[num_ranges].mc_data[i] =
   1480										reg_table->mc_reg_table_entry[num_ranges].mc_data[i - 1];
   1481								}
   1482							}
   1483							num_ranges++;
   1484						}
   1485						reg_data = (ATOM_MEMORY_SETTING_DATA_BLOCK *)
   1486							((u8 *)reg_data + le16_to_cpu(reg_block->usRegDataBlkSize));
   1487					}
   1488					if (le32_to_cpu(*(u32 *)reg_data) != END_OF_REG_DATA_BLOCK)
   1489						return -EINVAL;
   1490					reg_table->num_entries = num_ranges;
   1491				} else
   1492					return -EINVAL;
   1493				break;
   1494			default:
   1495				DRM_ERROR("Unknown table version %d, %d\n", frev, crev);
   1496				return -EINVAL;
   1497			}
   1498			break;
   1499		default:
   1500			DRM_ERROR("Unknown table version %d, %d\n", frev, crev);
   1501			return -EINVAL;
   1502		}
   1503		return 0;
   1504	}
   1505	return -EINVAL;
   1506}
   1507#endif
   1508
   1509bool amdgpu_atombios_has_gpu_virtualization_table(struct amdgpu_device *adev)
   1510{
   1511	int index = GetIndexIntoMasterTable(DATA, GPUVirtualizationInfo);
   1512	u8 frev, crev;
   1513	u16 data_offset, size;
   1514
   1515	if (amdgpu_atom_parse_data_header(adev->mode_info.atom_context, index, &size,
   1516					  &frev, &crev, &data_offset))
   1517		return true;
   1518
   1519	return false;
   1520}
   1521
   1522void amdgpu_atombios_scratch_regs_lock(struct amdgpu_device *adev, bool lock)
   1523{
   1524	uint32_t bios_6_scratch;
   1525
   1526	bios_6_scratch = RREG32(adev->bios_scratch_reg_offset + 6);
   1527
   1528	if (lock) {
   1529		bios_6_scratch |= ATOM_S6_CRITICAL_STATE;
   1530		bios_6_scratch &= ~ATOM_S6_ACC_MODE;
   1531	} else {
   1532		bios_6_scratch &= ~ATOM_S6_CRITICAL_STATE;
   1533		bios_6_scratch |= ATOM_S6_ACC_MODE;
   1534	}
   1535
   1536	WREG32(adev->bios_scratch_reg_offset + 6, bios_6_scratch);
   1537}
   1538
   1539static void amdgpu_atombios_scratch_regs_init(struct amdgpu_device *adev)
   1540{
   1541	uint32_t bios_2_scratch, bios_6_scratch;
   1542
   1543	adev->bios_scratch_reg_offset = mmBIOS_SCRATCH_0;
   1544
   1545	bios_2_scratch = RREG32(adev->bios_scratch_reg_offset + 2);
   1546	bios_6_scratch = RREG32(adev->bios_scratch_reg_offset + 6);
   1547
   1548	/* let the bios control the backlight */
   1549	bios_2_scratch &= ~ATOM_S2_VRI_BRIGHT_ENABLE;
   1550
   1551	/* tell the bios not to handle mode switching */
   1552	bios_6_scratch |= ATOM_S6_ACC_BLOCK_DISPLAY_SWITCH;
   1553
   1554	/* clear the vbios dpms state */
   1555	bios_2_scratch &= ~ATOM_S2_DEVICE_DPMS_STATE;
   1556
   1557	WREG32(adev->bios_scratch_reg_offset + 2, bios_2_scratch);
   1558	WREG32(adev->bios_scratch_reg_offset + 6, bios_6_scratch);
   1559}
   1560
   1561void amdgpu_atombios_scratch_regs_engine_hung(struct amdgpu_device *adev,
   1562					      bool hung)
   1563{
   1564	u32 tmp = RREG32(adev->bios_scratch_reg_offset + 3);
   1565
   1566	if (hung)
   1567		tmp |= ATOM_S3_ASIC_GUI_ENGINE_HUNG;
   1568	else
   1569		tmp &= ~ATOM_S3_ASIC_GUI_ENGINE_HUNG;
   1570
   1571	WREG32(adev->bios_scratch_reg_offset + 3, tmp);
   1572}
   1573
   1574void amdgpu_atombios_scratch_regs_set_backlight_level(struct amdgpu_device *adev,
   1575						      u32 backlight_level)
   1576{
   1577	u32 tmp = RREG32(adev->bios_scratch_reg_offset + 2);
   1578
   1579	tmp &= ~ATOM_S2_CURRENT_BL_LEVEL_MASK;
   1580	tmp |= (backlight_level << ATOM_S2_CURRENT_BL_LEVEL_SHIFT) &
   1581		ATOM_S2_CURRENT_BL_LEVEL_MASK;
   1582
   1583	WREG32(adev->bios_scratch_reg_offset + 2, tmp);
   1584}
   1585
   1586bool amdgpu_atombios_scratch_need_asic_init(struct amdgpu_device *adev)
   1587{
   1588	u32 tmp = RREG32(adev->bios_scratch_reg_offset + 7);
   1589
   1590	if (tmp & ATOM_S7_ASIC_INIT_COMPLETE_MASK)
   1591		return false;
   1592	else
   1593		return true;
   1594}
   1595
   1596/* Atom needs data in little endian format so swap as appropriate when copying
   1597 * data to or from atom. Note that atom operates on dw units.
   1598 *
   1599 * Use to_le=true when sending data to atom and provide at least
   1600 * ALIGN(num_bytes,4) bytes in the dst buffer.
   1601 *
   1602 * Use to_le=false when receiving data from atom and provide ALIGN(num_bytes,4)
   1603 * byes in the src buffer.
   1604 */
   1605void amdgpu_atombios_copy_swap(u8 *dst, u8 *src, u8 num_bytes, bool to_le)
   1606{
   1607#ifdef __BIG_ENDIAN
   1608	u32 src_tmp[5], dst_tmp[5];
   1609	int i;
   1610	u8 align_num_bytes = ALIGN(num_bytes, 4);
   1611
   1612	if (to_le) {
   1613		memcpy(src_tmp, src, num_bytes);
   1614		for (i = 0; i < align_num_bytes / 4; i++)
   1615			dst_tmp[i] = cpu_to_le32(src_tmp[i]);
   1616		memcpy(dst, dst_tmp, align_num_bytes);
   1617	} else {
   1618		memcpy(src_tmp, src, align_num_bytes);
   1619		for (i = 0; i < align_num_bytes / 4; i++)
   1620			dst_tmp[i] = le32_to_cpu(src_tmp[i]);
   1621		memcpy(dst, dst_tmp, num_bytes);
   1622	}
   1623#else
   1624	memcpy(dst, src, num_bytes);
   1625#endif
   1626}
   1627
   1628static int amdgpu_atombios_allocate_fb_scratch(struct amdgpu_device *adev)
   1629{
   1630	struct atom_context *ctx = adev->mode_info.atom_context;
   1631	int index = GetIndexIntoMasterTable(DATA, VRAM_UsageByFirmware);
   1632	uint16_t data_offset;
   1633	int usage_bytes = 0;
   1634	struct _ATOM_VRAM_USAGE_BY_FIRMWARE *firmware_usage;
   1635	u64 start_addr;
   1636	u64 size;
   1637
   1638	if (amdgpu_atom_parse_data_header(ctx, index, NULL, NULL, NULL, &data_offset)) {
   1639		firmware_usage = (struct _ATOM_VRAM_USAGE_BY_FIRMWARE *)(ctx->bios + data_offset);
   1640
   1641		DRM_DEBUG("atom firmware requested %08x %dkb\n",
   1642			  le32_to_cpu(firmware_usage->asFirmwareVramReserveInfo[0].ulStartAddrUsedByFirmware),
   1643			  le16_to_cpu(firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb));
   1644
   1645		start_addr = firmware_usage->asFirmwareVramReserveInfo[0].ulStartAddrUsedByFirmware;
   1646		size = firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb;
   1647
   1648		if ((uint32_t)(start_addr & ATOM_VRAM_OPERATION_FLAGS_MASK) ==
   1649			(uint32_t)(ATOM_VRAM_BLOCK_SRIOV_MSG_SHARE_RESERVATION <<
   1650			ATOM_VRAM_OPERATION_FLAGS_SHIFT)) {
   1651			/* Firmware request VRAM reservation for SR-IOV */
   1652			adev->mman.fw_vram_usage_start_offset = (start_addr &
   1653				(~ATOM_VRAM_OPERATION_FLAGS_MASK)) << 10;
   1654			adev->mman.fw_vram_usage_size = size << 10;
   1655			/* Use the default scratch size */
   1656			usage_bytes = 0;
   1657		} else {
   1658			usage_bytes = le16_to_cpu(firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb) * 1024;
   1659		}
   1660	}
   1661	ctx->scratch_size_bytes = 0;
   1662	if (usage_bytes == 0)
   1663		usage_bytes = 20 * 1024;
   1664	/* allocate some scratch memory */
   1665	ctx->scratch = kzalloc(usage_bytes, GFP_KERNEL);
   1666	if (!ctx->scratch)
   1667		return -ENOMEM;
   1668	ctx->scratch_size_bytes = usage_bytes;
   1669	return 0;
   1670}
   1671
   1672/* ATOM accessor methods */
   1673/*
   1674 * ATOM is an interpreted byte code stored in tables in the vbios.  The
   1675 * driver registers callbacks to access registers and the interpreter
   1676 * in the driver parses the tables and executes then to program specific
   1677 * actions (set display modes, asic init, etc.).  See amdgpu_atombios.c,
   1678 * atombios.h, and atom.c
   1679 */
   1680
   1681/**
   1682 * cail_pll_read - read PLL register
   1683 *
   1684 * @info: atom card_info pointer
   1685 * @reg: PLL register offset
   1686 *
   1687 * Provides a PLL register accessor for the atom interpreter (r4xx+).
   1688 * Returns the value of the PLL register.
   1689 */
   1690static uint32_t cail_pll_read(struct card_info *info, uint32_t reg)
   1691{
   1692	return 0;
   1693}
   1694
   1695/**
   1696 * cail_pll_write - write PLL register
   1697 *
   1698 * @info: atom card_info pointer
   1699 * @reg: PLL register offset
   1700 * @val: value to write to the pll register
   1701 *
   1702 * Provides a PLL register accessor for the atom interpreter (r4xx+).
   1703 */
   1704static void cail_pll_write(struct card_info *info, uint32_t reg, uint32_t val)
   1705{
   1706
   1707}
   1708
   1709/**
   1710 * cail_mc_read - read MC (Memory Controller) register
   1711 *
   1712 * @info: atom card_info pointer
   1713 * @reg: MC register offset
   1714 *
   1715 * Provides an MC register accessor for the atom interpreter (r4xx+).
   1716 * Returns the value of the MC register.
   1717 */
   1718static uint32_t cail_mc_read(struct card_info *info, uint32_t reg)
   1719{
   1720	return 0;
   1721}
   1722
   1723/**
   1724 * cail_mc_write - write MC (Memory Controller) register
   1725 *
   1726 * @info: atom card_info pointer
   1727 * @reg: MC register offset
   1728 * @val: value to write to the pll register
   1729 *
   1730 * Provides a MC register accessor for the atom interpreter (r4xx+).
   1731 */
   1732static void cail_mc_write(struct card_info *info, uint32_t reg, uint32_t val)
   1733{
   1734
   1735}
   1736
   1737/**
   1738 * cail_reg_write - write MMIO register
   1739 *
   1740 * @info: atom card_info pointer
   1741 * @reg: MMIO register offset
   1742 * @val: value to write to the pll register
   1743 *
   1744 * Provides a MMIO register accessor for the atom interpreter (r4xx+).
   1745 */
   1746static void cail_reg_write(struct card_info *info, uint32_t reg, uint32_t val)
   1747{
   1748	struct amdgpu_device *adev = drm_to_adev(info->dev);
   1749
   1750	WREG32(reg, val);
   1751}
   1752
   1753/**
   1754 * cail_reg_read - read MMIO register
   1755 *
   1756 * @info: atom card_info pointer
   1757 * @reg: MMIO register offset
   1758 *
   1759 * Provides an MMIO register accessor for the atom interpreter (r4xx+).
   1760 * Returns the value of the MMIO register.
   1761 */
   1762static uint32_t cail_reg_read(struct card_info *info, uint32_t reg)
   1763{
   1764	struct amdgpu_device *adev = drm_to_adev(info->dev);
   1765	uint32_t r;
   1766
   1767	r = RREG32(reg);
   1768	return r;
   1769}
   1770
   1771static ssize_t amdgpu_atombios_get_vbios_version(struct device *dev,
   1772						 struct device_attribute *attr,
   1773						 char *buf)
   1774{
   1775	struct drm_device *ddev = dev_get_drvdata(dev);
   1776	struct amdgpu_device *adev = drm_to_adev(ddev);
   1777	struct atom_context *ctx = adev->mode_info.atom_context;
   1778
   1779	return sysfs_emit(buf, "%s\n", ctx->vbios_version);
   1780}
   1781
   1782static DEVICE_ATTR(vbios_version, 0444, amdgpu_atombios_get_vbios_version,
   1783		   NULL);
   1784
   1785static struct attribute *amdgpu_vbios_version_attrs[] = {
   1786	&dev_attr_vbios_version.attr,
   1787	NULL
   1788};
   1789
   1790const struct attribute_group amdgpu_vbios_version_attr_group = {
   1791	.attrs = amdgpu_vbios_version_attrs
   1792};
   1793
   1794/**
   1795 * amdgpu_atombios_fini - free the driver info and callbacks for atombios
   1796 *
   1797 * @adev: amdgpu_device pointer
   1798 *
   1799 * Frees the driver info and register access callbacks for the ATOM
   1800 * interpreter (r4xx+).
   1801 * Called at driver shutdown.
   1802 */
   1803void amdgpu_atombios_fini(struct amdgpu_device *adev)
   1804{
   1805	if (adev->mode_info.atom_context) {
   1806		kfree(adev->mode_info.atom_context->scratch);
   1807		kfree(adev->mode_info.atom_context->iio);
   1808	}
   1809	kfree(adev->mode_info.atom_context);
   1810	adev->mode_info.atom_context = NULL;
   1811	kfree(adev->mode_info.atom_card_info);
   1812	adev->mode_info.atom_card_info = NULL;
   1813}
   1814
   1815/**
   1816 * amdgpu_atombios_init - init the driver info and callbacks for atombios
   1817 *
   1818 * @adev: amdgpu_device pointer
   1819 *
   1820 * Initializes the driver info and register access callbacks for the
   1821 * ATOM interpreter (r4xx+).
   1822 * Returns 0 on sucess, -ENOMEM on failure.
   1823 * Called at driver startup.
   1824 */
   1825int amdgpu_atombios_init(struct amdgpu_device *adev)
   1826{
   1827	struct card_info *atom_card_info =
   1828	    kzalloc(sizeof(struct card_info), GFP_KERNEL);
   1829
   1830	if (!atom_card_info)
   1831		return -ENOMEM;
   1832
   1833	adev->mode_info.atom_card_info = atom_card_info;
   1834	atom_card_info->dev = adev_to_drm(adev);
   1835	atom_card_info->reg_read = cail_reg_read;
   1836	atom_card_info->reg_write = cail_reg_write;
   1837	atom_card_info->mc_read = cail_mc_read;
   1838	atom_card_info->mc_write = cail_mc_write;
   1839	atom_card_info->pll_read = cail_pll_read;
   1840	atom_card_info->pll_write = cail_pll_write;
   1841
   1842	adev->mode_info.atom_context = amdgpu_atom_parse(atom_card_info, adev->bios);
   1843	if (!adev->mode_info.atom_context) {
   1844		amdgpu_atombios_fini(adev);
   1845		return -ENOMEM;
   1846	}
   1847
   1848	mutex_init(&adev->mode_info.atom_context->mutex);
   1849	if (adev->is_atom_fw) {
   1850		amdgpu_atomfirmware_scratch_regs_init(adev);
   1851		amdgpu_atomfirmware_allocate_fb_scratch(adev);
   1852		/* cached firmware_flags for further usage */
   1853		adev->mode_info.firmware_flags =
   1854			amdgpu_atomfirmware_query_firmware_capability(adev);
   1855	} else {
   1856		amdgpu_atombios_scratch_regs_init(adev);
   1857		amdgpu_atombios_allocate_fb_scratch(adev);
   1858	}
   1859
   1860	return 0;
   1861}
   1862
   1863int amdgpu_atombios_get_data_table(struct amdgpu_device *adev,
   1864				   uint32_t table,
   1865				   uint16_t *size,
   1866				   uint8_t *frev,
   1867				   uint8_t *crev,
   1868				   uint8_t **addr)
   1869{
   1870	uint16_t data_start;
   1871
   1872	if (!amdgpu_atom_parse_data_header(adev->mode_info.atom_context, table,
   1873					   size, frev, crev, &data_start))
   1874		return -EINVAL;
   1875
   1876	*addr = (uint8_t *)adev->mode_info.atom_context->bios + data_start;
   1877
   1878	return 0;
   1879}