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