📄 cim_vg.c
字号:
!(temp & GP3_BS_CB_EMPTY))
{
;
}
/* SET THE DOT CLOCK FREQUENCY */
if (!(mode_params->flags & VG_MODEFLAG_EXCLUDEPLL))
{
if (mode_params->flags & VG_MODEFLAG_HALFCLOCK)
flags = VG_PLL_DIVIDE_BY_2;
else if (mode_params->flags & VG_MODEFLAG_QVGA)
flags = VG_PLL_DIVIDE_BY_4;
else
flags = 0;
/* ALLOW DOTREF TO BE USED AS THE PLL */
/* This is useful for some external TV encoders. */
if (mode_params->flags & VG_MODEFLAG_PLL_BYPASS)
flags |= VG_PLL_BYPASS;
/* ALLOW THE USER TO MANUALLY ENTER THE MSR VALUE */
if (mode_params->flags & VG_MODEFLAG_MANUAL_FREQUENCY)
flags |= VG_PLL_MANUAL;
if (mode_params->flags & VG_MODEFLAG_VIP_TO_DOT_CLOCK)
flags |= VG_PLL_VIP_CLOCK;
vg_set_clock_frequency (mode_params->frequency, flags);
}
/* CLEAR ALL BUFFER OFFSETS */
WRITE_REG32 (DC3_FB_ST_OFFSET, 0);
WRITE_REG32 (DC3_CB_ST_OFFSET, 0);
WRITE_REG32 (DC3_CURS_ST_OFFSET, 0);
genlk_ctl = READ_REG32 (DC3_GENLK_CTL) & ~(DC3_GC_ALPHA_FLICK_ENABLE |
DC3_GC_FLICKER_FILTER_ENABLE | DC3_GC_FLICKER_FILTER_MASK);
/* ENABLE INTERLACING */
if (mode_params->flags & VG_MODEFLAG_INTERLACED)
{
irq_ctl |= DC3_IRQFILT_INTL_EN;
if ((mode_params->flags & VG_MODEFLAG_INT_MASK) == VG_MODEFLAG_INT_ADDRESS)
irq_ctl |= DC3_IRQFILT_INTL_ADDR;
else if ((mode_params->flags & VG_MODEFLAG_INT_MASK) == VG_MODEFLAG_INT_FLICKER)
{
genlk_ctl |= DC3_GC_FLICKER_FILTER_1_8 | DC3_GC_FLICKER_FILTER_ENABLE |
DC3_GC_ALPHA_FLICK_ENABLE;
}
}
WRITE_REG32 (DC3_GFX_SCALE, (vscale << 16) | (hscale & 0xFFFF));
WRITE_REG32 (DC3_IRQ_FILT_CTL, irq_ctl);
WRITE_REG32 (DC3_GENLK_CTL, genlk_ctl);
/* SET LINE SIZE AND PITCH */
/* The line size and pitch are calculated from the src_width parameter */
/* passed in to this routine. All other parameters are ignored. */
/* The pitch is set either to a power of 2 to allow efficient */
/* compression or to a linear value to allow efficient memory management. */
switch (bpp)
{
case 8:
size = mode_params->src_width;
line_size = starting_width;
break;
case 12:
case 15:
case 16:
size = mode_params->src_width << 1;
line_size = starting_width << 1;
break;
case 24:
case 32:
default:
size = mode_params->src_width << 2;
line_size = starting_width << 2; break;
}
/* CALCULATE DV RAM SETTINGS AND POWER OF 2 PITCH */
pitch = 1024;
dv_size = DC3_DV_LINE_SIZE_1024;
if (size > 1024) { pitch = 2048; dv_size = DC3_DV_LINE_SIZE_2048; }
if (size > 2048) { pitch = 4096; dv_size = DC3_DV_LINE_SIZE_4096; }
if (size > 4096) { pitch = 8192; dv_size = DC3_DV_LINE_SIZE_8192; }
/* OVERRIDE SETTINGS FOR LINEAR PITCH */
if (mode_params->flags & VG_MODEFLAG_LINEARPITCH)
{
unsigned long max;
if (pitch != size)
{
/* CALCULATE MAXIMUM ADDRESS (1K ALIGNED) */
max = size * output_height;
max = (max + 0x3FF) & 0xFFFFFC00;
WRITE_REG32 (DC3_DV_TOP, max | DC3_DVTOP_ENABLE);
gcfg |= DC3_GCFG_FDTY;
pitch = size;
}
else
{
WRITE_REG32 (DC3_DV_TOP, 0);
}
}
/* WRITE PITCH AND DV RAM SETTINGS */
/* The DV RAM line length is programmed at a power of 2 boundary */
/* in case the user wants to toggle back to a power of 2 pitch */
/* later. It could happen... */
temp = READ_REG32 (DC3_DV_CTL);
WRITE_REG32 (DC3_GFX_PITCH, pitch >> 3);
WRITE_REG32 (DC3_DV_CTL, (temp & ~DC3_DV_LINE_SIZE_MASK) | dv_size);
/* SET THE LINE SIZE */
WRITE_REG32 (DC3_LINE_SIZE, (line_size + 7) >> 3);
/* ALWAYS ENABLE VIDEO AND GRAPHICS DATA */
/* These bits are relics from a previous design and */
/* should always be enabled. */
dcfg |= (DC3_DCFG_VDEN | DC3_DCFG_GDEN);
/* SET PIXEL FORMAT */
dcfg |= bpp_mask;
/* ENABLE TIMING GENERATOR, TIM. REG. UPDATES, PALETTE BYPASS */
/* AND VERT. INT. SELECT */
dcfg |= (unsigned long)(DC3_DCFG_TGEN | DC3_DCFG_TRUP | DC3_DCFG_PALB | DC3_DCFG_VISL);
/* SET FIFO PRIORITIES AND DISPLAY FIFO LOAD ENABLE */
/* Note that the bandwidth setting gets upgraded when scaling or flicker */
/* filtering are enabled, as they require more data throughput. */
msr_read64 (MSR_DEVICE_GEODELX_VG, DC3_SPARE_MSR, &msr_value);
msr_value.low &= ~(DC3_SPARE_DISABLE_CFIFO_HGO | DC3_SPARE_VFIFO_ARB_SELECT |
DC3_SPARE_LOAD_WM_LPEN_MASK | DC3_SPARE_WM_LPEN_OVRD |
DC3_SPARE_DISABLE_INIT_VID_PRI | DC3_SPARE_DISABLE_VFIFO_WM);
if ((mode_params->flags & VG_MODEFLAG_BANDWIDTHMASK) == VG_MODEFLAG_HIGH_BAND ||
((mode_params->flags & VG_MODEFLAG_INTERLACED) &&
(mode_params->flags & VG_MODEFLAG_INT_MASK) == VG_MODEFLAG_INT_FLICKER) ||
(irq_ctl & DC3_IRQFILT_GFX_FILT_EN))
{
/* HIGH BANDWIDTH */
/* Set agressive watermarks and disallow forced low priority */
gcfg |= 0x0000BA01;
dcfg |= 0x000EA000;
acfg = 0x001A0201;
msr_value.low |= DC3_SPARE_DISABLE_CFIFO_HGO | DC3_SPARE_VFIFO_ARB_SELECT |
DC3_SPARE_WM_LPEN_OVRD;
}
else if ((mode_params->flags & VG_MODEFLAG_BANDWIDTHMASK) == VG_MODEFLAG_AVG_BAND)
{
/* AVERAGE BANDWIDTH */
/* Set average watermarks and allow small regions of forced low priority. */
gcfg |= 0x0000B601;
dcfg |= 0x00009000;
acfg = 0x00160001;
msr_value.low |= DC3_SPARE_DISABLE_CFIFO_HGO | DC3_SPARE_VFIFO_ARB_SELECT |
DC3_SPARE_WM_LPEN_OVRD;
/* SET THE NUMBER OF LOW PRIORITY LINES TO 1/2 THE TOTAL AVAILABLE */
temp = ((READ_REG32 (DC3_V_ACTIVE_TIMING) >> 16) & 0x7FF) + 1;
temp -= (READ_REG32 (DC3_V_SYNC_TIMING) & 0x7FF) + 1;
temp >>= 1;
if (temp > 127)
temp = 127;
acfg |= temp << 9;
}
else if ((mode_params->flags & VG_MODEFLAG_BANDWIDTHMASK) == VG_MODEFLAG_LOW_BAND)
{
/* LOW BANDWIDTH */
/* Set low watermarks and allow larger regions of forced low priority. */
gcfg |= 0x00009501;
dcfg |= 0x00008000;
acfg = 0x00150001;
msr_value.low |= DC3_SPARE_DISABLE_CFIFO_HGO | DC3_SPARE_VFIFO_ARB_SELECT |
DC3_SPARE_WM_LPEN_OVRD;
/* SET THE NUMBER OF LOW PRIORITY LINES TO 3/4 THE TOTAL AVAILABLE */
temp = ((READ_REG32 (DC3_V_ACTIVE_TIMING) >> 16) & 0x7FF) + 1;
temp -= (READ_REG32 (DC3_V_SYNC_TIMING) & 0x7FF) + 1;
temp = (temp * 3) >> 2;
if (temp > 127)
temp = 127;
acfg |= temp << 9;
}
else
{
/* LEGACY CHARACTERISTICS */
/* Arbitration from a single set of watermarks. */
gcfg |= 0x0000B601;
msr_value.low |= DC3_SPARE_DISABLE_VFIFO_WM | DC3_SPARE_DISABLE_INIT_VID_PRI;
acfg = 0;
}
msr_write64 (MSR_DEVICE_GEODELX_VG, DC3_SPARE_MSR, &msr_value);
/* ENABLE FLAT PANEL CENTERING */
/* For panel modes having a resolution smaller than the */
/* panel resolution, turn on data centering. */
if (mode_params->flags & VG_MODEFLAG_CENTERED)
dcfg |= DC3_DCFG_DCEN;
/* COMBINE AND SET TIMING VALUES */
temp = (mode_params->hactive - 1) | ((mode_params->htotal - 1) << 16);
WRITE_REG32(DC3_H_ACTIVE_TIMING, temp);
temp = (mode_params->hblankstart - 1) | ((mode_params->hblankend - 1) << 16);
WRITE_REG32(DC3_H_BLANK_TIMING, temp);
temp = (mode_params->hsyncstart - 1) | ((mode_params->hsyncend - 1) << 16);
WRITE_REG32(DC3_H_SYNC_TIMING, temp);
temp = (mode_params->vactive - 1) | ((mode_params->vtotal - 1) << 16);
WRITE_REG32(DC3_V_ACTIVE_TIMING, temp);
temp = (mode_params->vblankstart - 1) | ((mode_params->vblankend - 1) << 16);
WRITE_REG32(DC3_V_BLANK_TIMING, temp);
temp = (mode_params->vsyncstart - 1) | ((mode_params->vsyncend - 1) << 16);
WRITE_REG32(DC3_V_SYNC_TIMING, temp);
temp = (mode_params->vactive_even - 1) | ((mode_params->vtotal_even - 1) << 16);
WRITE_REG32(DC3_V_ACTIVE_EVEN, temp);
temp = (mode_params->vblankstart_even - 1) | ((mode_params->vblankend_even - 1) << 16);
WRITE_REG32(DC3_V_BLANK_EVEN, temp);
temp = (mode_params->vsyncstart_even - 1) | ((mode_params->vsyncend_even - 1) << 16);
WRITE_REG32(DC3_V_SYNC_EVEN, temp);
/* SET THE VIDEO REQUEST REGISTER */
WRITE_VID32 (DF_VIDEO_REQUEST, 0);
/* SET SOURCE DIMENSIONS */
WRITE_REG32 (DC3_FB_ACTIVE, ((starting_width - 1) << 16) |
(starting_height - 1));
/* SET SYNC POLARITIES */
temp = READ_VID32 (DF_DISPLAY_CONFIG);
temp &= ~(DF_DCFG_CRT_SYNC_SKW_MASK | DF_DCFG_PWR_SEQ_DLY_MASK |
DF_DCFG_CRT_HSYNC_POL | DF_DCFG_CRT_VSYNC_POL);
temp |= (DF_DCFG_CRT_SYNC_SKW_INIT |
DF_DCFG_PWR_SEQ_DLY_INIT |
DF_DCFG_GV_PAL_BYP);
if (mode_params->flags & VG_MODEFLAG_NEG_HSYNC)
temp |= DF_DCFG_CRT_HSYNC_POL;
if (mode_params->flags & VG_MODEFLAG_NEG_VSYNC)
temp |= DF_DCFG_CRT_VSYNC_POL;
WRITE_VID32 (DF_DISPLAY_CONFIG, temp);
WRITE_REG32 (DC3_DISPLAY_CFG, dcfg);
WRITE_REG32 (DC3_ARB_CFG, acfg);
WRITE_REG32 (DC3_GENERAL_CFG, gcfg);
/* RESTORE VALUE OF DC3_UNLOCK */
WRITE_REG32(DC3_UNLOCK, unlock);
return CIM_STATUS_OK;
}
/*---------------------------------------------------------------------------
* vg_set_bpp
*
* This routine changes the display BPP on the fly. It is intended only to
* switch between pixel depths of the same pixel size 24<->32 or 15<->16, NOT
* between pixel depths of differing sizes 16<->32
*---------------------------------------------------------------------------*/
int vg_set_display_bpp (int bpp)
{
unsigned long unlock, dcfg, bpp_mask;
switch (bpp)
{
case 8: bpp_mask = DC3_DCFG_DISP_MODE_8BPP; break;
case 24: bpp_mask = DC3_DCFG_DISP_MODE_24BPP; break;
case 32: bpp_mask = DC3_DCFG_DISP_MODE_32BPP; break;
case 12: bpp_mask = DC3_DCFG_DISP_MODE_16BPP | DC3_DCFG_12BPP; break;
case 15: bpp_mask = DC3_DCFG_DISP_MODE_16BPP | DC3_DCFG_15BPP; break;
case 16: bpp_mask = DC3_DCFG_DISP_MODE_16BPP | DC3_DCFG_16BPP; break;
default: return CIM_STATUS_INVALIDPARAMS;
}
unlock = READ_REG32 (DC3_UNLOCK);
dcfg = READ_REG32 (DC3_DISPLAY_CFG) & ~(DC3_DCFG_DISP_MODE_MASK | DC3_DCFG_16BPP_MODE_MASK);
dcfg |= bpp_mask;
WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
WRITE_REG32 (DC3_DISPLAY_CFG, dcfg);
WRITE_REG32 (DC3_UNLOCK, unlock);
return CIM_STATUS_OK;
}
/*---------------------------------------------------------------------------
* vg_get_display_mode_index
*
* This routine searches the Cimarron mode table for a mode that matches the
* input parameters. If a match is found, the return value is the index into
* the mode table. If no match is found, the return value is -1.
*---------------------------------------------------------------------------*/
int vg_get_display_mode_index (VG_QUERY_MODE *query)
{
unsigned int mode;
unsigned long hz_flag = 0xFFFFFFFF;
unsigned long bpp_flag = 0xFFFFFFFF;
unsigned long enc_flag = 0xFFFFFFFF;
unsigned long tv_flag = 0;
unsigned long interlaced = 0;
unsigned long halfclock = 0;
long minimum = 0x7FFFFFFF;
long diff;
int match = -1;
if (!query || !query->query_flags)
return -1;
if (query->query_flags & VG_QUERYFLAG_REFRESH)
{
/* SET FLAGS TO MATCH REFRESH RATE */
if (query->hz == 56) hz_flag = VG_SUPPORTFLAG_56HZ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -