randr12: Refine CR4B, anyone know what this does?
[nouveau] / src / nv04_video_overlay.c
1 /*
2  * Copyright 2007 Arthur Huillet
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17  * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
18  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
19  * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20  * SOFTWARE.
21  */
22
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26
27 #include "xf86xv.h"
28 #include <X11/extensions/Xv.h>
29 #include "exa.h"
30 #include "damage.h"
31 #include "dixstruct.h"
32 #include "fourcc.h"
33
34 #include "nv_include.h"
35 #include "nv_dma.h"
36
37 extern Atom xvBrightness, xvColorKey, xvAutopaintColorKey, xvSetDefaults;
38
39 void
40 NV04PutOverlayImage(ScrnInfoPtr pScrn, int offset, int id,
41                   int dstPitch, BoxPtr dstBox,
42                   int x1, int y1, int x2, int y2,
43                   short width, short height,
44                   short src_w, short src_h,
45                   short drw_w, short drw_h,
46                   RegionPtr clipBoxes)
47 {                       
48         NVPtr         pNv    = NVPTR(pScrn);
49         NVPortPrivPtr pPriv  = GET_OVERLAY_PRIVATE(pNv);
50                 
51         /* paint the color key */
52         if(pPriv->autopaintColorKey && (pPriv->grabbedByV4L ||
53                 !REGION_EQUAL(pScrn->pScreen, &pPriv->clip, clipBoxes))) {
54                 /* we always paint V4L's color key */
55                 if (!pPriv->grabbedByV4L)
56                         REGION_COPY(pScrn->pScreen, &pPriv->clip, clipBoxes);
57                 {
58                 xf86XVFillKeyHelper(pScrn->pScreen, pPriv->colorKey, clipBoxes);
59                 } 
60         }         
61                   
62         if(pNv->CurrentLayout.mode->Flags & V_DBLSCAN) { /*This may not work with NV04 overlay according to rivatv source*/
63                 dstBox->y1 <<= 1;
64                 dstBox->y2 <<= 1;
65                 drw_h <<= 1; 
66         }
67
68         /* NV_PVIDEO_OE_STATE */
69         /* NV_PVIDEO_SU_STATE */
70         /* NV_PVIDEO_RM_STATE */
71         nvWriteRAMDAC(pNv, 0, 0x224, 0);
72         nvWriteRAMDAC(pNv, 0, 0x228, 0);
73         nvWriteRAMDAC(pNv, 0, 0x22c, 0);
74
75         /* NV_PVIDEO_BUFF0_START_ADDRESS */
76         nvWriteRAMDAC(pNv, 0, 0x20C, offset);
77         nvWriteRAMDAC(pNv, 0, 0x20C + 4, offset);
78         /* NV_PVIDEO_BUFF0_PITCH_LENGTH */
79         nvWriteRAMDAC(pNv, 0, 0x214, dstPitch);
80         nvWriteRAMDAC(pNv, 0, 0x214 + 4, dstPitch);
81
82         /* NV_PVIDEO_BUFF0_OFFSET */
83         nvWriteRAMDAC(pNv, 0, 0x21C, 0);
84         nvWriteRAMDAC(pNv, 0, 0x21C + 4, 0);
85
86         /* NV_PVIDEO_WINDOW_START */
87         nvWriteRAMDAC(pNv, 0, 0x230, (dstBox->y1 << 16) | dstBox->x1);
88         /* NV_PVIDEO_WINDOW_SIZE */
89         nvWriteRAMDAC(pNv, 0, 0x234, ((dstBox->y2 - dstBox->y1) << 16) |
90                            (dstBox->x2 - dstBox->x1));
91         /* NV_PVIDEO_STEP_SIZE */
92         nvWriteRAMDAC(pNv,  0,  0x200, (uint32_t)(((src_h - 1) << 11) / (drw_h - 1)) << 16 | (uint32_t)(((src_w - 1) << 11) / (drw_w - 1)));
93
94         /* NV_PVIDEO_RED_CSC_OFFSET */
95         /* NV_PVIDEO_GREEN_CSC_OFFSET */
96         /* NV_PVIDEO_BLUE_CSC_OFFSET */
97         /* NV_PVIDEO_CSC_ADJUST */
98         nvWriteRAMDAC(pNv, 0, 0x280, (0x69 - (pPriv->brightness * 62 / 512)));
99         nvWriteRAMDAC(pNv, 0, 0x284, (0x3e + (pPriv->brightness * 62 / 512)));
100         nvWriteRAMDAC(pNv, 0, 0x288, (0x89 - (pPriv->brightness * 62 / 512)));
101         nvWriteRAMDAC(pNv, 0, 0x28C, 0x0);
102
103         /* NV_PVIDEO_CONTROL_Y (BLUR_ON, LINE_HALF) */
104         nvWriteRAMDAC(pNv, 0, 0x204, 0x001);
105         /* NV_PVIDEO_CONTROL_X (WEIGHT_HEAVY, SHARPENING_ON, SMOOTHING_ON) */
106         nvWriteRAMDAC(pNv, 0, 0x208, 0x111);
107
108         /* NV_PVIDEO_FIFO_BURST_LENGTH */
109         nvWriteRAMDAC(pNv, 0, 0x23C, 0x03);
110         /* NV_PVIDEO_FIFO_THRES_SIZE */
111         nvWriteRAMDAC(pNv, 0, 0x238, 0x38);
112
113         /* Color key */
114         nvWriteRAMDAC(pNv, 0, 0x240, pPriv->colorKey);
115
116         /*NV_PVIDEO_OVERLAY
117                 0x1 Video on
118                 0x10 Use colorkey
119                 0x100 Format YUY2 */
120         nvWriteRAMDAC(pNv, 0, 0x244, 0x111);
121
122         /* NV_PVIDEO_SU_STATE */
123         nvWriteRAMDAC(pNv, 0, 0x228, (nvReadRAMDAC(pNv, 0, 0x228) ^ (1 << 16)));
124
125         pPriv->videoStatus = CLIENT_VIDEO_ON;
126 }
127
128 /**
129  * NV04SetOverlayPortAttribute
130  * sets the attribute "attribute" of port "data" to value "value"
131  * calls NVResetVideo(pScrn) to apply changes to hardware
132  *                      
133  * @param pScrenInfo
134  * @param attribute attribute to set
135  * @param value value to which attribute is to be set
136  * @param data port from which the attribute is to be set
137  * 
138  * @return Success, if setting is successful
139  * BadValue/BadMatch, if value/attribute are invalid
140  * @see NVResetVideo(ScrnInfoPtr pScrn)
141  */
142 int
143 NV04SetOverlayPortAttribute(ScrnInfoPtr pScrn, Atom attribute,
144                           INT32 value, pointer data)
145 {
146         NVPortPrivPtr pPriv = (NVPortPrivPtr)data;
147         NVPtr         pNv   = NVPTR(pScrn);
148
149         if (attribute == xvBrightness) {
150                 if ((value < -512) || (value > 512))
151                         return BadValue;
152                 pPriv->brightness = value;
153         } else
154         if (attribute == xvColorKey) {
155                 pPriv->colorKey = value;
156                 REGION_EMPTY(pScrn->pScreen, &pPriv->clip);
157         } else
158         if (attribute == xvAutopaintColorKey) {
159                 if ((value < 0) || (value > 1))
160                         return BadValue;
161                 pPriv->autopaintColorKey = value;
162         } else
163         if (attribute == xvSetDefaults) {
164                 NVSetPortDefaults(pScrn, pPriv);
165         } else
166                 return BadMatch;
167
168         return Success;
169 }
170
171 /**
172  * NV04GetOverlayPortAttribute
173  * 
174  * @param pScrn unused
175  * @param attribute attribute to be read
176  * @param value value of attribute will be stored in this pointer
177  * @param data port from which attribute will be read
178  * @return Success, if queried attribute exists
179  */
180 int
181 NV04GetOverlayPortAttribute(ScrnInfoPtr pScrn, Atom attribute,
182                           INT32 *value, pointer data)
183 {
184         NVPortPrivPtr pPriv = (NVPortPrivPtr)data;
185
186         if (attribute == xvBrightness)
187                 *value = pPriv->brightness;
188         else if (attribute == xvColorKey)
189                 *value = pPriv->colorKey;
190         else if (attribute == xvAutopaintColorKey)
191                 *value = (pPriv->autopaintColorKey) ? 1 : 0;
192         else
193                 return BadMatch;
194
195         return Success;
196 }
197
198 /**
199  * NV04StopOverlay
200  * Tell the hardware to stop the overlay
201  */
202 void
203 NV04StopOverlay (ScrnInfoPtr pScrn)
204 {
205     NVPtr pNv = NVPTR(pScrn);
206
207     nvWriteRAMDAC(pNv, 0, 0x244, nvReadRAMDAC(pNv, 0, 0x244) &~ 0x1);
208     nvWriteRAMDAC(pNv, 0, 0x224, 0);
209     nvWriteRAMDAC(pNv, 0, 0x228, 0);
210     nvWriteRAMDAC(pNv, 0, 0x22c, 0);
211 }
212