⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 proposedisplaymode.c

📁 ati driver
💻 C
📖 第 1 页 / 共 2 页
字号:
/*	Copyright (c) 2002, Thomas Kurschel		Part of Radeon accelerant			Everything concerning getting/testing display modes*/#include "radeon_accelerant.h"#include "generic.h"#include <string.h>#include "GlobalData.h"#include "../regs/crtc_regs.h"#include "../common/utils.h"#include "set_mode.h"// standard mode list// all drivers contain this list - this should really be moved to// something like the screen preferences panel#define	T_POSITIVE_SYNC	(B_POSITIVE_HSYNC | B_POSITIVE_VSYNC)#define MODE_FLAGS	(B_8_BIT_DAC | B_HARDWARE_CURSOR | B_PARALLEL_ACCESS | B_DPMS | B_SUPPORTS_OVERLAYS)//#define MODE_COUNT (sizeof (mode_list) / sizeof (display_mode))static const display_mode base_mode_list[] = {// test for PAL//{ { 25175, 640, 656, 752, 816, 480, 490, 492, 625, 0}, B_CMAP8, 640, 480, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@60Hz_(640X480X8.Z1) */// test for NTSC//{ { 43956, 800, 824, 952, 992, 600, 632, 635, 740, T_POSITIVE_SYNC}, B_CMAP8, 800, 600, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@60Hz_(800X600X8.Z1) */{ { 25175, 640, 656, 752, 800, 480, 490, 492, 525, 0}, B_CMAP8, 640, 480, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@60Hz_(640X480X8.Z1) */{ { 27500, 640, 672, 768, 864, 480, 488, 494, 530, 0}, B_CMAP8, 640, 480, 0, 0, MODE_FLAGS}, /* 640X480X60Hz */{ { 30500, 640, 672, 768, 864, 480, 517, 523, 588, 0}, B_CMAP8, 640, 480, 0, 0, MODE_FLAGS}, /* SVGA_640X480X60HzNI */{ { 31500, 640, 664, 704, 832, 480, 489, 492, 520, 0}, B_CMAP8, 640, 480, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@70-72Hz_(640X480X8.Z1) */{ { 31500, 640, 656, 720, 840, 480, 481, 484, 500, 0}, B_CMAP8, 640, 480, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@75Hz_(640X480X8.Z1) */{ { 36000, 640, 696, 752, 832, 480, 481, 484, 509, 0}, B_CMAP8, 640, 480, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@85Hz_(640X480X8.Z1) */{ { 25175, 640, 656, 752, 800, 400, 412, 414, 449, B_POSITIVE_VSYNC}, B_CMAP8, 640, 400, 0, 0, MODE_FLAGS}, /* 640x400 - www.epanorama.net/documents/pc/vga_timing.html) */{ { 25175, 640, 656, 752, 800, 350, 387, 389, 449, B_POSITIVE_HSYNC}, B_CMAP8, 640, 350, 0, 0, MODE_FLAGS}, /* 640x350 - www.epanorama.net/documents/pc/vga_timing.html) */// NTSC non-isometric resolution (isometric resolution is 640x480){ { 26720, 720, 736, 808, 896, 480, 481, 484, 497, B_POSITIVE_VSYNC}, B_CMAP8, 720, 480, 0, 0, MODE_FLAGS},	/* 720x480@60Hz according to GMTF */// PAL resolutions{ { 26570, 720, 736, 808, 896, 576, 577, 580, 593, B_POSITIVE_VSYNC}, B_CMAP8, 720, 576, 0, 0, MODE_FLAGS},	/* 720x576@50Hz according to GMTF */{ { 28460, 768, 784, 864, 960, 576, 577, 580, 593, B_POSITIVE_VSYNC}, B_CMAP8, 768, 576, 0, 0, MODE_FLAGS},	/* 768x576@50Hz according to GMTF */{ { 38100, 800, 832, 960, 1088, 600, 602, 606, 620, 0}, B_CMAP8, 800, 600, 0, 0, MODE_FLAGS}, /* SVGA_800X600X56HzNI */{ { 40000, 800, 840, 968, 1056, 600, 601, 605, 628, T_POSITIVE_SYNC}, B_CMAP8, 800, 600, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@60Hz_(800X600X8.Z1) */{ { 49500, 800, 816, 896, 1056, 600, 601, 604, 625, T_POSITIVE_SYNC}, B_CMAP8, 800, 600, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@75Hz_(800X600X8.Z1) */{ { 50000, 800, 856, 976, 1040, 600, 637, 643, 666, T_POSITIVE_SYNC}, B_CMAP8, 800, 600, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@70-72Hz_(800X600X8.Z1) */{ { 56250, 800, 832, 896, 1048, 600, 601, 604, 631, T_POSITIVE_SYNC}, B_CMAP8, 800, 600, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@85Hz_(800X600X8.Z1) */{ { 65000, 1024, 1048, 1184, 1344, 768, 771, 777, 806, 0}, B_CMAP8, 1024, 768, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@60Hz_(1024X768X8.Z1) */{ { 75000, 1024, 1048, 1184, 1328, 768, 771, 777, 806, 0}, B_CMAP8, 1024, 768, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@70-72Hz_(1024X768X8.Z1) */{ { 78750, 1024, 1040, 1136, 1312, 768, 769, 772, 800, T_POSITIVE_SYNC}, B_CMAP8, 1024, 768, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@75Hz_(1024X768X8.Z1) */{ { 94500, 1024, 1072, 1168, 1376, 768, 769, 772, 808, T_POSITIVE_SYNC}, B_CMAP8, 1024, 768, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@85Hz_(1024X768X8.Z1) */{ { 94200, 1152, 1184, 1280, 1472, 864, 865, 868, 914, T_POSITIVE_SYNC}, B_CMAP8, 1152, 864, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@70Hz_(1152X864X8.Z1) */{ { 108000, 1152, 1216, 1344, 1600, 864, 865, 868, 900, T_POSITIVE_SYNC}, B_CMAP8, 1152, 864, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@75Hz_(1152X864X8.Z1) */{ { 121500, 1152, 1216, 1344, 1568, 864, 865, 868, 911, T_POSITIVE_SYNC}, B_CMAP8, 1152, 864, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@85Hz_(1152X864X8.Z1) */{ { 108000, 1280, 1376, 1488, 1800, 960, 961, 964, 1000, T_POSITIVE_SYNC}, B_CMAP8, 1152, 864, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@60Hz_(1280X960X8.Z1) - not in Be's list */{ { 148500, 1280, 1344, 1504, 1728, 960, 961, 964, 1011, T_POSITIVE_SYNC}, B_CMAP8, 1152, 864, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@85Hz_(1280X960X8.Z1) - not in Be's list */{ { 108000, 1280, 1328, 1440, 1688, 1024, 1025, 1028, 1066, T_POSITIVE_SYNC}, B_CMAP8, 1280, 1024, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@60Hz_(1280X1024X8.Z1) */{ { 135000, 1280, 1296, 1440, 1688, 1024, 1025, 1028, 1066, T_POSITIVE_SYNC}, B_CMAP8, 1280, 1024, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@75Hz_(1280X1024X8.Z1) */{ { 157500, 1280, 1344, 1504, 1728, 1024, 1025, 1028, 1072, T_POSITIVE_SYNC}, B_CMAP8, 1280, 1024, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@85Hz_(1280X1024X8.Z1) */{ { 162000, 1600, 1664, 1856, 2160, 1200, 1201, 1204, 1250, T_POSITIVE_SYNC}, B_CMAP8, 1600, 1200, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@60Hz_(1600X1200X8.Z1) */{ { 175500, 1600, 1664, 1856, 2160, 1200, 1201, 1204, 1250, T_POSITIVE_SYNC}, B_CMAP8, 1600, 1200, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@65Hz_(1600X1200X8.Z1) */{ { 189000, 1600, 1664, 1856, 2160, 1200, 1201, 1204, 1250, T_POSITIVE_SYNC}, B_CMAP8, 1600, 1200, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@70Hz_(1600X1200X8.Z1) */{ { 202500, 1600, 1664, 1856, 2160, 1200, 1201, 1204, 1250, T_POSITIVE_SYNC}, B_CMAP8, 1600, 1200, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@75Hz_(1600X1200X8.Z1) */{ { 216000, 1600, 1664, 1856, 2160, 1200, 1201, 1204, 1250, T_POSITIVE_SYNC}, B_CMAP8, 1600, 1200, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@80Hz_(1600X1200X8.Z1) */{ { 229500, 1600, 1664, 1856, 2160, 1200, 1201, 1204, 1250, T_POSITIVE_SYNC}, B_CMAP8, 1600, 1200, 0, 0, MODE_FLAGS}  /* Vesa_Monitor_@85Hz_(1600X1200X8.Z1) */};// convert Be colour space to Radeon data type// returns true, if supported colour space//	space - Be colour space//	format - (out) Radeon data type//	bpp - (out) bytes per pixelbool Radeon_GetFormat( int space, int *format, int *bpp ){	switch( space ) {    /*case 4:  format = 1; bytpp = 0; break;*/    case B_CMAP8:  *format = 2; *bpp = 1; break;    case B_RGB15_LITTLE: *format = 3; *bpp = 2; break;      /*  555 */    case B_RGB16_LITTLE: *format = 4; *bpp = 2; break;      /*  565 */    case B_RGB24_LITTLE: *format = 5; *bpp = 3; break;      /*  RGB */    case B_RGB32_LITTLE: *format = 6; *bpp = 4; break;      /* xRGB */    default:		SHOW_ERROR( 1, "Unsupported color space (%d)", space );		return false;    }        return true;}// macros to convert between register values and pixels#define H_DISPLAY_2REG( a ) ((a) / 8 - 1)#define H_DISPLAY_2PIX( a ) (((a) + 1) * 8)#define H_TOTAL_2REG( a ) ((a) / 8 - 1)#define H_TOTAL_2PIX( a ) (((a) + 1) * 8)#define H_SSTART_2REG( a ) ((a) - 8 + h_sync_fudge)#define H_SSTART_2PIX( a ) ((a) + 8 - h_sync_fudge)#define H_SWID_2REG( a ) ((a) / 8)#define H_SWID_2PIX( a ) ((a) * 8)#define V_2REG( a ) ((a) - 1)#define V_2PIX( a ) ((a) + 1)/*	Validate a target display mode is both		a) a valid display mode for this device and		b) falls between the contraints imposed by "low" and "high"		If the mode is not (or cannot) be made valid for this device, return B_ERROR.	If a valid mode can be constructed, but it does not fall within the limits,	 return B_BAD_VALUE.	If the mode is both valid AND falls within the limits, return B_OK.*/status_t Radeon_ProposeDisplayMode( 	shared_info *si, crtc_info *crtc, 	general_pll_info *pll, display_mode *target, 	const display_mode *low, const display_mode *high ){	status_t result = B_OK;		uint64 target_refresh;	bool want_same_width, want_same_height;	int format, bpp;	uint32 row_bytes;	int eff_virtual_width;	fp_info *flatpanel = &si->flatpanels[crtc->flatpanel_port];	// save refresh rate - we want to leave this (artifical) value untouched	// don't use floating point, we are in kernel mode	target_refresh = 		(((uint64)target->timing.pixel_clock * 1000) << FIX_SHIFT) / 		((uint64)target->timing.h_total * target->timing.v_total);			want_same_width = target->timing.h_display == target->virtual_width;	want_same_height = target->timing.v_display == target->virtual_height;		if( !Radeon_GetFormat( target->space, &format, &bpp ))		return B_ERROR;			// 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( target->timing.h_display > flatpanel->panel_xres )			target->timing.h_display = flatpanel->panel_xres;				if(	target->timing.v_display > flatpanel->panel_yres )			target->timing.v_display = flatpanel->panel_yres;	}/*	// the TV-Out encoder can "only" handle up to 1024x768	if( (head->chosen_displays & (dd_ctv | dd_stv)) != 0 ) {		if( target->timing.h_display > 1024 )			target->timing.h_display = 1024;				if(	target->timing.v_display > 768 )			target->timing.v_display = 768;	}*/					// validate horizontal timings	{		int h_sync_fudge, h_display, h_sync_start, h_sync_wid, h_total;					h_display = target->timing.h_display;		h_sync_fudge = Radeon_GetHSyncFudge( crtc, format );		h_sync_start = target->timing.h_sync_start;		h_sync_wid = target->timing.h_sync_end - target->timing.h_sync_start;		h_total = target->timing.h_total;		// make sure, display is not too small 		// (I reckon Radeon doesn't care, but your monitor probably does)		if( h_display < 320 ) 			h_display = 320;		// apply hardware restrictions		// as h_display is the smallest register, it's always possible 		// to adjust other values to keep them in supported range		if( h_display > H_DISPLAY_2PIX( RADEON_CRTC_H_DISP >> RADEON_CRTC_H_DISP_SHIFT ) )			h_display = H_DISPLAY_2PIX( RADEON_CRTC_H_DISP >> RADEON_CRTC_H_DISP_SHIFT );		// round properly		h_display = H_DISPLAY_2PIX( H_DISPLAY_2REG( h_display ));					// ensure minimum time before sync		if( h_sync_start < h_display + 2*8 )			h_sync_start = h_display + 2*8;		// sync has wider range than display are, so we won't collide there,		// but total width has same range as sync start, so leave some space		if( h_sync_start > H_SSTART_2PIX( RADEON_CRTC_H_SYNC_STRT_CHAR | RADEON_CRTC_H_SYNC_STRT_PIX ) - 4*8 )			h_sync_start = H_SSTART_2PIX( RADEON_CRTC_H_SYNC_STRT_CHAR | RADEON_CRTC_H_SYNC_STRT_PIX ) - 4*8;		// ensure minimum sync length		if( h_sync_wid < H_SWID_2PIX( 3 ))			h_sync_wid = H_SWID_2PIX( 3 );		// allowed range is quite small, so make sure sync isn't too long		if( h_sync_wid > H_SWID_2PIX( RADEON_CRTC_H_SYNC_WID >> RADEON_CRTC_H_SYNC_WID_SHIFT ) )			h_sync_wid = H_SWID_2PIX( RADEON_CRTC_H_SYNC_WID >> RADEON_CRTC_H_SYNC_WID_SHIFT );		// round properly		h_sync_wid = H_SWID_2PIX( H_SWID_2REG( h_sync_wid ));		// last but not least adapt total width		// "+7" is needed for rounding up: sync_start isn't rounded, but h_total is		if( h_total < h_sync_start + h_sync_wid + 1*8 + 7 )			h_total = h_sync_start + h_sync_wid + 1*8 + 7;		// we may get a too long total width; this can only happen 		// because sync is too long, so truncate sync accordingly		if( h_total > H_TOTAL_2PIX( RADEON_CRTC_H_TOTAL ) ) {			h_total = H_TOTAL_2PIX( RADEON_CRTC_H_TOTAL );			h_sync_wid = min( h_sync_wid, h_total - h_sync_start );			h_sync_wid = H_SWID_2PIX( H_SWID_2REG( h_sync_wid ));		}		// round properly		h_total = H_TOTAL_2PIX( H_TOTAL_2REG( h_total ));		target->timing.h_display = h_display;		target->timing.h_sync_start = h_sync_start;		target->timing.h_sync_end = h_sync_start + h_sync_wid;		target->timing.h_total = h_total;	}	// did we fall out of one of the limits?	if( target->timing.h_display < low->timing.h_display ||		target->timing.h_display > high->timing.h_display ||		target->timing.h_sync_start < low->timing.h_sync_start ||		target->timing.h_sync_start > high->timing.h_sync_start ||		target->timing.h_sync_end < low->timing.h_sync_end ||		target->timing.h_sync_end > high->timing.h_sync_end ||		target->timing.h_total < low->timing.h_total ||		target->timing.h_total > high->timing.h_total) 	{		SHOW_FLOW0( 4, "out of horizontal limits" );		result = B_BAD_VALUE;	}	// validate vertical timings	{		int v_display, v_sync_start, v_sync_wid, v_total;				v_display = target->timing.v_display;		v_sync_start = target->timing.v_sync_start;		v_sync_wid = target->timing.v_sync_end - target->timing.v_sync_start;		v_total = target->timing.v_total;		// apply a reasonable minimal height to make monitor happy		if( v_display < 200 )			v_display = 200;		// apply limits but make sure we have enough lines left for blank and sync		if( v_display > V_2PIX(RADEON_CRTC_V_DISP >> RADEON_CRTC_V_DISP_SHIFT) - 5)			v_display = V_2PIX(RADEON_CRTC_V_DISP >> RADEON_CRTC_V_DISP_SHIFT) - 5;		// leave at least one line before sync		// (some flat panel have zero gap here; probably, this leads to		// the infamous bright line at top of screen)		if( v_sync_start < v_display + 1 )			v_sync_start = v_display + 1;		// apply hardware limit and leave some lines for sync		if( v_sync_start > V_2PIX(RADEON_CRTC_V_SYNC_STRT) - 4)			v_sync_start = V_2PIX(RADEON_CRTC_V_SYNC_STRT) - 4;		// don't make sync too short		if( v_sync_wid < 2 )			v_sync_wid = 2;		// sync width is quite restricted		if( v_sync_wid > (RADEON_CRTC_V_SYNC_WID >> RADEON_CRTC_V_SYNC_WID_SHIFT))			v_sync_wid = (RADEON_CRTC_V_SYNC_WID >> RADEON_CRTC_V_SYNC_WID_SHIFT);		// leave a gap of at least 1 line		if( v_total < v_sync_start + v_sync_wid + 1 )			v_total = v_sync_start + v_sync_wid + 1;		// if too long, truncate it and adapt sync len		if( v_total > V_2PIX( RADEON_CRTC_V_TOTAL ) ) {			v_total = V_2PIX( RADEON_CRTC_V_TOTAL );			v_sync_wid = min( v_sync_wid, v_total - v_sync_start - 4 );		}		target->timing.v_display = v_display;		target->timing.v_sync_start = v_sync_start;		target->timing.v_sync_end = v_sync_start + v_sync_wid;		target->timing.v_total = v_total;	}	// did we fall out of one of the limits?	if(	target->timing.v_display < low->timing.v_display ||		target->timing.v_display > high->timing.v_display ||		target->timing.v_sync_start < low->timing.v_sync_start ||		target->timing.v_sync_start > high->timing.h_sync_start ||		target->timing.v_sync_end < low->timing.v_sync_end ||		target->timing.v_sync_end > high->timing.v_sync_end ||		target->timing.v_total < low->timing.v_total ||		target->timing.v_total > high->timing.v_total ) 	{		SHOW_FLOW0( 4, "out of vertical limits" );		result = B_BAD_VALUE;	}	// restore whished refresh rate	target->timing.pixel_clock = 		((uint64)target_refresh / 1000 * target->timing.h_total * target->timing.v_total + FIX_SCALE / 2) 		>> FIX_SHIFT;	// apply PLL restrictions	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, 			pll->max_pll_freq * 10, pll->min_pll_freq / 12 );		return B_ERROR;	}	// make sure virtual_size > visible_size	// additionally, restore virtual_size == visible_size if it was so on entry	if ((target->timing.h_display > target->virtual_width) || want_same_width)		target->virtual_width = target->timing.h_display;	if ((target->timing.v_display > target->virtual_height) || want_same_height)		target->virtual_height = target->timing.v_display;	// TBD: limit is taken from XFree86	// this is probably a CRTC limit; don't know about the accelerator limit (if any)	// h_display can be at most 512*8, so we don't risk h_virtual < h_display 	// after applying this restriction	if (target->virtual_width > 1024*8)		target->virtual_width = 1024*8;	if (target->virtual_width < low->virtual_width ||		target->virtual_width > high->virtual_width )	{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -