mirror of
https://gitlab.freedesktop.org/mesa/drm.git
synced 2026-05-01 01:08:00 +02:00
radeon_ms: add rom parsing & adapt code
Add rom (only combios for now) parsing and use informations retrieve instead of hardcoded table. Shuffle code around a bit.
This commit is contained in:
parent
e6fc47129f
commit
f1f934c8c9
20 changed files with 1300 additions and 157 deletions
|
|
@ -39,7 +39,8 @@ radeon_ms-objs := radeon_ms_drv.o radeon_ms_drm.o radeon_ms_family.o \
|
|||
radeon_ms_bus.o radeon_ms_fence.o \
|
||||
radeon_ms_cp.o radeon_ms_cp_mc.o radeon_ms_i2c.o \
|
||||
radeon_ms_output.o radeon_ms_crtc.o radeon_ms_fb.o \
|
||||
radeon_ms_exec.o radeon_ms_gpu.o radeon_ms_dac.o
|
||||
radeon_ms_exec.o radeon_ms_gpu.o radeon_ms_dac.o \
|
||||
radeon_ms_properties.o radeon_ms_rom.o radeon_ms_combios.o
|
||||
sis-objs := sis_drv.o sis_mm.o
|
||||
ffb-objs := ffb_drv.o ffb_context.o
|
||||
savage-objs := savage_drv.o savage_bci.o savage_state.o
|
||||
|
|
|
|||
1
linux-core/radeon_ms_combios.c
Symbolic link
1
linux-core/radeon_ms_combios.c
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../shared-core/radeon_ms_combios.c
|
||||
1
linux-core/radeon_ms_combios.h
Symbolic link
1
linux-core/radeon_ms_combios.h
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../shared-core/radeon_ms_combios.h
|
||||
1
linux-core/radeon_ms_properties.c
Symbolic link
1
linux-core/radeon_ms_properties.c
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../shared-core/radeon_ms_properties.c
|
||||
1
linux-core/radeon_ms_properties.h
Symbolic link
1
linux-core/radeon_ms_properties.h
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../shared-core/radeon_ms_properties.h
|
||||
1
linux-core/radeon_ms_rom.c
Symbolic link
1
linux-core/radeon_ms_rom.c
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../shared-core/radeon_ms_rom.c
|
||||
1
linux-core/radeon_ms_rom.h
Symbolic link
1
linux-core/radeon_ms_rom.h
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../shared-core/radeon_ms_rom.h
|
||||
|
|
@ -33,6 +33,8 @@
|
|||
#include "radeon_ms_drv.h"
|
||||
#include "radeon_ms_reg.h"
|
||||
#include "radeon_ms_drm.h"
|
||||
#include "radeon_ms_rom.h"
|
||||
#include "radeon_ms_properties.h"
|
||||
|
||||
#define DRIVER_AUTHOR "Jerome Glisse, Dave Airlie, Gareth Hughes, "\
|
||||
"Keith Whitwell, others."
|
||||
|
|
@ -43,10 +45,6 @@
|
|||
#define DRIVER_MINOR 0
|
||||
#define DRIVER_PATCHLEVEL 0
|
||||
|
||||
#define RADEON_PAGE_SIZE 4096
|
||||
#define RADEON_MAX_CONNECTORS 8
|
||||
#define RADEON_MAX_OUTPUTS 8
|
||||
|
||||
enum radeon_bus_type {
|
||||
RADEON_PCI = 0x10000,
|
||||
RADEON_AGP = 0x20000,
|
||||
|
|
@ -154,20 +152,6 @@ struct radeon_ms_output {
|
|||
struct radeon_state *state);
|
||||
};
|
||||
|
||||
struct radeon_ms_properties {
|
||||
uint16_t subvendor;
|
||||
uint16_t subdevice;
|
||||
int16_t pll_reference_freq;
|
||||
int32_t pll_min_pll_freq;
|
||||
int32_t pll_max_pll_freq;
|
||||
char pll_use_bios;
|
||||
char pll_dummy_reads;
|
||||
char pll_delay;
|
||||
char pll_r300_errata;
|
||||
struct radeon_ms_output *outputs[RADEON_MAX_OUTPUTS];
|
||||
struct radeon_ms_connector *connectors[RADEON_MAX_CONNECTORS];
|
||||
};
|
||||
|
||||
struct radeon_state {
|
||||
/* memory */
|
||||
uint32_t config_aper_0_base;
|
||||
|
|
@ -310,7 +294,6 @@ struct drm_radeon_private {
|
|||
/* card family */
|
||||
uint32_t usec_timeout;
|
||||
uint32_t family;
|
||||
struct radeon_ms_properties *properties;
|
||||
struct radeon_ms_output *outputs[RADEON_MAX_OUTPUTS];
|
||||
struct radeon_ms_connector *connectors[RADEON_MAX_CONNECTORS];
|
||||
/* drm map (MMIO, FB) */
|
||||
|
|
@ -342,6 +325,9 @@ struct drm_radeon_private {
|
|||
uint8_t cp_ready;
|
||||
uint8_t bus_ready;
|
||||
uint8_t write_back;
|
||||
/* abstract asic specific structures */
|
||||
struct radeon_ms_rom rom;
|
||||
struct radeon_ms_properties properties;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -369,6 +355,11 @@ int radeon_ms_pcie_init(struct drm_device *dev);
|
|||
void radeon_ms_pcie_restore(struct drm_device *dev, struct radeon_state *state);
|
||||
void radeon_ms_pcie_save(struct drm_device *dev, struct radeon_state *state);
|
||||
|
||||
/* radeon_ms_combios.c */
|
||||
int radeon_ms_combios_get_properties(struct drm_device *dev);
|
||||
int radeon_ms_connectors_from_combios(struct drm_device *dev);
|
||||
int radeon_ms_outputs_from_combios(struct drm_device *dev);
|
||||
|
||||
/* radeon_ms_compat.c */
|
||||
long radeon_ms_compat_ioctl(struct file *filp, unsigned int cmd,
|
||||
unsigned long arg);
|
||||
|
|
@ -475,12 +466,21 @@ void radeon_ms_irq_uninstall(struct drm_device * dev);
|
|||
/* radeon_ms_output.c */
|
||||
void radeon_ms_connectors_destroy(struct drm_device *dev);
|
||||
int radeon_ms_connectors_from_properties(struct drm_device *dev);
|
||||
int radeon_ms_connectors_from_rom(struct drm_device *dev);
|
||||
void radeon_ms_outputs_destroy(struct drm_device *dev);
|
||||
int radeon_ms_outputs_from_properties(struct drm_device *dev);
|
||||
int radeon_ms_outputs_from_rom(struct drm_device *dev);
|
||||
void radeon_ms_outputs_restore(struct drm_device *dev,
|
||||
struct radeon_state *state);
|
||||
void radeon_ms_outputs_save(struct drm_device *dev, struct radeon_state *state);
|
||||
|
||||
/* radeon_ms_properties.c */
|
||||
int radeon_ms_properties_init(struct drm_device *dev);
|
||||
|
||||
/* radeon_ms_rom.c */
|
||||
int radeon_ms_rom_get_properties(struct drm_device *dev);
|
||||
int radeon_ms_rom_init(struct drm_device *dev);
|
||||
|
||||
/* radeon_ms_state.c */
|
||||
void radeon_ms_state_save(struct drm_device *dev, struct radeon_state *state);
|
||||
void radeon_ms_state_restore(struct drm_device *dev,
|
||||
|
|
@ -545,7 +545,7 @@ static __inline__ void pll_index_errata(struct drm_radeon_private *dev_priv)
|
|||
/* This workaround is necessary on rv200 and RS200 or PLL
|
||||
* reads may return garbage (among others...)
|
||||
*/
|
||||
if (dev_priv->properties->pll_dummy_reads) {
|
||||
if (dev_priv->properties.pll_dummy_reads) {
|
||||
tmp = MMIO_R(CLOCK_CNTL_DATA);
|
||||
tmp = MMIO_R(CRTC_GEN_CNTL);
|
||||
}
|
||||
|
|
@ -554,7 +554,7 @@ static __inline__ void pll_index_errata(struct drm_radeon_private *dev_priv)
|
|||
* CLOCK_CNTL_INDEX register access. If not, register reads afterward
|
||||
* may not be correct.
|
||||
*/
|
||||
if (dev_priv->properties->pll_r300_errata) {
|
||||
if (dev_priv->properties.pll_r300_errata) {
|
||||
tmp = save = MMIO_R(CLOCK_CNTL_INDEX);
|
||||
tmp = tmp & ~CLOCK_CNTL_INDEX__PLL_ADDR__MASK;
|
||||
tmp = tmp & ~CLOCK_CNTL_INDEX__PLL_WR_EN;
|
||||
|
|
@ -569,7 +569,7 @@ static __inline__ void pll_data_errata(struct drm_radeon_private *dev_priv)
|
|||
/* This workarounds is necessary on RV100, RS100 and RS200 chips
|
||||
* or the chip could hang on a subsequent access
|
||||
*/
|
||||
if (dev_priv->properties->pll_delay) {
|
||||
if (dev_priv->properties.pll_delay) {
|
||||
/* we can't deal with posted writes here ... */
|
||||
udelay(5000);
|
||||
}
|
||||
|
|
|
|||
396
shared-core/radeon_ms_combios.c
Normal file
396
shared-core/radeon_ms_combios.c
Normal file
|
|
@ -0,0 +1,396 @@
|
|||
/*
|
||||
* Copyright 2007 Jérôme Glisse
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
/*
|
||||
* Authors:
|
||||
* Jérôme Glisse <glisse@freedesktop.org>
|
||||
*/
|
||||
#include "radeon_ms.h"
|
||||
|
||||
extern struct radeon_ms_output radeon_ms_dac1;
|
||||
extern struct radeon_ms_output radeon_ms_dac2;
|
||||
extern const struct drm_output_funcs radeon_ms_output_funcs;
|
||||
|
||||
static struct combios_connector_chip_info *
|
||||
radeon_ms_combios_get_connector_chip_info(struct drm_device *dev, int chip_num)
|
||||
{
|
||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||
struct radeon_ms_rom *rom = &dev_priv->rom;
|
||||
struct combios_header *header;
|
||||
struct combios_connector_table *connector_table;
|
||||
struct combios_connector_chip_info *connector_chip_info;
|
||||
uint32_t offset;
|
||||
int numof_chips, i;
|
||||
|
||||
if (rom->type != ROM_COMBIOS || rom->rom_image == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
header = rom->rom.combios_header;
|
||||
offset = header->usPointerToExtendedInitTable2;
|
||||
if ((offset + sizeof(struct combios_connector_table)) > rom->rom_size) {
|
||||
DRM_INFO("[radeon_ms] wrong COMBIOS connector offset\n");
|
||||
return NULL;
|
||||
}
|
||||
if (!offset) {
|
||||
return NULL;
|
||||
}
|
||||
connector_table = (struct combios_connector_table *)
|
||||
&rom->rom_image[offset];
|
||||
numof_chips = (connector_table->ucConnectorHeader &
|
||||
BIOS_CONNECTOR_HEADER__NUMBER_OF_CHIPS__MASK) >>
|
||||
BIOS_CONNECTOR_HEADER__NUMBER_OF_CHIPS__SHIFT;
|
||||
DRM_INFO("[radeon_ms] COMBIOS number of chip: %d (table rev: %d)\n",
|
||||
numof_chips,
|
||||
(connector_table->ucConnectorHeader &
|
||||
BIOS_CONNECTOR_HEADER__TABLE_REVISION__MASK) >>
|
||||
BIOS_CONNECTOR_HEADER__TABLE_REVISION__SHIFT);
|
||||
for (i = 0; i < numof_chips; i++) {
|
||||
int chip;
|
||||
|
||||
connector_chip_info = &connector_table->sChipConnectorInfo[i];
|
||||
chip = (connector_chip_info->ucChipHeader &
|
||||
BIOS_CHIPINFO_HEADER__CHIP_NUMBER__MASK) >>
|
||||
BIOS_CHIPINFO_HEADER__CHIP_NUMBER__SHIFT;
|
||||
DRM_INFO("[radeon_ms] COMBIOS chip: %d (asked for: %d)\n",
|
||||
chip, chip_num);
|
||||
if (chip == chip_num) {
|
||||
return connector_chip_info;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int radeon_combios_get_connector_infos(struct drm_device *dev,
|
||||
int connector_info,
|
||||
int *connector_type,
|
||||
int *ddc_line,
|
||||
int *tmds_type,
|
||||
int *dac_type)
|
||||
{
|
||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||
|
||||
*connector_type = (connector_info & BIOS_CONNECTOR_INFO__TYPE__MASK) >>
|
||||
BIOS_CONNECTOR_INFO__TYPE__SHIFT;
|
||||
*ddc_line = (connector_info & BIOS_CONNECTOR_INFO__DDC_LINE__MASK) >>
|
||||
BIOS_CONNECTOR_INFO__DDC_LINE__SHIFT;
|
||||
*tmds_type = (connector_info & BIOS_CONNECTOR_INFO__TMDS_TYPE__MASK) >>
|
||||
BIOS_CONNECTOR_INFO__TMDS_TYPE__SHIFT;
|
||||
*dac_type = (connector_info & BIOS_CONNECTOR_INFO__DAC_TYPE__MASK) >>
|
||||
BIOS_CONNECTOR_INFO__DAC_TYPE__SHIFT;
|
||||
|
||||
/* most XPRESS chips seem to specify DDC_CRT2 for their
|
||||
* VGA DDC port, however DDC never seems to work on that
|
||||
* port. Some have reported success on DDC_MONID, so
|
||||
* lets see what happens with that.
|
||||
*/
|
||||
if (dev_priv->family == CHIP_RS400 &&
|
||||
*connector_type == BIOS_CONNECTOR_TYPE__CRT &&
|
||||
*ddc_line == BIOS_DDC_LINE__CRT2) {
|
||||
*ddc_line = BIOS_DDC_LINE__MONID01;
|
||||
}
|
||||
/* XPRESS desktop chips seem to have a proprietary
|
||||
* connector listed for DVI-D, try and do the right
|
||||
* thing here.
|
||||
*/
|
||||
if (dev_priv->family == CHIP_RS400 &&
|
||||
*connector_type == BIOS_CONNECTOR_TYPE__PROPRIETARY) {
|
||||
DRM_INFO("[radeon_ms] COMBIOS Proprietary connector "
|
||||
"found, assuming DVI-D\n");
|
||||
*dac_type = 2;
|
||||
*tmds_type = BIOS_TMDS_TYPE__EXTERNAL;
|
||||
*connector_type = BIOS_CONNECTOR_TYPE__DVI_D;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int radeon_ms_combios_connector_add(struct drm_device *dev,
|
||||
int connector_number,
|
||||
int connector_type,
|
||||
uint32_t i2c_reg)
|
||||
{
|
||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||
struct radeon_ms_connector *connector = NULL;
|
||||
struct drm_output *output = NULL;
|
||||
|
||||
connector = drm_alloc(sizeof(struct radeon_ms_connector),
|
||||
DRM_MEM_DRIVER);
|
||||
if (connector == NULL) {
|
||||
radeon_ms_connectors_destroy(dev);
|
||||
return -ENOMEM;
|
||||
}
|
||||
memset(connector, 0, sizeof(struct radeon_ms_connector));
|
||||
connector->monitor_type = MT_NONE;
|
||||
connector->type = connector_type;
|
||||
connector->i2c_reg = i2c_reg;
|
||||
|
||||
if (i2c_reg) {
|
||||
connector->i2c = radeon_ms_i2c_create(dev,
|
||||
connector->i2c_reg,
|
||||
connector->type);
|
||||
if (connector->i2c == NULL) {
|
||||
radeon_ms_connectors_destroy(dev);
|
||||
return -ENOMEM;
|
||||
}
|
||||
} else {
|
||||
connector->i2c = NULL;
|
||||
}
|
||||
|
||||
output = drm_output_create(dev, &radeon_ms_output_funcs,
|
||||
connector->type);
|
||||
if (output == NULL) {
|
||||
radeon_ms_connectors_destroy(dev);
|
||||
return -EINVAL;
|
||||
}
|
||||
connector->output = output;
|
||||
output->driver_private = connector;
|
||||
output->possible_crtcs = 0x3;
|
||||
dev_priv->connectors[connector_number] = connector;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int radeon_ms_combios_get_properties(struct drm_device *dev)
|
||||
{
|
||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||
struct radeon_ms_rom *rom = &dev_priv->rom;
|
||||
struct combios_pll_block *pll_block;
|
||||
struct combios_header *header;
|
||||
uint32_t offset;
|
||||
|
||||
if (rom->type != ROM_COMBIOS || rom->rom_image == NULL) {
|
||||
return 0;
|
||||
}
|
||||
header = rom->rom.combios_header;
|
||||
offset = header->usPointerToPllInfoBlock;
|
||||
if ((offset + sizeof(struct combios_pll_block)) > rom->rom_size) {
|
||||
DRM_INFO("[radeon_ms] wrong COMBIOS pll block offset\n");
|
||||
return 0;
|
||||
}
|
||||
if (!offset) {
|
||||
return 0;
|
||||
}
|
||||
pll_block = (struct combios_pll_block *)&rom->rom_image[offset];
|
||||
dev_priv->properties.pll_reference_freq = pll_block->usDotClockRefFreq;
|
||||
dev_priv->properties.pll_reference_div = pll_block->usDotClockRefDiv;
|
||||
dev_priv->properties.pll_min_pll_freq = pll_block->ulDotClockMinFreq;
|
||||
dev_priv->properties.pll_max_pll_freq = pll_block->ulDotClockMaxFreq;
|
||||
dev_priv->properties.pll_reference_freq *= 10;
|
||||
dev_priv->properties.pll_min_pll_freq *= 10;
|
||||
dev_priv->properties.pll_max_pll_freq *= 10;
|
||||
DRM_INFO("[radeon_ms] COMBIOS pll reference frequency : %d\n",
|
||||
dev_priv->properties.pll_reference_freq);
|
||||
DRM_INFO("[radeon_ms] COMBIOS pll reference divider : %d\n",
|
||||
dev_priv->properties.pll_reference_div);
|
||||
DRM_INFO("[radeon_ms] COMBIOS pll minimum frequency : %d\n",
|
||||
dev_priv->properties.pll_min_pll_freq);
|
||||
DRM_INFO("[radeon_ms] COMBIOS pll maximum frequency : %d\n",
|
||||
dev_priv->properties.pll_max_pll_freq);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int radeon_ms_connectors_from_combios(struct drm_device *dev)
|
||||
{
|
||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||
struct combios_connector_chip_info *connector_chip_info;
|
||||
int connector_type, ddc_line, tmds_type, dac_type;
|
||||
int dac1, dac2, tmdsint, tmdsext;
|
||||
int numof_connector, i, c = 0, added, j;
|
||||
uint32_t i2c_reg;
|
||||
int ret;
|
||||
|
||||
dac1 = dac2 = tmdsint = tmdsext = -1;
|
||||
connector_chip_info = radeon_ms_combios_get_connector_chip_info(dev, 1);
|
||||
if (connector_chip_info == NULL) {
|
||||
return -1;
|
||||
}
|
||||
numof_connector = (connector_chip_info->ucChipHeader &
|
||||
BIOS_CHIPINFO_HEADER__NUMBER_OF_CONNECTORS__MASK) >>
|
||||
BIOS_CHIPINFO_HEADER__NUMBER_OF_CONNECTORS__SHIFT;
|
||||
DRM_INFO("[radeon_ms] COMBIOS number of connector: %d\n",
|
||||
numof_connector);
|
||||
for (i = 0; i < numof_connector; i++) {
|
||||
int connector_info = connector_chip_info->sConnectorInfo[i];
|
||||
|
||||
ret = radeon_combios_get_connector_infos(dev,
|
||||
connector_info,
|
||||
&connector_type,
|
||||
&ddc_line,
|
||||
&tmds_type,
|
||||
&dac_type);
|
||||
|
||||
switch (ddc_line) {
|
||||
case BIOS_DDC_LINE__MONID01:
|
||||
i2c_reg = GPIO_MONID;
|
||||
break;
|
||||
case BIOS_DDC_LINE__DVI:
|
||||
i2c_reg = GPIO_DVI_DDC;
|
||||
break;
|
||||
case BIOS_DDC_LINE__VGA:
|
||||
i2c_reg = GPIO_DDC1;
|
||||
break;
|
||||
case BIOS_DDC_LINE__CRT2:
|
||||
i2c_reg = GPIO_CRT2_DDC;
|
||||
break;
|
||||
case BIOS_DDC_LINE__GPIOPAD:
|
||||
i2c_reg = VIPPAD_EN;
|
||||
break;
|
||||
case BIOS_DDC_LINE__ZV_LCDPAD:
|
||||
i2c_reg = VIPPAD1_EN;
|
||||
break;
|
||||
default:
|
||||
i2c_reg = 0;
|
||||
break;
|
||||
}
|
||||
added = 0;
|
||||
switch (connector_type) {
|
||||
case BIOS_CONNECTOR_TYPE__CRT:
|
||||
ret = radeon_ms_combios_connector_add(dev, c,
|
||||
ConnectorVGA,
|
||||
i2c_reg);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
added = 1;
|
||||
break;
|
||||
case BIOS_CONNECTOR_TYPE__DVI_I:
|
||||
ret = radeon_ms_combios_connector_add(dev, c,
|
||||
ConnectorDVII,
|
||||
i2c_reg);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
added = 1;
|
||||
break;
|
||||
case BIOS_CONNECTOR_TYPE__DVI_D:
|
||||
ret = radeon_ms_combios_connector_add(dev, c,
|
||||
ConnectorDVID,
|
||||
i2c_reg);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
added = 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (added) {
|
||||
j = 0;
|
||||
/* find to which output this connector is associated
|
||||
* by following same algo as in:
|
||||
* radeon_ms_outputs_from_combios*/
|
||||
switch (dac_type) {
|
||||
case BIOS_DAC_TYPE__CRT:
|
||||
if (dac1 == -1) {
|
||||
dac1 = c;
|
||||
}
|
||||
dev_priv->connectors[c]->outputs[j++] = dac1;
|
||||
break;
|
||||
case BIOS_DAC_TYPE__NON_CRT:
|
||||
if (dac2 == -1) {
|
||||
dac2 = c;
|
||||
}
|
||||
dev_priv->connectors[c]->outputs[j++] = dac2;
|
||||
break;
|
||||
}
|
||||
#if 0
|
||||
switch (tmds_type) {
|
||||
case BIOS_TMDS_TYPE__INTERNAL:
|
||||
if (tmdsint == -1) {
|
||||
tmdsint = c;
|
||||
}
|
||||
dev_priv->connectors[c]->outputs[j++] = tmdsint;
|
||||
break;
|
||||
case BIOS_TMDS_TYPE__EXTERNAL:
|
||||
if (tmdsext == -1) {
|
||||
tmdsext = c;
|
||||
}
|
||||
dev_priv->connectors[c]->outputs[j++] = tmdsext;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
c++;
|
||||
}
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
int radeon_ms_outputs_from_combios(struct drm_device *dev)
|
||||
{
|
||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||
struct combios_connector_chip_info *connector_chip_info;
|
||||
int connector_type, ddc_line, tmds_type, dac_type;
|
||||
int numof_connector, i, dac1_present, dac2_present, c = 0;
|
||||
int ret;
|
||||
|
||||
dac1_present = dac2_present = 0;
|
||||
connector_chip_info = radeon_ms_combios_get_connector_chip_info(dev, 1);
|
||||
if (connector_chip_info == NULL) {
|
||||
return -1;
|
||||
}
|
||||
numof_connector = (connector_chip_info->ucChipHeader &
|
||||
BIOS_CHIPINFO_HEADER__NUMBER_OF_CONNECTORS__MASK) >>
|
||||
BIOS_CHIPINFO_HEADER__NUMBER_OF_CONNECTORS__SHIFT;
|
||||
DRM_INFO("[radeon_ms] COMBIOS number of connector: %d\n",
|
||||
numof_connector);
|
||||
for (i = 0; i < numof_connector; i++) {
|
||||
int connector_info = connector_chip_info->sConnectorInfo[i];
|
||||
|
||||
ret = radeon_combios_get_connector_infos(dev,
|
||||
connector_info,
|
||||
&connector_type,
|
||||
&ddc_line,
|
||||
&tmds_type,
|
||||
&dac_type);
|
||||
|
||||
if (!dac1_present && dac_type == BIOS_DAC_TYPE__CRT) {
|
||||
dev_priv->outputs[c] =
|
||||
drm_alloc(sizeof(struct radeon_ms_output),
|
||||
DRM_MEM_DRIVER);
|
||||
if (dev_priv->outputs[c] == NULL) {
|
||||
radeon_ms_outputs_destroy(dev);
|
||||
return -ENOMEM;
|
||||
}
|
||||
memcpy(dev_priv->outputs[c], &radeon_ms_dac1,
|
||||
sizeof(struct radeon_ms_output));
|
||||
dev_priv->outputs[c]->dev = dev;
|
||||
dev_priv->outputs[c]->initialize(dev_priv->outputs[c]);
|
||||
dac1_present = 1;
|
||||
c++;
|
||||
}
|
||||
if (!dac2_present && dac_type == BIOS_DAC_TYPE__NON_CRT) {
|
||||
dev_priv->outputs[c] =
|
||||
drm_alloc(sizeof(struct radeon_ms_output),
|
||||
DRM_MEM_DRIVER);
|
||||
if (dev_priv->outputs[c] == NULL) {
|
||||
radeon_ms_outputs_destroy(dev);
|
||||
return -ENOMEM;
|
||||
}
|
||||
memcpy(dev_priv->outputs[c], &radeon_ms_dac2,
|
||||
sizeof(struct radeon_ms_output));
|
||||
dev_priv->outputs[c]->dev = dev;
|
||||
dev_priv->outputs[c]->initialize(dev_priv->outputs[c]);
|
||||
dac1_present = 1;
|
||||
c++;
|
||||
}
|
||||
}
|
||||
return c;
|
||||
}
|
||||
385
shared-core/radeon_ms_combios.h
Normal file
385
shared-core/radeon_ms_combios.h
Normal file
|
|
@ -0,0 +1,385 @@
|
|||
/*
|
||||
* Copyright 2006-2007 Advanced Micro Devices, Inc.
|
||||
* Copyright 2007 Jérôme Glisse
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
/*
|
||||
* Authors:
|
||||
* Jérôme Glisse <glisse@freedesktop.org>
|
||||
*/
|
||||
#ifndef __RADEON_MS_COMBIOS_H__
|
||||
#define __RADEON_MS_COMBIOS_H__
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
#define ROM_HEADER 0x48
|
||||
|
||||
struct combios_header
|
||||
{
|
||||
uint8_t ucTypeDefinition;
|
||||
uint8_t ucExtFunctionCode;
|
||||
uint8_t ucOemID1;
|
||||
uint8_t ucOemID2;
|
||||
uint8_t ucBiosMajorRev;
|
||||
uint8_t ucBiosMinorRev;
|
||||
uint16_t usStructureSize;
|
||||
uint16_t usPointerToSmi;
|
||||
uint16_t usPointerToPmid;
|
||||
uint16_t usPointerToInitTable;
|
||||
uint16_t usPointerToCrcChecksumBlock;
|
||||
uint16_t usPointerToConfigFilename;
|
||||
uint16_t usPointerToLogonMessage;
|
||||
uint16_t usPointerToMiscInfo;
|
||||
uint16_t usPciBusDevInitCode;
|
||||
uint16_t usBiosRuntimeSegmentAddress;
|
||||
uint16_t usIoBaseAddress;
|
||||
uint16_t usSubsystemVendorID;
|
||||
uint16_t usSubsystemID;
|
||||
uint16_t usPostVendorID;
|
||||
uint16_t usInt10Offset;
|
||||
uint16_t usInt10Segment;
|
||||
uint16_t usMonitorInfo;
|
||||
uint16_t usPointerToConfigBlock;
|
||||
uint16_t usPointerToDacDelayInfo;
|
||||
uint16_t usPointerToCapDataStruct;
|
||||
uint16_t usPointerToInternalCrtTables;
|
||||
uint16_t usPointerToPllInfoBlock;
|
||||
uint16_t usPointerToTVInfoTable;
|
||||
uint16_t usPointerToDFPInfoTable;
|
||||
uint16_t usPointerToHWConfigTable;
|
||||
uint16_t usPointerToMMConfigTable;
|
||||
uint32_t ulTVStdPatchTableSignature;
|
||||
uint16_t usPointerToTVStdPatchTable;
|
||||
uint16_t usPointerToPanelInfoTable;
|
||||
uint16_t usPointerToAsicInfoTable;
|
||||
uint16_t usPointerToAuroraInfoTable;
|
||||
uint16_t usPointerToPllInitTable;
|
||||
uint16_t usPointerToMemoryConfigTable;
|
||||
uint16_t usPointerToSaveMaskTable;
|
||||
uint16_t usPointerHardCodedEdid;
|
||||
uint16_t usPointerToExtendedInitTable1;
|
||||
uint16_t usPointerToExtendedInitTable2;
|
||||
uint16_t usPointerToDynamicClkTable;
|
||||
uint16_t usPointerToReservedMemoryTable;
|
||||
uint16_t usPointerToBridgetInitTable;
|
||||
uint16_t usPointerToExtTMDSInitTable;
|
||||
uint16_t usPointerToMemClkInfoTable;
|
||||
uint16_t usPointerToExtDACTable;
|
||||
uint16_t usPointerToMiscInfoTable;
|
||||
};
|
||||
|
||||
struct combios_pll_block
|
||||
{
|
||||
/* Usually 6 */
|
||||
uint8_t ucPLLBiosVersion;
|
||||
/* Size in bytes */
|
||||
uint8_t ucStructureSize;
|
||||
/* Dot clock entry used for accelerated modes */
|
||||
uint8_t ucDotClockEntry;
|
||||
/* Dot clock entry used for extended VGA modes */
|
||||
uint8_t ucDotClockEntryVga;
|
||||
/* Offset into internal clock table used for by VGA parameter table */
|
||||
uint16_t usPointerToInternalClock;
|
||||
/* Offset into actual programmed frequency table at POST */
|
||||
uint16_t usPointerToFreqTable;
|
||||
/* XCLK setting, (memory clock in 10 KHz units) */
|
||||
uint16_t usXclkSetting;
|
||||
/* MCLK setting, (engine clock in 10 KHz units) */
|
||||
uint16_t usMclkSetting;
|
||||
/* Number of PLL information block to follow, currently value is 3 */
|
||||
uint8_t ucPllInfoBlockNumber;
|
||||
/* Size of each PLL information block */
|
||||
uint8_t ucPllInfoBlockSize;
|
||||
/* Reference frequency of the dot clock */
|
||||
uint16_t usDotClockRefFreq;
|
||||
/* Reference Divider of the dot clock */
|
||||
uint16_t usDotClockRefDiv;
|
||||
/* Min Frequency supported before post divider for the dot clock */
|
||||
uint32_t ulDotClockMinFreq;
|
||||
/* Max Frequency can be supported for the dot clock */
|
||||
uint32_t ulDotClockMaxFreq;
|
||||
/* Reference frequency of the MCLK, engine clock */
|
||||
uint16_t usMclkRefFreq;
|
||||
/* Reference Divider of the MCLK, engine clock */
|
||||
uint16_t usMclkRefDiv;
|
||||
/* Min Frequency supported before post divider for MCLK, engine clock */
|
||||
uint32_t ulMclkMinFreq;
|
||||
/* Max Frequency can be supported for the MCLK, engine clock */
|
||||
uint32_t ulMclkMaxFreq;
|
||||
/* Reference frequency of the XCLK, memory clock */
|
||||
uint16_t usXclkRefFreq;
|
||||
/* Reference Divider of the XCLK, memory clock */
|
||||
uint16_t usXclkRefDiv;
|
||||
/* Min Frequency supported before post divider for XCLK, memory clock */
|
||||
uint32_t ulXclkMinFreq;
|
||||
/* Max Frequency can be supported for the XCLK, memory clock */
|
||||
uint32_t ulXclkMaxFreq;
|
||||
|
||||
/*this is the PLL Information Table Extended structure version 10 */
|
||||
uint8_t ucNumberOfExtendedPllBlocks;
|
||||
uint8_t ucSizePLLDefinition;
|
||||
uint16_t ulCrystalFrequencyPixelClock_pll;
|
||||
uint32_t ulMinInputPixelClockPLLFrequency;
|
||||
uint32_t ulMaxInputPixelClockPLLFrequency;
|
||||
uint32_t ulMinOutputPixelClockPLLFrequency;
|
||||
uint32_t ulMaxOutputPixelClockPLLFrequency;
|
||||
|
||||
/*version 11 */
|
||||
uint16_t ulCrystalFrequencyEngineClock_pll;
|
||||
uint32_t ulMinInputFrequencyEngineClock_pll;
|
||||
uint32_t ulMaxInputFrequencyEngineClock_pll;
|
||||
uint32_t ulMinOutputFrequencyEngineClock_pll;
|
||||
uint32_t ulMaxOutputFrequencyEngineClock_pll;
|
||||
uint16_t ulCrystalFrequencyMemoryClock_pll;
|
||||
uint32_t ulMinInputFrequencyMemoryClock_pll;
|
||||
uint32_t ulMaxInputFrequencyMemoryClock_pll;
|
||||
uint32_t ulMinOutputFrequencyMemoryClock_pll;
|
||||
uint32_t ulMaxOutputFrequencyMemoryClock_pll;
|
||||
uint32_t ulMaximumDACOutputFrequency;
|
||||
};
|
||||
|
||||
#define MAX_NO_OF_LCD_RES_TIMING 25
|
||||
|
||||
struct panel_information_table
|
||||
{
|
||||
uint8_t ucPanelIdentification;
|
||||
uint8_t ucPanelIDString[24];
|
||||
uint16_t usHorizontalSize;
|
||||
uint16_t usVerticalSize;
|
||||
uint16_t usFlatPanelType;
|
||||
uint8_t ucRedBitsPerPrimary;
|
||||
uint8_t ucGreenBitsPerPrimary;
|
||||
uint8_t ucBlueBitsPerPrimary;
|
||||
uint8_t ucReservedBitsPerPrimary;
|
||||
uint8_t ucPanelCaps;
|
||||
uint8_t ucPowerSequenceDelayStepsInMS;
|
||||
uint8_t ucSupportedRefreshRateExtended;
|
||||
uint16_t usExtendedPanelInfoTable;
|
||||
uint16_t usPtrToHalfFrameBufferInformationTable;
|
||||
uint16_t usVccOntoBlOn;
|
||||
uint16_t usOffDelay;
|
||||
uint16_t usRefDiv;
|
||||
uint8_t ucPostDiv;
|
||||
uint16_t usFeedBackDiv;
|
||||
uint8_t ucSpreadSpectrumType;
|
||||
uint16_t usSpreadSpectrumPercentage;
|
||||
uint8_t ucBackLightLevel;
|
||||
uint8_t ucBiasLevel;
|
||||
uint8_t ucPowerSequenceDelay;
|
||||
uint32_t ulPanelData;
|
||||
uint8_t ucPanelRefreshRateData;
|
||||
uint16_t usSupportedRefreshRate;
|
||||
uint16_t usModeTableOffset[MAX_NO_OF_LCD_RES_TIMING];
|
||||
};
|
||||
|
||||
struct extended_panel_info_table
|
||||
{
|
||||
uint8_t ucExtendedPanelInfoTableVer;
|
||||
uint8_t ucSSDelay;
|
||||
uint8_t ucSSStepSizeIndex;
|
||||
};
|
||||
|
||||
struct lcd_mode_table_center
|
||||
{
|
||||
uint16_t usHorizontalRes;
|
||||
uint16_t usVerticalRes;
|
||||
uint8_t ucModeType;
|
||||
uint16_t usOffset2ExpParamTable;
|
||||
uint16_t usOffset2TvParamTable;
|
||||
uint16_t usPixelClock;
|
||||
uint16_t usPixelClockAdjustment;
|
||||
uint16_t usFpPos;
|
||||
uint8_t ucReserved;
|
||||
uint8_t ucMiscBits;
|
||||
uint16_t usCrtcHTotal;
|
||||
uint16_t usCrtcHDisp;
|
||||
uint16_t usCrtcHSyncStrt;
|
||||
uint8_t ucCrtcHSyncWid;
|
||||
uint16_t usCrtcVTotal;
|
||||
uint16_t usCrtcVDisp;
|
||||
uint16_t usCrtcVSyncStrt;
|
||||
uint8_t ucOvrWidTop;
|
||||
};
|
||||
|
||||
struct lcd_mode_table_exp
|
||||
{
|
||||
uint16_t usPixelClock;
|
||||
uint16_t usPixelClockAdjustment;
|
||||
uint16_t usFpPos;
|
||||
uint8_t ucReserved;
|
||||
uint8_t ucMiscBits;
|
||||
uint16_t usCrtcHTotal;
|
||||
uint16_t usCrtcHDisp;
|
||||
uint16_t usCrtcHSyncStrt;
|
||||
uint8_t ucCrtcHSyncWid;
|
||||
uint16_t usCrtcVTotal;
|
||||
uint16_t usCrtcVDisp;
|
||||
uint16_t usCrtcVSyncStrt;
|
||||
uint8_t ucOvrWidTop;
|
||||
uint16_t usHorizontalBlendRatio;
|
||||
uint32_t ulVgaVertStretching;
|
||||
uint16_t usCopVertStretching;
|
||||
uint16_t usVgaExtVertStretching;
|
||||
};
|
||||
|
||||
struct tmds_pll_cntl_block
|
||||
{
|
||||
uint16_t usClockUpperRange;
|
||||
uint32_t ulPllSetting;
|
||||
};
|
||||
|
||||
#define MAX_PLL_CNTL_ENTRIES 8
|
||||
|
||||
struct combios_dfp_info_table
|
||||
{
|
||||
uint8_t ucDFPInfoTableRev;
|
||||
uint8_t ucDFPInfoTableSize;
|
||||
uint16_t usOffsetDetailedTimingTable;
|
||||
uint8_t ucReserved;
|
||||
uint8_t ucNumberOfClockRanges;
|
||||
uint16_t usMaxPixelClock;
|
||||
uint32_t ulInitValueTmdsPllCntl;
|
||||
uint32_t ulFinalValueTmdsPllCntl;
|
||||
struct tmds_pll_cntl_block sTmdsPllCntlBlock[MAX_PLL_CNTL_ENTRIES];
|
||||
};
|
||||
|
||||
struct combios_exttmds_table_header
|
||||
{
|
||||
uint8_t ucTableRev;
|
||||
uint16_t usTableSize;
|
||||
uint8_t ucNoBlocks;
|
||||
};
|
||||
|
||||
struct combios_exttmds_block_header
|
||||
{
|
||||
uint16_t usMaxFreq;
|
||||
uint8_t ucI2CSlaveAddr;
|
||||
uint8_t ucI2CLine;
|
||||
uint8_t ucConnectorId;
|
||||
uint8_t ucFlags;
|
||||
};
|
||||
|
||||
/* Connector table - applicable from Piglet and later ASICs
|
||||
byte 0 (embedded revision)
|
||||
[7:4] = number of chips (valid number 1 - 15)
|
||||
[3:0] = revision number of table (valid number 1 - 15)
|
||||
|
||||
byte 1 (Chip info)
|
||||
[7:4] = chip number, max. 15 (valid number 1 - 15)
|
||||
[3:0] = number of connectors for that chip, (valid number 1 - 15)
|
||||
(number of connectors = number of 'Connector info' entries
|
||||
for that chip)
|
||||
|
||||
byte 2,3 (Connector info)
|
||||
[15:12] - connector type
|
||||
= 0 - no connector
|
||||
= 1 - proprietary
|
||||
= 2 - CRT
|
||||
= 3 - DVI-I
|
||||
= 4 - DVI-D
|
||||
= 5-15 - reserved for future expansion
|
||||
[11:8] - DDC line pair used for that connector
|
||||
= 0 - no DDC
|
||||
= 1 - MONID 0/1
|
||||
= 2 - DVI_DDC
|
||||
= 3 - VGA_DDC
|
||||
= 4 - CRT2_DDC
|
||||
= 5-15 - reserved for future expansion
|
||||
[5] - bit indicating presence of multiplexer for TV,CRT2
|
||||
[7:6] - reserved for future expansion
|
||||
[4] - TMDS type
|
||||
= 0 - internal TMDS
|
||||
= 1 - external TMDS
|
||||
[3:1] - reserved for future expansion
|
||||
[0] - DAC associated with that connector
|
||||
= 0 - CRT DAC
|
||||
= 1 - non-CRT DAC (e.g. TV DAC, external DAC ..)
|
||||
|
||||
byte 4,5,6... - byte 4,5 can be another "Connector info" word
|
||||
describing another connector
|
||||
- or byte 5 is a "Chip info" byte for anther chip,
|
||||
then start with byte 5,6 to describe connectors
|
||||
for that chip
|
||||
- or byte 5 = 0 if all connectors for all chips on
|
||||
board have been described, no more connector left
|
||||
to describe.
|
||||
*/
|
||||
#define BIOS_CONNECTOR_INFO__TYPE__MASK 0xF000
|
||||
#define BIOS_CONNECTOR_INFO__TYPE__SHIFT 0x0000000C
|
||||
#define BIOS_CONNECTOR_TYPE__NONE 0x00000000
|
||||
#define BIOS_CONNECTOR_TYPE__PROPRIETARY 0x00000001
|
||||
#define BIOS_CONNECTOR_TYPE__CRT 0x00000002
|
||||
#define BIOS_CONNECTOR_TYPE__DVI_I 0x00000003
|
||||
#define BIOS_CONNECTOR_TYPE__DVI_D 0x00000004
|
||||
|
||||
#define BIOS_CONNECTOR_INFO__DDC_LINE__MASK 0x0F00
|
||||
#define BIOS_CONNECTOR_INFO__DDC_LINE__SHIFT 0x00000008
|
||||
#define BIOS_DDC_LINE__NONE 0x00000000
|
||||
#define BIOS_DDC_LINE__MONID01 0x00000001
|
||||
#define BIOS_DDC_LINE__DVI 0x00000002
|
||||
#define BIOS_DDC_LINE__VGA 0x00000003
|
||||
#define BIOS_DDC_LINE__CRT2 0x00000004
|
||||
#define BIOS_DDC_LINE__GPIOPAD 0x00000005
|
||||
#define BIOS_DDC_LINE__ZV_LCDPAD 0x00000006
|
||||
|
||||
#define BIOS_CONNECTOR_INFO__TMDS_TYPE__MASK 0x0010
|
||||
#define BIOS_CONNECTOR_INFO__TMDS_TYPE__SHIFT 0x00000004
|
||||
#define BIOS_TMDS_TYPE__INTERNAL 0x00000000
|
||||
#define BIOS_TMDS_TYPE__EXTERNAL 0x00000001
|
||||
|
||||
#define BIOS_CONNECTOR_INFO__DAC_TYPE__MASK 0x0001
|
||||
#define BIOS_CONNECTOR_INFO__DAC_TYPE__SHIFT 0x00000000
|
||||
#define BIOS_DAC_TYPE__CRT 0x00000000
|
||||
#define BIOS_DAC_TYPE__NON_CRT 0x00000001
|
||||
|
||||
#define BIOS_CONNECTOR_INFO__MUX_MASK 0x00000020
|
||||
#define BIOS_CONNECTOR_INFO__MUX_SHIFT 0x00000005
|
||||
|
||||
#define BIOS_CHIPINFO_HEADER__CHIP_NUMBER__MASK 0xF0
|
||||
#define BIOS_CHIPINFO_HEADER__CHIP_NUMBER__SHIFT 0x00000004
|
||||
|
||||
#define BIOS_CHIPINFO_HEADER__NUMBER_OF_CONNECTORS__MASK 0x0F
|
||||
#define BIOS_CHIPINFO_HEADER__NUMBER_OF_CONNECTORS__SHIFT 0x00000000
|
||||
|
||||
#define BIOS_CHIPINFO__MAX_NUMBER_OF_CONNECTORS 0x00000010
|
||||
|
||||
struct combios_connector_chip_info
|
||||
{
|
||||
uint8_t ucChipHeader;
|
||||
uint16_t sConnectorInfo[BIOS_CHIPINFO__MAX_NUMBER_OF_CONNECTORS];
|
||||
};
|
||||
|
||||
#define BIOS_CONNECTOR_HEADER__NUMBER_OF_CHIPS__MASK 0xF0
|
||||
#define BIOS_CONNECTOR_HEADER__NUMBER_OF_CHIPS__SHIFT 0x00000004
|
||||
|
||||
#define BIOS_CONNECTOR_HEADER__TABLE_REVISION__MASK 0x0F
|
||||
#define BIOS_CONNECTOR_HEADER__TABLE_REVISION__SHIFT 0x00000000
|
||||
|
||||
struct combios_connector_table
|
||||
{
|
||||
uint8_t ucConnectorHeader;
|
||||
struct combios_connector_chip_info sChipConnectorInfo[0x10];
|
||||
};
|
||||
|
||||
#pragma pack()
|
||||
|
||||
int combios_parse(unsigned char *rom, struct combios_header *header);
|
||||
|
||||
#endif
|
||||
|
|
@ -380,23 +380,26 @@ static void radeon_ms_crtc_mode_prepare(struct drm_crtc *crtc)
|
|||
}
|
||||
|
||||
/* compute PLL registers values for requested video mode */
|
||||
static int radeon_pll1_constraint(int clock, int rdiv,
|
||||
static int radeon_pll1_constraint(struct drm_device *dev,
|
||||
int clock, int rdiv,
|
||||
int fdiv, int pdiv,
|
||||
int rfrq, int pfrq)
|
||||
{
|
||||
int dfrq;
|
||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||
int dfrq;
|
||||
|
||||
if (rdiv < 2 || fdiv < 4) {
|
||||
return 0;
|
||||
}
|
||||
dfrq = rfrq / rdiv;
|
||||
if (dfrq < 2000 || dfrq > 3300) {
|
||||
return 0;
|
||||
}
|
||||
if (pfrq < 125000 || pfrq > 250000) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
if (rdiv < 2 || fdiv < 4) {
|
||||
return 0;
|
||||
}
|
||||
dfrq = rfrq / rdiv;
|
||||
if (dfrq < 2000 || dfrq > 3300) {
|
||||
return 0;
|
||||
}
|
||||
if (pfrq < dev_priv->properties.pll_min_pll_freq ||
|
||||
pfrq > dev_priv->properties.pll_max_pll_freq) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void radeon_pll1_compute(struct drm_crtc *crtc,
|
||||
|
|
@ -424,7 +427,7 @@ static void radeon_pll1_compute(struct drm_crtc *crtc,
|
|||
struct drm_radeon_private *dev_priv = crtc->dev->dev_private;
|
||||
struct radeon_state *state = &dev_priv->driver_state;
|
||||
int clock = mode->clock;
|
||||
int rfrq = dev_priv->properties->pll_reference_freq;
|
||||
int rfrq = dev_priv->properties.pll_reference_freq;
|
||||
int pdiv = 1;
|
||||
int pdiv_id = 0;
|
||||
int rdiv_best = 2;
|
||||
|
|
@ -441,11 +444,11 @@ static void radeon_pll1_compute(struct drm_crtc *crtc,
|
|||
int diff_cpfrq = 350000;
|
||||
|
||||
/* clamp frequency into pll [min; max] frequency range */
|
||||
if (clock > dev_priv->properties->pll_max_pll_freq) {
|
||||
clock = dev_priv->properties->pll_max_pll_freq;
|
||||
if (clock > dev_priv->properties.pll_max_pll_freq) {
|
||||
clock = dev_priv->properties.pll_max_pll_freq;
|
||||
}
|
||||
if ((clock * 12) < dev_priv->properties->pll_min_pll_freq) {
|
||||
clock = dev_priv->properties->pll_min_pll_freq / 12;
|
||||
if ((clock * 12) < dev_priv->properties.pll_min_pll_freq) {
|
||||
clock = dev_priv->properties.pll_min_pll_freq / 12;
|
||||
}
|
||||
|
||||
/* maximize pll_ref_div while staying in boundary and minimizing
|
||||
|
|
@ -457,8 +460,8 @@ static void radeon_pll1_compute(struct drm_crtc *crtc,
|
|||
tfrq = clock * post_div->divider;
|
||||
for (fdiv = 1023; fdiv >= 4; fdiv--) {
|
||||
rdiv = (fdiv * rfrq) / tfrq;
|
||||
if (radeon_pll1_constraint(clock, rdiv, fdiv,
|
||||
pdiv, rfrq, tfrq)) {
|
||||
if (radeon_pll1_constraint(crtc->dev, clock, rdiv,
|
||||
fdiv, pdiv, rfrq, tfrq)) {
|
||||
pfrq = (fdiv * rfrq) / rdiv;
|
||||
diff_cpfrq = pfrq - tfrq;
|
||||
if ((diff_cpfrq >= 0 &&
|
||||
|
|
|
|||
|
|
@ -203,15 +203,35 @@ int radeon_ms_driver_load(struct drm_device *dev, unsigned long flags)
|
|||
radeon_ms_driver_unload(dev);
|
||||
return ret;
|
||||
}
|
||||
ret = radeon_ms_outputs_from_properties(dev);
|
||||
if (ret != 0) {
|
||||
ret = radeon_ms_outputs_from_rom(dev);
|
||||
if (ret < 0) {
|
||||
radeon_ms_driver_unload(dev);
|
||||
return ret;
|
||||
} else if (!ret) {
|
||||
ret = radeon_ms_outputs_from_properties(dev);
|
||||
if (ret < 0) {
|
||||
radeon_ms_driver_unload(dev);
|
||||
return ret;
|
||||
} else if (ret == 0) {
|
||||
DRM_INFO("[radeon_ms] no outputs !\n");
|
||||
}
|
||||
} else {
|
||||
DRM_INFO("[radeon_ms] added %d outputs from rom.\n", ret);
|
||||
}
|
||||
ret = radeon_ms_connectors_from_properties(dev);
|
||||
if (ret != 0) {
|
||||
ret = radeon_ms_connectors_from_rom(dev);
|
||||
if (ret < 0) {
|
||||
radeon_ms_driver_unload(dev);
|
||||
return ret;
|
||||
} else if (!ret) {
|
||||
ret = radeon_ms_connectors_from_properties(dev);
|
||||
if (ret < 0) {
|
||||
radeon_ms_driver_unload(dev);
|
||||
return ret;
|
||||
} else if (!ret) {
|
||||
DRM_INFO("[radeon_ms] no connectors !\n");
|
||||
}
|
||||
} else {
|
||||
DRM_INFO("[radeon_ms] added %d connectors from rom.\n", ret);
|
||||
}
|
||||
radeon_ms_outputs_save(dev, &dev_priv->load_state);
|
||||
drm_initial_config(dev, false);
|
||||
|
|
|
|||
|
|
@ -29,87 +29,6 @@
|
|||
#include "drm.h"
|
||||
#include "radeon_ms.h"
|
||||
|
||||
static struct radeon_ms_output radeon_ms_dac1 = {
|
||||
OUTPUT_DAC1,
|
||||
NULL,
|
||||
NULL,
|
||||
radeon_ms_dac1_initialize,
|
||||
radeon_ms_dac1_detect,
|
||||
radeon_ms_dac1_dpms,
|
||||
radeon_ms_dac1_get_modes,
|
||||
radeon_ms_dac1_mode_fixup,
|
||||
radeon_ms_dac1_mode_set,
|
||||
radeon_ms_dac1_restore,
|
||||
radeon_ms_dac1_save
|
||||
};
|
||||
|
||||
static struct radeon_ms_output radeon_ms_dac2 = {
|
||||
OUTPUT_DAC2,
|
||||
NULL,
|
||||
NULL,
|
||||
radeon_ms_dac2_initialize,
|
||||
radeon_ms_dac2_detect,
|
||||
radeon_ms_dac2_dpms,
|
||||
radeon_ms_dac2_get_modes,
|
||||
radeon_ms_dac2_mode_fixup,
|
||||
radeon_ms_dac2_mode_set,
|
||||
radeon_ms_dac2_restore,
|
||||
radeon_ms_dac2_save
|
||||
};
|
||||
|
||||
static struct radeon_ms_connector radeon_ms_vga = {
|
||||
NULL, NULL, NULL, CONNECTOR_VGA, MT_NONE, 0, GPIO_DDC1,
|
||||
{
|
||||
0, -1, -1, -1, -1, -1, -1, -1
|
||||
},
|
||||
"VGA"
|
||||
};
|
||||
|
||||
static struct radeon_ms_connector radeon_ms_dvi_i_2 = {
|
||||
NULL, NULL, NULL, CONNECTOR_DVI_I, MT_NONE, 0, GPIO_DDC2,
|
||||
{
|
||||
1, -1, -1, -1, -1, -1, -1, -1
|
||||
},
|
||||
"DVI-I"
|
||||
};
|
||||
|
||||
static struct radeon_ms_properties properties[] = {
|
||||
/* default only one VGA connector */
|
||||
{
|
||||
0, 0, 27000, 25000, 200000, 1, 1, 1, 1,
|
||||
{
|
||||
&radeon_ms_dac1, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL
|
||||
},
|
||||
{
|
||||
&radeon_ms_vga, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL
|
||||
}
|
||||
},
|
||||
{
|
||||
0x1043, 0x176, 27000, 25000, 200000, 1, 1, 1, 1,
|
||||
{
|
||||
&radeon_ms_dac1, &radeon_ms_dac2, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL
|
||||
},
|
||||
{
|
||||
&radeon_ms_vga, &radeon_ms_dvi_i_2, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL
|
||||
}
|
||||
},
|
||||
{
|
||||
0x1002, 0x4150, 27000, 25000, 200000, 1, 1, 1, 1,
|
||||
{
|
||||
&radeon_ms_dac1, &radeon_ms_dac2, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL
|
||||
},
|
||||
{
|
||||
&radeon_ms_vga, &radeon_ms_dvi_i_2, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
extern const uint32_t radeon_cp_microcode[];
|
||||
extern const uint32_t r200_cp_microcode[];
|
||||
extern const uint32_t r300_cp_microcode[];
|
||||
|
|
@ -159,7 +78,7 @@ static void r300_flush_cache(struct drm_device *dev)
|
|||
int radeon_ms_family_init(struct drm_device *dev)
|
||||
{
|
||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||
int i;
|
||||
int ret;
|
||||
|
||||
dev_priv->microcode = radeon_cp_microcode;
|
||||
dev_priv->irq_emit = radeon_ms_irq_emit;
|
||||
|
|
@ -213,17 +132,10 @@ int radeon_ms_family_init(struct drm_device *dev)
|
|||
DRM_ERROR("Unknown radeon bus type, aborting\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
dev_priv->properties = NULL;
|
||||
for (i = 1; i < sizeof(properties)/sizeof(properties[0]); i++) {
|
||||
if (dev->pdev->subsystem_vendor == properties[i].subvendor &&
|
||||
dev->pdev->subsystem_device == properties[i].subdevice) {
|
||||
DRM_INFO("[radeon_ms] found properties for 0x%04X:0x%04X\n",
|
||||
properties[i].subvendor, properties[i].subdevice);
|
||||
dev_priv->properties = &properties[i];
|
||||
}
|
||||
ret = radeon_ms_rom_init(dev);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
if (dev_priv->properties == NULL) {
|
||||
dev_priv->properties = &properties[0];
|
||||
}
|
||||
return 0;
|
||||
ret = radeon_ms_properties_init(dev);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,6 +66,22 @@ static int get_clock(void *data)
|
|||
v = 0;
|
||||
}
|
||||
break;
|
||||
case GPIO_MONID:
|
||||
v = MMIO_R(GPIO_MONID);
|
||||
if ((GPIO_MONID__GPIO_MONID_1_INPUT & v)) {
|
||||
v = 1;
|
||||
} else {
|
||||
v = 0;
|
||||
}
|
||||
break;
|
||||
case GPIO_CRT2_DDC:
|
||||
v = MMIO_R(GPIO_CRT2_DDC);
|
||||
if ((GPIO_CRT2_DDC__CRT2_DDC_CLK_INPUT & v)) {
|
||||
v = 1;
|
||||
} else {
|
||||
v = 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
v = 0;
|
||||
break;
|
||||
|
|
@ -112,6 +128,22 @@ static int get_data(void *data)
|
|||
v = 0;
|
||||
}
|
||||
break;
|
||||
case GPIO_MONID:
|
||||
v = MMIO_R(GPIO_MONID);
|
||||
if ((GPIO_MONID__GPIO_MONID_0_INPUT & v)) {
|
||||
v = 1;
|
||||
} else {
|
||||
v = 0;
|
||||
}
|
||||
break;
|
||||
case GPIO_CRT2_DDC:
|
||||
v = MMIO_R(GPIO_CRT2_DDC);
|
||||
if ((GPIO_CRT2_DDC__CRT2_DDC_DATA_INPUT & v)) {
|
||||
v = 1;
|
||||
} else {
|
||||
v = 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
v = 0;
|
||||
break;
|
||||
|
|
@ -157,6 +189,18 @@ static void set_clock(void *i2c_priv, int clock)
|
|||
v |= GPIO_DDC2__DDC2_CLK_OUT_EN;
|
||||
}
|
||||
break;
|
||||
case GPIO_MONID:
|
||||
v &= ~GPIO_MONID__GPIO_MONID_1_OUT_EN;
|
||||
if (!clock) {
|
||||
v |= GPIO_MONID__GPIO_MONID_1_OUT_EN;
|
||||
}
|
||||
break;
|
||||
case GPIO_CRT2_DDC:
|
||||
v &= ~GPIO_CRT2_DDC__CRT2_DDC_CLK_OUT_EN;
|
||||
if (!clock) {
|
||||
v |= GPIO_CRT2_DDC__CRT2_DDC_CLK_OUT_EN;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
|
@ -201,6 +245,18 @@ static void set_data(void *i2c_priv, int data)
|
|||
v |= GPIO_DDC2__DDC2_DATA_OUT_EN;
|
||||
}
|
||||
break;
|
||||
case GPIO_MONID:
|
||||
v &= ~GPIO_MONID__GPIO_MONID_0_OUT_EN;
|
||||
if (!data) {
|
||||
v |= GPIO_MONID__GPIO_MONID_0_OUT_EN;
|
||||
}
|
||||
break;
|
||||
case GPIO_CRT2_DDC:
|
||||
v &= ~GPIO_CRT2_DDC__CRT2_DDC_DATA_OUT_EN;
|
||||
if (!data) {
|
||||
v |= GPIO_CRT2_DDC__CRT2_DDC_DATA_OUT_EN;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
|
@ -251,11 +307,12 @@ struct radeon_ms_i2c *radeon_ms_i2c_create(struct drm_device *dev,
|
|||
|
||||
ret = i2c_bit_add_bus(&i2c->adapter);
|
||||
if(ret) {
|
||||
DRM_INFO("[radeon_ms] failed to register I2C '%s' bus\n",
|
||||
i2c->adapter.name);
|
||||
DRM_INFO("[radeon_ms] failed to register I2C '%s' bus (0x%X)\n",
|
||||
i2c->adapter.name, reg);
|
||||
goto out_free;
|
||||
}
|
||||
DRM_INFO("[radeon_ms] registered I2C '%s' bus\n", i2c->adapter.name);
|
||||
DRM_INFO("[radeon_ms] registered I2C '%s' bus (0x%X)\n",
|
||||
i2c->adapter.name, reg);
|
||||
return i2c;
|
||||
|
||||
out_free:
|
||||
|
|
|
|||
|
|
@ -189,7 +189,7 @@ static void radeon_ms_output_cleanup(struct drm_output *output)
|
|||
output->driver_private = NULL;
|
||||
}
|
||||
|
||||
static const struct drm_output_funcs radeon_ms_output_funcs = {
|
||||
const struct drm_output_funcs radeon_ms_output_funcs = {
|
||||
.dpms = radeon_ms_output_dpms,
|
||||
.save = NULL,
|
||||
.restore = NULL,
|
||||
|
|
@ -233,11 +233,11 @@ int radeon_ms_connectors_from_properties(struct drm_device *dev)
|
|||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||
struct radeon_ms_connector *connector = NULL;
|
||||
struct drm_output *output = NULL;
|
||||
int i = 0;
|
||||
int i = 0, c = 0;
|
||||
|
||||
radeon_ms_connectors_destroy(dev);
|
||||
for (i = 0; i < RADEON_MAX_CONNECTORS; i++) {
|
||||
if (dev_priv->properties->connectors[i]) {
|
||||
if (dev_priv->properties.connectors[i]) {
|
||||
connector =
|
||||
drm_alloc(sizeof(struct radeon_ms_connector),
|
||||
DRM_MEM_DRIVER);
|
||||
|
|
@ -245,11 +245,11 @@ int radeon_ms_connectors_from_properties(struct drm_device *dev)
|
|||
radeon_ms_connectors_destroy(dev);
|
||||
return -ENOMEM;
|
||||
}
|
||||
memcpy(connector,
|
||||
dev_priv->properties->connectors[i],
|
||||
sizeof(struct radeon_ms_connector));
|
||||
connector->i2c = radeon_ms_i2c_create(dev,
|
||||
connector->i2c_reg, connector->name);
|
||||
memcpy(connector, dev_priv->properties.connectors[i],
|
||||
sizeof(struct radeon_ms_connector));
|
||||
connector->i2c =
|
||||
radeon_ms_i2c_create(dev, connector->i2c_reg,
|
||||
connector->name);
|
||||
if (connector->i2c == NULL) {
|
||||
radeon_ms_connectors_destroy(dev);
|
||||
return -ENOMEM;
|
||||
|
|
@ -264,9 +264,20 @@ int radeon_ms_connectors_from_properties(struct drm_device *dev)
|
|||
connector->output = output;
|
||||
output->driver_private = connector;
|
||||
output->possible_crtcs = 0x3;
|
||||
dev_priv->connectors[i] = connector;
|
||||
dev_priv->connectors[c++] = connector;
|
||||
}
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
int radeon_ms_connectors_from_rom(struct drm_device *dev)
|
||||
{
|
||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||
|
||||
switch (dev_priv->rom.type) {
|
||||
case ROM_COMBIOS:
|
||||
return radeon_ms_connectors_from_combios(dev);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -289,24 +300,37 @@ int radeon_ms_outputs_from_properties(struct drm_device *dev)
|
|||
{
|
||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||
int i = 0;
|
||||
int c = 0;
|
||||
|
||||
radeon_ms_outputs_destroy(dev);
|
||||
for (i = 0; i < RADEON_MAX_OUTPUTS; i++) {
|
||||
if (dev_priv->properties->outputs[i]) {
|
||||
if (dev_priv->properties.outputs[i]) {
|
||||
dev_priv->outputs[i] =
|
||||
drm_alloc(sizeof(struct radeon_ms_output),
|
||||
DRM_MEM_DRIVER);
|
||||
DRM_MEM_DRIVER);
|
||||
if (dev_priv->outputs[i] == NULL) {
|
||||
radeon_ms_outputs_destroy(dev);
|
||||
return -ENOMEM;
|
||||
}
|
||||
memcpy(dev_priv->outputs[i],
|
||||
dev_priv->properties->outputs[i],
|
||||
sizeof(struct radeon_ms_output));
|
||||
dev_priv->properties.outputs[i],
|
||||
sizeof(struct radeon_ms_output));
|
||||
dev_priv->outputs[i]->dev = dev;
|
||||
dev_priv->outputs[i]->initialize(dev_priv->outputs[i]);
|
||||
c++;
|
||||
}
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
int radeon_ms_outputs_from_rom(struct drm_device *dev)
|
||||
{
|
||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||
|
||||
switch (dev_priv->rom.type) {
|
||||
case ROM_COMBIOS:
|
||||
return radeon_ms_outputs_from_combios(dev);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
121
shared-core/radeon_ms_properties.c
Normal file
121
shared-core/radeon_ms_properties.c
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
* Copyright 2007 Jérôme Glisse
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
/*
|
||||
* Authors:
|
||||
* Jerome Glisse <glisse@freedesktop.org>
|
||||
*/
|
||||
#include "drmP.h"
|
||||
#include "drm.h"
|
||||
#include "radeon_ms.h"
|
||||
|
||||
struct radeon_ms_output radeon_ms_dac1 = {
|
||||
OUTPUT_DAC1,
|
||||
NULL,
|
||||
NULL,
|
||||
radeon_ms_dac1_initialize,
|
||||
radeon_ms_dac1_detect,
|
||||
radeon_ms_dac1_dpms,
|
||||
radeon_ms_dac1_get_modes,
|
||||
radeon_ms_dac1_mode_fixup,
|
||||
radeon_ms_dac1_mode_set,
|
||||
radeon_ms_dac1_restore,
|
||||
radeon_ms_dac1_save
|
||||
};
|
||||
|
||||
struct radeon_ms_output radeon_ms_dac2 = {
|
||||
OUTPUT_DAC2,
|
||||
NULL,
|
||||
NULL,
|
||||
radeon_ms_dac2_initialize,
|
||||
radeon_ms_dac2_detect,
|
||||
radeon_ms_dac2_dpms,
|
||||
radeon_ms_dac2_get_modes,
|
||||
radeon_ms_dac2_mode_fixup,
|
||||
radeon_ms_dac2_mode_set,
|
||||
radeon_ms_dac2_restore,
|
||||
radeon_ms_dac2_save
|
||||
};
|
||||
|
||||
struct radeon_ms_connector radeon_ms_vga = {
|
||||
NULL, NULL, NULL, ConnectorVGA, MT_NONE, 0, GPIO_DDC1,
|
||||
{
|
||||
0, -1, -1, -1, -1, -1, -1, -1
|
||||
}
|
||||
};
|
||||
|
||||
struct radeon_ms_connector radeon_ms_dvi_i_2 = {
|
||||
NULL, NULL, NULL, ConnectorDVII, MT_NONE, 0, GPIO_DDC2,
|
||||
{
|
||||
1, -1, -1, -1, -1, -1, -1, -1
|
||||
}
|
||||
};
|
||||
|
||||
struct radeon_ms_properties properties[] = {
|
||||
/* default only one VGA connector */
|
||||
{
|
||||
0, 0, 27000, 12, 25000, 200000, 1, 1, 1, 1,
|
||||
{
|
||||
&radeon_ms_dac1, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL
|
||||
},
|
||||
{
|
||||
&radeon_ms_vga, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
int radeon_ms_properties_init(struct drm_device *dev)
|
||||
{
|
||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||
int i, ret;
|
||||
|
||||
for (i = 1; i < sizeof(properties)/sizeof(properties[0]); i++) {
|
||||
if (dev->pdev->subsystem_vendor == properties[i].subvendor &&
|
||||
dev->pdev->subsystem_device == properties[i].subdevice) {
|
||||
DRM_INFO("[radeon_ms] found properties for "
|
||||
"0x%04X:0x%04X\n", properties[i].subvendor,
|
||||
properties[i].subdevice);
|
||||
memcpy(&dev_priv->properties, &properties[i],
|
||||
sizeof(struct radeon_ms_properties));
|
||||
}
|
||||
}
|
||||
if (dev_priv->properties.subvendor == 0) {
|
||||
ret = radeon_ms_rom_get_properties(dev);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
if (!ret) {
|
||||
memcpy(&dev_priv->properties, &properties[0],
|
||||
sizeof(struct radeon_ms_properties));
|
||||
} else {
|
||||
dev_priv->properties.pll_dummy_reads = 1;
|
||||
dev_priv->properties.pll_delay = 1;
|
||||
dev_priv->properties.pll_r300_errata = 1;
|
||||
}
|
||||
dev_priv->properties.subvendor = dev->pdev->subsystem_vendor;
|
||||
dev_priv->properties.subdevice = dev->pdev->subsystem_device;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
50
shared-core/radeon_ms_properties.h
Normal file
50
shared-core/radeon_ms_properties.h
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright 2007 Jérôme Glisse
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
/*
|
||||
* Authors:
|
||||
* Jerome Glisse <glisse@freedesktop.org>
|
||||
*/
|
||||
#ifndef __RADEON_MS_PROPERTIES_H__
|
||||
#define __RADEON_MS_PROPERTIES_H__
|
||||
|
||||
#define RADEON_PAGE_SIZE 4096
|
||||
#define RADEON_MAX_CONNECTORS 8
|
||||
#define RADEON_MAX_OUTPUTS 8
|
||||
|
||||
struct radeon_ms_properties {
|
||||
uint16_t subvendor;
|
||||
uint16_t subdevice;
|
||||
int16_t pll_reference_freq;
|
||||
int16_t pll_reference_div;
|
||||
int32_t pll_min_pll_freq;
|
||||
int32_t pll_max_pll_freq;
|
||||
char pll_use_bios;
|
||||
char pll_dummy_reads;
|
||||
char pll_delay;
|
||||
char pll_r300_errata;
|
||||
struct radeon_ms_output *outputs[RADEON_MAX_OUTPUTS];
|
||||
struct radeon_ms_connector *connectors[RADEON_MAX_CONNECTORS];
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -827,6 +827,32 @@
|
|||
#define GPIO_DDC2__SW_CAN_USE_DVI_I2C 0x00100000
|
||||
#define GPIO_DDC2__SW_DONE_USING_DVI_I2C 0x00200000
|
||||
#define GPIO_DDC2__HW_USING_DVI_I2C 0x00400000
|
||||
#define GPIO_DVI_DDC 0x00000064
|
||||
#define GPIO_DVI_DDC__DVI_DDC_DATA_OUTPUT 0x00000001
|
||||
#define GPIO_DVI_DDC__DVI_DCC_DATA_OUTPUT 0x00000001
|
||||
#define GPIO_DVI_DDC__DVI_DDC_CLK_OUTPUT 0x00000002
|
||||
#define GPIO_DVI_DDC__DVI_DDC_DATA_INPUT 0x00000100
|
||||
#define GPIO_DVI_DDC__DVI_DDC_CLK_INPUT 0x00000200
|
||||
#define GPIO_DVI_DDC__DVI_DDC_DATA_OUT_EN 0x00010000
|
||||
#define GPIO_DVI_DDC__DVI_DDC_CLK_OUT_EN 0x00020000
|
||||
#define GPIO_DVI_DDC__SW_WANTS_TO_USE_DVI_I2C 0x00100000
|
||||
#define GPIO_DVI_DDC__SW_CAN_USE_DVI_I2C 0x00100000
|
||||
#define GPIO_DVI_DDC__SW_DONE_USING_DVI_I2C 0x00200000
|
||||
#define GPIO_DVI_DDC__HW_USING_DVI_I2C 0x00400000
|
||||
#define GPIO_MONID 0x00000068
|
||||
#define GPIO_MONID__GPIO_MONID_0_OUTPUT 0x00000001
|
||||
#define GPIO_MONID__GPIO_MONID_1_OUTPUT 0x00000002
|
||||
#define GPIO_MONID__GPIO_MONID_0_INPUT 0x00000100
|
||||
#define GPIO_MONID__GPIO_MONID_1_INPUT 0x00000200
|
||||
#define GPIO_MONID__GPIO_MONID_0_OUT_EN 0x00010000
|
||||
#define GPIO_MONID__GPIO_MONID_1_OUT_EN 0x00020000
|
||||
#define GPIO_CRT2_DDC 0x0000006C
|
||||
#define GPIO_CRT2_DDC__CRT2_DDC_DATA_OUTPUT 0x00000001
|
||||
#define GPIO_CRT2_DDC__CRT2_DDC_CLK_OUTPUT 0x00000002
|
||||
#define GPIO_CRT2_DDC__CRT2_DDC_DATA_INPUT 0x00000100
|
||||
#define GPIO_CRT2_DDC__CRT2_DDC_CLK_INPUT 0x00000200
|
||||
#define GPIO_CRT2_DDC__CRT2_DDC_DATA_OUT_EN 0x00010000
|
||||
#define GPIO_CRT2_DDC__CRT2_DDC_CLK_OUT_EN 0x00020000
|
||||
#define CLOCK_CNTL_INDEX 0x00000008
|
||||
#define CLOCK_CNTL_INDEX__PLL_ADDR__MASK 0x0000001F
|
||||
#define CLOCK_CNTL_INDEX__PLL_ADDR__SHIFT 0
|
||||
|
|
|
|||
91
shared-core/radeon_ms_rom.c
Normal file
91
shared-core/radeon_ms_rom.c
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* Copyright 2007 Jérôme Glisse
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
/*
|
||||
* Authors:
|
||||
* Jerome Glisse <glisse@freedesktop.org>
|
||||
*/
|
||||
#include "radeon_ms.h"
|
||||
|
||||
int radeon_ms_rom_get_properties(struct drm_device *dev)
|
||||
{
|
||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||
|
||||
switch (dev_priv->rom.type) {
|
||||
case ROM_COMBIOS:
|
||||
return radeon_ms_combios_get_properties(dev);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int radeon_ms_rom_init(struct drm_device *dev)
|
||||
{
|
||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||
struct radeon_ms_rom *rom = &dev_priv->rom;
|
||||
void *rom_mapped;
|
||||
char atomstr[5] = {0, 0, 0, 0, 0};
|
||||
uint16_t *offset;
|
||||
|
||||
dev_priv->rom.type = ROM_UNKNOWN;
|
||||
/* copy rom if any */
|
||||
rom_mapped = pci_map_rom_copy(dev->pdev, &rom->rom_size);
|
||||
if (rom->rom_size) {
|
||||
rom->rom_image = drm_alloc(rom->rom_size, DRM_MEM_DRIVER);
|
||||
if (rom->rom_image == NULL) {
|
||||
return -1;
|
||||
}
|
||||
memcpy(rom->rom_image, rom_mapped, rom->rom_size);
|
||||
DRM_INFO("[radeon_ms] ROM %d bytes copied\n", rom->rom_size);
|
||||
} else {
|
||||
DRM_INFO("[radeon_ms] no ROM\n");
|
||||
return 0;
|
||||
}
|
||||
pci_unmap_rom(dev->pdev, rom_mapped);
|
||||
|
||||
if (rom->rom_image[0] != 0x55 || rom->rom_image[1] != 0xaa) {
|
||||
DRM_INFO("[radeon_ms] no ROM\n");
|
||||
DRM_INFO("[radeon_ms] ROM signature 0x55 0xaa missing\n");
|
||||
return 0;
|
||||
}
|
||||
offset = (uint16_t *)&rom->rom_image[ROM_HEADER];
|
||||
memcpy(atomstr, &rom->rom_image[*offset + 4], 4);
|
||||
if (!strcpy(atomstr, "ATOM") || !strcpy(atomstr, "MOTA")) {
|
||||
DRM_INFO("[radeon_ms] ATOMBIOS ROM detected\n");
|
||||
return 0;
|
||||
} else {
|
||||
struct combios_header **header;
|
||||
|
||||
header = &rom->rom.combios_header;
|
||||
if ((*offset + sizeof(struct combios_header)) > rom->rom_size) {
|
||||
DRM_INFO("[radeon_ms] wrong COMBIOS header offset\n");
|
||||
return -1;
|
||||
}
|
||||
dev_priv->rom.type = ROM_COMBIOS;
|
||||
*header = (struct combios_header *)&rom->rom_image[*offset];
|
||||
DRM_INFO("[radeon_ms] COMBIOS type : %d\n",
|
||||
(*header)->ucTypeDefinition);
|
||||
DRM_INFO("[radeon_ms] COMBIOS OEM ID: %02x %02x\n",
|
||||
(*header)->ucOemID1, (*header)->ucOemID2);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
51
shared-core/radeon_ms_rom.h
Normal file
51
shared-core/radeon_ms_rom.h
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Copyright 2007 Jérôme Glisse
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
/*
|
||||
* Authors:
|
||||
* Jerome Glisse <glisse@freedesktop.org>
|
||||
*/
|
||||
#ifndef __RADEON_MS_ROM_H__
|
||||
#define __RADEON_MS_ROM_H__
|
||||
|
||||
#include "radeon_ms_combios.h"
|
||||
|
||||
enum radeon_rom_type {
|
||||
ROM_COMBIOS,
|
||||
ROM_ATOMBIOS,
|
||||
ROM_UNKNOWN
|
||||
};
|
||||
|
||||
union radeon_ms_rom_type {
|
||||
struct combios_header *combios_header;
|
||||
};
|
||||
|
||||
struct radeon_ms_rom {
|
||||
uint8_t type;
|
||||
size_t rom_size;
|
||||
uint8_t *rom_image;
|
||||
union radeon_ms_rom_type rom;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
Loading…
Add table
Reference in a new issue