Committed patch by Euan Kirkhope to improve routing problems with Radeon cards;
this should fix bug #1293. I've tested it here on two machines, one works better now, the other stayed the same (Radeon 9250, and a laptop FireGL (id 4c66) version). This apparently also fixed bug #1394. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21930 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -35,6 +35,7 @@
|
|||||||
# define RADEON_FP2_PANEL_FORMAT (1 << 3)
|
# define RADEON_FP2_PANEL_FORMAT (1 << 3)
|
||||||
# define RADEON_FP2_SOURCE_SEL_MASK (3 << 10)
|
# define RADEON_FP2_SOURCE_SEL_MASK (3 << 10)
|
||||||
# define RADEON_FP2_SOURCE_SEL_CRTC2 (1 << 10)
|
# define RADEON_FP2_SOURCE_SEL_CRTC2 (1 << 10)
|
||||||
|
# define RADEON_FP2_SOURCE_SEL_RMX (2 << 10)
|
||||||
# define RADEON_FP2_SRC_SEL_MASK (3 << 13)
|
# define RADEON_FP2_SRC_SEL_MASK (3 << 13)
|
||||||
# define RADEON_FP2_SRC_SEL_CRTC2 (1 << 13)
|
# define RADEON_FP2_SRC_SEL_CRTC2 (1 << 13)
|
||||||
# define RADEON_FP2_FP_POL (1 << 16)
|
# define RADEON_FP2_FP_POL (1 << 16)
|
||||||
@@ -68,6 +69,12 @@
|
|||||||
# define RADEON_VERT_STRETCH_BLEND (1 << 26)
|
# define RADEON_VERT_STRETCH_BLEND (1 << 26)
|
||||||
# define RADEON_VERT_AUTO_RATIO_EN (1 << 27)
|
# define RADEON_VERT_AUTO_RATIO_EN (1 << 27)
|
||||||
# define RADEON_VERT_STRETCH_RESERVED 0xf1000000
|
# define RADEON_VERT_STRETCH_RESERVED 0xf1000000
|
||||||
|
|
||||||
|
#define RADEON_TMDS_PLL_CNTL 0x02a8
|
||||||
|
#define RADEON_TMDS_TRANSMITTER_CNTL 0x02a4
|
||||||
|
# define RADEON_TMDS_TRANSMITTER_PLLEN 1
|
||||||
|
# define RADEON_TMDS_TRANSMITTER_PLLRST 2
|
||||||
|
|
||||||
#define RADEON_FP_H_SYNC_STRT_WID 0x02c4
|
#define RADEON_FP_H_SYNC_STRT_WID 0x02c4
|
||||||
#define RADEON_FP_V_SYNC_STRT_WID 0x02c8
|
#define RADEON_FP_V_SYNC_STRT_WID 0x02c8
|
||||||
|
|
||||||
@@ -80,6 +87,9 @@
|
|||||||
# define RADEON_LVDS_DIGON (1 << 18)
|
# define RADEON_LVDS_DIGON (1 << 18)
|
||||||
# define RADEON_LVDS_BLON (1 << 19)
|
# define RADEON_LVDS_BLON (1 << 19)
|
||||||
# define RADEON_LVDS_SEL_CRTC2 (1 << 23)
|
# define RADEON_LVDS_SEL_CRTC2 (1 << 23)
|
||||||
|
#define RADEON_LVDS_PLL_CNTL 0x02d4
|
||||||
|
# define RADEON_HSYNC_DELAY_SHIFT 28
|
||||||
|
# define RADEON_HSYNC_DELAY_MASK (0xf << 28)
|
||||||
|
|
||||||
#define RADEON_FP_CRTC2_H_TOTAL_DISP 0x0350
|
#define RADEON_FP_CRTC2_H_TOTAL_DISP 0x0350
|
||||||
#define RADEON_FP_CRTC2_V_TOTAL_DISP 0x0354
|
#define RADEON_FP_CRTC2_V_TOTAL_DISP 0x0354
|
||||||
|
|||||||
@@ -348,6 +348,11 @@ typedef struct {
|
|||||||
uint32 best_vco; // preferred VCO frequency (0 for don't care)
|
uint32 best_vco; // preferred VCO frequency (0 for don't care)
|
||||||
} pll_info;
|
} pll_info;
|
||||||
|
|
||||||
|
// info for ext tmds pll
|
||||||
|
typedef struct {
|
||||||
|
uint32 freq;
|
||||||
|
uint32 value;
|
||||||
|
} tmds_pll_info;
|
||||||
|
|
||||||
// one overlay buffer
|
// one overlay buffer
|
||||||
typedef struct overlay_buffer_node {
|
typedef struct overlay_buffer_node {
|
||||||
@@ -520,22 +525,22 @@ typedef struct {
|
|||||||
uint16 device_id; // PCI device id
|
uint16 device_id; // PCI device id
|
||||||
uint8 revision; // PCI device revision
|
uint8 revision; // PCI device revision
|
||||||
|
|
||||||
//bool has_crtc2; // has second CRTC
|
|
||||||
radeon_type asic; // ASIC version
|
radeon_type asic; // ASIC version
|
||||||
bool is_mobility; // mobility version
|
bool is_mobility; // mobility version
|
||||||
bool is_igp; // might need to know if it's an integrated chip
|
bool is_igp; // might need to know if it's an integrated chip
|
||||||
bool is_atombios;
|
bool is_atombios;
|
||||||
|
|
||||||
tv_chip_type tv_chip; // type of TV-Out encoder
|
tv_chip_type tv_chip; // type of TV-Out encoder
|
||||||
bool new_pll; // r300 style PLL
|
bool new_pll; // r300 style PLL
|
||||||
bool has_no_i2c; // I2C is broken
|
bool has_no_i2c; // I2C is broken
|
||||||
uint16 panel_pwr_delay;// delay for LCD backlight to stabilise
|
uint16 panel_pwr_delay; // delay for LCD backlight to stabilise
|
||||||
uint8 theatre_channel;// VIP channel of Rage Theatre (if applicable)
|
uint8 theatre_channel; // VIP channel of Rage Theatre (if applicable)
|
||||||
|
|
||||||
general_pll_info pll;
|
general_pll_info pll;
|
||||||
|
tmds_pll_info tmds_pll[4];
|
||||||
|
|
||||||
area_id regs_area; // area of memory mapped registers
|
area_id regs_area; // area of memory mapped registers
|
||||||
area_id ROM_area; // area of ROM
|
area_id ROM_area; // area of ROM
|
||||||
//area_id fb_area; // area of frame buffer
|
|
||||||
void *framebuffer_pci; // physical address of frame buffer (aka local memory)
|
void *framebuffer_pci; // physical address of frame buffer (aka local memory)
|
||||||
// this is a hack needed by BeOS
|
// this is a hack needed by BeOS
|
||||||
|
|
||||||
@@ -557,6 +562,8 @@ typedef struct {
|
|||||||
uint32 active_vc; // currently selected virtual card in terms of 2D acceleration
|
uint32 active_vc; // currently selected virtual card in terms of 2D acceleration
|
||||||
|
|
||||||
uint32 dac_cntl2; // content of dac_cntl2 register
|
uint32 dac_cntl2; // content of dac_cntl2 register
|
||||||
|
uint32 tmds_pll_cntl; // undocumented here be dragons
|
||||||
|
uint32 tmds_transmitter_cntl; // undocumented here be dragons
|
||||||
|
|
||||||
overlay_info pending_overlay; // overlay to be shown
|
overlay_info pending_overlay; // overlay to be shown
|
||||||
overlay_info active_overlay; // overlay shown
|
overlay_info active_overlay; // overlay shown
|
||||||
|
|||||||
@@ -148,6 +148,10 @@ Radeon_ProposeDisplayMode(shared_info *si, crtc_info *crtc,
|
|||||||
int eff_virtual_width;
|
int eff_virtual_width;
|
||||||
fp_info *flatpanel = &si->flatpanels[crtc->flatpanel_port];
|
fp_info *flatpanel = &si->flatpanels[crtc->flatpanel_port];
|
||||||
|
|
||||||
|
SHOW_FLOW( 4, "CRTC %d, DVI %d", (crtc == &si->crtc[0]) ? 0 : 1, crtc->flatpanel_port );
|
||||||
|
SHOW_FLOW( 4, "X %d, virtX %d", target->timing.h_display, target->virtual_width);
|
||||||
|
SHOW_FLOW( 4, "fpRes %dx%d", flatpanel->panel_xres, flatpanel->panel_yres);
|
||||||
|
|
||||||
// save refresh rate - we want to leave this (artifical) value untouched
|
// save refresh rate - we want to leave this (artifical) value untouched
|
||||||
// don't use floating point, we are in kernel mode
|
// don't use floating point, we are in kernel mode
|
||||||
target_refresh =
|
target_refresh =
|
||||||
@@ -163,7 +167,7 @@ Radeon_ProposeDisplayMode(shared_info *si, crtc_info *crtc,
|
|||||||
// for flat panels, check maximum resolution;
|
// for flat panels, check maximum resolution;
|
||||||
// all the other tricks (like fixed resolution and resulting scaling)
|
// all the other tricks (like fixed resolution and resulting scaling)
|
||||||
// are done automagically by set_display_mode
|
// are done automagically by set_display_mode
|
||||||
if( (crtc->chosen_displays & (dd_lvds | dd_dvi | dd_dvi_ext)) != 0 ) {
|
if( (crtc->chosen_displays & (dd_lvds | dd_dvi)) != 0 ) {
|
||||||
if( target->timing.h_display > flatpanel->panel_xres )
|
if( target->timing.h_display > flatpanel->panel_xres )
|
||||||
target->timing.h_display = flatpanel->panel_xres;
|
target->timing.h_display = flatpanel->panel_xres;
|
||||||
|
|
||||||
@@ -171,6 +175,17 @@ Radeon_ProposeDisplayMode(shared_info *si, crtc_info *crtc,
|
|||||||
target->timing.v_display = flatpanel->panel_yres;
|
target->timing.v_display = flatpanel->panel_yres;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// for secondary flat panels there is no RMX unit for
|
||||||
|
// scaling up lower resolutions. Until we can do centered timings
|
||||||
|
// we need to disable the screen unless it is the native resolution.
|
||||||
|
// if the DVI input has a scaler we would need to know about it somehow...
|
||||||
|
if( (crtc->chosen_displays & dd_dvi_ext) != 0 ) {
|
||||||
|
SHOW_FLOW0( 4, "external (secondary) DVI cannot support non-native resolutions" );
|
||||||
|
if( ( target->timing.h_display != flatpanel->panel_xres ) ||
|
||||||
|
( target->timing.v_display != flatpanel->panel_yres ) )
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// the TV-Out encoder can "only" handle up to 1024x768
|
// the TV-Out encoder can "only" handle up to 1024x768
|
||||||
if( (head->chosen_displays & (dd_ctv | dd_stv)) != 0 ) {
|
if( (head->chosen_displays & (dd_ctv | dd_stv)) != 0 ) {
|
||||||
@@ -325,7 +340,7 @@ Radeon_ProposeDisplayMode(shared_info *si, crtc_info *crtc,
|
|||||||
if( target->timing.pixel_clock / 10 > pll->max_pll_freq ||
|
if( target->timing.pixel_clock / 10 > pll->max_pll_freq ||
|
||||||
target->timing.pixel_clock / 10 * 12 < pll->min_pll_freq )
|
target->timing.pixel_clock / 10 * 12 < pll->min_pll_freq )
|
||||||
{
|
{
|
||||||
SHOW_ERROR( 2, "pixel_clock (%ld) out of range (%d, %d)", target->timing.pixel_clock,
|
SHOW_ERROR( 4, "pixel_clock (%ld) out of range (%d, %d)", target->timing.pixel_clock,
|
||||||
pll->max_pll_freq * 10, pll->min_pll_freq / 12 );
|
pll->max_pll_freq * 10, pll->min_pll_freq / 12 );
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
@@ -371,7 +386,7 @@ Radeon_ProposeDisplayMode(shared_info *si, crtc_info *crtc,
|
|||||||
|
|
||||||
// make sure we haven't shrunk virtual height too much
|
// make sure we haven't shrunk virtual height too much
|
||||||
if (target->virtual_height < target->timing.v_display) {
|
if (target->virtual_height < target->timing.v_display) {
|
||||||
SHOW_ERROR( 2, "not enough memory for this mode (could show only %d of %d lines)",
|
SHOW_ERROR( 4, "not enough memory for this mode (could show only %d of %d lines)",
|
||||||
target->virtual_height, target->timing.v_display );
|
target->virtual_height, target->timing.v_display );
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
@@ -516,11 +531,11 @@ static void addFPMode( accelerator_info *ai )
|
|||||||
{
|
{
|
||||||
shared_info *si = ai->si;
|
shared_info *si = ai->si;
|
||||||
|
|
||||||
fp_info *fp_info = &si->flatpanels[0];
|
fp_info *fp_info = &si->flatpanels[0]; //todo fix the hardcoding what about ext dvi?
|
||||||
|
|
||||||
if( (ai->vc->connected_displays & (dd_dvi | dd_lvds)) != 0 ) {
|
if( (ai->vc->connected_displays & (dd_dvi | dd_dvi_ext | dd_lvds)) != 0 ) {
|
||||||
display_mode mode;
|
display_mode mode;
|
||||||
|
SHOW_FLOW0( 2, "" );
|
||||||
mode.virtual_width = mode.timing.h_display = fp_info->panel_xres;
|
mode.virtual_width = mode.timing.h_display = fp_info->panel_xres;
|
||||||
mode.virtual_height = mode.timing.v_display = fp_info->panel_yres;
|
mode.virtual_height = mode.timing.v_display = fp_info->panel_yres;
|
||||||
|
|
||||||
@@ -631,14 +646,14 @@ PROPOSE_DISPLAY_MODE(display_mode *target, const display_mode *low,
|
|||||||
Radeon_DetectMultiMode( vc, target );
|
Radeon_DetectMultiMode( vc, target );
|
||||||
Radeon_VerifyMultiMode( vc, si, target );
|
Radeon_VerifyMultiMode( vc, si, target );
|
||||||
|
|
||||||
SHOW_FLOW0( 3, "wished:" );
|
SHOW_FLOW0( 2, "wished:" );
|
||||||
SHOW_FLOW( 3, "H: %4d %4d %4d %4d (v=%4d)",
|
SHOW_FLOW( 2, "H: %4d %4d %4d %4d (v=%4d)",
|
||||||
target->timing.h_display, target->timing.h_sync_start,
|
target->timing.h_display, target->timing.h_sync_start,
|
||||||
target->timing.h_sync_end, target->timing.h_total, target->virtual_width );
|
target->timing.h_sync_end, target->timing.h_total, target->virtual_width );
|
||||||
SHOW_FLOW( 3, "V: %4d %4d %4d %4d (h=%4d)",
|
SHOW_FLOW( 2, "V: %4d %4d %4d %4d (h=%4d)",
|
||||||
target->timing.v_display, target->timing.v_sync_start,
|
target->timing.v_display, target->timing.v_sync_start,
|
||||||
target->timing.v_sync_end, target->timing.v_total, target->virtual_height );
|
target->timing.v_sync_end, target->timing.v_total, target->virtual_height );
|
||||||
SHOW_FLOW( 3, "clk: %ld", target->timing.pixel_clock );
|
SHOW_FLOW( 2, "clk: %ld", target->timing.pixel_clock );
|
||||||
|
|
||||||
// we must assure that each ProposeMode call doesn't tweak the mode in
|
// we must assure that each ProposeMode call doesn't tweak the mode in
|
||||||
// a way that it cannot be handled by the other port anymore
|
// a way that it cannot be handled by the other port anymore
|
||||||
@@ -659,14 +674,14 @@ PROPOSE_DISPLAY_MODE(display_mode *target, const display_mode *low,
|
|||||||
result2 = B_OK;
|
result2 = B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
SHOW_INFO0( 4, "got:" );
|
SHOW_INFO0( 2, "got:" );
|
||||||
SHOW_INFO( 4, "H: %4d %4d %4d %4d (v=%4d)",
|
SHOW_INFO( 2, "H: %4d %4d %4d %4d (v=%4d)",
|
||||||
target->timing.h_display, target->timing.h_sync_start,
|
target->timing.h_display, target->timing.h_sync_start,
|
||||||
target->timing.h_sync_end, target->timing.h_total, target->virtual_width );
|
target->timing.h_sync_end, target->timing.h_total, target->virtual_width );
|
||||||
SHOW_INFO( 4, "V: %4d %4d %4d %4d (h=%4d)",
|
SHOW_INFO( 2, "V: %4d %4d %4d %4d (h=%4d)",
|
||||||
target->timing.v_display, target->timing.v_sync_start,
|
target->timing.v_display, target->timing.v_sync_start,
|
||||||
target->timing.v_sync_end, target->timing.v_total, target->virtual_height );
|
target->timing.v_sync_end, target->timing.v_total, target->virtual_height );
|
||||||
SHOW_INFO( 4, "clk: %ld", target->timing.pixel_clock );
|
SHOW_INFO( 2, "clk: %ld", target->timing.pixel_clock );
|
||||||
|
|
||||||
Radeon_HideMultiMode( vc, target );
|
Radeon_HideMultiMode( vc, target );
|
||||||
|
|
||||||
|
|||||||
@@ -23,11 +23,20 @@
|
|||||||
#include "fp_regs.h"
|
#include "fp_regs.h"
|
||||||
#include "gpiopad_regs.h"
|
#include "gpiopad_regs.h"
|
||||||
|
|
||||||
|
#include "pll_regs.h"
|
||||||
|
#include "tv_out_regs.h"
|
||||||
|
#include "config_regs.h"
|
||||||
|
#include "ddc_regs.h"
|
||||||
|
#include "pll_access.h"
|
||||||
|
#include "theatre_regs.h"
|
||||||
|
#include "set_mode.h"
|
||||||
|
#include "ddc.h"
|
||||||
|
|
||||||
#include "set_mode.h"
|
#include "set_mode.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
void Radeon_SetMode(
|
status_t Radeon_SetMode(
|
||||||
accelerator_info *ai, crtc_info *crtc, display_mode *mode, impactv_params *tv_params );
|
accelerator_info *ai, crtc_info *crtc, display_mode *mode, impactv_params *tv_params );
|
||||||
|
|
||||||
// round virtual width up to next valid size
|
// round virtual width up to next valid size
|
||||||
@@ -94,7 +103,7 @@ static void Radeon_InitCommonRegs(
|
|||||||
|
|
||||||
// set display mode of one head;
|
// set display mode of one head;
|
||||||
// port restrictions, like fixed-sync TFTs connected to it, are taken care of
|
// port restrictions, like fixed-sync TFTs connected to it, are taken care of
|
||||||
void Radeon_SetMode(
|
status_t Radeon_SetMode(
|
||||||
accelerator_info *ai, crtc_info *crtc, display_mode *mode, impactv_params *tv_params )
|
accelerator_info *ai, crtc_info *crtc, display_mode *mode, impactv_params *tv_params )
|
||||||
{
|
{
|
||||||
virtual_card *vc = ai->vc;
|
virtual_card *vc = ai->vc;
|
||||||
@@ -126,11 +135,26 @@ void Radeon_SetMode(
|
|||||||
// is determined by the physical resolution;
|
// is determined by the physical resolution;
|
||||||
// also, all timing is fixed
|
// also, all timing is fixed
|
||||||
if( (disp_devices & (dd_lvds | dd_dvi | dd_dvi_ext)) != 0 ) {
|
if( (disp_devices & (dd_lvds | dd_dvi | dd_dvi_ext)) != 0 ) {
|
||||||
|
SHOW_FLOW0( 0, "requested resolution higher than native panel" );
|
||||||
if( mode->timing.h_display > fp_info->panel_xres )
|
if( mode->timing.h_display > fp_info->panel_xres )
|
||||||
mode->timing.h_display = fp_info->panel_xres;
|
mode->timing.h_display = fp_info->panel_xres;
|
||||||
if( mode->timing.v_display > fp_info->panel_yres )
|
if( mode->timing.v_display > fp_info->panel_yres )
|
||||||
mode->timing.v_display = fp_info->panel_yres;
|
mode->timing.v_display = fp_info->panel_yres;
|
||||||
|
|
||||||
|
if( (disp_devices & dd_dvi_ext) != 0 ) {
|
||||||
|
SHOW_FLOW0( 0, "requested resolution less than second native panel" );
|
||||||
|
if( mode->timing.h_display < fp_info->panel_xres )
|
||||||
|
mode->timing.h_display = fp_info->panel_xres;
|
||||||
|
if( mode->timing.v_display < fp_info->panel_yres )
|
||||||
|
mode->timing.v_display = fp_info->panel_yres;
|
||||||
|
|
||||||
|
//TODO at this point we know we are going to do centered timing
|
||||||
|
//need to set flags to a. blank the unused memory, b.center screen
|
||||||
|
//for now it's in the top corner, and surrounded by garbage.
|
||||||
|
// although if the DVI panels are the same size and we are cloning
|
||||||
|
// we can switch the FP2 source to RMX, and drive both screens from
|
||||||
|
// the RMX unit.
|
||||||
|
}
|
||||||
mode->timing.h_total = mode->timing.h_display + fp_info->h_blank;
|
mode->timing.h_total = mode->timing.h_display + fp_info->h_blank;
|
||||||
mode->timing.h_sync_start = mode->timing.h_display + fp_info->h_over_plus;
|
mode->timing.h_sync_start = mode->timing.h_display + fp_info->h_over_plus;
|
||||||
mode->timing.h_sync_end = mode->timing.h_sync_start + fp_info->h_sync_width;
|
mode->timing.h_sync_end = mode->timing.h_sync_start + fp_info->h_sync_width;
|
||||||
@@ -254,6 +278,28 @@ void Radeon_SetMode(
|
|||||||
Radeon_TheatreProgramTVRegisters( ai, &impactv_values );
|
Radeon_TheatreProgramTVRegisters( ai, &impactv_values );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// spit out some debug stuff in a radeontool stylee
|
||||||
|
SHOW_FLOW0( 0, "" );
|
||||||
|
SHOW_FLOW( 0, "RADEON_DAC_CNTL %08X ", INREG( regs, RADEON_DAC_CNTL ));
|
||||||
|
SHOW_FLOW( 0, "RADEON_DAC_CNTL2 %08X ", INREG( regs, RADEON_DAC_CNTL2 ));
|
||||||
|
SHOW_FLOW( 0, "RADEON_TV_DAC_CNTL %08X ", INREG( regs, RADEON_TV_DAC_CNTL ));
|
||||||
|
SHOW_FLOW( 0, "RADEON_DISP_OUTPUT_CNTL %08X ", INREG( regs, RADEON_DISP_OUTPUT_CNTL ));
|
||||||
|
SHOW_FLOW( 0, "RADEON_AUX_SC_CNTL %08X ", INREG( regs, RADEON_AUX_SC_CNTL ));
|
||||||
|
SHOW_FLOW( 0, "RADEON_CRTC_EXT_CNTL %08X ", INREG( regs, RADEON_CRTC_EXT_CNTL ));
|
||||||
|
SHOW_FLOW( 0, "RADEON_CRTC_GEN_CNTL %08X ", INREG( regs, RADEON_CRTC_GEN_CNTL ));
|
||||||
|
SHOW_FLOW( 0, "RADEON_CRTC2_GEN_CNTL %08X ", INREG( regs, RADEON_CRTC2_GEN_CNTL ));
|
||||||
|
SHOW_FLOW( 0, "RADEON_DISP_MISC_CNTL %08X ", INREG( regs, RADEON_DISP_MISC_CNTL ));
|
||||||
|
SHOW_FLOW( 0, "RADEON_FP_GEN_CNTL %08X ", INREG( regs, RADEON_FP_GEN_CNTL ));
|
||||||
|
SHOW_FLOW( 0, "RADEON_FP2_GEN_CNTL %08X ", INREG( regs, RADEON_FP2_GEN_CNTL ));
|
||||||
|
SHOW_FLOW( 0, "RADEON_LVDS_GEN_CNTL %08X ", INREG( regs, RADEON_LVDS_GEN_CNTL ));
|
||||||
|
SHOW_FLOW( 0, "RADEON_TMDS_PLL_CNTL %08X ", INREG( regs, RADEON_TMDS_PLL_CNTL ));
|
||||||
|
SHOW_FLOW( 0, "RADEON_TMDS_TRANSMITTER_CNTL %08X ", INREG( regs, RADEON_TMDS_TRANSMITTER_CNTL ));
|
||||||
|
SHOW_FLOW( 0, "RADEON_FP_H_SYNC_STRT_WID %08X ", INREG( regs, RADEON_FP_H_SYNC_STRT_WID ));
|
||||||
|
SHOW_FLOW( 0, "RADEON_FP_V_SYNC_STRT_WID %08X ", INREG( regs, RADEON_FP_V_SYNC_STRT_WID ));
|
||||||
|
SHOW_FLOW( 0, "RADEON_FP_H2_SYNC_STRT_WID %08X ", INREG( regs, RADEON_FP_H2_SYNC_STRT_WID ));
|
||||||
|
SHOW_FLOW( 0, "RADEON_FP_V2_SYNC_STRT_WID %08X ", INREG( regs, RADEON_FP_V2_SYNC_STRT_WID ));
|
||||||
|
// spit end
|
||||||
|
|
||||||
crtc->active_displays = disp_devices;
|
crtc->active_displays = disp_devices;
|
||||||
|
|
||||||
// programming is over, so hardware can be used again
|
// programming is over, so hardware can be used again
|
||||||
@@ -263,6 +309,8 @@ void Radeon_SetMode(
|
|||||||
// TBD: this won't work if another virtual card was using it,
|
// TBD: this won't work if another virtual card was using it,
|
||||||
// but currently, virtual cards don't work anyway...
|
// but currently, virtual cards don't work anyway...
|
||||||
si->active_overlay.crtc_idx = -1;
|
si->active_overlay.crtc_idx = -1;
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -432,6 +480,8 @@ status_t SET_DISPLAY_MODE(
|
|||||||
{
|
{
|
||||||
routing_regs routing_values;
|
routing_regs routing_values;
|
||||||
impactv_params tv_params;
|
impactv_params tv_params;
|
||||||
|
status_t err1 , err2;
|
||||||
|
err1 = err2 = B_OK;
|
||||||
|
|
||||||
// we first switch off all output, so the monitor(s) won't get invalid signals
|
// we first switch off all output, so the monitor(s) won't get invalid signals
|
||||||
if( vc->assigned_crtc[0] ) {
|
if( vc->assigned_crtc[0] ) {
|
||||||
@@ -451,9 +501,13 @@ status_t SET_DISPLAY_MODE(
|
|||||||
|
|
||||||
// then change the mode
|
// then change the mode
|
||||||
if( vc->used_crtc[0] )
|
if( vc->used_crtc[0] )
|
||||||
Radeon_SetMode( ai, &si->crtc[0], &mode, &tv_params );
|
err1 = Radeon_SetMode( ai, &si->crtc[0], &mode, &tv_params );
|
||||||
if( vc->used_crtc[1] )
|
if( vc->used_crtc[1] )
|
||||||
Radeon_SetMode( ai, &si->crtc[1], &mode, &tv_params );
|
err2 = Radeon_SetMode( ai, &si->crtc[1], &mode, &tv_params );
|
||||||
|
|
||||||
|
|
||||||
|
SHOW_FLOW( 2, "SetModes 1=%s, 2=%s",
|
||||||
|
(err1 == B_OK) ? "OK" : "FAIL", (err2 == B_OK) ? "OK" : "FAIL");
|
||||||
|
|
||||||
// setup signal routing
|
// setup signal routing
|
||||||
Radeon_ReadMonitorRoutingRegs( ai, &routing_values );
|
Radeon_ReadMonitorRoutingRegs( ai, &routing_values );
|
||||||
@@ -462,9 +516,9 @@ status_t SET_DISPLAY_MODE(
|
|||||||
|
|
||||||
// finally, switch display(s) on
|
// finally, switch display(s) on
|
||||||
if( vc->used_crtc[0] )
|
if( vc->used_crtc[0] )
|
||||||
Radeon_SetDPMS( ai, 0, B_DPMS_ON );
|
Radeon_SetDPMS( ai, 0, (err1 == B_OK) ? B_DPMS_ON : B_DPMS_SUSPEND );
|
||||||
if( vc->used_crtc[1] )
|
if( vc->used_crtc[1] )
|
||||||
Radeon_SetDPMS( ai, 1, B_DPMS_ON );
|
Radeon_SetDPMS( ai, 1, (err2 == B_OK) ? B_DPMS_ON : B_DPMS_SUSPEND );
|
||||||
|
|
||||||
OUTREGP( ai->regs, RADEON_CRTC_EXT_CNTL, 0, ~RADEON_CRTC_DISPLAY_DIS );
|
OUTREGP( ai->regs, RADEON_CRTC_EXT_CNTL, 0, ~RADEON_CRTC_DISPLAY_DIS );
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ void Radeon_ProgramRMXRegisters(
|
|||||||
accelerator_info *ai, fp_regs *values )
|
accelerator_info *ai, fp_regs *values )
|
||||||
{
|
{
|
||||||
vuint8 *regs = ai->regs;
|
vuint8 *regs = ai->regs;
|
||||||
|
SHOW_FLOW0( 2, "" );
|
||||||
OUTREG( regs, RADEON_FP_HORZ_STRETCH, values->fp_horz_stretch );
|
OUTREG( regs, RADEON_FP_HORZ_STRETCH, values->fp_horz_stretch );
|
||||||
OUTREG( regs, RADEON_FP_VERT_STRETCH, values->fp_vert_stretch );
|
OUTREG( regs, RADEON_FP_VERT_STRETCH, values->fp_vert_stretch );
|
||||||
}
|
}
|
||||||
@@ -122,6 +122,8 @@ void Radeon_ReadFPRegisters(
|
|||||||
values->fp_gen_cntl = INREG( regs, RADEON_FP_GEN_CNTL );
|
values->fp_gen_cntl = INREG( regs, RADEON_FP_GEN_CNTL );
|
||||||
values->fp2_gen_cntl = INREG( regs, RADEON_FP2_GEN_CNTL );
|
values->fp2_gen_cntl = INREG( regs, RADEON_FP2_GEN_CNTL );
|
||||||
values->lvds_gen_cntl = INREG( regs, RADEON_LVDS_GEN_CNTL );
|
values->lvds_gen_cntl = INREG( regs, RADEON_LVDS_GEN_CNTL );
|
||||||
|
values->tmds_pll_cntl = INREG( regs, RADEON_TMDS_PLL_CNTL );
|
||||||
|
values->tmds_trans_cntl = INREG( regs, RADEON_TMDS_TRANSMITTER_CNTL );
|
||||||
values->fp_h_sync_strt_wid = INREG( regs, RADEON_FP_H_SYNC_STRT_WID );
|
values->fp_h_sync_strt_wid = INREG( regs, RADEON_FP_H_SYNC_STRT_WID );
|
||||||
values->fp_v_sync_strt_wid = INREG( regs, RADEON_FP_V_SYNC_STRT_WID );
|
values->fp_v_sync_strt_wid = INREG( regs, RADEON_FP_V_SYNC_STRT_WID );
|
||||||
values->fp2_h_sync_strt_wid = INREG( regs, RADEON_FP_H2_SYNC_STRT_WID );
|
values->fp2_h_sync_strt_wid = INREG( regs, RADEON_FP_H2_SYNC_STRT_WID );
|
||||||
@@ -130,6 +132,11 @@ void Radeon_ReadFPRegisters(
|
|||||||
values->bios_5_scratch = INREG( regs, RADEON_BIOS_5_SCRATCH );
|
values->bios_5_scratch = INREG( regs, RADEON_BIOS_5_SCRATCH );
|
||||||
values->bios_6_scratch = INREG( regs, RADEON_BIOS_6_SCRATCH );
|
values->bios_6_scratch = INREG( regs, RADEON_BIOS_6_SCRATCH );
|
||||||
|
|
||||||
|
if (ai->si->asic == rt_rv280) {
|
||||||
|
// bit 22 of TMDS_PLL_CNTL is read-back inverted
|
||||||
|
values->tmds_pll_cntl ^= (1 << 22);
|
||||||
|
}
|
||||||
|
|
||||||
SHOW_FLOW( 2, "before: fp_gen_cntl=%08lx, horz=%08lx, vert=%08lx, lvds_gen_cntl=%08lx",
|
SHOW_FLOW( 2, "before: fp_gen_cntl=%08lx, horz=%08lx, vert=%08lx, lvds_gen_cntl=%08lx",
|
||||||
values->fp_gen_cntl, values->fp_horz_stretch, values->fp_vert_stretch,
|
values->fp_gen_cntl, values->fp_horz_stretch, values->fp_vert_stretch,
|
||||||
values->lvds_gen_cntl );
|
values->lvds_gen_cntl );
|
||||||
@@ -141,20 +148,27 @@ void Radeon_CalcFPRegisters(
|
|||||||
accelerator_info *ai, crtc_info *crtc,
|
accelerator_info *ai, crtc_info *crtc,
|
||||||
fp_info *fp_port, crtc_regs *crtc_values, fp_regs *values )
|
fp_info *fp_port, crtc_regs *crtc_values, fp_regs *values )
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
|
uint32 tmp = values->tmds_pll_cntl & 0xfffff;
|
||||||
|
|
||||||
// setup synchronization position
|
// setup synchronization position
|
||||||
// (most values are ignored according to fp_gen_cntl, but at least polarity
|
// (most values are ignored according to fp_gen_cntl, but at least polarity
|
||||||
// and pixel precise horizontal sync position are always used)
|
// and pixel precise horizontal sync position are always used)
|
||||||
if( fp_port->is_fp2 ) {
|
if( fp_port->is_fp2 ) {
|
||||||
|
SHOW_FLOW0( 2, "is_fp2" );
|
||||||
values->fp2_h_sync_strt_wid = crtc_values->crtc_h_sync_strt_wid;
|
values->fp2_h_sync_strt_wid = crtc_values->crtc_h_sync_strt_wid;
|
||||||
values->fp2_v_sync_strt_wid = crtc_values->crtc_v_sync_strt_wid;
|
values->fp2_v_sync_strt_wid = crtc_values->crtc_v_sync_strt_wid;
|
||||||
} else {
|
} else {
|
||||||
|
SHOW_FLOW0( 2, "fp1" );
|
||||||
values->fp_h_sync_strt_wid = crtc_values->crtc_h_sync_strt_wid;
|
values->fp_h_sync_strt_wid = crtc_values->crtc_h_sync_strt_wid;
|
||||||
values->fp_v_sync_strt_wid = crtc_values->crtc_v_sync_strt_wid;
|
values->fp_v_sync_strt_wid = crtc_values->crtc_v_sync_strt_wid;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( fp_port->is_fp2 )
|
if( fp_port->is_fp2 ) {
|
||||||
values->fp2_gen_cntl = 0;
|
// should retain POST values (esp bit 28)
|
||||||
else {
|
values->fp2_gen_cntl &= (0xFFFF0000);
|
||||||
|
|
||||||
|
} else {
|
||||||
// setup magic CRTC shadowing
|
// setup magic CRTC shadowing
|
||||||
values->fp_gen_cntl &=
|
values->fp_gen_cntl &=
|
||||||
~(RADEON_FP_RMX_HVSYNC_CONTROL_EN |
|
~(RADEON_FP_RMX_HVSYNC_CONTROL_EN |
|
||||||
@@ -169,29 +183,64 @@ void Radeon_CalcFPRegisters(
|
|||||||
RADEON_FP_CRTC_DONT_SHADOW_HEND;
|
RADEON_FP_CRTC_DONT_SHADOW_HEND;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < 4; i++) {
|
||||||
|
if (ai->si->tmds_pll[i].freq == 0)
|
||||||
|
break;
|
||||||
|
if ((uint32)(fp_port->dot_clock) < ai->si->tmds_pll[i].freq) {
|
||||||
|
tmp = ai->si->tmds_pll[i].value ;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IS_R300_VARIANT || (ai->si->asic == rt_rv280)) {
|
||||||
|
if (tmp & 0xfff00000) {
|
||||||
|
values->tmds_pll_cntl = tmp;
|
||||||
|
} else {
|
||||||
|
values->tmds_pll_cntl = ai->si->tmds_pll_cntl & 0xfff00000;
|
||||||
|
values->tmds_pll_cntl |= tmp;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
values->tmds_pll_cntl = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
values->tmds_trans_cntl = ai->si->tmds_transmitter_cntl
|
||||||
|
& ~(RADEON_TMDS_TRANSMITTER_PLLRST);
|
||||||
|
|
||||||
|
if (IS_R300_VARIANT || (ai->si->asic == rt_r200) || (ai->si->num_crtc == 1))
|
||||||
|
values->tmds_trans_cntl &= ~(RADEON_TMDS_TRANSMITTER_PLLEN);
|
||||||
|
else // weird, RV chips got this bit reversed?
|
||||||
|
values->tmds_trans_cntl |= (RADEON_TMDS_TRANSMITTER_PLLEN);
|
||||||
|
|
||||||
|
|
||||||
// enable proper transmitter
|
// enable proper transmitter
|
||||||
if( (crtc->chosen_displays & dd_lvds) != 0 ) {
|
if( (crtc->chosen_displays & dd_lvds) != 0 ) {
|
||||||
// using LVDS means there cannot be a DVI monitor
|
// using LVDS means there cannot be a DVI monitor
|
||||||
|
SHOW_FLOW0( 2, "lvds" );
|
||||||
values->lvds_gen_cntl |= (RADEON_LVDS_ON | RADEON_LVDS_BLON);
|
values->lvds_gen_cntl |= (RADEON_LVDS_ON | RADEON_LVDS_BLON);
|
||||||
values->fp_gen_cntl &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN);
|
values->fp_gen_cntl &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN);
|
||||||
|
|
||||||
} else if( !fp_port->is_fp2 ) {
|
} else if( !fp_port->is_fp2 ) {
|
||||||
// DVI on internal transmitter
|
// DVI on internal transmitter
|
||||||
|
SHOW_FLOW0( 2, "DVI INT" );
|
||||||
values->fp_gen_cntl |= RADEON_FP_FPON | RADEON_FP_TMDS_EN;
|
values->fp_gen_cntl |= RADEON_FP_FPON | RADEON_FP_TMDS_EN;
|
||||||
// enabling 8 bit data may be dangerous; BIOS should have taken care of that
|
// enabling 8 bit data may be dangerous; BIOS should have taken care of that
|
||||||
values->fp_gen_cntl |= RADEON_FP_PANEL_FORMAT;
|
values->fp_gen_cntl |= RADEON_FP_PANEL_FORMAT;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// DVI on external transmitter
|
// DVI on external transmitter
|
||||||
|
SHOW_FLOW0( 2, "DVI EXT" );
|
||||||
values->fp2_gen_cntl |= RADEON_FP2_FPON | RADEON_FP_PANEL_FORMAT;
|
values->fp2_gen_cntl |= RADEON_FP2_FPON | RADEON_FP_PANEL_FORMAT;
|
||||||
values->fp2_gen_cntl &= ~RADEON_FP2_BLANK_EN;
|
values->fp2_gen_cntl &= ~RADEON_FP2_BLANK_EN;
|
||||||
|
|
||||||
|
//hack in missing bits test...
|
||||||
|
//values->fp2_gen_cntl |= (1 << 22) | (1 << 28);
|
||||||
|
|
||||||
if( ai->si->asic >= rt_r200 )
|
if( ai->si->asic >= rt_r200 )
|
||||||
values->fp2_gen_cntl |= RADEON_FP2_DV0_EN;
|
values->fp2_gen_cntl |= RADEON_FP2_DV0_EN;
|
||||||
}
|
}
|
||||||
|
|
||||||
SHOW_FLOW( 2, "after: fp_gen_cntl=%08lx, horz=%08lx, vert=%08lx, lvds_gen_cntl=%08lx",
|
SHOW_FLOW( 2, "after: fp_gen_cntl=%08lx, fp2_gen_cntl=%08lx, horz=%08lx, vert=%08lx, lvds_gen_cntl=%08lx",
|
||||||
values->fp_gen_cntl, values->fp_horz_stretch, values->fp_vert_stretch,
|
values->fp_gen_cntl, values->fp2_gen_cntl, values->fp_horz_stretch, values->fp_vert_stretch,
|
||||||
values->lvds_gen_cntl );
|
values->lvds_gen_cntl );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -209,11 +258,15 @@ void Radeon_ProgramFPRegisters(
|
|||||||
OUTREGP( regs, RADEON_FP_GEN_CNTL, values->fp_gen_cntl, RADEON_FP_SEL_CRTC2 );
|
OUTREGP( regs, RADEON_FP_GEN_CNTL, values->fp_gen_cntl, RADEON_FP_SEL_CRTC2 );
|
||||||
|
|
||||||
if( fp_port->is_fp2 ) {
|
if( fp_port->is_fp2 ) {
|
||||||
|
SHOW_FLOW0( 2, "is_fp2" );
|
||||||
|
OUTREGP( regs, RADEON_FP2_GEN_CNTL, values->fp2_gen_cntl,
|
||||||
|
~(RADEON_FP2_SOURCE_SEL_MASK | RADEON_FP2_SRC_SEL_MASK));
|
||||||
OUTREGP( regs, RADEON_FP2_GEN_CNTL, values->fp2_gen_cntl,
|
OUTREGP( regs, RADEON_FP2_GEN_CNTL, values->fp2_gen_cntl,
|
||||||
RADEON_FP2_SOURCE_SEL_CRTC2 | RADEON_FP2_SRC_SEL_CRTC2 );
|
RADEON_FP2_SOURCE_SEL_CRTC2 | RADEON_FP2_SRC_SEL_CRTC2 );
|
||||||
OUTREG( regs, RADEON_FP_H2_SYNC_STRT_WID, values->fp2_h_sync_strt_wid );
|
OUTREG( regs, RADEON_FP_H2_SYNC_STRT_WID, values->fp2_h_sync_strt_wid );
|
||||||
OUTREG( regs, RADEON_FP_V2_SYNC_STRT_WID, values->fp2_v_sync_strt_wid );
|
OUTREG( regs, RADEON_FP_V2_SYNC_STRT_WID, values->fp2_v_sync_strt_wid );
|
||||||
} else {
|
} else {
|
||||||
|
SHOW_FLOW0( 2, "is_fp1" );
|
||||||
OUTREG( regs, RADEON_FP_H_SYNC_STRT_WID, values->fp_h_sync_strt_wid );
|
OUTREG( regs, RADEON_FP_H_SYNC_STRT_WID, values->fp_h_sync_strt_wid );
|
||||||
OUTREG( regs, RADEON_FP_V_SYNC_STRT_WID, values->fp_v_sync_strt_wid );
|
OUTREG( regs, RADEON_FP_V_SYNC_STRT_WID, values->fp_v_sync_strt_wid );
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -800,9 +800,9 @@ static void Radeon_FindFPTiming_StandardTiming(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// read edid data of flat panel and setup its timing accordingly
|
// read edid data of flat panel and setup its timing accordingly
|
||||||
static status_t Radeon_StoreFPEDID( accelerator_info *ai, const edid1_info *edid )
|
static status_t Radeon_StoreFPEDID( accelerator_info *ai, int port, const edid1_info *edid )
|
||||||
{
|
{
|
||||||
fp_info *fp = &ai->si->flatpanels[0];
|
fp_info *fp = &ai->si->flatpanels[port];
|
||||||
uint32 max_hsize, max_vsize;
|
uint32 max_hsize, max_vsize;
|
||||||
|
|
||||||
//SHOW_FLOW0( 2, "EDID data read from DVI port via DDC2:" );
|
//SHOW_FLOW0( 2, "EDID data read from DVI port via DDC2:" );
|
||||||
@@ -954,10 +954,12 @@ void Radeon_DetectDisplays( accelerator_info *ai )
|
|||||||
// use DDC to detect monitors - if we can read DDC, there must be a monitor
|
// use DDC to detect monitors - if we can read DDC, there must be a monitor
|
||||||
for ( i = 0; i < 2; i++ )
|
for ( i = 0; i < 2; i++ )
|
||||||
{
|
{
|
||||||
if (routes->port_info[i].mon_type != mt_unknown ) {
|
//TODO could skip edid reading instead if we already have it, but what
|
||||||
SHOW_FLOW0( 2, "known type, skpping detection" );
|
//if monitors have been hot swapped? Also rely on edid for DVI-D detection
|
||||||
continue;
|
//if (routes->port_info[i].mon_type != mt_unknown ) {
|
||||||
}
|
// SHOW_FLOW0( 2, "known type, skpping detection" );
|
||||||
|
// continue;
|
||||||
|
//}
|
||||||
|
|
||||||
memset( &routes->port_info[i].edid , 0, sizeof(edid1_info) );
|
memset( &routes->port_info[i].edid , 0, sizeof(edid1_info) );
|
||||||
switch ( routes->port_info[i].ddc_type ) {
|
switch ( routes->port_info[i].ddc_type ) {
|
||||||
@@ -993,9 +995,10 @@ void Radeon_DetectDisplays( accelerator_info *ai )
|
|||||||
// both LDVS and TMDS are disable, we still need to treat it as a LVDS panel.
|
// both LDVS and TMDS are disable, we still need to treat it as a LVDS panel.
|
||||||
if ( routes->port_info[i].tmds_type == tmds_ext ){
|
if ( routes->port_info[i].tmds_type == tmds_ext ){
|
||||||
// store info about DVI-connected flat-panel
|
// store info about DVI-connected flat-panel
|
||||||
if( Radeon_StoreFPEDID( ai, &routes->port_info[i].edid ) == B_OK ) {
|
if( Radeon_StoreFPEDID( ai, i, &routes->port_info[i].edid ) == B_OK ) {
|
||||||
SHOW_INFO0( 2, "Found Ext Laptop DVI" );
|
SHOW_INFO0( 2, "Found Ext Laptop DVI" );
|
||||||
routes->port_info[i].mon_type = mt_dfp;
|
routes->port_info[i].mon_type = mt_dfp;
|
||||||
|
ai->si->flatpanels[i].is_fp2 = true;
|
||||||
displays |= dd_dvi_ext;
|
displays |= dd_dvi_ext;
|
||||||
} else {
|
} else {
|
||||||
SHOW_ERROR0( 2, "Disabled Ext DVI - invalid EDID" );
|
SHOW_ERROR0( 2, "Disabled Ext DVI - invalid EDID" );
|
||||||
@@ -1003,7 +1006,7 @@ void Radeon_DetectDisplays( accelerator_info *ai )
|
|||||||
} else {
|
} else {
|
||||||
if( INREG( ai->regs, RADEON_FP_GEN_CNTL) & (1 << 7) || ( !si->is_mobility ) ) {
|
if( INREG( ai->regs, RADEON_FP_GEN_CNTL) & (1 << 7) || ( !si->is_mobility ) ) {
|
||||||
// store info about DVI-connected flat-panel
|
// store info about DVI-connected flat-panel
|
||||||
if( Radeon_StoreFPEDID( ai, &routes->port_info[i].edid ) == B_OK ) {
|
if( Radeon_StoreFPEDID( ai, i, &routes->port_info[i].edid ) == B_OK ) {
|
||||||
SHOW_INFO0( 2, "Found DVI" );
|
SHOW_INFO0( 2, "Found DVI" );
|
||||||
routes->port_info[i].mon_type = mt_dfp;
|
routes->port_info[i].mon_type = mt_dfp;
|
||||||
displays |= dd_dvi;
|
displays |= dd_dvi;
|
||||||
@@ -1015,6 +1018,7 @@ void Radeon_DetectDisplays( accelerator_info *ai )
|
|||||||
routes->port_info[i].mon_type = mt_lcd;
|
routes->port_info[i].mon_type = mt_lcd;
|
||||||
displays |= dd_lvds;
|
displays |= dd_lvds;
|
||||||
}
|
}
|
||||||
|
ai->si->flatpanels[1].is_fp2 = FALSE;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// must be the analog portion of DVI
|
// must be the analog portion of DVI
|
||||||
@@ -1049,7 +1053,7 @@ void Radeon_DetectDisplays( accelerator_info *ai )
|
|||||||
if ( si->is_mobility && (INREG( ai->regs, RADEON_FP2_GEN_CNTL) & RADEON_FP2_FPON)) {
|
if ( si->is_mobility && (INREG( ai->regs, RADEON_FP2_GEN_CNTL) & RADEON_FP2_FPON)) {
|
||||||
SHOW_INFO0( 2, "Found Ext Laptop DVI" );
|
SHOW_INFO0( 2, "Found Ext Laptop DVI" );
|
||||||
routes->port_info[1].mon_type = mt_dfp;
|
routes->port_info[1].mon_type = mt_dfp;
|
||||||
displays |= dd_dvi;
|
displays |= dd_dvi_ext;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -635,7 +635,10 @@ static void assignDefaultMonitorRoute(
|
|||||||
crtc2_displays |= dd_tv_crt;
|
crtc2_displays |= dd_tv_crt;
|
||||||
}
|
}
|
||||||
|
|
||||||
SHOW_FLOW( 3, "CRTC1: 0x%x, CRTC2: 0x%x", crtc1_displays, crtc2_displays );
|
if( (display_devices & dd_dvi_ext) != 0 )
|
||||||
|
crtc2_displays |= dd_dvi_ext;
|
||||||
|
|
||||||
|
SHOW_FLOW( 2, "CRTC1: 0x%x, CRTC2: 0x%x", crtc1_displays, crtc2_displays );
|
||||||
|
|
||||||
*crtc1 = crtc1_displays;
|
*crtc1 = crtc1_displays;
|
||||||
*crtc2 = crtc2_displays;
|
*crtc2 = crtc2_displays;
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ extern int debug_level_error;
|
|||||||
|
|
||||||
#define DEBUG_MSG_PREFIX "Radeon - "
|
#define DEBUG_MSG_PREFIX "Radeon - "
|
||||||
|
|
||||||
#define DEBUG_MAX_LEVEL_FLOW 2
|
#define DEBUG_MAX_LEVEL_FLOW 3
|
||||||
|
|
||||||
#include "debug_ext.h"
|
#include "debug_ext.h"
|
||||||
|
|
||||||
|
|||||||
@@ -99,6 +99,8 @@ typedef struct {
|
|||||||
uint32 fp_gen_cntl;
|
uint32 fp_gen_cntl;
|
||||||
uint32 fp_panel_cntl;
|
uint32 fp_panel_cntl;
|
||||||
uint32 lvds_gen_cntl;
|
uint32 lvds_gen_cntl;
|
||||||
|
uint32 tmds_pll_cntl;
|
||||||
|
uint32 tmds_trans_cntl;
|
||||||
uint32 fp_h_sync_strt_wid;
|
uint32 fp_h_sync_strt_wid;
|
||||||
uint32 fp_v_sync_strt_wid;
|
uint32 fp_v_sync_strt_wid;
|
||||||
uint32 fp2_gen_cntl;
|
uint32 fp2_gen_cntl;
|
||||||
|
|||||||
@@ -33,12 +33,31 @@
|
|||||||
#define RADEON_BIOS16(v) ((di->rom.rom_ptr[v]) | \
|
#define RADEON_BIOS16(v) ((di->rom.rom_ptr[v]) | \
|
||||||
(di->rom.rom_ptr[(v) + 1] << 8))
|
(di->rom.rom_ptr[(v) + 1] << 8))
|
||||||
#define RADEON_BIOS32(v) ((di->rom.rom_ptr[v]) | \
|
#define RADEON_BIOS32(v) ((di->rom.rom_ptr[v]) | \
|
||||||
(di->rom.rom_ptr[(v) + 1] << 8) \
|
(di->rom.rom_ptr[(v) + 1] << 8) | \
|
||||||
(di->rom.rom_ptr[(v) + 2] << 16) \
|
(di->rom.rom_ptr[(v) + 2] << 16) | \
|
||||||
(di->rom.rom_ptr[(v) + 3] << 24))
|
(di->rom.rom_ptr[(v) + 3] << 24))
|
||||||
|
|
||||||
static const char ati_rom_sig[] = "761295520";
|
static const char ati_rom_sig[] = "761295520";
|
||||||
|
|
||||||
|
static const tmds_pll_info default_tmds_pll[14][4] =
|
||||||
|
{
|
||||||
|
{{12000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}}, // r100
|
||||||
|
{{12000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}}, // rv100
|
||||||
|
{{0, 0}, {0, 0}, {0, 0}, {0, 0}}, // rs100
|
||||||
|
{{15000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}}, // rv200
|
||||||
|
{{12000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}}, // rs200
|
||||||
|
{{15000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}}, // r200
|
||||||
|
{{15500, 0x81b}, {0xffffffff, 0x83f}, {0, 0}, {0, 0}}, // rv250
|
||||||
|
{{0, 0}, {0, 0}, {0, 0}, {0, 0}}, // rs300
|
||||||
|
{{13000, 0x400f4}, {15000, 0x400f7}, {0xffffffff, 0x40111}, {0, 0}}, // rv280
|
||||||
|
{{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, // r300
|
||||||
|
{{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, // r350
|
||||||
|
{{15000, 0xb0155}, {0xffffffff, 0xb01cb}, {0, 0}, {0, 0}}, // rv350
|
||||||
|
{{15000, 0xb0155}, {0xffffffff, 0xb01cb}, {0, 0}, {0, 0}}, // rv380
|
||||||
|
{{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, // r420
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// find address of ROM;
|
// find address of ROM;
|
||||||
// this code is really nasty as maintaining the radeon signatures
|
// this code is really nasty as maintaining the radeon signatures
|
||||||
// is almost impossible (the signatures provided by ATI are always out-dated);
|
// is almost impossible (the signatures provided by ATI are always out-dated);
|
||||||
@@ -691,6 +710,108 @@ static void Radeon_RevEnvDFPTiming( device_info *di )
|
|||||||
>> RADEON_CRTC_V_SYNC_WID_SHIFT);
|
>> RADEON_CRTC_V_SYNC_WID_SHIFT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//snaffled from X.org hope it works...
|
||||||
|
static void Radeon_GetTMDSInfoFromBios( device_info *di )
|
||||||
|
{
|
||||||
|
uint32 tmp, maxfreq;
|
||||||
|
uint32 found = FALSE;
|
||||||
|
int i, n;
|
||||||
|
uint16 bios_header;
|
||||||
|
|
||||||
|
bios_header = RADEON_BIOS16( 0x48 );
|
||||||
|
|
||||||
|
for (i = 0; i < 4; i++) {
|
||||||
|
di->tmds_pll[i].value = 0;
|
||||||
|
di->tmds_pll[i].freq = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (di->is_atombios)
|
||||||
|
{
|
||||||
|
int master_data_start;
|
||||||
|
master_data_start = RADEON_BIOS16( bios_header + 32 );
|
||||||
|
|
||||||
|
if((tmp = RADEON_BIOS16 (master_data_start + 18))) {
|
||||||
|
|
||||||
|
maxfreq = RADEON_BIOS16(tmp + 4);
|
||||||
|
|
||||||
|
for (i = 0; i < 4; i++) {
|
||||||
|
di->tmds_pll[i].freq = RADEON_BIOS16(tmp + i * 6 + 6);
|
||||||
|
// This assumes each field in TMDS_PLL has 6 bit as in R300/R420
|
||||||
|
di->tmds_pll[i].value = ((RADEON_BIOS8(tmp + i * 6 + 8) & 0x3f) |
|
||||||
|
((RADEON_BIOS8(tmp + i * 6 + 10) & 0x3f) << 6) |
|
||||||
|
((RADEON_BIOS8(tmp + i * 6 + 9) & 0xf) << 12) |
|
||||||
|
((RADEON_BIOS8(tmp + i * 6 + 11) & 0xf) << 16));
|
||||||
|
SHOW_ERROR( 2, "TMDS PLL from BIOS: %ld %lx",
|
||||||
|
di->tmds_pll[i].freq, di->tmds_pll[i].value);
|
||||||
|
|
||||||
|
if (maxfreq == di->tmds_pll[i].freq) {
|
||||||
|
di->tmds_pll[i].freq = 0xffffffff;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
found = TRUE;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
|
||||||
|
tmp = RADEON_BIOS16(bios_header + 0x34);
|
||||||
|
if (tmp) {
|
||||||
|
SHOW_ERROR( 2, "DFP table revision: %d", RADEON_BIOS8(tmp));
|
||||||
|
if (RADEON_BIOS8(tmp) == 3) {
|
||||||
|
n = RADEON_BIOS8(tmp + 5) + 1;
|
||||||
|
if (n > 4)
|
||||||
|
n = 4;
|
||||||
|
for (i = 0; i < n; i++) {
|
||||||
|
di->tmds_pll[i].value = RADEON_BIOS32(tmp + i * 10 + 0x08);
|
||||||
|
di->tmds_pll[i].freq = RADEON_BIOS16(tmp + i * 10 + 0x10);
|
||||||
|
}
|
||||||
|
found = TRUE;
|
||||||
|
} else if (RADEON_BIOS8(tmp) == 4) {
|
||||||
|
int stride = 0;
|
||||||
|
n = RADEON_BIOS8(tmp + 5) + 1;
|
||||||
|
if (n > 4)
|
||||||
|
n = 4;
|
||||||
|
for (i = 0; i < n; i++) {
|
||||||
|
di->tmds_pll[i].value = RADEON_BIOS32(tmp + stride + 0x08);
|
||||||
|
di->tmds_pll[i].freq = RADEON_BIOS16(tmp + stride + 0x10);
|
||||||
|
if (i == 0)
|
||||||
|
stride += 10;
|
||||||
|
else
|
||||||
|
stride += 6;
|
||||||
|
}
|
||||||
|
found = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// revision 4 has some problem as it appears in RV280,
|
||||||
|
// comment it off for now, use default instead
|
||||||
|
/*
|
||||||
|
else if (RADEON_BIOS8(tmp) == 4) {
|
||||||
|
int stride = 0;
|
||||||
|
n = RADEON_BIOS8(tmp + 5) + 1;
|
||||||
|
if (n > 4) n = 4;
|
||||||
|
for (i = 0; i < n; i++) {
|
||||||
|
di->tmds_pll[i].value = RADEON_BIOS32(tmp + stride + 0x08);
|
||||||
|
di->tmds_pll[i].freq = RADEON_BIOS16(tmp + stride + 0x10);
|
||||||
|
if (i == 0)
|
||||||
|
stride += 10;
|
||||||
|
else
|
||||||
|
stride += 6;
|
||||||
|
}
|
||||||
|
found = TRUE;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found == FALSE) {
|
||||||
|
for (i = 0; i < 4; i++) {
|
||||||
|
di->tmds_pll[i].value = default_tmds_pll[di->asic][i].value;
|
||||||
|
di->tmds_pll[i].freq = default_tmds_pll[di->asic][i].freq;
|
||||||
|
SHOW_ERROR( 2, "TMDS PLL from DEFAULTS: %ld %lx",
|
||||||
|
di->tmds_pll[i].freq, di->tmds_pll[i].value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// get everything in terms of monitors connected to the card
|
// get everything in terms of monitors connected to the card
|
||||||
@@ -965,6 +1086,12 @@ status_t Radeon_ReadBIOSData( device_info *di )
|
|||||||
di->routing.port_info[0].tmds_type = tmds_unknown;
|
di->routing.port_info[0].tmds_type = tmds_unknown;
|
||||||
di->routing.port_info[0].connector_type = connector_none;
|
di->routing.port_info[0].connector_type = connector_none;
|
||||||
|
|
||||||
|
di->routing.port_info[1].mon_type = mt_unknown;
|
||||||
|
di->routing.port_info[1].ddc_type = ddc_none_detected;
|
||||||
|
di->routing.port_info[1].dac_type = dac_unknown;
|
||||||
|
di->routing.port_info[1].tmds_type = tmds_unknown;
|
||||||
|
di->routing.port_info[1].connector_type = connector_none;
|
||||||
|
|
||||||
if ( !Radeon_GetConnectorInfoFromBIOS( di ) )
|
if ( !Radeon_GetConnectorInfoFromBIOS( di ) )
|
||||||
{
|
{
|
||||||
di->routing.port_info[0].mon_type = mt_unknown;
|
di->routing.port_info[0].mon_type = mt_unknown;
|
||||||
@@ -981,6 +1108,7 @@ status_t Radeon_ReadBIOSData( device_info *di )
|
|||||||
|
|
||||||
}
|
}
|
||||||
Radeon_GetFPData( di );
|
Radeon_GetFPData( di );
|
||||||
|
Radeon_GetTMDSInfoFromBios( di );
|
||||||
Radeon_DetectRAM( di );
|
Radeon_DetectRAM( di );
|
||||||
|
|
||||||
Radeon_UnmapDevice( di );
|
Radeon_UnmapDevice( di );
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "dac_regs.h"
|
#include "dac_regs.h"
|
||||||
|
#include "tv_out_regs.h"
|
||||||
#include "fp_regs.h"
|
#include "fp_regs.h"
|
||||||
#include "mmio.h"
|
#include "mmio.h"
|
||||||
#include "radeon_driver.h"
|
#include "radeon_driver.h"
|
||||||
@@ -266,19 +267,16 @@ status_t Radeon_FirstOpen( device_info *di )
|
|||||||
// so we let the first accelerant take care of it
|
// so we let the first accelerant take care of it
|
||||||
si->theatre_channel = -1;
|
si->theatre_channel = -1;
|
||||||
|
|
||||||
/* si->ports[0].disp_type = di->disp_type[0];
|
|
||||||
si->ports[1].disp_type = di->disp_type[1];*/
|
|
||||||
si->crtc[0].crtc_idx = 0;
|
si->crtc[0].crtc_idx = 0;
|
||||||
si->crtc[0].flatpanel_port = 0;
|
si->crtc[0].flatpanel_port = 0;
|
||||||
si->crtc[1].crtc_idx = 1;
|
si->crtc[1].crtc_idx = 1;
|
||||||
si->crtc[1].flatpanel_port = 1;
|
si->crtc[1].flatpanel_port = 1;
|
||||||
si->num_crtc = di->num_crtc;
|
si->num_crtc = di->num_crtc;
|
||||||
|
|
||||||
|
if (di->is_mobility)
|
||||||
si->flatpanels[0] = di->fp_info;
|
si->flatpanels[0] = di->fp_info;
|
||||||
|
|
||||||
si->pll = di->pll;
|
si->pll = di->pll;
|
||||||
/* si->ram = di->ram;
|
|
||||||
strcpy( si->ram_type, di->ram_type );*/
|
|
||||||
//si->local_mem_size = di->local_mem_size;
|
|
||||||
|
|
||||||
// create virtual card info; don't allow access by apps -
|
// create virtual card info; don't allow access by apps -
|
||||||
// they'll clone it
|
// they'll clone it
|
||||||
@@ -306,7 +304,7 @@ status_t Radeon_FirstOpen( device_info *di )
|
|||||||
di->vc->assigned_crtc[0] = true;
|
di->vc->assigned_crtc[0] = true;
|
||||||
di->vc->assigned_crtc[1] = si->num_crtc > 1;
|
di->vc->assigned_crtc[1] = si->num_crtc > 1;
|
||||||
di->vc->controlled_displays =
|
di->vc->controlled_displays =
|
||||||
dd_tv_crt | dd_crt | dd_lvds | dd_dvi | dd_ctv | dd_stv;
|
dd_tv_crt | dd_crt | dd_lvds | dd_dvi | dd_dvi_ext | dd_ctv | dd_stv;
|
||||||
|
|
||||||
di->vc->fb_mem_handle = 0;
|
di->vc->fb_mem_handle = 0;
|
||||||
di->vc->cursor.mem_handle = 0;
|
di->vc->cursor.mem_handle = 0;
|
||||||
@@ -324,13 +322,21 @@ status_t Radeon_FirstOpen( device_info *di )
|
|||||||
if( di->asic == rt_rv100 && di->is_mobility)
|
if( di->asic == rt_rv100 && di->is_mobility)
|
||||||
di->dac2_cntl = INREG( di->regs, RADEON_DAC_CNTL2 );
|
di->dac2_cntl = INREG( di->regs, RADEON_DAC_CNTL2 );
|
||||||
|
|
||||||
|
memcpy(&si->tmds_pll, &di->tmds_pll, sizeof(di->tmds_pll));
|
||||||
|
si->tmds_pll_cntl = INREG( di->regs, RADEON_TMDS_PLL_CNTL);
|
||||||
|
si->tmds_transmitter_cntl = INREG( di->regs, RADEON_TMDS_TRANSMITTER_CNTL);
|
||||||
|
|
||||||
// print these out to capture bios status...
|
// print these out to capture bios status...
|
||||||
if ( di->is_mobility ) {
|
// if ( di->is_mobility ) {
|
||||||
SHOW_INFO0( 4, "Copy of Laptop Display Regs for Reference:");
|
SHOW_INFO0( 2, "Copy of Laptop Display Regs for Reference:");
|
||||||
SHOW_INFO( 4, "LVDS CNTL = %8lx", INREG( di->regs, RADEON_LVDS_GEN_CNTL ));
|
SHOW_INFO( 2, "LVDS GEN = %8lx", INREG( di->regs, RADEON_LVDS_GEN_CNTL ));
|
||||||
SHOW_INFO( 4, "FP1 CNTL = %8lx", INREG( di->regs, RADEON_FP_GEN_CNTL ));
|
SHOW_INFO( 2, "LVDS PLL = %8lx", INREG( di->regs, RADEON_LVDS_PLL_CNTL ));
|
||||||
SHOW_INFO( 4, "FP2 CNTL = %8lx", INREG( di->regs, RADEON_FP2_GEN_CNTL ));
|
SHOW_INFO( 2, "TMDS PLL = %8lx", INREG( di->regs, RADEON_TMDS_PLL_CNTL ));
|
||||||
}
|
SHOW_INFO( 2, "TMDS TRANS = %8lx", INREG( di->regs, RADEON_TMDS_TRANSMITTER_CNTL ));
|
||||||
|
SHOW_INFO( 2, "FP1 GEN = %8lx", INREG( di->regs, RADEON_FP_GEN_CNTL ));
|
||||||
|
SHOW_INFO( 2, "FP2 GEN = %8lx", INREG( di->regs, RADEON_FP2_GEN_CNTL ));
|
||||||
|
SHOW_INFO( 2, "TV DAC = %8lx", INREG( di->regs, RADEON_TV_DAC_CNTL )); //not setup right when ext dvi
|
||||||
|
// }
|
||||||
|
|
||||||
result = Radeon_InitPCIGART( di );
|
result = Radeon_InitPCIGART( di );
|
||||||
if( result < 0 )
|
if( result < 0 )
|
||||||
|
|||||||
@@ -116,6 +116,7 @@ typedef struct device_info {
|
|||||||
disp_entity routing;
|
disp_entity routing;
|
||||||
|
|
||||||
general_pll_info pll;
|
general_pll_info pll;
|
||||||
|
tmds_pll_info tmds_pll[4];
|
||||||
ram_info ram;
|
ram_info ram;
|
||||||
char ram_type[32]; // human-readable name of ram type
|
char ram_type[32]; // human-readable name of ram type
|
||||||
uint32 local_mem_size;
|
uint32 local_mem_size;
|
||||||
|
|||||||
Reference in New Issue
Block a user