Subversion Repositories Kolibri OS

Rev

Rev 5271 | Rev 6321 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

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