📄 stg4000overlaydevice.c
字号:
/* * linux/drivers/video/kyro/STG4000OverlayDevice.c * * Copyright (C) 2000 Imagination Technologies Ltd * Copyright (C) 2002 STMicroelectronics * * This file is subject to the terms and conditions of the GNU General Public * License. See the file COPYING in the main directory of this archive * for more details. */#include <linux/kernel.h>#include <linux/errno.h>#include <linux/types.h>#include "STG4000Reg.h"#include "STG4000Interface.h"/* HW Defines */#define STG4000_NO_SCALING 0x800#define STG4000_NO_DECIMATION 0xFFFFFFFF/* Primary surface */#define STG4000_PRIM_NUM_PIX 5#define STG4000_PRIM_ALIGN 4#define STG4000_PRIM_ADDR_BITS 20#define STG4000_PRIM_MIN_WIDTH 640#define STG4000_PRIM_MAX_WIDTH 1600#define STG4000_PRIM_MIN_HEIGHT 480#define STG4000_PRIM_MAX_HEIGHT 1200/* Overlay surface */#define STG4000_OVRL_NUM_PIX 4#define STG4000_OVRL_ALIGN 2#define STG4000_OVRL_ADDR_BITS 20#define STG4000_OVRL_NUM_MODES 5#define STG4000_OVRL_MIN_WIDTH 0#define STG4000_OVRL_MAX_WIDTH 720#define STG4000_OVRL_MIN_HEIGHT 0#define STG4000_OVRL_MAX_HEIGHT 576/* Decimation and Scaling */static u32 adwDecim8[33] = { 0xffffffff, 0xfffeffff, 0xffdffbff, 0xfefefeff, 0xfdf7efbf, 0xfbdf7bdf, 0xf7bbddef, 0xeeeeeeef, 0xeeddbb77, 0xedb76db7, 0xdb6db6db, 0xdb5b5b5b, 0xdab5ad6b, 0xd5ab55ab, 0xd555aaab, 0xaaaaaaab, 0xaaaa5555, 0xaa952a55, 0xa94a5295, 0xa5252525, 0xa4924925, 0x92491249, 0x91224489, 0x91111111, 0x90884211, 0x88410821, 0x88102041, 0x81010101, 0x80800801, 0x80010001, 0x80000001, 0x00000001, 0x00000000};typedef struct _OVRL_SRC_DEST { /*clipped on-screen pixel position of overlay */ u32 ulDstX1; u32 ulDstY1; u32 ulDstX2; u32 ulDstY2; /*clipped pixel pos of source data within buffer thses need to be 128 bit word aligned */ u32 ulSrcX1; u32 ulSrcY1; u32 ulSrcX2; u32 ulSrcY2; /* on-screen pixel position of overlay */ s32 lDstX1; s32 lDstY1; s32 lDstX2; s32 lDstY2;} OVRL_SRC_DEST;static u32 ovlWidth, ovlHeight, ovlStride;static int ovlLinear;void ResetOverlayRegisters(volatile STG4000REG __iomem *pSTGReg){ u32 tmp; /* Set Overlay address to default */ tmp = STG_READ_REG(DACOverlayAddr); CLEAR_BITS_FRM_TO(0, 20); CLEAR_BIT(31); STG_WRITE_REG(DACOverlayAddr, tmp); /* Set Overlay U address */ tmp = STG_READ_REG(DACOverlayUAddr); CLEAR_BITS_FRM_TO(0, 20); STG_WRITE_REG(DACOverlayUAddr, tmp); /* Set Overlay V address */ tmp = STG_READ_REG(DACOverlayVAddr); CLEAR_BITS_FRM_TO(0, 20); STG_WRITE_REG(DACOverlayVAddr, tmp); /* Set Overlay Size */ tmp = STG_READ_REG(DACOverlaySize); CLEAR_BITS_FRM_TO(0, 10); CLEAR_BITS_FRM_TO(12, 31); STG_WRITE_REG(DACOverlaySize, tmp); /* Set Overlay Vt Decimation */ tmp = STG4000_NO_DECIMATION; STG_WRITE_REG(DACOverlayVtDec, tmp); /* Set Overlay format to default value */ tmp = STG_READ_REG(DACPixelFormat); CLEAR_BITS_FRM_TO(4, 7); CLEAR_BITS_FRM_TO(16, 22); STG_WRITE_REG(DACPixelFormat, tmp); /* Set Vertical scaling to default */ tmp = STG_READ_REG(DACVerticalScal); CLEAR_BITS_FRM_TO(0, 11); CLEAR_BITS_FRM_TO(16, 22); tmp |= STG4000_NO_SCALING; /* Set to no scaling */ STG_WRITE_REG(DACVerticalScal, tmp); /* Set Horizontal Scaling to default */ tmp = STG_READ_REG(DACHorizontalScal); CLEAR_BITS_FRM_TO(0, 11); CLEAR_BITS_FRM_TO(16, 17); tmp |= STG4000_NO_SCALING; /* Set to no scaling */ STG_WRITE_REG(DACHorizontalScal, tmp); /* Set Blend mode to Alpha Blend */ /* ????? SG 08/11/2001 Surely this isn't the alpha blend mode, hopefully its overwrite */ tmp = STG_READ_REG(DACBlendCtrl); CLEAR_BITS_FRM_TO(0, 30); tmp = (GRAPHICS_MODE << 28); STG_WRITE_REG(DACBlendCtrl, tmp);}int CreateOverlaySurface(volatile STG4000REG __iomem *pSTGReg, u32 inWidth, u32 inHeight, int bLinear, u32 ulOverlayOffset, u32 * retStride, u32 * retUVStride){ u32 tmp; u32 ulStride; if (inWidth > STG4000_OVRL_MAX_WIDTH || inHeight > STG4000_OVRL_MAX_HEIGHT) { return -EINVAL; } /* Stride in 16 byte words - 16Bpp */ if (bLinear) { /* Format is 16bits so num 16 byte words is width/8 */ if ((inWidth & 0x7) == 0) { /* inWidth % 8 */ ulStride = (inWidth / 8); } else { /* Round up to next 16byte boundary */ ulStride = ((inWidth + 8) / 8); } } else { /* Y component is 8bits so num 16 byte words is width/16 */ if ((inWidth & 0xf) == 0) { /* inWidth % 16 */ ulStride = (inWidth / 16); } else { /* Round up to next 16byte boundary */ ulStride = ((inWidth + 16) / 16); } } /* Set Overlay address and Format mode */ tmp = STG_READ_REG(DACOverlayAddr); CLEAR_BITS_FRM_TO(0, 20); if (bLinear) { CLEAR_BIT(31); /* Overlay format to Linear */ } else { tmp |= SET_BIT(31); /* Overlay format to Planer */ } /* Only bits 24:4 of the Overlay address */ tmp |= (ulOverlayOffset >> 4); STG_WRITE_REG(DACOverlayAddr, tmp); if (!bLinear) { u32 uvSize = (inWidth & 0x1) ? (inWidth + 1 / 2) : (inWidth / 2); u32 uvStride; u32 ulOffset; /* Y component is 8bits so num 32 byte words is width/32 */ if ((uvSize & 0xf) == 0) { /* inWidth % 16 */ uvStride = (uvSize / 16); } else { /* Round up to next 32byte boundary */ uvStride = ((uvSize + 16) / 16); } ulOffset = ulOverlayOffset + (inHeight * (ulStride * 16)); /* Align U,V data to 32byte boundary */ if ((ulOffset & 0x1f) != 0) ulOffset = (ulOffset + 32L) & 0xffffffE0L; tmp = STG_READ_REG(DACOverlayUAddr); CLEAR_BITS_FRM_TO(0, 20); tmp |= (ulOffset >> 4); STG_WRITE_REG(DACOverlayUAddr, tmp); ulOffset += (inHeight / 2) * (uvStride * 16); /* Align U,V data to 32byte boundary */ if ((ulOffset & 0x1f) != 0) ulOffset = (ulOffset + 32L) & 0xffffffE0L; tmp = STG_READ_REG(DACOverlayVAddr); CLEAR_BITS_FRM_TO(0, 20); tmp |= (ulOffset >> 4); STG_WRITE_REG(DACOverlayVAddr, tmp); *retUVStride = uvStride * 16; } /* Set Overlay YUV pixel format * Make sure that LUT not used - ?????? */ tmp = STG_READ_REG(DACPixelFormat); /* Only support Planer or UYVY linear formats */ CLEAR_BITS_FRM_TO(4, 9); STG_WRITE_REG(DACPixelFormat, tmp); ovlWidth = inWidth; ovlHeight = inHeight; ovlStride = ulStride; ovlLinear = bLinear; *retStride = ulStride << 4; /* In bytes */ return 0;}int SetOverlayBlendMode(volatile STG4000REG __iomem *pSTGReg, OVRL_BLEND_MODE mode, u32 ulAlpha, u32 ulColorKey){ u32 tmp; tmp = STG_READ_REG(DACBlendCtrl); CLEAR_BITS_FRM_TO(28, 30); tmp |= (mode << 28); switch (mode) { case COLOR_KEY: CLEAR_BITS_FRM_TO(0, 23); tmp |= (ulColorKey & 0x00FFFFFF); break; case GLOBAL_ALPHA: CLEAR_BITS_FRM_TO(24, 27); tmp |= ((ulAlpha & 0xF) << 24); break; case CK_PIXEL_ALPHA: CLEAR_BITS_FRM_TO(0, 23); tmp |= (ulColorKey & 0x00FFFFFF); break; case CK_GLOBAL_ALPHA: CLEAR_BITS_FRM_TO(0, 23); tmp |= (ulColorKey & 0x00FFFFFF); CLEAR_BITS_FRM_TO(24, 27); tmp |= ((ulAlpha & 0xF) << 24); break; case GRAPHICS_MODE: case PER_PIXEL_ALPHA: break; default: return -EINVAL; } STG_WRITE_REG(DACBlendCtrl, tmp); return 0;}void EnableOverlayPlane(volatile STG4000REG __iomem *pSTGReg){ u32 tmp; /* Enable Overlay */ tmp = STG_READ_REG(DACPixelFormat); tmp |= SET_BIT(7); STG_WRITE_REG(DACPixelFormat, tmp); /* Set video stream control */ tmp = STG_READ_REG(DACStreamCtrl); tmp |= SET_BIT(1); /* video stream */ STG_WRITE_REG(DACStreamCtrl, tmp);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -