cim_df.c revision 7aef237f
1f29dbc25Smrg/* 2f29dbc25Smrg * Copyright (c) 2006 Advanced Micro Devices, Inc. 3f29dbc25Smrg * 4f29dbc25Smrg * Permission is hereby granted, free of charge, to any person obtaining a 5f29dbc25Smrg * copy of this software and associated documentation files (the "Software"), 6f29dbc25Smrg * to deal in the Software without restriction, including without limitation 7f29dbc25Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8f29dbc25Smrg * and/or sell copies of the Software, and to permit persons to whom the 9f29dbc25Smrg * Software is furnished to do so, subject to the following conditions: 10f29dbc25Smrg * 11f29dbc25Smrg * The above copyright notice and this permission notice shall be included in 12f29dbc25Smrg * all copies or substantial portions of the Software. 13f29dbc25Smrg * 14f29dbc25Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15f29dbc25Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16f29dbc25Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17f29dbc25Smrg * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18f29dbc25Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19f29dbc25Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20f29dbc25Smrg * DEALINGS IN THE SOFTWARE. 21f29dbc25Smrg * 22f29dbc25Smrg * Neither the name of the Advanced Micro Devices, Inc. nor the names of its 23f29dbc25Smrg * contributors may be used to endorse or promote products derived from this 24f29dbc25Smrg * software without specific prior written permission. 25f29dbc25Smrg */ 26f29dbc25Smrg 27f29dbc25Smrg /* 28f29dbc25Smrg * Cimarron display filter routines. These routines program the video 29f29dbc25Smrg * hardware. 30f29dbc25Smrg */ 31f29dbc25Smrg 32f29dbc25Smrg/*--------------------------------------------------------------------------- 33f29dbc25Smrg * df_set_crt_enable 34f29dbc25Smrg * 35f29dbc25Smrg * This routine enables or disables CRT output. 36f29dbc25Smrg *--------------------------------------------------------------------------*/ 37f29dbc25Smrg 38f29dbc25Smrgint 39f29dbc25Smrgdf_set_crt_enable(int crt_output) 40f29dbc25Smrg{ 41f29dbc25Smrg unsigned long config, misc; 42f29dbc25Smrg 43f29dbc25Smrg config = READ_VID32(DF_DISPLAY_CONFIG); 44f29dbc25Smrg misc = READ_VID32(DF_VID_MISC); 45f29dbc25Smrg 46f29dbc25Smrg switch (crt_output) { 47f29dbc25Smrg /* DISABLE DISPLAY */ 48f29dbc25Smrg 49f29dbc25Smrg case DF_CRT_DISABLE: 50f29dbc25Smrg 51f29dbc25Smrg config &= ~(DF_DCFG_DIS_EN | DF_DCFG_HSYNC_EN | 52f29dbc25Smrg DF_DCFG_VSYNC_EN | DF_DCFG_DAC_BL_EN); 53f29dbc25Smrg misc |= DF_DAC_POWER_DOWN; 54f29dbc25Smrg break; 55f29dbc25Smrg 56f29dbc25Smrg /* ENABLE THE DISPLAY */ 57f29dbc25Smrg 58f29dbc25Smrg case DF_CRT_ENABLE: 59f29dbc25Smrg 60f29dbc25Smrg config |= (DF_DCFG_DIS_EN | DF_DCFG_HSYNC_EN | 61f29dbc25Smrg DF_DCFG_VSYNC_EN | DF_DCFG_DAC_BL_EN); 62f29dbc25Smrg misc &= ~(DF_DAC_POWER_DOWN | DF_ANALOG_POWER_DOWN); 63f29dbc25Smrg break; 64f29dbc25Smrg 65f29dbc25Smrg /* HSYNC:OFF VSYNC:ON */ 66f29dbc25Smrg 67f29dbc25Smrg case DF_CRT_STANDBY: 68f29dbc25Smrg 69f29dbc25Smrg config = (config & ~(DF_DCFG_DIS_EN | DF_DCFG_HSYNC_EN | 70f29dbc25Smrg DF_DCFG_DAC_BL_EN)) | DF_DCFG_VSYNC_EN; 71f29dbc25Smrg misc |= DF_DAC_POWER_DOWN; 72f29dbc25Smrg break; 73f29dbc25Smrg 74f29dbc25Smrg /* HSYNC:ON VSYNC:OFF */ 75f29dbc25Smrg 76f29dbc25Smrg case DF_CRT_SUSPEND: 77f29dbc25Smrg 78f29dbc25Smrg config = (config & ~(DF_DCFG_DIS_EN | DF_DCFG_VSYNC_EN | 79f29dbc25Smrg DF_DCFG_DAC_BL_EN)) | DF_DCFG_HSYNC_EN; 80f29dbc25Smrg misc |= DF_DAC_POWER_DOWN; 81f29dbc25Smrg break; 82f29dbc25Smrg 83f29dbc25Smrg default: 84f29dbc25Smrg return CIM_STATUS_INVALIDPARAMS; 85f29dbc25Smrg } 86f29dbc25Smrg 87f29dbc25Smrg WRITE_VID32(DF_DISPLAY_CONFIG, config); 88f29dbc25Smrg WRITE_VID32(DF_VID_MISC, misc); 89f29dbc25Smrg 90f29dbc25Smrg return CIM_STATUS_OK; 91f29dbc25Smrg} 92f29dbc25Smrg 93f29dbc25Smrg/*--------------------------------------------------------------------------- 94f29dbc25Smrg * df_set_panel_enable 95f29dbc25Smrg * 96f29dbc25Smrg * This routine enables or disables panel output. 97f29dbc25Smrg *--------------------------------------------------------------------------*/ 98f29dbc25Smrg 99f29dbc25Smrgint 100f29dbc25Smrgdf_set_panel_enable(int enable) 101f29dbc25Smrg{ 102f29dbc25Smrg unsigned long pm; 103f29dbc25Smrg 104f29dbc25Smrg pm = READ_VID32(DF_POWER_MANAGEMENT); 105f29dbc25Smrg 106f29dbc25Smrg if (enable) 107f29dbc25Smrg pm |= DF_PM_PANEL_ON; 108f29dbc25Smrg else 109f29dbc25Smrg pm &= ~DF_PM_PANEL_ON; 110f29dbc25Smrg 111f29dbc25Smrg WRITE_VID32(DF_POWER_MANAGEMENT, pm); 112f29dbc25Smrg 113f29dbc25Smrg return CIM_STATUS_OK; 114f29dbc25Smrg} 115f29dbc25Smrg 116f29dbc25Smrg/*--------------------------------------------------------------------------- 117f29dbc25Smrg * df_configure_video_source 118f29dbc25Smrg * 119f29dbc25Smrg * This routine initializes all aspects of the source buffer for a video overlay. 120f29dbc25Smrg *--------------------------------------------------------------------------*/ 121f29dbc25Smrg 122f29dbc25Smrgint 123f29dbc25Smrgdf_configure_video_source(DF_VIDEO_SOURCE_PARAMS * video_source_odd, 124f29dbc25Smrg DF_VIDEO_SOURCE_PARAMS * video_source_even) 125f29dbc25Smrg{ 126f29dbc25Smrg unsigned long pitch, ctrl, vcfg; 127f29dbc25Smrg unsigned long lock, vg_line, gcfg; 128f29dbc25Smrg unsigned long width, size, scale; 129f29dbc25Smrg unsigned long misc; 130f29dbc25Smrg 131f29dbc25Smrg lock = READ_REG32(DC3_UNLOCK); 132f29dbc25Smrg vg_line = READ_REG32(DC3_LINE_SIZE); 133f29dbc25Smrg gcfg = READ_REG32(DC3_GENERAL_CFG); 134f29dbc25Smrg vcfg = READ_VID32(DF_VIDEO_CONFIG); 135f29dbc25Smrg ctrl = READ_VID32(DF_VID_ALPHA_CONTROL); 136f29dbc25Smrg scale = READ_VID32(DF_VIDEO_SCALER); 137f29dbc25Smrg 138f29dbc25Smrg /* STORE THE DESIRED SCALING PROCEDURE */ 139f29dbc25Smrg /* Cimarron supports two modes when programming the scale and position */ 140f29dbc25Smrg /* of the video window. The first mode is designed to implicitly apply */ 141f29dbc25Smrg /* the graphics scale to any video operations. The second applys the */ 142f29dbc25Smrg /* video unchanged, allowing complete control by the user. To allow */ 143f29dbc25Smrg /* visibility between modules, the current mode is stored in a spare */ 144f29dbc25Smrg /* bit in the DF miscellaneous register. */ 145f29dbc25Smrg 146f29dbc25Smrg misc = READ_VID32(DF_VID_MISC); 147f29dbc25Smrg if (video_source_odd->flags & DF_SOURCEFLAG_IMPLICITSCALING) 148f29dbc25Smrg misc |= DF_USER_IMPLICIT_SCALING; 149f29dbc25Smrg else 150f29dbc25Smrg misc &= DF_USER_IMPLICIT_SCALING; 151f29dbc25Smrg WRITE_VID32(DF_VID_MISC, misc); 152f29dbc25Smrg 153f29dbc25Smrg /* PARAMETER - VIDEO PITCH */ 154f29dbc25Smrg 155f29dbc25Smrg pitch = 156f29dbc25Smrg (video_source_odd->y_pitch >> 3) | ((video_source_odd-> 157f29dbc25Smrg uv_pitch >> 3) << 16); 158f29dbc25Smrg 159f29dbc25Smrg /* PARAMETER - VIDEO FORMAT */ 160f29dbc25Smrg 161f29dbc25Smrg gcfg &= ~DC3_GCFG_YUV_420; 162f29dbc25Smrg vcfg &= ~(DF_VCFG_VID_INP_FORMAT | DF_VCFG_4_2_0_MODE); 163f29dbc25Smrg ctrl &= ~(DF_VIDEO_INPUT_IS_RGB | DF_CSC_VIDEO_YUV_TO_RGB | DF_HD_VIDEO | 164f29dbc25Smrg DF_YUV_CSC_EN); 165f29dbc25Smrg 166f29dbc25Smrg /* SELECT PIXEL ORDERING */ 167f29dbc25Smrg 168f29dbc25Smrg switch (video_source_odd->video_format & 3) { 169f29dbc25Smrg case 0: 170f29dbc25Smrg vcfg |= DF_VCFG_UYVY_FORMAT; 171f29dbc25Smrg break; 172f29dbc25Smrg case 1: 173f29dbc25Smrg vcfg |= DF_VCFG_Y2YU_FORMAT; 174f29dbc25Smrg break; 175f29dbc25Smrg case 2: 176f29dbc25Smrg vcfg |= DF_VCFG_YUYV_FORMAT; 177f29dbc25Smrg break; 178f29dbc25Smrg case 3: 179f29dbc25Smrg vcfg |= DF_VCFG_YVYU_FORMAT; 180f29dbc25Smrg break; 181f29dbc25Smrg } 182f29dbc25Smrg 183f29dbc25Smrg /* SELECT SOURCE FORMAT (4:2:2, 4:2:0, RGB) */ 184f29dbc25Smrg 185f29dbc25Smrg switch (video_source_odd->video_format >> 2) { 186f29dbc25Smrg case 0: 187f29dbc25Smrg ctrl |= DF_CSC_VIDEO_YUV_TO_RGB; 188f29dbc25Smrg break; 189f29dbc25Smrg 190f29dbc25Smrg case 1: 191f29dbc25Smrg ctrl |= DF_CSC_VIDEO_YUV_TO_RGB; 192f29dbc25Smrg vcfg |= DF_VCFG_4_2_0_MODE; 193f29dbc25Smrg gcfg |= DC3_GCFG_YUV_420; 194f29dbc25Smrg break; 195f29dbc25Smrg 196f29dbc25Smrg case 2: 197f29dbc25Smrg ctrl |= DF_VIDEO_INPUT_IS_RGB; 198f29dbc25Smrg break; 199f29dbc25Smrg 200f29dbc25Smrg default: 201f29dbc25Smrg return CIM_STATUS_INVALIDPARAMS; 202f29dbc25Smrg } 203f29dbc25Smrg 204f29dbc25Smrg /* ALIGN TO APPROPRIATE OUTPUT COLOR SPACE */ 205f29dbc25Smrg /* We have assumed until this point that the output color space is RGB */ 206f29dbc25Smrg /* and the input (if YUV) is always SDTV video. */ 207f29dbc25Smrg 208f29dbc25Smrg if (video_source_odd->flags & DF_SOURCEFLAG_HDTVSOURCE) 209f29dbc25Smrg ctrl |= DF_HD_VIDEO; 210f29dbc25Smrg 211f29dbc25Smrg if (ctrl & DF_CSC_GRAPHICS_RGB_TO_YUV) { 212f29dbc25Smrg /* YUV OUTPUT - DISABLE YUV->RGB AND ENABLE YUV->YUV */ 213f29dbc25Smrg 214f29dbc25Smrg ctrl &= ~DF_CSC_VIDEO_YUV_TO_RGB; 215f29dbc25Smrg 216f29dbc25Smrg if ((!(ctrl & DF_HD_VIDEO) && (ctrl & DF_HD_GRAPHICS)) || 217f29dbc25Smrg ((ctrl & DF_HD_VIDEO) && !(ctrl & DF_HD_GRAPHICS))) { 218f29dbc25Smrg ctrl |= DF_YUV_CSC_EN; 219f29dbc25Smrg } 220f29dbc25Smrg } 221f29dbc25Smrg 222f29dbc25Smrg /* PARAMETER - DISPLAY FILTER BUFFER SIZE */ 223f29dbc25Smrg /* The line size in the video generator must be 32-byte aligned. */ 224f29dbc25Smrg /* However, smaller alignments are managed by setting the */ 225f29dbc25Smrg /* appropriate pitch and clipping the video window. */ 226f29dbc25Smrg 227f29dbc25Smrg vcfg &= ~(DF_VCFG_LINE_SIZE_LOWER_MASK | DF_VCFG_LINE_SIZE_BIT8 | 228f29dbc25Smrg DF_VCFG_LINE_SIZE_BIT9); 229f29dbc25Smrg 230f29dbc25Smrg size = ((video_source_odd->width >> 1) + 7) & 0xFFF8; 231f29dbc25Smrg 232f29dbc25Smrg vcfg |= (size & 0x00FF) << 8; 233f29dbc25Smrg if (size & 0x0100) 234f29dbc25Smrg vcfg |= DF_VCFG_LINE_SIZE_BIT8; 235f29dbc25Smrg if (size & 0x0200) 236f29dbc25Smrg vcfg |= DF_VCFG_LINE_SIZE_BIT9; 237f29dbc25Smrg 238f29dbc25Smrg scale = (scale & ~0x7FF) | video_source_odd->height; 239f29dbc25Smrg 240f29dbc25Smrg /* PARAMETER - VIDEO GENERATOR BUFFER SIZE */ 241f29dbc25Smrg 242f29dbc25Smrg vg_line &= ~DC3_LINE_SIZE_VLS_MASK; 243f29dbc25Smrg 244f29dbc25Smrg if (gcfg & DC3_GCFG_YUV_420) 245f29dbc25Smrg width = ((video_source_odd->width >> 1) + 7) & 0xFFF8; 246f29dbc25Smrg else 247f29dbc25Smrg width = ((video_source_odd->width << 1) + 31) & 0xFFE0; 248f29dbc25Smrg 249f29dbc25Smrg vg_line |= (width >> 3) << DC3_LINE_SIZE_VB_SHIFT; 250f29dbc25Smrg 251f29dbc25Smrg /* WRITE ALL PARAMETERS AT ONCE */ 252f29dbc25Smrg 253f29dbc25Smrg WRITE_REG32(DC3_UNLOCK, DC3_UNLOCK_VALUE); 254f29dbc25Smrg WRITE_VID32(DF_VIDEO_CONFIG, vcfg); 255f29dbc25Smrg WRITE_VID32(DF_VID_ALPHA_CONTROL, ctrl); 256f29dbc25Smrg WRITE_VID32(DF_VIDEO_SCALER, scale); 257f29dbc25Smrg WRITE_REG32(DC3_GENERAL_CFG, gcfg); 258f29dbc25Smrg WRITE_REG32(DC3_LINE_SIZE, vg_line); 259f29dbc25Smrg WRITE_REG32(DC3_VID_YUV_PITCH, pitch); 260f29dbc25Smrg 261f29dbc25Smrg /* WRITE EVEN OR ODD BUFFER OFFSETS */ 262f29dbc25Smrg /* The even buffer is only valid inside an interlaced display. */ 263f29dbc25Smrg 264f29dbc25Smrg if (READ_REG32(DC3_IRQ_FILT_CTL) & DC3_IRQFILT_INTL_EN) { 265f29dbc25Smrg WRITE_REG32(DC3_VID_EVEN_Y_ST_OFFSET, video_source_even->y_offset); 266f29dbc25Smrg WRITE_REG32(DC3_VID_EVEN_U_ST_OFFSET, video_source_even->u_offset); 267f29dbc25Smrg WRITE_REG32(DC3_VID_EVEN_V_ST_OFFSET, video_source_even->v_offset); 268f29dbc25Smrg } 269f29dbc25Smrg 270f29dbc25Smrg WRITE_REG32(DC3_VID_Y_ST_OFFSET, video_source_odd->y_offset); 271f29dbc25Smrg WRITE_REG32(DC3_VID_U_ST_OFFSET, video_source_odd->u_offset); 272f29dbc25Smrg WRITE_REG32(DC3_VID_V_ST_OFFSET, video_source_odd->v_offset); 273f29dbc25Smrg 274f29dbc25Smrg WRITE_REG32(DC3_UNLOCK, lock); 275f29dbc25Smrg 276f29dbc25Smrg return CIM_STATUS_OK; 277f29dbc25Smrg} 278f29dbc25Smrg 279f29dbc25Smrg/*--------------------------------------------------------------------------- 280f29dbc25Smrg * df_set_video_offsets 281f29dbc25Smrg * 282f29dbc25Smrg * This routine sets the starting offset for the video buffer(s). The buffers 283f29dbc25Smrg * can also be configured inside df_configure_video_source, but a separate 284f29dbc25Smrg * routine is provided here to allow quick buffer flipping. 285f29dbc25Smrg *--------------------------------------------------------------------------*/ 286f29dbc25Smrg 287f29dbc25Smrgint 288f29dbc25Smrgdf_set_video_offsets(int even, unsigned long y_offset, 289f29dbc25Smrg unsigned long u_offset, unsigned long v_offset) 290f29dbc25Smrg{ 291f29dbc25Smrg unsigned long lock = READ_REG32(DC3_UNLOCK); 292f29dbc25Smrg 293f29dbc25Smrg WRITE_REG32(DC3_UNLOCK, DC3_UNLOCK_VALUE); 294f29dbc25Smrg 295f29dbc25Smrg if (even) { 296f29dbc25Smrg WRITE_REG32(DC3_VID_EVEN_Y_ST_OFFSET, y_offset); 297f29dbc25Smrg WRITE_REG32(DC3_VID_EVEN_U_ST_OFFSET, u_offset); 298f29dbc25Smrg WRITE_REG32(DC3_VID_EVEN_V_ST_OFFSET, v_offset); 299f29dbc25Smrg } else { 300f29dbc25Smrg WRITE_REG32(DC3_VID_Y_ST_OFFSET, y_offset); 301f29dbc25Smrg WRITE_REG32(DC3_VID_U_ST_OFFSET, u_offset); 302f29dbc25Smrg WRITE_REG32(DC3_VID_V_ST_OFFSET, v_offset); 303f29dbc25Smrg } 304f29dbc25Smrg 305f29dbc25Smrg WRITE_REG32(DC3_UNLOCK, lock); 306f29dbc25Smrg 307f29dbc25Smrg return CIM_STATUS_OK; 308f29dbc25Smrg} 309f29dbc25Smrg 310f29dbc25Smrg/*--------------------------------------------------------------------------- 311f29dbc25Smrg * df_set_video_scale 312f29dbc25Smrg * 313f29dbc25Smrg * This routine programs the horizontal/vertical scale factors for video. To 314f29dbc25Smrg * disable scaling/filtering, this routine should be called with identical source 315f29dbc25Smrg * and destination dimensions. 316f29dbc25Smrg *--------------------------------------------------------------------------*/ 317f29dbc25Smrg 318f29dbc25Smrgint 319f29dbc25Smrgdf_set_video_scale(unsigned long src_width, unsigned long src_height, 320f29dbc25Smrg unsigned long dst_width, unsigned long dst_height, unsigned long flags) 321f29dbc25Smrg{ 322f29dbc25Smrg unsigned long temp, misc; 323f29dbc25Smrg unsigned long scale, gfxscale; 324f29dbc25Smrg unsigned long fbactive, src; 325f29dbc25Smrg unsigned long size, downscale; 326f29dbc25Smrg unsigned long vcfg, gcfg, unlock; 327f29dbc25Smrg 328f29dbc25Smrg /* APPLY THE GRAPHICS SCALE */ 329f29dbc25Smrg /* When requested by the user, we will adjust the video scale by the */ 330f29dbc25Smrg /* current graphics scale factor. This allows video to be programmed */ 331f29dbc25Smrg /* in terms of the graphics source resolution. */ 332f29dbc25Smrg 333f29dbc25Smrg misc = READ_VID32(DF_VID_MISC); 334f29dbc25Smrg if (misc & DF_USER_IMPLICIT_SCALING) { 335f29dbc25Smrg gfxscale = READ_REG32(DC3_GFX_SCALE); 336f29dbc25Smrg fbactive = READ_REG32(DC3_FB_ACTIVE); 337f29dbc25Smrg 338f29dbc25Smrg /* REVERSE ENGINEER THE SCALE FACTOR */ 339f29dbc25Smrg /* The graphics scale factor is (source / (dst - 1)), so a little */ 340f29dbc25Smrg /* math is performed to reverse engineer the correct scale for */ 341f29dbc25Smrg /* video. */ 342f29dbc25Smrg /* */ 343f29dbc25Smrg /* F = (0x4000*S)/(D-1) -> (D/S) = (((0x4000*S)/F)+1)/S */ 344f29dbc25Smrg 345f29dbc25Smrg scale = gfxscale & 0xFFFF; 346f29dbc25Smrg src = (fbactive >> 16) + 1; 347f29dbc25Smrg if (scale != 0x4000) { 348f29dbc25Smrg dst_width = dst_width * (((0x4000 * src) / scale) + 1); 349f29dbc25Smrg dst_width /= src; 350f29dbc25Smrg } 351f29dbc25Smrg 352f29dbc25Smrg scale = gfxscale >> 16; 353f29dbc25Smrg src = (fbactive & 0xFFFF) + 1; 354f29dbc25Smrg if (scale != 0x4000) { 355f29dbc25Smrg dst_height = dst_height * (((0x4000 * src) / scale) + 1); 356f29dbc25Smrg dst_height /= src; 357f29dbc25Smrg } 358f29dbc25Smrg } 359f29dbc25Smrg 360f29dbc25Smrg /* CHECK FOR VALID SCALING FACTOR */ 361f29dbc25Smrg /* The display filter/video generator can support up to 8:1 */ 362f29dbc25Smrg /* horizontal downscale and up to 4:1 vertical downscale. */ 363f29dbc25Smrg /* Scale factors above 4:1 horizontal and 2:1 horizontal */ 364f29dbc25Smrg /* will have a quality impact. However, at such large scale */ 365f29dbc25Smrg /* factors, it might not matter, */ 366f29dbc25Smrg 367f29dbc25Smrg if (((flags & DF_SCALEFLAG_CHANGEX) && dst_width < (src_width >> 3)) || 368f29dbc25Smrg ((flags & DF_SCALEFLAG_CHANGEY) && dst_height < (src_height >> 2))) { 369f29dbc25Smrg return CIM_STATUS_INVALIDSCALE; 370f29dbc25Smrg } 371f29dbc25Smrg 372f29dbc25Smrg /* ENABLE OR DISABLE ADVANCED SCALING FEATURES */ 373f29dbc25Smrg /* Scaling above 2:1 vertical and 4:1 horizontal relies */ 374f29dbc25Smrg /* on mechanisms beside the line filter. */ 375f29dbc25Smrg 376f29dbc25Smrg if (flags & DF_SCALEFLAG_CHANGEX) { 377f29dbc25Smrg scale = READ_VID32(DF_VIDEO_SCALER); 378f29dbc25Smrg vcfg = READ_VID32(DF_VIDEO_CONFIG); 379f29dbc25Smrg vcfg &= ~(DF_VCFG_LINE_SIZE_LOWER_MASK | DF_VCFG_LINE_SIZE_BIT8 | 380f29dbc25Smrg DF_VCFG_LINE_SIZE_BIT9); 381f29dbc25Smrg 382f29dbc25Smrg if (dst_width < (src_width >> 2)) { 383f29dbc25Smrg src_width >>= 1; 384f29dbc25Smrg WRITE_VID32(DF_VIDEO_SCALER, scale | DF_SCALE_DOUBLE_H_DOWNSCALE); 385f29dbc25Smrg } else { 386f29dbc25Smrg WRITE_VID32(DF_VIDEO_SCALER, 387f29dbc25Smrg scale & ~DF_SCALE_DOUBLE_H_DOWNSCALE); 388f29dbc25Smrg } 389f29dbc25Smrg 390f29dbc25Smrg /* PROGRAM A NEW LINE SIZE */ 391f29dbc25Smrg /* The line size must be updated when using the Double Horizontal */ 392f29dbc25Smrg /* Downscale (DHD) bit. This is because the amount of VFIFO space */ 393f29dbc25Smrg /* consumed is effectively half in this mode. */ 394f29dbc25Smrg 395f29dbc25Smrg size = ((src_width >> 1) + 7) & 0xFFF8; 396f29dbc25Smrg vcfg |= (size & 0x00FF) << 8; 397f29dbc25Smrg if (size & 0x0100) 398f29dbc25Smrg vcfg |= DF_VCFG_LINE_SIZE_BIT8; 399f29dbc25Smrg if (size & 0x0200) 400f29dbc25Smrg vcfg |= DF_VCFG_LINE_SIZE_BIT9; 401f29dbc25Smrg WRITE_VID32(DF_VIDEO_CONFIG, vcfg); 402f29dbc25Smrg WRITE_VID32(DF_VIDEO_XSCALE, ((0x10000 * src_width) / dst_width)); 403f29dbc25Smrg } 404f29dbc25Smrg 405f29dbc25Smrg if (flags & DF_SCALEFLAG_CHANGEY) { 406f29dbc25Smrg unlock = READ_REG32(DC3_UNLOCK); 407f29dbc25Smrg gcfg = READ_REG32(DC3_GENERAL_CFG) & ~DC3_GCFG_VDSE; 408f29dbc25Smrg WRITE_REG32(DC3_UNLOCK, DC3_UNLOCK_VALUE); 409f29dbc25Smrg if (dst_height < (src_height >> 1)) { 410f29dbc25Smrg gcfg |= DC3_GCFG_VDSE; 411f29dbc25Smrg downscale = READ_REG32(DC3_VID_DS_DELTA) & ~DC3_DS_DELTA_MASK; 412f29dbc25Smrg if (dst_height == (src_height >> 2)) 413f29dbc25Smrg downscale |= (0x3FFF << 18); 414f29dbc25Smrg else 415f29dbc25Smrg downscale |= (((src_height >> 1) << 14) / dst_height) << 18; 416f29dbc25Smrg 417f29dbc25Smrg WRITE_REG32(DC3_VID_DS_DELTA, downscale); 418f29dbc25Smrg WRITE_VID32(DF_VIDEO_YSCALE, 0x20000); 419f29dbc25Smrg } else { 420f29dbc25Smrg WRITE_VID32(DF_VIDEO_YSCALE, 421f29dbc25Smrg ((0x10000 * src_height) / dst_height)); 422f29dbc25Smrg } 423f29dbc25Smrg WRITE_REG32(DC3_GENERAL_CFG, gcfg); 424f29dbc25Smrg WRITE_REG32(DC3_UNLOCK, unlock); 425f29dbc25Smrg } 426f29dbc25Smrg 427f29dbc25Smrg /* CHECK IF SCALING IS DISABLED */ 428f29dbc25Smrg /* If no scaling occurs, we disable the hardware filter. */ 429f29dbc25Smrg 430f29dbc25Smrg temp = READ_VID32(DF_VIDEO_CONFIG); 431f29dbc25Smrg if ((READ_VID32(DF_VIDEO_XSCALE) == 0x10000) && 432f29dbc25Smrg (READ_VID32(DF_VIDEO_YSCALE) == 0x10000)) { 433f29dbc25Smrg WRITE_VID32(DF_VIDEO_CONFIG, (temp | DF_VCFG_SC_BYP)); 434f29dbc25Smrg } else 435f29dbc25Smrg WRITE_VID32(DF_VIDEO_CONFIG, (temp & ~DF_VCFG_SC_BYP)); 436f29dbc25Smrg 437f29dbc25Smrg return CIM_STATUS_OK; 438f29dbc25Smrg} 439f29dbc25Smrg 440f29dbc25Smrg/*--------------------------------------------------------------------------- 441f29dbc25Smrg * df_set_video_position 442f29dbc25Smrg * 443f29dbc25Smrg * This routine programs the position of the video window on the display. 444f29dbc25Smrg * An indent parameter is also passed to this program to prevent artifacts 445f29dbc25Smrg * when the video window is moved beyond the left edge of the screen. 446f29dbc25Smrg *--------------------------------------------------------------------------*/ 447f29dbc25Smrg 448f29dbc25Smrgint 449f29dbc25Smrgdf_set_video_position(DF_VIDEO_POSITION * video_window) 450f29dbc25Smrg{ 451f29dbc25Smrg unsigned long vblankstart_even, vblankend_even, vsyncend_even, 452f29dbc25Smrg vtotal_even, vactive_even; 453f29dbc25Smrg unsigned long hblankstart, hblankend, hsyncend, htotal, hactive; 454f29dbc25Smrg unsigned long vblankstart, vblankend, vsyncend, vtotal, vactive; 455f29dbc25Smrg unsigned long width, height, height_even; 456f29dbc25Smrg unsigned long adjust, border_x, border_y, border_y_even; 457f29dbc25Smrg unsigned long xstart, xend; 458f29dbc25Smrg unsigned long ystart, yend; 459f29dbc25Smrg unsigned long ckey_x, ckey_y; 460f29dbc25Smrg unsigned long x_copy, y_copy; 461f29dbc25Smrg unsigned long width_copy, height_copy; 462f29dbc25Smrg unsigned long vcfg, initread; 463f29dbc25Smrg unsigned long xscale, dst_clip; 464f29dbc25Smrg unsigned long ypos, ypos_even; 465f29dbc25Smrg unsigned long y, gfxscale; 466f29dbc25Smrg unsigned long misc, fbactive; 467f29dbc25Smrg unsigned long scale, src; 468f29dbc25Smrg unsigned long irq_ctl; 469f29dbc25Smrg unsigned long unlock; 470f29dbc25Smrg 471f29dbc25Smrg hsyncend = ((READ_REG32(DC3_H_SYNC_TIMING) >> 16) & 0xFFF) + 1; 472f29dbc25Smrg vsyncend = ((READ_REG32(DC3_V_SYNC_TIMING) >> 16) & 0xFFF) + 1; 473f29dbc25Smrg vblankend = ((READ_REG32(DC3_V_BLANK_TIMING) >> 16) & 0xFFF) + 1; 474f29dbc25Smrg hblankend = ((READ_REG32(DC3_H_BLANK_TIMING) >> 16) & 0xFFF) + 1; 475f29dbc25Smrg htotal = ((READ_REG32(DC3_H_ACTIVE_TIMING) >> 16) & 0xFFF) + 1; 476f29dbc25Smrg vtotal = ((READ_REG32(DC3_V_ACTIVE_TIMING) >> 16) & 0xFFF) + 1; 477f29dbc25Smrg vblankstart = (READ_REG32(DC3_V_BLANK_TIMING) & 0xFFF) + 1; 478f29dbc25Smrg hblankstart = (READ_REG32(DC3_H_BLANK_TIMING) & 0xFFF) + 1; 479f29dbc25Smrg hactive = (READ_REG32(DC3_H_ACTIVE_TIMING) & 0xFFF) + 1; 480f29dbc25Smrg vactive = (READ_REG32(DC3_V_ACTIVE_TIMING) & 0xFFF) + 1; 481f29dbc25Smrg unlock = READ_REG32(DC3_UNLOCK); 482f29dbc25Smrg 483f29dbc25Smrg /* INCLUDE BORDER IF REQUESTED */ 484f29dbc25Smrg 485f29dbc25Smrg if (video_window->flags & DF_POSFLAG_INCLUDEBORDER) { 486f29dbc25Smrg border_x = htotal - hblankend; 487f29dbc25Smrg border_y = vtotal - vblankend; 488f29dbc25Smrg hactive = hblankstart + htotal - hblankend; 489f29dbc25Smrg vactive = vblankstart + vtotal - vblankend; 490f29dbc25Smrg } else { 491f29dbc25Smrg border_x = border_y = 0; 492f29dbc25Smrg } 493f29dbc25Smrg 494f29dbc25Smrg /* APPLY THE GRAPHICS SCALE */ 495f29dbc25Smrg /* Do not alter the input data. */ 496f29dbc25Smrg 497f29dbc25Smrg width_copy = video_window->width; 498f29dbc25Smrg height_copy = video_window->height; 499f29dbc25Smrg x_copy = video_window->x; 500f29dbc25Smrg y_copy = video_window->y; 501f29dbc25Smrg 502f29dbc25Smrg misc = READ_VID32(DF_VID_MISC); 503f29dbc25Smrg if (misc & DF_USER_IMPLICIT_SCALING) { 504f29dbc25Smrg gfxscale = READ_REG32(DC3_GFX_SCALE); 505f29dbc25Smrg fbactive = READ_REG32(DC3_FB_ACTIVE); 506f29dbc25Smrg 507f29dbc25Smrg /* REVERSE ENGINEER THE SCALE FACTOR */ 508f29dbc25Smrg 509f29dbc25Smrg scale = gfxscale & 0xFFFF; 510f29dbc25Smrg src = (fbactive >> 16) + 1; 511f29dbc25Smrg if (scale != 0x4000) { 512f29dbc25Smrg width_copy = width_copy * (((0x4000 * src) / scale) + 1); 513f29dbc25Smrg width_copy /= src; 514f29dbc25Smrg x_copy = x_copy * (((0x4000 * src) / scale) + 1); 515f29dbc25Smrg x_copy /= src; 516f29dbc25Smrg } 517f29dbc25Smrg 518f29dbc25Smrg scale = gfxscale >> 16; 519f29dbc25Smrg src = (fbactive & 0xFFFF) + 1; 520f29dbc25Smrg if (scale != 0x4000) { 521f29dbc25Smrg height_copy = height_copy * (((0x4000 * src) / scale) + 1); 522f29dbc25Smrg height_copy /= src; 523f29dbc25Smrg y_copy = y_copy * (((0x4000 * src) / scale) + 1); 524f29dbc25Smrg y_copy /= src; 525f29dbc25Smrg } 526f29dbc25Smrg } 527f29dbc25Smrg 528f29dbc25Smrg /* HANDLE INTERLACING */ 529f29dbc25Smrg /* When the output is interlaced, we must set the position and height */ 530f29dbc25Smrg /* on the fields and not on the composite image. */ 531f29dbc25Smrg 532f29dbc25Smrg if ((irq_ctl = READ_REG32(DC3_IRQ_FILT_CTL)) & DC3_IRQFILT_INTL_EN) { 533f29dbc25Smrg vsyncend_even = ((READ_REG32(DC3_V_SYNC_EVEN) >> 16) & 0xFFF) + 1; 534f29dbc25Smrg vtotal_even = ((READ_REG32(DC3_V_ACTIVE_EVEN) >> 16) & 0xFFF) + 1; 535f29dbc25Smrg vblankend_even = ((READ_REG32(DC3_V_BLANK_EVEN) >> 16) & 0xFFF) + 1; 536f29dbc25Smrg vactive_even = (READ_REG32(DC3_V_ACTIVE_EVEN) & 0xFFF) + 1; 537f29dbc25Smrg vblankstart_even = (READ_REG32(DC3_V_BLANK_EVEN) & 0xFFF) + 1; 538f29dbc25Smrg 539f29dbc25Smrg if (video_window->flags & DF_POSFLAG_INCLUDEBORDER) { 540f29dbc25Smrg border_y_even = vtotal_even - vblankend_even; 541f29dbc25Smrg vactive_even = vblankstart_even + vtotal_even - vblankend_even; 542f29dbc25Smrg } else 543f29dbc25Smrg border_y_even = 0; 544f29dbc25Smrg 545f29dbc25Smrg /* 546f29dbc25Smrg * THE ODD FIELD MUST ALWAYS PRECEDE THE EVEN FIELD 547f29dbc25Smrg * This implies that we can never start video on an odd y position 548f29dbc25Smrg * in the composite image. This is required because the only way 549f29dbc25Smrg * to accomplish an odd y start would be to switch the buffer 550f29dbc25Smrg * which could have serious repercussions for genlocked VIP. 551f29dbc25Smrg */ 552f29dbc25Smrg 553f29dbc25Smrg y = y_copy >> 1; 554f29dbc25Smrg 555f29dbc25Smrg /* CALCULATE Y POSITION FOR ODD FIELD */ 556f29dbc25Smrg /* Clip the video window to the odd field timings. Note that the */ 557f29dbc25Smrg /* height in the odd field may be greater if the video height is */ 558f29dbc25Smrg /* odd. */ 559f29dbc25Smrg 560f29dbc25Smrg height = (height_copy + 1) >> 1; 561f29dbc25Smrg if ((y + height) > vactive) 562f29dbc25Smrg height = vactive - y; 563f29dbc25Smrg 564f29dbc25Smrg ystart = y + vtotal_even - vsyncend_even + 1; 565f29dbc25Smrg if (video_window->flags & DF_POSFLAG_INCLUDEBORDER) 566f29dbc25Smrg ystart -= border_y_even; 567f29dbc25Smrg 568f29dbc25Smrg yend = ystart + height; 569f29dbc25Smrg ypos = (yend << 16) | ystart; 570f29dbc25Smrg 571f29dbc25Smrg /* CALCULATE Y POSITION FOR EVEN FIELD */ 572f29dbc25Smrg 573f29dbc25Smrg height_even = height_copy >> 1; 574f29dbc25Smrg if ((y + height_even) > vactive_even) 575f29dbc25Smrg height_even = vactive_even - y; 576f29dbc25Smrg 577f29dbc25Smrg ystart = y + vtotal - vsyncend + 1; 578f29dbc25Smrg if (video_window->flags & DF_POSFLAG_INCLUDEBORDER) 579f29dbc25Smrg ystart -= border_y; 580f29dbc25Smrg 581f29dbc25Smrg yend = ystart + height_even; 582f29dbc25Smrg ypos_even = (yend << 16) | ystart; 583f29dbc25Smrg 584f29dbc25Smrg /* CALCULATE ACTUAL FRAME BUFFER HEIGHT */ 585f29dbc25Smrg /* The y position and height are used to determine the actual */ 586f29dbc25Smrg /* placement of the color key region. The region will either be */ 587f29dbc25Smrg /* the sum of the even and odd fields (for interlaced addressing */ 588f29dbc25Smrg /* or flicker filtering) or it will be the union of the two (for */ 589f29dbc25Smrg /* line doubling). We must also adjust the region such that the */ 590f29dbc25Smrg /* origin (0, 0) is centered on the beginning of graphics data. */ 591f29dbc25Smrg /* This is only a problem if video is being displayed over the */ 592f29dbc25Smrg /* overscan area. */ 593f29dbc25Smrg 594f29dbc25Smrg if ((READ_REG32(DC3_GENLK_CTL) & DC3_GC_FLICKER_FILTER_ENABLE) || 595f29dbc25Smrg (irq_ctl & DC3_IRQFILT_INTL_ADDR)) { 596f29dbc25Smrg y <<= 1; 597f29dbc25Smrg height += height_even; 598f29dbc25Smrg adjust = border_y + border_y_even; 599f29dbc25Smrg } else { 600f29dbc25Smrg adjust = border_y; 601f29dbc25Smrg if (height_even > height) 602f29dbc25Smrg height = height_even; 603f29dbc25Smrg } 604f29dbc25Smrg if (video_window->flags & DF_POSFLAG_INCLUDEBORDER) { 605f29dbc25Smrg if (y > adjust) { 606f29dbc25Smrg y -= adjust; 607f29dbc25Smrg adjust = 0; 608f29dbc25Smrg } else { 609f29dbc25Smrg adjust -= y; 610f29dbc25Smrg if (height > adjust) 611f29dbc25Smrg height -= adjust; 612f29dbc25Smrg else 613f29dbc25Smrg height = 0; 614f29dbc25Smrg } 615f29dbc25Smrg } 616f29dbc25Smrg 617f29dbc25Smrg } else { 618f29dbc25Smrg y = y_copy; 619f29dbc25Smrg 620f29dbc25Smrg height = height_copy; 621f29dbc25Smrg if ((y + height) > vactive) 622f29dbc25Smrg height = vactive - y; 623f29dbc25Smrg 624f29dbc25Smrg ystart = y + vtotal - vsyncend + 1; 625f29dbc25Smrg if (video_window->flags & DF_POSFLAG_INCLUDEBORDER) 626f29dbc25Smrg ystart -= border_y; 627f29dbc25Smrg 628f29dbc25Smrg yend = ystart + height; 629f29dbc25Smrg ypos = (yend << 16) | ystart; 630f29dbc25Smrg ypos_even = 0; 631f29dbc25Smrg } 632f29dbc25Smrg 633f29dbc25Smrg /* HORIZONTAL POSITION */ 634f29dbc25Smrg /* The horizontal values are identical for the even and odd field. */ 635f29dbc25Smrg 636f29dbc25Smrg width = width_copy; 637f29dbc25Smrg xstart = x_copy + htotal - hsyncend - 14; 638f29dbc25Smrg if (video_window->flags & DF_POSFLAG_INCLUDEBORDER) 639f29dbc25Smrg xstart -= border_x; 640f29dbc25Smrg 641f29dbc25Smrg /* RIGHT CLIPPING */ 642f29dbc25Smrg 643f29dbc25Smrg if ((x_copy + width) > hactive) 644f29dbc25Smrg width = hactive - x_copy; 645f29dbc25Smrg 646f29dbc25Smrg xend = xstart + width; 647f29dbc25Smrg 648f29dbc25Smrg /* 649f29dbc25Smrg * CALCULATE LEFT CLIPPING PARAMETER 650f29dbc25Smrg * The value passed in can be interpreted as destination pixels, in 651f29dbc25Smrg * which case the video scale is factored in, or as source pixels, in 652f29dbc25Smrg * which case the value is written directly. Also, the display filter's 653f29dbc25Smrg * initial read address value is only programmable on 4-pixel increments. 654f29dbc25Smrg * However, we can achieve an arbitrary left clip by adjusting the 655f29dbc25Smrg * xstart value, as there is a 14-clock delay in which to play. Also, 656f29dbc25Smrg * according to the designers, 4:2:0 and 4:2:2 behave identically when 657f29dbc25Smrg * setting the initial read address. The addition of scaling further 658f29dbc25Smrg * complicates the algorithm. When setting the initial read address, it 659f29dbc25Smrg * is in terms of source pixels, while adjusting the xstart value is in 660f29dbc25Smrg * destination pixels We may thus not be able to achieve a perfect 661f29dbc25Smrg * clipping fit for scaled video. We compensate by including two 662f29dbc25Smrg * clipping parameters in our structure. This allows us the user 663f29dbc25Smrg * additional control and it allows us to accurately convey to the user 664f29dbc25Smrg * the state of clipping on the machine. 665f29dbc25Smrg */ 666f29dbc25Smrg 667f29dbc25Smrg initread = video_window->left_clip; 668f29dbc25Smrg dst_clip = 0; 669f29dbc25Smrg if (!(video_window->flags & DF_POSFLAG_DIRECTCLIP)) { 670f29dbc25Smrg xscale = READ_VID32(DF_VIDEO_XSCALE) & 0xFFFFF; 671f29dbc25Smrg initread = (initread * xscale) / 0x10000; 672f29dbc25Smrg if (xscale) 673f29dbc25Smrg dst_clip = ((initread & 3) * 0x10000) / xscale; 674f29dbc25Smrg } else 675f29dbc25Smrg dst_clip = video_window->dst_clip; 676f29dbc25Smrg 677f29dbc25Smrg /* 678f29dbc25Smrg * LIMIT THE CLIP 679f29dbc25Smrg * We technically have a 14 pixel window in which to play. However, 680f29dbc25Smrg * taking the entire 14 pixels makes the video timing a little hairy... 681f29dbc25Smrg * Also note that we cannot do this when performing panel centering, as 682f29dbc25Smrg * the video would then exceed the mode size. 683f29dbc25Smrg */ 684f29dbc25Smrg 685f29dbc25Smrg if (dst_clip > 4) 686f29dbc25Smrg dst_clip = 4; 687f29dbc25Smrg if (READ_REG32(DC3_DISPLAY_CFG) & DC3_DCFG_DCEN) 688f29dbc25Smrg dst_clip = 0; 689f29dbc25Smrg 690f29dbc25Smrg xstart -= dst_clip; 691f29dbc25Smrg 692f29dbc25Smrg vcfg = READ_VID32(DF_VIDEO_CONFIG); 693f29dbc25Smrg vcfg &= ~DF_VCFG_INIT_READ_MASK; 694f29dbc25Smrg vcfg |= (initread >> 2) << 16; 695f29dbc25Smrg 696f29dbc25Smrg /* SET COLOR KEY REGION */ 697f29dbc25Smrg /* We are assuming that color keying will never be desired outside */ 698f29dbc25Smrg /* of the video region. We adjust the color key region for graphics */ 699f29dbc25Smrg /* scaling. */ 700f29dbc25Smrg 701f29dbc25Smrg gfxscale = READ_REG32(DC3_GFX_SCALE); 702f29dbc25Smrg 703f29dbc25Smrg ckey_x = ((x_copy * (gfxscale & 0xFFFF)) / 0x4000) | 704f29dbc25Smrg ((((x_copy + width) * (gfxscale & 0xFFFF)) / 0x4000) << 16); 705f29dbc25Smrg ckey_y = ((y * (gfxscale >> 16)) / 0x4000) | 706f29dbc25Smrg ((((y + height) * (gfxscale >> 16)) / 0x4000) << 16); 707f29dbc25Smrg 708f29dbc25Smrg /* WRITE ALL PARAMETERS AT ONCE */ 709f29dbc25Smrg 710f29dbc25Smrg WRITE_REG32(DC3_UNLOCK, DC3_UNLOCK_VALUE); 711f29dbc25Smrg WRITE_REG32(DC3_CLR_KEY_X, ckey_x); 712f29dbc25Smrg WRITE_REG32(DC3_CLR_KEY_Y, ckey_y); 713f29dbc25Smrg WRITE_VID32(DF_VIDEO_X_POS, (xend << 16) | xstart); 714f29dbc25Smrg WRITE_VID32(DF_VIDEO_Y_POS, ypos); 715f29dbc25Smrg WRITE_VID32(DF_VID_YPOS_EVEN, ypos_even); 716f29dbc25Smrg WRITE_VID32(DF_VIDEO_CONFIG, vcfg); 717f29dbc25Smrg WRITE_REG32(DC3_UNLOCK, unlock); 718f29dbc25Smrg 719f29dbc25Smrg return CIM_STATUS_OK; 720f29dbc25Smrg} 721f29dbc25Smrg 722f29dbc25Smrg/*--------------------------------------------------------------------------- 723f29dbc25Smrg * df_set_video_filter_coefficients 724f29dbc25Smrg * 725f29dbc25Smrg * This routine sets the horizontal and vertical filter coefficients for video 726f29dbc25Smrg * scaling. These coefficients are used for upscaling and downscaling video. 727f29dbc25Smrg * If the phase256 parameter is 1, the coefficient arrays are used as single 728f29dbc25Smrg * arrays of 256 phases for both vertical and horizontal scaling. If the 729f29dbc25Smrg * phase256 parameter is clear, the coefficient arrays are used as two 730f29dbc25Smrg * 128-phase arrays. The first 128 entries represent the phases for 731f29dbc25Smrg * vertical scaling. The last 128 entries represent the phases for 732f29dbc25Smrg * horizontal scaling. 733f29dbc25Smrg *--------------------------------------------------------------------------*/ 734f29dbc25Smrg 735f29dbc25Smrgint 736f29dbc25Smrgdf_set_video_filter_coefficients(long taps[][4], int phase256) 737f29dbc25Smrg{ 738f29dbc25Smrg unsigned long scale, coeff0, coeff1; 739f29dbc25Smrg unsigned long i; 740f29dbc25Smrg long (*defaults)[2]; 741f29dbc25Smrg 742f29dbc25Smrg /* SET PHASE COUNT AND CHOOSE COEFFICIENT ARRAY */ 743f29dbc25Smrg 744f29dbc25Smrg scale = READ_VID32(DF_VIDEO_SCALER); 745f29dbc25Smrg if (phase256) { 746f29dbc25Smrg WRITE_VID32(DF_VIDEO_SCALER, (scale & ~DF_SCALE_128_PHASES)); 747f29dbc25Smrg defaults = CimarronVideoFilter256; 748f29dbc25Smrg } else { 749f29dbc25Smrg WRITE_VID32(DF_VIDEO_SCALER, (scale | DF_SCALE_128_PHASES)); 750f29dbc25Smrg defaults = CimarronVideoFilter128; 751f29dbc25Smrg } 752f29dbc25Smrg 753f29dbc25Smrg /* PROGRAM COEFFICIENTS */ 754f29dbc25Smrg 755f29dbc25Smrg for (i = 0; i < 256; i++) { 756f29dbc25Smrg if (!taps) { 757f29dbc25Smrg coeff0 = defaults[i][0]; 758f29dbc25Smrg coeff1 = defaults[i][1]; 759f29dbc25Smrg } else { 760f29dbc25Smrg if (taps[i][1] < 0) 761f29dbc25Smrg coeff0 = -taps[i][1] | 0x8000; 762f29dbc25Smrg else 763f29dbc25Smrg coeff0 = taps[i][1]; 764f29dbc25Smrg 765f29dbc25Smrg coeff0 <<= 16; 766f29dbc25Smrg 767f29dbc25Smrg if (taps[i][0] < 0) 768f29dbc25Smrg coeff0 |= -taps[i][0] | 0x8000; 769f29dbc25Smrg else 770f29dbc25Smrg coeff0 |= taps[i][0]; 771f29dbc25Smrg 772f29dbc25Smrg if (taps[i][3] < 0) 773f29dbc25Smrg coeff1 = -taps[i][3] | 0x8000; 774f29dbc25Smrg else 775f29dbc25Smrg coeff1 = taps[i][3]; 776f29dbc25Smrg 777f29dbc25Smrg coeff1 <<= 16; 778f29dbc25Smrg 779f29dbc25Smrg if (taps[i][2] < 0) 780f29dbc25Smrg coeff1 |= -taps[i][2] | 0x8000; 781f29dbc25Smrg else 782f29dbc25Smrg coeff1 |= taps[i][2]; 783f29dbc25Smrg } 784f29dbc25Smrg 785f29dbc25Smrg WRITE_VID32((DF_COEFFICIENT_BASE + (i << 3)), coeff0); 786f29dbc25Smrg WRITE_VID32((DF_COEFFICIENT_BASE + (i << 3) + 4), coeff1); 787f29dbc25Smrg } 788f29dbc25Smrg 789f29dbc25Smrg return CIM_STATUS_OK; 790f29dbc25Smrg} 791f29dbc25Smrg 792f29dbc25Smrg/*--------------------------------------------------------------------------- 793f29dbc25Smrg * df_set_video_enable 794f29dbc25Smrg * 795f29dbc25Smrg * This routine enables or disables the video overlay. 796f29dbc25Smrg *--------------------------------------------------------------------------*/ 797f29dbc25Smrg 798f29dbc25Smrgint 799f29dbc25Smrgdf_set_video_enable(int enable, unsigned long flags) 800f29dbc25Smrg{ 801f29dbc25Smrg unsigned long vcfg, lock, gcfg; 802f29dbc25Smrg unsigned long dcfg, vg_ckey, fifo = 0; 803f29dbc25Smrg 804f29dbc25Smrg vcfg = READ_VID32(DF_VIDEO_CONFIG); 805f29dbc25Smrg lock = READ_REG32(DC3_UNLOCK); 806f29dbc25Smrg gcfg = READ_REG32(DC3_GENERAL_CFG); 807f29dbc25Smrg 808f29dbc25Smrg /* SET VIDEO FIFO END WATERMARK */ 809f29dbc25Smrg /* The video FIFO end watermark is set to 0 when video is disabled */ 810f29dbc25Smrg /* to allow low priority transactions in the VG. Otherwise, the */ 811f29dbc25Smrg /* priority will be forced high until the VG fills the video FIFO */ 812f29dbc25Smrg /* by not fetching video. That could take a while... Note that */ 813f29dbc25Smrg /* we set the end priority to be 4 greater than the start. We */ 814f29dbc25Smrg /* assume that the start priority has been configured by a modeset. */ 815f29dbc25Smrg 816f29dbc25Smrg dcfg = READ_REG32(DC3_DISPLAY_CFG) & ~DC3_DCFG_VFHPEL_MASK; 817f29dbc25Smrg if (enable) { 818f29dbc25Smrg fifo = ((dcfg >> 12) & 0x0000000F) + 4; 819f29dbc25Smrg if (fifo > 0xF) 820f29dbc25Smrg fifo = 0xF; 821f29dbc25Smrg } 822f29dbc25Smrg WRITE_REG32(DC3_UNLOCK, DC3_UNLOCK_VALUE); 823f29dbc25Smrg WRITE_REG32(DC3_DISPLAY_CFG, dcfg | (fifo << 16)); 824f29dbc25Smrg 825f29dbc25Smrg /* ENABLE OR DISABLE VIDEO */ 826f29dbc25Smrg /* The mechanism to fetch video data is enabled first and */ 827f29dbc25Smrg /* disabled last. */ 828f29dbc25Smrg 829f29dbc25Smrg if (enable) { 830f29dbc25Smrg WRITE_REG32(DC3_GENERAL_CFG, (gcfg | DC3_GCFG_VIDE)); 831f29dbc25Smrg WRITE_VID32(DF_VIDEO_CONFIG, (vcfg | DF_VCFG_VID_EN)); 832f29dbc25Smrg 833f29dbc25Smrg /* DISABLE COLOR KEYING IF REQUESTED BY THE USER */ 834f29dbc25Smrg 835f29dbc25Smrg if (flags & DF_ENABLEFLAG_NOCOLORKEY) { 836f29dbc25Smrg /* OVERRIDE THE MODE TO COLOR KEYING */ 837f29dbc25Smrg 838f29dbc25Smrg dcfg = READ_VID32(DF_DISPLAY_CONFIG); 839f29dbc25Smrg WRITE_VID32(DF_DISPLAY_CONFIG, (dcfg & ~DF_DCFG_VG_CK)); 840f29dbc25Smrg 841f29dbc25Smrg /* DISABLE COLOR KEYING IN THE VG */ 842f29dbc25Smrg 843f29dbc25Smrg vg_ckey = READ_REG32(DC3_COLOR_KEY); 844f29dbc25Smrg WRITE_REG32(DC3_COLOR_KEY, (vg_ckey & ~DC3_CLR_KEY_ENABLE)); 845f29dbc25Smrg } else if (!(READ_VID32(DF_DISPLAY_CONFIG) & DF_DCFG_VG_CK)) { 846f29dbc25Smrg /* OTHERWISE RE-ENABLE COLOR KEYING */ 847f29dbc25Smrg 848f29dbc25Smrg vg_ckey = READ_REG32(DC3_COLOR_KEY); 849f29dbc25Smrg WRITE_REG32(DC3_COLOR_KEY, (vg_ckey | DC3_CLR_KEY_ENABLE)); 850f29dbc25Smrg } 851f29dbc25Smrg } else { 852f29dbc25Smrg WRITE_VID32(DF_VIDEO_CONFIG, (vcfg & ~DF_VCFG_VID_EN)); 853f29dbc25Smrg WRITE_REG32(DC3_GENERAL_CFG, (gcfg & ~DC3_GCFG_VIDE)); 854f29dbc25Smrg 855f29dbc25Smrg /* DISABLE COLOR KEY WINDOW WHEN VIDEO IS INACTIVE */ 856f29dbc25Smrg /* To mimic legacy functionality, we disble color keying */ 857f29dbc25Smrg /* when the video window is not active. We will restore */ 858f29dbc25Smrg /* the enable when video is re-enabled if the appropriate */ 859f29dbc25Smrg /* bit is set in display config. */ 860f29dbc25Smrg 861f29dbc25Smrg vg_ckey = READ_REG32(DC3_COLOR_KEY); 862f29dbc25Smrg WRITE_REG32(DC3_COLOR_KEY, (vg_ckey & ~DC3_CLR_KEY_ENABLE)); 863f29dbc25Smrg } 864f29dbc25Smrg WRITE_REG32(DC3_UNLOCK, lock); 865f29dbc25Smrg 866f29dbc25Smrg return CIM_STATUS_OK; 867f29dbc25Smrg} 868f29dbc25Smrg 869f29dbc25Smrg/*--------------------------------------------------------------------------- 870f29dbc25Smrg * df_set_video_color_key 871f29dbc25Smrg * 872f29dbc25Smrg * This routine configures the video color/chroma key mechanism. 873f29dbc25Smrg *--------------------------------------------------------------------------*/ 874f29dbc25Smrg 875f29dbc25Smrgint 876f29dbc25Smrgdf_set_video_color_key(unsigned long key, unsigned long mask, int graphics) 877f29dbc25Smrg{ 878f29dbc25Smrg unsigned long lock, vg_ckey, df_dcfg; 879f29dbc25Smrg 880f29dbc25Smrg vg_ckey = READ_REG32(DC3_COLOR_KEY); 881f29dbc25Smrg lock = READ_REG32(DC3_UNLOCK); 882f29dbc25Smrg df_dcfg = READ_VID32(DF_DISPLAY_CONFIG); 883f29dbc25Smrg 884f29dbc25Smrg WRITE_REG32(DC3_UNLOCK, DC3_UNLOCK_VALUE); 885f29dbc25Smrg 886f29dbc25Smrg if (graphics) { 887f29dbc25Smrg /* COLOR KEY - USE VG HARDWARE */ 888f29dbc25Smrg /* Note that color key is never enabled unless a video window */ 889f29dbc25Smrg /* is active. This is to match legacy behavior. */ 890f29dbc25Smrg 891f29dbc25Smrg df_dcfg &= ~DF_DCFG_VG_CK; 892f29dbc25Smrg vg_ckey = (vg_ckey & 0xFF000000) | (key & 0xFFFFFF); 893f29dbc25Smrg if (READ_VID32(DF_VIDEO_CONFIG) & DF_VCFG_VID_EN) 894f29dbc25Smrg vg_ckey |= DC3_CLR_KEY_ENABLE; 895f29dbc25Smrg else 896f29dbc25Smrg vg_ckey &= ~DC3_CLR_KEY_ENABLE; 897f29dbc25Smrg 898f29dbc25Smrg WRITE_VID32(DF_DISPLAY_CONFIG, df_dcfg); 899f29dbc25Smrg WRITE_REG32(DC3_COLOR_KEY, vg_ckey); 900f29dbc25Smrg WRITE_REG32(DC3_COLOR_MASK, (mask & 0xFFFFFF)); 901f29dbc25Smrg } else { 902f29dbc25Smrg /* CHROMA KEY - USE DF HARDWARE */ 903f29dbc25Smrg 904f29dbc25Smrg df_dcfg |= DF_DCFG_VG_CK; 905f29dbc25Smrg vg_ckey &= ~DC3_CLR_KEY_ENABLE; 906f29dbc25Smrg 907f29dbc25Smrg WRITE_REG32(DC3_COLOR_KEY, vg_ckey); 908f29dbc25Smrg WRITE_VID32(DF_DISPLAY_CONFIG, df_dcfg); 909f29dbc25Smrg WRITE_VID32(DF_VIDEO_COLOR_KEY, (key & 0xFFFFFF)); 910f29dbc25Smrg WRITE_VID32(DF_VIDEO_COLOR_MASK, (mask & 0xFFFFFF)); 911f29dbc25Smrg } 912f29dbc25Smrg 913f29dbc25Smrg WRITE_REG32(DC3_UNLOCK, lock); 914f29dbc25Smrg 915f29dbc25Smrg return CIM_STATUS_OK; 916f29dbc25Smrg} 917f29dbc25Smrg 918f29dbc25Smrg/*--------------------------------------------------------------------------- 919f29dbc25Smrg * df_set_video_palette 920f29dbc25Smrg * 921f29dbc25Smrg * This routine loads the video hardware palette. If a NULL pointer is 922f29dbc25Smrg * specified, the palette is bypassed. 923f29dbc25Smrg *-------------------------------------------------------------------------*/ 924f29dbc25Smrg 925f29dbc25Smrgint 926f29dbc25Smrgdf_set_video_palette(unsigned long *palette) 927f29dbc25Smrg{ 928f29dbc25Smrg unsigned long i, entry; 929f29dbc25Smrg unsigned long misc, dcfg; 930f29dbc25Smrg 931f29dbc25Smrg /* LOAD GEODE LX VIDEO PALETTE */ 932f29dbc25Smrg 933f29dbc25Smrg WRITE_VID32(DF_PALETTE_ADDRESS, 0); 934f29dbc25Smrg for (i = 0; i < 256; i++) { 935f29dbc25Smrg if (palette) 936f29dbc25Smrg entry = palette[i]; 937f29dbc25Smrg else 938f29dbc25Smrg entry = i | (i << 8) | (i << 16); 939f29dbc25Smrg WRITE_VID32(DF_PALETTE_DATA, entry); 940f29dbc25Smrg } 941f29dbc25Smrg 942f29dbc25Smrg /* ENABLE THE VIDEO PALETTE */ 943f29dbc25Smrg /* Ensure that the video palette has an effect by routing video data */ 944f29dbc25Smrg /* through the palette RAM and clearing the 'Bypass Both' bit. */ 945f29dbc25Smrg 946f29dbc25Smrg dcfg = READ_VID32(DF_DISPLAY_CONFIG); 947f29dbc25Smrg misc = READ_VID32(DF_VID_MISC); 948f29dbc25Smrg 949f29dbc25Smrg dcfg |= DF_DCFG_GV_PAL_BYP; 950f29dbc25Smrg misc &= ~DF_GAMMA_BYPASS_BOTH; 951f29dbc25Smrg 952f29dbc25Smrg WRITE_VID32(DF_DISPLAY_CONFIG, dcfg); 953f29dbc25Smrg WRITE_VID32(DF_VID_MISC, misc); 954f29dbc25Smrg 955f29dbc25Smrg return CIM_STATUS_OK; 956f29dbc25Smrg} 957f29dbc25Smrg 958f29dbc25Smrg/*--------------------------------------------------------------------------- 959f29dbc25Smrg * df_set_video_palette_entry 960f29dbc25Smrg * 961f29dbc25Smrg * This routine loads a single entry of the video hardware palette. 962f29dbc25Smrg *--------------------------------------------------------------------------*/ 963f29dbc25Smrg 964f29dbc25Smrgint 965f29dbc25Smrgdf_set_video_palette_entry(unsigned long index, unsigned long palette) 966f29dbc25Smrg{ 967f29dbc25Smrg unsigned long misc, dcfg; 968f29dbc25Smrg 969f29dbc25Smrg if (index > 0xFF) 970f29dbc25Smrg return CIM_STATUS_INVALIDPARAMS; 971f29dbc25Smrg 972f29dbc25Smrg /* SET A SINGLE ENTRY */ 973f29dbc25Smrg 974f29dbc25Smrg WRITE_VID32(DF_PALETTE_ADDRESS, index); 975f29dbc25Smrg WRITE_VID32(DF_PALETTE_DATA, palette); 976f29dbc25Smrg 977f29dbc25Smrg /* ENABLE THE VIDEO PALETTE */ 978f29dbc25Smrg /* Ensure that the video palette has an effect by routing video data */ 979f29dbc25Smrg /* through the palette RAM and clearing the 'Bypass Both' bit. */ 980f29dbc25Smrg 981f29dbc25Smrg dcfg = READ_VID32(DF_DISPLAY_CONFIG); 982f29dbc25Smrg misc = READ_VID32(DF_VID_MISC); 983f29dbc25Smrg 984170d5fdcSmrg /* Ensure that the Graphic data passes through the Gamma 985170d5fdcSmrg * Correction RAM 9867aef237fSmrg * 9877aef237fSmrg * XXX is this a bug? perhaps it should be setting the bit so that video 9887aef237fSmrg * data is routed, according to the description above. 9897aef237fSmrg * it also mismatches df_set_video_palette(). 990170d5fdcSmrg */ 991170d5fdcSmrg dcfg &= ~DF_DCFG_GV_PAL_BYP; 992170d5fdcSmrg 9937aef237fSmrg /* Unset the "bypass both" bit to make sure the above selection (gfx/video 9947aef237fSmrg * data through gamma correction RAM) takes effect. 995170d5fdcSmrg */ 996f29dbc25Smrg misc &= ~DF_GAMMA_BYPASS_BOTH; 997f29dbc25Smrg 998f29dbc25Smrg WRITE_VID32(DF_DISPLAY_CONFIG, dcfg); 999f29dbc25Smrg WRITE_VID32(DF_VID_MISC, misc); 1000f29dbc25Smrg 1001f29dbc25Smrg return CIM_STATUS_OK; 1002f29dbc25Smrg} 1003f29dbc25Smrg 1004f29dbc25Smrg/*--------------------------------------------------------------------------- 1005f29dbc25Smrg * df_configure_video_cursor_color_key 1006f29dbc25Smrg * 1007f29dbc25Smrg * This routine configures the hardware video cursor color key mechanism. 1008f29dbc25Smrg *--------------------------------------------------------------------------*/ 1009f29dbc25Smrg 1010f29dbc25Smrgint 1011f29dbc25Smrgdf_configure_video_cursor_color_key(DF_VIDEO_CURSOR_PARAMS * cursor_color_key) 1012f29dbc25Smrg{ 1013f29dbc25Smrg unsigned long key; 1014f29dbc25Smrg 1015f29dbc25Smrg if (cursor_color_key->select_color2 >= 24) 1016f29dbc25Smrg return CIM_STATUS_INVALIDPARAMS; 1017f29dbc25Smrg 1018f29dbc25Smrg key = READ_VID32(DF_CURSOR_COLOR_KEY) & DF_CURSOR_COLOR_KEY_ENABLE; 1019f29dbc25Smrg key = key | (cursor_color_key->key & 0xFFFFFF) | (cursor_color_key-> 1020f29dbc25Smrg select_color2 << 24); 1021f29dbc25Smrg 1022f29dbc25Smrg WRITE_VID32(DF_CURSOR_COLOR_KEY, key); 1023f29dbc25Smrg WRITE_VID32(DF_CURSOR_COLOR_MASK, (cursor_color_key->mask & 0xFFFFFF)); 1024f29dbc25Smrg WRITE_VID32(DF_CURSOR_COLOR_1, (cursor_color_key->color1 & 0xFFFFFF)); 1025f29dbc25Smrg WRITE_VID32(DF_CURSOR_COLOR_2, (cursor_color_key->color2 & 0xFFFFFF)); 1026f29dbc25Smrg 1027f29dbc25Smrg return CIM_STATUS_OK; 1028f29dbc25Smrg} 1029f29dbc25Smrg 1030f29dbc25Smrg/*--------------------------------------------------------------------------- 1031f29dbc25Smrg * df_set_video_cursor_color_key_enable 1032f29dbc25Smrg * 1033f29dbc25Smrg * This routine enables or disables the video cursor color key. 1034f29dbc25Smrg *--------------------------------------------------------------------------*/ 1035f29dbc25Smrg 1036f29dbc25Smrgint 1037f29dbc25Smrgdf_set_video_cursor_color_key_enable(int enable) 1038f29dbc25Smrg{ 1039f29dbc25Smrg unsigned long temp = READ_VID32(DF_CURSOR_COLOR_KEY); 1040f29dbc25Smrg 1041f29dbc25Smrg if (enable) 1042f29dbc25Smrg temp |= DF_CURSOR_COLOR_KEY_ENABLE; 1043f29dbc25Smrg else 1044f29dbc25Smrg temp &= ~DF_CURSOR_COLOR_KEY_ENABLE; 1045f29dbc25Smrg 1046f29dbc25Smrg WRITE_VID32(DF_CURSOR_COLOR_KEY, temp); 1047f29dbc25Smrg 1048f29dbc25Smrg return CIM_STATUS_OK; 1049f29dbc25Smrg} 1050f29dbc25Smrg 1051f29dbc25Smrg/*--------------------------------------------------------------------------- 1052f29dbc25Smrg * df_configure_alpha_window 1053f29dbc25Smrg * 1054f29dbc25Smrg * This routine configures one of the three hardware alpha regions. 1055f29dbc25Smrg *--------------------------------------------------------------------------*/ 1056f29dbc25Smrg 1057f29dbc25Smrgint 1058f29dbc25Smrgdf_configure_alpha_window(int window, DF_ALPHA_REGION_PARAMS * alpha_data) 1059f29dbc25Smrg{ 1060f29dbc25Smrg unsigned long vsyncend_even, vtotal_even, vactive_even; 1061f29dbc25Smrg unsigned long hsyncend, htotal, hactive; 1062f29dbc25Smrg unsigned long vsyncend, vtotal, vactive; 1063f29dbc25Smrg unsigned long alpha_ctl, pos; 1064f29dbc25Smrg unsigned long hadjust, vadjust; 1065f29dbc25Smrg unsigned long y, height; 1066f29dbc25Smrg unsigned long xstart, xend; 1067f29dbc25Smrg unsigned long ystart, yend; 1068f29dbc25Smrg unsigned long x_copy, width_copy; 1069f29dbc25Smrg unsigned long y_copy, height_copy; 1070f29dbc25Smrg unsigned long scale, src, misc; 1071f29dbc25Smrg unsigned long gfxscale, fbactive; 1072f29dbc25Smrg unsigned long color; 1073f29dbc25Smrg 1074f29dbc25Smrg if (window > 2) 1075f29dbc25Smrg return CIM_STATUS_INVALIDPARAMS; 1076f29dbc25Smrg 1077f29dbc25Smrg hsyncend = ((READ_REG32(DC3_H_SYNC_TIMING) >> 16) & 0xFFF) + 1; 1078f29dbc25Smrg vsyncend = ((READ_REG32(DC3_V_SYNC_TIMING) >> 16) & 0xFFF) + 1; 1079f29dbc25Smrg htotal = ((READ_REG32(DC3_H_ACTIVE_TIMING) >> 16) & 0xFFF) + 1; 1080f29dbc25Smrg vtotal = ((READ_REG32(DC3_V_ACTIVE_TIMING) >> 16) & 0xFFF) + 1; 1081f29dbc25Smrg hactive = (READ_REG32(DC3_H_ACTIVE_TIMING) & 0xFFF) + 1; 1082f29dbc25Smrg vactive = (READ_REG32(DC3_V_ACTIVE_TIMING) & 0xFFF) + 1; 1083f29dbc25Smrg 1084f29dbc25Smrg /* APPLY THE GRAPHICS SCALE */ 1085f29dbc25Smrg 1086f29dbc25Smrg width_copy = alpha_data->width; 1087f29dbc25Smrg height_copy = alpha_data->height; 1088f29dbc25Smrg x_copy = alpha_data->x; 1089f29dbc25Smrg y_copy = alpha_data->y; 1090f29dbc25Smrg 1091f29dbc25Smrg misc = READ_VID32(DF_VID_MISC); 1092f29dbc25Smrg if (misc & DF_USER_IMPLICIT_SCALING) { 1093f29dbc25Smrg gfxscale = READ_REG32(DC3_GFX_SCALE); 1094f29dbc25Smrg fbactive = READ_REG32(DC3_FB_ACTIVE); 1095f29dbc25Smrg 1096f29dbc25Smrg /* REVERSE ENGINEER THE SCALE FACTOR */ 1097f29dbc25Smrg 1098f29dbc25Smrg scale = gfxscale & 0xFFFF; 1099f29dbc25Smrg src = (fbactive >> 16) + 1; 1100f29dbc25Smrg if (scale != 0x4000) { 1101f29dbc25Smrg width_copy = width_copy * (((0x4000 * src) / scale) + 1); 1102f29dbc25Smrg width_copy /= src; 1103f29dbc25Smrg x_copy = x_copy * (((0x4000 * src) / scale) + 1); 1104f29dbc25Smrg x_copy /= src; 1105f29dbc25Smrg } 1106f29dbc25Smrg 1107f29dbc25Smrg scale = gfxscale >> 16; 1108f29dbc25Smrg src = (fbactive & 0xFFFF) + 1; 1109f29dbc25Smrg if (scale != 0x4000) { 1110f29dbc25Smrg height_copy = height_copy * (((0x4000 * src) / scale) + 1); 1111f29dbc25Smrg height_copy /= src; 1112f29dbc25Smrg y_copy = y_copy * (((0x4000 * src) / scale) + 1); 1113f29dbc25Smrg y_copy /= src; 1114f29dbc25Smrg } 1115f29dbc25Smrg } 1116f29dbc25Smrg 1117f29dbc25Smrg /* SET PRIORITY */ 1118f29dbc25Smrg /* Priority is the only alpha parameter that is not in a register that */ 1119f29dbc25Smrg /* can be indexed based on the alpha window number. */ 1120f29dbc25Smrg 1121f29dbc25Smrg pos = 16 + (window << 1); 1122f29dbc25Smrg alpha_ctl = READ_VID32(DF_VID_ALPHA_CONTROL) & ~(3L << pos); 1123f29dbc25Smrg alpha_ctl |= (alpha_data->priority & 3) << pos; 1124f29dbc25Smrg WRITE_VID32(DF_VID_ALPHA_CONTROL, alpha_ctl); 1125f29dbc25Smrg 1126f29dbc25Smrg /* HANDLE INTERLACED MODES */ 1127f29dbc25Smrg 1128f29dbc25Smrg if (READ_REG32(DC3_IRQ_FILT_CTL) & DC3_IRQFILT_INTL_EN) { 1129f29dbc25Smrg vsyncend_even = ((READ_REG32(DC3_V_SYNC_EVEN) >> 16) & 0xFFF) + 1; 1130f29dbc25Smrg vtotal_even = ((READ_REG32(DC3_V_ACTIVE_EVEN) >> 16) & 0xFFF) + 1; 1131f29dbc25Smrg vactive_even = (READ_REG32(DC3_V_ACTIVE_EVEN) & 0xFFF) + 1; 1132f29dbc25Smrg 1133f29dbc25Smrg y = y_copy >> 1; 1134f29dbc25Smrg 1135f29dbc25Smrg /* SET Y POSITION FOR ODD FIELD */ 1136f29dbc25Smrg 1137f29dbc25Smrg height = (height_copy + 1) >> 1; 1138f29dbc25Smrg vadjust = vtotal_even - vsyncend_even + 1; 1139f29dbc25Smrg 1140f29dbc25Smrg ystart = y + vadjust; 1141f29dbc25Smrg yend = y + vadjust + height; 1142f29dbc25Smrg 1143f29dbc25Smrg if (yend > (vactive + vadjust)) 1144f29dbc25Smrg yend = vactive + vadjust; 1145f29dbc25Smrg 1146f29dbc25Smrg WRITE_VID32((DF_ALPHA_YPOS_1 + (window << 5)), 1147f29dbc25Smrg (ystart | (yend << 16))); 1148f29dbc25Smrg 1149f29dbc25Smrg /* SET Y POSITION FOR EVEN FIELD */ 1150f29dbc25Smrg 1151f29dbc25Smrg height = height_copy >> 1; 1152f29dbc25Smrg vadjust = vtotal - vsyncend + 1; 1153f29dbc25Smrg 1154f29dbc25Smrg ystart = y + vadjust; 1155f29dbc25Smrg yend = y + vadjust + height; 1156f29dbc25Smrg 1157f29dbc25Smrg if (yend > (vactive_even + vadjust)) 1158f29dbc25Smrg yend = vactive_even + vadjust; 1159f29dbc25Smrg 1160f29dbc25Smrg WRITE_VID32((DF_VID_ALPHA_Y_EVEN_1 + (window << 3)), 1161f29dbc25Smrg (ystart | (yend << 16))); 1162f29dbc25Smrg } else { 1163f29dbc25Smrg y = y_copy; 1164f29dbc25Smrg height = height_copy; 1165f29dbc25Smrg vadjust = vtotal - vsyncend + 1; 1166f29dbc25Smrg 1167f29dbc25Smrg ystart = y + vadjust; 1168f29dbc25Smrg yend = y + vadjust + height; 1169f29dbc25Smrg 1170f29dbc25Smrg if (yend > (vactive + vadjust)) 1171f29dbc25Smrg yend = vactive + vadjust; 1172f29dbc25Smrg 1173f29dbc25Smrg WRITE_VID32((DF_ALPHA_YPOS_1 + (window << 5)), 1174f29dbc25Smrg (ystart | (yend << 16))); 1175f29dbc25Smrg } 1176f29dbc25Smrg 1177f29dbc25Smrg /* SET ALPHA X POSITION */ 1178f29dbc25Smrg /* The x position is the same for both the odd and even fields. */ 1179f29dbc25Smrg 1180f29dbc25Smrg hadjust = htotal - hsyncend - 2; 1181f29dbc25Smrg 1182f29dbc25Smrg xstart = x_copy + hadjust; 1183f29dbc25Smrg xend = x_copy + hadjust + width_copy; 1184f29dbc25Smrg 1185f29dbc25Smrg if (xend > (hactive + hadjust)) 1186f29dbc25Smrg xend = hactive + hadjust; 1187f29dbc25Smrg 1188f29dbc25Smrg WRITE_VID32((DF_ALPHA_XPOS_1 + (window << 5)), (xstart | (xend << 16))); 1189f29dbc25Smrg 1190f29dbc25Smrg /* SET COLOR REGISTER */ 1191f29dbc25Smrg 1192f29dbc25Smrg color = alpha_data->color & 0xFFFFFF; 1193f29dbc25Smrg if (alpha_data->flags & DF_ALPHAFLAG_COLORENABLED) 1194f29dbc25Smrg color |= DF_ALPHA_COLOR_ENABLE; 1195f29dbc25Smrg 1196f29dbc25Smrg WRITE_VID32((DF_ALPHA_COLOR_1 + (window << 5)), color); 1197f29dbc25Smrg 1198f29dbc25Smrg /* SET ALPHA VALUE, DELTA AND PER PIXEL */ 1199f29dbc25Smrg 1200f29dbc25Smrg alpha_ctl = READ_VID32(DF_ALPHA_CONTROL_1 + (window << 5)) & 1201f29dbc25Smrg DF_ACTRL_WIN_ENABLE; 1202f29dbc25Smrg alpha_ctl |= (alpha_data->alpha_value & 0xFF) | DF_ACTRL_LOAD_ALPHA | 1203f29dbc25Smrg (((unsigned long)alpha_data->delta & 0xFF) << 8); 1204f29dbc25Smrg if (alpha_data->flags & DF_ALPHAFLAG_PERPIXELENABLED) 1205f29dbc25Smrg alpha_ctl |= DF_ACTRL_PERPIXEL_EN; 1206f29dbc25Smrg 1207f29dbc25Smrg WRITE_VID32((DF_ALPHA_CONTROL_1 + (window << 5)), alpha_ctl); 1208f29dbc25Smrg 1209f29dbc25Smrg return CIM_STATUS_OK; 1210f29dbc25Smrg} 1211f29dbc25Smrg 1212f29dbc25Smrg/*--------------------------------------------------------------------------- 1213f29dbc25Smrg * df_set_alpha_window_enable 1214f29dbc25Smrg * 1215f29dbc25Smrg * This routine enables or disables one of the three hardware alpha regions. 1216f29dbc25Smrg *--------------------------------------------------------------------------*/ 1217f29dbc25Smrg 1218f29dbc25Smrgint 1219f29dbc25Smrgdf_set_alpha_window_enable(int window, int enable) 1220f29dbc25Smrg{ 1221f29dbc25Smrg unsigned long alpha_ctl; 1222f29dbc25Smrg 1223f29dbc25Smrg if (window > 2) 1224f29dbc25Smrg return CIM_STATUS_INVALIDPARAMS; 1225f29dbc25Smrg 1226f29dbc25Smrg alpha_ctl = READ_VID32(DF_ALPHA_CONTROL_1 + (window << 5)); 1227f29dbc25Smrg if (enable) 1228f29dbc25Smrg alpha_ctl |= DF_ACTRL_WIN_ENABLE; 1229f29dbc25Smrg else 1230f29dbc25Smrg alpha_ctl &= ~DF_ACTRL_WIN_ENABLE; 1231f29dbc25Smrg WRITE_VID32((DF_ALPHA_CONTROL_1 + (window << 5)), alpha_ctl); 1232f29dbc25Smrg 1233f29dbc25Smrg return CIM_STATUS_OK; 1234f29dbc25Smrg} 1235f29dbc25Smrg 1236f29dbc25Smrg/*--------------------------------------------------------------------------- 1237f29dbc25Smrg * df_set_no_ck_outside_alpha 1238f29dbc25Smrg * 1239f29dbc25Smrg * This function affects how color/chroma keying is performed inside the video 1240f29dbc25Smrg * window. 1241f29dbc25Smrg * 1242f29dbc25Smrg * If enable is 1, color/chroma key comparison is performed only inside 1243f29dbc25Smrg * the enabled alpha windows. Outside the enabled alpha windows, video 1244f29dbc25Smrg * is displayed if color keying is enabled, or graphics is displayed if 1245f29dbc25Smrg * chroma keying is enabled. 1246f29dbc25Smrg * If enable is 0, color/chroma key comparison is performed inside the 1247f29dbc25Smrg * entire video window. 1248f29dbc25Smrg *--------------------------------------------------------------------------*/ 1249f29dbc25Smrg 1250f29dbc25Smrgint 1251f29dbc25Smrgdf_set_no_ck_outside_alpha(int enable) 1252f29dbc25Smrg{ 1253f29dbc25Smrg unsigned long value; 1254f29dbc25Smrg 1255f29dbc25Smrg value = READ_VID32(DF_VID_ALPHA_CONTROL); 1256f29dbc25Smrg if (enable) 1257f29dbc25Smrg value |= DF_NO_CK_OUTSIDE_ALPHA; 1258f29dbc25Smrg else 1259f29dbc25Smrg value &= ~DF_NO_CK_OUTSIDE_ALPHA; 1260f29dbc25Smrg WRITE_VID32(DF_VID_ALPHA_CONTROL, value); 1261f29dbc25Smrg 1262f29dbc25Smrg return CIM_STATUS_OK; 1263f29dbc25Smrg} 1264f29dbc25Smrg 1265f29dbc25Smrg/*--------------------------------------------------------------------------- 1266f29dbc25Smrg * df_set_video_request 1267f29dbc25Smrg * 1268f29dbc25Smrg * This routine sets the horizontal (pixel) and vertical (line) video request 1269f29dbc25Smrg * values. 1270f29dbc25Smrg *--------------------------------------------------------------------------*/ 1271f29dbc25Smrg 1272f29dbc25Smrgint 1273f29dbc25Smrgdf_set_video_request(unsigned long x, unsigned long y) 1274f29dbc25Smrg{ 1275f29dbc25Smrg unsigned long htotal, hsyncend; 1276f29dbc25Smrg unsigned long vtotal, vsyncend; 1277f29dbc25Smrg 1278f29dbc25Smrg hsyncend = ((READ_REG32(DC3_H_SYNC_TIMING) >> 16) & 0xFFF) + 1; 1279f29dbc25Smrg vsyncend = ((READ_REG32(DC3_V_SYNC_TIMING) >> 16) & 0xFFF) + 1; 1280f29dbc25Smrg htotal = ((READ_REG32(DC3_H_ACTIVE_TIMING) >> 16) & 0xFFF) + 1; 1281f29dbc25Smrg vtotal = ((READ_REG32(DC3_V_ACTIVE_TIMING) >> 16) & 0xFFF) + 1; 1282f29dbc25Smrg 1283f29dbc25Smrg /* SET DISPLAY FILTER VIDEO REQUEST */ 1284f29dbc25Smrg 1285f29dbc25Smrg x += htotal - hsyncend - 2; 1286f29dbc25Smrg y += vtotal - vsyncend + 1; 1287f29dbc25Smrg 1288f29dbc25Smrg if (x >= 0x1000 || y >= 0x800) 1289f29dbc25Smrg return CIM_STATUS_INVALIDPARAMS; 1290f29dbc25Smrg 1291f29dbc25Smrg WRITE_VID32(DF_VIDEO_REQUEST, (y | (x << 16))); 1292f29dbc25Smrg return CIM_STATUS_OK; 1293f29dbc25Smrg} 1294f29dbc25Smrg 1295f29dbc25Smrg/*--------------------------------------------------------------------------- 1296f29dbc25Smrg * df_set_output_color_space 1297f29dbc25Smrg * 1298f29dbc25Smrg * This routine sets the color space used when combining graphics and video. 1299f29dbc25Smrg *--------------------------------------------------------------------------*/ 1300f29dbc25Smrg 1301f29dbc25Smrgint 1302f29dbc25Smrgdf_set_output_color_space(int color_space) 1303f29dbc25Smrg{ 1304f29dbc25Smrg unsigned long alpha_ctl; 1305f29dbc25Smrg 1306f29dbc25Smrg alpha_ctl = READ_VID32(DF_VID_ALPHA_CONTROL); 1307f29dbc25Smrg 1308f29dbc25Smrg alpha_ctl &= ~(DF_CSC_GRAPHICS_RGB_TO_YUV | DF_CSC_VIDEO_YUV_TO_RGB | 1309f29dbc25Smrg DF_HD_GRAPHICS | DF_YUV_CSC_EN | DF_ALPHA_DRGB); 1310f29dbc25Smrg 1311f29dbc25Smrg /* OUTPUT IS RGB */ 1312f29dbc25Smrg /* Enable YUV->RGB CSC if necessary and enable alpha output if */ 1313f29dbc25Smrg /* requested. */ 1314f29dbc25Smrg 1315f29dbc25Smrg if (color_space == DF_OUTPUT_RGB || color_space == DF_OUTPUT_ARGB) { 1316f29dbc25Smrg if (!(alpha_ctl & DF_VIDEO_INPUT_IS_RGB)) 1317f29dbc25Smrg alpha_ctl |= DF_CSC_VIDEO_YUV_TO_RGB; 1318f29dbc25Smrg 1319f29dbc25Smrg if (color_space == DF_OUTPUT_ARGB) 1320f29dbc25Smrg alpha_ctl |= DF_ALPHA_DRGB; 1321f29dbc25Smrg } 1322f29dbc25Smrg 1323f29dbc25Smrg /* OUTPUT IS YUV */ 1324f29dbc25Smrg /* Enable YUV->YUV CSC if necessary and enable RGB->YUV CSC. */ 1325f29dbc25Smrg 1326f29dbc25Smrg else if (color_space == DF_OUTPUT_SDTV || color_space == DF_OUTPUT_HDTV) { 1327f29dbc25Smrg alpha_ctl |= DF_CSC_GRAPHICS_RGB_TO_YUV; 1328f29dbc25Smrg 1329f29dbc25Smrg if (((alpha_ctl & DF_HD_VIDEO) && color_space == DF_OUTPUT_SDTV) || 1330f29dbc25Smrg (!(alpha_ctl & DF_HD_VIDEO) && color_space == DF_OUTPUT_HDTV)) { 1331f29dbc25Smrg alpha_ctl |= DF_YUV_CSC_EN; 1332f29dbc25Smrg } 1333f29dbc25Smrg 1334f29dbc25Smrg if (color_space == DF_OUTPUT_HDTV) 1335f29dbc25Smrg alpha_ctl |= DF_HD_GRAPHICS; 1336f29dbc25Smrg } else 1337f29dbc25Smrg return CIM_STATUS_INVALIDPARAMS; 1338f29dbc25Smrg 1339f29dbc25Smrg WRITE_VID32(DF_VID_ALPHA_CONTROL, alpha_ctl); 1340f29dbc25Smrg 1341f29dbc25Smrg return CIM_STATUS_OK; 1342f29dbc25Smrg} 1343f29dbc25Smrg 1344f29dbc25Smrg/*--------------------------------------------------------------------------- 1345f29dbc25Smrg * df_set_output_path 1346f29dbc25Smrg * 1347f29dbc25Smrg * This routine changes the current output path in the display filter. 1348f29dbc25Smrg *--------------------------------------------------------------------------*/ 1349f29dbc25Smrg 1350f29dbc25Smrgint 1351f29dbc25Smrgdf_set_output_path(int format) 1352f29dbc25Smrg{ 1353f29dbc25Smrg unsigned long panel_tim2, panel_pm; 1354f29dbc25Smrg unsigned long output = 0; 1355f29dbc25Smrg Q_WORD msr_value; 1356f29dbc25Smrg 1357f29dbc25Smrg msr_read64(MSR_DEVICE_GEODELX_DF, MSR_GEODELINK_CONFIG, &msr_value); 1358f29dbc25Smrg msr_value.low &= ~(DF_SIMULTANEOUS_CRT_FP | DF_CONFIG_OUTPUT_MASK); 1359f29dbc25Smrg panel_tim2 = READ_VID32(DF_VIDEO_PANEL_TIM2); 1360f29dbc25Smrg panel_pm = READ_VID32(DF_POWER_MANAGEMENT); 1361f29dbc25Smrg 1362f29dbc25Smrg if (format == DF_DISPLAY_CRT) { 1363f29dbc25Smrg /* SiBZ #4188 */ 1364f29dbc25Smrg /* When CRT output is selected, the DF drives the DISP_EN signal */ 1365f29dbc25Smrg /* with the CRT display enable. As a consequence, systems that */ 1366f29dbc25Smrg /* wire the DISP_EN signal to the TFT backlight control will not */ 1367f29dbc25Smrg /* be able to set CRT-only output without leaving the backlight */ 1368f29dbc25Smrg /* enabled. To workaround this issue, we are setting simultaneous */ 1369f29dbc25Smrg /* TFT/CRT and disabling the TFT logic. The only caveat to this */ 1370f29dbc25Smrg /* is that some TFT pins are shared with VIP 601 pins. VIP 601 */ 1371f29dbc25Smrg /* will thus not work when in this pseudo-CRT mode. To address */ 1372f29dbc25Smrg /* THAT issue, normal CRT mode sets (in cim_vg.c) will set CRT */ 1373f29dbc25Smrg /* as the DF output format. This will allow VIP 601 on CRT-only */ 1374f29dbc25Smrg /* systems without a TFT attached. */ 1375f29dbc25Smrg 1376f29dbc25Smrg panel_pm &= ~DF_PM_PANEL_ON; 1377f29dbc25Smrg panel_tim2 |= DF_PMTIM2_TFT_PASSHTHROUGH; 1378f29dbc25Smrg output = DF_OUTPUT_PANEL | DF_SIMULTANEOUS_CRT_FP; 1379f29dbc25Smrg } else if (format == DF_DISPLAY_FP || format == DF_DISPLAY_CRT_FP) { 1380f29dbc25Smrg panel_pm |= DF_PM_PANEL_ON; 1381f29dbc25Smrg panel_tim2 &= ~DF_PMTIM2_TFT_PASSHTHROUGH; 1382f29dbc25Smrg 1383f29dbc25Smrg if (format == DF_DISPLAY_FP) 1384f29dbc25Smrg output = DF_OUTPUT_PANEL; 1385f29dbc25Smrg else if (format == DF_DISPLAY_CRT_FP) 1386f29dbc25Smrg output = DF_OUTPUT_PANEL | DF_SIMULTANEOUS_CRT_FP; 1387f29dbc25Smrg } else { 1388f29dbc25Smrg switch (format) { 1389f29dbc25Smrg case DF_DISPLAY_VOP: 1390f29dbc25Smrg output = DF_OUTPUT_VOP; 1391f29dbc25Smrg break; 1392f29dbc25Smrg case DF_DISPLAY_DRGB: 1393f29dbc25Smrg output = DF_OUTPUT_DRGB; 1394f29dbc25Smrg break; 1395f29dbc25Smrg case DF_DISPLAY_CRT_DRGB: 1396f29dbc25Smrg output = DF_OUTPUT_DRGB | DF_SIMULTANEOUS_CRT_FP; 1397f29dbc25Smrg break; 1398f29dbc25Smrg default: 1399f29dbc25Smrg return CIM_STATUS_INVALIDPARAMS; 1400f29dbc25Smrg } 1401f29dbc25Smrg } 1402f29dbc25Smrg msr_value.low |= output; 1403f29dbc25Smrg msr_write64(MSR_DEVICE_GEODELX_DF, MSR_GEODELINK_CONFIG, &msr_value); 1404f29dbc25Smrg WRITE_VID32(DF_VIDEO_PANEL_TIM2, panel_tim2); 1405f29dbc25Smrg WRITE_VID32(DF_POWER_MANAGEMENT, panel_pm); 1406f29dbc25Smrg 1407f29dbc25Smrg return CIM_STATUS_OK; 1408f29dbc25Smrg} 1409f29dbc25Smrg 1410f29dbc25Smrg/*--------------------------------------------------------------------------- 1411f29dbc25Smrg * df_test_video_flip_status 1412f29dbc25Smrg * 1413f29dbc25Smrg * This routine tests if a new video offset has been latched. 1414f29dbc25Smrg *--------------------------------------------------------------------------*/ 1415f29dbc25Smrg 1416f29dbc25Smrgunsigned long 1417f29dbc25Smrgdf_test_video_flip_status(void) 1418f29dbc25Smrg{ 1419f29dbc25Smrg return (READ_REG32(DC3_LINE_CNT_STATUS) & DC3_LNCNT_VFLIP); 1420f29dbc25Smrg} 1421f29dbc25Smrg 1422f29dbc25Smrg/*--------------------------------------------------------------------------- 1423f29dbc25Smrg * df_save_state 1424f29dbc25Smrg * 1425f29dbc25Smrg * This routine saves all persistent DF state information. 1426f29dbc25Smrg *--------------------------------------------------------------------------*/ 1427f29dbc25Smrg 1428f29dbc25Smrgint 1429f29dbc25Smrgdf_save_state(DF_SAVE_RESTORE * df_state) 1430f29dbc25Smrg{ 1431f29dbc25Smrg unsigned long i; 1432f29dbc25Smrg 1433f29dbc25Smrg /* READ ALL DF REGISTERS */ 1434f29dbc25Smrg 1435f29dbc25Smrg df_state->vcfg = READ_VID32(DF_VIDEO_CONFIG); 1436f29dbc25Smrg df_state->dcfg = READ_VID32(DF_DISPLAY_CONFIG); 1437f29dbc25Smrg df_state->video_x = READ_VID32(DF_VIDEO_X_POS); 1438f29dbc25Smrg df_state->video_y = READ_VID32(DF_VIDEO_Y_POS); 1439f29dbc25Smrg df_state->video_scaler = READ_VID32(DF_VIDEO_SCALER); 1440f29dbc25Smrg df_state->video_color_key = READ_VID32(DF_VIDEO_COLOR_KEY); 1441f29dbc25Smrg df_state->video_color_mask = READ_VID32(DF_VIDEO_COLOR_MASK); 1442f29dbc25Smrg df_state->sat_limit = READ_VID32(DF_SATURATION_LIMIT); 1443f29dbc25Smrg df_state->vid_misc = READ_VID32(DF_VID_MISC); 1444f29dbc25Smrg df_state->video_yscale = READ_VID32(DF_VIDEO_YSCALE); 1445f29dbc25Smrg df_state->video_xscale = READ_VID32(DF_VIDEO_XSCALE); 1446f29dbc25Smrg df_state->vid_alpha_control = READ_VID32(DF_VID_ALPHA_CONTROL); 1447f29dbc25Smrg df_state->cursor_key = READ_VID32(DF_CURSOR_COLOR_KEY); 1448f29dbc25Smrg df_state->cursor_mask = READ_VID32(DF_CURSOR_COLOR_MASK); 1449f29dbc25Smrg df_state->cursor_color1 = READ_VID32(DF_CURSOR_COLOR_1); 1450f29dbc25Smrg df_state->cursor_color2 = READ_VID32(DF_CURSOR_COLOR_2); 1451f29dbc25Smrg df_state->alpha_xpos1 = READ_VID32(DF_ALPHA_XPOS_1); 1452f29dbc25Smrg df_state->alpha_ypos1 = READ_VID32(DF_ALPHA_YPOS_1); 1453f29dbc25Smrg df_state->alpha_color1 = READ_VID32(DF_ALPHA_COLOR_1); 1454f29dbc25Smrg df_state->alpha_control1 = READ_VID32(DF_ALPHA_CONTROL_1); 1455f29dbc25Smrg df_state->alpha_xpos2 = READ_VID32(DF_ALPHA_XPOS_2); 1456f29dbc25Smrg df_state->alpha_ypos2 = READ_VID32(DF_ALPHA_YPOS_2); 1457f29dbc25Smrg df_state->alpha_color2 = READ_VID32(DF_ALPHA_COLOR_2); 1458f29dbc25Smrg df_state->alpha_control2 = READ_VID32(DF_ALPHA_CONTROL_2); 1459f29dbc25Smrg df_state->alpha_xpos3 = READ_VID32(DF_ALPHA_XPOS_3); 1460f29dbc25Smrg df_state->alpha_ypos3 = READ_VID32(DF_ALPHA_YPOS_3); 1461f29dbc25Smrg df_state->alpha_color3 = READ_VID32(DF_ALPHA_COLOR_3); 1462f29dbc25Smrg df_state->alpha_control3 = READ_VID32(DF_ALPHA_CONTROL_3); 1463f29dbc25Smrg df_state->vid_request = READ_VID32(DF_VIDEO_REQUEST); 1464f29dbc25Smrg df_state->vid_ypos_even = READ_VID32(DF_VID_YPOS_EVEN); 1465f29dbc25Smrg df_state->alpha_ypos_even1 = READ_VID32(DF_VID_ALPHA_Y_EVEN_1); 1466f29dbc25Smrg df_state->alpha_ypos_even2 = READ_VID32(DF_VID_ALPHA_Y_EVEN_2); 1467f29dbc25Smrg df_state->alpha_ypos_even3 = READ_VID32(DF_VID_ALPHA_Y_EVEN_3); 1468f29dbc25Smrg df_state->panel_tim1 = READ_VID32(DF_VIDEO_PANEL_TIM1); 1469f29dbc25Smrg df_state->panel_tim2 = READ_VID32(DF_VIDEO_PANEL_TIM2); 1470f29dbc25Smrg df_state->panel_pm = READ_VID32(DF_POWER_MANAGEMENT); 1471f29dbc25Smrg df_state->panel_dither = READ_VID32(DF_DITHER_CONTROL); 1472f29dbc25Smrg 1473f29dbc25Smrg /* READ DF PALETTE */ 1474f29dbc25Smrg 1475f29dbc25Smrg WRITE_VID32(DF_PALETTE_ADDRESS, 0); 1476f29dbc25Smrg for (i = 0; i < 256; i++) 1477f29dbc25Smrg df_state->palette[i] = READ_VID32(DF_PALETTE_DATA); 1478f29dbc25Smrg 1479f29dbc25Smrg /* READ FILTER COEFFICIENTS */ 1480f29dbc25Smrg 1481f29dbc25Smrg for (i = 0; i < 512; i++) 1482f29dbc25Smrg df_state->coefficients[i] = 1483f29dbc25Smrg READ_VID32(DF_COEFFICIENT_BASE + (i << 2)); 1484f29dbc25Smrg 1485f29dbc25Smrg /* READ ALL DF MSRS */ 1486f29dbc25Smrg 1487f29dbc25Smrg msr_read64(MSR_DEVICE_GEODELX_DF, MSR_GEODELINK_CAP, 1488f29dbc25Smrg &(df_state->msr_cap)); 1489f29dbc25Smrg msr_read64(MSR_DEVICE_GEODELX_DF, MSR_GEODELINK_CONFIG, 1490f29dbc25Smrg &(df_state->msr_config)); 1491f29dbc25Smrg msr_read64(MSR_DEVICE_GEODELX_DF, MSR_GEODELINK_SMI, 1492f29dbc25Smrg &(df_state->msr_smi)); 1493f29dbc25Smrg msr_read64(MSR_DEVICE_GEODELX_DF, MSR_GEODELINK_ERROR, 1494f29dbc25Smrg &(df_state->msr_error)); 1495f29dbc25Smrg msr_read64(MSR_DEVICE_GEODELX_DF, MSR_GEODELINK_PM, &(df_state->msr_pm)); 1496f29dbc25Smrg msr_read64(MSR_DEVICE_GEODELX_DF, MSR_GEODELINK_DIAG, 1497f29dbc25Smrg &(df_state->msr_diag)); 1498f29dbc25Smrg msr_read64(MSR_DEVICE_GEODELX_DF, DF_MBD_MSR_DIAG_DF, 1499f29dbc25Smrg &(df_state->msr_df_diag)); 1500f29dbc25Smrg msr_read64(MSR_DEVICE_GEODELX_DF, DF_MSR_PAD_SEL, 1501f29dbc25Smrg &(df_state->msr_pad_sel)); 1502f29dbc25Smrg 1503f29dbc25Smrg return CIM_STATUS_OK; 1504f29dbc25Smrg} 1505f29dbc25Smrg 1506f29dbc25Smrg/*--------------------------------------------------------------------------- 1507f29dbc25Smrg * df_restore_state 1508f29dbc25Smrg * 1509f29dbc25Smrg * This routine restores all persistent DF state information. 1510f29dbc25Smrg *--------------------------------------------------------------------------*/ 1511f29dbc25Smrg 1512f29dbc25Smrgint 1513f29dbc25Smrgdf_restore_state(DF_SAVE_RESTORE * df_state) 1514f29dbc25Smrg{ 1515f29dbc25Smrg unsigned long i; 1516f29dbc25Smrg 1517f29dbc25Smrg /* CLEAR VCFG AND DCFG */ 1518f29dbc25Smrg 1519f29dbc25Smrg WRITE_VID32(DF_VIDEO_CONFIG, 0); 1520f29dbc25Smrg WRITE_VID32(DF_DISPLAY_CONFIG, 0); 1521f29dbc25Smrg 1522f29dbc25Smrg /* RESTORE DF MSRS */ 1523f29dbc25Smrg 1524f29dbc25Smrg msr_write64(MSR_DEVICE_GEODELX_DF, MSR_GEODELINK_CAP, 1525f29dbc25Smrg &(df_state->msr_cap)); 1526f29dbc25Smrg msr_write64(MSR_DEVICE_GEODELX_DF, MSR_GEODELINK_CONFIG, 1527f29dbc25Smrg &(df_state->msr_config)); 1528f29dbc25Smrg msr_write64(MSR_DEVICE_GEODELX_DF, MSR_GEODELINK_SMI, 1529f29dbc25Smrg &(df_state->msr_smi)); 1530f29dbc25Smrg msr_write64(MSR_DEVICE_GEODELX_DF, MSR_GEODELINK_ERROR, 1531f29dbc25Smrg &(df_state->msr_error)); 1532f29dbc25Smrg msr_write64(MSR_DEVICE_GEODELX_DF, MSR_GEODELINK_PM, &(df_state->msr_pm)); 1533f29dbc25Smrg msr_write64(MSR_DEVICE_GEODELX_DF, MSR_GEODELINK_DIAG, 1534f29dbc25Smrg &(df_state->msr_diag)); 1535f29dbc25Smrg msr_write64(MSR_DEVICE_GEODELX_DF, DF_MBD_MSR_DIAG_DF, 1536f29dbc25Smrg &(df_state->msr_df_diag)); 1537f29dbc25Smrg msr_write64(MSR_DEVICE_GEODELX_DF, DF_MSR_PAD_SEL, 1538f29dbc25Smrg &(df_state->msr_pad_sel)); 1539f29dbc25Smrg 1540f29dbc25Smrg /* RESTORE ALL DF REGISTERS */ 1541f29dbc25Smrg 1542f29dbc25Smrg WRITE_VID32(DF_VIDEO_X_POS, df_state->video_x); 1543f29dbc25Smrg WRITE_VID32(DF_VIDEO_Y_POS, df_state->video_y); 1544f29dbc25Smrg WRITE_VID32(DF_VIDEO_SCALER, df_state->video_scaler); 1545f29dbc25Smrg WRITE_VID32(DF_VIDEO_COLOR_KEY, df_state->video_color_key); 1546f29dbc25Smrg WRITE_VID32(DF_VIDEO_COLOR_MASK, df_state->video_color_mask); 1547f29dbc25Smrg WRITE_VID32(DF_SATURATION_LIMIT, df_state->sat_limit); 1548f29dbc25Smrg WRITE_VID32(DF_VID_MISC, df_state->vid_misc); 1549f29dbc25Smrg WRITE_VID32(DF_VIDEO_YSCALE, df_state->video_yscale); 1550f29dbc25Smrg WRITE_VID32(DF_VIDEO_XSCALE, df_state->video_xscale); 1551f29dbc25Smrg WRITE_VID32(DF_VID_ALPHA_CONTROL, df_state->vid_alpha_control); 1552f29dbc25Smrg WRITE_VID32(DF_CURSOR_COLOR_KEY, df_state->cursor_key); 1553f29dbc25Smrg WRITE_VID32(DF_CURSOR_COLOR_MASK, df_state->cursor_mask); 1554f29dbc25Smrg WRITE_VID32(DF_CURSOR_COLOR_1, df_state->cursor_color1); 1555f29dbc25Smrg WRITE_VID32(DF_CURSOR_COLOR_2, df_state->cursor_color2); 1556f29dbc25Smrg WRITE_VID32(DF_ALPHA_XPOS_1, df_state->alpha_xpos1); 1557f29dbc25Smrg WRITE_VID32(DF_ALPHA_YPOS_1, df_state->alpha_ypos1); 1558f29dbc25Smrg WRITE_VID32(DF_ALPHA_COLOR_1, df_state->alpha_color1); 1559f29dbc25Smrg WRITE_VID32(DF_ALPHA_CONTROL_1, df_state->alpha_control1); 1560f29dbc25Smrg WRITE_VID32(DF_ALPHA_XPOS_2, df_state->alpha_xpos2); 1561f29dbc25Smrg WRITE_VID32(DF_ALPHA_YPOS_2, df_state->alpha_ypos2); 1562f29dbc25Smrg WRITE_VID32(DF_ALPHA_COLOR_2, df_state->alpha_color2); 1563f29dbc25Smrg WRITE_VID32(DF_ALPHA_CONTROL_2, df_state->alpha_control1); 1564f29dbc25Smrg WRITE_VID32(DF_ALPHA_XPOS_3, df_state->alpha_xpos3); 1565f29dbc25Smrg WRITE_VID32(DF_ALPHA_YPOS_3, df_state->alpha_ypos3); 1566f29dbc25Smrg WRITE_VID32(DF_ALPHA_COLOR_3, df_state->alpha_color3); 1567f29dbc25Smrg WRITE_VID32(DF_ALPHA_CONTROL_3, df_state->alpha_control3); 1568f29dbc25Smrg WRITE_VID32(DF_VIDEO_REQUEST, df_state->vid_request); 1569f29dbc25Smrg WRITE_VID32(DF_VID_YPOS_EVEN, df_state->vid_ypos_even); 1570f29dbc25Smrg WRITE_VID32(DF_VID_ALPHA_Y_EVEN_1, df_state->alpha_ypos_even1); 1571f29dbc25Smrg WRITE_VID32(DF_VID_ALPHA_Y_EVEN_2, df_state->alpha_ypos_even2); 1572f29dbc25Smrg WRITE_VID32(DF_VID_ALPHA_Y_EVEN_3, df_state->alpha_ypos_even3); 1573f29dbc25Smrg WRITE_VID32(DF_VIDEO_PANEL_TIM1, df_state->panel_tim1); 1574f29dbc25Smrg WRITE_VID32(DF_VIDEO_PANEL_TIM2, df_state->panel_tim2); 1575f29dbc25Smrg WRITE_VID32(DF_POWER_MANAGEMENT, df_state->panel_pm); 1576f29dbc25Smrg WRITE_VID32(DF_DITHER_CONTROL, df_state->panel_dither); 1577f29dbc25Smrg 1578f29dbc25Smrg /* RESTORE DF PALETTE */ 1579f29dbc25Smrg 1580f29dbc25Smrg WRITE_VID32(DF_PALETTE_ADDRESS, 0); 1581f29dbc25Smrg for (i = 0; i < 256; i++) 1582f29dbc25Smrg WRITE_VID32(DF_PALETTE_DATA, df_state->palette[i]); 1583f29dbc25Smrg 1584f29dbc25Smrg /* RESTORE FILTER COEFFICIENTS */ 1585f29dbc25Smrg 1586f29dbc25Smrg for (i = 0; i < 512; i++) 1587f29dbc25Smrg WRITE_VID32(DF_COEFFICIENT_BASE + (i << 2), 1588f29dbc25Smrg df_state->coefficients[i]); 1589f29dbc25Smrg 1590f29dbc25Smrg /* RESTORE DCFG AND VCFG */ 1591f29dbc25Smrg 1592f29dbc25Smrg WRITE_VID32(DF_DISPLAY_CONFIG, df_state->dcfg); 1593f29dbc25Smrg WRITE_VID32(DF_VIDEO_CONFIG, df_state->vcfg); 1594f29dbc25Smrg 1595f29dbc25Smrg return CIM_STATUS_OK; 1596f29dbc25Smrg} 1597f29dbc25Smrg 1598f29dbc25Smrg/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1599f29dbc25Smrg * CIMARRON DF READ ROUTINES 1600f29dbc25Smrg * These routines are included for use in diagnostics or when debugging. They 1601f29dbc25Smrg * can be optionally excluded from a project. 1602f29dbc25Smrg *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ 1603f29dbc25Smrg 1604f29dbc25Smrg#if CIMARRON_INCLUDE_DF_READ_ROUTINES 1605f29dbc25Smrg 1606f29dbc25Smrg/*--------------------------------------------------------------------------- 1607f29dbc25Smrg * df_read_composite_crc 1608f29dbc25Smrg * 1609f29dbc25Smrg * This routine reads the CRC of the combination of graphics/video data. This 1610f29dbc25Smrg * CRC checks data immediately before the CRT DACs. 1611f29dbc25Smrg *--------------------------------------------------------------------------*/ 1612f29dbc25Smrg 1613f29dbc25Smrgunsigned long 1614f29dbc25Smrgdf_read_composite_crc(int crc_source) 1615f29dbc25Smrg{ 1616f29dbc25Smrg Q_WORD msr_value; 1617f29dbc25Smrg unsigned long crc; 1618f29dbc25Smrg unsigned long interlaced; 1619f29dbc25Smrg unsigned long line, field; 1620f29dbc25Smrg unsigned long timeout = 1000; 1621f29dbc25Smrg 1622f29dbc25Smrg if (!(READ_REG32(DC3_DISPLAY_CFG) & DC3_DCFG_TGEN)) 1623f29dbc25Smrg return 0xFFFFFFFF; 1624f29dbc25Smrg 1625f29dbc25Smrg /* ENABLE 32-BIT CRCS */ 1626f29dbc25Smrg 1627f29dbc25Smrg msr_read64(MSR_DEVICE_GEODELX_DF, DF_MBD_MSR_DIAG_DF, &msr_value); 1628f29dbc25Smrg msr_value.low |= DF_DIAG_32BIT_CRC; 1629f29dbc25Smrg msr_write64(MSR_DEVICE_GEODELX_DF, DF_MBD_MSR_DIAG_DF, &msr_value); 1630f29dbc25Smrg 1631f29dbc25Smrg /* RESET THE CRC */ 1632f29dbc25Smrg 1633f29dbc25Smrg WRITE_VID32(DF_VID_CRC, 0); 1634f29dbc25Smrg 1635f29dbc25Smrg /* WAIT FOR THE RESET TO BE LATCHED */ 1636f29dbc25Smrg 1637f29dbc25Smrg while ((READ_VID32(DF_VID_CRC32) != 0x00000001) && timeout) 1638f29dbc25Smrg timeout--; 1639f29dbc25Smrg 1640f29dbc25Smrg /* WAIT FOR THE CORRECT FIELD */ 1641f29dbc25Smrg /* We use the VG line count and field indicator to determine when */ 1642f29dbc25Smrg /* to kick off a CRC. */ 1643f29dbc25Smrg 1644f29dbc25Smrg if (crc_source & DF_CRC_SOURCE_EVEN) 1645f29dbc25Smrg field = 0; 1646f29dbc25Smrg else 1647f29dbc25Smrg field = DC3_LNCNT_EVEN_FIELD; 1648f29dbc25Smrg 1649f29dbc25Smrg if ((interlaced = (READ_REG32(DC3_IRQ_FILT_CTL) & DC3_IRQFILT_INTL_EN))) { 1650f29dbc25Smrg /* WAIT FOR THE BEGINNING OF THE FIELD (LINE 1-5) */ 1651f29dbc25Smrg /* Note that we wait for the field to be odd when CRCing the even */ 1652f29dbc25Smrg /* field and vice versa. This is because the CRC will not begin */ 1653f29dbc25Smrg /* until the following field. */ 1654f29dbc25Smrg 1655f29dbc25Smrg do { 1656f29dbc25Smrg line = READ_REG32(DC3_LINE_CNT_STATUS); 1657f29dbc25Smrg } while ((line & DC3_LNCNT_EVEN_FIELD) != field || 1658f29dbc25Smrg ((line & DC3_LNCNT_V_LINE_CNT) >> 16) < 10 || 1659f29dbc25Smrg ((line & DC3_LNCNT_V_LINE_CNT) >> 16) > 15); 1660f29dbc25Smrg } else { 1661f29dbc25Smrg /* NON-INTERLACED - EVEN FIELD CRCS ARE INVALID */ 1662f29dbc25Smrg 1663f29dbc25Smrg if (crc_source & DF_CRC_SOURCE_EVEN) 1664f29dbc25Smrg return 0xFFFFFFFF; 1665f29dbc25Smrg } 1666f29dbc25Smrg 1667f29dbc25Smrg /* ENABLE THE CRC */ 1668f29dbc25Smrg 1669f29dbc25Smrg WRITE_VID32(DF_VID_CRC, 1); 1670f29dbc25Smrg 1671f29dbc25Smrg /* WAIT FOR THE CRC TO BE COMPLETED */ 1672f29dbc25Smrg 1673f29dbc25Smrg while (!(READ_VID32(DF_VID_CRC) & 4)) ; 1674f29dbc25Smrg 1675f29dbc25Smrg crc = READ_VID32(DF_VID_CRC32); 1676f29dbc25Smrg 1677f29dbc25Smrg return crc; 1678f29dbc25Smrg} 1679f29dbc25Smrg 1680f29dbc25Smrg/*--------------------------------------------------------------------------- 1681f29dbc25Smrg * df_read_composite_window_crc 1682f29dbc25Smrg * 1683f29dbc25Smrg * This routine reads the CRC of a rectangular subsection of the combination 1684f29dbc25Smrg * of graphics/video data. 1685f29dbc25Smrg *--------------------------------------------------------------------------*/ 1686f29dbc25Smrg 1687f29dbc25Smrgunsigned long 1688f29dbc25Smrgdf_read_composite_window_crc(unsigned long x, unsigned long y, 1689f29dbc25Smrg unsigned long width, unsigned long height, int source) 1690f29dbc25Smrg{ 1691f29dbc25Smrg Q_WORD msr_value; 1692f29dbc25Smrg unsigned long interlaced; 1693f29dbc25Smrg unsigned long line, field; 1694f29dbc25Smrg unsigned long crc = 0; 1695f29dbc25Smrg unsigned long hsyncend, htotal, hsyncstart; 1696f29dbc25Smrg unsigned long vsyncend, vtotal, vsyncstart; 1697f29dbc25Smrg unsigned long hblankstart, hactive; 1698f29dbc25Smrg unsigned long vblankstart, vactive; 1699f29dbc25Smrg 1700f29dbc25Smrg hsyncend = ((READ_REG32(DC3_H_SYNC_TIMING) >> 16) & 0xFFF) + 1; 1701f29dbc25Smrg htotal = ((READ_REG32(DC3_H_ACTIVE_TIMING) >> 16) & 0xFFF) + 1; 1702f29dbc25Smrg hsyncstart = (READ_REG32(DC3_H_SYNC_TIMING) & 0xFFF) + 1; 1703f29dbc25Smrg hactive = (READ_REG32(DC3_H_ACTIVE_TIMING) & 0xFFF) + 1; 1704f29dbc25Smrg hblankstart = (READ_REG32(DC3_H_BLANK_TIMING) & 0xFFF) + 1; 1705f29dbc25Smrg if ((interlaced = (READ_REG32(DC3_IRQ_FILT_CTL) & DC3_IRQFILT_INTL_EN)) && 1706f29dbc25Smrg !(source & DF_CRC_SOURCE_EVEN)) { 1707f29dbc25Smrg vsyncend = ((READ_REG32(DC3_V_SYNC_EVEN) >> 16) & 0xFFF) + 1; 1708f29dbc25Smrg vtotal = ((READ_REG32(DC3_V_ACTIVE_EVEN) >> 16) & 0xFFF) + 1; 1709f29dbc25Smrg vsyncstart = (READ_REG32(DC3_V_SYNC_EVEN) & 0xFFF) + 1; 1710f29dbc25Smrg vactive = (READ_REG32(DC3_V_ACTIVE_EVEN) & 0xFFF) + 1; 1711f29dbc25Smrg vblankstart = (READ_REG32(DC3_V_BLANK_EVEN) & 0xFFF) + 1; 1712f29dbc25Smrg } else { 1713f29dbc25Smrg vsyncend = ((READ_REG32(DC3_V_SYNC_TIMING) >> 16) & 0xFFF) + 1; 1714f29dbc25Smrg vtotal = ((READ_REG32(DC3_V_ACTIVE_TIMING) >> 16) & 0xFFF) + 1; 1715f29dbc25Smrg vsyncstart = (READ_REG32(DC3_V_SYNC_TIMING) & 0xFFF) + 1; 1716f29dbc25Smrg vactive = (READ_REG32(DC3_V_ACTIVE_TIMING) & 0xFFF) + 1; 1717f29dbc25Smrg vblankstart = (READ_REG32(DC3_V_BLANK_TIMING) & 0xFFF) + 1; 1718f29dbc25Smrg } 1719f29dbc25Smrg 1720f29dbc25Smrg /* TIMINGS MUST BE ACTIVE */ 1721f29dbc25Smrg 1722f29dbc25Smrg if (!(READ_REG32(DC3_DISPLAY_CFG) & DC3_DCFG_TGEN)) 1723f29dbc25Smrg return 0xFFFFFFFF; 1724f29dbc25Smrg 1725f29dbc25Smrg /* DISABLE GLCP ACTIONS */ 1726f29dbc25Smrg 1727f29dbc25Smrg msr_value.low = 0; 1728f29dbc25Smrg msr_value.high = 0; 1729f29dbc25Smrg msr_write64(MSR_DEVICE_GEODELX_GLCP, GLCP_DIAGCTL, &msr_value); 1730f29dbc25Smrg 1731f29dbc25Smrg /* ENABLE HW CLOCK GATING AND SET GLCP CLOCK TO DOT CLOCK */ 1732f29dbc25Smrg 1733f29dbc25Smrg msr_value.low = 5; 1734f29dbc25Smrg msr_write64(MSR_DEVICE_GEODELX_GLCP, MSR_GEODELINK_PM, &msr_value); 1735f29dbc25Smrg msr_value.low = 0; 1736f29dbc25Smrg msr_write64(MSR_DEVICE_GEODELX_GLCP, GLCP_DBGCLKCTL, &msr_value); 1737f29dbc25Smrg msr_value.low = 3; 1738f29dbc25Smrg msr_write64(MSR_DEVICE_GEODELX_GLCP, GLCP_DBGCLKCTL, &msr_value); 1739f29dbc25Smrg 1740f29dbc25Smrg /* USE H4 FUNCTION A FOR HSYNC AND H4 FUNCTION B FOR NOT HSYNC */ 1741f29dbc25Smrg /* HSYNC is bit 30 for the DF */ 1742f29dbc25Smrg 1743f29dbc25Smrg msr_value.high = 0x00000001; 1744f29dbc25Smrg msr_value.low = 0xE0000FF0; 1745f29dbc25Smrg msr_write64(MSR_DEVICE_GEODELX_GLCP, GLCP_H0CTL + 4, &msr_value); 1746f29dbc25Smrg 1747f29dbc25Smrg /* USE H3 FUNCTION A FOR VSYNC AND H3 FUNCTION B FOR NOT VSYNC */ 1748f29dbc25Smrg /* VSYNC is bit 54 for VG and bit 29 for DF */ 1749f29dbc25Smrg 1750f29dbc25Smrg msr_value.high = 0x00000000; 1751f29dbc25Smrg msr_value.low = 0x001D55AA; 1752f29dbc25Smrg msr_write64(MSR_DEVICE_GEODELX_GLCP, GLCP_H0CTL + 3, &msr_value); 1753f29dbc25Smrg 1754f29dbc25Smrg /* M4 (XSTATE = 00 AND VSYNC HIGH) */ 1755f29dbc25Smrg /* Goto state 01 */ 1756f29dbc25Smrg /* Note: VSync = H3A */ 1757f29dbc25Smrg 1758f29dbc25Smrg msr_value.high = 0x00000001; 1759f29dbc25Smrg msr_value.low = 0x000000A0; 1760f29dbc25Smrg msr_write64(MSR_DEVICE_GEODELX_GLCP, GLCP_SETM0CTL + 4, &msr_value); 1761f29dbc25Smrg 1762f29dbc25Smrg /* N0 (XSTATE = 01 AND VSYNC LOW) */ 1763f29dbc25Smrg /* Goto state 02 */ 1764f29dbc25Smrg /* Note: VSync low = H3B */ 1765f29dbc25Smrg 1766f29dbc25Smrg msr_value.high = 0x00040000; 1767f29dbc25Smrg msr_value.low = 0x000000C0; 1768f29dbc25Smrg msr_write64(MSR_DEVICE_GEODELX_GLCP, GLCP_SETN0CTL, &msr_value); 1769f29dbc25Smrg 1770f29dbc25Smrg /* M5 (XSTATE = 10 AND VSYNC HIGH) */ 1771f29dbc25Smrg /* Goto state 11 */ 1772f29dbc25Smrg 1773f29dbc25Smrg msr_value.high = 0x00000001; 1774f29dbc25Smrg msr_value.low = 0x00000120; 1775f29dbc25Smrg msr_write64(MSR_DEVICE_GEODELX_GLCP, GLCP_SETM0CTL + 5, &msr_value); 1776f29dbc25Smrg 1777f29dbc25Smrg /* N1 (XSTATE = 10 and HSYNC LOW) */ 1778f29dbc25Smrg /* Increment H. Counter */ 1779f29dbc25Smrg /* Note: HSync = H4 */ 1780f29dbc25Smrg 1781f29dbc25Smrg msr_value.high = 0x00080000; 1782f29dbc25Smrg msr_value.low = 0x00000120; 1783f29dbc25Smrg msr_write64(MSR_DEVICE_GEODELX_GLCP, GLCP_SETN0CTL + 1, &msr_value); 1784f29dbc25Smrg 1785f29dbc25Smrg /* M0 (XSTATE = 10 and H. COUNTER == LIMIT) */ 1786f29dbc25Smrg /* Clear H. Counter and increment V. Counter */ 1787f29dbc25Smrg 1788f29dbc25Smrg msr_value.high = 0x00000000; 1789f29dbc25Smrg msr_value.low = 0x00000122; 1790f29dbc25Smrg msr_write64(MSR_DEVICE_GEODELX_GLCP, GLCP_SETM0CTL, &msr_value); 1791f29dbc25Smrg 1792f29dbc25Smrg /* N4 (XSTATE = 10 && CMP0 <= H. COUNTER <= CMP1 && CMP2 <= V. COUNTER 1793f29dbc25Smrg * <= CMP3) 1794f29dbc25Smrg * CRC into REGB 1795f29dbc25Smrg */ 1796f29dbc25Smrg 1797f29dbc25Smrg msr_value.high = 0x00000000; 1798f29dbc25Smrg msr_value.low = 0x10C20120; 1799f29dbc25Smrg msr_write64(MSR_DEVICE_GEODELX_GLCP, GLCP_SETN0CTL + 4, &msr_value); 1800f29dbc25Smrg 1801f29dbc25Smrg /* COMPARATOR 0 VALUE */ 1802f29dbc25Smrg /* Value = xstart + (htotal - hsync_end) - 1 */ 1803f29dbc25Smrg /* The value will be adjusted for a border if necessary */ 1804f29dbc25Smrg 1805f29dbc25Smrg msr_value.low = x + htotal - hsyncend - 1; 1806f29dbc25Smrg if (READ_REG32(DC3_DISPLAY_CFG) & DC3_DCFG_DCEN) 1807f29dbc25Smrg msr_value.low -= hblankstart - hactive; 1808f29dbc25Smrg msr_value.low--; 1809f29dbc25Smrg msr_write64(MSR_DEVICE_GEODELX_GLCP, GLCP_CMPVAL0, &msr_value); 1810f29dbc25Smrg 1811f29dbc25Smrg /* COMPARATOR 1 VALUE */ 1812f29dbc25Smrg /* Value = xstart + (htotal - hsync_end - 1) - 1 + width */ 1813f29dbc25Smrg 1814f29dbc25Smrg msr_value.low += width - 1; 1815f29dbc25Smrg msr_write64(MSR_DEVICE_GEODELX_GLCP, GLCP_CMPVAL0 + 2, &msr_value); 1816f29dbc25Smrg 1817f29dbc25Smrg /* COMPARATOR 2 VALUE */ 1818f29dbc25Smrg /* Value = ystart + vtotal - vsyncend */ 1819f29dbc25Smrg 1820f29dbc25Smrg msr_value.low = (y + vtotal - vsyncend) << 16; 1821f29dbc25Smrg if (READ_REG32(DC3_DISPLAY_CFG) & DC3_DCFG_DCEN) 1822f29dbc25Smrg msr_value.low -= (vblankstart - vactive) << 16; 1823f29dbc25Smrg msr_write64(MSR_DEVICE_GEODELX_GLCP, GLCP_CMPVAL0 + 4, &msr_value); 1824f29dbc25Smrg 1825f29dbc25Smrg /* COMPARATOR 3 VALUE */ 1826f29dbc25Smrg /* Value = ystart + vtotal - vsyncend + height - 1 */ 1827f29dbc25Smrg 1828f29dbc25Smrg msr_value.low += (height - 1) << 16; 1829f29dbc25Smrg msr_write64(MSR_DEVICE_GEODELX_GLCP, GLCP_CMPVAL0 + 6, &msr_value); 1830f29dbc25Smrg 1831f29dbc25Smrg /* COMPARATOR MASKS */ 1832f29dbc25Smrg /* Comparators 0 and 1 refer to lower 16 bits of RegB */ 1833f29dbc25Smrg 1834f29dbc25Smrg msr_value.low = 0x0000FFFF; 1835f29dbc25Smrg msr_write64(MSR_DEVICE_GEODELX_GLCP, GLCP_CMPMASK0, &msr_value); 1836f29dbc25Smrg msr_write64(MSR_DEVICE_GEODELX_GLCP, GLCP_CMPMASK0 + 2, &msr_value); 1837f29dbc25Smrg 1838f29dbc25Smrg /* Comparators 2 and 3 refer to upper 16 bits of RegB */ 1839f29dbc25Smrg 1840f29dbc25Smrg msr_value.low = 0xFFFF0000; 1841f29dbc25Smrg msr_write64(MSR_DEVICE_GEODELX_GLCP, GLCP_CMPMASK0 + 4, &msr_value); 1842f29dbc25Smrg msr_write64(MSR_DEVICE_GEODELX_GLCP, GLCP_CMPMASK0 + 6, &msr_value); 1843f29dbc25Smrg 1844f29dbc25Smrg /* SET REGB MASK */ 1845f29dbc25Smrg /* We set the mask such that all only 24 bits of data are CRCed */ 1846f29dbc25Smrg 1847f29dbc25Smrg msr_value.low = 0x00FFFFFF; 1848f29dbc25Smrg msr_write64(MSR_DEVICE_GEODELX_GLCP, GLCP_REGBMASK, &msr_value); 1849f29dbc25Smrg 1850f29dbc25Smrg /* SET REGA LIMITS */ 1851f29dbc25Smrg /* Lower counter uses htotal - sync_time - 1. */ 1852f29dbc25Smrg /* Upper counter is 0xFFFF to prevent rollover. */ 1853f29dbc25Smrg 1854f29dbc25Smrg msr_value.low = 0xFFFF0000 | (htotal - (hsyncend - hsyncstart) - 1); 1855f29dbc25Smrg msr_write64(MSR_DEVICE_GEODELX_GLCP, GLCP_REGAVAL, &msr_value); 1856f29dbc25Smrg 1857f29dbc25Smrg /* ACTIONS */ 1858f29dbc25Smrg 1859f29dbc25Smrg /* STATE 00->01 (SET 4M) */ 1860f29dbc25Smrg 1861f29dbc25Smrg msr_value.low = 0x000C0000; 1862f29dbc25Smrg msr_write64(MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 14, &msr_value); 1863f29dbc25Smrg 1864f29dbc25Smrg /* STATE 01->10 (SET 0N) */ 1865f29dbc25Smrg 1866f29dbc25Smrg msr_value.low = 0x0000000A; 1867f29dbc25Smrg msr_write64(MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 15, &msr_value); 1868f29dbc25Smrg 1869f29dbc25Smrg /* STATE 10->11 (SET 5M) */ 1870f29dbc25Smrg 1871f29dbc25Smrg msr_value.low = 0x00C00000; 1872f29dbc25Smrg msr_write64(MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 16, &msr_value); 1873f29dbc25Smrg 1874f29dbc25Smrg /* CLEAR REGA WHEN TRANSITIONING TO STATE 10 */ 1875f29dbc25Smrg /* Do not clear RegB as the initial value must be 0x00000001 */ 1876f29dbc25Smrg 1877f29dbc25Smrg msr_value.low = 0x0000000A; 1878f29dbc25Smrg msr_write64(MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0, &msr_value); 1879f29dbc25Smrg 1880f29dbc25Smrg /* REGISTER ACTION 1 */ 1881f29dbc25Smrg /* CRC into RegB if cmp0 <= h.counter <= cmp1 && cmp2 <= v. counter < 1882f29dbc25Smrg * cmp3 && 7 xstate = 10 8 1883f29dbc25Smrg * Increment h.counter if xstate = 10 and HSync is low. 1884f29dbc25Smrg */ 1885f29dbc25Smrg 1886f29dbc25Smrg msr_value.low = 0x000A00A0; 1887f29dbc25Smrg msr_write64(MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 1, &msr_value); 1888f29dbc25Smrg 1889f29dbc25Smrg /* REGISTER ACTION 2 */ 1890f29dbc25Smrg /* Increment V. Counter in REGA */ 1891f29dbc25Smrg 1892f29dbc25Smrg msr_value.low = 0x0000000C; 1893f29dbc25Smrg msr_write64(MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 2, &msr_value); 1894f29dbc25Smrg 1895f29dbc25Smrg /* SET REGB TO 0x00000001 */ 1896f29dbc25Smrg 1897f29dbc25Smrg msr_value.low = 0x00000001; 1898f29dbc25Smrg msr_write64(MSR_DEVICE_GEODELX_GLCP, GLCP_REGB, &msr_value); 1899f29dbc25Smrg 1900f29dbc25Smrg /* SET XSTATE TO 0 */ 1901f29dbc25Smrg 1902f29dbc25Smrg msr_value.low = 0x00000000; 1903f29dbc25Smrg msr_write64(MSR_DEVICE_GEODELX_GLCP, GLCP_XSTATE, &msr_value); 1904f29dbc25Smrg 1905f29dbc25Smrg /* CLEAR ALL OTHER ACTIONS */ 1906f29dbc25Smrg /* This prevents side-effects from previous accesses to the GLCP */ 1907f29dbc25Smrg /* debug logic. */ 1908f29dbc25Smrg 1909f29dbc25Smrg msr_value.low = 0x00000000; 1910f29dbc25Smrg msr_value.high = 0x00000000; 1911f29dbc25Smrg msr_write64(MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 3, &msr_value); 1912f29dbc25Smrg msr_write64(MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 4, &msr_value); 1913f29dbc25Smrg msr_write64(MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 5, &msr_value); 1914f29dbc25Smrg msr_write64(MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 6, &msr_value); 1915f29dbc25Smrg msr_write64(MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 7, &msr_value); 1916f29dbc25Smrg msr_write64(MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 8, &msr_value); 1917f29dbc25Smrg msr_write64(MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 9, &msr_value); 1918f29dbc25Smrg msr_write64(MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 10, &msr_value); 1919f29dbc25Smrg msr_write64(MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 11, &msr_value); 1920f29dbc25Smrg msr_write64(MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 12, &msr_value); 1921f29dbc25Smrg msr_write64(MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 13, &msr_value); 1922f29dbc25Smrg msr_write64(MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 17, &msr_value); 1923f29dbc25Smrg msr_write64(MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 18, &msr_value); 1924f29dbc25Smrg msr_write64(MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 19, &msr_value); 1925f29dbc25Smrg msr_write64(MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 20, &msr_value); 1926f29dbc25Smrg 1927f29dbc25Smrg /* WAIT FOR THE CORRECT FIELD */ 1928f29dbc25Smrg /* We use the VG line count and field indicator to determine when */ 1929f29dbc25Smrg /* to kick off a CRC. */ 1930f29dbc25Smrg 1931f29dbc25Smrg if (source & DF_CRC_SOURCE_EVEN) 1932f29dbc25Smrg field = 0; 1933f29dbc25Smrg else 1934f29dbc25Smrg field = DC3_LNCNT_EVEN_FIELD; 1935f29dbc25Smrg 1936f29dbc25Smrg if (interlaced) { 1937f29dbc25Smrg /* WAIT FOR THE BEGINNING OF THE FIELD (LINE 1-5) */ 1938f29dbc25Smrg /* Note that we wait for the field to be odd when CRCing the even */ 1939f29dbc25Smrg /* field and vice versa. This is because the CRC will not begin */ 1940f29dbc25Smrg /* until the following field. */ 1941f29dbc25Smrg 1942f29dbc25Smrg do { 1943f29dbc25Smrg line = READ_REG32(DC3_LINE_CNT_STATUS); 1944f29dbc25Smrg } while ((line & DC3_LNCNT_EVEN_FIELD) != field || 1945f29dbc25Smrg ((line & DC3_LNCNT_V_LINE_CNT) >> 16) < 1 || 1946f29dbc25Smrg ((line & DC3_LNCNT_V_LINE_CNT) >> 16) > 5); 1947f29dbc25Smrg } else { 1948f29dbc25Smrg /* NON-INTERLACED - EVEN FIELD CRCS ARE INVALID */ 1949f29dbc25Smrg 1950f29dbc25Smrg if (source & DF_CRC_SOURCE_EVEN) 1951f29dbc25Smrg return 0xFFFFFFFF; 1952f29dbc25Smrg } 1953f29dbc25Smrg 1954f29dbc25Smrg /* CONFIGURE DISPLAY FILTER TO LOAD DATA ONTO LOWER 32-BITS */ 1955f29dbc25Smrg 1956f29dbc25Smrg msr_value.high = 0; 1957f29dbc25Smrg msr_value.low = 0x0000800B; 1958f29dbc25Smrg msr_write64(MSR_DEVICE_GEODELX_DF, MSR_GEODELINK_DIAG, &msr_value); 1959f29dbc25Smrg 1960f29dbc25Smrg /* CONFIGURE DIAG CONTROL */ 1961f29dbc25Smrg /* Set RegA action1 to increment lower 16 bits and clear at limit. (5) 1962f29dbc25Smrg * Set RegA action2 to increment upper 16 bits. (6) 1963f29dbc25Smrg * Set RegB action1 to CRC32 (1) 1964f29dbc25Smrg * Set all comparators to REGA override (0,1 lower mbus, 2,3 upper mbus) 1965f29dbc25Smrg * Enable all actions 1966f29dbc25Smrg */ 1967f29dbc25Smrg 1968f29dbc25Smrg msr_value.low = 0x80EA20A0; 1969f29dbc25Smrg msr_write64(MSR_DEVICE_GEODELX_GLCP, GLCP_DIAGCTL, &msr_value); 1970f29dbc25Smrg 1971f29dbc25Smrg /* DELAY TWO FRAMES */ 1972f29dbc25Smrg 1973f29dbc25Smrg while (READ_REG32(DC3_LINE_CNT_STATUS) & DC3_LNCNT_VNA) ; 1974f29dbc25Smrg while (!(READ_REG32(DC3_LINE_CNT_STATUS) & DC3_LNCNT_VNA)) ; 1975f29dbc25Smrg while (READ_REG32(DC3_LINE_CNT_STATUS) & DC3_LNCNT_VNA) ; 1976f29dbc25Smrg while (!(READ_REG32(DC3_LINE_CNT_STATUS) & DC3_LNCNT_VNA)) ; 1977f29dbc25Smrg while (READ_REG32(DC3_LINE_CNT_STATUS) & DC3_LNCNT_VNA) ; 1978f29dbc25Smrg 1979f29dbc25Smrg /* VERIFY THAT XSTATE = 11 */ 1980f29dbc25Smrg 1981f29dbc25Smrg msr_read64(MSR_DEVICE_GEODELX_GLCP, GLCP_XSTATE, &msr_value); 1982f29dbc25Smrg if ((msr_value.low & 3) == 3) { 1983f29dbc25Smrg msr_read64(MSR_DEVICE_GEODELX_GLCP, GLCP_REGB, &msr_value); 1984f29dbc25Smrg 1985f29dbc25Smrg crc = msr_value.low; 1986f29dbc25Smrg } 1987f29dbc25Smrg 1988f29dbc25Smrg /* DISABLE DF DIAG BUS OUTPUTS */ 1989f29dbc25Smrg 1990f29dbc25Smrg msr_value.low = 0x00000000; 1991f29dbc25Smrg msr_value.high = 0x00000000; 1992f29dbc25Smrg msr_write64(MSR_DEVICE_GEODELX_DF, MSR_GEODELINK_DIAG, &msr_value); 1993f29dbc25Smrg 1994f29dbc25Smrg /* DISABLE GLCP ACTIONS */ 1995f29dbc25Smrg 1996f29dbc25Smrg msr_write64(MSR_DEVICE_GEODELX_GLCP, GLCP_DIAGCTL, &msr_value); 1997f29dbc25Smrg 1998f29dbc25Smrg return crc; 1999f29dbc25Smrg} 2000f29dbc25Smrg 2001f29dbc25Smrg/*--------------------------------------------------------------------------- 2002f29dbc25Smrg * df_read_panel_crc 2003f29dbc25Smrg * 2004f29dbc25Smrg * This routine reads the CRC for a frame of data after the panel dithering 2005f29dbc25Smrg * logic. 2006f29dbc25Smrg *--------------------------------------------------------------------------*/ 2007f29dbc25Smrg 2008f29dbc25Smrgunsigned long 2009f29dbc25Smrgdf_read_panel_crc(void) 2010f29dbc25Smrg{ 2011f29dbc25Smrg Q_WORD msr_value; 2012f29dbc25Smrg unsigned long timeout = 1000; 2013f29dbc25Smrg 2014f29dbc25Smrg if (!(READ_REG32(DC3_DISPLAY_CFG) & DC3_DCFG_TGEN)) 2015f29dbc25Smrg return 0xFFFFFFFF; 2016f29dbc25Smrg 2017f29dbc25Smrg /* ENABLE 32-BIT CRCS */ 2018f29dbc25Smrg 2019f29dbc25Smrg msr_read64(MSR_DEVICE_GEODELX_DF, DF_MBD_MSR_DIAG_DF, &msr_value); 2020f29dbc25Smrg msr_value.low |= DF_DIAG_32BIT_CRC; 2021f29dbc25Smrg msr_write64(MSR_DEVICE_GEODELX_DF, DF_MBD_MSR_DIAG_DF, &msr_value); 2022f29dbc25Smrg 2023f29dbc25Smrg /* RESET CRC */ 2024f29dbc25Smrg 2025f29dbc25Smrg WRITE_VID32(DF_PANEL_CRC, 0); 2026f29dbc25Smrg 2027f29dbc25Smrg /* WAIT FOR THE RESET TO BE LATCHED */ 2028f29dbc25Smrg 2029f29dbc25Smrg while ((READ_VID32(DF_PANEL_CRC32) != 0x00000001) && timeout) 2030f29dbc25Smrg timeout--; 2031f29dbc25Smrg 2032f29dbc25Smrg WRITE_VID32(DF_PANEL_CRC, 1); 2033f29dbc25Smrg 2034f29dbc25Smrg /* WAIT FOR THE CRC TO BE COMPLETED */ 2035f29dbc25Smrg 2036f29dbc25Smrg while (!(READ_VID32(DF_PANEL_CRC) & 4)) ; 2037f29dbc25Smrg 2038f29dbc25Smrg return READ_VID32(DF_PANEL_CRC32); 2039f29dbc25Smrg} 2040f29dbc25Smrg 2041f29dbc25Smrg/*--------------------------------------------------------------------------- 2042f29dbc25Smrg * df_get_video_enable 2043f29dbc25Smrg * 2044f29dbc25Smrg * This routine reads the enable status of the video overlay. 2045f29dbc25Smrg *--------------------------------------------------------------------------*/ 2046f29dbc25Smrg 2047f29dbc25Smrgint 2048f29dbc25Smrgdf_get_video_enable(int *enable, unsigned long *flags) 2049f29dbc25Smrg{ 2050f29dbc25Smrg *enable = 0; 2051f29dbc25Smrg *flags = 0; 2052f29dbc25Smrg if (READ_VID32(DF_VIDEO_CONFIG) & DF_VCFG_VID_EN) { 2053f29dbc25Smrg *enable = 1; 2054f29dbc25Smrg 2055f29dbc25Smrg /* CHECK FOR COLOR KEY DISABLED */ 2056f29dbc25Smrg /* Color keying can be completely disabled when video is enabled to */ 2057f29dbc25Smrg /* allow unhindered per-pixel alpha blending. As color keying is */ 2058f29dbc25Smrg /* always disabled when video is disabled, it is only possible to */ 2059f29dbc25Smrg /* test for this condition when video is enabled. */ 2060f29dbc25Smrg 2061f29dbc25Smrg if (!(READ_VID32(DF_DISPLAY_CONFIG) & DF_DCFG_VG_CK) && 2062f29dbc25Smrg !(READ_REG32(DC3_COLOR_KEY) & DC3_CLR_KEY_ENABLE)) { 2063f29dbc25Smrg *flags = DF_ENABLEFLAG_NOCOLORKEY; 2064f29dbc25Smrg } 2065f29dbc25Smrg } 2066f29dbc25Smrg 2067f29dbc25Smrg return CIM_STATUS_OK; 2068f29dbc25Smrg} 2069f29dbc25Smrg 2070f29dbc25Smrg/*--------------------------------------------------------------------------- 2071f29dbc25Smrg * df_get_video_source_configuration 2072f29dbc25Smrg * 2073f29dbc25Smrg * This routine reads the current configuration of the source buffers for the 2074f29dbc25Smrg * video overlay. 2075f29dbc25Smrg *--------------------------------------------------------------------------*/ 2076f29dbc25Smrg 2077f29dbc25Smrgint 2078f29dbc25Smrgdf_get_video_source_configuration(DF_VIDEO_SOURCE_PARAMS * video_source_odd, 2079f29dbc25Smrg DF_VIDEO_SOURCE_PARAMS * video_source_even) 2080f29dbc25Smrg{ 2081f29dbc25Smrg unsigned long format, temp; 2082f29dbc25Smrg unsigned long size; 2083f29dbc25Smrg 2084f29dbc25Smrg /* READ VIDEO FORMAT */ 2085f29dbc25Smrg 2086f29dbc25Smrg temp = READ_VID32(DF_VIDEO_CONFIG); 2087f29dbc25Smrg 2088f29dbc25Smrg format = (temp >> 2) & 3; 2089f29dbc25Smrg if (temp & DF_VCFG_4_2_0_MODE) 2090f29dbc25Smrg format |= 4; 2091f29dbc25Smrg else if (READ_VID32(DF_VID_ALPHA_CONTROL) & DF_VIDEO_INPUT_IS_RGB) 2092f29dbc25Smrg format |= 8; 2093f29dbc25Smrg video_source_odd->video_format = format; 2094f29dbc25Smrg 2095f29dbc25Smrg /* CHECK IF SOURCE IS HD VIDEO */ 2096f29dbc25Smrg 2097f29dbc25Smrg if (READ_VID32(DF_VID_ALPHA_CONTROL) & DF_HD_VIDEO) 2098f29dbc25Smrg video_source_odd->flags = DF_SOURCEFLAG_HDTVSOURCE; 2099f29dbc25Smrg else 2100f29dbc25Smrg video_source_odd->flags = 0; 2101f29dbc25Smrg 2102f29dbc25Smrg /* READ SCALING ALGORITHM */ 2103f29dbc25Smrg 2104f29dbc25Smrg if (READ_VID32(DF_VID_MISC) & DF_USER_IMPLICIT_SCALING) 2105f29dbc25Smrg video_source_odd->flags |= DF_SOURCEFLAG_IMPLICITSCALING; 2106f29dbc25Smrg 2107f29dbc25Smrg /* READ VIDEO PITCH */ 2108f29dbc25Smrg 2109f29dbc25Smrg temp = READ_REG32(DC3_VID_YUV_PITCH); 2110f29dbc25Smrg video_source_odd->y_pitch = (temp & 0xFFFF) << 3; 2111f29dbc25Smrg video_source_odd->uv_pitch = (temp >> 16) << 3; 2112f29dbc25Smrg 2113f29dbc25Smrg /* READ VIDEO SIZE */ 2114f29dbc25Smrg 2115f29dbc25Smrg temp = READ_VID32(DF_VIDEO_CONFIG); 2116f29dbc25Smrg size = (temp >> 8) & 0xFF; 2117f29dbc25Smrg if (temp & DF_VCFG_LINE_SIZE_BIT8) 2118f29dbc25Smrg size |= 0x100; 2119f29dbc25Smrg if (temp & DF_VCFG_LINE_SIZE_BIT9) 2120f29dbc25Smrg size |= 0x200; 2121f29dbc25Smrg 2122f29dbc25Smrg video_source_odd->width = size << 1; 2123f29dbc25Smrg video_source_odd->height = READ_VID32(DF_VIDEO_SCALER) & 0x7FF; 2124f29dbc25Smrg 2125f29dbc25Smrg /* READ VIDEO OFFSETS */ 2126f29dbc25Smrg 2127f29dbc25Smrg video_source_odd->y_offset = READ_REG32(DC3_VID_Y_ST_OFFSET) & 0xFFFFFFF; 2128f29dbc25Smrg video_source_odd->u_offset = READ_REG32(DC3_VID_U_ST_OFFSET) & 0xFFFFFFF; 2129f29dbc25Smrg video_source_odd->v_offset = READ_REG32(DC3_VID_V_ST_OFFSET) & 0xFFFFFFF; 2130f29dbc25Smrg 2131f29dbc25Smrg if (READ_REG32(DC3_IRQ_FILT_CTL) & DC3_IRQFILT_INTL_EN) { 2132f29dbc25Smrg video_source_even->y_offset = 2133f29dbc25Smrg READ_REG32(DC3_VID_EVEN_Y_ST_OFFSET) & 0xFFFFFFF; 2134f29dbc25Smrg video_source_even->u_offset = 2135f29dbc25Smrg READ_REG32(DC3_VID_EVEN_U_ST_OFFSET) & 0xFFFFFFF; 2136f29dbc25Smrg video_source_even->v_offset = 2137f29dbc25Smrg READ_REG32(DC3_VID_EVEN_V_ST_OFFSET) & 0xFFFFFFF; 2138f29dbc25Smrg } 2139f29dbc25Smrg 2140f29dbc25Smrg return CIM_STATUS_OK; 2141f29dbc25Smrg} 2142f29dbc25Smrg 2143f29dbc25Smrg/*--------------------------------------------------------------------------- 2144f29dbc25Smrg * df_get_video_position 2145f29dbc25Smrg * 2146f29dbc25Smrg * This routine reads the current position of the video overlay. 2147f29dbc25Smrg *--------------------------------------------------------------------------*/ 2148f29dbc25Smrg 2149f29dbc25Smrgint 2150f29dbc25Smrgdf_get_video_position(DF_VIDEO_POSITION * video_window) 2151f29dbc25Smrg{ 2152f29dbc25Smrg unsigned long xreg, yreg, dst_clip, clip; 2153f29dbc25Smrg unsigned long height; 2154f29dbc25Smrg unsigned long xend, yend; 2155f29dbc25Smrg unsigned long hsyncend, htotal; 2156f29dbc25Smrg unsigned long vsyncend, vtotal; 2157f29dbc25Smrg unsigned long hadjust, vadjust; 2158f29dbc25Smrg unsigned long misc, gfxscale; 2159f29dbc25Smrg unsigned long temp; 2160f29dbc25Smrg long xstart, ystart; 2161f29dbc25Smrg 2162f29dbc25Smrg video_window->flags = DF_POSFLAG_DIRECTCLIP; 2163f29dbc25Smrg 2164f29dbc25Smrg hsyncend = ((READ_REG32(DC3_H_SYNC_TIMING) >> 16) & 0xFFF) + 1; 2165f29dbc25Smrg htotal = ((READ_REG32(DC3_H_ACTIVE_TIMING) >> 16) & 0xFFF) + 1; 2166f29dbc25Smrg 2167f29dbc25Smrg /* ODD FIELD START COUNTS FROM THE EVEN FIELD TIMINGS */ 2168f29dbc25Smrg /* We assume that the even field y position is always programmed */ 2169f29dbc25Smrg /* to be just after the odd field. */ 2170f29dbc25Smrg 2171f29dbc25Smrg if (READ_REG32(DC3_IRQ_FILT_CTL) & DC3_IRQFILT_INTL_EN) { 2172f29dbc25Smrg vsyncend = ((READ_REG32(DC3_V_SYNC_EVEN) >> 16) & 0xFFF) + 1; 2173f29dbc25Smrg vtotal = ((READ_REG32(DC3_V_ACTIVE_EVEN) >> 16) & 0xFFF) + 1; 2174f29dbc25Smrg } else { 2175f29dbc25Smrg vsyncend = ((READ_REG32(DC3_V_SYNC_TIMING) >> 16) & 0xFFF) + 1; 2176f29dbc25Smrg vtotal = ((READ_REG32(DC3_V_ACTIVE_TIMING) >> 16) & 0xFFF) + 1; 2177f29dbc25Smrg } 2178f29dbc25Smrg 2179f29dbc25Smrg hadjust = htotal - hsyncend - 14; 2180f29dbc25Smrg vadjust = vtotal - vsyncend + 1; 2181f29dbc25Smrg 2182f29dbc25Smrg xreg = READ_VID32(DF_VIDEO_X_POS); 2183f29dbc25Smrg yreg = READ_VID32(DF_VIDEO_Y_POS); 2184f29dbc25Smrg 2185f29dbc25Smrg xstart = (xreg & 0xFFF) - hadjust; 2186f29dbc25Smrg ystart = (yreg & 0x7FF) - vadjust; 2187f29dbc25Smrg xend = ((xreg >> 16) & 0xFFF) - hadjust; 2188f29dbc25Smrg yend = ((yreg >> 16) & 0x7FF) - vadjust; 2189f29dbc25Smrg 2190f29dbc25Smrg height = yend - ystart; 2191f29dbc25Smrg 2192f29dbc25Smrg if (READ_REG32(DC3_IRQ_FILT_CTL) & DC3_IRQFILT_INTL_EN) { 2193f29dbc25Smrg /* Y COORDINATE IS ACTUALLY 2X THE ODD FIELD START */ 2194f29dbc25Smrg 2195f29dbc25Smrg ystart <<= 1; 2196f29dbc25Smrg 2197f29dbc25Smrg /* CALCULATE THE EXACT VIDEO HEIGHT */ 2198f29dbc25Smrg /* The height of the video window is the sum of the */ 2199f29dbc25Smrg /* odd and even field heights. */ 2200f29dbc25Smrg 2201f29dbc25Smrg yreg = READ_VID32(DF_VID_YPOS_EVEN); 2202f29dbc25Smrg height += ((yreg >> 16) & 0x7FF) - (yreg & 0x7FF); 2203f29dbc25Smrg } 2204f29dbc25Smrg 2205f29dbc25Smrg clip = ((READ_VID32(DF_VIDEO_CONFIG) >> 16) & 0x1FF) << 2; 2206f29dbc25Smrg 2207f29dbc25Smrg /* ADJUST FOR CLIPPING VALUES THAT ARE NOT FOUR-PIXEL ALIGNED */ 2208f29dbc25Smrg 2209f29dbc25Smrg dst_clip = 0; 2210f29dbc25Smrg if (xstart < 0) { 2211f29dbc25Smrg dst_clip += -xstart; 2212f29dbc25Smrg xstart = 0; 2213f29dbc25Smrg } 2214f29dbc25Smrg 2215f29dbc25Smrg /* REVERSE THE GRAPHICS SCALE */ 2216f29dbc25Smrg 2217f29dbc25Smrg misc = READ_VID32(DF_VID_MISC); 2218f29dbc25Smrg if (misc & DF_USER_IMPLICIT_SCALING) { 2219f29dbc25Smrg gfxscale = READ_REG32(DC3_GFX_SCALE); 2220f29dbc25Smrg 2221f29dbc25Smrg if (gfxscale != 0x40004000) { 2222f29dbc25Smrg temp = ystart + height; 2223f29dbc25Smrg temp = (temp * (gfxscale >> 16)) / 0x4000; 2224f29dbc25Smrg 2225f29dbc25Smrg xstart = (xstart * (gfxscale & 0xFFFF)) / 0x4000; 2226f29dbc25Smrg xend = (xend * (gfxscale & 0xFFFF)) / 0x4000; 2227f29dbc25Smrg ystart = (ystart * (gfxscale >> 16)) / 0x4000; 2228f29dbc25Smrg height = temp - ystart; 2229f29dbc25Smrg } 2230f29dbc25Smrg } 2231f29dbc25Smrg 2232f29dbc25Smrg video_window->left_clip = clip; 2233f29dbc25Smrg video_window->dst_clip = dst_clip; 2234f29dbc25Smrg video_window->x = xstart; 2235f29dbc25Smrg video_window->y = ystart; 2236f29dbc25Smrg video_window->width = xend - xstart; 2237f29dbc25Smrg video_window->height = height; 2238f29dbc25Smrg 2239f29dbc25Smrg return CIM_STATUS_OK; 2240f29dbc25Smrg} 2241f29dbc25Smrg 2242f29dbc25Smrg/*--------------------------------------------------------------------------- 2243f29dbc25Smrg * df_get_video_scale 2244f29dbc25Smrg * 2245f29dbc25Smrg * This routine reads the current scale values for video scaling. 2246f29dbc25Smrg *--------------------------------------------------------------------------*/ 2247f29dbc25Smrg 2248f29dbc25Smrgint 2249f29dbc25Smrgdf_get_video_scale(unsigned long *x_scale, unsigned long *y_scale) 2250f29dbc25Smrg{ 2251f29dbc25Smrg *x_scale = READ_VID32(DF_VIDEO_XSCALE) & 0x000FFFFF; 2252f29dbc25Smrg *y_scale = READ_VID32(DF_VIDEO_YSCALE) & 0x000FFFFF; 2253f29dbc25Smrg return CIM_STATUS_OK; 2254f29dbc25Smrg} 2255f29dbc25Smrg 2256f29dbc25Smrg/*--------------------------------------------------------------------------- 2257f29dbc25Smrg * df_get_video_filter_coefficients 2258f29dbc25Smrg * 2259f29dbc25Smrg * This routine reads the coefficients for the video scaler/filter. 2260f29dbc25Smrg *--------------------------------------------------------------------------*/ 2261f29dbc25Smrg 2262f29dbc25Smrgint 2263f29dbc25Smrgdf_get_video_filter_coefficients(long taps[][4], int *phase256) 2264f29dbc25Smrg{ 2265f29dbc25Smrg unsigned long i, temp; 2266f29dbc25Smrg long coeff; 2267f29dbc25Smrg 2268f29dbc25Smrg if (READ_VID32(DF_VIDEO_SCALER) & DF_SCALE_128_PHASES) 2269f29dbc25Smrg *phase256 = 0; 2270f29dbc25Smrg else 2271f29dbc25Smrg *phase256 = 1; 2272f29dbc25Smrg 2273f29dbc25Smrg for (i = 0; i < 256; i++) { 2274f29dbc25Smrg temp = READ_VID32(DF_COEFFICIENT_BASE + (i << 3)); 2275f29dbc25Smrg 2276f29dbc25Smrg /* TAP 0 */ 2277f29dbc25Smrg 2278f29dbc25Smrg coeff = temp & 0x7FFF; 2279f29dbc25Smrg if (temp & 0x8000) 2280f29dbc25Smrg coeff = -coeff; 2281f29dbc25Smrg taps[i][0] = coeff; 2282f29dbc25Smrg 2283f29dbc25Smrg /* TAP 1 */ 2284f29dbc25Smrg 2285f29dbc25Smrg temp >>= 16; 2286f29dbc25Smrg coeff = temp & 0x7FFF; 2287f29dbc25Smrg if (temp & 0x8000) 2288f29dbc25Smrg coeff = -coeff; 2289f29dbc25Smrg taps[i][1] = coeff; 2290f29dbc25Smrg 2291f29dbc25Smrg temp = READ_VID32(DF_COEFFICIENT_BASE + (i << 3) + 4); 2292f29dbc25Smrg 2293f29dbc25Smrg /* TAP 2 */ 2294f29dbc25Smrg 2295f29dbc25Smrg coeff = temp & 0x7FFF; 2296f29dbc25Smrg if (temp & 0x8000) 2297f29dbc25Smrg coeff = -coeff; 2298f29dbc25Smrg taps[i][2] = coeff; 2299f29dbc25Smrg 2300f29dbc25Smrg /* TAP 3 */ 2301f29dbc25Smrg 2302f29dbc25Smrg temp >>= 16; 2303f29dbc25Smrg coeff = temp & 0x7FFF; 2304f29dbc25Smrg if (temp & 0x8000) 2305f29dbc25Smrg coeff = -coeff; 2306f29dbc25Smrg taps[i][3] = coeff; 2307f29dbc25Smrg } 2308f29dbc25Smrg 2309f29dbc25Smrg return CIM_STATUS_OK; 2310f29dbc25Smrg} 2311f29dbc25Smrg 2312f29dbc25Smrg/*--------------------------------------------------------------------------- 2313f29dbc25Smrg * df_get_video_color_key 2314f29dbc25Smrg * 2315f29dbc25Smrg * This routine reads the current settings for hardware color/chroma keying. 2316f29dbc25Smrg *--------------------------------------------------------------------------*/ 2317f29dbc25Smrg 2318f29dbc25Smrgint 2319f29dbc25Smrgdf_get_video_color_key(unsigned long *key, unsigned long *mask, int *graphics) 2320f29dbc25Smrg{ 2321f29dbc25Smrg unsigned long chroma = READ_VID32(DF_DISPLAY_CONFIG) & DF_DCFG_VG_CK; 2322f29dbc25Smrg 2323f29dbc25Smrg if (chroma) { 2324f29dbc25Smrg /* CHROMA KEY - READ KEY AND MASK FROM DF */ 2325f29dbc25Smrg 2326f29dbc25Smrg *graphics = 0; 2327f29dbc25Smrg *key = READ_VID32(DF_VIDEO_COLOR_KEY) & 0xFFFFFF; 2328f29dbc25Smrg *mask = READ_VID32(DF_VIDEO_COLOR_MASK) & 0xFFFFFF; 2329f29dbc25Smrg } else { 2330f29dbc25Smrg *graphics = 1; 2331f29dbc25Smrg 2332f29dbc25Smrg *key = READ_REG32(DC3_COLOR_KEY) & 0xFFFFFF; 2333f29dbc25Smrg *mask = READ_REG32(DC3_COLOR_MASK) & 0xFFFFFF; 2334f29dbc25Smrg } 2335f29dbc25Smrg 2336f29dbc25Smrg return CIM_STATUS_OK; 2337f29dbc25Smrg} 2338f29dbc25Smrg 2339f29dbc25Smrg/*--------------------------------------------------------------------------- 2340f29dbc25Smrg * df_get_video_palette_entry 2341f29dbc25Smrg * 2342f29dbc25Smrg * This routine returns a single palette entry. 2343f29dbc25Smrg *--------------------------------------------------------------------------*/ 2344f29dbc25Smrg 2345f29dbc25Smrgint 2346f29dbc25Smrgdf_get_video_palette_entry(unsigned long index, unsigned long *palette) 2347f29dbc25Smrg{ 2348f29dbc25Smrg if (index > 0xFF) 2349f29dbc25Smrg return CIM_STATUS_INVALIDPARAMS; 2350f29dbc25Smrg 2351f29dbc25Smrg /* READ A SINGLE ENTRY */ 2352f29dbc25Smrg 2353f29dbc25Smrg WRITE_VID32(DF_PALETTE_ADDRESS, index); 2354f29dbc25Smrg *palette = READ_VID32(DF_PALETTE_DATA); 2355f29dbc25Smrg 2356f29dbc25Smrg return CIM_STATUS_OK; 2357f29dbc25Smrg} 2358f29dbc25Smrg 2359f29dbc25Smrg/*--------------------------------------------------------------------------- 2360f29dbc25Smrg * df_get_video_palette 2361f29dbc25Smrg * 2362f29dbc25Smrg * This routine returns the entire video palette. 2363f29dbc25Smrg *--------------------------------------------------------------------------*/ 2364f29dbc25Smrg 2365f29dbc25Smrgint 2366f29dbc25Smrgdf_get_video_palette(unsigned long *palette) 2367f29dbc25Smrg{ 2368f29dbc25Smrg unsigned long i; 2369f29dbc25Smrg 2370f29dbc25Smrg WRITE_VID32(DF_PALETTE_ADDRESS, 0); 2371f29dbc25Smrg for (i = 0; i < 256; i++) 2372f29dbc25Smrg palette[i] = READ_VID32(DF_PALETTE_DATA); 2373f29dbc25Smrg 2374f29dbc25Smrg return CIM_STATUS_OK; 2375f29dbc25Smrg} 2376f29dbc25Smrg 2377f29dbc25Smrg/*--------------------------------------------------------------------------- 2378f29dbc25Smrg * df_get_video_cursor_color_key 2379f29dbc25Smrg * 2380f29dbc25Smrg * This routine returns the current configuration for the hardware video cursor 2381f29dbc25Smrg * color key. 2382f29dbc25Smrg *--------------------------------------------------------------------------*/ 2383f29dbc25Smrg 2384f29dbc25Smrgint 2385f29dbc25Smrgdf_get_video_cursor_color_key(DF_VIDEO_CURSOR_PARAMS * cursor_color_key) 2386f29dbc25Smrg{ 2387f29dbc25Smrg unsigned long key; 2388f29dbc25Smrg 2389f29dbc25Smrg cursor_color_key->flags = 0; 2390f29dbc25Smrg cursor_color_key->color1 = READ_VID32(DF_CURSOR_COLOR_1) & 0xFFFFFF; 2391f29dbc25Smrg cursor_color_key->color2 = READ_VID32(DF_CURSOR_COLOR_2) & 0xFFFFFF; 2392f29dbc25Smrg cursor_color_key->mask = READ_VID32(DF_CURSOR_COLOR_MASK) & 0xFFFFFF; 2393f29dbc25Smrg 2394f29dbc25Smrg key = READ_VID32(DF_CURSOR_COLOR_KEY); 2395f29dbc25Smrg cursor_color_key->key = key & 0xFFFFFF; 2396f29dbc25Smrg cursor_color_key->select_color2 = (key >> 24) & 0x1F; 2397f29dbc25Smrg 2398f29dbc25Smrg return CIM_STATUS_OK; 2399f29dbc25Smrg} 2400f29dbc25Smrg 2401f29dbc25Smrg/*--------------------------------------------------------------------------- 2402f29dbc25Smrg * df_get_video_cursor_color_key_enable 2403f29dbc25Smrg * 2404f29dbc25Smrg * This routine returns the current enable status of the hardware video cursor 2405f29dbc25Smrg * color key. 2406f29dbc25Smrg *--------------------------------------------------------------------------*/ 2407f29dbc25Smrg 2408f29dbc25Smrgint 2409f29dbc25Smrgdf_get_video_cursor_color_key_enable(void) 2410f29dbc25Smrg{ 2411f29dbc25Smrg if (READ_VID32(DF_CURSOR_COLOR_KEY) & DF_CURSOR_COLOR_KEY_ENABLE) 2412f29dbc25Smrg return 1; 2413f29dbc25Smrg 2414f29dbc25Smrg return 0; 2415f29dbc25Smrg} 2416f29dbc25Smrg 2417f29dbc25Smrg/*--------------------------------------------------------------------------- 2418f29dbc25Smrg * df_get_alpha_window_configuration 2419f29dbc25Smrg * 2420f29dbc25Smrg * This routine reads the current configuration for one of the three hardware 2421f29dbc25Smrg * alpha regions. 2422f29dbc25Smrg *--------------------------------------------------------------------------*/ 2423f29dbc25Smrg 2424f29dbc25Smrgint 2425f29dbc25Smrgdf_get_alpha_window_configuration(int window, 2426f29dbc25Smrg DF_ALPHA_REGION_PARAMS * alpha_data) 2427f29dbc25Smrg{ 2428f29dbc25Smrg unsigned long pos, color, alpha_ctl; 2429f29dbc25Smrg unsigned long hsyncend, htotal; 2430f29dbc25Smrg unsigned long vsyncend, vtotal; 2431f29dbc25Smrg unsigned long hadjust, vadjust; 2432f29dbc25Smrg unsigned long xreg, yreg; 2433f29dbc25Smrg unsigned long misc, gfxscale; 2434f29dbc25Smrg unsigned long temp; 2435f29dbc25Smrg char delta; 2436f29dbc25Smrg 2437f29dbc25Smrg if (window > 2) 2438f29dbc25Smrg return CIM_STATUS_INVALIDPARAMS; 2439f29dbc25Smrg 2440f29dbc25Smrg hsyncend = ((READ_REG32(DC3_H_SYNC_TIMING) >> 16) & 0xFFF) + 1; 2441f29dbc25Smrg htotal = ((READ_REG32(DC3_H_ACTIVE_TIMING) >> 16) & 0xFFF) + 1; 2442f29dbc25Smrg if (READ_REG32(DC3_IRQ_FILT_CTL) & DC3_IRQFILT_INTL_EN) { 2443f29dbc25Smrg vtotal = ((READ_REG32(DC3_V_ACTIVE_EVEN) >> 16) & 0xFFF) + 1; 2444f29dbc25Smrg vsyncend = ((READ_REG32(DC3_V_SYNC_EVEN) >> 16) & 0xFFF) + 1; 2445f29dbc25Smrg } else { 2446f29dbc25Smrg vtotal = ((READ_REG32(DC3_V_ACTIVE_TIMING) >> 16) & 0xFFF) + 1; 2447f29dbc25Smrg vsyncend = ((READ_REG32(DC3_V_SYNC_TIMING) >> 16) & 0xFFF) + 1; 2448f29dbc25Smrg } 2449f29dbc25Smrg 2450f29dbc25Smrg /* GET PRIORITY */ 2451f29dbc25Smrg 2452f29dbc25Smrg pos = 16 + (window << 1); 2453f29dbc25Smrg alpha_data->priority = (READ_VID32(DF_VID_ALPHA_CONTROL) >> pos) & 3L; 2454f29dbc25Smrg 2455f29dbc25Smrg /* GET ALPHA WINDOW */ 2456f29dbc25Smrg 2457f29dbc25Smrg hadjust = htotal - hsyncend - 2; 2458f29dbc25Smrg vadjust = vtotal - vsyncend + 1; 2459f29dbc25Smrg 2460f29dbc25Smrg xreg = READ_VID32(DF_ALPHA_XPOS_1 + (window << 5)); 2461f29dbc25Smrg yreg = READ_VID32(DF_ALPHA_YPOS_1 + (window << 5)); 2462f29dbc25Smrg alpha_data->width = ((xreg >> 16) & 0xFFF) - (xreg & 0xFFF); 2463f29dbc25Smrg alpha_data->height = ((yreg >> 16) & 0x7FF) - (yreg & 0x7FF); 2464f29dbc25Smrg alpha_data->x = (xreg & 0xFFF) - hadjust; 2465f29dbc25Smrg alpha_data->y = (yreg & 0x7FF) - vadjust; 2466f29dbc25Smrg 2467f29dbc25Smrg /* REVERSE THE GRAPHICS SCALE */ 2468f29dbc25Smrg 2469f29dbc25Smrg misc = READ_VID32(DF_VID_MISC); 2470f29dbc25Smrg if (misc & DF_USER_IMPLICIT_SCALING) { 2471f29dbc25Smrg gfxscale = READ_REG32(DC3_GFX_SCALE); 2472f29dbc25Smrg if (gfxscale != 0x40004000) { 2473f29dbc25Smrg temp = alpha_data->y + alpha_data->height; 2474f29dbc25Smrg temp = (temp * (gfxscale >> 16)) / 0x4000; 2475f29dbc25Smrg 2476f29dbc25Smrg alpha_data->x = (alpha_data->x * (gfxscale & 0xFFFF)) / 0x4000; 2477f29dbc25Smrg alpha_data->width = 2478f29dbc25Smrg (alpha_data->width * (gfxscale & 0xFFFF)) / 0x4000; 2479f29dbc25Smrg alpha_data->y = (alpha_data->y * (gfxscale >> 16)) / 0x4000; 2480f29dbc25Smrg alpha_data->height = temp - alpha_data->y; 2481f29dbc25Smrg } 2482f29dbc25Smrg } 2483f29dbc25Smrg 2484f29dbc25Smrg if (READ_REG32(DC3_IRQ_FILT_CTL) & DC3_IRQFILT_INTL_EN) { 2485f29dbc25Smrg /* Y COORDINATE IS ACTUALLY 2X THE ODD FIELD START */ 2486f29dbc25Smrg 2487f29dbc25Smrg alpha_data->y <<= 1; 2488f29dbc25Smrg 2489f29dbc25Smrg /* CALCULATE THE EXACT VIDEO HEIGHT */ 2490f29dbc25Smrg /* The height of the video window is the sum of the */ 2491f29dbc25Smrg /* odd and even field heights. */ 2492f29dbc25Smrg 2493f29dbc25Smrg yreg = READ_VID32(DF_VID_ALPHA_Y_EVEN_1 + (window << 3)); 2494f29dbc25Smrg alpha_data->height += ((yreg >> 16) & 0x7FF) - (yreg & 0x7FF); 2495f29dbc25Smrg } 2496f29dbc25Smrg 2497f29dbc25Smrg /* GET COLOR REGISTER */ 2498f29dbc25Smrg 2499f29dbc25Smrg color = READ_VID32(DF_ALPHA_COLOR_1 + (window << 5)); 2500f29dbc25Smrg alpha_data->color = color & 0xFFFFFF; 2501f29dbc25Smrg if (color & DF_ALPHA_COLOR_ENABLE) 2502f29dbc25Smrg alpha_data->flags = DF_ALPHAFLAG_COLORENABLED; 2503f29dbc25Smrg else 2504f29dbc25Smrg alpha_data->flags = 0; 2505f29dbc25Smrg 2506f29dbc25Smrg /* GET ALPHA VALUE, DELTA AND PER PIXEL */ 2507f29dbc25Smrg 2508f29dbc25Smrg alpha_ctl = READ_VID32(DF_ALPHA_CONTROL_1 + (window << 5)); 2509f29dbc25Smrg alpha_data->alpha_value = alpha_ctl & 0xFF; 2510f29dbc25Smrg if (alpha_ctl & DF_ACTRL_PERPIXEL_EN) 2511f29dbc25Smrg alpha_data->flags |= DF_ALPHAFLAG_PERPIXELENABLED; 2512f29dbc25Smrg 2513f29dbc25Smrg delta = (char)((alpha_ctl >> 8) & 0xFF); 2514f29dbc25Smrg alpha_data->delta = (long)delta; 2515f29dbc25Smrg return CIM_STATUS_OK; 2516f29dbc25Smrg} 2517f29dbc25Smrg 2518f29dbc25Smrg/*--------------------------------------------------------------------------- 2519f29dbc25Smrg * df_get_alpha_window_enable 2520f29dbc25Smrg * 2521f29dbc25Smrg * This routine reads the current enable status of one of the three hardware 2522f29dbc25Smrg * alpha regions. 2523f29dbc25Smrg *--------------------------------------------------------------------------*/ 2524f29dbc25Smrg 2525f29dbc25Smrgint 2526f29dbc25Smrgdf_get_alpha_window_enable(int window) 2527f29dbc25Smrg{ 2528f29dbc25Smrg if (window > 2) 2529f29dbc25Smrg return 0; 2530f29dbc25Smrg 2531f29dbc25Smrg if (READ_VID32(DF_ALPHA_CONTROL_1 + (window << 5)) & DF_ACTRL_WIN_ENABLE) 2532f29dbc25Smrg return 1; 2533f29dbc25Smrg 2534f29dbc25Smrg return 0; 2535f29dbc25Smrg} 2536f29dbc25Smrg 2537f29dbc25Smrg/*--------------------------------------------------------------------------- 2538f29dbc25Smrg * df_get_video_request 2539f29dbc25Smrg * 2540f29dbc25Smrg * This routine reads the horizontal (pixel) and vertical (line) video request 2541f29dbc25Smrg * values. 2542f29dbc25Smrg *--------------------------------------------------------------------------*/ 2543f29dbc25Smrg 2544f29dbc25Smrgint 2545f29dbc25Smrgdf_get_video_request(unsigned long *x, unsigned long *y) 2546f29dbc25Smrg{ 2547f29dbc25Smrg unsigned long request; 2548f29dbc25Smrg unsigned long hsyncend, htotal; 2549f29dbc25Smrg unsigned long vsyncend, vtotal; 2550f29dbc25Smrg 2551f29dbc25Smrg hsyncend = ((READ_REG32(DC3_H_SYNC_TIMING) >> 16) & 0xFFF) + 1; 2552f29dbc25Smrg vsyncend = ((READ_REG32(DC3_V_SYNC_TIMING) >> 16) & 0xFFF) + 1; 2553f29dbc25Smrg htotal = ((READ_REG32(DC3_H_ACTIVE_TIMING) >> 16) & 0xFFF) + 1; 2554f29dbc25Smrg vtotal = ((READ_REG32(DC3_V_ACTIVE_TIMING) >> 16) & 0xFFF) + 1; 2555f29dbc25Smrg 2556f29dbc25Smrg request = READ_VID32(DF_VIDEO_REQUEST); 2557f29dbc25Smrg *x = ((request >> 16) & 0xFFF) - (htotal - hsyncend - 2); 2558f29dbc25Smrg *y = (request & 0x7FF) - (vtotal - vsyncend + 1); 2559f29dbc25Smrg 2560f29dbc25Smrg return CIM_STATUS_OK; 2561f29dbc25Smrg} 2562f29dbc25Smrg 2563f29dbc25Smrg/*--------------------------------------------------------------------------- 2564f29dbc25Smrg * df_get_output_color_space 2565f29dbc25Smrg * 2566f29dbc25Smrg * This routine sets the color space used when combining graphics and video. 2567f29dbc25Smrg *--------------------------------------------------------------------------*/ 2568f29dbc25Smrg 2569f29dbc25Smrgint 2570f29dbc25Smrgdf_get_output_color_space(int *color_space) 2571f29dbc25Smrg{ 2572f29dbc25Smrg unsigned long alpha_ctl; 2573f29dbc25Smrg 2574f29dbc25Smrg alpha_ctl = READ_VID32(DF_VID_ALPHA_CONTROL); 2575f29dbc25Smrg 2576f29dbc25Smrg if ((alpha_ctl & DF_CSC_VIDEO_YUV_TO_RGB) || 2577f29dbc25Smrg !(alpha_ctl & DF_CSC_GRAPHICS_RGB_TO_YUV)) { 2578f29dbc25Smrg if (alpha_ctl & DF_ALPHA_DRGB) 2579f29dbc25Smrg *color_space = DF_OUTPUT_ARGB; 2580f29dbc25Smrg else 2581f29dbc25Smrg *color_space = DF_OUTPUT_RGB; 2582f29dbc25Smrg } else { 2583f29dbc25Smrg *color_space = DF_OUTPUT_SDTV; 2584f29dbc25Smrg 2585f29dbc25Smrg if (alpha_ctl & DF_HD_GRAPHICS) 2586f29dbc25Smrg *color_space = DF_OUTPUT_HDTV; 2587f29dbc25Smrg } 2588f29dbc25Smrg 2589f29dbc25Smrg return CIM_STATUS_OK; 2590f29dbc25Smrg} 2591f29dbc25Smrg 2592f29dbc25Smrg#endif 2593