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)&REG_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)&REG_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)&REG_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