diff --git a/headers/private/graphics/nvidia/DriverInterface.h b/headers/private/graphics/nvidia/DriverInterface.h index 64eebac1d0..dc7ee440fa 100644 --- a/headers/private/graphics/nvidia/DriverInterface.h +++ b/headers/private/graphics/nvidia/DriverInterface.h @@ -227,11 +227,9 @@ typedef struct { bool master_tmds2; /* on die TMDS encoder active on CRTC2 */ bool tmds1_active; /* found panel on CRTC1 that is active */ bool tmds2_active; /* found panel on CRTC2 that is active */ - uint16 panel1_width; /* native horizontal resolution for digital panels */ - uint16 panel1_height; /* navive vertical resolution for digital panels */ + display_timing p1_timing; /* 'modeline' fetched for panel 1 */ + display_timing p2_timing; /* 'modeline' fetched for panel 2 */ float panel1_aspect; /* panel's aspect ratio */ - uint16 panel2_width; /* native horizontal resolution for digital panels */ - uint16 panel2_height; /* navive vertical resolution for digital panels */ float panel2_aspect; /* panel's aspect ratio */ bool crtc2_prim; /* using CRTC2 as primary CRTC */ uint32 tvout_chip_type; /* see tvchip_type enum above */ diff --git a/src/add-ons/accelerants/nvidia/ProposeDisplayMode.c b/src/add-ons/accelerants/nvidia/ProposeDisplayMode.c index a84d5efd9d..8abf63ecb5 100644 --- a/src/add-ons/accelerants/nvidia/ProposeDisplayMode.c +++ b/src/add-ons/accelerants/nvidia/ProposeDisplayMode.c @@ -437,7 +437,7 @@ status_t create_mode_list(void) /* see if there are panels connected and get their native modelines */ bool pan1 = false, pan2 = false, pan1_added = false, pan2_added = false; display_mode p1, p2; - get_panel_modelines(&p1, &p2, &pan1, &pan2); + get_panel_modes(&p1, &p2, &pan1, &pan2); /* figure out how big the list could be, and adjust up to nearest multiple of B_PAGE_SIZE */ /* note: two extra modes might be added for flatpanels */ diff --git a/src/add-ons/accelerants/nvidia/engine/nv_crtc.c b/src/add-ons/accelerants/nvidia/engine/nv_crtc.c index 50ab310623..0ba111bc84 100644 --- a/src/add-ons/accelerants/nvidia/engine/nv_crtc.c +++ b/src/add-ons/accelerants/nvidia/engine/nv_crtc.c @@ -305,8 +305,8 @@ status_t nv_crtc_set_timing(display_mode target) uint32 iscale_x, iscale_y; /* calculate inverse scaling factors used by hardware in 20.12 format */ - iscale_x = (((1 << 12) * target.timing.h_display) / si->ps.panel1_width); - iscale_y = (((1 << 12) * target.timing.v_display) / si->ps.panel1_height); + iscale_x = (((1 << 12) * target.timing.h_display) / si->ps.p1_timing.h_display); + iscale_y = (((1 << 12) * target.timing.v_display) / si->ps.p1_timing.v_display); /* unblock flatpanel timing programming (or something like that..) */ CRTCW(FP_HTIMING, 0); @@ -316,10 +316,10 @@ status_t nv_crtc_set_timing(display_mode target) /* enable full width visibility on flatpanel */ DACW(FP_HVALID_S, 0); - DACW(FP_HVALID_E, (si->ps.panel1_width - 1)); + DACW(FP_HVALID_E, (si->ps.p1_timing.h_display - 1)); /* enable full height visibility on flatpanel */ DACW(FP_VVALID_S, 0); - DACW(FP_VVALID_E, (si->ps.panel1_height - 1)); + DACW(FP_VVALID_E, (si->ps.p1_timing.v_display - 1)); /* nVidia cards support upscaling except on ??? */ /* NV11 cards can upscale after all! */ @@ -382,11 +382,11 @@ status_t nv_crtc_set_timing(display_mode target) /* enable testmode (b12) and program modified X-scaling factor */ DACW(FP_DEBUG1, (((iscale_x >> 1) & 0x00000fff) | (1 << 12))); /* center/cut-off left and right side of screen */ - diff = ((si->ps.panel1_width - + diff = ((si->ps.p1_timing.h_display - (target.timing.h_display * ((1 << 12) / ((float)iscale_x)))) / 2); DACW(FP_HVALID_S, diff); - DACW(FP_HVALID_E, ((si->ps.panel1_width - diff) - 1)); + DACW(FP_HVALID_E, ((si->ps.p1_timing.h_display - diff) - 1)); } /* correct for portrait panels... */ /* NOTE: diff --git a/src/add-ons/accelerants/nvidia/engine/nv_crtc2.c b/src/add-ons/accelerants/nvidia/engine/nv_crtc2.c index 164180e052..1a91f9b399 100644 --- a/src/add-ons/accelerants/nvidia/engine/nv_crtc2.c +++ b/src/add-ons/accelerants/nvidia/engine/nv_crtc2.c @@ -288,8 +288,8 @@ status_t nv_crtc2_set_timing(display_mode target) uint32 iscale_x, iscale_y; /* calculate inverse scaling factors used by hardware in 20.12 format */ - iscale_x = (((1 << 12) * target.timing.h_display) / si->ps.panel2_width); - iscale_y = (((1 << 12) * target.timing.v_display) / si->ps.panel2_height); + iscale_x = (((1 << 12) * target.timing.h_display) / si->ps.p2_timing.h_display); + iscale_y = (((1 << 12) * target.timing.v_display) / si->ps.p2_timing.v_display); /* unblock flatpanel timing programming (or something like that..) */ CRTC2W(FP_HTIMING, 0); @@ -299,10 +299,10 @@ status_t nv_crtc2_set_timing(display_mode target) /* enable full width visibility on flatpanel */ DAC2W(FP_HVALID_S, 0); - DAC2W(FP_HVALID_E, (si->ps.panel2_width - 1)); + DAC2W(FP_HVALID_E, (si->ps.p2_timing.h_display - 1)); /* enable full height visibility on flatpanel */ DAC2W(FP_VVALID_S, 0); - DAC2W(FP_VVALID_E, (si->ps.panel2_height - 1)); + DAC2W(FP_VVALID_E, (si->ps.p2_timing.v_display - 1)); /* nVidia cards support upscaling except on ??? */ /* NV11 cards can upscale after all! */ @@ -365,11 +365,11 @@ status_t nv_crtc2_set_timing(display_mode target) /* enable testmode (b12) and program new X-scaling factor */ DAC2W(FP_DEBUG1, (((iscale_x >> 1) & 0x00000fff) | (1 << 12))); /* center/cut-off left and right side of screen */ - diff = ((si->ps.panel2_width - + diff = ((si->ps.p2_timing.h_display - (target.timing.h_display * ((1 << 12) / ((float)iscale_x)))) / 2); DAC2W(FP_HVALID_S, diff); - DAC2W(FP_HVALID_E, ((si->ps.panel2_width - diff) - 1)); + DAC2W(FP_HVALID_E, ((si->ps.p2_timing.h_display - diff) - 1)); } /* correct for portrait panels... */ /* NOTE: diff --git a/src/add-ons/accelerants/nvidia/engine/nv_dac.c b/src/add-ons/accelerants/nvidia/engine/nv_dac.c index 120350b2c8..3783339043 100644 --- a/src/add-ons/accelerants/nvidia/engine/nv_dac.c +++ b/src/add-ons/accelerants/nvidia/engine/nv_dac.c @@ -151,11 +151,8 @@ status_t nv_dac_set_pix_pll(display_mode target) { LOG(4,("DAC: Fixing DFP refresh to 62Hz!\n")); - /* readout the panel's modeline to determine the needed pixelclock */ - target.timing.pixel_clock = ( - ((DACR(FP_HTOTAL) & 0x0000ffff) + 1) * - ((DACR(FP_VTOTAL) & 0x0000ffff) + 1) * - 62) / 1000; + /* use the panel's modeline to determine the needed pixelclock */ + target.timing.pixel_clock = si->ps.p1_timing.pixel_clock; } req_pclk = (target.timing.pixel_clock)/1000.0; diff --git a/src/add-ons/accelerants/nvidia/engine/nv_dac2.c b/src/add-ons/accelerants/nvidia/engine/nv_dac2.c index 60521f9e41..2107a26a97 100644 --- a/src/add-ons/accelerants/nvidia/engine/nv_dac2.c +++ b/src/add-ons/accelerants/nvidia/engine/nv_dac2.c @@ -157,11 +157,8 @@ status_t nv_dac2_set_pix_pll(display_mode target) { LOG(4,("DAC2: Fixing DFP refresh to 62Hz!\n")); - /* readout the panel's modeline to determine the needed pixelclock */ - target.timing.pixel_clock = ( - ((DAC2R(FP_HTOTAL) & 0x0000ffff) + 1) * - ((DAC2R(FP_VTOTAL) & 0x0000ffff) + 1) * - 62) / 1000; + /* use the panel's modeline to determine the needed pixelclock */ + target.timing.pixel_clock = si->ps.p2_timing.pixel_clock; } req_pclk = (target.timing.pixel_clock)/1000.0; diff --git a/src/add-ons/accelerants/nvidia/engine/nv_info.c b/src/add-ons/accelerants/nvidia/engine/nv_info.c index 31e8c7c02d..a7aa7aac93 100644 --- a/src/add-ons/accelerants/nvidia/engine/nv_info.c +++ b/src/add-ons/accelerants/nvidia/engine/nv_info.c @@ -325,11 +325,11 @@ static void detect_panels() LOG(2,("INFO: End flatpanel related CRTC registers dump.\n")); /* do some presets */ - si->ps.panel1_width = 0; - si->ps.panel1_height = 0; + si->ps.p1_timing.h_display = 0; + si->ps.p1_timing.v_display = 0; si->ps.panel1_aspect = 0; - si->ps.panel2_width = 0; - si->ps.panel2_height = 0; + si->ps.p2_timing.h_display = 0; + si->ps.p2_timing.v_display = 0; si->ps.panel2_aspect = 0; si->ps.slaved_tmds1 = false; si->ps.slaved_tmds2 = false; @@ -367,8 +367,8 @@ static void detect_panels() { si->ps.slaved_tmds1 = true; si->ps.tmds1_active = true; - si->ps.panel1_width = width; - si->ps.panel1_height = height; + si->ps.p1_timing.h_display = width; + si->ps.p1_timing.v_display = height; } } @@ -380,8 +380,8 @@ static void detect_panels() { si->ps.slaved_tmds2 = true; si->ps.tmds2_active = true; - si->ps.panel2_width = width; - si->ps.panel2_height = height; + si->ps.p2_timing.h_display = width; + si->ps.p2_timing.v_display = height; } } @@ -393,8 +393,8 @@ static void detect_panels() { si->ps.master_tmds1 = true; si->ps.tmds1_active = true; - si->ps.panel1_width = width; - si->ps.panel1_height = height; + si->ps.p1_timing.h_display = width; + si->ps.p1_timing.v_display = height; } } @@ -406,8 +406,8 @@ static void detect_panels() { si->ps.master_tmds2 = true; si->ps.tmds2_active = true; - si->ps.panel2_width = width; - si->ps.panel2_height = height; + si->ps.p2_timing.h_display = width; + si->ps.p2_timing.v_display = height; } } @@ -416,8 +416,8 @@ static void detect_panels() //otherwise we probably get into trouble here if the checked specs match. if (si->ps.laptop && si->ps.tmds1_active && si->ps.tmds2_active && ((DACR(FP_TG_CTRL) & 0x80000000) == (DAC2R(FP_TG_CTRL) & 0x80000000)) && - (si->ps.panel1_width == si->ps.panel2_width) && - (si->ps.panel1_height == si->ps.panel2_height)) + (si->ps.p1_timing.h_display == si->ps.p2_timing.h_display) && + (si->ps.p1_timing.v_display == si->ps.p2_timing.v_display)) { LOG(2,("INFO: correcting double detection of single panel!\n")); @@ -427,8 +427,8 @@ static void detect_panels() si->ps.slaved_tmds1 = false; si->ps.master_tmds1 = false; si->ps.tmds1_active = false; - si->ps.panel1_width = 0; - si->ps.panel1_height = 0; + si->ps.p1_timing.h_display = 0; + si->ps.p1_timing.v_display = 0; } else { @@ -436,16 +436,58 @@ static void detect_panels() si->ps.slaved_tmds2 = false; si->ps.master_tmds2 = false; si->ps.tmds2_active = false; - si->ps.panel2_width = 0; - si->ps.panel2_height = 0; + si->ps.p2_timing.h_display = 0; + si->ps.p2_timing.v_display = 0; } } - /* determine panel(s) aspect ratio(s) */ + /* fetch panel(s) modeline(s) */ if (si->ps.tmds1_active) - si->ps.panel1_aspect = (si->ps.panel1_width / ((float)si->ps.panel1_height)); + { + /* determine panel aspect ratio */ + si->ps.panel1_aspect = + (si->ps.p1_timing.h_display / ((float)si->ps.p1_timing.v_display)); + /* horizontal timing */ + si->ps.p1_timing.h_sync_start = (DACR(FP_HSYNC_S) & 0x0000ffff) + 1; + si->ps.p1_timing.h_sync_end = (DACR(FP_HSYNC_E) & 0x0000ffff) + 1; + si->ps.p1_timing.h_total = (DACR(FP_HTOTAL) & 0x0000ffff) + 1; + /* vertical timing */ + si->ps.p1_timing.v_sync_start = (DACR(FP_VSYNC_S) & 0x0000ffff) + 1; + si->ps.p1_timing.v_sync_end = (DACR(FP_VSYNC_E) & 0x0000ffff) + 1; + si->ps.p1_timing.v_total = (DACR(FP_VTOTAL) & 0x0000ffff) + 1; + /* sync polarity */ + si->ps.p1_timing.flags = 0; + if (DACR(FP_TG_CTRL) & 0x00000001) si->ps.p1_timing.flags |= B_POSITIVE_VSYNC; + if (DACR(FP_TG_CTRL) & 0x00000010) si->ps.p1_timing.flags |= B_POSITIVE_HSYNC; + /* refreshrate: + * fix a DVI or laptop flatpanel to 62Hz refresh! + * (we can't risk getting below 60.0Hz as some panels shut-off then!) */ + si->ps.p1_timing.pixel_clock = + (si->ps.p1_timing.h_total * si->ps.p1_timing.v_total * 62) / 1000; + } if (si->ps.tmds2_active) - si->ps.panel2_aspect = (si->ps.panel2_width / ((float)si->ps.panel2_height)); + { + /* determine panel aspect ratio */ + si->ps.panel2_aspect = + (si->ps.p2_timing.h_display / ((float)si->ps.p2_timing.v_display)); + /* horizontal timing */ + si->ps.p2_timing.h_sync_start = (DAC2R(FP_HSYNC_S) & 0x0000ffff) + 1; + si->ps.p2_timing.h_sync_end = (DAC2R(FP_HSYNC_E) & 0x0000ffff) + 1; + si->ps.p2_timing.h_total = (DAC2R(FP_HTOTAL) & 0x0000ffff) + 1; + /* vertical timing */ + si->ps.p2_timing.v_sync_start = (DAC2R(FP_VSYNC_S) & 0x0000ffff) + 1; + si->ps.p2_timing.v_sync_end = (DAC2R(FP_VSYNC_E) & 0x0000ffff) + 1; + si->ps.p2_timing.v_total = (DAC2R(FP_VTOTAL) & 0x0000ffff) + 1; + /* sync polarity */ + si->ps.p2_timing.flags = 0; + if (DAC2R(FP_TG_CTRL) & 0x00000001) si->ps.p2_timing.flags |= B_POSITIVE_VSYNC; + if (DAC2R(FP_TG_CTRL) & 0x00000010) si->ps.p2_timing.flags |= B_POSITIVE_HSYNC; + /* refreshrate: + * fix a DVI or laptop flatpanel to 62Hz refresh! + * (we can't risk getting below 60.0Hz as some panels shut-off then!) */ + si->ps.p2_timing.pixel_clock = + (si->ps.p2_timing.h_total * si->ps.p2_timing.v_total * 62) / 1000; + } /* dump some panel configuration registers... */ LOG(2,("INFO: Dumping flatpanel registers:\n")); @@ -685,26 +727,12 @@ static void setup_output_matrix() } } -void get_panel_modelines(display_mode *p1, display_mode *p2, bool *pan1, bool *pan2) +void get_panel_modes(display_mode *p1, display_mode *p2, bool *pan1, bool *pan2) { if (si->ps.tmds1_active) { - /* horizontal timing */ - p1->timing.h_display = (DACR(FP_HDISPEND) & 0x0000ffff) + 1; - p1->timing.h_sync_start = (DACR(FP_HSYNC_S) & 0x0000ffff) + 1; - p1->timing.h_sync_end = (DACR(FP_HSYNC_E) & 0x0000ffff) + 1; - p1->timing.h_total = (DACR(FP_HTOTAL) & 0x0000ffff) + 1; - /* vertical timing */ - p1->timing.v_display = (DACR(FP_VDISPEND) & 0x0000ffff) + 1; - p1->timing.v_sync_start = (DACR(FP_VSYNC_S) & 0x0000ffff) + 1; - p1->timing.v_sync_end = (DACR(FP_VSYNC_E) & 0x0000ffff) + 1; - p1->timing.v_total = (DACR(FP_VTOTAL) & 0x0000ffff) + 1; - /* sync polarity */ - p1->timing.flags = 0; - if (DACR(FP_TG_CTRL) & 0x00000001) p1->timing.flags |= B_POSITIVE_VSYNC; - if (DACR(FP_TG_CTRL) & 0x00000010) p1->timing.flags |= B_POSITIVE_HSYNC; - /* refreshrate */ - p1->timing.pixel_clock = (p1->timing.h_total * p1->timing.v_total * 60) / 1000; + /* timing ('modeline') */ + p1->timing = si->ps.p1_timing; /* setup the rest */ p1->space = B_CMAP8; p1->virtual_width = p1->timing.h_display; @@ -719,22 +747,8 @@ void get_panel_modelines(display_mode *p1, display_mode *p2, bool *pan1, bool *p if (si->ps.tmds2_active) { - /* horizontal timing */ - p2->timing.h_display = (DAC2R(FP_HDISPEND) & 0x0000ffff) + 1; - p2->timing.h_sync_start = (DAC2R(FP_HSYNC_S) & 0x0000ffff) + 1; - p2->timing.h_sync_end = (DAC2R(FP_HSYNC_E) & 0x0000ffff) + 1; - p2->timing.h_total = (DAC2R(FP_HTOTAL) & 0x0000ffff) + 1; - /* vertical timing */ - p2->timing.v_display = (DAC2R(FP_VDISPEND) & 0x0000ffff) + 1; - p2->timing.v_sync_start = (DAC2R(FP_VSYNC_S) & 0x0000ffff) + 1; - p2->timing.v_sync_end = (DAC2R(FP_VSYNC_E) & 0x0000ffff) + 1; - p2->timing.v_total = (DAC2R(FP_VTOTAL) & 0x0000ffff) + 1; - /* sync polarity */ - p2->timing.flags = 0; - if (DAC2R(FP_TG_CTRL) & 0x00000001) p2->timing.flags |= B_POSITIVE_VSYNC; - if (DAC2R(FP_TG_CTRL) & 0x00000010) p2->timing.flags |= B_POSITIVE_HSYNC; - /* refreshrate */ - p2->timing.pixel_clock = (p2->timing.h_total * p2->timing.v_total * 60) / 1000; + /* timing ('modeline') */ + p2->timing = si->ps.p2_timing; /* setup the rest */ p2->space = B_CMAP8; p2->virtual_width = p2->timing.h_display; @@ -1213,14 +1227,14 @@ void dump_pins(void) LOG(2,("found DFP (digital flatpanel) on CRTC1; CRTC1 is ")); if (si->ps.slaved_tmds1) LOG(2,("slaved\n")); else LOG(2,("master\n")); LOG(2,("panel width: %d, height: %d, aspect ratio: %1.2f\n", - si->ps.panel1_width, si->ps.panel1_height, si->ps.panel1_aspect)); + si->ps.p1_timing.h_display, si->ps.p1_timing.v_display, si->ps.panel1_aspect)); } if (si->ps.tmds2_active) { LOG(2,("found DFP (digital flatpanel) on CRTC2; CRTC2 is ")); if (si->ps.slaved_tmds2) LOG(2,("slaved\n")); else LOG(2,("master\n")); LOG(2,("panel width: %d, height: %d, aspect ratio: %1.2f\n", - si->ps.panel2_width, si->ps.panel2_height, si->ps.panel2_aspect)); + si->ps.p2_timing.h_display, si->ps.p2_timing.v_display, si->ps.panel2_aspect)); } LOG(2,("monitor (output devices) setup matrix: $%02x\n", si->ps.monitors)); LOG(2,("INFO: end pinsdump.\n")); diff --git a/src/add-ons/accelerants/nvidia/engine/nv_proto.h b/src/add-ons/accelerants/nvidia/engine/nv_proto.h index 9bac930c04..e6ef3d34bc 100644 --- a/src/add-ons/accelerants/nvidia/engine/nv_proto.h +++ b/src/add-ons/accelerants/nvidia/engine/nv_proto.h @@ -30,7 +30,7 @@ status_t i2c_maven_probe(void); /*card info functions*/ status_t parse_pins(void); -void get_panel_modelines(display_mode *p1, display_mode *p2, bool *pan1, bool *pan2); +void get_panel_modes(display_mode *p1, display_mode *p2, bool *pan1, bool *pan2); void fake_pins(void); void dump_pins(void);