1 /*
2 radeon_vid - VIDIX based video driver for Radeon and Rage128 chips
3 Copyrights 2002 Nick Kurshev. This file is based on sources from
4 GATOS (gatos.sf.net) and X11 (www.xfree86.org)
5 Licence: GPL
6 */
7
8 #ifdef HAVE_CONFIG_H
9 #include "config.h"
10 #endif
11
12 #include <errno.h>
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include <math.h>
17 #include <inttypes.h>
18 #include <sys/types.h>
19 #include <sys/mman.h>
20 #include "bswap.h"
21 #include "pci_ids.h"
22 #include "pci_names.h"
23 #include "vidix.h"
24 #include "fourcc.h"
25 #include "libdha.h"
26 #include "radeon.h"
27
28 #ifdef RAGE128
29 #define RADEON_MSG "[rage128]"
30 #define X_ADJUST 0
31 #else
32 #define RADEON_MSG "[radeon]"
33 #define X_ADJUST (((besr.chip_flags&R_OVL_SHIFT)==R_OVL_SHIFT)?8:0)
34 #ifndef RADEON
35 #define RADEON
36 #endif
37 #endif
38
39 #define RADEON_ASSERT(msg) printf(RADEON_MSG"################# FATAL:"msg);
40
41 #ifdef RAGE128
42 #define VIDIX_STATIC rage128_
43 #else
44 #define VIDIX_STATIC radeo_
45 #endif
46
47 //#undef RADEON_ENABLE_BM /* unfinished stuff. May corrupt your filesystem ever */
48 #define RADEON_ENABLE_BM 1
49
50 #ifdef RADEON_ENABLE_BM
51 static void * radeon_dma_desc_base = 0;
52 static unsigned long bus_addr_dma_desc = 0;
53 static unsigned long *dma_phys_addrs = 0;
54 #pragma pack(1)
55 typedef struct
56 {
57 uint32_t framebuf_offset;
58 uint32_t sys_addr;
59 uint32_t command;
60 uint32_t reserved;
61 } bm_list_descriptor;
62 #pragma pack()
63 #endif
64
65 #define VERBOSE_LEVEL 0
66 static int __verbose = 0;
67 typedef struct bes_registers_s
68 {
69 /* base address of yuv framebuffer */
70 uint32_t yuv_base;
71 uint32_t fourcc;
72 uint32_t surf_id;
73 int load_prg_start;
74 int horz_pick_nearest;
75 int vert_pick_nearest;
76 int swap_uv; /* for direct support of bgr fourccs */
77 uint32_t dest_bpp;
78 /* YUV BES registers */
79 uint32_t reg_load_cntl;
80 uint32_t h_inc;
81 uint32_t step_by;
82 uint32_t y_x_start;
83 uint32_t y_x_end;
84 uint32_t v_inc;
85 uint32_t p1_blank_lines_at_top;
86 uint32_t p23_blank_lines_at_top;
87 uint32_t vid_buf_pitch0_value;
88 uint32_t vid_buf_pitch1_value;
89 uint32_t p1_x_start_end;
90 uint32_t p2_x_start_end;
91 uint32_t p3_x_start_end;
92 uint32_t base_addr;
93 uint32_t vid_buf_base_adrs_y[VID_PLAY_MAXFRAMES];
94 uint32_t vid_buf_base_adrs_u[VID_PLAY_MAXFRAMES];
95 uint32_t vid_buf_base_adrs_v[VID_PLAY_MAXFRAMES];
96 uint32_t vid_nbufs;
97
98 uint32_t p1_v_accum_init;
99 uint32_t p1_h_accum_init;
100 uint32_t p23_v_accum_init;
101 uint32_t p23_h_accum_init;
102 uint32_t scale_cntl;
103 uint32_t exclusive_horz;
104 uint32_t auto_flip_cntl;
105 uint32_t filter_cntl;
106 uint32_t four_tap_coeff[5];
107 uint32_t key_cntl;
108 uint32_t test;
109 /* Configurable stuff */
110 int double_buff;
111
112 int brightness;
113 int saturation;
114
115 uint32_t graphics_key_clr;
116 uint32_t graphics_key_msk;
117 uint32_t ckey_cntl;
118
119 int deinterlace_on;
120 uint32_t deinterlace_pattern;
121 unsigned chip_flags;
122 } bes_registers_t;
123
124 typedef struct video_registers_s
125 {
126 const char * sname;
127 uint32_t name;
128 uint32_t value;
129 }video_registers_t;
130
131 static bes_registers_t besr;
132 #define DECLARE_VREG(name) { #name, name, 0 }
133 static video_registers_t vregs[] =
134 {
135 DECLARE_VREG(VIDEOMUX_CNTL),
136 DECLARE_VREG(VIPPAD_MASK),
137 DECLARE_VREG(VIPPAD1_A),
138 DECLARE_VREG(VIPPAD1_EN),
139 DECLARE_VREG(VIPPAD1_Y),
140 DECLARE_VREG(OV0_Y_X_START),
141 DECLARE_VREG(OV0_Y_X_END),
142 DECLARE_VREG(OV0_PIPELINE_CNTL),
143 DECLARE_VREG(OV0_EXCLUSIVE_HORZ),
144 DECLARE_VREG(OV0_EXCLUSIVE_VERT),
145 DECLARE_VREG(OV0_REG_LOAD_CNTL),
146 DECLARE_VREG(OV0_SCALE_CNTL),
147 DECLARE_VREG(OV0_V_INC),
148 DECLARE_VREG(OV0_P1_V_ACCUM_INIT),
149 DECLARE_VREG(OV0_P23_V_ACCUM_INIT),
150 DECLARE_VREG(OV0_P1_BLANK_LINES_AT_TOP),
151 DECLARE_VREG(OV0_P23_BLANK_LINES_AT_TOP),
152 #ifdef RADEON
153 DECLARE_VREG(OV0_BASE_ADDR),
154 #endif
155 DECLARE_VREG(OV0_VID_BUF0_BASE_ADRS),
156 DECLARE_VREG(OV0_VID_BUF1_BASE_ADRS),
157 DECLARE_VREG(OV0_VID_BUF2_BASE_ADRS),
158 DECLARE_VREG(OV0_VID_BUF3_BASE_ADRS),
159 DECLARE_VREG(OV0_VID_BUF4_BASE_ADRS),
160 DECLARE_VREG(OV0_VID_BUF5_BASE_ADRS),
161 DECLARE_VREG(OV0_VID_BUF_PITCH0_VALUE),
162 DECLARE_VREG(OV0_VID_BUF_PITCH1_VALUE),
163 DECLARE_VREG(OV0_AUTO_FLIP_CNTL),
164 DECLARE_VREG(OV0_DEINTERLACE_PATTERN),
165 DECLARE_VREG(OV0_SUBMIT_HISTORY),
166 DECLARE_VREG(OV0_H_INC),
167 DECLARE_VREG(OV0_STEP_BY),
168 DECLARE_VREG(OV0_P1_H_ACCUM_INIT),
169 DECLARE_VREG(OV0_P23_H_ACCUM_INIT),
170 DECLARE_VREG(OV0_P1_X_START_END),
171 DECLARE_VREG(OV0_P2_X_START_END),
172 DECLARE_VREG(OV0_P3_X_START_END),
173 DECLARE_VREG(OV0_FILTER_CNTL),
174 DECLARE_VREG(OV0_FOUR_TAP_COEF_0),
175 DECLARE_VREG(OV0_FOUR_TAP_COEF_1),
176 DECLARE_VREG(OV0_FOUR_TAP_COEF_2),
177 DECLARE_VREG(OV0_FOUR_TAP_COEF_3),
178 DECLARE_VREG(OV0_FOUR_TAP_COEF_4),
179 DECLARE_VREG(OV0_FLAG_CNTL),
180 #ifdef RAGE128
181 DECLARE_VREG(OV0_COLOUR_CNTL),
182 #else
183 DECLARE_VREG(OV0_SLICE_CNTL),
184 #endif
185 DECLARE_VREG(OV0_VID_KEY_CLR),
186 DECLARE_VREG(OV0_VID_KEY_MSK),
187 DECLARE_VREG(OV0_GRAPHICS_KEY_CLR),
188 DECLARE_VREG(OV0_GRAPHICS_KEY_MSK),
189 DECLARE_VREG(OV0_KEY_CNTL),
190 DECLARE_VREG(OV0_TEST),
191 DECLARE_VREG(OV0_LIN_TRANS_A),
192 DECLARE_VREG(OV0_LIN_TRANS_B),
193 DECLARE_VREG(OV0_LIN_TRANS_C),
194 DECLARE_VREG(OV0_LIN_TRANS_D),
195 DECLARE_VREG(OV0_LIN_TRANS_E),
196 DECLARE_VREG(OV0_LIN_TRANS_F),
197 DECLARE_VREG(OV0_GAMMA_0_F),
198 DECLARE_VREG(OV0_GAMMA_10_1F),
199 DECLARE_VREG(OV0_GAMMA_20_3F),
200 DECLARE_VREG(OV0_GAMMA_40_7F),
201 DECLARE_VREG(OV0_GAMMA_380_3BF),
202 DECLARE_VREG(OV0_GAMMA_3C0_3FF),
203 DECLARE_VREG(SUBPIC_CNTL),
204 DECLARE_VREG(SUBPIC_DEFCOLCON),
205 DECLARE_VREG(SUBPIC_Y_X_START),
206 DECLARE_VREG(SUBPIC_Y_X_END),
207 DECLARE_VREG(SUBPIC_V_INC),
208 DECLARE_VREG(SUBPIC_H_INC),
209 DECLARE_VREG(SUBPIC_BUF0_OFFSET),
210 DECLARE_VREG(SUBPIC_BUF1_OFFSET),
211 DECLARE_VREG(SUBPIC_LC0_OFFSET),
212 DECLARE_VREG(SUBPIC_LC1_OFFSET),
213 DECLARE_VREG(SUBPIC_PITCH),
214 DECLARE_VREG(SUBPIC_BTN_HLI_COLCON),
215 DECLARE_VREG(SUBPIC_BTN_HLI_Y_X_START),
216 DECLARE_VREG(SUBPIC_BTN_HLI_Y_X_END),
217 DECLARE_VREG(SUBPIC_PALETTE_INDEX),
218 DECLARE_VREG(SUBPIC_PALETTE_DATA),
219 DECLARE_VREG(SUBPIC_H_ACCUM_INIT),
220 DECLARE_VREG(SUBPIC_V_ACCUM_INIT),
221 DECLARE_VREG(IDCT_RUNS),
222 DECLARE_VREG(IDCT_LEVELS),
223 DECLARE_VREG(IDCT_AUTH_CONTROL),
224 DECLARE_VREG(IDCT_AUTH),
225 DECLARE_VREG(IDCT_CONTROL),
226 #ifdef RAGE128
227 DECLARE_VREG(BM_FRAME_BUF_OFFSET),
228 DECLARE_VREG(BM_SYSTEM_MEM_ADDR),
229 DECLARE_VREG(BM_COMMAND),
230 DECLARE_VREG(BM_STATUS),
231 DECLARE_VREG(BM_QUEUE_STATUS),
232 DECLARE_VREG(BM_QUEUE_FREE_STATUS),
233 DECLARE_VREG(BM_CHUNK_0_VAL),
234 DECLARE_VREG(BM_CHUNK_1_VAL),
235 DECLARE_VREG(BM_VIP0_BUF),
236 DECLARE_VREG(BM_VIP0_ACTIVE),
237 DECLARE_VREG(BM_VIP1_BUF),
238 DECLARE_VREG(BM_VIP1_ACTIVE),
239 DECLARE_VREG(BM_VIP2_BUF),
240 DECLARE_VREG(BM_VIP2_ACTIVE),
241 DECLARE_VREG(BM_VIP3_BUF),
242 DECLARE_VREG(BM_VIP3_ACTIVE),
243 DECLARE_VREG(BM_VIDCAP_BUF0),
244 DECLARE_VREG(BM_VIDCAP_BUF1),
245 DECLARE_VREG(BM_VIDCAP_BUF2),
246 DECLARE_VREG(BM_VIDCAP_ACTIVE),
247 DECLARE_VREG(BM_GUI),
248 DECLARE_VREG(BM_ABORT)
249 #else
250 DECLARE_VREG(DMA_GUI_TABLE_ADDR),
251 DECLARE_VREG(DMA_GUI_SRC_ADDR),
252 DECLARE_VREG(DMA_GUI_DST_ADDR),
253 DECLARE_VREG(DMA_GUI_COMMAND),
254 DECLARE_VREG(DMA_GUI_STATUS),
255 DECLARE_VREG(DMA_GUI_ACT_DSCRPTR),
256 DECLARE_VREG(DMA_VID_SRC_ADDR),
257 DECLARE_VREG(DMA_VID_DST_ADDR),
258 DECLARE_VREG(DMA_VID_COMMAND),
259 DECLARE_VREG(DMA_VID_STATUS),
260 DECLARE_VREG(DMA_VID_ACT_DSCRPTR),
261 #endif
262 };
263
264 #define R_FAMILY 0x000000FF
265 #define R_100 0x00000001
266 #define R_120 0x00000002
267 #define R_150 0x00000003
268 #define R_200 0x00000004
269 #define R_250 0x00000005
270 #define R_280 0x00000006
271 #define R_300 0x00000007
272 #define R_350 0x00000008
273 #define R_370 0x00000010
274 #define R_380 0x00000020
275 #define R_420 0x00000040
276 #define R_OVL_SHIFT 0x00000100
277 #define R_INTEGRATED 0x00000200
278 #define R_PCIE 0x00000400
279
280 typedef struct ati_card_ids_s
281 {
282 unsigned short id;
283 unsigned flags;
284 }ati_card_ids_t;
285
286 static const ati_card_ids_t ati_card_ids[] =
287 {
288 #ifdef RAGE128
289 /*
290 This driver should be compatible with Rage128 (pro) chips.
291 (include adaptive deinterlacing!!!).
292 Moreover: the same logic can be used with Mach64 chips.
293 (I mean: mach64xx, 3d rage, 3d rage IIc, 3D rage pro, 3d rage mobility).
294 but they are incompatible by i/o ports. So if enthusiasts will want
295 then they can redefine OUTREG and INREG macros and redefine OV0_*
296 constants. Also it seems that mach64 chips supports only: YUY2, YV12, UYVY
297 fourccs (422 and 420 formats only).
298 */
299 /* Rage128 Pro GL */
300 { DEVICE_ATI_RAGE_128_PA_PRO, 0 },
301 { DEVICE_ATI_RAGE_128_PB_PRO, 0 },
302 { DEVICE_ATI_RAGE_128_PC_PRO, 0 },
303 { DEVICE_ATI_RAGE_128_PD_PRO, 0 },
304 { DEVICE_ATI_RAGE_128_PE_PRO, 0 },
305 { DEVICE_ATI_RAGE_128_PF_PRO, 0 },
306 /* Rage128 Pro VR */
307 { DEVICE_ATI_RAGE_128_PG_PRO, 0 },
308 { DEVICE_ATI_RAGE_128_PH_PRO, 0 },
309 { DEVICE_ATI_RAGE_128_PI_PRO, 0 },
310 { DEVICE_ATI_RAGE_128_PJ_PRO, 0 },
311 { DEVICE_ATI_RAGE_128_PK_PRO, 0 },
312 { DEVICE_ATI_RAGE_128_PL_PRO, 0 },
313 { DEVICE_ATI_RAGE_128_PM_PRO, 0 },
314 { DEVICE_ATI_RAGE_128_PN_PRO, 0 },
315 { DEVICE_ATI_RAGE_128_PO_PRO, 0 },
316 { DEVICE_ATI_RAGE_128_PP_PRO, 0 },
317 { DEVICE_ATI_RAGE_128_PQ_PRO, 0 },
318 { DEVICE_ATI_RAGE_128_PR_PRO, 0 },
319 { DEVICE_ATI_RAGE_128_PS_PRO, 0 },
320 { DEVICE_ATI_RAGE_128_PT_PRO, 0 },
321 { DEVICE_ATI_RAGE_128_PU_PRO, 0 },
322 { DEVICE_ATI_RAGE_128_PV_PRO, 0 },
323 { DEVICE_ATI_RAGE_128_PW_PRO, 0 },
324 { DEVICE_ATI_RAGE_128_PX_PRO, 0 },
325 /* Rage128 GL */
326 { DEVICE_ATI_RAGE_128_RE_SG, 0 },
327 { DEVICE_ATI_RAGE_128_RF_SG, 0 },
328 { DEVICE_ATI_RAGE_128_RG, 0 },
329 { DEVICE_ATI_RAGE_128_RK_VR, 0 },
330 { DEVICE_ATI_RAGE_128_RL_VR, 0 },
331 { DEVICE_ATI_RAGE_128_SE_4X, 0 },
332 { DEVICE_ATI_RAGE_128_SF_4X, 0 },
333 { DEVICE_ATI_RAGE_128_SG_4X, 0 },
334 { DEVICE_ATI_RAGE_128_SH, 0 },
335 { DEVICE_ATI_RAGE_128_SK_4X, 0 },
336 { DEVICE_ATI_RAGE_128_SL_4X, 0 },
337 { DEVICE_ATI_RAGE_128_SM_4X, 0 },
338 { DEVICE_ATI_RAGE_128_4X, 0 },
339 { DEVICE_ATI_RAGE_128_PRO, 0 },
340 { DEVICE_ATI_RAGE_128_PRO2, 0 },
341 { DEVICE_ATI_RAGE_128_PRO3, 0 },
342 /* these seem to be based on rage 128 instead of mach64 */
343 { DEVICE_ATI_RAGE_MOBILITY_M3, 0 },
344 { DEVICE_ATI_RAGE_MOBILITY_M32, 0 },
345 #else
346 /* Radeon1 (indeed: Rage 256 Pro ;) */
347 { DEVICE_ATI_RADEON_R100_QD, R_100|R_OVL_SHIFT },
348 { DEVICE_ATI_RADEON_R100_QE, R_100|R_OVL_SHIFT },
349 { DEVICE_ATI_RADEON_R100_QF, R_100|R_OVL_SHIFT },
350 { DEVICE_ATI_RADEON_R100_QG, R_100|R_OVL_SHIFT },
351 { DEVICE_ATI_RADEON_IGP_320, R_150|R_OVL_SHIFT|R_INTEGRATED },
352 { DEVICE_ATI_RADEON_MOBILITY_U1, R_150|R_OVL_SHIFT|R_INTEGRATED },
353 { DEVICE_ATI_RADEON_RV100_QY, R_120|R_OVL_SHIFT },
354 { DEVICE_ATI_RADEON_RV100_QZ, R_120|R_OVL_SHIFT },
355 { DEVICE_ATI_RADEON_MOBILITY_M7, R_150|R_OVL_SHIFT },
356 { DEVICE_ATI_RADEON_RV200_LX, R_150|R_OVL_SHIFT },
357 { DEVICE_ATI_RADEON_MOBILITY_M6, R_120|R_OVL_SHIFT },
358 { DEVICE_ATI_RADEON_MOBILITY_M62, R_120|R_OVL_SHIFT },
359 /* Radeon2 (indeed: Rage 512 Pro ;) */
360 { DEVICE_ATI_R200_BB_RADEON, R_200 },
361 { DEVICE_ATI_R200_BC_RADEON, R_200 },
362 { DEVICE_ATI_RADEON_R200_QH, R_200 },
363 { DEVICE_ATI_RADEON_R200_QI, R_200 },
364 { DEVICE_ATI_RADEON_R200_QJ, R_200 },
365 { DEVICE_ATI_RADEON_R200_QK, R_200 },
366 { DEVICE_ATI_RADEON_R200_QL, R_200 },
367 { DEVICE_ATI_RADEON_R200_QM, R_200 },
368 { DEVICE_ATI_RADEON_R200_QN, R_200 },
369 { DEVICE_ATI_RADEON_R200_QO, R_200 },
370 { DEVICE_ATI_RADEON_R200_QH2, R_200 },
371 { DEVICE_ATI_RADEON_R200_QI2, R_200 },
372 { DEVICE_ATI_RADEON_R200_QJ2, R_200 },
373 { DEVICE_ATI_RADEON_R200_QK2, R_200 },
374 { DEVICE_ATI_RADEON_R200_QL2, R_200 },
375 { DEVICE_ATI_RADEON_RV200_QW, R_150|R_OVL_SHIFT },
376 { DEVICE_ATI_RADEON_RV200_QX, R_150|R_OVL_SHIFT },
377 { DEVICE_ATI_RADEON_IGP330_340_350,R_200|R_INTEGRATED },
378 { DEVICE_ATI_RADEON_IGP_330M_340M_350M,R_200|R_INTEGRATED },
379 { DEVICE_ATI_RADEON_RV250_IG, R_250|R_OVL_SHIFT },
380 { DEVICE_ATI_RADEON_7000_IGP, R_250|R_OVL_SHIFT|R_INTEGRATED },
381 { DEVICE_ATI_RADEON_MOBILITY_7000, R_250|R_OVL_SHIFT|R_INTEGRATED },
382 { DEVICE_ATI_RADEON_RV250_ID, R_250|R_OVL_SHIFT },
383 { DEVICE_ATI_RADEON_RV250_IE, R_250|R_OVL_SHIFT },
384 { DEVICE_ATI_RADEON_RV250_IF, R_250|R_OVL_SHIFT },
385 { DEVICE_ATI_RADEON_RV250_IG, R_250|R_OVL_SHIFT },
386 { DEVICE_ATI_RADEON_R250_LD, R_250|R_OVL_SHIFT },
387 { DEVICE_ATI_RADEON_R250_LE, R_250|R_OVL_SHIFT },
388 { DEVICE_ATI_RADEON_R250_LF, R_250|R_OVL_SHIFT },
389 { DEVICE_ATI_RADEON_R250_LG, R_250|R_OVL_SHIFT },
390 { DEVICE_ATI_RV280_RADEON_92003, R_280 },
391 { DEVICE_ATI_RV280_RADEON_92004, R_280 },
392 { DEVICE_ATI_RV280_RADEON_92005, R_280 },
393 /* Radeon3 (indeed: Rage 1024 Pro ;) */
394 { DEVICE_ATI_R300_AG_FIREGL, R_300 },
395 { DEVICE_ATI_RADEON_R300_ND, R_300 },
396 { DEVICE_ATI_RADEON_R300_NE, R_300 },
397 { DEVICE_ATI_RADEON_R300_NG, R_300 },
398 { DEVICE_ATI_R300_AD_RADEON, R_300 },
399 { DEVICE_ATI_R300_AE_RADEON, R_300 },
400 { DEVICE_ATI_R300_AF_RADEON, R_300 },
401 { DEVICE_ATI_RADEON_9100_IGP2, R_300|R_OVL_SHIFT|R_INTEGRATED },
402 { DEVICE_ATI_RS300M_AGP_RADEON, R_300|R_INTEGRATED },
403 { DEVICE_ATI_R350_AH_RADEON, R_350 },
404 { DEVICE_ATI_R350_AI_RADEON, R_350 },
405 { DEVICE_ATI_R350_AJ_RADEON, R_350 },
406 { DEVICE_ATI_R350_AK_FIRE, R_350 },
407 { DEVICE_ATI_RADEON_R350_RADEON2, R_350 },
408 { DEVICE_ATI_RADEON_R350_RADEON3, R_350 },
409 { DEVICE_ATI_RV350_NJ_RADEON, R_350 },
410 { DEVICE_ATI_R350_NK_FIRE, R_350 },
411 { DEVICE_ATI_RV350_AP_RADEON, R_350 },
412 { DEVICE_ATI_RV350_AQ_RADEON, R_350 },
413 { DEVICE_ATI_RV350_AR_RADEON, R_350 },
414 { DEVICE_ATI_RV350_AS_RADEON, R_350 },
415 { DEVICE_ATI_RV350_AT_FIRE, R_350 },
416 { DEVICE_ATI_RV350_AU_FIRE, R_350 },
417 { DEVICE_ATI_RV350_AV_FIRE, R_350 },
418 { DEVICE_ATI_RV350_AW_FIRE, R_350 },
419 { DEVICE_ATI_RV350_MOBILITY_RADEON, R_350 },
420 { DEVICE_ATI_RV350_NF_RADEON, R_300 },
421 { DEVICE_ATI_RV350_NJ_RADEON, R_300 },
422 { DEVICE_ATI_M10_NQ_RADEON, R_350 },
423 { DEVICE_ATI_RV350_MOBILITY_RADEON2, R_350 },
424 { DEVICE_ATI_M10_NS_RADEON, R_350 },
425 { DEVICE_ATI_M10_NT_FIREGL, R_350 },
426 { DEVICE_ATI_M11_NV_FIREGL, R_350 },
427 { DEVICE_ATI_RV370_5B60_RADEON, R_370|R_PCIE },
428 { DEVICE_ATI_RV370_5B62_RADEON, R_370|R_PCIE },
429 { DEVICE_ATI_RV370_5B64_FIREGL, R_370|R_PCIE },
430 { DEVICE_ATI_RV370_5B65_FIREGL, R_370|R_PCIE },
431 { DEVICE_ATI_RV380_0X3E50_RADEON, R_380|R_PCIE },
432 { DEVICE_ATI_RV380_0X3E54_FIREGL, R_380|R_PCIE },
433 { DEVICE_ATI_RV380_RADEON_X600, R_380|R_PCIE },
434 { DEVICE_ATI_R420_JH_RADEON, R_420|R_PCIE },
435 { DEVICE_ATI_R420_JI_RADEON, R_420|R_PCIE },
436 { DEVICE_ATI_R420_JJ_RADEON, R_420|R_PCIE },
437 { DEVICE_ATI_R420_JK_RADEON, R_420|R_PCIE },
438 { DEVICE_ATI_R420_JL_RADEON, R_420|R_PCIE },
439 { DEVICE_ATI_R420_JM_FIREGL, R_420|R_PCIE },
440 { DEVICE_ATI_M18_JN_RADEON, R_420|R_PCIE },
441 { DEVICE_ATI_R420_JP_RADEON, R_420|R_PCIE },
442 { DEVICE_ATI_R420_JM_FIREGL, R_420|R_PCIE },
443 { DEVICE_ATI_R423_5F57_RADEON, R_420|R_PCIE }
444 #endif
445 };
446
447
448 static void * radeon_mmio_base = 0;
449 static void * radeon_mem_base = 0;
450 static int32_t radeon_overlay_off = 0;
451 static uint32_t radeon_ram_size = 0;
452
453 #define GETREG(TYPE,PTR,OFFZ) (*((volatile TYPE*)((PTR)+(OFFZ))))
454 #define SETREG(TYPE,PTR,OFFZ,VAL) (*((volatile TYPE*)((PTR)+(OFFZ))))=VAL
455
456 #define INREG8(addr) GETREG(uint8_t,(uint32_t)(radeon_mmio_base),addr)
457 #define OUTREG8(addr,val) SETREG(uint8_t,(uint32_t)(radeon_mmio_base),addr,val)
INREG(uint32_t addr)458 static inline uint32_t INREG (uint32_t addr) {
459 uint32_t tmp = GETREG(uint32_t,(uint32_t)(radeon_mmio_base),addr);
460 return le2me_32(tmp);
461 }
462 #define OUTREG(addr,val) SETREG(uint32_t,(uint32_t)(radeon_mmio_base),addr,le2me_32(val))
463 #define OUTREGP(addr,val,mask) \
464 do { \
465 unsigned int _tmp = INREG(addr); \
466 _tmp &= (mask); \
467 _tmp |= (val); \
468 OUTREG(addr, _tmp); \
469 } while (0)
470
471
INPLL(uint32_t addr)472 static __inline__ uint32_t INPLL(uint32_t addr)
473 {
474 OUTREG8(CLOCK_CNTL_INDEX, addr & 0x0000001f);
475 return (INREG(CLOCK_CNTL_DATA));
476 }
477
478 #define OUTPLL(addr,val) OUTREG8(CLOCK_CNTL_INDEX, (addr & 0x0000001f) | 0x00000080); \
479 OUTREG(CLOCK_CNTL_DATA, val)
480 #define OUTPLLP(addr,val,mask) \
481 do { \
482 unsigned int _tmp = INPLL(addr); \
483 _tmp &= (mask); \
484 _tmp |= (val); \
485 OUTPLL(addr, _tmp); \
486 } while (0)
487
radeon_vid_get_dbpp(void)488 static uint32_t radeon_vid_get_dbpp( void )
489 {
490 uint32_t dbpp,retval;
491 dbpp = (INREG(CRTC_GEN_CNTL)>>8)& 0xF;
492 switch(dbpp)
493 {
494 case DST_8BPP: retval = 8; break;
495 case DST_15BPP: retval = 15; break;
496 case DST_16BPP: retval = 16; break;
497 case DST_24BPP: retval = 24; break;
498 default: retval=32; break;
499 }
500 return retval;
501 }
502
radeon_is_dbl_scan(void)503 static int radeon_is_dbl_scan( void )
504 {
505 return (INREG(CRTC_GEN_CNTL))&CRTC_DBL_SCAN_EN;
506 }
507
radeon_is_interlace(void)508 static int radeon_is_interlace( void )
509 {
510 return (INREG(CRTC_GEN_CNTL))&CRTC_INTERLACE_EN;
511 }
512
radeon_get_xres(void)513 static uint32_t radeon_get_xres( void )
514 {
515 /* FIXME: currently we extract that from CRTC!!!*/
516 uint32_t xres,h_total;
517 h_total = INREG(CRTC_H_TOTAL_DISP);
518 xres = (h_total >> 16) & 0xffff;
519 return (xres + 1)*8;
520 }
521
radeon_get_yres(void)522 static uint32_t radeon_get_yres( void )
523 {
524 /* FIXME: currently we extract that from CRTC!!!*/
525 uint32_t yres,v_total;
526 v_total = INREG(CRTC_V_TOTAL_DISP);
527 yres = (v_total >> 16) & 0xffff;
528 return yres + 1;
529 }
530
radeon_wait_vsync(void)531 static void radeon_wait_vsync(void)
532 {
533 int i;
534
535 OUTREG(GEN_INT_STATUS, VSYNC_INT_AK);
536 for (i = 0; i < 2000000; i++)
537 {
538 if (INREG(GEN_INT_STATUS) & VSYNC_INT) break;
539 }
540 }
541
542 #ifdef RAGE128
543 static void _radeon_engine_idle(void);
544 static void _radeon_fifo_wait(unsigned);
545 #define radeon_engine_idle() _radeon_engine_idle()
546 #define radeon_fifo_wait(entries) _radeon_fifo_wait(entries)
547 /* Flush all dirty data in the Pixel Cache to memory. */
radeon_engine_flush(void)548 static __inline__ void radeon_engine_flush ( void )
549 {
550 unsigned i;
551
552 OUTREGP(PC_NGUI_CTLSTAT, PC_FLUSH_ALL, ~PC_FLUSH_ALL);
553 for (i = 0; i < 2000000; i++) {
554 if (!(INREG(PC_NGUI_CTLSTAT) & PC_BUSY)) break;
555 }
556 }
557
558 /* Reset graphics card to known state. */
radeon_engine_reset(void)559 static void radeon_engine_reset( void )
560 {
561 uint32_t clock_cntl_index;
562 uint32_t mclk_cntl;
563 uint32_t gen_reset_cntl;
564
565 radeon_engine_flush();
566
567 clock_cntl_index = INREG(CLOCK_CNTL_INDEX);
568 mclk_cntl = INPLL(MCLK_CNTL);
569
570 OUTPLL(MCLK_CNTL, mclk_cntl | FORCE_GCP | FORCE_PIPE3D_CP);
571
572 gen_reset_cntl = INREG(GEN_RESET_CNTL);
573
574 OUTREG(GEN_RESET_CNTL, gen_reset_cntl | SOFT_RESET_GUI);
575 INREG(GEN_RESET_CNTL);
576 OUTREG(GEN_RESET_CNTL,
577 gen_reset_cntl & (uint32_t)(~SOFT_RESET_GUI));
578 INREG(GEN_RESET_CNTL);
579
580 OUTPLL(MCLK_CNTL, mclk_cntl);
581 OUTREG(CLOCK_CNTL_INDEX, clock_cntl_index);
582 OUTREG(GEN_RESET_CNTL, gen_reset_cntl);
583 }
584 #else
585
radeon_engine_flush(void)586 static __inline__ void radeon_engine_flush ( void )
587 {
588 int i;
589
590 /* initiate flush */
591 OUTREGP(RB2D_DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL,
592 ~RB2D_DC_FLUSH_ALL);
593
594 for (i=0; i < 2000000; i++) {
595 if (!(INREG(RB2D_DSTCACHE_CTLSTAT) & RB2D_DC_BUSY))
596 break;
597 }
598 }
599
600 static void _radeon_engine_idle(void);
601 static void _radeon_fifo_wait(unsigned);
602 #define radeon_engine_idle() _radeon_engine_idle()
603 #define radeon_fifo_wait(entries) _radeon_fifo_wait(entries)
604
radeon_engine_reset(void)605 static void radeon_engine_reset( void )
606 {
607 uint32_t clock_cntl_index, mclk_cntl, rbbm_soft_reset;
608
609 radeon_engine_flush ();
610
611 clock_cntl_index = INREG(CLOCK_CNTL_INDEX);
612 mclk_cntl = INPLL(MCLK_CNTL);
613
614 OUTPLL(MCLK_CNTL, (mclk_cntl |
615 FORCEON_MCLKA |
616 FORCEON_MCLKB |
617 FORCEON_YCLKA |
618 FORCEON_YCLKB |
619 FORCEON_MC |
620 FORCEON_AIC));
621 rbbm_soft_reset = INREG(RBBM_SOFT_RESET);
622
623 OUTREG(RBBM_SOFT_RESET, rbbm_soft_reset |
624 SOFT_RESET_CP |
625 SOFT_RESET_HI |
626 SOFT_RESET_SE |
627 SOFT_RESET_RE |
628 SOFT_RESET_PP |
629 SOFT_RESET_E2 |
630 SOFT_RESET_RB |
631 SOFT_RESET_HDP);
632 INREG(RBBM_SOFT_RESET);
633 OUTREG(RBBM_SOFT_RESET, rbbm_soft_reset & (uint32_t)
634 ~(SOFT_RESET_CP |
635 SOFT_RESET_HI |
636 SOFT_RESET_SE |
637 SOFT_RESET_RE |
638 SOFT_RESET_PP |
639 SOFT_RESET_E2 |
640 SOFT_RESET_RB |
641 SOFT_RESET_HDP));
642 INREG(RBBM_SOFT_RESET);
643
644 OUTPLL(MCLK_CNTL, mclk_cntl);
645 OUTREG(CLOCK_CNTL_INDEX, clock_cntl_index);
646 OUTREG(RBBM_SOFT_RESET, rbbm_soft_reset);
647
648 return;
649 }
650 #endif
radeon_engine_restore(void)651 static void radeon_engine_restore( void )
652 {
653 #ifndef RAGE128
654 int pitch64;
655 uint32_t xres,yres,bpp;
656 radeon_fifo_wait(1);
657 xres = radeon_get_xres();
658 yres = radeon_get_yres();
659 bpp = radeon_vid_get_dbpp();
660 /* turn of all automatic flushing - we'll do it all */
661 OUTREG(RB2D_DSTCACHE_MODE, 0);
662
663 pitch64 = ((xres * (bpp / 8) + 0x3f)) >> 6;
664
665 radeon_fifo_wait(1);
666 OUTREG(DEFAULT_OFFSET, (INREG(DEFAULT_OFFSET) & 0xC0000000) |
667 (pitch64 << 22));
668
669 radeon_fifo_wait(1);
670 #if defined(WORDS_BIGENDIAN)
671 OUTREGP(DP_DATATYPE,
672 HOST_BIG_ENDIAN_EN, ~HOST_BIG_ENDIAN_EN);
673 #else
674 OUTREGP(DP_DATATYPE, 0, ~HOST_BIG_ENDIAN_EN);
675 #endif
676
677 radeon_fifo_wait(1);
678 OUTREG(DEFAULT_SC_BOTTOM_RIGHT, (DEFAULT_SC_RIGHT_MAX
679 | DEFAULT_SC_BOTTOM_MAX));
680 radeon_fifo_wait(1);
681 OUTREG(DP_GUI_MASTER_CNTL, (INREG(DP_GUI_MASTER_CNTL)
682 | GMC_BRUSH_SOLID_COLOR
683 | GMC_SRC_DATATYPE_COLOR));
684
685 radeon_fifo_wait(7);
686 OUTREG(DST_LINE_START, 0);
687 OUTREG(DST_LINE_END, 0);
688 OUTREG(DP_BRUSH_FRGD_CLR, 0xffffffff);
689 OUTREG(DP_BRUSH_BKGD_CLR, 0x00000000);
690 OUTREG(DP_SRC_FRGD_CLR, 0xffffffff);
691 OUTREG(DP_SRC_BKGD_CLR, 0x00000000);
692 OUTREG(DP_WRITE_MASK, 0xffffffff);
693
694 radeon_engine_idle();
695 #endif
696 }
697 #ifdef RAGE128
_radeon_fifo_wait(unsigned entries)698 static void _radeon_fifo_wait (unsigned entries)
699 {
700 unsigned i;
701
702 for(;;)
703 {
704 for (i=0; i<2000000; i++)
705 if ((INREG(GUI_STAT) & GUI_FIFOCNT_MASK) >= entries)
706 return;
707 radeon_engine_reset();
708 radeon_engine_restore();
709 }
710 }
711
_radeon_engine_idle(void)712 static void _radeon_engine_idle ( void )
713 {
714 unsigned i;
715
716 /* ensure FIFO is empty before waiting for idle */
717 radeon_fifo_wait (64);
718 for(;;)
719 {
720 for (i=0; i<2000000; i++) {
721 if ((INREG(GUI_STAT) & GUI_ACTIVE) == 0) {
722 radeon_engine_flush ();
723 return;
724 }
725 }
726 radeon_engine_reset();
727 radeon_engine_restore();
728 }
729 }
730 #else
_radeon_fifo_wait(unsigned entries)731 static void _radeon_fifo_wait (unsigned entries)
732 {
733 unsigned i;
734
735 for(;;)
736 {
737 for (i=0; i<2000000; i++)
738 if ((INREG(RBBM_STATUS) & RBBM_FIFOCNT_MASK) >= entries)
739 return;
740 radeon_engine_reset();
741 radeon_engine_restore();
742 }
743 }
_radeon_engine_idle(void)744 static void _radeon_engine_idle ( void )
745 {
746 int i;
747
748 /* ensure FIFO is empty before waiting for idle */
749 radeon_fifo_wait (64);
750 for(;;)
751 {
752 for (i=0; i<2000000; i++) {
753 if (((INREG(RBBM_STATUS) & RBBM_ACTIVE)) == 0) {
754 radeon_engine_flush ();
755 return;
756 }
757 }
758 radeon_engine_reset();
759 radeon_engine_restore();
760 }
761 }
762 #endif
763
764 #ifndef RAGE128
765 /* Reference color space transform data */
766 typedef struct tagREF_TRANSFORM
767 {
768 float RefLuma;
769 float RefRCb;
770 float RefRCr;
771 float RefGCb;
772 float RefGCr;
773 float RefBCb;
774 float RefBCr;
775 } REF_TRANSFORM;
776
777 /* Parameters for ITU-R BT.601 and ITU-R BT.709 colour spaces */
778 REF_TRANSFORM trans[2] =
779 {
780 {1.1678, 0.0, 1.6007, -0.3929, -0.8154, 2.0232, 0.0}, /* BT.601 */
781 {1.1678, 0.0, 1.7980, -0.2139, -0.5345, 2.1186, 0.0} /* BT.709 */
782 };
783 /****************************************************************************
784 * SetTransform *
785 * Function: Calculates and sets color space transform from supplied *
786 * reference transform, gamma, brightness, contrast, hue and *
787 * saturation. *
788 * Inputs: bright - brightness *
789 * cont - contrast *
790 * sat - saturation *
791 * hue - hue *
792 * red_intensity - intense of red component *
793 * green_intensity - intense of green component *
794 * blue_intensity - intense of blue component *
795 * ref - index to the table of refernce transforms *
796 * Outputs: NONE *
797 ****************************************************************************/
798
radeon_set_transform(float bright,float cont,float sat,float hue,float red_intensity,float green_intensity,float blue_intensity,unsigned ref)799 static void radeon_set_transform(float bright, float cont, float sat,
800 float hue, float red_intensity,
801 float green_intensity,float blue_intensity,
802 unsigned ref)
803 {
804 float OvHueSin, OvHueCos;
805 float CAdjLuma, CAdjOff;
806 float RedAdj,GreenAdj,BlueAdj;
807 float CAdjRCb, CAdjRCr;
808 float CAdjGCb, CAdjGCr;
809 float CAdjBCb, CAdjBCr;
810 float OvLuma, OvROff, OvGOff, OvBOff;
811 float OvRCb, OvRCr;
812 float OvGCb, OvGCr;
813 float OvBCb, OvBCr;
814 float Loff = 64.0;
815 float Coff = 512.0f;
816
817 uint32_t dwOvLuma, dwOvROff, dwOvGOff, dwOvBOff;
818 uint32_t dwOvRCb, dwOvRCr;
819 uint32_t dwOvGCb, dwOvGCr;
820 uint32_t dwOvBCb, dwOvBCr;
821
822 if (ref >= 2) return;
823
824 OvHueSin = sin((double)hue);
825 OvHueCos = cos((double)hue);
826
827 CAdjLuma = cont * trans[ref].RefLuma;
828 CAdjOff = cont * trans[ref].RefLuma * bright * 1023.0;
829 RedAdj = cont * trans[ref].RefLuma * red_intensity * 1023.0;
830 GreenAdj = cont * trans[ref].RefLuma * green_intensity * 1023.0;
831 BlueAdj = cont * trans[ref].RefLuma * blue_intensity * 1023.0;
832
833 CAdjRCb = sat * -OvHueSin * trans[ref].RefRCr;
834 CAdjRCr = sat * OvHueCos * trans[ref].RefRCr;
835 CAdjGCb = sat * (OvHueCos * trans[ref].RefGCb - OvHueSin * trans[ref].RefGCr);
836 CAdjGCr = sat * (OvHueSin * trans[ref].RefGCb + OvHueCos * trans[ref].RefGCr);
837 CAdjBCb = sat * OvHueCos * trans[ref].RefBCb;
838 CAdjBCr = sat * OvHueSin * trans[ref].RefBCb;
839
840 #if 0 /* default constants */
841 CAdjLuma = 1.16455078125;
842
843 CAdjRCb = 0.0;
844 CAdjRCr = 1.59619140625;
845 CAdjGCb = -0.39111328125;
846 CAdjGCr = -0.8125;
847 CAdjBCb = 2.01708984375;
848 CAdjBCr = 0;
849 #endif
850 OvLuma = CAdjLuma;
851 OvRCb = CAdjRCb;
852 OvRCr = CAdjRCr;
853 OvGCb = CAdjGCb;
854 OvGCr = CAdjGCr;
855 OvBCb = CAdjBCb;
856 OvBCr = CAdjBCr;
857 OvROff = RedAdj + CAdjOff -
858 OvLuma * Loff - (OvRCb + OvRCr) * Coff;
859 OvGOff = GreenAdj + CAdjOff -
860 OvLuma * Loff - (OvGCb + OvGCr) * Coff;
861 OvBOff = BlueAdj + CAdjOff -
862 OvLuma * Loff - (OvBCb + OvBCr) * Coff;
863 #if 0 /* default constants */
864 OvROff = -888.5;
865 OvGOff = 545;
866 OvBOff = -1104;
867 #endif
868
869 dwOvROff = ((int)(OvROff * 2.0)) & 0x1fff;
870 dwOvGOff = (int)(OvGOff * 2.0) & 0x1fff;
871 dwOvBOff = (int)(OvBOff * 2.0) & 0x1fff;
872 /* Whatever docs say about R200 having 3.8 format instead of 3.11
873 as in Radeon is a lie */
874 #if 0
875 if(!IsR200)
876 {
877 #endif
878 dwOvLuma =(((int)(OvLuma * 2048.0))&0x7fff)<<17;
879 dwOvRCb = (((int)(OvRCb * 2048.0))&0x7fff)<<1;
880 dwOvRCr = (((int)(OvRCr * 2048.0))&0x7fff)<<17;
881 dwOvGCb = (((int)(OvGCb * 2048.0))&0x7fff)<<1;
882 dwOvGCr = (((int)(OvGCr * 2048.0))&0x7fff)<<17;
883 dwOvBCb = (((int)(OvBCb * 2048.0))&0x7fff)<<1;
884 dwOvBCr = (((int)(OvBCr * 2048.0))&0x7fff)<<17;
885 #if 0
886 }
887 else
888 {
889 dwOvLuma = (((int)(OvLuma * 256.0))&0x7ff)<<20;
890 dwOvRCb = (((int)(OvRCb * 256.0))&0x7ff)<<4;
891 dwOvRCr = (((int)(OvRCr * 256.0))&0x7ff)<<20;
892 dwOvGCb = (((int)(OvGCb * 256.0))&0x7ff)<<4;
893 dwOvGCr = (((int)(OvGCr * 256.0))&0x7ff)<<20;
894 dwOvBCb = (((int)(OvBCb * 256.0))&0x7ff)<<4;
895 dwOvBCr = (((int)(OvBCr * 256.0))&0x7ff)<<20;
896 }
897 #endif
898 OUTREG(OV0_LIN_TRANS_A, dwOvRCb | dwOvLuma);
899 OUTREG(OV0_LIN_TRANS_B, dwOvROff | dwOvRCr);
900 OUTREG(OV0_LIN_TRANS_C, dwOvGCb | dwOvLuma);
901 OUTREG(OV0_LIN_TRANS_D, dwOvGOff | dwOvGCr);
902 OUTREG(OV0_LIN_TRANS_E, dwOvBCb | dwOvLuma);
903 OUTREG(OV0_LIN_TRANS_F, dwOvBOff | dwOvBCr);
904 }
905
906 /* Gamma curve definition */
907 typedef struct
908 {
909 unsigned int gammaReg;
910 unsigned int gammaSlope;
911 unsigned int gammaOffset;
912 }GAMMA_SETTINGS;
913
914 /* Recommended gamma curve parameters */
915 GAMMA_SETTINGS r200_def_gamma[18] =
916 {
917 {OV0_GAMMA_0_F, 0x100, 0x0000},
918 {OV0_GAMMA_10_1F, 0x100, 0x0020},
919 {OV0_GAMMA_20_3F, 0x100, 0x0040},
920 {OV0_GAMMA_40_7F, 0x100, 0x0080},
921 {OV0_GAMMA_80_BF, 0x100, 0x0100},
922 {OV0_GAMMA_C0_FF, 0x100, 0x0100},
923 {OV0_GAMMA_100_13F, 0x100, 0x0200},
924 {OV0_GAMMA_140_17F, 0x100, 0x0200},
925 {OV0_GAMMA_180_1BF, 0x100, 0x0300},
926 {OV0_GAMMA_1C0_1FF, 0x100, 0x0300},
927 {OV0_GAMMA_200_23F, 0x100, 0x0400},
928 {OV0_GAMMA_240_27F, 0x100, 0x0400},
929 {OV0_GAMMA_280_2BF, 0x100, 0x0500},
930 {OV0_GAMMA_2C0_2FF, 0x100, 0x0500},
931 {OV0_GAMMA_300_33F, 0x100, 0x0600},
932 {OV0_GAMMA_340_37F, 0x100, 0x0600},
933 {OV0_GAMMA_380_3BF, 0x100, 0x0700},
934 {OV0_GAMMA_3C0_3FF, 0x100, 0x0700}
935 };
936
937 GAMMA_SETTINGS r100_def_gamma[6] =
938 {
939 {OV0_GAMMA_0_F, 0x100, 0x0000},
940 {OV0_GAMMA_10_1F, 0x100, 0x0020},
941 {OV0_GAMMA_20_3F, 0x100, 0x0040},
942 {OV0_GAMMA_40_7F, 0x100, 0x0080},
943 {OV0_GAMMA_380_3BF, 0x100, 0x0100},
944 {OV0_GAMMA_3C0_3FF, 0x100, 0x0100}
945 };
946
make_default_gamma_correction(void)947 static void make_default_gamma_correction( void )
948 {
949 size_t i;
950 if((besr.chip_flags & R_100)==R_100||
951 (besr.chip_flags & R_120)==R_120||
952 (besr.chip_flags & R_150)==R_150){
953 OUTREG(OV0_LIN_TRANS_A, 0x12A00000);
954 OUTREG(OV0_LIN_TRANS_B, 0x199018FE);
955 OUTREG(OV0_LIN_TRANS_C, 0x12A0F9B0);
956 OUTREG(OV0_LIN_TRANS_D, 0xF2F0043B);
957 OUTREG(OV0_LIN_TRANS_E, 0x12A02050);
958 OUTREG(OV0_LIN_TRANS_F, 0x0000174E);
959 for(i=0; i<6; i++){
960 OUTREG(r100_def_gamma[i].gammaReg,
961 (r100_def_gamma[i].gammaSlope<<16) |
962 r100_def_gamma[i].gammaOffset);
963 }
964 }
965 else{
966 OUTREG(OV0_LIN_TRANS_A, 0x12a20000);
967 OUTREG(OV0_LIN_TRANS_B, 0x198a190e);
968 OUTREG(OV0_LIN_TRANS_C, 0x12a2f9da);
969 OUTREG(OV0_LIN_TRANS_D, 0xf2fe0442);
970 OUTREG(OV0_LIN_TRANS_E, 0x12a22046);
971 OUTREG(OV0_LIN_TRANS_F, 0x175f);
972 /* Default Gamma,
973 Of 18 segments for gamma cure, all segments in R200 are programmable,
974 while only lower 4 and upper 2 segments are programmable in Radeon*/
975 for(i=0; i<18; i++){
976 OUTREG(r200_def_gamma[i].gammaReg,
977 (r200_def_gamma[i].gammaSlope<<16) |
978 r200_def_gamma[i].gammaOffset);
979 }
980 }
981 }
982 #endif
983
radeon_vid_make_default(void)984 static void radeon_vid_make_default(void)
985 {
986 #ifdef RAGE128
987 besr.saturation = 0x0F;
988 besr.brightness = 0;
989 OUTREG(OV0_COLOUR_CNTL,0x000F0F00UL); /* Default brihgtness and saturation for Rage128 */
990 #else
991 make_default_gamma_correction();
992 #endif
993 besr.deinterlace_pattern = 0x900AAAAA;
994 OUTREG(OV0_DEINTERLACE_PATTERN,besr.deinterlace_pattern);
995 besr.deinterlace_on=1;
996 besr.double_buff=1;
997 besr.graphics_key_msk=0;
998 besr.graphics_key_clr=0;
999 besr.ckey_cntl = VIDEO_KEY_FN_TRUE|GRAPHIC_KEY_FN_TRUE|CMP_MIX_AND;
1000 }
1001
1002
VIDIX_NAME(vixGetVersion)1003 unsigned VIDIX_NAME(vixGetVersion)( void ) { return VIDIX_VERSION; }
1004
1005
find_chip(unsigned chip_id)1006 static int find_chip(unsigned chip_id)
1007 {
1008 unsigned i;
1009 for(i = 0;i < sizeof(ati_card_ids)/sizeof(ati_card_ids_t);i++)
1010 {
1011 if(chip_id == ati_card_ids[i].id) return i;
1012 }
1013 return -1;
1014 }
1015
1016 static pciinfo_t pci_info;
1017 static int probed=0;
1018
1019 vidix_capability_t def_cap =
1020 {
1021 #ifdef RAGE128
1022 "BES driver for rage128 cards",
1023 #else
1024 "BES driver for radeon cards",
1025 #endif
1026 "Nick Kurshev",
1027 TYPE_OUTPUT | TYPE_FX,
1028 { 0, 0, 0, 0 },
1029 2048,
1030 2048,
1031 4,
1032 4,
1033 -1,
1034 FLAG_UPSCALER | FLAG_DOWNSCALER | FLAG_EQUALIZER,
1035 VENDOR_ATI,
1036 0,
1037 { 0, 0, 0, 0}
1038 };
1039
1040
VIDIX_NAME(vixProbe)1041 int VIDIX_NAME(vixProbe)( int verbose,int force )
1042 {
1043 pciinfo_t lst[MAX_PCI_DEVICES];
1044 unsigned i,num_pci;
1045 int err;
1046 __verbose = verbose;
1047 err = pci_scan(lst,&num_pci);
1048 if(err)
1049 {
1050 printf(RADEON_MSG" Error occured during pci scan: %s\n",strerror(err));
1051 return err;
1052 }
1053 else
1054 {
1055 err = ENXIO;
1056 for(i=0;i<num_pci;i++)
1057 {
1058 if(lst[i].vendor == VENDOR_ATI)
1059 {
1060 int idx;
1061 const char *dname;
1062 idx = find_chip(lst[i].device);
1063 if(idx == -1 && force == PROBE_NORMAL) continue;
1064 dname = pci_device_name(VENDOR_ATI,lst[i].device);
1065 dname = dname ? dname : "Unknown chip";
1066 printf(RADEON_MSG" Found chip: %s\n",dname);
1067 memset(&besr,0,sizeof(bes_registers_t));
1068 if(force > PROBE_NORMAL)
1069 {
1070 printf(RADEON_MSG" Driver was forced. Was found %sknown chip\n",idx == -1 ? "un" : "");
1071 if(idx == -1)
1072 #ifdef RAGE128
1073 printf(RADEON_MSG" Assuming it as Rage128\n");
1074 #else
1075 printf(RADEON_MSG" Assuming it as Radeon1\n");
1076 #endif
1077 besr.chip_flags=R_100|R_OVL_SHIFT;
1078 }
1079 if(idx != -1) besr.chip_flags=ati_card_ids[idx].flags;
1080 def_cap.device_id = lst[i].device;
1081 err = 0;
1082 memcpy(&pci_info,&lst[i],sizeof(pciinfo_t));
1083 probed=1;
1084 break;
1085 }
1086 }
1087 }
1088 if(err && verbose) printf(RADEON_MSG" Can't find chip\n");
1089 return err;
1090 }
1091
1092 #ifndef RAGE128
1093 enum radeon_montype
1094 {
1095 MT_NONE,
1096 MT_CRT, /* CRT-(cathode ray tube) analog monitor. (15-pin VGA connector) */
1097 MT_LCD, /* Liquid Crystal Display */
1098 MT_DFP, /* DFP-digital flat panel monitor. (24-pin DVI-I connector) */
1099 MT_CTV, /* Composite TV out (not in VE) */
1100 MT_STV /* S-Video TV out (probably in VE only) */
1101 };
1102
1103 typedef struct radeon_info_s
1104 {
1105 int hasCRTC2;
1106 int crtDispType;
1107 int dviDispType;
1108 }rinfo_t;
1109
1110 static rinfo_t rinfo;
1111
GET_MON_NAME(int type)1112 static const char * GET_MON_NAME(int type)
1113 {
1114 const char *pret;
1115 switch(type)
1116 {
1117 case MT_NONE: pret = "no"; break;
1118 case MT_CRT: pret = "CRT"; break;
1119 case MT_DFP: pret = "DFP"; break;
1120 case MT_LCD: pret = "LCD"; break;
1121 case MT_CTV: pret = "CTV"; break;
1122 case MT_STV: pret = "STV"; break;
1123 default: pret = "Unknown";
1124 }
1125 return pret;
1126 }
1127
radeon_get_moninfo(rinfo_t * rinfo)1128 static void radeon_get_moninfo (rinfo_t *rinfo)
1129 {
1130 unsigned int tmp;
1131
1132 tmp = INREG(RADEON_BIOS_4_SCRATCH);
1133
1134 if (rinfo->hasCRTC2) {
1135 /* primary DVI port */
1136 if (tmp & 0x08)
1137 rinfo->dviDispType = MT_DFP;
1138 else if (tmp & 0x4)
1139 rinfo->dviDispType = MT_LCD;
1140 else if (tmp & 0x200)
1141 rinfo->dviDispType = MT_CRT;
1142 else if (tmp & 0x10)
1143 rinfo->dviDispType = MT_CTV;
1144 else if (tmp & 0x20)
1145 rinfo->dviDispType = MT_STV;
1146
1147 /* secondary CRT port */
1148 if (tmp & 0x2)
1149 rinfo->crtDispType = MT_CRT;
1150 else if (tmp & 0x800)
1151 rinfo->crtDispType = MT_DFP;
1152 else if (tmp & 0x400)
1153 rinfo->crtDispType = MT_LCD;
1154 else if (tmp & 0x1000)
1155 rinfo->crtDispType = MT_CTV;
1156 else if (tmp & 0x2000)
1157 rinfo->crtDispType = MT_STV;
1158 } else {
1159 rinfo->dviDispType = MT_NONE;
1160
1161 tmp = INREG(FP_GEN_CNTL);
1162
1163 if (tmp & FP_EN_TMDS)
1164 rinfo->crtDispType = MT_DFP;
1165 else
1166 rinfo->crtDispType = MT_CRT;
1167 }
1168 }
1169 #endif
1170
1171 typedef struct saved_regs_s
1172 {
1173 uint32_t ov0_vid_key_clr;
1174 uint32_t ov0_vid_key_msk;
1175 uint32_t ov0_graphics_key_clr;
1176 uint32_t ov0_graphics_key_msk;
1177 uint32_t ov0_key_cntl;
1178 }saved_regs_t;
1179 static saved_regs_t savreg;
1180
save_regs(void)1181 static void save_regs( void )
1182 {
1183 radeon_fifo_wait(6);
1184 savreg.ov0_vid_key_clr = INREG(OV0_VID_KEY_CLR);
1185 savreg.ov0_vid_key_msk = INREG(OV0_VID_KEY_MSK);
1186 savreg.ov0_graphics_key_clr = INREG(OV0_GRAPHICS_KEY_CLR);
1187 savreg.ov0_graphics_key_msk = INREG(OV0_GRAPHICS_KEY_MSK);
1188 savreg.ov0_key_cntl = INREG(OV0_KEY_CNTL);
1189 }
1190
restore_regs(void)1191 static void restore_regs( void )
1192 {
1193 radeon_fifo_wait(6);
1194 OUTREG(OV0_VID_KEY_CLR,savreg.ov0_vid_key_clr);
1195 OUTREG(OV0_VID_KEY_MSK,savreg.ov0_vid_key_msk);
1196 OUTREG(OV0_GRAPHICS_KEY_CLR,savreg.ov0_graphics_key_clr);
1197 OUTREG(OV0_GRAPHICS_KEY_MSK,savreg.ov0_graphics_key_msk);
1198 OUTREG(OV0_KEY_CNTL,savreg.ov0_key_cntl);
1199 }
1200
VIDIX_NAME(vixInit)1201 int VIDIX_NAME(vixInit)( const char *args )
1202 {
1203 int err;
1204 (void)args;
1205 if(!probed)
1206 {
1207 printf(RADEON_MSG" Driver was not probed but is being initializing\n");
1208 return EINTR;
1209 }
1210 if((radeon_mmio_base = map_phys_mem(pci_info.base2,0xFFFF))==(void *)-1) return ENOMEM;
1211 radeon_ram_size = INREG(CONFIG_MEMSIZE);
1212 /* mem size is bits [28:0], mask off the rest. Range: from 1Mb up to 512 Mb */
1213 radeon_ram_size &= CONFIG_MEMSIZE_MASK;
1214 #ifdef RADEON
1215 /* according to XFree86 4.2.0, some production M6's return 0 for 8MB */
1216 if (radeon_ram_size == 0 &&
1217 (def_cap.device_id == DEVICE_ATI_RADEON_MOBILITY_M6 ||
1218 def_cap.device_id == DEVICE_ATI_RADEON_MOBILITY_M62))
1219 {
1220 printf(RADEON_MSG" Workarounding buggy Radeon Mobility M6 (0 vs. 8MB ram)\n");
1221 radeon_ram_size = 8192*1024;
1222 }
1223 #else
1224 /* Rage Mobility (rage128) also has memsize bug */
1225 if (radeon_ram_size == 0 &&
1226 (def_cap.device_id == DEVICE_ATI_RAGE_MOBILITY_M3 ||
1227 def_cap.device_id == DEVICE_ATI_RAGE_MOBILITY_M32))
1228 {
1229 printf(RADEON_MSG" Workarounding buggy Rage Mobility M3 (0 vs. 8MB ram)\n");
1230 radeon_ram_size = 8192*1024;
1231 }
1232 #endif
1233 if((radeon_mem_base = map_phys_mem(pci_info.base0,radeon_ram_size))==(void *)-1) return ENOMEM;
1234 radeon_vid_make_default();
1235 printf(RADEON_MSG" Video memory = %uMb\n",radeon_ram_size/0x100000);
1236 err = mtrr_set_type(pci_info.base0,radeon_ram_size,MTRR_TYPE_WRCOMB);
1237 if(!err) printf(RADEON_MSG" Set write-combining type of video memory\n");
1238 #ifndef RAGE128
1239 {
1240 memset(&rinfo,0,sizeof(rinfo_t));
1241 if((besr.chip_flags&R_100) != R_100) rinfo.hasCRTC2 = 1;
1242
1243 radeon_get_moninfo(&rinfo);
1244 if(rinfo.hasCRTC2) {
1245 printf(RADEON_MSG" DVI port has %s monitor connected\n",GET_MON_NAME(rinfo.dviDispType));
1246 printf(RADEON_MSG" CRT port has %s monitor connected\n",GET_MON_NAME(rinfo.crtDispType));
1247 }
1248 else
1249 printf(RADEON_MSG" CRT port has %s monitor connected\n",GET_MON_NAME(rinfo.crtDispType));
1250 }
1251 #endif
1252 #ifdef RADEON_ENABLE_BM
1253 if(bm_open() == 0)
1254 {
1255 if((dma_phys_addrs = malloc(radeon_ram_size*sizeof(unsigned long)/4096)) != 0)
1256 def_cap.flags |= FLAG_DMA | FLAG_EQ_DMA;
1257 else
1258 printf(RADEON_MSG" Can't allocate temopary buffer for DMA\n");
1259 }
1260 else
1261 if(__verbose) printf(RADEON_MSG" Can't initialize busmastering: %s\n",strerror(errno));
1262 #endif
1263 save_regs();
1264 return 0;
1265 }
1266
VIDIX_NAME(vixDestroy)1267 void VIDIX_NAME(vixDestroy)( void )
1268 {
1269 restore_regs();
1270 unmap_phys_mem(radeon_mem_base,radeon_ram_size);
1271 unmap_phys_mem(radeon_mmio_base,0xFFFF);
1272 bm_close();
1273 }
1274
VIDIX_NAME(vixGetCapability)1275 int VIDIX_NAME(vixGetCapability)(vidix_capability_t *to)
1276 {
1277 memcpy(to,&def_cap,sizeof(vidix_capability_t));
1278 return 0;
1279 }
1280
1281 /*
1282 Full list of fourcc which are supported by Win2K radeon driver:
1283 YUY2, UYVY, DDES, OGLT, OGL2, OGLS, OGLB, OGNT, OGNZ, OGNS,
1284 IF09, YVU9, IMC4, M2IA, IYUV, VBID, DXT1, DXT2, DXT3, DXT4, DXT5
1285 */
1286 typedef struct fourcc_desc_s
1287 {
1288 uint32_t fourcc;
1289 unsigned max_srcw;
1290 }fourcc_desc_t;
1291
1292 fourcc_desc_t supported_fourcc[] =
1293 {
1294 { IMGFMT_Y800, 1567 },
1295 { IMGFMT_YVU9, 1567 },
1296 { IMGFMT_IF09, 1567 },
1297 { IMGFMT_YV12, 1567 },
1298 { IMGFMT_I420, 1567 },
1299 { IMGFMT_IYUV, 1567 },
1300 { IMGFMT_UYVY, 1551 },
1301 { IMGFMT_YUY2, 1551 },
1302 { IMGFMT_YVYU, 1551 },
1303 { IMGFMT_RGB15, 1551 },
1304 { IMGFMT_BGR15, 1551 },
1305 { IMGFMT_RGB16, 1551 },
1306 { IMGFMT_BGR16, 1551 },
1307 { IMGFMT_RGB32, 775 },
1308 { IMGFMT_BGR32, 775 }
1309 };
1310
is_supported_fourcc(uint32_t fourcc,unsigned srcw)1311 __inline__ static int is_supported_fourcc(uint32_t fourcc,unsigned srcw)
1312 {
1313 unsigned i;
1314 for(i=0;i<sizeof(supported_fourcc)/sizeof(fourcc_desc_t);i++)
1315 {
1316 if(fourcc==supported_fourcc[i].fourcc &&
1317 srcw <=supported_fourcc[i].max_srcw) return 1;
1318 }
1319 return 0;
1320 }
1321
VIDIX_NAME(vixQueryFourcc)1322 int VIDIX_NAME(vixQueryFourcc)(vidix_fourcc_t *to)
1323 {
1324 if(is_supported_fourcc(to->fourcc,to->srcw))
1325 {
1326 to->depth = VID_DEPTH_1BPP | VID_DEPTH_2BPP |
1327 VID_DEPTH_4BPP | VID_DEPTH_8BPP |
1328 VID_DEPTH_12BPP| VID_DEPTH_15BPP|
1329 VID_DEPTH_16BPP| VID_DEPTH_24BPP|
1330 VID_DEPTH_32BPP;
1331 to->flags = VID_CAP_EXPAND | VID_CAP_SHRINK | VID_CAP_COLORKEY;
1332 return 0;
1333 }
1334 else to->depth = to->flags = 0;
1335 return ENOSYS;
1336 }
1337
1338 static double H_scale_ratio;
radeon_vid_dump_regs(void)1339 static void radeon_vid_dump_regs( void )
1340 {
1341 size_t i;
1342 printf(RADEON_MSG"*** Begin of DRIVER variables dump ***\n");
1343 printf(RADEON_MSG"radeon_mmio_base=%p\n",radeon_mmio_base);
1344 printf(RADEON_MSG"radeon_mem_base=%p\n",radeon_mem_base);
1345 printf(RADEON_MSG"radeon_overlay_off=%08X\n",radeon_overlay_off);
1346 printf(RADEON_MSG"radeon_ram_size=%08X\n",radeon_ram_size);
1347 printf(RADEON_MSG"video mode: %ux%u@%u\n",radeon_get_xres(),radeon_get_yres(),radeon_vid_get_dbpp());
1348 printf(RADEON_MSG"H_scale_ratio=%8.2f\n",H_scale_ratio);
1349 printf(RADEON_MSG"*** Begin of OV0 registers dump ***\n");
1350 for(i=0;i<sizeof(vregs)/sizeof(video_registers_t);i++)
1351 printf(RADEON_MSG"%s = %08X\n",vregs[i].sname,INREG(vregs[i].name));
1352 printf(RADEON_MSG"*** End of OV0 registers dump ***\n");
1353 }
1354
radeon_vid_stop_video(void)1355 static void radeon_vid_stop_video( void )
1356 {
1357 radeon_engine_idle();
1358 OUTREG(OV0_SCALE_CNTL, SCALER_SOFT_RESET);
1359 OUTREG(OV0_EXCLUSIVE_HORZ, 0);
1360 OUTREG(OV0_AUTO_FLIP_CNTL, 0); /* maybe */
1361 OUTREG(OV0_FILTER_CNTL, FILTER_HARDCODED_COEF);
1362 #ifdef RAGE128
1363 OUTREG(OV0_KEY_CNTL, GRAPHIC_KEY_FN_NE);
1364 #else
1365 OUTREG(OV0_KEY_CNTL, GRAPHIC_KEY_FN_EQ);
1366 #endif
1367 OUTREG(OV0_TEST, 0);
1368 }
1369
radeon_vid_display_video(void)1370 static void radeon_vid_display_video( void )
1371 {
1372 int bes_flags;
1373 radeon_fifo_wait(2);
1374 OUTREG(OV0_REG_LOAD_CNTL, REG_LD_CTL_LOCK);
1375 radeon_engine_idle();
1376 while(!(INREG(OV0_REG_LOAD_CNTL)®_LD_CTL_LOCK_READBACK));
1377 radeon_fifo_wait(15);
1378
1379 /* Shutdown capturing */
1380 OUTREG(FCP_CNTL, FCP_CNTL__GND);
1381 OUTREG(CAP0_TRIG_CNTL, 0);
1382
1383 OUTREG(VID_BUFFER_CONTROL, (1<<16) | 0x01);
1384 OUTREG(DISP_TEST_DEBUG_CNTL, 0);
1385
1386 OUTREG(OV0_AUTO_FLIP_CNTL,OV0_AUTO_FLIP_CNTL_SOFT_BUF_ODD);
1387
1388 if(besr.deinterlace_on) OUTREG(OV0_DEINTERLACE_PATTERN,besr.deinterlace_pattern);
1389 #ifdef RAGE128
1390 OUTREG(OV0_COLOUR_CNTL, (besr.brightness & 0x7f) |
1391 (besr.saturation << 8) |
1392 (besr.saturation << 16));
1393 #endif
1394 radeon_fifo_wait(2);
1395 OUTREG(OV0_GRAPHICS_KEY_MSK, besr.graphics_key_msk);
1396 OUTREG(OV0_GRAPHICS_KEY_CLR, besr.graphics_key_clr);
1397 OUTREG(OV0_KEY_CNTL,besr.ckey_cntl);
1398
1399 OUTREG(OV0_H_INC, besr.h_inc);
1400 OUTREG(OV0_STEP_BY, besr.step_by);
1401 OUTREG(OV0_Y_X_START, besr.y_x_start);
1402 OUTREG(OV0_Y_X_END, besr.y_x_end);
1403 OUTREG(OV0_V_INC, besr.v_inc);
1404 OUTREG(OV0_P1_BLANK_LINES_AT_TOP, besr.p1_blank_lines_at_top);
1405 OUTREG(OV0_P23_BLANK_LINES_AT_TOP, besr.p23_blank_lines_at_top);
1406 OUTREG(OV0_VID_BUF_PITCH0_VALUE, besr.vid_buf_pitch0_value);
1407 OUTREG(OV0_VID_BUF_PITCH1_VALUE, besr.vid_buf_pitch1_value);
1408 OUTREG(OV0_P1_X_START_END, besr.p1_x_start_end);
1409 OUTREG(OV0_P2_X_START_END, besr.p2_x_start_end);
1410 OUTREG(OV0_P3_X_START_END, besr.p3_x_start_end);
1411 #ifdef RADEON
1412 OUTREG(OV0_BASE_ADDR, besr.base_addr);
1413 #endif
1414 OUTREG(OV0_VID_BUF0_BASE_ADRS, besr.vid_buf_base_adrs_y[0]);
1415 OUTREG(OV0_VID_BUF1_BASE_ADRS, besr.vid_buf_base_adrs_v[0]);
1416 OUTREG(OV0_VID_BUF2_BASE_ADRS, besr.vid_buf_base_adrs_u[0]);
1417 radeon_fifo_wait(9);
1418 OUTREG(OV0_VID_BUF3_BASE_ADRS, besr.vid_buf_base_adrs_y[0]);
1419 OUTREG(OV0_VID_BUF4_BASE_ADRS, besr.vid_buf_base_adrs_v[0]);
1420 OUTREG(OV0_VID_BUF5_BASE_ADRS, besr.vid_buf_base_adrs_u[0]);
1421 OUTREG(OV0_P1_V_ACCUM_INIT, besr.p1_v_accum_init);
1422 OUTREG(OV0_P1_H_ACCUM_INIT, besr.p1_h_accum_init);
1423 OUTREG(OV0_P23_H_ACCUM_INIT, besr.p23_h_accum_init);
1424 OUTREG(OV0_P23_V_ACCUM_INIT, besr.p23_v_accum_init);
1425
1426 bes_flags = SCALER_ENABLE |
1427 SCALER_SMART_SWITCH |
1428 SCALER_Y2R_TEMP |
1429 SCALER_PIX_EXPAND;
1430 if(besr.double_buff) bes_flags |= SCALER_DOUBLE_BUFFER;
1431 if(besr.deinterlace_on) bes_flags |= SCALER_ADAPTIVE_DEINT;
1432 if(besr.horz_pick_nearest) bes_flags |= SCALER_HORZ_PICK_NEAREST;
1433 if(besr.vert_pick_nearest) bes_flags |= SCALER_VERT_PICK_NEAREST;
1434 #ifdef RAGE128
1435 bes_flags |= SCALER_BURST_PER_PLANE;
1436 #endif
1437 bes_flags |= (besr.surf_id << 8) & SCALER_SURFAC_FORMAT;
1438 if(besr.load_prg_start) bes_flags |= SCALER_PRG_LOAD_START;
1439 OUTREG(OV0_SCALE_CNTL, bes_flags);
1440 #ifndef RAGE128
1441 if(rinfo.hasCRTC2 &&
1442 (rinfo.dviDispType == MT_CTV || rinfo.dviDispType == MT_STV))
1443 {
1444 /* TODO: suppress scaler output to CRTC here and enable TVO only */
1445 }
1446 #endif
1447 radeon_fifo_wait(6);
1448 OUTREG(OV0_FILTER_CNTL,besr.filter_cntl);
1449 OUTREG(OV0_FOUR_TAP_COEF_0,besr.four_tap_coeff[0]);
1450 OUTREG(OV0_FOUR_TAP_COEF_1,besr.four_tap_coeff[1]);
1451 OUTREG(OV0_FOUR_TAP_COEF_2,besr.four_tap_coeff[2]);
1452 OUTREG(OV0_FOUR_TAP_COEF_3,besr.four_tap_coeff[3]);
1453 OUTREG(OV0_FOUR_TAP_COEF_4,besr.four_tap_coeff[4]);
1454 if(besr.swap_uv) OUTREG(OV0_TEST,INREG(OV0_TEST)|OV0_SWAP_UV);
1455 OUTREG(OV0_REG_LOAD_CNTL, 0);
1456 if(__verbose > VERBOSE_LEVEL) printf(RADEON_MSG"we wanted: scaler=%08X\n",bes_flags);
1457 if(__verbose > VERBOSE_LEVEL) radeon_vid_dump_regs();
1458 }
1459
1460 /* Goal of this function: hide RGB background and provide black screen around movie.
1461 Useful in '-vo fbdev:vidix -fs -zoom' mode.
1462 Reverse effect to colorkey */
1463 #ifdef RAGE128
radeon_vid_exclusive(void)1464 static void radeon_vid_exclusive( void )
1465 {
1466 /* this function works only with Rage128.
1467 Radeon should has something the same */
1468 unsigned screenw,screenh;
1469 screenw = radeon_get_xres();
1470 screenh = radeon_get_yres();
1471 radeon_fifo_wait(2);
1472 OUTREG(OV0_EXCLUSIVE_VERT,(((screenh-1)<<16)&EXCL_VERT_END_MASK));
1473 OUTREG(OV0_EXCLUSIVE_HORZ,(((screenw/8+1)<<8)&EXCL_HORZ_END_MASK)|EXCL_HORZ_EXCLUSIVE_EN);
1474 }
1475
radeon_vid_non_exclusive(void)1476 static void radeon_vid_non_exclusive( void )
1477 {
1478 OUTREG(OV0_EXCLUSIVE_HORZ,0);
1479 }
1480 #endif
1481
radeon_query_pitch(unsigned fourcc,const vidix_yuv_t * spitch)1482 static unsigned radeon_query_pitch(unsigned fourcc,const vidix_yuv_t *spitch)
1483 {
1484 unsigned pitch,spy,spv,spu;
1485 spy = spv = spu = 0;
1486 switch(spitch->y)
1487 {
1488 case 16:
1489 case 32:
1490 case 64:
1491 case 128:
1492 case 256: spy = spitch->y; break;
1493 default: break;
1494 }
1495 switch(spitch->u)
1496 {
1497 case 16:
1498 case 32:
1499 case 64:
1500 case 128:
1501 case 256: spu = spitch->u; break;
1502 default: break;
1503 }
1504 switch(spitch->v)
1505 {
1506 case 16:
1507 case 32:
1508 case 64:
1509 case 128:
1510 case 256: spv = spitch->v; break;
1511 default: break;
1512 }
1513 switch(fourcc)
1514 {
1515 /* 4:2:0 */
1516 case IMGFMT_IYUV:
1517 case IMGFMT_YV12:
1518 case IMGFMT_I420:
1519 if(spy > 16 && spu == spy/2 && spv == spy/2) pitch = spy;
1520 else pitch = 32;
1521 break;
1522 case IMGFMT_IF09:
1523 case IMGFMT_YVU9:
1524 if(spy >= 64 && spu == spy/4 && spv == spy/4) pitch = spy;
1525 else pitch = 64;
1526 break;
1527 default:
1528 if(spy >= 16) pitch = spy;
1529 else pitch = 16;
1530 break;
1531 }
1532 return pitch;
1533 }
1534
Calc_H_INC_STEP_BY(int fieldvalue_OV0_SURFACE_FORMAT,double H_scale_ratio,int DisallowFourTapVertFiltering,int DisallowFourTapUVVertFiltering,uint32_t * val_OV0_P1_H_INC,uint32_t * val_OV0_P1_H_STEP_BY,uint32_t * val_OV0_P23_H_INC,uint32_t * val_OV0_P23_H_STEP_BY,int * P1GroupSize,int * P1StepSize,int * P23StepSize)1535 static void Calc_H_INC_STEP_BY (
1536 int fieldvalue_OV0_SURFACE_FORMAT,
1537 double H_scale_ratio,
1538 int DisallowFourTapVertFiltering,
1539 int DisallowFourTapUVVertFiltering,
1540 uint32_t *val_OV0_P1_H_INC,
1541 uint32_t *val_OV0_P1_H_STEP_BY,
1542 uint32_t *val_OV0_P23_H_INC,
1543 uint32_t *val_OV0_P23_H_STEP_BY,
1544 int *P1GroupSize,
1545 int *P1StepSize,
1546 int *P23StepSize )
1547 {
1548
1549 double ClocksNeededFor16Pixels;
1550
1551 switch (fieldvalue_OV0_SURFACE_FORMAT)
1552 {
1553 case 3:
1554 case 4: /*16BPP (ARGB1555 and RGB565) */
1555 /* All colour components are fetched in pairs */
1556 *P1GroupSize = 2;
1557 /* We don't support four tap in this mode because G's are split between two bytes. In theory we could support it if */
1558 /* we saved part of the G when fetching the R, and then filter the G, followed by the B in the following cycles. */
1559 if (H_scale_ratio>=.5)
1560 {
1561 /* We are actually generating two pixels (but 3 colour components) per tick. Thus we don't have to skip */
1562 /* until we reach .5. P1 and P23 are the same. */
1563 *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio)) * (1<<0xc) + 0.5);
1564 *val_OV0_P1_H_STEP_BY = 1;
1565 *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio)) * (1<<0xc) + 0.5);
1566 *val_OV0_P23_H_STEP_BY = 1;
1567 *P1StepSize = 1;
1568 *P23StepSize = 1;
1569 }
1570 else if (H_scale_ratio>=.25)
1571 {
1572 /* Step by two */
1573 *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio*2)) * (1<<0xc) + 0.5);
1574 *val_OV0_P1_H_STEP_BY = 2;
1575 *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*2)) * (1<<0xc) + 0.5);
1576 *val_OV0_P23_H_STEP_BY = 2;
1577 *P1StepSize = 2;
1578 *P23StepSize = 2;
1579 }
1580 else if (H_scale_ratio>=.125)
1581 {
1582 /* Step by four */
1583 *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio*4)) * (1<<0xc) + 0.5);
1584 *val_OV0_P1_H_STEP_BY = 3;
1585 *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*4)) * (1<<0xc) + 0.5);
1586 *val_OV0_P23_H_STEP_BY = 3;
1587 *P1StepSize = 4;
1588 *P23StepSize = 4;
1589 }
1590 else if (H_scale_ratio>=.0625)
1591 {
1592 /* Step by eight */
1593 *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio*8)) * (1<<0xc) + 0.5);
1594 *val_OV0_P1_H_STEP_BY = 4;
1595 *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*8)) * (1<<0xc) + 0.5);
1596 *val_OV0_P23_H_STEP_BY = 4;
1597 *P1StepSize = 8;
1598 *P23StepSize = 8;
1599 }
1600 else if (H_scale_ratio>=0.03125)
1601 {
1602 /* Step by sixteen */
1603 *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio*16)) * (1<<0xc) + 0.5);
1604 *val_OV0_P1_H_STEP_BY = 5;
1605 *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*16)) * (1<<0xc) + 0.5);
1606 *val_OV0_P23_H_STEP_BY = 5;
1607 *P1StepSize = 16;
1608 *P23StepSize = 16;
1609 }
1610 else
1611 {
1612 H_scale_ratio=0.03125;
1613 *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio*16)) * (1<<0xc) + 0.5);
1614 *val_OV0_P1_H_STEP_BY = 5;
1615 *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*16)) * (1<<0xc) + 0.5);
1616 *val_OV0_P23_H_STEP_BY = 5;
1617 *P1StepSize = 16;
1618 *P23StepSize = 16;
1619 }
1620 break;
1621 case 6: /*32BPP RGB */
1622 if (H_scale_ratio>=1.5 && !DisallowFourTapVertFiltering)
1623 {
1624 /* All colour components are fetched in pairs */
1625 *P1GroupSize = 2;
1626 /* With four tap filtering, we can generate two colour components every clock, or two pixels every three */
1627 /* clocks. This means that we will have four tap filtering when scaling 1.5 or more. */
1628 *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio)) * (1<<0xc) + 0.5);
1629 *val_OV0_P1_H_STEP_BY = 0;
1630 *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio)) * (1<<0xc) + 0.5);
1631 *val_OV0_P23_H_STEP_BY = 0;
1632 *P1StepSize = 1;
1633 *P23StepSize = 1;
1634 }
1635 else if (H_scale_ratio>=0.75)
1636 {
1637 /* Four G colour components are fetched at once */
1638 *P1GroupSize = 4;
1639 /* R and B colour components are fetched in pairs */
1640 /* With two tap filtering, we can generate four colour components every clock. */
1641 /* This means that we will have two tap filtering when scaling 1.0 or more. */
1642 *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio)) * (1<<0xc) + 0.5);
1643 *val_OV0_P1_H_STEP_BY = 1;
1644 *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio)) * (1<<0xc) + 0.5);
1645 *val_OV0_P23_H_STEP_BY = 1;
1646 *P1StepSize = 1;
1647 *P23StepSize = 1;
1648 }
1649 else if (H_scale_ratio>=0.375)
1650 {
1651 /* Step by two. */
1652 /* Four G colour components are fetched at once */
1653 *P1GroupSize = 4;
1654 /* R and B colour components are fetched in pairs */
1655 *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio*2)) * (1<<0xc) + 0.5);
1656 *val_OV0_P1_H_STEP_BY = 2;
1657 *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*2)) * (1<<0xc) + 0.5);
1658 *val_OV0_P23_H_STEP_BY = 2;
1659 *P1StepSize = 2;
1660 *P23StepSize = 2;
1661 }
1662 else if (H_scale_ratio>=0.25)
1663 {
1664 /* Step by two. */
1665 /* Four G colour components are fetched at once */
1666 *P1GroupSize = 4;
1667 /* R and B colour components are fetched in pairs */
1668 *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio*2)) * (1<<0xc) + 0.5);
1669 *val_OV0_P1_H_STEP_BY = 2;
1670 *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*4)) * (1<<0xc) + 0.5);
1671 *val_OV0_P23_H_STEP_BY = 3;
1672 *P1StepSize = 2;
1673 *P23StepSize = 4;
1674 }
1675 else if (H_scale_ratio>=0.1875)
1676 {
1677 /* Step by four */
1678 /* Four G colour components are fetched at once */
1679 *P1GroupSize = 4;
1680 /* R and B colour components are fetched in pairs */
1681 *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio*4)) * (1<<0xc) + 0.5);
1682 *val_OV0_P1_H_STEP_BY = 3;
1683 *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*4)) * (1<<0xc) + 0.5);
1684 *val_OV0_P23_H_STEP_BY = 3;
1685 *P1StepSize = 4;
1686 *P23StepSize = 4;
1687 }
1688 else if (H_scale_ratio>=0.125)
1689 {
1690 /* Step by four */
1691 /* Four G colour components are fetched at once */
1692 *P1GroupSize = 4;
1693 /* R and B colour components are fetched in pairs */
1694 *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio*4)) * (1<<0xc) + 0.5);
1695 *val_OV0_P1_H_STEP_BY = 3;
1696 *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*8)) * (1<<0xc) + 0.5);
1697 *val_OV0_P23_H_STEP_BY = 4;
1698 *P1StepSize = 4;
1699 *P23StepSize = 8;
1700 }
1701 else if (H_scale_ratio>=0.09375)
1702 {
1703 /* Step by eight */
1704 /* Four G colour components are fetched at once */
1705 *P1GroupSize = 4;
1706 /* R and B colour components are fetched in pairs */
1707 *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio*8)) * (1<<0xc) + 0.5);
1708 *val_OV0_P1_H_STEP_BY = 4;
1709 *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*8)) * (1<<0xc) + 0.5);
1710 *val_OV0_P23_H_STEP_BY = 4;
1711 *P1StepSize = 8;
1712 *P23StepSize = 8;
1713 }
1714 else if (H_scale_ratio>=0.0625)
1715 {
1716 /* Step by eight */
1717 /* Four G colour components are fetched at once */
1718 *P1GroupSize = 4;
1719 /* R and B colour components are fetched in pairs */
1720 *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio*16)) * (1<<0xc) + 0.5);
1721 *val_OV0_P1_H_STEP_BY = 5;
1722 *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*16)) * (1<<0xc) + 0.5);
1723 *val_OV0_P23_H_STEP_BY = 5;
1724 *P1StepSize = 16;
1725 *P23StepSize = 16;
1726 }
1727 else
1728 {
1729 H_scale_ratio=0.0625;
1730 *P1GroupSize = 4;
1731 *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio*16)) * (1<<0xc) + 0.5);
1732 *val_OV0_P1_H_STEP_BY = 5;
1733 *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*16)) * (1<<0xc) + 0.5);
1734 *val_OV0_P23_H_STEP_BY = 5;
1735 *P1StepSize = 16;
1736 *P23StepSize = 16;
1737 }
1738 break;
1739 case 9:
1740 /*ToDo_Active: In mode 9 there is a possibility that HScale ratio may be set to an illegal value, so we have extra conditions in the if statement. For consistancy, these conditions be added to the other modes as well. */
1741 /* four tap on both (unless Y is too wide) */
1742 if ((H_scale_ratio>=(ClocksNeededFor16Pixels=8+2+2) / 16.0) &&
1743 ((uint16_t)((1/(H_scale_ratio)) * (1<<0xc) + 0.5)<=0x3000) &&
1744 ((uint16_t)((1/(H_scale_ratio*4)) * (1<<0xc) + 0.5)<=0x2000) &&
1745 !DisallowFourTapVertFiltering && !DisallowFourTapUVVertFiltering)
1746 { /*0.75 */
1747 /* Colour components are fetched in pairs */
1748 *P1GroupSize = 2;
1749 *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio)) * (1<<0xc) + 0.5);
1750 *val_OV0_P1_H_STEP_BY = 0;
1751 *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*4)) * (1<<0xc) + 0.5);
1752 *val_OV0_P23_H_STEP_BY = 0;
1753 *P1StepSize = 1;
1754 *P23StepSize = 1;
1755 }
1756 /* two tap on Y (because it is too big for four tap), four tap on UV */
1757 else if ((H_scale_ratio>=(ClocksNeededFor16Pixels=4+2+2) / 16.0) &&
1758 ((uint16_t)((1/(H_scale_ratio)) * (1<<0xc) + 0.5)<=0x3000) &&
1759 ((uint16_t)((1/(H_scale_ratio*4)) * (1<<0xc) + 0.5)<=0x2000) &&
1760 DisallowFourTapVertFiltering && !DisallowFourTapUVVertFiltering)
1761 { /*0.75 */
1762 *P1GroupSize = 4;
1763 *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio)) * (1<<0xc) + 0.5);
1764 *val_OV0_P1_H_STEP_BY = 1;
1765 *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*4)) * (1<<0xc) + 0.5);
1766 *val_OV0_P23_H_STEP_BY = 0;
1767 *P1StepSize = 1;
1768 *P23StepSize = 1;
1769 }
1770 /* We scale the Y with the four tap filters, but UV's are generated
1771 with dual two tap configuration. */
1772 else if ((H_scale_ratio>=(ClocksNeededFor16Pixels=8+1+1) / 16.0) &&
1773 ((uint16_t)((1/(H_scale_ratio)) * (1<<0xc) + 0.5)<=0x3000) &&
1774 ((uint16_t)((1/(H_scale_ratio*4)) * (1<<0xc) + 0.5)<=0x2000) &&
1775 !DisallowFourTapVertFiltering)
1776 { /*0.625 */
1777 *P1GroupSize = 2;
1778 *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio)) * (1<<0xc) + 0.5);
1779 *val_OV0_P1_H_STEP_BY = 0;
1780 *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*4)) * (1<<0xc) + 0.5);
1781 *val_OV0_P23_H_STEP_BY = 1;
1782 *P1StepSize = 1;
1783 *P23StepSize = 1;
1784 }
1785 /* We scale the Y, U, and V with the two tap filters */
1786 else if ((H_scale_ratio>=(ClocksNeededFor16Pixels=4+1+1) / 16.0) &&
1787 ((uint16_t)((1/(H_scale_ratio)) * (1<<0xc) + 0.5)<=0x3000) &&
1788 ((uint16_t)((1/(H_scale_ratio*4)) * (1<<0xc) + 0.5)<=0x2000))
1789 { /*0.375 */
1790 *P1GroupSize = 4;
1791 *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio)) * (1<<0xc) + 0.5);
1792 *val_OV0_P1_H_STEP_BY = 1;
1793 *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*4)) * (1<<0xc) + 0.5);
1794 *val_OV0_P23_H_STEP_BY = 1;
1795 *P1StepSize = 1;
1796 *P23StepSize = 1;
1797 }
1798 /* We scale step the U and V by two to allow more bandwidth for fetching Y's,
1799 thus we won't drop Y's yet. */
1800 else if ((H_scale_ratio>=(ClocksNeededFor16Pixels=4+.5+.5) / 16.0) &&
1801 ((uint16_t)((1/(H_scale_ratio)) * (1<<0xc) + 0.5)<=0x3000) &&
1802 ((uint16_t)((1/(H_scale_ratio*4*2)) * (1<<0xc) + 0.5)<=0x2000))
1803 { /*>=0.3125 and >.333333~ */
1804 *P1GroupSize = 4;
1805 *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio)) * (1<<0xc) + 0.5);
1806 *val_OV0_P1_H_STEP_BY = 1;
1807 *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*4*2)) * (1<<0xc) + 0.5);
1808 *val_OV0_P23_H_STEP_BY = 2;
1809 *P1StepSize = 1;
1810 *P23StepSize = 2;
1811 }
1812 /* We step the Y, U, and V by two. */
1813 else if ((H_scale_ratio>=(ClocksNeededFor16Pixels=2+.5+.5) / 16.0) &&
1814 ((uint16_t)((1/(H_scale_ratio*2)) * (1<<0xc) + 0.5)<=0x3000) &&
1815 ((uint16_t)((1/(H_scale_ratio*4*2)) * (1<<0xc) + 0.5)<=0x2000))
1816 {
1817 *P1GroupSize = 4;
1818 *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio*2)) * (1<<0xc) + 0.5);
1819 *val_OV0_P1_H_STEP_BY = 2;
1820 *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*4*2)) * (1<<0xc) + 0.5);
1821 *val_OV0_P23_H_STEP_BY = 2;
1822 *P1StepSize = 2;
1823 *P23StepSize = 2;
1824 }
1825 /* We step the Y by two and the U and V by four. */
1826 else if ((H_scale_ratio>=(ClocksNeededFor16Pixels=2+.25+.25) / 16.0) &&
1827 ((uint16_t)((1/(H_scale_ratio)) * (1<<0xc) + 0.5)<=0x3000) &&
1828 ((uint16_t)((1/(H_scale_ratio*4*4)) * (1<<0xc) + 0.5)<=0x2000))
1829 {
1830 *P1GroupSize = 4;
1831 *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio*2)) * (1<<0xc) + 0.5);
1832 *val_OV0_P1_H_STEP_BY = 2;
1833 *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*4*4)) * (1<<0xc) + 0.5);
1834 *val_OV0_P23_H_STEP_BY = 3;
1835 *P1StepSize = 2;
1836 *P23StepSize = 4;
1837 }
1838 /* We step the Y, U, and V by four. */
1839 else if ((H_scale_ratio>=(ClocksNeededFor16Pixels=1+.25+.25) / 16.0) &&
1840 ((uint16_t)((1/(H_scale_ratio*4)) * (1<<0xc) + 0.5)<=0x3000) &&
1841 ((uint16_t)((1/(H_scale_ratio*4*4)) * (1<<0xc) + 0.5)<=0x2000))
1842 {
1843 *P1GroupSize = 4;
1844 *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio*4)) * (1<<0xc) + 0.5);
1845 *val_OV0_P1_H_STEP_BY = 3;
1846 *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*4*4)) * (1<<0xc) + 0.5);
1847 *val_OV0_P23_H_STEP_BY = 3;
1848 *P1StepSize = 4;
1849 *P23StepSize = 4;
1850 }
1851 /* We would like to step the Y by four and the U and V by eight, but we can't mix step by 3 and step by 4 for packed modes */
1852
1853 /* We step the Y, U, and V by eight. */
1854 else if ((H_scale_ratio>=(ClocksNeededFor16Pixels=.5+.125+.125) / 16.0) &&
1855 ((uint16_t)((1/(H_scale_ratio*8)) * (1<<0xc) + 0.5)<=0x3000) &&
1856 ((uint16_t)((1/(H_scale_ratio*4*8)) * (1<<0xc) + 0.5)<=0x2000))
1857 {
1858 *P1GroupSize = 4;
1859 *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio*8)) * (1<<0xc) + 0.5);
1860 *val_OV0_P1_H_STEP_BY = 4;
1861 *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*4*8)) * (1<<0xc) + 0.5);
1862 *val_OV0_P23_H_STEP_BY = 4;
1863 *P1StepSize = 8;
1864 *P23StepSize = 8;
1865 }
1866 /* We step the Y by eight and the U and V by sixteen. */
1867 else if ((H_scale_ratio>=(ClocksNeededFor16Pixels=.5+.0625+.0625) / 16.0) &&
1868 ((uint16_t)((1/(H_scale_ratio*8)) * (1<<0xc) + 0.5)<=0x3000) &&
1869 ((uint16_t)((1/(H_scale_ratio*4*16)) * (1<<0xc) + 0.5)<=0x2000))
1870 {
1871 *P1GroupSize = 4;
1872 *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio*8)) * (1<<0xc) + 0.5);
1873 *val_OV0_P1_H_STEP_BY = 4;
1874 *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*4*16)) * (1<<0xc) + 0.5);
1875 *val_OV0_P23_H_STEP_BY = 5;
1876 *P1StepSize = 8;
1877 *P23StepSize = 16;
1878 }
1879 /* We step the Y, U, and V by sixteen. */
1880 else if ((H_scale_ratio>=(ClocksNeededFor16Pixels=.25+.0625+.0625) / 16.0) &&
1881 ((uint16_t)((1/(H_scale_ratio*16)) * (1<<0xc) + 0.5)<=0x3000) &&
1882 ((uint16_t)((1/(H_scale_ratio*4*16)) * (1<<0xc) + 0.5)<=0x2000))
1883 {
1884 *P1GroupSize = 4;
1885 *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio*16)) * (1<<0xc) + 0.5);
1886 *val_OV0_P1_H_STEP_BY = 5;
1887 *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*4*16)) * (1<<0xc) + 0.5);
1888 *val_OV0_P23_H_STEP_BY = 5;
1889 *P1StepSize = 16;
1890 *P23StepSize = 16;
1891 }
1892 else
1893 {
1894 H_scale_ratio=(ClocksNeededFor16Pixels=.25+.0625+.0625) / 16;
1895 *P1GroupSize = 4;
1896 *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio*16)) * (1<<0xc) + 0.5);
1897 *val_OV0_P1_H_STEP_BY = 5;
1898 *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*4*16)) * (1<<0xc) + 0.5);
1899 *val_OV0_P23_H_STEP_BY = 5;
1900 *P1StepSize = 16;
1901 *P23StepSize = 16;
1902 }
1903 break;
1904 case 10:
1905 case 11:
1906 case 12:
1907 case 13:
1908 case 14: /* YUV12, VYUY422, YUYV422, YOverPkCRCB12, YWovenWithPkCRCB12 */
1909 /* We scale the Y, U, and V with the four tap filters */
1910 /* four tap on both (unless Y is too wide) */
1911 if ((H_scale_ratio>=(ClocksNeededFor16Pixels=8+4+4) / 16.0) &&
1912 !DisallowFourTapVertFiltering && !DisallowFourTapUVVertFiltering)
1913 { /*0.75 */
1914 *P1GroupSize = 2;
1915 *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio)) * (1<<0xc) + 0.5);
1916 *val_OV0_P1_H_STEP_BY = 0;
1917 *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*2)) * (1<<0xc) + 0.5);
1918 *val_OV0_P23_H_STEP_BY = 0;
1919 *P1StepSize = 1;
1920 *P23StepSize = 1;
1921 }
1922 /* two tap on Y (because it is too big for four tap), four tap on UV */
1923 else if ((H_scale_ratio>=(ClocksNeededFor16Pixels=4+4+4) / 16.0) &&
1924 DisallowFourTapVertFiltering && !DisallowFourTapUVVertFiltering)
1925 { /*0.75 */
1926 *P1GroupSize = 4;
1927 *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio)) * (1<<0xc) + 0.5);
1928 *val_OV0_P1_H_STEP_BY = 1;
1929 *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*2)) * (1<<0xc) + 0.5);
1930 *val_OV0_P23_H_STEP_BY = 0;
1931 *P1StepSize = 1;
1932 *P23StepSize = 1;
1933 }
1934 /* We scale the Y with the four tap filters, but UV's are generated
1935 with dual two tap configuration. */
1936 else if ((H_scale_ratio>=(ClocksNeededFor16Pixels=8+2+2) / 16.0) &&
1937 !DisallowFourTapVertFiltering)
1938 { /*0.625 */
1939 *P1GroupSize = 2;
1940 *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio)) * (1<<0xc) + 0.5);
1941 *val_OV0_P1_H_STEP_BY = 0;
1942 *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*2)) * (1<<0xc) + 0.5);
1943 *val_OV0_P23_H_STEP_BY = 1;
1944 *P1StepSize = 1;
1945 *P23StepSize = 1;
1946 }
1947 /* We scale the Y, U, and V with the two tap filters */
1948 else if (H_scale_ratio>=(ClocksNeededFor16Pixels=4+2+2) / 16.0)
1949 { /*0.375 */
1950 *P1GroupSize = 4;
1951 *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio)) * (1<<0xc) + 0.5);
1952 *val_OV0_P1_H_STEP_BY = 1;
1953 *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*2)) * (1<<0xc) + 0.5);
1954 *val_OV0_P23_H_STEP_BY = 1;
1955 *P1StepSize = 1;
1956 *P23StepSize = 1;
1957 }
1958 /* We scale step the U and V by two to allow more bandwidth for
1959 fetching Y's, thus we won't drop Y's yet. */
1960 else if (H_scale_ratio>=(ClocksNeededFor16Pixels=4+1+1) / 16.0)
1961 { /*0.312 */
1962 *P1GroupSize = 4;
1963 *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio)) * (1<<0xc) + 0.5);
1964 *val_OV0_P1_H_STEP_BY = 1;
1965 *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*2*2)) * (1<<0xc) + 0.5);
1966 *val_OV0_P23_H_STEP_BY = 2;
1967 *P1StepSize = 1;
1968 *P23StepSize = 2;
1969 }
1970 /* We step the Y, U, and V by two. */
1971 else if (H_scale_ratio>=(ClocksNeededFor16Pixels=2+1+1) / 16.0)
1972 {
1973 *P1GroupSize = 4;
1974 *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio*2)) * (1<<0xc) + 0.5);
1975 *val_OV0_P1_H_STEP_BY = 2;
1976 *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*2*2)) * (1<<0xc) + 0.5);
1977 *val_OV0_P23_H_STEP_BY = 2;
1978 *P1StepSize = 2;
1979 *P23StepSize = 2;
1980 }
1981 /* We step the Y by two and the U and V by four. */
1982 else if (H_scale_ratio>=(ClocksNeededFor16Pixels=2+.5+.5) / 16.0)
1983 {
1984 *P1GroupSize = 4;
1985 *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio*2)) * (1<<0xc) + 0.5);
1986 *val_OV0_P1_H_STEP_BY = 2;
1987 *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*2*4)) * (1<<0xc) + 0.5);
1988 *val_OV0_P23_H_STEP_BY = 3;
1989 *P1StepSize = 2;
1990 *P23StepSize = 4;
1991 }
1992 /* We step the Y, U, and V by four. */
1993 else if (H_scale_ratio>=(ClocksNeededFor16Pixels=1+.5+.5) / 16.0)
1994 {
1995 *P1GroupSize = 4;
1996 *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio*4)) * (1<<0xc) + 0.5);
1997 *val_OV0_P1_H_STEP_BY = 3;
1998 *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*2*4)) * (1<<0xc) + 0.5);
1999 *val_OV0_P23_H_STEP_BY = 3;
2000 *P1StepSize = 4;
2001 *P23StepSize = 4;
2002 }
2003 /* We step the Y by four and the U and V by eight. */
2004 else if ((H_scale_ratio>=(ClocksNeededFor16Pixels=1+.25+.25) / 16.0) &&
2005 (fieldvalue_OV0_SURFACE_FORMAT==10))
2006 {
2007 *P1GroupSize = 4;
2008 /* Can't mix step by 3 and step by 4 for packed modes */
2009 *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio*4)) * (1<<0xc) + 0.5);
2010 *val_OV0_P1_H_STEP_BY = 3;
2011 *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*2*8)) * (1<<0xc) + 0.5);
2012 *val_OV0_P23_H_STEP_BY = 4;
2013 *P1StepSize = 4;
2014 *P23StepSize = 8;
2015 }
2016 /* We step the Y, U, and V by eight. */
2017 else if (H_scale_ratio>=(ClocksNeededFor16Pixels=.5+.25+.25) / 16.0)
2018 {
2019 *P1GroupSize = 4;
2020 *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio*8)) * (1<<0xc) + 0.5);
2021 *val_OV0_P1_H_STEP_BY = 4;
2022 *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*2*8)) * (1<<0xc) + 0.5);
2023 *val_OV0_P23_H_STEP_BY = 4;
2024 *P1StepSize = 8;
2025 *P23StepSize = 8;
2026 }
2027 /* We step the Y by eight and the U and V by sixteen. */
2028 else if ((H_scale_ratio>=(ClocksNeededFor16Pixels=.5+.125+.125) / 16.0) && (fieldvalue_OV0_SURFACE_FORMAT==10))
2029 {
2030 *P1GroupSize = 4;
2031 /* Step by 5 not supported for packed modes */
2032 *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio*8)) * (1<<0xc) + 0.5);
2033 *val_OV0_P1_H_STEP_BY = 4;
2034 *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*2*16)) * (1<<0xc) + 0.5);
2035 *val_OV0_P23_H_STEP_BY = 5;
2036 *P1StepSize = 8;
2037 *P23StepSize = 16;
2038 }
2039 /* We step the Y, U, and V by sixteen. */
2040 else if ((H_scale_ratio>=(ClocksNeededFor16Pixels=.25+.125+.125) / 16.0) &&
2041 (fieldvalue_OV0_SURFACE_FORMAT==10))
2042 {
2043 *P1GroupSize = 4;
2044 /* Step by 5 not supported for packed modes */
2045 *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio*16)) * (1<<0xc) + 0.5);
2046 *val_OV0_P1_H_STEP_BY = 5;
2047 *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*2*16)) * (1<<0xc) + 0.5);
2048 *val_OV0_P23_H_STEP_BY = 5;
2049 *P1StepSize = 16;
2050 *P23StepSize = 16;
2051 }
2052 else
2053 {
2054 if (fieldvalue_OV0_SURFACE_FORMAT==10)
2055 {
2056 H_scale_ratio=(ClocksNeededFor16Pixels=.25+.125+.125) / 16;
2057 *P1GroupSize = 4;
2058 *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio*16)) * (1<<0xc) + 0.5);
2059 *val_OV0_P1_H_STEP_BY = 5;
2060 *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*2*16)) * (1<<0xc) + 0.5);
2061 *val_OV0_P23_H_STEP_BY = 5;
2062 *P1StepSize = 16;
2063 *P23StepSize = 16;
2064 }
2065 else
2066 {
2067 H_scale_ratio=(ClocksNeededFor16Pixels=.5+.25+.25) / 16;
2068 *P1GroupSize = 4;
2069 *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio*8)) * (1<<0xc) + 0.5);
2070 *val_OV0_P1_H_STEP_BY = 4;
2071 *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*2*8)) * (1<<0xc) + 0.5);
2072 *val_OV0_P23_H_STEP_BY = 4;
2073 *P1StepSize = 8;
2074 *P23StepSize = 8;
2075 }
2076 }
2077 break;
2078 default: break;
2079
2080 }
2081 besr.h_inc = (*(val_OV0_P1_H_INC)&0x3fff) | ((*(val_OV0_P23_H_INC)&0x3fff)<<16);
2082 besr.step_by = (*(val_OV0_P1_H_STEP_BY)&0x7) | ((*(val_OV0_P23_H_STEP_BY)&0x7)<<8);
2083 }
2084
2085 /* ********************************************************* */
2086 /* ** Setup Black Bordering */
2087 /* ********************************************************* */
2088
ComputeBorders(vidix_playback_t * config,int VertUVSubSample)2089 static void ComputeBorders( vidix_playback_t *config, int VertUVSubSample )
2090 {
2091 double tempBLANK_LINES_AT_TOP;
2092 unsigned TopLine,BottomLine,SourceLinesUsed,TopUVLine,BottomUVLine,SourceUVLinesUsed;
2093 uint32_t val_OV0_P1_ACTIVE_LINES_M1,val_OV0_P1_BLNK_LN_AT_TOP_M1;
2094 uint32_t val_OV0_P23_ACTIVE_LINES_M1,val_OV0_P23_BLNK_LN_AT_TOP_M1;
2095
2096 if (floor(config->src.y)<0) {
2097 tempBLANK_LINES_AT_TOP = -floor(config->src.y);
2098 TopLine = 0;
2099 }
2100 else {
2101 tempBLANK_LINES_AT_TOP = 0;
2102 TopLine = (int)floor(config->src.y);
2103 }
2104 /* Round rSrcBottom up and subtract one */
2105 if (ceil(config->src.y+config->src.h) > config->src.h)
2106 {
2107 BottomLine = config->src.h - 1;
2108 }
2109 else
2110 {
2111 BottomLine = (int)ceil(config->src.y+config->src.h) - 1;
2112 }
2113
2114 if (BottomLine >= TopLine)
2115 {
2116 SourceLinesUsed = BottomLine - TopLine + 1;
2117 }
2118 else
2119 {
2120 /*CYCACC_ASSERT(0, "SourceLinesUsed less than or equal to zero.") */
2121 SourceLinesUsed = 1;
2122 }
2123
2124 {
2125 int SourceHeightInPixels;
2126 SourceHeightInPixels = BottomLine - TopLine + 1;
2127 }
2128
2129 val_OV0_P1_ACTIVE_LINES_M1 = SourceLinesUsed - 1;
2130 val_OV0_P1_BLNK_LN_AT_TOP_M1 = ((int)tempBLANK_LINES_AT_TOP-1) & 0xfff;
2131
2132 TopUVLine = ((int)(config->src.y/VertUVSubSample) < 0) ? 0: (int)(config->src.y/VertUVSubSample); /* Round rSrcTop down */
2133 BottomUVLine = (ceil(((config->src.y+config->src.h)/VertUVSubSample)) > (config->src.h/VertUVSubSample))
2134 ? (config->src.h/VertUVSubSample)-1 : (u_int)ceil(((config->src.y+config->src.h)/VertUVSubSample))-1;
2135
2136 if (BottomUVLine >= TopUVLine)
2137 {
2138 SourceUVLinesUsed = BottomUVLine - TopUVLine + 1;
2139 }
2140 else
2141 {
2142 /*CYCACC_ASSERT(0, "SourceUVLinesUsed less than or equal to zero.") */
2143 SourceUVLinesUsed = 1;
2144 }
2145 val_OV0_P23_ACTIVE_LINES_M1 = SourceUVLinesUsed - 1;
2146 val_OV0_P23_BLNK_LN_AT_TOP_M1 = ((int)(tempBLANK_LINES_AT_TOP/VertUVSubSample)-1) & 0x7ff;
2147 besr.p1_blank_lines_at_top = (val_OV0_P1_BLNK_LN_AT_TOP_M1 & 0xfff) |
2148 ((val_OV0_P1_ACTIVE_LINES_M1 & 0xfff) << 16);
2149 besr.p23_blank_lines_at_top = (val_OV0_P23_BLNK_LN_AT_TOP_M1 & 0x7ff) |
2150 ((val_OV0_P23_ACTIVE_LINES_M1 & 0x7ff) << 16);
2151 }
2152
2153
ComputeXStartEnd(int is_400,uint32_t LeftPixel,uint32_t LeftUVPixel,uint32_t MemWordsInBytes,uint32_t BytesPerPixel,uint32_t SourceWidthInPixels,uint32_t P1StepSize,uint32_t BytesPerUVPixel,uint32_t SourceUVWidthInPixels,uint32_t P23StepSize,uint32_t * p1_x_start,uint32_t * p2_x_start)2154 static void ComputeXStartEnd(
2155 int is_400,
2156 uint32_t LeftPixel,uint32_t LeftUVPixel,
2157 uint32_t MemWordsInBytes,uint32_t BytesPerPixel,
2158 uint32_t SourceWidthInPixels, uint32_t P1StepSize,
2159 uint32_t BytesPerUVPixel,uint32_t SourceUVWidthInPixels,
2160 uint32_t P23StepSize, uint32_t *p1_x_start, uint32_t *p2_x_start )
2161 {
2162 uint32_t val_OV0_P1_X_START,val_OV0_P2_X_START,val_OV0_P3_X_START;
2163 uint32_t val_OV0_P1_X_END,val_OV0_P2_X_END,val_OV0_P3_X_END;
2164 /* ToDo_Active: At the moment we are not using iOV0_VID_BUF?_START_PIX, but instead // are using iOV0_P?_X_START and iOV0_P?_X_END. We should use "start pix" and // "width" to derive the start and end. */
2165
2166 val_OV0_P1_X_START = (int)LeftPixel % (MemWordsInBytes/BytesPerPixel);
2167 val_OV0_P1_X_END = (int)((val_OV0_P1_X_START + SourceWidthInPixels - 1) / P1StepSize) * P1StepSize;
2168
2169 val_OV0_P2_X_START = val_OV0_P2_X_END = 0;
2170 switch (besr.surf_id)
2171 {
2172 case 9:
2173 case 10:
2174 case 13:
2175 case 14: /* ToDo_Active: The driver must insure that the initial value is */
2176 /* a multiple of a power of two when decimating */
2177 val_OV0_P2_X_START = (int)LeftUVPixel %
2178 (MemWordsInBytes/BytesPerUVPixel);
2179 val_OV0_P2_X_END = (int)((val_OV0_P2_X_START +
2180 SourceUVWidthInPixels - 1) / P23StepSize) * P23StepSize;
2181 break;
2182 case 11:
2183 case 12: val_OV0_P2_X_START = (int)LeftUVPixel % (MemWordsInBytes/(BytesPerPixel*2));
2184 val_OV0_P2_X_END = (int)((val_OV0_P2_X_START + SourceUVWidthInPixels - 1) / P23StepSize) * P23StepSize;
2185 break;
2186 case 3:
2187 case 4: val_OV0_P2_X_START = val_OV0_P1_X_START;
2188 /* This value is needed only to allow proper setting of */
2189 /* val_OV0_PRESHIFT_P23_TO */
2190 /* val_OV0_P2_X_END = 0; */
2191 break;
2192 case 6: val_OV0_P2_X_START = (int)LeftPixel % (MemWordsInBytes/BytesPerPixel);
2193 val_OV0_P2_X_END = (int)((val_OV0_P1_X_START + SourceWidthInPixels - 1) / P23StepSize) * P23StepSize;
2194 break;
2195 default: /* insert debug statement here. */
2196 RADEON_ASSERT("unknown fourcc\n");
2197 break;
2198 }
2199 val_OV0_P3_X_START = val_OV0_P2_X_START;
2200 val_OV0_P3_X_END = val_OV0_P2_X_END;
2201
2202 besr.p1_x_start_end = (val_OV0_P1_X_END&0x7ff) | ((val_OV0_P1_X_START&0x7ff)<<16);
2203 besr.p2_x_start_end = (val_OV0_P2_X_END&0x7ff) | ((val_OV0_P2_X_START&0x7ff)<<16);
2204 besr.p3_x_start_end = (val_OV0_P3_X_END&0x7ff) | ((val_OV0_P3_X_START&0x7ff)<<16);
2205 if(is_400)
2206 {
2207 besr.p2_x_start_end = 0;
2208 besr.p3_x_start_end = 0;
2209 }
2210 *p1_x_start = val_OV0_P1_X_START;
2211 *p2_x_start = val_OV0_P2_X_START;
2212 }
2213
ComputeAccumInit(uint32_t val_OV0_P1_X_START,uint32_t val_OV0_P2_X_START,uint32_t val_OV0_P1_H_INC,uint32_t val_OV0_P23_H_INC,uint32_t val_OV0_P1_H_STEP_BY,uint32_t val_OV0_P23_H_STEP_BY,uint32_t CRT_V_INC,uint32_t P1GroupSize,uint32_t P23GroupSize,uint32_t val_OV0_P1_MAX_LN_IN_PER_LN_OUT,uint32_t val_OV0_P23_MAX_LN_IN_PER_LN_OUT)2214 static void ComputeAccumInit(
2215 uint32_t val_OV0_P1_X_START,uint32_t val_OV0_P2_X_START,
2216 uint32_t val_OV0_P1_H_INC,uint32_t val_OV0_P23_H_INC,
2217 uint32_t val_OV0_P1_H_STEP_BY,uint32_t val_OV0_P23_H_STEP_BY,
2218 uint32_t CRT_V_INC,
2219 uint32_t P1GroupSize, uint32_t P23GroupSize,
2220 uint32_t val_OV0_P1_MAX_LN_IN_PER_LN_OUT,
2221 uint32_t val_OV0_P23_MAX_LN_IN_PER_LN_OUT)
2222 {
2223 uint32_t val_OV0_P1_H_ACCUM_INIT,val_OV0_PRESHIFT_P1_TO;
2224 uint32_t val_OV0_P23_H_ACCUM_INIT,val_OV0_PRESHIFT_P23_TO;
2225 uint32_t val_OV0_P1_V_ACCUM_INIT,val_OV0_P23_V_ACCUM_INIT;
2226 /* 2.5 puts the kernal 50% of the way between the source pixel that is off screen */
2227 /* and the first on-screen source pixel. "(float)valOV0_P?_H_INC / (1<<0xc)" is */
2228 /* the distance (in source pixel coordinates) to the center of the first */
2229 /* destination pixel. Need to add additional pixels depending on how many pixels */
2230 /* are fetched at a time and how many pixels in a set are masked. */
2231 /* P23 values are always fetched in groups of two or four. If the start */
2232 /* pixel does not fall on the boundary, then we need to shift preshift for */
2233 /* some additional pixels */
2234
2235 {
2236 double ExtraHalfPixel;
2237 double tempAdditionalShift;
2238 double tempP1HStartPoint;
2239 double tempP23HStartPoint;
2240 double tempP1Init;
2241 double tempP23Init;
2242
2243 if (besr.horz_pick_nearest) ExtraHalfPixel = 0.5;
2244 else ExtraHalfPixel = 0.0;
2245 tempAdditionalShift = val_OV0_P1_X_START % P1GroupSize + ExtraHalfPixel;
2246 tempP1HStartPoint = tempAdditionalShift + 2.5 + ((float)val_OV0_P1_H_INC / (1<<0xd));
2247 tempP1Init = (double)((int)(tempP1HStartPoint * (1<<0x5) + 0.5)) / (1<<0x5);
2248
2249 /* P23 values are always fetched in pairs. If the start pixel is odd, then we */
2250 /* need to shift an additional pixel */
2251 /* Note that if the pitch is a multiple of two, and if we store fields using */
2252 /* the traditional planer format where the V plane and the U plane share the */
2253 /* same pitch, then OverlayRegFields->val_OV0_P2_X_START % P23Group */
2254 /* OverlayRegFields->val_OV0_P3_X_START % P23GroupSize. Either way */
2255 /* it is a requirement that the U and V start on the same polarity byte */
2256 /* (even or odd). */
2257 tempAdditionalShift = val_OV0_P2_X_START % P23GroupSize + ExtraHalfPixel;
2258 tempP23HStartPoint = tempAdditionalShift + 2.5 + ((float)val_OV0_P23_H_INC / (1<<0xd));
2259 tempP23Init = (double)((int)(tempP23HStartPoint * (1<<0x5) + 0.5)) / (1 << 0x5);
2260 val_OV0_P1_H_ACCUM_INIT = (int)((tempP1Init - (int)tempP1Init) * (1<<0x5));
2261 val_OV0_PRESHIFT_P1_TO = (int)tempP1Init;
2262 val_OV0_P23_H_ACCUM_INIT = (int)((tempP23Init - (int)tempP23Init) * (1<<0x5));
2263 val_OV0_PRESHIFT_P23_TO = (int)tempP23Init;
2264 }
2265
2266 /* ************************************************************** */
2267 /* ** Calculate values for initializing the vertical accumulators */
2268 /* ************************************************************** */
2269
2270 {
2271 double ExtraHalfLine;
2272 double ExtraFullLine;
2273 double tempP1VStartPoint;
2274 double tempP23VStartPoint;
2275
2276 if (besr.vert_pick_nearest) ExtraHalfLine = 0.5;
2277 else ExtraHalfLine = 0.0;
2278
2279 if (val_OV0_P1_H_STEP_BY==0)ExtraFullLine = 1.0;
2280 else ExtraFullLine = 0.0;
2281
2282 tempP1VStartPoint = 1.5 + ExtraFullLine + ExtraHalfLine + ((float)CRT_V_INC / (1<<0xd));
2283 if (tempP1VStartPoint>2.5 + 2*ExtraFullLine)
2284 {
2285 tempP1VStartPoint = 2.5 + 2*ExtraFullLine;
2286 }
2287 val_OV0_P1_V_ACCUM_INIT = (int)(tempP1VStartPoint * (1<<0x5) + 0.5);
2288
2289 if (val_OV0_P23_H_STEP_BY==0)ExtraFullLine = 1.0;
2290 else ExtraFullLine = 0.0;
2291
2292 switch (besr.surf_id)
2293 {
2294 case 10:
2295 case 13:
2296 case 14: tempP23VStartPoint = 1.5 + ExtraFullLine + ExtraHalfLine +
2297 ((float)CRT_V_INC / (1<<0xe));
2298 break;
2299 case 9: tempP23VStartPoint = 1.5 + ExtraFullLine + ExtraHalfLine +
2300 ((float)CRT_V_INC / (1<<0xf));
2301 break;
2302 case 3:
2303 case 4:
2304 case 6:
2305 case 11:
2306 case 12: tempP23VStartPoint = 0;
2307 break;
2308 default: tempP23VStartPoint = 0xFFFF;/* insert debug statement here */
2309 break;
2310 }
2311
2312 if (tempP23VStartPoint>2.5 + 2*ExtraFullLine)
2313 {
2314 tempP23VStartPoint = 2.5 + 2*ExtraFullLine;
2315 }
2316
2317 val_OV0_P23_V_ACCUM_INIT = (int)(tempP23VStartPoint * (1<<0x5) + 0.5);
2318 }
2319 besr.p1_h_accum_init = ((val_OV0_P1_H_ACCUM_INIT&0x1f)<<15) |((val_OV0_PRESHIFT_P1_TO&0xf)<<28);
2320 besr.p1_v_accum_init = (val_OV0_P1_MAX_LN_IN_PER_LN_OUT&0x3) |((val_OV0_P1_V_ACCUM_INIT&0x7ff)<<15);
2321 besr.p23_h_accum_init= ((val_OV0_P23_H_ACCUM_INIT&0x1f)<<15) |((val_OV0_PRESHIFT_P23_TO&0xf)<<28);
2322 besr.p23_v_accum_init= (val_OV0_P23_MAX_LN_IN_PER_LN_OUT&0x3)|((val_OV0_P23_V_ACCUM_INIT&0x3ff)<<15);
2323 }
2324
2325 typedef struct RangeAndCoefSet {
2326 double Range;
2327 signed char CoefSet[5][4];
2328 } RANGEANDCOEFSET;
2329
2330 /* Filter Setup Routine */
FilterSetup(uint32_t val_OV0_P1_H_INC)2331 static void FilterSetup ( uint32_t val_OV0_P1_H_INC )
2332 {
2333 static RANGEANDCOEFSET ArrayOfSets[] = {
2334 {0.25, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2335 {0.26, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2336 {0.27, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2337 {0.28, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2338 {0.29, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2339 {0.30, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2340 {0.31, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2341 {0.32, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2342 {0.33, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2343 {0.34, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2344 {0.35, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2345 {0.36, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2346 {0.37, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2347 {0.38, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2348 {0.39, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2349 {0.40, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2350 {0.41, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2351 {0.42, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2352 {0.43, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2353 {0.44, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2354 {0.45, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2355 {0.46, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2356 {0.47, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2357 {0.48, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2358 {0.49, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2359 {0.50, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2360 {0.51, {{ 7, 17, 8, 0}, { 6, 17, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 2, 14, 14, 2}, }},
2361 {0.52, {{ 7, 17, 8, 0}, { 6, 17, 9, 0}, { 5, 16, 11, 0}, { 3, 15, 13, 1}, { 2, 14, 14, 2}, }},
2362 {0.53, {{ 7, 17, 8, 0}, { 6, 17, 9, 0}, { 5, 16, 11, 0}, { 3, 15, 13, 1}, { 2, 14, 14, 2}, }},
2363 {0.54, {{ 7, 17, 8, 0}, { 6, 17, 9, 0}, { 4, 17, 11, 0}, { 3, 15, 13, 1}, { 2, 14, 14, 2}, }},
2364 {0.55, {{ 7, 18, 7, 0}, { 6, 17, 9, 0}, { 4, 17, 11, 0}, { 3, 15, 13, 1}, { 1, 15, 15, 1}, }},
2365 {0.56, {{ 7, 18, 7, 0}, { 5, 18, 9, 0}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }},
2366 {0.57, {{ 7, 18, 7, 0}, { 5, 18, 9, 0}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }},
2367 {0.58, {{ 7, 18, 7, 0}, { 5, 18, 9, 0}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }},
2368 {0.59, {{ 7, 18, 7, 0}, { 5, 18, 9, 0}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }},
2369 {0.60, {{ 7, 18, 8, -1}, { 6, 17, 10, -1}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }},
2370 {0.61, {{ 7, 18, 8, -1}, { 6, 17, 10, -1}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }},
2371 {0.62, {{ 7, 18, 8, -1}, { 6, 17, 10, -1}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }},
2372 {0.63, {{ 7, 18, 8, -1}, { 6, 17, 10, -1}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }},
2373 {0.64, {{ 7, 18, 8, -1}, { 6, 17, 10, -1}, { 4, 17, 12, -1}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }},
2374 {0.65, {{ 7, 18, 8, -1}, { 6, 17, 10, -1}, { 4, 17, 12, -1}, { 2, 17, 13, 0}, { 0, 16, 16, 0}, }},
2375 {0.66, {{ 7, 18, 8, -1}, { 6, 18, 10, -2}, { 4, 17, 12, -1}, { 2, 17, 13, 0}, { 0, 16, 16, 0}, }},
2376 {0.67, {{ 7, 20, 7, -2}, { 5, 19, 10, -2}, { 3, 18, 12, -1}, { 2, 17, 13, 0}, { 0, 16, 16, 0}, }},
2377 {0.68, {{ 7, 20, 7, -2}, { 5, 19, 10, -2}, { 3, 19, 12, -2}, { 1, 18, 14, -1}, { 0, 16, 16, 0}, }},
2378 {0.69, {{ 7, 20, 7, -2}, { 5, 19, 10, -2}, { 3, 19, 12, -2}, { 1, 18, 14, -1}, { 0, 16, 16, 0}, }},
2379 {0.70, {{ 7, 20, 7, -2}, { 5, 20, 9, -2}, { 3, 19, 12, -2}, { 1, 18, 14, -1}, { 0, 16, 16, 0}, }},
2380 {0.71, {{ 7, 20, 7, -2}, { 5, 20, 9, -2}, { 3, 19, 12, -2}, { 1, 18, 14, -1}, { 0, 16, 16, 0}, }},
2381 {0.72, {{ 7, 20, 7, -2}, { 5, 20, 9, -2}, { 2, 20, 12, -2}, { 0, 19, 15, -2}, {-1, 17, 17, -1}, }},
2382 {0.73, {{ 7, 20, 7, -2}, { 4, 21, 9, -2}, { 2, 20, 12, -2}, { 0, 19, 15, -2}, {-1, 17, 17, -1}, }},
2383 {0.74, {{ 6, 22, 6, -2}, { 4, 21, 9, -2}, { 2, 20, 12, -2}, { 0, 19, 15, -2}, {-1, 17, 17, -1}, }},
2384 {0.75, {{ 6, 22, 6, -2}, { 4, 21, 9, -2}, { 1, 21, 12, -2}, { 0, 19, 15, -2}, {-1, 17, 17, -1}, }},
2385 {0.76, {{ 6, 22, 6, -2}, { 4, 21, 9, -2}, { 1, 21, 12, -2}, { 0, 19, 15, -2}, {-1, 17, 17, -1}, }},
2386 {0.77, {{ 6, 22, 6, -2}, { 3, 22, 9, -2}, { 1, 22, 12, -3}, { 0, 19, 15, -2}, {-2, 18, 18, -2}, }},
2387 {0.78, {{ 6, 21, 6, -1}, { 3, 22, 9, -2}, { 1, 22, 12, -3}, { 0, 19, 15, -2}, {-2, 18, 18, -2}, }},
2388 {0.79, {{ 5, 23, 5, -1}, { 3, 22, 9, -2}, { 0, 23, 12, -3}, {-1, 21, 15, -3}, {-2, 18, 18, -2}, }},
2389 {0.80, {{ 5, 23, 5, -1}, { 3, 23, 8, -2}, { 0, 23, 12, -3}, {-1, 21, 15, -3}, {-2, 18, 18, -2}, }},
2390 {0.81, {{ 5, 23, 5, -1}, { 2, 24, 8, -2}, { 0, 23, 12, -3}, {-1, 21, 15, -3}, {-2, 18, 18, -2}, }},
2391 {0.82, {{ 5, 23, 5, -1}, { 2, 24, 8, -2}, { 0, 23, 12, -3}, {-1, 21, 15, -3}, {-3, 19, 19, -3}, }},
2392 {0.83, {{ 5, 23, 5, -1}, { 2, 24, 8, -2}, { 0, 23, 11, -2}, {-2, 22, 15, -3}, {-3, 19, 19, -3}, }},
2393 {0.84, {{ 4, 25, 4, -1}, { 1, 25, 8, -2}, { 0, 23, 11, -2}, {-2, 22, 15, -3}, {-3, 19, 19, -3}, }},
2394 {0.85, {{ 4, 25, 4, -1}, { 1, 25, 8, -2}, { 0, 23, 11, -2}, {-2, 22, 15, -3}, {-3, 19, 19, -3}, }},
2395 {0.86, {{ 4, 24, 4, 0}, { 1, 25, 7, -1}, {-1, 24, 11, -2}, {-2, 22, 15, -3}, {-3, 19, 19, -3}, }},
2396 {0.87, {{ 4, 24, 4, 0}, { 1, 25, 7, -1}, {-1, 24, 11, -2}, {-2, 22, 15, -3}, {-3, 19, 19, -3}, }},
2397 {0.88, {{ 3, 26, 3, 0}, { 0, 26, 7, -1}, {-1, 24, 11, -2}, {-3, 23, 15, -3}, {-3, 19, 19, -3}, }},
2398 {0.89, {{ 3, 26, 3, 0}, { 0, 26, 7, -1}, {-1, 24, 11, -2}, {-3, 23, 15, -3}, {-3, 19, 19, -3}, }},
2399 {0.90, {{ 3, 26, 3, 0}, { 0, 26, 7, -1}, {-2, 25, 11, -2}, {-3, 23, 15, -3}, {-3, 19, 19, -3}, }},
2400 {0.91, {{ 3, 26, 3, 0}, { 0, 27, 6, -1}, {-2, 25, 11, -2}, {-3, 23, 15, -3}, {-3, 19, 19, -3}, }},
2401 {0.92, {{ 2, 28, 2, 0}, { 0, 27, 6, -1}, {-2, 25, 11, -2}, {-3, 23, 15, -3}, {-3, 19, 19, -3}, }},
2402 {0.93, {{ 2, 28, 2, 0}, { 0, 26, 6, 0}, {-2, 25, 10, -1}, {-3, 23, 15, -3}, {-3, 19, 19, -3}, }},
2403 {0.94, {{ 2, 28, 2, 0}, { 0, 26, 6, 0}, {-2, 25, 10, -1}, {-3, 23, 15, -3}, {-3, 19, 19, -3}, }},
2404 {0.95, {{ 1, 30, 1, 0}, {-1, 28, 5, 0}, {-3, 26, 10, -1}, {-3, 23, 14, -2}, {-3, 19, 19, -3}, }},
2405 {0.96, {{ 1, 30, 1, 0}, {-1, 28, 5, 0}, {-3, 26, 10, -1}, {-3, 23, 14, -2}, {-3, 19, 19, -3}, }},
2406 {0.97, {{ 1, 30, 1, 0}, {-1, 28, 5, 0}, {-3, 26, 10, -1}, {-3, 23, 14, -2}, {-3, 19, 19, -3}, }},
2407 {0.98, {{ 1, 30, 1, 0}, {-2, 29, 5, 0}, {-3, 27, 9, -1}, {-3, 23, 14, -2}, {-3, 19, 19, -3}, }},
2408 {0.99, {{ 0, 32, 0, 0}, {-2, 29, 5, 0}, {-3, 27, 9, -1}, {-4, 24, 14, -2}, {-3, 19, 19, -3}, }},
2409 {1.00, {{ 0, 32, 0, 0}, {-2, 29, 5, 0}, {-3, 27, 9, -1}, {-4, 24, 14, -2}, {-3, 19, 19, -3}, }}
2410 };
2411
2412 double DSR;
2413
2414 unsigned ArrayElement;
2415
2416 DSR = (double)(1<<0xc)/val_OV0_P1_H_INC;
2417 if (DSR<.25) DSR=.25;
2418 if (DSR>1) DSR=1;
2419
2420 ArrayElement = (int)((DSR-0.25) * 100);
2421 besr.four_tap_coeff[0] = (ArrayOfSets[ArrayElement].CoefSet[0][0] & 0xf) |
2422 ((ArrayOfSets[ArrayElement].CoefSet[0][1] & 0x7f)<<8) |
2423 ((ArrayOfSets[ArrayElement].CoefSet[0][2] & 0x7f)<<16) |
2424 ((ArrayOfSets[ArrayElement].CoefSet[0][3] & 0xf)<<24);
2425 besr.four_tap_coeff[1] = (ArrayOfSets[ArrayElement].CoefSet[1][0] & 0xf) |
2426 ((ArrayOfSets[ArrayElement].CoefSet[1][1] & 0x7f)<<8) |
2427 ((ArrayOfSets[ArrayElement].CoefSet[1][2] & 0x7f)<<16) |
2428 ((ArrayOfSets[ArrayElement].CoefSet[1][3] & 0xf)<<24);
2429 besr.four_tap_coeff[2] = (ArrayOfSets[ArrayElement].CoefSet[2][0] & 0xf) |
2430 ((ArrayOfSets[ArrayElement].CoefSet[2][1] & 0x7f)<<8) |
2431 ((ArrayOfSets[ArrayElement].CoefSet[2][2] & 0x7f)<<16) |
2432 ((ArrayOfSets[ArrayElement].CoefSet[2][3] & 0xf)<<24);
2433 besr.four_tap_coeff[3] = (ArrayOfSets[ArrayElement].CoefSet[3][0] & 0xf) |
2434 ((ArrayOfSets[ArrayElement].CoefSet[3][1] & 0x7f)<<8) |
2435 ((ArrayOfSets[ArrayElement].CoefSet[3][2] & 0x7f)<<16) |
2436 ((ArrayOfSets[ArrayElement].CoefSet[3][3] & 0xf)<<24);
2437 besr.four_tap_coeff[4] = (ArrayOfSets[ArrayElement].CoefSet[4][0] & 0xf) |
2438 ((ArrayOfSets[ArrayElement].CoefSet[4][1] & 0x7f)<<8) |
2439 ((ArrayOfSets[ArrayElement].CoefSet[4][2] & 0x7f)<<16) |
2440 ((ArrayOfSets[ArrayElement].CoefSet[4][3] & 0xf)<<24);
2441 /*
2442 For more details, refer to Microsoft's draft of PC99.
2443 */
2444 }
2445
2446 /* The minimal value of horizontal scale ratio when hard coded coefficients
2447 are suitable for the best quality. */
2448 /* FIXME: Should it be 0.9 for Rage128 ??? */
2449 const double MinHScaleHard=0.75;
2450
radeon_vid_init_video(vidix_playback_t * config)2451 static int radeon_vid_init_video( vidix_playback_t *config )
2452 {
2453 double V_scale_ratio;
2454 uint32_t i,src_w,src_h,dest_w,dest_h,pitch,left,leftUV,top,h_inc;
2455 uint32_t val_OV0_P1_H_INC=0,val_OV0_P1_H_STEP_BY=0,val_OV0_P23_H_INC=0,val_OV0_P23_H_STEP_BY=0;
2456 uint32_t val_OV0_P1_X_START,val_OV0_P2_X_START;
2457 uint32_t val_OV0_P1_MAX_LN_IN_PER_LN_OUT,val_OV0_P23_MAX_LN_IN_PER_LN_OUT;
2458 uint32_t CRT_V_INC;
2459 uint32_t BytesPerOctWord,LogMemWordsInBytes,MemWordsInBytes,LogTileWidthInMemWords;
2460 uint32_t TileWidthInMemWords,TileWidthInBytes,LogTileHeight,TileHeight;
2461 uint32_t PageSizeInBytes,OV0LB_Rows;
2462 uint32_t SourceWidthInMemWords,SourceUVWidthInMemWords;
2463 uint32_t SourceWidthInPixels,SourceUVWidthInPixels;
2464 uint32_t RightPixel,RightUVPixel,LeftPixel,LeftUVPixel;
2465 int is_400,is_410,is_420,best_pitch,mpitch;
2466 int horz_repl_factor,interlace_factor;
2467 int BytesPerPixel,BytesPerUVPixel,HorzUVSubSample,VertUVSubSample;
2468 int DisallowFourTapVertFiltering,DisallowFourTapUVVertFiltering;
2469
2470 radeon_vid_stop_video();
2471 left = config->src.x << 16;
2472 top = config->src.y << 16;
2473 src_h = config->src.h;
2474 src_w = config->src.w;
2475 is_400 = is_410 = is_420 = 0;
2476 if(config->fourcc == IMGFMT_YV12 ||
2477 config->fourcc == IMGFMT_I420 ||
2478 config->fourcc == IMGFMT_IYUV) is_420 = 1;
2479 if(config->fourcc == IMGFMT_YVU9 ||
2480 config->fourcc == IMGFMT_IF09) is_410 = 1;
2481 if(config->fourcc == IMGFMT_Y800) is_400 = 1;
2482 best_pitch = radeon_query_pitch(config->fourcc,&config->src.pitch);
2483 mpitch = best_pitch-1;
2484 BytesPerOctWord = 16;
2485 LogMemWordsInBytes = 4;
2486 MemWordsInBytes = 1<<LogMemWordsInBytes;
2487 LogTileWidthInMemWords = 2;
2488 TileWidthInMemWords = 1<<LogTileWidthInMemWords;
2489 TileWidthInBytes = 1<<(LogTileWidthInMemWords+LogMemWordsInBytes);
2490 LogTileHeight = 4;
2491 TileHeight = 1<<LogTileHeight;
2492 PageSizeInBytes = 64*MemWordsInBytes;
2493 OV0LB_Rows = 96;
2494 h_inc = 1;
2495 switch(config->fourcc)
2496 {
2497 /* 4:0:0*/
2498 case IMGFMT_Y800:
2499 /* 4:1:0*/
2500 case IMGFMT_YVU9:
2501 case IMGFMT_IF09:
2502 /* 4:2:0 */
2503 case IMGFMT_IYUV:
2504 case IMGFMT_YV12:
2505 case IMGFMT_I420: pitch = (src_w + mpitch) & ~mpitch;
2506 config->dest.pitch.y =
2507 config->dest.pitch.u =
2508 config->dest.pitch.v = best_pitch;
2509 break;
2510 /* RGB 4:4:4:4 */
2511 case IMGFMT_RGB32:
2512 case IMGFMT_BGR32: pitch = (src_w*4 + mpitch) & ~mpitch;
2513 config->dest.pitch.y =
2514 config->dest.pitch.u =
2515 config->dest.pitch.v = best_pitch;
2516 break;
2517 /* 4:2:2 */
2518
2519 default: /* RGB15, RGB16, YVYU, UYVY, YUY2 */
2520 pitch = ((src_w*2) + mpitch) & ~mpitch;
2521 config->dest.pitch.y =
2522 config->dest.pitch.u =
2523 config->dest.pitch.v = best_pitch;
2524 break;
2525 }
2526 besr.load_prg_start=0;
2527 besr.swap_uv=0;
2528 switch(config->fourcc)
2529 {
2530 case IMGFMT_RGB15:
2531 besr.swap_uv=1;
2532 case IMGFMT_BGR15: besr.surf_id = SCALER_SOURCE_15BPP>>8;
2533 besr.load_prg_start = 1;
2534 break;
2535 case IMGFMT_RGB16:
2536 besr.swap_uv=1;
2537 case IMGFMT_BGR16: besr.surf_id = SCALER_SOURCE_16BPP>>8;
2538 besr.load_prg_start = 1;
2539 break;
2540 case IMGFMT_RGB32:
2541 besr.swap_uv=1;
2542 case IMGFMT_BGR32: besr.surf_id = SCALER_SOURCE_32BPP>>8;
2543 besr.load_prg_start = 1;
2544 break;
2545 /* 4:1:0*/
2546 case IMGFMT_IF09:
2547 case IMGFMT_YVU9: besr.surf_id = SCALER_SOURCE_YUV9>>8;
2548 break;
2549 /* 4:0:0*/
2550 case IMGFMT_Y800:
2551 /* 4:2:0 */
2552 case IMGFMT_IYUV:
2553 case IMGFMT_I420:
2554 case IMGFMT_YV12: besr.surf_id = SCALER_SOURCE_YUV12>>8;
2555 break;
2556 /* 4:2:2 */
2557 case IMGFMT_YVYU:
2558 case IMGFMT_UYVY: besr.surf_id = SCALER_SOURCE_YVYU422>>8;
2559 break;
2560 case IMGFMT_YUY2:
2561 default: besr.surf_id = SCALER_SOURCE_VYUY422>>8;
2562 break;
2563 }
2564 switch (besr.surf_id)
2565 {
2566 case 3:
2567 case 4:
2568 case 11:
2569 case 12: BytesPerPixel = 2;
2570 break;
2571 case 6: BytesPerPixel = 4;
2572 break;
2573 case 9:
2574 case 10:
2575 case 13:
2576 case 14: BytesPerPixel = 1;
2577 break;
2578 default: BytesPerPixel = 0;/*insert a debug statement here. */
2579 break;
2580 }
2581 switch (besr.surf_id)
2582 {
2583 case 3:
2584 case 4: BytesPerUVPixel = 0;
2585 break;/* In RGB modes, the BytesPerUVPixel is don't care */
2586 case 11:
2587 case 12: BytesPerUVPixel = 2;
2588 break;
2589 case 6: BytesPerUVPixel = 0;
2590 break; /* In RGB modes, the BytesPerUVPixel is don't care */
2591 case 9:
2592 case 10: BytesPerUVPixel = 1;
2593 break;
2594 case 13:
2595 case 14: BytesPerUVPixel = 2;
2596 break;
2597 default: BytesPerUVPixel = 0;/* insert a debug statement here. */
2598 break;
2599
2600 }
2601 switch (besr.surf_id)
2602 {
2603 case 3:
2604 case 4:
2605 case 6: HorzUVSubSample = 1;
2606 break;
2607 case 9: HorzUVSubSample = 4;
2608 break;
2609 case 10:
2610 case 11:
2611 case 12:
2612 case 13:
2613 case 14: HorzUVSubSample = 2;
2614 break;
2615 default: HorzUVSubSample = 0;/* insert debug statement here. */
2616 break;
2617 }
2618 switch (besr.surf_id)
2619 {
2620 case 3:
2621 case 4:
2622 case 6:
2623 case 11:
2624 case 12: VertUVSubSample = 1;
2625 break;
2626 case 9: VertUVSubSample = 4;
2627 break;
2628 case 10:
2629 case 13:
2630 case 14: VertUVSubSample = 2;
2631 break;
2632 default: VertUVSubSample = 0;/* insert debug statment here. */
2633 break;
2634 }
2635 DisallowFourTapVertFiltering = 0; /* Allow it by default */
2636 DisallowFourTapUVVertFiltering = 0; /* Allow it by default */
2637 LeftPixel = config->src.x;
2638 RightPixel = config->src.w-1;
2639 if(floor(config->src.x/HorzUVSubSample)<0) LeftUVPixel = 0;
2640 else LeftUVPixel = (int)floor(config->src.x/HorzUVSubSample);
2641 if(ceil((config->src.x+config->src.w)/HorzUVSubSample) > config->src.w/HorzUVSubSample)
2642 RightUVPixel = config->src.w/HorzUVSubSample - 1;
2643 else RightUVPixel = (int)ceil((config->src.x+config->src.w)/HorzUVSubSample) - 1;
2644 /* Top, Bottom and Right Crops can be out of range. The driver will program the hardware
2645 // to create a black border at the top and bottom. This is useful for DVD letterboxing. */
2646 SourceWidthInPixels = (int)(config->src.w + 1);
2647 SourceUVWidthInPixels = (int)(RightUVPixel - LeftUVPixel + 1);
2648
2649 SourceWidthInMemWords = (int)(ceil(RightPixel*BytesPerPixel / MemWordsInBytes) -
2650 floor(LeftPixel*BytesPerPixel / MemWordsInBytes) + 1);
2651 /* SourceUVWidthInMemWords means Source_U_or_V_or_UV_WidthInMemWords depending on whether the UV is packed together of not. */
2652 SourceUVWidthInMemWords = (int)(ceil(RightUVPixel*BytesPerUVPixel /
2653 MemWordsInBytes) - floor(LeftUVPixel*BytesPerUVPixel /
2654 MemWordsInBytes) + 1);
2655
2656 switch (besr.surf_id)
2657 {
2658 case 9:
2659 case 10: if ((ceil(SourceWidthInMemWords/2)-1) * 2 > OV0LB_Rows-1)
2660 {
2661 RADEON_ASSERT("ceil(SourceWidthInMemWords/2)-1) * 2 > OV0LB_Rows-1\n");
2662 }
2663 else if ((SourceWidthInMemWords-1) * 2 > OV0LB_Rows-1)
2664 {
2665 DisallowFourTapVertFiltering = 1;
2666 }
2667
2668 if ((ceil(SourceUVWidthInMemWords/2)-1) * 4 + 1 > OV0LB_Rows-1)
2669 {
2670 /*CYCACC_ASSERT(0, "Image U plane width spans more octwords than supported by hardware.") */
2671 }
2672 else if ((SourceUVWidthInMemWords-1) * 4 + 1 > OV0LB_Rows-1)
2673 {
2674 DisallowFourTapUVVertFiltering = 1;
2675 }
2676
2677 if ((ceil(SourceUVWidthInMemWords/2)-1) * 4 + 3 > OV0LB_Rows-1)
2678 {
2679 /*CYCACC_ASSERT(0, "Image V plane width spans more octwords than supported by hardware.") */
2680 }
2681 else if ((SourceUVWidthInMemWords-1) * 4 + 3 > OV0LB_Rows-1)
2682 {
2683 DisallowFourTapUVVertFiltering = 1;
2684 }
2685 break;
2686 case 13:
2687 case 14: if ((ceil(SourceWidthInMemWords/2)-1) * 2 > OV0LB_Rows-1)
2688 {
2689 RADEON_ASSERT("ceil(SourceWidthInMemWords/2)-1) * 2 > OV0LB_Rows-1\n");
2690 }
2691 else if ((SourceWidthInMemWords-1) * 2 > OV0LB_Rows-1)
2692 {
2693 DisallowFourTapVertFiltering = 1;
2694 }
2695
2696 if ((ceil(SourceUVWidthInMemWords/2)-1) * 2 + 1 > OV0LB_Rows-1)
2697 {
2698 /*CYCACC_ASSERT(0, "Image UV plane width spans more octwords than supported by hardware.") */
2699 }
2700 else if ((SourceUVWidthInMemWords-1) * 2 + 1 > OV0LB_Rows-1)
2701 {
2702 DisallowFourTapUVVertFiltering = 1;
2703 }
2704 break;
2705 case 3:
2706 case 4:
2707 case 6:
2708 case 11:
2709 case 12: if ((ceil(SourceWidthInMemWords/2)-1) > OV0LB_Rows-1)
2710 {
2711 RADEON_ASSERT("(ceil(SourceWidthInMemWords/2)-1) > OV0LB_Rows-1\n")
2712 }
2713 else if ((SourceWidthInMemWords-1) > OV0LB_Rows-1)
2714 {
2715 DisallowFourTapVertFiltering = 1;
2716 }
2717 break;
2718 default: /* insert debug statement here. */
2719 break;
2720 }
2721 dest_w = config->dest.w;
2722 dest_h = config->dest.h;
2723 if(radeon_is_dbl_scan()) dest_h *= 2;
2724 besr.dest_bpp = radeon_vid_get_dbpp();
2725 besr.fourcc = config->fourcc;
2726 if(radeon_is_interlace()) interlace_factor = 2;
2727 else interlace_factor = 1;
2728 /* TODO: must be checked in doublescan mode!!! */
2729 if((besr.chip_flags&R_INTEGRATED)==R_INTEGRATED)
2730 {
2731 /* Force the overlay clock on for integrated chips */
2732 OUTPLL(VCLK_ECP_CNTL, (INPLL(VCLK_ECP_CNTL) | (1<<18)));
2733 }
2734 horz_repl_factor = 1 << (uint32_t)((INPLL(VCLK_ECP_CNTL) & 0x300) >> 8);
2735 H_scale_ratio = (double)ceil(((double)dest_w+1)/horz_repl_factor)/src_w;
2736 V_scale_ratio = (double)(dest_h+1)/src_h;
2737 if(H_scale_ratio < 0.5 && V_scale_ratio < 0.5)
2738 {
2739 val_OV0_P1_MAX_LN_IN_PER_LN_OUT = 3;
2740 val_OV0_P23_MAX_LN_IN_PER_LN_OUT = 2;
2741 }
2742 else
2743 if(H_scale_ratio < 1 && V_scale_ratio < 1)
2744 {
2745 val_OV0_P1_MAX_LN_IN_PER_LN_OUT = 2;
2746 val_OV0_P23_MAX_LN_IN_PER_LN_OUT = 1;
2747 }
2748 else
2749 {
2750 val_OV0_P1_MAX_LN_IN_PER_LN_OUT = 1;
2751 val_OV0_P23_MAX_LN_IN_PER_LN_OUT = 1;
2752 }
2753 /* N.B.: Indeed it has 6.12 format but shifted on 8 to the left!!! */
2754 besr.v_inc = (uint16_t)((1./V_scale_ratio)*(1<<12)*interlace_factor+0.5);
2755 CRT_V_INC = besr.v_inc/interlace_factor;
2756 besr.v_inc <<= 8;
2757 {
2758 int ThereIsTwoTapVerticalFiltering,DoNotUseMostRecentlyFetchedLine;
2759 int P1GroupSize = 0;
2760 int P23GroupSize;
2761 int P1StepSize = 0;
2762 int P23StepSize = 0;
2763
2764 Calc_H_INC_STEP_BY(
2765 besr.surf_id,
2766 H_scale_ratio,
2767 DisallowFourTapVertFiltering,
2768 DisallowFourTapUVVertFiltering,
2769 &val_OV0_P1_H_INC,
2770 &val_OV0_P1_H_STEP_BY,
2771 &val_OV0_P23_H_INC,
2772 &val_OV0_P23_H_STEP_BY,
2773 &P1GroupSize,
2774 &P1StepSize,
2775 &P23StepSize);
2776
2777 if(H_scale_ratio > MinHScaleHard)
2778 {
2779 h_inc = (src_w << 12) / dest_w;
2780 besr.step_by = 0x0101;
2781 switch (besr.surf_id)
2782 {
2783 case 3:
2784 case 4:
2785 case 6:
2786 besr.h_inc = (h_inc)|(h_inc<<16);
2787 break;
2788 case 9:
2789 besr.h_inc = h_inc | ((h_inc >> 2) << 16);
2790 break;
2791 default:
2792 besr.h_inc = h_inc | ((h_inc >> 1) << 16);
2793 break;
2794 }
2795 }
2796
2797 P23GroupSize = 2; /* Current vaue for all modes */
2798
2799 besr.horz_pick_nearest=0;
2800 DoNotUseMostRecentlyFetchedLine=0;
2801 ThereIsTwoTapVerticalFiltering = (val_OV0_P1_H_STEP_BY!=0) || (val_OV0_P23_H_STEP_BY!=0);
2802 if (ThereIsTwoTapVerticalFiltering && DoNotUseMostRecentlyFetchedLine)
2803 besr.vert_pick_nearest = 1;
2804 else
2805 besr.vert_pick_nearest = 0;
2806
2807 ComputeXStartEnd(is_400,LeftPixel,LeftUVPixel,MemWordsInBytes,BytesPerPixel,
2808 SourceWidthInPixels,P1StepSize,BytesPerUVPixel,
2809 SourceUVWidthInPixels,P23StepSize,&val_OV0_P1_X_START,&val_OV0_P2_X_START);
2810
2811 if(H_scale_ratio > MinHScaleHard)
2812 {
2813 unsigned tmp;
2814 tmp = (left & 0x0003ffff) + 0x00028000 + (h_inc << 3);
2815 besr.p1_h_accum_init = ((tmp << 4) & 0x000f8000) |
2816 ((tmp << 12) & 0xf0000000);
2817
2818 tmp = (top & 0x0000ffff) + 0x00018000;
2819 besr.p1_v_accum_init = ((tmp << 4) & OV0_P1_V_ACCUM_INIT_MASK)
2820 |(OV0_P1_MAX_LN_IN_PER_LN_OUT & 1);
2821 tmp = ((left >> 1) & 0x0001ffff) + 0x00028000 + (h_inc << 2);
2822 besr.p23_h_accum_init = ((tmp << 4) & 0x000f8000) |
2823 ((tmp << 12) & 0x70000000);
2824
2825 tmp = ((top >> 1) & 0x0000ffff) + 0x00018000;
2826 besr.p23_v_accum_init = (is_420||is_410) ?
2827 ((tmp << 4) & OV0_P23_V_ACCUM_INIT_MASK)
2828 |(OV0_P23_MAX_LN_IN_PER_LN_OUT & 1) : 0;
2829 }
2830 else
2831 ComputeAccumInit( val_OV0_P1_X_START,val_OV0_P2_X_START,
2832 val_OV0_P1_H_INC,val_OV0_P23_H_INC,
2833 val_OV0_P1_H_STEP_BY,val_OV0_P23_H_STEP_BY,
2834 CRT_V_INC,P1GroupSize,P23GroupSize,
2835 val_OV0_P1_MAX_LN_IN_PER_LN_OUT,
2836 val_OV0_P23_MAX_LN_IN_PER_LN_OUT);
2837 }
2838
2839 /* keep everything in 16.16 */
2840 besr.base_addr = INREG(DISPLAY_BASE_ADDR);
2841 config->offsets[0] = 0;
2842 for(i=1;i<besr.vid_nbufs;i++)
2843 config->offsets[i] = config->offsets[i-1]+config->frame_size;
2844 if(is_420 || is_410 || is_400)
2845 {
2846 uint32_t d1line,d2line,d3line;
2847 d1line = top*pitch;
2848 if(is_420)
2849 {
2850 d2line = src_h*pitch+(d1line>>2);
2851 d3line = d2line+((src_h*pitch)>>2);
2852 }
2853 else
2854 if(is_410)
2855 {
2856 d2line = src_h*pitch+(d1line>>4);
2857 d3line = d2line+((src_h*pitch)>>4);
2858 }
2859 else
2860 {
2861 d2line = 0;
2862 d3line = 0;
2863 }
2864 d1line += (left >> 16) & ~15;
2865 if(is_420)
2866 {
2867 d2line += (left >> 17) & ~15;
2868 d3line += (left >> 17) & ~15;
2869 }
2870 else /* is_410 */
2871 {
2872 d2line += (left >> 18) & ~15;
2873 d3line += (left >> 18) & ~15;
2874 }
2875 config->offset.y = d1line & VIF_BUF0_BASE_ADRS_MASK;
2876 if(is_400)
2877 {
2878 config->offset.v = 0;
2879 config->offset.u = 0;
2880 }
2881 else
2882 {
2883 config->offset.v = d2line & VIF_BUF1_BASE_ADRS_MASK;
2884 config->offset.u = d3line & VIF_BUF2_BASE_ADRS_MASK;
2885 }
2886 for(i=0;i<besr.vid_nbufs;i++)
2887 {
2888 besr.vid_buf_base_adrs_y[i]=((radeon_overlay_off+config->offsets[i]+config->offset.y)&VIF_BUF0_BASE_ADRS_MASK);
2889 if(is_400)
2890 {
2891 besr.vid_buf_base_adrs_v[i]=0;
2892 besr.vid_buf_base_adrs_u[i]=0;
2893 }
2894 else
2895 {
2896 besr.vid_buf_base_adrs_v[i]=((radeon_overlay_off+config->offsets[i]+config->offset.v)&VIF_BUF1_BASE_ADRS_MASK)|VIF_BUF1_PITCH_SEL;
2897 besr.vid_buf_base_adrs_u[i]=((radeon_overlay_off+config->offsets[i]+config->offset.u)&VIF_BUF2_BASE_ADRS_MASK)|VIF_BUF2_PITCH_SEL;
2898 }
2899 }
2900 config->offset.y = ((besr.vid_buf_base_adrs_y[0])&VIF_BUF0_BASE_ADRS_MASK) - radeon_overlay_off;
2901 if(is_400)
2902 {
2903 config->offset.v = 0;
2904 config->offset.u = 0;
2905 }
2906 else
2907 {
2908 config->offset.v = ((besr.vid_buf_base_adrs_v[0])&VIF_BUF1_BASE_ADRS_MASK) - radeon_overlay_off;
2909 config->offset.u = ((besr.vid_buf_base_adrs_u[0])&VIF_BUF2_BASE_ADRS_MASK) - radeon_overlay_off;
2910 }
2911 if(besr.fourcc == IMGFMT_I420 || besr.fourcc == IMGFMT_IYUV)
2912 {
2913 uint32_t tmp;
2914 tmp = config->offset.u;
2915 config->offset.u = config->offset.v;
2916 config->offset.v = tmp;
2917 }
2918 }
2919 else
2920 {
2921 config->offset.y = config->offset.u = config->offset.v = ((left & ~7) << 1)&VIF_BUF0_BASE_ADRS_MASK;
2922 for(i=0;i<besr.vid_nbufs;i++)
2923 {
2924 besr.vid_buf_base_adrs_y[i] =
2925 besr.vid_buf_base_adrs_u[i] =
2926 besr.vid_buf_base_adrs_v[i] = radeon_overlay_off + config->offsets[i] + config->offset.y;
2927 }
2928 }
2929 leftUV = (left >> (is_410?18:17)) & 15;
2930 left = (left >> 16) & 15;
2931 besr.y_x_start = (config->dest.x+X_ADJUST) | (config->dest.y << 16);
2932 besr.y_x_end = (config->dest.x + dest_w+X_ADJUST) | ((config->dest.y + dest_h) << 16);
2933 ComputeBorders(config,VertUVSubSample);
2934 besr.vid_buf_pitch0_value = pitch;
2935 besr.vid_buf_pitch1_value = is_410 ? pitch>>2 : is_420 ? pitch>>1 : pitch;
2936 /* ********************************************************* */
2937 /* ** Calculate programmable coefficients as needed */
2938 /* ********************************************************* */
2939
2940 /* ToDo_Active: When in pick nearest mode, we need to program the filter tap zero */
2941 /* coefficients to 0, 32, 0, 0. Or use hard coded coefficients. */
2942 if(H_scale_ratio > MinHScaleHard) besr.filter_cntl |= FILTER_HARDCODED_COEF;
2943 else
2944 {
2945 FilterSetup (val_OV0_P1_H_INC);
2946 /* ToDo_Active: Must add the smarts into the driver to decide what type of filtering it */
2947 /* would like to do. For now, we let the test application decide. */
2948 besr.filter_cntl = FILTER_PROGRAMMABLE_COEF;
2949 if(DisallowFourTapVertFiltering)
2950 besr.filter_cntl |= FILTER_HARD_SCALE_VERT_Y;
2951 if(DisallowFourTapUVVertFiltering)
2952 besr.filter_cntl |= FILTER_HARD_SCALE_VERT_UV;
2953 }
2954 return 0;
2955 }
2956
radeon_compute_framesize(vidix_playback_t * info)2957 static void radeon_compute_framesize(vidix_playback_t *info)
2958 {
2959 unsigned pitch,awidth,dbpp;
2960 pitch = radeon_query_pitch(info->fourcc,&info->src.pitch);
2961 dbpp = radeon_vid_get_dbpp();
2962 switch(info->fourcc)
2963 {
2964 case IMGFMT_Y800:
2965 awidth = (info->src.w + (pitch-1)) & ~(pitch-1);
2966 info->frame_size = awidth*info->src.h;
2967 break;
2968 case IMGFMT_YVU9:
2969 case IMGFMT_IF09:
2970 awidth = (info->src.w + (pitch-1)) & ~(pitch-1);
2971 info->frame_size = awidth*(info->src.h+info->src.h/8);
2972 break;
2973 case IMGFMT_I420:
2974 case IMGFMT_YV12:
2975 case IMGFMT_IYUV:
2976 awidth = (info->src.w + (pitch-1)) & ~(pitch-1);
2977 info->frame_size = awidth*(info->src.h+info->src.h/2);
2978 break;
2979 case IMGFMT_RGB32:
2980 case IMGFMT_BGR32:
2981 awidth = (info->src.w*4 + (pitch-1)) & ~(pitch-1);
2982 info->frame_size = awidth*info->src.h;
2983 break;
2984 /* YUY2 YVYU, RGB15, RGB16 */
2985 default:
2986 awidth = (info->src.w*2 + (pitch-1)) & ~(pitch-1);
2987 info->frame_size = awidth*info->src.h;
2988 break;
2989 }
2990 info->frame_size = (info->frame_size+4095)&~4095;
2991 }
2992
VIDIX_NAME(vixConfigPlayback)2993 int VIDIX_NAME(vixConfigPlayback)(vidix_playback_t *info)
2994 {
2995 unsigned rgb_size,nfr;
2996 uint32_t radeon_video_size;
2997 if(!is_supported_fourcc(info->fourcc,info->src.w)) return ENOSYS;
2998 if(info->num_frames>VID_PLAY_MAXFRAMES) info->num_frames=VID_PLAY_MAXFRAMES;
2999 if(info->num_frames==1) besr.double_buff=0;
3000 else besr.double_buff=1;
3001 radeon_compute_framesize(info);
3002
3003 rgb_size = radeon_get_xres()*radeon_get_yres()*((radeon_vid_get_dbpp()+7)/8);
3004 nfr = info->num_frames;
3005 radeon_video_size = radeon_ram_size;
3006 #ifdef RADEON_ENABLE_BM
3007 if(def_cap.flags & FLAG_DMA)
3008 {
3009 /* every descriptor describes one 4K page and takes 16 bytes in memory
3010 Note: probably it's ont good idea to locate them in video memory
3011 but as initial release it's OK */
3012 radeon_video_size -= radeon_ram_size * sizeof(bm_list_descriptor) / 4096;
3013 radeon_dma_desc_base = (uint8_t *) pci_info.base0 + radeon_video_size;
3014 }
3015 #endif
3016 for(;nfr>0; nfr--)
3017 {
3018 radeon_overlay_off = radeon_video_size - info->frame_size*nfr;
3019 radeon_overlay_off &= 0xffff0000;
3020 if(radeon_overlay_off >= (int)rgb_size ) break;
3021 }
3022 if(nfr <= 3)
3023 {
3024 nfr = info->num_frames;
3025 for(;nfr>0; nfr--)
3026 {
3027 radeon_overlay_off = radeon_video_size - info->frame_size*nfr;
3028 radeon_overlay_off &= 0xffff0000;
3029 if(radeon_overlay_off > 0) break;
3030 }
3031 }
3032 if(nfr <= 0) return EINVAL;
3033 info->num_frames = nfr;
3034 besr.vid_nbufs = info->num_frames;
3035 info->dga_addr = (char *)radeon_mem_base + radeon_overlay_off;
3036 radeon_vid_init_video(info);
3037 return 0;
3038 }
3039
VIDIX_NAME(vixPlaybackOn)3040 int VIDIX_NAME(vixPlaybackOn)( void )
3041 {
3042 #ifdef RAGE128
3043 unsigned dw,dh;
3044 #endif
3045 radeon_vid_display_video();
3046 #ifdef RAGE128
3047 dh = (besr.y_x_end >> 16) - (besr.y_x_start >> 16);
3048 dw = (besr.y_x_end & 0xFFFF) - (besr.y_x_start & 0xFFFF);
3049 if(dw == radeon_get_xres() || dh == radeon_get_yres()) radeon_vid_exclusive();
3050 else radeon_vid_non_exclusive();
3051 #endif
3052 return 0;
3053 }
3054
VIDIX_NAME(vixPlaybackOff)3055 int VIDIX_NAME(vixPlaybackOff)( void )
3056 {
3057 radeon_vid_stop_video();
3058 return 0;
3059 }
3060
VIDIX_NAME(vixPlaybackFrameSelect)3061 int VIDIX_NAME(vixPlaybackFrameSelect)(unsigned frame)
3062 {
3063 uint32_t off[6];
3064 int prev_frame= (frame-1+besr.vid_nbufs) % besr.vid_nbufs;
3065 /*
3066 buf3-5 always should point onto second buffer for better
3067 deinterlacing and TV-in
3068 */
3069 if(!besr.double_buff) return 0;
3070 if(frame > besr.vid_nbufs) frame = besr.vid_nbufs-1;
3071 if(prev_frame > (int)besr.vid_nbufs) prev_frame = besr.vid_nbufs-1;
3072 off[0] = besr.vid_buf_base_adrs_y[frame];
3073 off[1] = besr.vid_buf_base_adrs_v[frame];
3074 off[2] = besr.vid_buf_base_adrs_u[frame];
3075 off[3] = besr.vid_buf_base_adrs_y[prev_frame];
3076 off[4] = besr.vid_buf_base_adrs_v[prev_frame];
3077 off[5] = besr.vid_buf_base_adrs_u[prev_frame];
3078 radeon_fifo_wait(8);
3079 OUTREG(OV0_REG_LOAD_CNTL, REG_LD_CTL_LOCK);
3080 radeon_engine_idle();
3081 while(!(INREG(OV0_REG_LOAD_CNTL)®_LD_CTL_LOCK_READBACK));
3082 OUTREG(OV0_VID_BUF0_BASE_ADRS, off[0]);
3083 OUTREG(OV0_VID_BUF1_BASE_ADRS, off[1]);
3084 OUTREG(OV0_VID_BUF2_BASE_ADRS, off[2]);
3085 OUTREG(OV0_VID_BUF3_BASE_ADRS, off[3]);
3086 OUTREG(OV0_VID_BUF4_BASE_ADRS, off[4]);
3087 OUTREG(OV0_VID_BUF5_BASE_ADRS, off[5]);
3088 OUTREG(OV0_REG_LOAD_CNTL, 0);
3089 if(besr.vid_nbufs == 2) radeon_wait_vsync();
3090 if(__verbose > VERBOSE_LEVEL) radeon_vid_dump_regs();
3091 return 0;
3092 }
3093
3094 vidix_video_eq_t equal =
3095 {
3096 VEQ_CAP_BRIGHTNESS | VEQ_CAP_SATURATION
3097 #ifndef RAGE128
3098 | VEQ_CAP_CONTRAST | VEQ_CAP_HUE | VEQ_CAP_RGB_INTENSITY
3099 #endif
3100 ,
3101 0, 0, 0, 0, 0, 0, 0, 0 };
3102
VIDIX_NAME(vixPlaybackGetEq)3103 int VIDIX_NAME(vixPlaybackGetEq)( vidix_video_eq_t * eq)
3104 {
3105 memcpy(eq,&equal,sizeof(vidix_video_eq_t));
3106 return 0;
3107 }
3108
3109 #ifndef RAGE128
3110 #define RTFSaturation(a) (1.0 + ((a)*1.0)/1000.0)
3111 #define RTFBrightness(a) (((a)*1.0)/2000.0)
3112 #define RTFIntensity(a) (((a)*1.0)/2000.0)
3113 #define RTFContrast(a) (1.0 + ((a)*1.0)/1000.0)
3114 #define RTFHue(a) (((a)*3.1416)/1000.0)
3115 #define RTFCheckParam(a) {if((a)<-1000) (a)=-1000; if((a)>1000) (a)=1000;}
3116 #endif
3117
VIDIX_NAME(vixPlaybackSetEq)3118 int VIDIX_NAME(vixPlaybackSetEq)( const vidix_video_eq_t * eq)
3119 {
3120 #ifdef RAGE128
3121 int br,sat;
3122 #else
3123 int itu_space;
3124 #endif
3125 if(eq->cap & VEQ_CAP_BRIGHTNESS) equal.brightness = eq->brightness;
3126 if(eq->cap & VEQ_CAP_CONTRAST) equal.contrast = eq->contrast;
3127 if(eq->cap & VEQ_CAP_SATURATION) equal.saturation = eq->saturation;
3128 if(eq->cap & VEQ_CAP_HUE) equal.hue = eq->hue;
3129 if(eq->cap & VEQ_CAP_RGB_INTENSITY)
3130 {
3131 equal.red_intensity = eq->red_intensity;
3132 equal.green_intensity = eq->green_intensity;
3133 equal.blue_intensity = eq->blue_intensity;
3134 }
3135 equal.flags = eq->flags;
3136 #ifdef RAGE128
3137 br = equal.brightness * 64 / 1000;
3138 if(br < -64) br = -64; if(br > 63) br = 63;
3139 sat = (equal.saturation*31 + 31000) / 2000;
3140 if(sat < 0) sat = 0; if(sat > 31) sat = 31;
3141 OUTREG(OV0_COLOUR_CNTL, (br & 0x7f) | (sat << 8) | (sat << 16));
3142 #else
3143 itu_space = equal.flags == VEQ_FLG_ITU_R_BT_709 ? 1 : 0;
3144 RTFCheckParam(equal.brightness);
3145 RTFCheckParam(equal.saturation);
3146 RTFCheckParam(equal.contrast);
3147 RTFCheckParam(equal.hue);
3148 RTFCheckParam(equal.red_intensity);
3149 RTFCheckParam(equal.green_intensity);
3150 RTFCheckParam(equal.blue_intensity);
3151 radeon_set_transform(RTFBrightness(equal.brightness),
3152 RTFContrast(equal.contrast),
3153 RTFSaturation(equal.saturation),
3154 RTFHue(equal.hue),
3155 RTFIntensity(equal.red_intensity),
3156 RTFIntensity(equal.green_intensity),
3157 RTFIntensity(equal.blue_intensity),
3158 itu_space);
3159 #endif
3160 return 0;
3161 }
3162
VIDIX_NAME(vixPlaybackSetDeint)3163 int VIDIX_NAME(vixPlaybackSetDeint)( const vidix_deinterlace_t * info)
3164 {
3165 unsigned sflg;
3166 switch(info->flags)
3167 {
3168 default:
3169 case CFG_NON_INTERLACED:
3170 besr.deinterlace_on = 0;
3171 break;
3172 case CFG_EVEN_ODD_INTERLACING:
3173 case CFG_INTERLACED:
3174 besr.deinterlace_on = 1;
3175 besr.deinterlace_pattern = 0x900AAAAA;
3176 break;
3177 case CFG_ODD_EVEN_INTERLACING:
3178 besr.deinterlace_on = 1;
3179 besr.deinterlace_pattern = 0x00055555;
3180 break;
3181 case CFG_UNIQUE_INTERLACING:
3182 besr.deinterlace_on = 1;
3183 besr.deinterlace_pattern = info->deinterlace_pattern;
3184 break;
3185 }
3186 OUTREG(OV0_REG_LOAD_CNTL, REG_LD_CTL_LOCK);
3187 radeon_engine_idle();
3188 while(!(INREG(OV0_REG_LOAD_CNTL)®_LD_CTL_LOCK_READBACK));
3189 radeon_fifo_wait(15);
3190 sflg = INREG(OV0_SCALE_CNTL);
3191 if(besr.deinterlace_on)
3192 {
3193 OUTREG(OV0_SCALE_CNTL,sflg | SCALER_ADAPTIVE_DEINT);
3194 OUTREG(OV0_DEINTERLACE_PATTERN,besr.deinterlace_pattern);
3195 }
3196 else OUTREG(OV0_SCALE_CNTL,sflg & (~SCALER_ADAPTIVE_DEINT));
3197 OUTREG(OV0_REG_LOAD_CNTL, 0);
3198 return 0;
3199 }
3200
VIDIX_NAME(vixPlaybackGetDeint)3201 int VIDIX_NAME(vixPlaybackGetDeint)( vidix_deinterlace_t * info)
3202 {
3203 if(!besr.deinterlace_on) info->flags = CFG_NON_INTERLACED;
3204 else
3205 {
3206 info->flags = CFG_UNIQUE_INTERLACING;
3207 info->deinterlace_pattern = besr.deinterlace_pattern;
3208 }
3209 return 0;
3210 }
3211
3212
3213 /* Graphic keys */
3214 static vidix_grkey_t radeon_grkey;
3215
set_gr_key(void)3216 static void set_gr_key( void )
3217 {
3218 if(radeon_grkey.ckey.op == CKEY_TRUE)
3219 {
3220 int dbpp=radeon_vid_get_dbpp();
3221
3222 switch(dbpp)
3223 {
3224 case 15:
3225 #ifndef RAGE128
3226 besr.graphics_key_clr=
3227 ((radeon_grkey.ckey.blue &0xF8))
3228 | ((radeon_grkey.ckey.green&0xF8)<<8)
3229 | ((radeon_grkey.ckey.red &0xF8)<<16);
3230 #else
3231 besr.graphics_key_clr=
3232 ((radeon_grkey.ckey.blue &0xF8)>>3)
3233 | ((radeon_grkey.ckey.green&0xF8)<<2)
3234 | ((radeon_grkey.ckey.red &0xF8)<<7);
3235 #endif
3236 break;
3237 case 16:
3238 #ifndef RAGE128
3239 besr.graphics_key_clr=
3240 ((radeon_grkey.ckey.blue &0xF8))
3241 | ((radeon_grkey.ckey.green&0xFC)<<8)
3242 | ((radeon_grkey.ckey.red &0xF8)<<16);
3243 #else
3244 besr.graphics_key_clr=
3245 ((radeon_grkey.ckey.blue &0xF8)>>3)
3246 | ((radeon_grkey.ckey.green&0xFC)<<3)
3247 | ((radeon_grkey.ckey.red &0xF8)<<8);
3248 #endif
3249 break;
3250 case 24:
3251 case 32:
3252 besr.graphics_key_clr=
3253 ((radeon_grkey.ckey.blue &0xFF))
3254 | ((radeon_grkey.ckey.green&0xFF)<<8)
3255 | ((radeon_grkey.ckey.red &0xFF)<<16);
3256 break;
3257 default:
3258 besr.graphics_key_msk=0;
3259 besr.graphics_key_clr=0;
3260 }
3261 #ifdef RAGE128
3262 besr.graphics_key_msk=(1<<dbpp)-1;
3263 besr.ckey_cntl = VIDEO_KEY_FN_TRUE|GRAPHIC_KEY_FN_NE|CMP_MIX_AND;
3264 #else
3265 besr.graphics_key_msk=besr.graphics_key_clr;
3266 besr.ckey_cntl = VIDEO_KEY_FN_TRUE|CMP_MIX_AND|GRAPHIC_KEY_FN_EQ;
3267 #endif
3268 }
3269 else
3270 {
3271 besr.graphics_key_msk=0;
3272 besr.graphics_key_clr=0;
3273 besr.ckey_cntl = VIDEO_KEY_FN_TRUE|GRAPHIC_KEY_FN_TRUE|CMP_MIX_AND;
3274 }
3275 radeon_fifo_wait(3);
3276 OUTREG(OV0_GRAPHICS_KEY_MSK, besr.graphics_key_msk);
3277 OUTREG(OV0_GRAPHICS_KEY_CLR, besr.graphics_key_clr);
3278 OUTREG(OV0_KEY_CNTL,besr.ckey_cntl);
3279 }
3280
VIDIX_NAME(vixGetGrKeys)3281 int VIDIX_NAME(vixGetGrKeys)(vidix_grkey_t *grkey)
3282 {
3283 memcpy(grkey, &radeon_grkey, sizeof(vidix_grkey_t));
3284 return(0);
3285 }
3286
VIDIX_NAME(vixSetGrKeys)3287 int VIDIX_NAME(vixSetGrKeys)(const vidix_grkey_t *grkey)
3288 {
3289 memcpy(&radeon_grkey, grkey, sizeof(vidix_grkey_t));
3290 set_gr_key();
3291 return(0);
3292 }
3293
3294 #ifdef RADEON_ENABLE_BM
radeon_setup_frame(vidix_dma_t * dmai)3295 static int radeon_setup_frame( vidix_dma_t * dmai )
3296 {
3297 bm_list_descriptor * list = (bm_list_descriptor *)radeon_dma_desc_base;
3298 unsigned long dest_ptr;
3299 unsigned i,n,count;
3300 int retval;
3301 if(dmai->dest_offset + dmai->size > radeon_ram_size) return E2BIG;
3302 n = dmai->size / 4096;
3303 if(dmai->size % 4096) n++;
3304 if((retval = bm_virt_to_bus(dmai->src,dmai->size,dma_phys_addrs)) != 0) return retval;
3305 dest_ptr = dmai->dest_offset;
3306 count = dmai->size;
3307 for(i=0;i<n;i++)
3308 {
3309 list[i].framebuf_offset = radeon_overlay_off + dest_ptr;
3310 list[i].sys_addr = dma_phys_addrs[i];
3311 #ifdef RAGE128
3312 list[i].command = (count > 4096 ? 4096 : count | BM_END_OF_LIST)|BM_FORCE_TO_PCI;
3313 #else
3314 list[i].command = (count > 4096 ? 4096 : count | DMA_GUI_COMMAND__EOL);
3315 #endif
3316 list[i].reserved = 0;
3317 printf("RADEON_DMA_TABLE[%i] %X %X %X %X\n",i,list[i].framebuf_offset,list[i].sys_addr,list[i].command,list[i].reserved);
3318 dest_ptr += 4096;
3319 count -= 4096;
3320 }
3321 return 0;
3322 }
3323
radeon_transfer_frame(void)3324 static int radeon_transfer_frame( void )
3325 {
3326 unsigned i;
3327 radeon_engine_idle();
3328 for(i=0;i<1000;i++) INREG(BUS_CNTL); /* FlushWriteCombining */
3329 OUTREG(BUS_CNTL,(INREG(BUS_CNTL) | BUS_STOP_REQ_DIS)&(~BUS_MASTER_DIS));
3330 #ifdef RAGE128
3331 OUTREG(BM_CHUNK_0_VAL,0x000000FF | BM_GLOBAL_FORCE_TO_PCI);
3332 OUTREG(BM_CHUNK_1_VAL,0x0F0F0F0F);
3333 OUTREG(BM_VIP0_BUF,bus_addr_dma_desc|SYSTEM_TRIGGER_SYSTEM_TO_VIDEO);
3334 // OUTREG(GEN_INT_STATUS,INREG(GEN_INT_STATUS)|0x00010000);
3335 #else
3336 OUTREG(MC_FB_LOCATION,
3337 ((pci_info.base0>>16)&0xffff)|
3338 ((pci_info.base0+INREG(CONFIG_APER_SIZE)-1)&0xffff0000));
3339 if((INREG(MC_AGP_LOCATION)&0xffff)!=
3340 (((pci_info.base0+INREG(CONFIG_APER_SIZE))>>16)&0xffff))
3341 /*Radeon memory controller is misconfigured*/
3342 return EINVAL;
3343 OUTREG(DMA_VID_ACT_DSCRPTR,bus_addr_dma_desc);
3344 // OUTREG(GEN_INT_STATUS,INREG(GEN_INT_STATUS)|(1<<30));
3345 #endif
3346 OUTREG(GEN_INT_STATUS,INREG(GEN_INT_STATUS)|0x00010000);
3347 return 0;
3348 }
3349
3350
VIDIX_NAME(vixPlaybackCopyFrame)3351 int VIDIX_NAME(vixPlaybackCopyFrame)( vidix_dma_t * dmai )
3352 {
3353 int retval;
3354 if(mlock(dmai->src,dmai->size) != 0) return errno;
3355 retval = radeon_setup_frame(dmai);
3356 if(retval == 0) retval = radeon_transfer_frame();
3357 munlock(dmai->src,dmai->size);
3358 return retval;
3359 }
3360
VIDIX_NAME(vixQueryDMAStatus)3361 int VIDIX_NAME(vixQueryDMAStatus)( void )
3362 {
3363 int bm_active;
3364 #if 1 //def RAGE128
3365 bm_active=(INREG(GEN_INT_STATUS)&0x00010000)==0?1:0;
3366 #else
3367 bm_active=(INREG(GEN_INT_STATUS)&(1<<30))==0?1:0;
3368 #endif
3369 return bm_active?1:0;
3370 }
3371 #endif
3372