2 * Copyright 2007-8 Advanced Micro Devices, Inc.
3 * Copyright 2008 Red Hat Inc.
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
19 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21 * OTHER DEALINGS IN THE SOFTWARE.
23 * Authors: Dave Airlie
27 #include "radeon_drm.h"
28 #include "radeon_drv.h"
31 #include "atom-bits.h"
34 union atom_supported_devices {
35 struct _ATOM_SUPPORTED_DEVICES_INFO info;
36 struct _ATOM_SUPPORTED_DEVICES_INFO_2 info_2;
37 struct _ATOM_SUPPORTED_DEVICES_INFO_2d1 info_2d1;
40 static inline struct radeon_i2c_bus_rec radeon_lookup_gpio_for_ddc(struct drm_device *dev, uint8_t id)
42 struct drm_radeon_private *dev_priv = dev->dev_private;
43 struct atom_context *ctx = dev_priv->mode_info.atom_context;
44 ATOM_GPIO_I2C_ASSIGMENT gpio;
45 struct radeon_i2c_bus_rec i2c;
46 int index = GetIndexIntoMasterTable(DATA, GPIO_I2C_Info);
47 struct _ATOM_GPIO_I2C_INFO *i2c_info;
50 memset(&i2c, 0, sizeof(struct radeon_i2c_bus_rec));
53 atom_parse_data_header(ctx, index, NULL, NULL, NULL, &data_offset);
55 i2c_info = (struct _ATOM_GPIO_I2C_INFO *)(ctx->bios + data_offset);
57 gpio = i2c_info->asGPIO_Info[id];
59 i2c.mask_clk_reg = le16_to_cpu(gpio.usClkMaskRegisterIndex) * 4;
60 i2c.mask_data_reg = le16_to_cpu(gpio.usDataMaskRegisterIndex) * 4;
61 i2c.put_clk_reg = le16_to_cpu(gpio.usClkEnRegisterIndex) * 4;
62 i2c.put_data_reg = le16_to_cpu(gpio.usDataEnRegisterIndex) * 4;
63 i2c.get_clk_reg = le16_to_cpu(gpio.usClkY_RegisterIndex) * 4;
64 i2c.get_data_reg = le16_to_cpu(gpio.usDataY_RegisterIndex) * 4;
65 i2c.a_clk_reg = le16_to_cpu(gpio.usClkA_RegisterIndex) * 4;
66 i2c.a_data_reg = le16_to_cpu(gpio.usDataA_RegisterIndex) * 4;
67 i2c.mask_clk_mask = (1 << gpio.ucClkMaskShift);
68 i2c.mask_data_mask = (1 << gpio.ucDataMaskShift);
69 i2c.put_clk_mask = (1 << gpio.ucClkEnShift);
70 i2c.put_data_mask = (1 << gpio.ucDataEnShift);
71 i2c.get_clk_mask = (1 << gpio.ucClkY_Shift);
72 i2c.get_data_mask = (1 << gpio.ucDataY_Shift);
73 i2c.a_clk_mask = (1 << gpio.ucClkA_Shift);
74 i2c.a_data_mask = (1 << gpio.ucDataA_Shift);
80 static void radeon_atom_apply_quirks(struct drm_device *dev, int index)
82 struct drm_radeon_private *dev_priv = dev->dev_private;
83 struct radeon_mode_info *mode_info = &dev_priv->mode_info;
85 if ((dev->pdev->device == 0x791e) &&
86 (dev->pdev->subsystem_vendor == 0x1043) &&
87 (dev->pdev->subsystem_device == 0x826d)) {
88 if ((mode_info->bios_connector[index].connector_type == CONNECTOR_HDMI_TYPE_A) &&
89 (mode_info->bios_connector[index].tmds_type == TMDS_LVTMA)) {
90 mode_info->bios_connector[index].connector_type = CONNECTOR_DVI_D;
94 if ((dev->pdev->device == 0x5653) &&
95 (dev->pdev->subsystem_vendor == 0x1462) &&
96 (dev->pdev->subsystem_device == 0x0291)) {
97 if (mode_info->bios_connector[index].connector_type == CONNECTOR_LVDS) {
98 mode_info->bios_connector[index].ddc_i2c.valid = false;
103 bool radeon_get_atom_connector_info_from_bios_connector_table(struct drm_device *dev)
105 struct drm_radeon_private *dev_priv = dev->dev_private;
106 struct radeon_mode_info *mode_info = &dev_priv->mode_info;
107 struct atom_context *ctx = mode_info->atom_context;
108 int index = GetIndexIntoMasterTable(DATA, SupportedDevicesInfo);
109 uint16_t size, data_offset;
111 uint16_t device_support;
113 union atom_supported_devices *supported_devices;
115 atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset);
117 supported_devices = (union atom_supported_devices *)(ctx->bios + data_offset);
119 device_support = le16_to_cpu(supported_devices->info.usDeviceSupport);
121 for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) {
123 ATOM_CONNECTOR_INFO_I2C ci = supported_devices->info.asConnInfo[i];
125 if (!(device_support & (1 << i))) {
126 mode_info->bios_connector[i].valid = false;
130 if (i == ATOM_DEVICE_CV_INDEX) {
131 DRM_DEBUG("Skipping Component Video\n");
132 mode_info->bios_connector[i].valid = false;
136 if (i == ATOM_DEVICE_TV1_INDEX) {
137 DRM_DEBUG("Skipping TV Out\n");
138 mode_info->bios_connector[i].valid = false;
142 mode_info->bios_connector[i].valid = true;
143 mode_info->bios_connector[i].output_id = ci.sucI2cId.sbfAccess.bfI2C_LineMux;
144 mode_info->bios_connector[i].devices = 1 << i;
145 mode_info->bios_connector[i].connector_type = ci.sucConnectorInfo.sbfAccess.bfConnectorType;
147 if (mode_info->bios_connector[i].connector_type == CONNECTOR_NONE) {
148 mode_info->bios_connector[i].valid = false;
152 mode_info->bios_connector[i].dac_type = ci.sucConnectorInfo.sbfAccess.bfAssociatedDAC;
154 if ((i == ATOM_DEVICE_TV1_INDEX) ||
155 (i == ATOM_DEVICE_TV2_INDEX) ||
156 (i == ATOM_DEVICE_TV1_INDEX))
157 mode_info->bios_connector[i].ddc_i2c.valid = false;
158 else if ((dev_priv->chip_family == CHIP_RS600) ||
159 (dev_priv->chip_family == CHIP_RS690) ||
160 (dev_priv->chip_family == CHIP_RS740)) {
161 if ((i == ATOM_DEVICE_DFP2_INDEX) || (i == ATOM_DEVICE_DFP3_INDEX))
162 mode_info->bios_connector[i].ddc_i2c =
163 radeon_lookup_gpio_for_ddc(dev, ci.sucI2cId.sbfAccess.bfI2C_LineMux + 1);
165 mode_info->bios_connector[i].ddc_i2c =
166 radeon_lookup_gpio_for_ddc(dev, ci.sucI2cId.sbfAccess.bfI2C_LineMux);
168 mode_info->bios_connector[i].ddc_i2c =
169 radeon_lookup_gpio_for_ddc(dev, ci.sucI2cId.sbfAccess.bfI2C_LineMux);
171 if (i == ATOM_DEVICE_DFP1_INDEX)
172 mode_info->bios_connector[i].tmds_type = TMDS_INT;
173 else if (i == ATOM_DEVICE_DFP2_INDEX) {
174 if ((dev_priv->chip_family == CHIP_RS600) ||
175 (dev_priv->chip_family == CHIP_RS690) ||
176 (dev_priv->chip_family == CHIP_RS740))
177 mode_info->bios_connector[i].tmds_type = TMDS_DDIA;
179 mode_info->bios_connector[i].tmds_type = TMDS_EXT;
180 } else if (i == ATOM_DEVICE_DFP3_INDEX)
181 mode_info->bios_connector[i].tmds_type = TMDS_LVTMA;
183 mode_info->bios_connector[i].tmds_type = TMDS_NONE;
185 /* Always set the connector type to VGA for CRT1/CRT2. if they are
186 * shared with a DVI port, we'll pick up the DVI connector below when we
189 if ((i == ATOM_DEVICE_CRT1_INDEX || i == ATOM_DEVICE_CRT2_INDEX) &&
190 (mode_info->bios_connector[i].connector_type == CONNECTOR_DVI_I ||
191 mode_info->bios_connector[i].connector_type == CONNECTOR_DVI_D ||
192 mode_info->bios_connector[i].connector_type == CONNECTOR_DVI_A)) {
193 mode_info->bios_connector[i].connector_type = CONNECTOR_VGA;
197 ATOM_CONNECTOR_INC_SRC_BITMAP isb = supported_devices->info_2.asIntSrcInfo[i];
199 switch(isb.ucIntSrcBitmap) {
201 mode_info->bios_connector[i].hpd_mask = 0x1;
204 mode_info->bios_connector[i].hpd_mask = 0x100;
207 mode_info->bios_connector[i].hpd_mask = 0;
211 mode_info->bios_connector[i].hpd_mask = 0;
214 radeon_atom_apply_quirks(dev, i);
217 /* CRTs/DFPs may share a port */
218 for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) {
219 if (!mode_info->bios_connector[i].valid)
222 for (j = 0; j < ATOM_MAX_SUPPORTED_DEVICE; j++) {
223 if (mode_info->bios_connector[j].valid && (i != j)) {
224 if (mode_info->bios_connector[i].output_id ==
225 mode_info->bios_connector[j].output_id) {
226 if (((i == ATOM_DEVICE_DFP1_INDEX) ||
227 (i == ATOM_DEVICE_DFP2_INDEX) ||
228 (i == ATOM_DEVICE_DFP3_INDEX)) &&
229 ((j == ATOM_DEVICE_CRT1_INDEX) ||
230 (j == ATOM_DEVICE_CRT2_INDEX))) {
231 mode_info->bios_connector[i].dac_type = mode_info->bios_connector[j].dac_type;
232 mode_info->bios_connector[i].devices |= mode_info->bios_connector[j].devices;
233 mode_info->bios_connector[i].hpd_mask = mode_info->bios_connector[j].hpd_mask;
234 mode_info->bios_connector[j].valid = false;
235 } else if (((j == ATOM_DEVICE_DFP1_INDEX) ||
236 (j == ATOM_DEVICE_DFP2_INDEX) ||
237 (j == ATOM_DEVICE_DFP3_INDEX)) &&
238 ((i == ATOM_DEVICE_CRT1_INDEX) ||
239 (i == ATOM_DEVICE_CRT2_INDEX))) {
240 mode_info->bios_connector[j].dac_type = mode_info->bios_connector[i].dac_type;
241 mode_info->bios_connector[j].devices |= mode_info->bios_connector[i].devices;
242 mode_info->bios_connector[j].hpd_mask = mode_info->bios_connector[i].hpd_mask;
243 mode_info->bios_connector[i].valid = false;
251 DRM_DEBUG("BIOS Connector table\n");
252 for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) {
253 if (!mode_info->bios_connector[i].valid)
256 DRM_DEBUG("Port %d: ddc_type 0x%x, dac_type %d, tmds_type %d, connector type %d, hpd_mask %d\n",
257 i, mode_info->bios_connector[i].ddc_i2c.mask_clk_reg,
258 mode_info->bios_connector[i].dac_type,
259 mode_info->bios_connector[i].tmds_type,
260 mode_info->bios_connector[i].connector_type,
261 mode_info->bios_connector[i].hpd_mask);
266 union firmware_info {
267 ATOM_FIRMWARE_INFO info;
268 ATOM_FIRMWARE_INFO_V1_2 info_12;
269 ATOM_FIRMWARE_INFO_V1_3 info_13;
270 ATOM_FIRMWARE_INFO_V1_4 info_14;
273 bool radeon_atom_get_clock_info(struct drm_device *dev)
275 struct drm_radeon_private *dev_priv = dev->dev_private;
276 struct radeon_mode_info *mode_info = &dev_priv->mode_info;
277 int index = GetIndexIntoMasterTable(DATA, FirmwareInfo);
278 union firmware_info *firmware_info;
280 struct radeon_pll *pll = &mode_info->pll;
281 uint16_t data_offset;
283 atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, &crev, &data_offset);
285 firmware_info = (union firmware_info *)(mode_info->atom_context->bios + data_offset);
287 pll->reference_freq = le16_to_cpu(firmware_info->info.usReferenceClock);
288 pll->reference_div = 0;
290 pll->pll_out_min = le16_to_cpu(firmware_info->info.usMinPixelClockPLL_Output);
291 pll->pll_out_max = le32_to_cpu(firmware_info->info.ulMaxPixelClockPLL_Output);
293 if (pll->pll_out_min == 0) {
294 if (radeon_is_avivo(dev_priv))
295 pll->pll_out_min = 64800;
297 pll->pll_out_min = 20000;
300 pll->pll_in_min = le16_to_cpu(firmware_info->info.usMinPixelClockPLL_Input);
301 pll->pll_in_max = le16_to_cpu(firmware_info->info.usMaxPixelClockPLL_Input);
303 pll->xclk = le16_to_cpu(firmware_info->info.usMaxPixelClock);
309 struct _ATOM_LVDS_INFO info;
310 struct _ATOM_LVDS_INFO_V12 info_12;
313 void radeon_get_lvds_info(struct radeon_encoder *encoder)
315 struct drm_device *dev = encoder->base.dev;
316 struct drm_radeon_private *dev_priv = dev->dev_private;
317 struct radeon_mode_info *mode_info = &dev_priv->mode_info;
318 int index = GetIndexIntoMasterTable(DATA, LVDS_Info);
319 uint16_t data_offset;
320 union lvds_info *lvds_info;
323 atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, &crev, &data_offset);
325 lvds_info = (union lvds_info *)(mode_info->atom_context->bios + data_offset);
327 encoder->dotclock = le16_to_cpu(lvds_info->info.sLCDTiming.usPixClk) * 10;
328 encoder->panel_xres = le16_to_cpu(lvds_info->info.sLCDTiming.usHActive);
329 encoder->panel_yres = le16_to_cpu(lvds_info->info.sLCDTiming.usVActive);
330 encoder->hblank = le16_to_cpu(lvds_info->info.sLCDTiming.usHBlanking_Time);
331 encoder->hoverplus = le16_to_cpu(lvds_info->info.sLCDTiming.usHSyncOffset);
332 encoder->hsync_width = le16_to_cpu(lvds_info->info.sLCDTiming.usHSyncWidth);
334 encoder->vblank = le16_to_cpu(lvds_info->info.sLCDTiming.usVBlanking_Time);
335 encoder->hoverplus = le16_to_cpu(lvds_info->info.sLCDTiming.usVSyncOffset);
336 encoder->hsync_width = le16_to_cpu(lvds_info->info.sLCDTiming.usVSyncWidth);
337 encoder->panel_pwr_delay = le16_to_cpu(lvds_info->info.usOffDelayInMs);
340 void radeon_atom_dyn_clk_setup(struct drm_device *dev, int enable)
342 struct drm_radeon_private *dev_priv = dev->dev_private;
343 struct radeon_mode_info *mode_info = &dev_priv->mode_info;
344 struct atom_context *ctx = mode_info->atom_context;
345 DYNAMIC_CLOCK_GATING_PS_ALLOCATION args;
346 int index = GetIndexIntoMasterTable(COMMAND, DynamicClockGating);
348 args.ucEnable = enable;
350 atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args);
353 void radeon_atom_static_pwrmgt_setup(struct drm_device *dev, int enable)
355 struct drm_radeon_private *dev_priv = dev->dev_private;
356 struct radeon_mode_info *mode_info = &dev_priv->mode_info;
357 struct atom_context *ctx = mode_info->atom_context;
358 ENABLE_ASIC_STATIC_PWR_MGT_PS_ALLOCATION args;
359 int index = GetIndexIntoMasterTable(COMMAND, EnableASIC_StaticPwrMgt);
361 args.ucEnable = enable;
363 atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args);