From f9a5b215cd501744b1ede0d783b66efad7e4642e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Mon, 13 Aug 2007 17:22:32 +0000 Subject: [PATCH] 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 --- headers/private/graphics/radeon/fp_regs.h | 10 ++ .../graphics/radeon/radeon_interface.h | 27 ++-- .../accelerants/radeon/ProposeDisplayMode.c | 43 ++++-- .../accelerants/radeon/SetDisplayMode.c | 66 ++++++++- src/add-ons/accelerants/radeon/flat_panel.c | 77 ++++++++-- .../accelerants/radeon/monitor_detection.c | 36 ++--- .../accelerants/radeon/monitor_routing.c | 9 +- .../accelerants/radeon/radeon_accelerant.h | 2 +- src/add-ons/accelerants/radeon/set_mode.h | 8 +- .../kernel/drivers/graphics/radeon/bios.c | 136 +++++++++++++++++- .../kernel/drivers/graphics/radeon/init.c | 34 +++-- .../drivers/graphics/radeon/radeon_driver.h | 1 + 12 files changed, 366 insertions(+), 83 deletions(-) diff --git a/headers/private/graphics/radeon/fp_regs.h b/headers/private/graphics/radeon/fp_regs.h index c3c17d932f..e145173c83 100644 --- a/headers/private/graphics/radeon/fp_regs.h +++ b/headers/private/graphics/radeon/fp_regs.h @@ -35,6 +35,7 @@ # define RADEON_FP2_PANEL_FORMAT (1 << 3) # define RADEON_FP2_SOURCE_SEL_MASK (3 << 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_CRTC2 (1 << 13) # define RADEON_FP2_FP_POL (1 << 16) @@ -68,6 +69,12 @@ # define RADEON_VERT_STRETCH_BLEND (1 << 26) # define RADEON_VERT_AUTO_RATIO_EN (1 << 27) # 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_V_SYNC_STRT_WID 0x02c8 @@ -80,6 +87,9 @@ # define RADEON_LVDS_DIGON (1 << 18) # define RADEON_LVDS_BLON (1 << 19) # 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_V_TOTAL_DISP 0x0354 diff --git a/headers/private/graphics/radeon/radeon_interface.h b/headers/private/graphics/radeon/radeon_interface.h index ae9e5ca9d8..c8f718a261 100644 --- a/headers/private/graphics/radeon/radeon_interface.h +++ b/headers/private/graphics/radeon/radeon_interface.h @@ -348,6 +348,11 @@ typedef struct { uint32 best_vco; // preferred VCO frequency (0 for don't care) } pll_info; +// info for ext tmds pll +typedef struct { + uint32 freq; + uint32 value; +} tmds_pll_info; // one overlay buffer typedef struct overlay_buffer_node { @@ -520,24 +525,24 @@ typedef struct { uint16 device_id; // PCI device id uint8 revision; // PCI device revision - //bool has_crtc2; // has second CRTC radeon_type asic; // ASIC version - bool is_mobility; // mobility version - bool is_igp; // might need to know if it's an integrated chip + bool is_mobility; // mobility version + bool is_igp; // might need to know if it's an integrated chip 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 has_no_i2c; // I2C is broken - uint16 panel_pwr_delay;// delay for LCD backlight to stabilise - uint8 theatre_channel;// VIP channel of Rage Theatre (if applicable) + bool has_no_i2c; // I2C is broken + uint16 panel_pwr_delay; // delay for LCD backlight to stabilise + uint8 theatre_channel; // VIP channel of Rage Theatre (if applicable) general_pll_info pll; - + tmds_pll_info tmds_pll[4]; + area_id regs_area; // area of memory mapped registers 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) - // this is a hack needed by BeOS + // this is a hack needed by BeOS crtc_info crtc[2]; // info about each crtc uint8 num_crtc; // number of physical heads @@ -557,6 +562,8 @@ typedef struct { uint32 active_vc; // currently selected virtual card in terms of 2D acceleration 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 active_overlay; // overlay shown diff --git a/src/add-ons/accelerants/radeon/ProposeDisplayMode.c b/src/add-ons/accelerants/radeon/ProposeDisplayMode.c index 2efe86b80d..46bcc76ddd 100644 --- a/src/add-ons/accelerants/radeon/ProposeDisplayMode.c +++ b/src/add-ons/accelerants/radeon/ProposeDisplayMode.c @@ -148,6 +148,10 @@ Radeon_ProposeDisplayMode(shared_info *si, crtc_info *crtc, int eff_virtual_width; 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 // don't use floating point, we are in kernel mode target_refresh = @@ -163,7 +167,7 @@ Radeon_ProposeDisplayMode(shared_info *si, crtc_info *crtc, // for flat panels, check maximum resolution; // all the other tricks (like fixed resolution and resulting scaling) // 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 ) 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; } + // 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 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 || 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 ); 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 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 ); return B_ERROR; } @@ -516,11 +531,11 @@ static void addFPMode( accelerator_info *ai ) { 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; - + SHOW_FLOW0( 2, "" ); mode.virtual_width = mode.timing.h_display = fp_info->panel_xres; 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_VerifyMultiMode( vc, si, target ); - SHOW_FLOW0( 3, "wished:" ); - SHOW_FLOW( 3, "H: %4d %4d %4d %4d (v=%4d)", + SHOW_FLOW0( 2, "wished:" ); + SHOW_FLOW( 2, "H: %4d %4d %4d %4d (v=%4d)", target->timing.h_display, target->timing.h_sync_start, 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_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 // 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; } - SHOW_INFO0( 4, "got:" ); - SHOW_INFO( 4, "H: %4d %4d %4d %4d (v=%4d)", + SHOW_INFO0( 2, "got:" ); + SHOW_INFO( 2, "H: %4d %4d %4d %4d (v=%4d)", target->timing.h_display, target->timing.h_sync_start, 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_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 ); diff --git a/src/add-ons/accelerants/radeon/SetDisplayMode.c b/src/add-ons/accelerants/radeon/SetDisplayMode.c index b41f52200b..bd7e40e475 100644 --- a/src/add-ons/accelerants/radeon/SetDisplayMode.c +++ b/src/add-ons/accelerants/radeon/SetDisplayMode.c @@ -23,11 +23,20 @@ #include "fp_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 -void Radeon_SetMode( +status_t Radeon_SetMode( accelerator_info *ai, crtc_info *crtc, display_mode *mode, impactv_params *tv_params ); // round virtual width up to next valid size @@ -94,7 +103,7 @@ static void Radeon_InitCommonRegs( // set display mode of one head; // 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 ) { virtual_card *vc = ai->vc; @@ -126,11 +135,26 @@ void Radeon_SetMode( // is determined by the physical resolution; // also, all timing is fixed 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 ) 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; + 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_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; @@ -254,6 +278,28 @@ void Radeon_SetMode( 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; // 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, // but currently, virtual cards don't work anyway... si->active_overlay.crtc_idx = -1; + + return B_OK; } @@ -432,6 +480,8 @@ status_t SET_DISPLAY_MODE( { routing_regs routing_values; 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 if( vc->assigned_crtc[0] ) { @@ -451,10 +501,14 @@ status_t SET_DISPLAY_MODE( // then change the mode 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] ) - 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 Radeon_ReadMonitorRoutingRegs( ai, &routing_values ); Radeon_CalcMonitorRouting( ai, &tv_params, &routing_values ); @@ -462,9 +516,9 @@ status_t SET_DISPLAY_MODE( // finally, switch display(s) on 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] ) - 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 ); } diff --git a/src/add-ons/accelerants/radeon/flat_panel.c b/src/add-ons/accelerants/radeon/flat_panel.c index 7d27350b81..66ea70082c 100644 --- a/src/add-ons/accelerants/radeon/flat_panel.c +++ b/src/add-ons/accelerants/radeon/flat_panel.c @@ -108,7 +108,7 @@ void Radeon_ProgramRMXRegisters( accelerator_info *ai, fp_regs *values ) { vuint8 *regs = ai->regs; - + SHOW_FLOW0( 2, "" ); OUTREG( regs, RADEON_FP_HORZ_STRETCH, values->fp_horz_stretch ); OUTREG( regs, RADEON_FP_VERT_STRETCH, values->fp_vert_stretch ); } @@ -119,9 +119,11 @@ void Radeon_ReadFPRegisters( { vuint8 *regs = ai->regs; - values->fp_gen_cntl = INREG( regs, RADEON_FP_GEN_CNTL ); - values->fp2_gen_cntl = INREG( regs, RADEON_FP2_GEN_CNTL ); - values->lvds_gen_cntl = INREG( regs, RADEON_LVDS_GEN_CNTL ); + values->fp_gen_cntl = INREG( regs, RADEON_FP_GEN_CNTL ); + values->fp2_gen_cntl = INREG( regs, RADEON_FP2_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_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 ); @@ -130,9 +132,14 @@ void Radeon_ReadFPRegisters( values->bios_5_scratch = INREG( regs, RADEON_BIOS_5_SCRATCH ); values->bios_6_scratch = INREG( regs, RADEON_BIOS_6_SCRATCH ); - 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->lvds_gen_cntl ); + 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", + values->fp_gen_cntl, values->fp_horz_stretch, values->fp_vert_stretch, + values->lvds_gen_cntl ); } // calculcate flat panel crtc registers; @@ -141,20 +148,27 @@ void Radeon_CalcFPRegisters( accelerator_info *ai, crtc_info *crtc, fp_info *fp_port, crtc_regs *crtc_values, fp_regs *values ) { + int i; + uint32 tmp = values->tmds_pll_cntl & 0xfffff; + // setup synchronization position // (most values are ignored according to fp_gen_cntl, but at least polarity // and pixel precise horizontal sync position are always used) 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_v_sync_strt_wid = crtc_values->crtc_v_sync_strt_wid; } else { + SHOW_FLOW0( 2, "fp1" ); 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; } - if( fp_port->is_fp2 ) - values->fp2_gen_cntl = 0; - else { + if( fp_port->is_fp2 ) { + // should retain POST values (esp bit 28) + values->fp2_gen_cntl &= (0xFFFF0000); + + } else { // setup magic CRTC shadowing values->fp_gen_cntl &= ~(RADEON_FP_RMX_HVSYNC_CONTROL_EN | @@ -169,29 +183,64 @@ void Radeon_CalcFPRegisters( 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 if( (crtc->chosen_displays & dd_lvds) != 0 ) { // using LVDS means there cannot be a DVI monitor + SHOW_FLOW0( 2, "lvds" ); values->lvds_gen_cntl |= (RADEON_LVDS_ON | RADEON_LVDS_BLON); values->fp_gen_cntl &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN); } else if( !fp_port->is_fp2 ) { // DVI on internal transmitter + SHOW_FLOW0( 2, "DVI INT" ); 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 values->fp_gen_cntl |= RADEON_FP_PANEL_FORMAT; } else { // 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_BLANK_EN; + //hack in missing bits test... + //values->fp2_gen_cntl |= (1 << 22) | (1 << 28); + if( ai->si->asic >= rt_r200 ) values->fp2_gen_cntl |= RADEON_FP2_DV0_EN; } - SHOW_FLOW( 2, "after: fp_gen_cntl=%08lx, horz=%08lx, vert=%08lx, lvds_gen_cntl=%08lx", - values->fp_gen_cntl, values->fp_horz_stretch, values->fp_vert_stretch, + 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->fp2_gen_cntl, values->fp_horz_stretch, values->fp_vert_stretch, 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 ); 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, 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_V2_SYNC_STRT_WID, values->fp2_v_sync_strt_wid ); } else { + SHOW_FLOW0( 2, "is_fp1" ); 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 ); } diff --git a/src/add-ons/accelerants/radeon/monitor_detection.c b/src/add-ons/accelerants/radeon/monitor_detection.c index 79c8405a16..521c0aba97 100644 --- a/src/add-ons/accelerants/radeon/monitor_detection.c +++ b/src/add-ons/accelerants/radeon/monitor_detection.c @@ -269,19 +269,19 @@ static bool Radeon_DetectTVCRT_R300( accelerator_info *ai ) RADEON_DAC_FORCE_DATA_SEL_RGB | (0x1b6 << RADEON_DAC_FORCE_DATA_SHIFT )); - old_dac_cntl2 = INREG( regs, RADEON_DAC_CNTL2 ); + old_dac_cntl2 = INREG( regs, RADEON_DAC_CNTL2 ); // enable CRT mode of TV-DAC and enable comparator - tmp = old_dac_cntl2 | RADEON_DAC2_CLK_SEL_CRT | RADEON_DAC2_CMP_EN; + tmp = old_dac_cntl2 | RADEON_DAC2_CLK_SEL_CRT | RADEON_DAC2_CMP_EN; - OUTREG( regs, RADEON_DAC_CNTL2, tmp ); + OUTREG( regs, RADEON_DAC_CNTL2, tmp ); - snooze( 10000 ); + snooze( 10000 ); - // check connection of blue data signal to see whether there is a CRT + // check connection of blue data signal to see whether there is a CRT found = (INREG( regs, RADEON_DAC_CNTL2 ) & RADEON_DAC2_CMP_OUT_B) != 0; - // clean up the mess + // clean up the mess OUTREG( regs, RADEON_DAC_CNTL2, old_dac_cntl2 ); OUTREG( regs, RADEON_DAC_EXT_CNTL, 0 ); OUTREG( regs, RADEON_TV_DAC_CNTL, old_tv_dac_cntl ); @@ -289,7 +289,7 @@ static bool Radeon_DetectTVCRT_R300( accelerator_info *ai ) OUTREGP( regs, RADEON_GPIOPAD_A, old_radeon_gpiopad_a, ~1 ); - return found; + return found; } @@ -800,9 +800,9 @@ static void Radeon_FindFPTiming_StandardTiming( } // 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; //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 for ( i = 0; i < 2; i++ ) { - if (routes->port_info[i].mon_type != mt_unknown ) { - SHOW_FLOW0( 2, "known type, skpping detection" ); - continue; - } + //TODO could skip edid reading instead if we already have it, but what + //if monitors have been hot swapped? Also rely on edid for DVI-D detection + //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) ); 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. if ( routes->port_info[i].tmds_type == tmds_ext ){ // 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" ); routes->port_info[i].mon_type = mt_dfp; + ai->si->flatpanels[i].is_fp2 = true; displays |= dd_dvi_ext; } else { SHOW_ERROR0( 2, "Disabled Ext DVI - invalid EDID" ); @@ -1003,7 +1006,7 @@ void Radeon_DetectDisplays( accelerator_info *ai ) } else { if( INREG( ai->regs, RADEON_FP_GEN_CNTL) & (1 << 7) || ( !si->is_mobility ) ) { // 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" ); routes->port_info[i].mon_type = mt_dfp; displays |= dd_dvi; @@ -1015,6 +1018,7 @@ void Radeon_DetectDisplays( accelerator_info *ai ) routes->port_info[i].mon_type = mt_lcd; displays |= dd_lvds; } + ai->si->flatpanels[1].is_fp2 = FALSE; } } else { // 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)) { SHOW_INFO0( 2, "Found Ext Laptop DVI" ); routes->port_info[1].mon_type = mt_dfp; - displays |= dd_dvi; + displays |= dd_dvi_ext; } } diff --git a/src/add-ons/accelerants/radeon/monitor_routing.c b/src/add-ons/accelerants/radeon/monitor_routing.c index 7bfb466500..08be63afe3 100644 --- a/src/add-ons/accelerants/radeon/monitor_routing.c +++ b/src/add-ons/accelerants/radeon/monitor_routing.c @@ -634,8 +634,11 @@ static void assignDefaultMonitorRoute( else if( ai->si->num_crtc > 1 && (crtc2_displays & ~(dd_stv | dd_ctv)) == 0 && vc->assigned_crtc[1] ) 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; *crtc2 = crtc2_displays; @@ -651,7 +654,7 @@ void Radeon_SetupDefaultMonitorRouting( shared_info *si = ai->si; display_device_e display_devices = vc->connected_displays; - if (ai->si->settings.force_lcd) { + if (ai->si->settings.force_lcd) { use_laptop_panel = true; SHOW_FLOW0( 2, "LCD Forced Used by Kernel Settings"); } diff --git a/src/add-ons/accelerants/radeon/radeon_accelerant.h b/src/add-ons/accelerants/radeon/radeon_accelerant.h index c69035bc24..d769019dfb 100644 --- a/src/add-ons/accelerants/radeon/radeon_accelerant.h +++ b/src/add-ons/accelerants/radeon/radeon_accelerant.h @@ -32,7 +32,7 @@ extern int debug_level_error; #define DEBUG_MSG_PREFIX "Radeon - " -#define DEBUG_MAX_LEVEL_FLOW 2 +#define DEBUG_MAX_LEVEL_FLOW 3 #include "debug_ext.h" diff --git a/src/add-ons/accelerants/radeon/set_mode.h b/src/add-ons/accelerants/radeon/set_mode.h index a5d826faa6..4e32935e7e 100644 --- a/src/add-ons/accelerants/radeon/set_mode.h +++ b/src/add-ons/accelerants/radeon/set_mode.h @@ -98,17 +98,19 @@ typedef struct { typedef struct { uint32 fp_gen_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_v_sync_strt_wid; uint32 fp2_gen_cntl; - uint32 fp2_h_sync_strt_wid; + uint32 fp2_h_sync_strt_wid; uint32 fp2_v_sync_strt_wid; // RMX registers uint32 fp_horz_stretch; - uint32 fp_vert_stretch; + uint32 fp_vert_stretch; // Bios values used by Mobility Asics uint32 bios_4_scratch; diff --git a/src/add-ons/kernel/drivers/graphics/radeon/bios.c b/src/add-ons/kernel/drivers/graphics/radeon/bios.c index 5e4d276012..2dcf0eacf2 100644 --- a/src/add-ons/kernel/drivers/graphics/radeon/bios.c +++ b/src/add-ons/kernel/drivers/graphics/radeon/bios.c @@ -31,14 +31,33 @@ #define RADEON_BIOS8(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]) | \ - (di->rom.rom_ptr[(v) + 1] << 8) \ - (di->rom.rom_ptr[(v) + 2] << 16) \ - (di->rom.rom_ptr[(v) + 3] << 24)) + (di->rom.rom_ptr[(v) + 1] << 8) | \ + (di->rom.rom_ptr[(v) + 2] << 16) | \ + (di->rom.rom_ptr[(v) + 3] << 24)) 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; // this code is really nasty as maintaining the radeon signatures // 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); } +//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 @@ -964,6 +1085,12 @@ status_t Radeon_ReadBIOSData( device_info *di ) di->routing.port_info[0].dac_type = dac_unknown; di->routing.port_info[0].tmds_type = tmds_unknown; 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 ) ) { @@ -981,6 +1108,7 @@ status_t Radeon_ReadBIOSData( device_info *di ) } Radeon_GetFPData( di ); + Radeon_GetTMDSInfoFromBios( di ); Radeon_DetectRAM( di ); Radeon_UnmapDevice( di ); diff --git a/src/add-ons/kernel/drivers/graphics/radeon/init.c b/src/add-ons/kernel/drivers/graphics/radeon/init.c index cb63eb92c0..818098358f 100644 --- a/src/add-ons/kernel/drivers/graphics/radeon/init.c +++ b/src/add-ons/kernel/drivers/graphics/radeon/init.c @@ -15,6 +15,7 @@ */ #include "dac_regs.h" +#include "tv_out_regs.h" #include "fp_regs.h" #include "mmio.h" #include "radeon_driver.h" @@ -266,20 +267,17 @@ status_t Radeon_FirstOpen( device_info *di ) // so we let the first accelerant take care of it 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].flatpanel_port = 0; si->crtc[1].crtc_idx = 1; si->crtc[1].flatpanel_port = 1; si->num_crtc = di->num_crtc; - si->flatpanels[0] = di->fp_info; + if (di->is_mobility) + si->flatpanels[0] = di->fp_info; + 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 - // they'll clone it sprintf( buffer, "%04X_%04X_%02X%02X%02X virtual card 0", @@ -306,7 +304,7 @@ status_t Radeon_FirstOpen( device_info *di ) di->vc->assigned_crtc[0] = true; di->vc->assigned_crtc[1] = si->num_crtc > 1; 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->cursor.mem_handle = 0; @@ -324,13 +322,21 @@ status_t Radeon_FirstOpen( device_info *di ) if( di->asic == rt_rv100 && di->is_mobility) 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... - if ( di->is_mobility ) { - SHOW_INFO0( 4, "Copy of Laptop Display Regs for Reference:"); - SHOW_INFO( 4, "LVDS CNTL = %8lx", INREG( di->regs, RADEON_LVDS_GEN_CNTL )); - SHOW_INFO( 4, "FP1 CNTL = %8lx", INREG( di->regs, RADEON_FP_GEN_CNTL )); - SHOW_INFO( 4, "FP2 CNTL = %8lx", INREG( di->regs, RADEON_FP2_GEN_CNTL )); - } +// if ( di->is_mobility ) { + SHOW_INFO0( 2, "Copy of Laptop Display Regs for Reference:"); + SHOW_INFO( 2, "LVDS GEN = %8lx", INREG( di->regs, RADEON_LVDS_GEN_CNTL )); + SHOW_INFO( 2, "LVDS PLL = %8lx", INREG( di->regs, RADEON_LVDS_PLL_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 ); if( result < 0 ) diff --git a/src/add-ons/kernel/drivers/graphics/radeon/radeon_driver.h b/src/add-ons/kernel/drivers/graphics/radeon/radeon_driver.h index 1ff6bddda0..d681c59426 100644 --- a/src/add-ons/kernel/drivers/graphics/radeon/radeon_driver.h +++ b/src/add-ons/kernel/drivers/graphics/radeon/radeon_driver.h @@ -116,6 +116,7 @@ typedef struct device_info { disp_entity routing; general_pll_info pll; + tmds_pll_info tmds_pll[4]; ram_info ram; char ram_type[32]; // human-readable name of ram type uint32 local_mem_size;