2 * VIDIX driver for ATI Rage128 and Radeon chipsets.
3 * Copyright (C) 2002 Nick Kurshev
5 * This file is part of MPlayer.
7 * MPlayer is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * MPlayer is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with MPlayer; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 * This file is based on sources from
22 * GATOS (gatos.sf.net) and X11 (www.xfree86.org)
26 * added support for fglrx drivers by Marcel Naziri (zwobbl@zwobbl.de)
28 * fixes to allow compiling vidix without X11 (broken in original patch)
29 * - PowerPC support by Alex Beregszaszi
40 #include "libavutil/common.h"
43 #include "pci_names.h"
50 #if !defined(RAGE128) && defined(HAVE_X11)
52 static uint32_t firegl_shift
= 0;
56 #define RADEON_MSG "[rage128]"
59 #define RADEON_MSG "[radeon]"
60 #define X_ADJUST (((besr.chip_flags&R_OVL_SHIFT)==R_OVL_SHIFT)?8:0)
66 #define RADEON_ASSERT(msg) printf(RADEON_MSG"################# FATAL:"msg);
68 #define VERBOSE_LEVEL 0
69 static int __verbose
= 0;
70 typedef struct bes_registers_s
72 /* base address of yuv framebuffer */
77 int horz_pick_nearest
;
78 int vert_pick_nearest
;
79 int swap_uv
; /* for direct support of bgr fourccs */
81 /* YUV BES registers */
82 uint32_t reg_load_cntl
;
88 uint32_t p1_blank_lines_at_top
;
89 uint32_t p23_blank_lines_at_top
;
90 uint32_t vid_buf_pitch0_value
;
91 uint32_t vid_buf_pitch1_value
;
92 uint32_t p1_x_start_end
;
93 uint32_t p2_x_start_end
;
94 uint32_t p3_x_start_end
;
96 uint32_t vid_buf_base_adrs_y
[VID_PLAY_MAXFRAMES
];
97 uint32_t vid_buf_base_adrs_u
[VID_PLAY_MAXFRAMES
];
98 uint32_t vid_buf_base_adrs_v
[VID_PLAY_MAXFRAMES
];
101 uint32_t p1_v_accum_init
;
102 uint32_t p1_h_accum_init
;
103 uint32_t p23_v_accum_init
;
104 uint32_t p23_h_accum_init
;
106 uint32_t exclusive_horz
;
107 uint32_t auto_flip_cntl
;
108 uint32_t filter_cntl
;
109 uint32_t four_tap_coeff
[5];
112 /* Configurable stuff */
119 uint32_t graphics_key_clr
;
120 uint32_t graphics_key_msk
;
125 uint32_t deinterlace_pattern
;
130 typedef struct video_registers_s
137 static bes_registers_t besr
;
138 #define DECLARE_VREG(name) { #name, name, 0 }
139 static video_registers_t vregs
[] =
141 DECLARE_VREG(VIDEOMUX_CNTL
),
142 DECLARE_VREG(VIPPAD_MASK
),
143 DECLARE_VREG(VIPPAD1_A
),
144 DECLARE_VREG(VIPPAD1_EN
),
145 DECLARE_VREG(VIPPAD1_Y
),
146 DECLARE_VREG(OV0_Y_X_START
),
147 DECLARE_VREG(OV0_Y_X_END
),
148 DECLARE_VREG(OV1_Y_X_START
),
149 DECLARE_VREG(OV1_Y_X_END
),
150 DECLARE_VREG(OV0_PIPELINE_CNTL
),
151 DECLARE_VREG(OV0_EXCLUSIVE_HORZ
),
152 DECLARE_VREG(OV0_EXCLUSIVE_VERT
),
153 DECLARE_VREG(OV0_REG_LOAD_CNTL
),
154 DECLARE_VREG(OV0_SCALE_CNTL
),
155 DECLARE_VREG(OV0_V_INC
),
156 DECLARE_VREG(OV0_P1_V_ACCUM_INIT
),
157 DECLARE_VREG(OV0_P23_V_ACCUM_INIT
),
158 DECLARE_VREG(OV0_P1_BLANK_LINES_AT_TOP
),
159 DECLARE_VREG(OV0_P23_BLANK_LINES_AT_TOP
),
161 DECLARE_VREG(OV0_BASE_ADDR
),
163 DECLARE_VREG(OV0_VID_BUF0_BASE_ADRS
),
164 DECLARE_VREG(OV0_VID_BUF1_BASE_ADRS
),
165 DECLARE_VREG(OV0_VID_BUF2_BASE_ADRS
),
166 DECLARE_VREG(OV0_VID_BUF3_BASE_ADRS
),
167 DECLARE_VREG(OV0_VID_BUF4_BASE_ADRS
),
168 DECLARE_VREG(OV0_VID_BUF5_BASE_ADRS
),
169 DECLARE_VREG(OV0_VID_BUF_PITCH0_VALUE
),
170 DECLARE_VREG(OV0_VID_BUF_PITCH1_VALUE
),
171 DECLARE_VREG(OV0_AUTO_FLIP_CNTL
),
172 DECLARE_VREG(OV0_DEINTERLACE_PATTERN
),
173 DECLARE_VREG(OV0_SUBMIT_HISTORY
),
174 DECLARE_VREG(OV0_H_INC
),
175 DECLARE_VREG(OV0_STEP_BY
),
176 DECLARE_VREG(OV0_P1_H_ACCUM_INIT
),
177 DECLARE_VREG(OV0_P23_H_ACCUM_INIT
),
178 DECLARE_VREG(OV0_P1_X_START_END
),
179 DECLARE_VREG(OV0_P2_X_START_END
),
180 DECLARE_VREG(OV0_P3_X_START_END
),
181 DECLARE_VREG(OV0_FILTER_CNTL
),
182 DECLARE_VREG(OV0_FOUR_TAP_COEF_0
),
183 DECLARE_VREG(OV0_FOUR_TAP_COEF_1
),
184 DECLARE_VREG(OV0_FOUR_TAP_COEF_2
),
185 DECLARE_VREG(OV0_FOUR_TAP_COEF_3
),
186 DECLARE_VREG(OV0_FOUR_TAP_COEF_4
),
187 DECLARE_VREG(OV0_FLAG_CNTL
),
189 DECLARE_VREG(OV0_COLOUR_CNTL
),
191 DECLARE_VREG(OV0_SLICE_CNTL
),
193 DECLARE_VREG(OV0_VID_KEY_CLR
),
194 DECLARE_VREG(OV0_VID_KEY_MSK
),
195 DECLARE_VREG(OV0_GRAPHICS_KEY_CLR
),
196 DECLARE_VREG(OV0_GRAPHICS_KEY_MSK
),
197 DECLARE_VREG(OV0_KEY_CNTL
),
198 DECLARE_VREG(OV0_TEST
),
199 DECLARE_VREG(OV0_LIN_TRANS_A
),
200 DECLARE_VREG(OV0_LIN_TRANS_B
),
201 DECLARE_VREG(OV0_LIN_TRANS_C
),
202 DECLARE_VREG(OV0_LIN_TRANS_D
),
203 DECLARE_VREG(OV0_LIN_TRANS_E
),
204 DECLARE_VREG(OV0_LIN_TRANS_F
),
205 DECLARE_VREG(OV0_GAMMA_0_F
),
206 DECLARE_VREG(OV0_GAMMA_10_1F
),
207 DECLARE_VREG(OV0_GAMMA_20_3F
),
208 DECLARE_VREG(OV0_GAMMA_40_7F
),
209 DECLARE_VREG(OV0_GAMMA_380_3BF
),
210 DECLARE_VREG(OV0_GAMMA_3C0_3FF
),
211 DECLARE_VREG(SUBPIC_CNTL
),
212 DECLARE_VREG(SUBPIC_DEFCOLCON
),
213 DECLARE_VREG(SUBPIC_Y_X_START
),
214 DECLARE_VREG(SUBPIC_Y_X_END
),
215 DECLARE_VREG(SUBPIC_V_INC
),
216 DECLARE_VREG(SUBPIC_H_INC
),
217 DECLARE_VREG(SUBPIC_BUF0_OFFSET
),
218 DECLARE_VREG(SUBPIC_BUF1_OFFSET
),
219 DECLARE_VREG(SUBPIC_LC0_OFFSET
),
220 DECLARE_VREG(SUBPIC_LC1_OFFSET
),
221 DECLARE_VREG(SUBPIC_PITCH
),
222 DECLARE_VREG(SUBPIC_BTN_HLI_COLCON
),
223 DECLARE_VREG(SUBPIC_BTN_HLI_Y_X_START
),
224 DECLARE_VREG(SUBPIC_BTN_HLI_Y_X_END
),
225 DECLARE_VREG(SUBPIC_PALETTE_INDEX
),
226 DECLARE_VREG(SUBPIC_PALETTE_DATA
),
227 DECLARE_VREG(SUBPIC_H_ACCUM_INIT
),
228 DECLARE_VREG(SUBPIC_V_ACCUM_INIT
),
229 DECLARE_VREG(IDCT_RUNS
),
230 DECLARE_VREG(IDCT_LEVELS
),
231 DECLARE_VREG(IDCT_AUTH_CONTROL
),
232 DECLARE_VREG(IDCT_AUTH
),
233 DECLARE_VREG(IDCT_CONTROL
),
235 DECLARE_VREG(BM_FRAME_BUF_OFFSET
),
236 DECLARE_VREG(BM_SYSTEM_MEM_ADDR
),
237 DECLARE_VREG(BM_COMMAND
),
238 DECLARE_VREG(BM_STATUS
),
239 DECLARE_VREG(BM_QUEUE_STATUS
),
240 DECLARE_VREG(BM_QUEUE_FREE_STATUS
),
241 DECLARE_VREG(BM_CHUNK_0_VAL
),
242 DECLARE_VREG(BM_CHUNK_1_VAL
),
243 DECLARE_VREG(BM_VIP0_BUF
),
244 DECLARE_VREG(BM_VIP0_ACTIVE
),
245 DECLARE_VREG(BM_VIP1_BUF
),
246 DECLARE_VREG(BM_VIP1_ACTIVE
),
247 DECLARE_VREG(BM_VIP2_BUF
),
248 DECLARE_VREG(BM_VIP2_ACTIVE
),
249 DECLARE_VREG(BM_VIP3_BUF
),
250 DECLARE_VREG(BM_VIP3_ACTIVE
),
251 DECLARE_VREG(BM_VIDCAP_BUF0
),
252 DECLARE_VREG(BM_VIDCAP_BUF1
),
253 DECLARE_VREG(BM_VIDCAP_BUF2
),
254 DECLARE_VREG(BM_VIDCAP_ACTIVE
),
255 DECLARE_VREG(BM_GUI
),
256 DECLARE_VREG(BM_ABORT
)
258 DECLARE_VREG(DMA_GUI_TABLE_ADDR
),
259 DECLARE_VREG(DMA_GUI_SRC_ADDR
),
260 DECLARE_VREG(DMA_GUI_DST_ADDR
),
261 DECLARE_VREG(DMA_GUI_COMMAND
),
262 DECLARE_VREG(DMA_GUI_STATUS
),
263 DECLARE_VREG(DMA_GUI_ACT_DSCRPTR
),
264 DECLARE_VREG(DMA_VID_SRC_ADDR
),
265 DECLARE_VREG(DMA_VID_DST_ADDR
),
266 DECLARE_VREG(DMA_VID_COMMAND
),
267 DECLARE_VREG(DMA_VID_STATUS
),
268 DECLARE_VREG(DMA_VID_ACT_DSCRPTR
),
272 #define R_FAMILY 0x000000FF
273 #define R_100 0x00000001
274 #define R_120 0x00000002
275 #define R_150 0x00000003
276 #define R_200 0x00000004
277 #define R_250 0x00000005
278 #define R_280 0x00000006
279 #define R_300 0x00000007
280 #define R_350 0x00000008
281 #define R_370 0x00000010
282 #define R_380 0x00000020
283 #define R_420 0x00000040
284 #define R_430 0x00000080
285 #define R_480 0x00000100
286 #define R_520 0x00000200
287 #define R_530 0x00000400
288 #define R_580 0x00000800
289 #define R_OVL_SHIFT 0x01000000
290 #define R_INTEGRATED 0x02000000
291 #define R_PCIE 0x04000000
293 typedef struct ati_card_ids_s
299 static const ati_card_ids_t ati_card_ids
[] =
303 This driver should be compatible with Rage128 (pro) chips.
304 (include adaptive deinterlacing!!!).
305 Moreover: the same logic can be used with Mach64 chips.
306 (I mean: mach64xx, 3d rage, 3d rage IIc, 3D rage pro, 3d rage mobility).
307 but they are incompatible by i/o ports. So if enthusiasts will want
308 then they can redefine OUTREG and INREG macros and redefine OV0_*
309 constants. Also it seems that mach64 chips supports only: YUY2, YV12, UYVY
310 fourccs (422 and 420 formats only).
313 { DEVICE_ATI_RAGE_128_PA_PRO
, 0 },
314 { DEVICE_ATI_RAGE_128_PB_PRO
, 0 },
315 { DEVICE_ATI_RAGE_128_PC_PRO
, 0 },
316 { DEVICE_ATI_RAGE_128_PD_PRO
, 0 },
317 { DEVICE_ATI_RAGE_128_PE_PRO
, 0 },
318 { DEVICE_ATI_RAGE_128_PF_PRO
, 0 },
320 { DEVICE_ATI_RAGE_128_PG_PRO
, 0 },
321 { DEVICE_ATI_RAGE_128_PH_PRO
, 0 },
322 { DEVICE_ATI_RAGE_128_PI_PRO
, 0 },
323 { DEVICE_ATI_RAGE_128_PJ_PRO
, 0 },
324 { DEVICE_ATI_RAGE_128_PK_PRO
, 0 },
325 { DEVICE_ATI_RAGE_128_PL_PRO
, 0 },
326 { DEVICE_ATI_RAGE_128_PM_PRO
, 0 },
327 { DEVICE_ATI_RAGE_128_PN_PRO
, 0 },
328 { DEVICE_ATI_RAGE_128_PO_PRO
, 0 },
329 { DEVICE_ATI_RAGE_128_PP_PRO
, 0 },
330 { DEVICE_ATI_RAGE_128_PQ_PRO
, 0 },
331 { DEVICE_ATI_RAGE_128_PR_PRO
, 0 },
332 { DEVICE_ATI_RAGE_128_PS_PRO
, 0 },
333 { DEVICE_ATI_RAGE_128_PT_PRO
, 0 },
334 { DEVICE_ATI_RAGE_128_PU_PRO
, 0 },
335 { DEVICE_ATI_RAGE_128_PV_PRO
, 0 },
336 { DEVICE_ATI_RAGE_128_PW_PRO
, 0 },
337 { DEVICE_ATI_RAGE_128_PX_PRO
, 0 },
339 { DEVICE_ATI_RAGE_128_RE_SG
, 0 },
340 { DEVICE_ATI_RAGE_128_RF_SG
, 0 },
341 { DEVICE_ATI_RAGE_128_RG
, 0 },
342 { DEVICE_ATI_RAGE_128_RK_VR
, 0 },
343 { DEVICE_ATI_RAGE_128_RL_VR
, 0 },
344 { DEVICE_ATI_RAGE_128_SE_4X
, 0 },
345 { DEVICE_ATI_RAGE_128_SF_4X
, 0 },
346 { DEVICE_ATI_RAGE_128_SG_4X
, 0 },
347 { DEVICE_ATI_RAGE_128_SH
, 0 },
348 { DEVICE_ATI_RAGE_128_SK_4X
, 0 },
349 { DEVICE_ATI_RAGE_128_SL_4X
, 0 },
350 { DEVICE_ATI_RAGE_128_SM_4X
, 0 },
351 { DEVICE_ATI_RAGE_128_4X
, 0 },
352 { DEVICE_ATI_RAGE_128_PRO
, 0 },
353 { DEVICE_ATI_RAGE_128_PRO2
, 0 },
354 { DEVICE_ATI_RAGE_128_PRO3
, 0 },
355 /* these seem to be based on rage 128 instead of mach64 */
356 { DEVICE_ATI_RAGE_MOBILITY_M3
, 0 },
357 { DEVICE_ATI_RAGE_MOBILITY_M32
, 0 },
359 /* Radeon1 (indeed: Rage 256 Pro ;) */
360 { DEVICE_ATI_RADEON_R100_QD
, R_100
|R_OVL_SHIFT
},
361 { DEVICE_ATI_RADEON_R100_QE
, R_100
|R_OVL_SHIFT
},
362 { DEVICE_ATI_RADEON_R100_QF
, R_100
|R_OVL_SHIFT
},
363 { DEVICE_ATI_RADEON_R100_QG
, R_100
|R_OVL_SHIFT
},
364 { DEVICE_ATI_RADEON_IGP_320
, R_150
|R_OVL_SHIFT
|R_INTEGRATED
},
365 { DEVICE_ATI_RADEON_MOBILITY_U1
, R_150
|R_OVL_SHIFT
|R_INTEGRATED
},
366 { DEVICE_ATI_RADEON_RV100_QY
, R_120
|R_OVL_SHIFT
},
367 { DEVICE_ATI_RADEON_RV100_QZ
, R_120
|R_OVL_SHIFT
},
368 { DEVICE_ATI_RADEON_MOBILITY_M7
, R_150
|R_OVL_SHIFT
},
369 { DEVICE_ATI_RADEON_RV200_LX
, R_150
|R_OVL_SHIFT
},
370 { DEVICE_ATI_RADEON_MOBILITY_M6
, R_120
|R_OVL_SHIFT
},
371 { DEVICE_ATI_RADEON_MOBILITY_M62
, R_120
|R_OVL_SHIFT
},
372 /* Radeon2 (indeed: Rage 512 Pro ;) */
373 { DEVICE_ATI_R200_BB_RADEON
, R_200
},
374 { DEVICE_ATI_R200_BC_RADEON
, R_200
},
375 { DEVICE_ATI_RADEON_R200_QH
, R_200
},
376 { DEVICE_ATI_RADEON_R200_QI
, R_200
},
377 { DEVICE_ATI_RADEON_R200_QJ
, R_200
},
378 { DEVICE_ATI_RADEON_R200_QK
, R_200
},
379 { DEVICE_ATI_RADEON_R200_QL
, R_200
},
380 { DEVICE_ATI_RADEON_R200_QM
, R_200
},
381 { DEVICE_ATI_RADEON_R200_QN
, R_200
},
382 { DEVICE_ATI_RADEON_R200_QO
, R_200
},
383 { DEVICE_ATI_RADEON_R200_QH2
, R_200
},
384 { DEVICE_ATI_RADEON_R200_QI2
, R_200
},
385 { DEVICE_ATI_RADEON_R200_QJ2
, R_200
},
386 { DEVICE_ATI_RADEON_R200_QK2
, R_200
},
387 { DEVICE_ATI_RADEON_R200_QL2
, R_200
},
388 { DEVICE_ATI_RADEON_RV200_QW
, R_150
|R_OVL_SHIFT
},
389 { DEVICE_ATI_RADEON_RV200_QX
, R_150
|R_OVL_SHIFT
},
390 { DEVICE_ATI_RADEON_IGP330_340_350
,R_200
|R_INTEGRATED
},
391 { DEVICE_ATI_RADEON_IGP_330M_340M_350M
,R_200
|R_INTEGRATED
},
392 { DEVICE_ATI_RADEON_RV250_IG
, R_250
|R_OVL_SHIFT
},
393 { DEVICE_ATI_RADEON_7000_IGP
, R_250
|R_OVL_SHIFT
|R_INTEGRATED
},
394 { DEVICE_ATI_RADEON_MOBILITY_7000
, R_250
|R_OVL_SHIFT
|R_INTEGRATED
},
395 { DEVICE_ATI_RADEON_RV250_ID
, R_250
|R_OVL_SHIFT
},
396 { DEVICE_ATI_RADEON_RV250_IE
, R_250
|R_OVL_SHIFT
},
397 { DEVICE_ATI_RADEON_RV250_IF
, R_250
|R_OVL_SHIFT
},
398 { DEVICE_ATI_RADEON_RV250_IG
, R_250
|R_OVL_SHIFT
},
399 { DEVICE_ATI_RADEON_R250_LD
, R_250
|R_OVL_SHIFT
},
400 { DEVICE_ATI_RADEON_R250_LE
, R_250
|R_OVL_SHIFT
},
401 { DEVICE_ATI_RADEON_R250_MOBILITY
, R_250
|R_OVL_SHIFT
},
402 { DEVICE_ATI_RADEON_R250_LG
, R_250
|R_OVL_SHIFT
},
403 { DEVICE_ATI_RV250_RADEON_9000
, R_250
|R_OVL_SHIFT
},
404 { DEVICE_ATI_RADEON_RV250_RADEON2
, R_250
|R_OVL_SHIFT
},
405 { DEVICE_ATI_RV280_RADEON_9200
, R_280
},
406 { DEVICE_ATI_RV280_RADEON_92002
, R_280
},
407 { DEVICE_ATI_RV280_RADEON_92003
, R_280
},
408 { DEVICE_ATI_RV280_RADEON_92004
, R_280
},
409 { DEVICE_ATI_RV280_RADEON_92005
, R_280
},
410 { DEVICE_ATI_RV280_RADEON_92006
, R_280
},
411 { DEVICE_ATI_RV280_RADEON_92007
, R_280
},
412 { DEVICE_ATI_M9_5C61_RADEON
, R_280
},
413 { DEVICE_ATI_M9_5C63_RADEON
, R_280
},
414 /* Radeon3 (indeed: Rage 1024 Pro ;) */
415 { DEVICE_ATI_R300_AG_FIREGL
, R_300
},
416 { DEVICE_ATI_RADEON_R300_ND
, R_300
},
417 { DEVICE_ATI_RADEON_R300_NE
, R_300
},
418 { DEVICE_ATI_RADEON_R300_NG
, R_300
},
419 { DEVICE_ATI_R300_AD_RADEON
, R_300
},
420 { DEVICE_ATI_R300_AE_RADEON
, R_300
},
421 { DEVICE_ATI_R300_AF_RADEON
, R_300
},
422 { DEVICE_ATI_RADEON_9100_IGP2
, R_300
|R_OVL_SHIFT
|R_INTEGRATED
},
423 { DEVICE_ATI_RS300M_AGP_RADEON
, R_300
|R_INTEGRATED
},
424 { DEVICE_ATI_RS482_RADEON_XPRESS
, R_350
|R_INTEGRATED
},
425 { DEVICE_ATI_R350_AH_RADEON
, R_350
},
426 { DEVICE_ATI_R350_AI_RADEON
, R_350
},
427 { DEVICE_ATI_R350_AJ_RADEON
, R_350
},
428 { DEVICE_ATI_R350_AK_FIRE
, R_350
},
429 { DEVICE_ATI_RADEON_R350_RADEON2
, R_350
},
430 { DEVICE_ATI_RADEON_R350_RADEON3
, R_350
},
431 { DEVICE_ATI_RV350_NJ_RADEON
, R_350
},
432 { DEVICE_ATI_R350_NK_FIRE
, R_350
},
433 { DEVICE_ATI_RV350_AP_RADEON
, R_350
},
434 { DEVICE_ATI_RV350_AQ_RADEON
, R_350
},
435 { DEVICE_ATI_RV350_AR_RADEON
, R_350
},
436 { DEVICE_ATI_RV350_AS_RADEON
, R_350
},
437 { DEVICE_ATI_RV350_AT_FIRE
, R_350
},
438 { DEVICE_ATI_RV350_AU_FIRE
, R_350
},
439 { DEVICE_ATI_RV350_AV_FIRE
, R_350
},
440 { DEVICE_ATI_RV350_AW_FIRE
, R_350
},
441 { DEVICE_ATI_RV350_MOBILITY_RADEON
, R_350
},
442 { DEVICE_ATI_RV350_NF_RADEON
, R_300
},
443 { DEVICE_ATI_RV350_NJ_RADEON
, R_300
},
444 { DEVICE_ATI_RV350_AS_RADEON2
, R_350
},
445 { DEVICE_ATI_M10_NQ_RADEON
, R_350
},
446 { DEVICE_ATI_M10_NQ_RADEON2
, R_350
},
447 { DEVICE_ATI_RV350_MOBILITY_RADEON2
, R_350
},
448 { DEVICE_ATI_M10_NS_RADEON
, R_350
},
449 { DEVICE_ATI_M10_NT_FIREGL
, R_350
},
450 { DEVICE_ATI_M11_NV_FIREGL
, R_350
},
451 { DEVICE_ATI_RV370_5B60_RADEON
, R_370
|R_PCIE
},
452 { DEVICE_ATI_RV370_SAPPHIRE_X550
, R_370
},
453 { DEVICE_ATI_RV370_5B64_FIREGL
, R_370
|R_PCIE
},
454 { DEVICE_ATI_RV370_5B65_FIREGL
, R_370
|R_PCIE
},
455 { DEVICE_ATI_M24_1P_RADEON
, R_370
},
456 { DEVICE_ATI_M22_RADEON_MOBILITY
, R_370
},
457 { DEVICE_ATI_M24_1T_FIREGL
, R_370
},
458 { DEVICE_ATI_M24_RADEON_MOBILITY
, R_370
},
459 { DEVICE_ATI_RV370_RADEON_X300SE
, R_370
},
460 { DEVICE_ATI_RV370_SECONDARY_SAPPHIRE
, R_370
},
461 { DEVICE_ATI_RV370_5B64_FIREGL2
, R_370
},
462 { DEVICE_ATI_RV380_0X3E50_RADEON
, R_380
|R_PCIE
},
463 { DEVICE_ATI_RV380_0X3E54_FIREGL
, R_380
|R_PCIE
},
464 { DEVICE_ATI_RV380_RADEON_X600
, R_380
|R_PCIE
},
465 { DEVICE_ATI_RV380_RADEON_X6002
, R_380
},
466 { DEVICE_ATI_RV380_RADEON_X6003
, R_380
},
467 { DEVICE_ATI_RV410_FIREGL_V5000
, R_420
},
468 { DEVICE_ATI_RV410_FIREGL_V3300
, R_420
},
469 { DEVICE_ATI_RV410_RADEON_X700XT
, R_420
},
470 { DEVICE_ATI_RV410_RADEON_X700
, R_420
|R_PCIE
},
471 { DEVICE_ATI_RV410_RADEON_X700SE
, R_420
},
472 { DEVICE_ATI_RV410_RADEON_X7002
, R_420
|R_PCIE
},
473 { DEVICE_ATI_RV410_RADEON_X7003
, R_420
},
474 { DEVICE_ATI_RV410_RADEON_X7004
, R_420
|R_PCIE
},
475 { DEVICE_ATI_RV410_RADEON_X7005
, R_420
|R_PCIE
},
476 { DEVICE_ATI_M26_MOBILITY_FIREGL
, R_420
},
477 { DEVICE_ATI_M26_MOBILITY_FIREGL2
, R_420
},
478 { DEVICE_ATI_M26_RADEON_MOBILITY
, R_420
},
479 { DEVICE_ATI_M26_RADEON_MOBILITY2
, R_420
},
480 { DEVICE_ATI_RADEON_MOBILITY_X700
, R_420
},
481 { DEVICE_ATI_R420_JH_RADEON
, R_420
|R_PCIE
},
482 { DEVICE_ATI_R420_JI_RADEON
, R_420
|R_PCIE
},
483 { DEVICE_ATI_R420_JJ_RADEON
, R_420
|R_PCIE
},
484 { DEVICE_ATI_R420_JK_RADEON
, R_420
|R_PCIE
},
485 { DEVICE_ATI_R420_JL_RADEON
, R_420
|R_PCIE
},
486 { DEVICE_ATI_R420_JM_FIREGL
, R_420
|R_PCIE
},
487 { DEVICE_ATI_M18_JN_RADEON
, R_420
|R_PCIE
},
488 { DEVICE_ATI_R420_JP_RADEON
, R_420
|R_PCIE
},
489 { DEVICE_ATI_R420_RADEON_X800
, R_420
|R_PCIE
},
490 { DEVICE_ATI_R420_RADEON_X8002
, R_420
|R_PCIE
},
491 { DEVICE_ATI_R420_RADEON_X8003
, R_420
|R_PCIE
},
492 { DEVICE_ATI_R420_RADEON_X8004
, R_420
|R_PCIE
},
493 { DEVICE_ATI_R420_RADEON_X8005
, R_420
|R_PCIE
},
494 { DEVICE_ATI_R420_JM_FIREGL
, R_420
|R_PCIE
},
495 { DEVICE_ATI_R423_5F57_RADEON
, R_420
|R_PCIE
},
496 { DEVICE_ATI_R423_5F57_RADEON2
, R_420
|R_PCIE
},
497 { DEVICE_ATI_R423_UH_RADEON
, R_420
|R_PCIE
},
498 { DEVICE_ATI_R423_UI_RADEON
, R_420
|R_PCIE
},
499 { DEVICE_ATI_R423_UJ_RADEON
, R_420
|R_PCIE
},
500 { DEVICE_ATI_R423_UK_RADEON
, R_420
|R_PCIE
},
501 { DEVICE_ATI_R423_FIRE_GL
, R_420
|R_PCIE
},
502 { DEVICE_ATI_R423_UQ_FIREGL
, R_420
|R_PCIE
},
503 { DEVICE_ATI_R423_UR_FIREGL
, R_420
|R_PCIE
},
504 { DEVICE_ATI_R423_UT_FIREGL
, R_420
|R_PCIE
},
505 { DEVICE_ATI_R423_UI_RADEON2
, R_420
|R_PCIE
},
506 { DEVICE_ATI_R423GL_SE_ATI_FIREGL
, R_420
|R_PCIE
},
507 { DEVICE_ATI_R423_RADEON_X800XT
, R_420
|R_PCIE
},
508 { DEVICE_ATI_RADEON_R423_UK
, R_420
|R_PCIE
},
509 { DEVICE_ATI_M28_RADEON_MOBILITY
, R_420
},
510 { DEVICE_ATI_M28_MOBILITY_FIREGL
, R_420
},
511 { DEVICE_ATI_MOBILITY_RADEON_X800
, R_420
},
512 { DEVICE_ATI_R430_RADEON_X800
, R_430
|R_PCIE
},
513 { DEVICE_ATI_R430_RADEON_X8002
, R_430
|R_PCIE
},
514 { DEVICE_ATI_R430_RADEON_X8003
, R_430
|R_PCIE
},
515 { DEVICE_ATI_R430_RADEON_X8004
, R_430
|R_PCIE
},
516 { DEVICE_ATI_R480_RADEON_X800
, R_480
},
517 { DEVICE_ATI_R480_RADEON_X8002
, R_480
},
518 { DEVICE_ATI_R480_RADEON_X850XT
, R_480
},
519 { DEVICE_ATI_R480_RADEON_X850PRO
, R_480
},
520 { DEVICE_ATI_R481_RADEON_X850XT_PE
, R_480
|R_PCIE
},
521 { DEVICE_ATI_R480_RADEON_X850XT2
, R_480
},
522 { DEVICE_ATI_R480_RADEON_X850PRO2
, R_480
},
523 { DEVICE_ATI_R481_RADEON_X850XT_PE2
, R_480
|R_PCIE
},
524 { DEVICE_ATI_R480_RADEON_X850XT3
, R_480
|R_PCIE
},
525 { DEVICE_ATI_R480_RADEON_X850XT4
, R_480
|R_PCIE
},
526 { DEVICE_ATI_R480_RADEON_X850XT5
, R_480
|R_PCIE
},
527 { DEVICE_ATI_R480_RADEON_X850XT6
, R_480
|R_PCIE
},
528 { DEVICE_ATI_R520_FIREGL
, R_520
},
529 { DEVICE_ATI_R520_GL_ATI
, R_520
},
530 { DEVICE_ATI_R520_GL_ATI2
, R_520
},
531 { DEVICE_ATI_R520_RADEON_X1800
, R_520
},
532 { DEVICE_ATI_R520_RADEON_X18002
, R_520
},
533 { DEVICE_ATI_R520_RADEON_X18003
, R_520
},
534 { DEVICE_ATI_R520_RADEON_X18004
, R_520
},
535 { DEVICE_ATI_R520_RADEON_X18005
, R_520
},
536 { DEVICE_ATI_R520_RADEON_X18006
, R_520
},
537 { DEVICE_ATI_R520_RADEON_X18007
, R_520
},
538 { DEVICE_ATI_M58_RADEON_MOBILITY
, R_520
},
539 { DEVICE_ATI_M58_RADEON_MOBILITY2
, R_520
},
540 { DEVICE_ATI_M58_MOBILITY_FIREGL
, R_520
},
541 { DEVICE_ATI_M58_MOBILITY_FIREGL2
, R_520
},
542 { DEVICE_ATI_RV515_RADEON_X1600
, R_520
},
543 { DEVICE_ATI_RV515_RADEON_X1300
, R_520
},
544 { DEVICE_ATI_RV515_RADEON_X13002
, R_520
},
545 { DEVICE_ATI_RV515_RADEON_X13003
, R_520
},
546 { DEVICE_ATI_RV515_RADEON_X13004
, R_520
},
547 { DEVICE_ATI_RV515_RADEON_X13005
, R_520
},
548 { DEVICE_ATI_RV515_RADEON_X13006
, R_520
},
549 { DEVICE_ATI_RV515_RADEON_X13007
, R_520
},
550 { DEVICE_ATI_RV515_GL_ATI
, R_520
},
551 { DEVICE_ATI_RV515_GL_ATI2
, R_520
},
552 { DEVICE_ATI_RADEON_MOBILITY_X1400
, R_520
},
553 { DEVICE_ATI_M52_ATI_MOBILITY
, R_520
},
554 { DEVICE_ATI_M52_ATI_MOBILITY2
, R_520
},
555 { DEVICE_ATI_M52_ATI_MOBILITY3
, R_520
},
556 { DEVICE_ATI_M52_ATI_MOBILITY4
, R_520
},
557 { DEVICE_ATI_RV516_RADEON_X1300
, R_520
},
558 { DEVICE_ATI_RV516_RADEON_X13002
, R_520
},
559 { DEVICE_ATI_RV516_XT_RADEON
, R_520
},
560 { DEVICE_ATI_RV516_XT_RADEON2
, R_520
},
561 { DEVICE_ATI_RV530_RADEON_X1600
, R_520
},
562 { DEVICE_ATI_RV530_RADEON_X16002
, R_520
},
563 { DEVICE_ATI_M56GL_ATI_MOBILITY
, R_520
},
564 { DEVICE_ATI_M56P_RADEON_MOBILITY
, R_520
},
565 { DEVICE_ATI_M66_P_ATI_MOBILITY
, R_520
},
566 { DEVICE_ATI_M66_XT_ATI_MOBILITY
, R_520
},
567 { DEVICE_ATI_RV530LE_RADEON_X1600
, R_520
},
568 { DEVICE_ATI_RV530LE_RADEON_X16002
, R_520
},
569 { DEVICE_ATI_RV530LE_RADEON_X16003
, R_520
},
570 { DEVICE_ATI_RV530_RADEON_X16003
, R_520
},
571 { DEVICE_ATI_RV530_RADEON_X16004
, R_520
},
572 { DEVICE_ATI_R580_RADEON_X1900
, R_520
},
573 { DEVICE_ATI_R580_RADEON_X19002
, R_520
},
574 { DEVICE_ATI_R580_RADEON_X19003
, R_520
},
575 { DEVICE_ATI_R580_RADEON_X19004
, R_520
},
576 { DEVICE_ATI_R580_RADEON_X19005
, R_520
},
577 { DEVICE_ATI_R580_RADEON_X19006
, R_520
},
578 { DEVICE_ATI_R580_RADEON_X19007
, R_520
},
579 { DEVICE_ATI_R580_RADEON_X19008
, R_520
},
580 { DEVICE_ATI_R580_RADEON_X19009
, R_520
},
581 { DEVICE_ATI_R580_RADEON_X190010
, R_520
},
582 { DEVICE_ATI_R580_RADEON_X190011
, R_520
},
583 { DEVICE_ATI_R580_RADEON_X190012
, R_520
},
584 { DEVICE_ATI_R580_RADEON_X190013
, R_520
},
585 { DEVICE_ATI_R580_RADEON_X190014
, R_520
},
586 { DEVICE_ATI_R580_RADEON_X190015
, R_520
},
587 { DEVICE_ATI_R580_FIREGL_V7300_V7350
, R_520
},
588 { DEVICE_ATI_R580_FIREGL_V7300_V73502
, R_520
},
593 static void * radeon_mmio_base
= 0;
594 static void * radeon_mem_base
= 0;
595 static int32_t radeon_overlay_off
= 0;
596 static uint32_t radeon_ram_size
= 0;
598 #define GETREG(TYPE,PTR,OFFZ) (*((volatile TYPE*)((PTR)+(OFFZ))))
599 #define SETREG(TYPE,PTR,OFFZ,VAL) (*((volatile TYPE*)((PTR)+(OFFZ))))=VAL
601 #define INREG8(addr) GETREG(uint8_t,(uint8_t *)(radeon_mmio_base),addr)
602 #define OUTREG8(addr,val) SETREG(uint8_t,(uint8_t *)(radeon_mmio_base),addr,val)
603 static inline uint32_t INREG (uint32_t addr
) {
604 uint32_t tmp
= GETREG(uint32_t,(uint8_t *)(radeon_mmio_base
),addr
);
605 return le2me_32(tmp
);
607 #define OUTREG(addr,val) SETREG(uint32_t,(uint8_t *)(radeon_mmio_base),addr,le2me_32(val))
608 #define OUTREGP(addr,val,mask) \
610 unsigned int _tmp = INREG(addr); \
613 OUTREG(addr, _tmp); \
616 static __inline__
uint32_t INPLL(uint32_t addr
)
618 OUTREG8(CLOCK_CNTL_INDEX
, addr
& 0x0000001f);
619 return (INREG(CLOCK_CNTL_DATA
));
622 #define OUTPLL(addr,val) OUTREG8(CLOCK_CNTL_INDEX, (addr & 0x0000001f) | 0x00000080); \
623 OUTREG(CLOCK_CNTL_DATA, val)
624 #define OUTPLLP(addr,val,mask) \
626 unsigned int _tmp = INPLL(addr); \
629 OUTPLL(addr, _tmp); \
636 MT_CRT
, /* CRT-(cathode ray tube) analog monitor. (15-pin VGA connector) */
637 MT_LCD
, /* Liquid Crystal Display */
638 MT_DFP
, /* DFP-digital flat panel monitor. (24-pin DVI-I connector) */
639 MT_CTV
, /* Composite TV out (not in VE) */
640 MT_STV
/* S-Video TV out (probably in VE only) */
643 typedef struct radeon_info_s
650 static rinfo_t rinfo
;
652 static char * GET_MON_NAME(int type
)
657 case MT_NONE
: pret
= "no"; break;
658 case MT_CRT
: pret
= "CRT"; break;
659 case MT_DFP
: pret
= "DFP"; break;
660 case MT_LCD
: pret
= "LCD"; break;
661 case MT_CTV
: pret
= "CTV"; break;
662 case MT_STV
: pret
= "STV"; break;
663 default: pret
= "Unknown";
668 static void radeon_get_moninfo (rinfo_t
*rinfo
)
672 tmp
= INREG(RADEON_BIOS_4_SCRATCH
);
674 if (rinfo
->hasCRTC2
) {
675 /* primary DVI port */
677 rinfo
->dviDispType
= MT_DFP
;
679 rinfo
->dviDispType
= MT_LCD
;
680 else if (tmp
& 0x200)
681 rinfo
->dviDispType
= MT_CRT
;
683 rinfo
->dviDispType
= MT_CTV
;
685 rinfo
->dviDispType
= MT_STV
;
687 /* secondary CRT port */
689 rinfo
->crtDispType
= MT_CRT
;
690 else if (tmp
& 0x800)
691 rinfo
->crtDispType
= MT_DFP
;
692 else if (tmp
& 0x400)
693 rinfo
->crtDispType
= MT_LCD
;
694 else if (tmp
& 0x1000)
695 rinfo
->crtDispType
= MT_CTV
;
696 else if (tmp
& 0x2000)
697 rinfo
->crtDispType
= MT_STV
;
699 rinfo
->dviDispType
= MT_NONE
;
701 tmp
= INREG(FP_GEN_CNTL
);
703 if (tmp
& FP_EN_TMDS
)
704 rinfo
->crtDispType
= MT_DFP
;
706 rinfo
->crtDispType
= MT_CRT
;
711 static uint32_t radeon_vid_get_dbpp( void )
713 uint32_t dbpp
,retval
;
714 dbpp
= (INREG(CRTC_GEN_CNTL
)>>8)& 0xF;
717 case DST_8BPP
: retval
= 8; break;
718 case DST_15BPP
: retval
= 15; break;
719 case DST_16BPP
: retval
= 16; break;
720 case DST_24BPP
: retval
= 24; break;
721 default: retval
=32; break;
726 static int radeon_is_dbl_scan( void )
728 return (INREG(CRTC_GEN_CNTL
))&CRTC_DBL_SCAN_EN
;
731 static int radeon_is_interlace( void )
733 return (INREG(CRTC_GEN_CNTL
))&CRTC_INTERLACE_EN
;
736 static uint32_t radeon_get_xres( void )
738 uint32_t xres
,h_total
;
741 (rinfo
.dviDispType
== MT_CTV
|| rinfo
.dviDispType
== MT_STV
))
742 h_total
= INREG(CRTC2_H_TOTAL_DISP
);
745 h_total
= INREG(CRTC_H_TOTAL_DISP
);
746 xres
= (h_total
>> 16) & 0xffff;
750 static uint32_t radeon_get_yres( void )
752 uint32_t yres
,v_total
;
755 (rinfo
.dviDispType
== MT_CTV
|| rinfo
.dviDispType
== MT_STV
))
756 v_total
= INREG(CRTC2_V_TOTAL_DISP
);
759 v_total
= INREG(CRTC_V_TOTAL_DISP
);
760 yres
= (v_total
>> 16) & 0xffff;
764 static void radeon_wait_vsync(void)
768 OUTREG(GEN_INT_STATUS
, VSYNC_INT_AK
);
769 for (i
= 0; i
< 2000000; i
++)
771 if (INREG(GEN_INT_STATUS
) & VSYNC_INT
) break;
776 static void _radeon_engine_idle(void);
777 static void _radeon_fifo_wait(unsigned);
778 #define radeon_engine_idle() _radeon_engine_idle()
779 #define radeon_fifo_wait(entries) _radeon_fifo_wait(entries)
780 /* Flush all dirty data in the Pixel Cache to memory. */
781 static __inline__
void radeon_engine_flush ( void )
785 OUTREGP(PC_NGUI_CTLSTAT
, PC_FLUSH_ALL
, ~PC_FLUSH_ALL
);
786 for (i
= 0; i
< 2000000; i
++) {
787 if (!(INREG(PC_NGUI_CTLSTAT
) & PC_BUSY
)) break;
791 /* Reset graphics card to known state. */
792 static void radeon_engine_reset( void )
794 uint32_t clock_cntl_index
;
796 uint32_t gen_reset_cntl
;
798 radeon_engine_flush();
800 clock_cntl_index
= INREG(CLOCK_CNTL_INDEX
);
801 mclk_cntl
= INPLL(MCLK_CNTL
);
803 OUTPLL(MCLK_CNTL
, mclk_cntl
| FORCE_GCP
| FORCE_PIPE3D_CP
);
805 gen_reset_cntl
= INREG(GEN_RESET_CNTL
);
807 OUTREG(GEN_RESET_CNTL
, gen_reset_cntl
| SOFT_RESET_GUI
);
808 INREG(GEN_RESET_CNTL
);
809 OUTREG(GEN_RESET_CNTL
,
810 gen_reset_cntl
& (uint32_t)(~SOFT_RESET_GUI
));
811 INREG(GEN_RESET_CNTL
);
813 OUTPLL(MCLK_CNTL
, mclk_cntl
);
814 OUTREG(CLOCK_CNTL_INDEX
, clock_cntl_index
);
815 OUTREG(GEN_RESET_CNTL
, gen_reset_cntl
);
819 static __inline__
void radeon_engine_flush ( void )
824 OUTREGP(RB2D_DSTCACHE_CTLSTAT
, RB2D_DC_FLUSH_ALL
,
827 for (i
=0; i
< 2000000; i
++) {
828 if (!(INREG(RB2D_DSTCACHE_CTLSTAT
) & RB2D_DC_BUSY
))
833 static void _radeon_engine_idle(void);
834 static void _radeon_fifo_wait(unsigned);
835 #define radeon_engine_idle() _radeon_engine_idle()
836 #define radeon_fifo_wait(entries) _radeon_fifo_wait(entries)
838 static void radeon_engine_reset( void )
840 uint32_t clock_cntl_index
, mclk_cntl
, rbbm_soft_reset
;
842 radeon_engine_flush ();
844 clock_cntl_index
= INREG(CLOCK_CNTL_INDEX
);
845 mclk_cntl
= INPLL(MCLK_CNTL
);
847 OUTPLL(MCLK_CNTL
, (mclk_cntl
|
854 rbbm_soft_reset
= INREG(RBBM_SOFT_RESET
);
856 OUTREG(RBBM_SOFT_RESET
, rbbm_soft_reset
|
865 INREG(RBBM_SOFT_RESET
);
866 OUTREG(RBBM_SOFT_RESET
, rbbm_soft_reset
& (uint32_t)
875 INREG(RBBM_SOFT_RESET
);
877 OUTPLL(MCLK_CNTL
, mclk_cntl
);
878 OUTREG(CLOCK_CNTL_INDEX
, clock_cntl_index
);
879 OUTREG(RBBM_SOFT_RESET
, rbbm_soft_reset
);
884 static void radeon_engine_restore( void )
888 uint32_t xres
,yres
,bpp
;
890 xres
= radeon_get_xres();
891 yres
= radeon_get_yres();
892 bpp
= radeon_vid_get_dbpp();
893 /* turn of all automatic flushing - we'll do it all */
894 OUTREG(RB2D_DSTCACHE_MODE
, 0);
896 pitch64
= ((xres
* (bpp
/ 8) + 0x3f)) >> 6;
899 OUTREG(DEFAULT_OFFSET
, (INREG(DEFAULT_OFFSET
) & 0xC0000000) |
903 #if defined(WORDS_BIGENDIAN)
905 HOST_BIG_ENDIAN_EN
, ~HOST_BIG_ENDIAN_EN
);
907 OUTREGP(DP_DATATYPE
, 0, ~HOST_BIG_ENDIAN_EN
);
911 OUTREG(DEFAULT_SC_BOTTOM_RIGHT
, (DEFAULT_SC_RIGHT_MAX
912 | DEFAULT_SC_BOTTOM_MAX
));
914 OUTREG(DP_GUI_MASTER_CNTL
, (INREG(DP_GUI_MASTER_CNTL
)
915 | GMC_BRUSH_SOLID_COLOR
916 | GMC_SRC_DATATYPE_COLOR
));
919 OUTREG(DST_LINE_START
, 0);
920 OUTREG(DST_LINE_END
, 0);
921 OUTREG(DP_BRUSH_FRGD_CLR
, 0xffffffff);
922 OUTREG(DP_BRUSH_BKGD_CLR
, 0x00000000);
923 OUTREG(DP_SRC_FRGD_CLR
, 0xffffffff);
924 OUTREG(DP_SRC_BKGD_CLR
, 0x00000000);
925 OUTREG(DP_WRITE_MASK
, 0xffffffff);
927 radeon_engine_idle();
931 static void _radeon_fifo_wait (unsigned entries
)
937 for (i
=0; i
<2000000; i
++)
938 if ((INREG(GUI_STAT
) & GUI_FIFOCNT_MASK
) >= entries
)
940 radeon_engine_reset();
941 radeon_engine_restore();
945 static void _radeon_engine_idle ( void )
949 /* ensure FIFO is empty before waiting for idle */
950 radeon_fifo_wait (64);
953 for (i
=0; i
<2000000; i
++) {
954 if ((INREG(GUI_STAT
) & GUI_ACTIVE
) == 0) {
955 radeon_engine_flush ();
959 radeon_engine_reset();
960 radeon_engine_restore();
964 static void _radeon_fifo_wait (unsigned entries
)
970 for (i
=0; i
<2000000; i
++)
971 if ((INREG(RBBM_STATUS
) & RBBM_FIFOCNT_MASK
) >= entries
)
973 radeon_engine_reset();
974 radeon_engine_restore();
977 static void _radeon_engine_idle ( void )
981 /* ensure FIFO is empty before waiting for idle */
982 radeon_fifo_wait (64);
985 for (i
=0; i
<2000000; i
++) {
986 if (((INREG(RBBM_STATUS
) & RBBM_ACTIVE
)) == 0) {
987 radeon_engine_flush ();
991 radeon_engine_reset();
992 radeon_engine_restore();
998 /* Reference color space transform data */
999 typedef struct tagREF_TRANSFORM
1010 /* Parameters for ITU-R BT.601 and ITU-R BT.709 colour spaces */
1011 REF_TRANSFORM trans
[2] =
1013 {1.1678, 0.0, 1.6007, -0.3929, -0.8154, 2.0232, 0.0}, /* BT.601 */
1014 {1.1678, 0.0, 1.7980, -0.2139, -0.5345, 2.1186, 0.0} /* BT.709 */
1016 /****************************************************************************
1018 * Function: Calculates and sets color space transform from supplied *
1019 * reference transform, gamma, brightness, contrast, hue and *
1021 * Inputs: bright - brightness *
1023 * sat - saturation *
1025 * red_intensity - intense of red component *
1026 * green_intensity - intense of green component *
1027 * blue_intensity - intense of blue component *
1028 * ref - index to the table of refernce transforms *
1030 ****************************************************************************/
1032 static void radeon_set_transform(float bright
, float cont
, float sat
,
1033 float hue
, float red_intensity
,
1034 float green_intensity
,float blue_intensity
,
1037 float OvHueSin
, OvHueCos
;
1038 float CAdjLuma
, CAdjOff
;
1039 float RedAdj
,GreenAdj
,BlueAdj
;
1040 float CAdjRCb
, CAdjRCr
;
1041 float CAdjGCb
, CAdjGCr
;
1042 float CAdjBCb
, CAdjBCr
;
1043 float OvLuma
, OvROff
, OvGOff
, OvBOff
;
1048 float Coff
= 512.0f
;
1050 uint32_t dwOvLuma
, dwOvROff
, dwOvGOff
, dwOvBOff
;
1051 uint32_t dwOvRCb
, dwOvRCr
;
1052 uint32_t dwOvGCb
, dwOvGCr
;
1053 uint32_t dwOvBCb
, dwOvBCr
;
1055 if (ref
>= 2) return;
1057 OvHueSin
= sin((double)hue
);
1058 OvHueCos
= cos((double)hue
);
1060 CAdjLuma
= cont
* trans
[ref
].RefLuma
;
1061 CAdjOff
= cont
* trans
[ref
].RefLuma
* bright
* 1023.0;
1062 RedAdj
= cont
* trans
[ref
].RefLuma
* red_intensity
* 1023.0;
1063 GreenAdj
= cont
* trans
[ref
].RefLuma
* green_intensity
* 1023.0;
1064 BlueAdj
= cont
* trans
[ref
].RefLuma
* blue_intensity
* 1023.0;
1066 CAdjRCb
= sat
* -OvHueSin
* trans
[ref
].RefRCr
;
1067 CAdjRCr
= sat
* OvHueCos
* trans
[ref
].RefRCr
;
1068 CAdjGCb
= sat
* (OvHueCos
* trans
[ref
].RefGCb
- OvHueSin
* trans
[ref
].RefGCr
);
1069 CAdjGCr
= sat
* (OvHueSin
* trans
[ref
].RefGCb
+ OvHueCos
* trans
[ref
].RefGCr
);
1070 CAdjBCb
= sat
* OvHueCos
* trans
[ref
].RefBCb
;
1071 CAdjBCr
= sat
* OvHueSin
* trans
[ref
].RefBCb
;
1080 OvROff
= RedAdj
+ CAdjOff
-
1081 OvLuma
* Loff
- (OvRCb
+ OvRCr
) * Coff
;
1082 OvGOff
= GreenAdj
+ CAdjOff
-
1083 OvLuma
* Loff
- (OvGCb
+ OvGCr
) * Coff
;
1084 OvBOff
= BlueAdj
+ CAdjOff
-
1085 OvLuma
* Loff
- (OvBCb
+ OvBCr
) * Coff
;
1087 dwOvROff
= ((int)(OvROff
* 2.0)) & 0x1fff;
1088 dwOvGOff
= (int)(OvGOff
* 2.0) & 0x1fff;
1089 dwOvBOff
= (int)(OvBOff
* 2.0) & 0x1fff;
1090 /* Whatever docs say about R200 having 3.8 format instead of 3.11
1091 as in Radeon is a lie */
1093 dwOvLuma
=(((int)(OvLuma
* 2048.0))&0x7fff)<<17;
1094 dwOvRCb
= (((int)(OvRCb
* 2048.0))&0x7fff)<<1;
1095 dwOvRCr
= (((int)(OvRCr
* 2048.0))&0x7fff)<<17;
1096 dwOvGCb
= (((int)(OvGCb
* 2048.0))&0x7fff)<<1;
1097 dwOvGCr
= (((int)(OvGCr
* 2048.0))&0x7fff)<<17;
1098 dwOvBCb
= (((int)(OvBCb
* 2048.0))&0x7fff)<<1;
1099 dwOvBCr
= (((int)(OvBCr
* 2048.0))&0x7fff)<<17;
1101 OUTREG(OV0_LIN_TRANS_A
, dwOvRCb
| dwOvLuma
);
1102 OUTREG(OV0_LIN_TRANS_B
, dwOvROff
| dwOvRCr
);
1103 OUTREG(OV0_LIN_TRANS_C
, dwOvGCb
| dwOvLuma
);
1104 OUTREG(OV0_LIN_TRANS_D
, dwOvGOff
| dwOvGCr
);
1105 OUTREG(OV0_LIN_TRANS_E
, dwOvBCb
| dwOvLuma
);
1106 OUTREG(OV0_LIN_TRANS_F
, dwOvBOff
| dwOvBCr
);
1109 /* Gamma curve definition */
1112 unsigned int gammaReg
;
1113 unsigned int gammaSlope
;
1114 unsigned int gammaOffset
;
1117 /* Recommended gamma curve parameters */
1118 GAMMA_SETTINGS r200_def_gamma
[18] =
1120 {OV0_GAMMA_0_F
, 0x100, 0x0000},
1121 {OV0_GAMMA_10_1F
, 0x100, 0x0020},
1122 {OV0_GAMMA_20_3F
, 0x100, 0x0040},
1123 {OV0_GAMMA_40_7F
, 0x100, 0x0080},
1124 {OV0_GAMMA_80_BF
, 0x100, 0x0100},
1125 {OV0_GAMMA_C0_FF
, 0x100, 0x0100},
1126 {OV0_GAMMA_100_13F
, 0x100, 0x0200},
1127 {OV0_GAMMA_140_17F
, 0x100, 0x0200},
1128 {OV0_GAMMA_180_1BF
, 0x100, 0x0300},
1129 {OV0_GAMMA_1C0_1FF
, 0x100, 0x0300},
1130 {OV0_GAMMA_200_23F
, 0x100, 0x0400},
1131 {OV0_GAMMA_240_27F
, 0x100, 0x0400},
1132 {OV0_GAMMA_280_2BF
, 0x100, 0x0500},
1133 {OV0_GAMMA_2C0_2FF
, 0x100, 0x0500},
1134 {OV0_GAMMA_300_33F
, 0x100, 0x0600},
1135 {OV0_GAMMA_340_37F
, 0x100, 0x0600},
1136 {OV0_GAMMA_380_3BF
, 0x100, 0x0700},
1137 {OV0_GAMMA_3C0_3FF
, 0x100, 0x0700}
1140 GAMMA_SETTINGS r100_def_gamma
[6] =
1142 {OV0_GAMMA_0_F
, 0x100, 0x0000},
1143 {OV0_GAMMA_10_1F
, 0x100, 0x0020},
1144 {OV0_GAMMA_20_3F
, 0x100, 0x0040},
1145 {OV0_GAMMA_40_7F
, 0x100, 0x0080},
1146 {OV0_GAMMA_380_3BF
, 0x100, 0x0100},
1147 {OV0_GAMMA_3C0_3FF
, 0x100, 0x0100}
1150 static void make_default_gamma_correction( void )
1153 if((besr
.chip_flags
& R_100
)==R_100
||
1154 (besr
.chip_flags
& R_120
)==R_120
||
1155 (besr
.chip_flags
& R_150
)==R_150
){
1156 OUTREG(OV0_LIN_TRANS_A
, 0x12A00000);
1157 OUTREG(OV0_LIN_TRANS_B
, 0x199018FE);
1158 OUTREG(OV0_LIN_TRANS_C
, 0x12A0F9B0);
1159 OUTREG(OV0_LIN_TRANS_D
, 0xF2F0043B);
1160 OUTREG(OV0_LIN_TRANS_E
, 0x12A02050);
1161 OUTREG(OV0_LIN_TRANS_F
, 0x0000174E);
1163 OUTREG(r100_def_gamma
[i
].gammaReg
,
1164 (r100_def_gamma
[i
].gammaSlope
<<16) |
1165 r100_def_gamma
[i
].gammaOffset
);
1169 OUTREG(OV0_LIN_TRANS_A
, 0x12a20000);
1170 OUTREG(OV0_LIN_TRANS_B
, 0x198a190e);
1171 OUTREG(OV0_LIN_TRANS_C
, 0x12a2f9da);
1172 OUTREG(OV0_LIN_TRANS_D
, 0xf2fe0442);
1173 OUTREG(OV0_LIN_TRANS_E
, 0x12a22046);
1174 OUTREG(OV0_LIN_TRANS_F
, 0x175f);
1176 Of 18 segments for gamma cure, all segments in R200 are programmable,
1177 while only lower 4 and upper 2 segments are programmable in Radeon*/
1178 for(i
=0; i
<18; i
++){
1179 OUTREG(r200_def_gamma
[i
].gammaReg
,
1180 (r200_def_gamma
[i
].gammaSlope
<<16) |
1181 r200_def_gamma
[i
].gammaOffset
);
1187 static void radeon_vid_make_default(void)
1190 besr
.saturation
= 0x0F;
1191 besr
.brightness
= 0;
1192 OUTREG(OV0_COLOUR_CNTL
,0x000F0F00UL
); /* Default brihgtness and saturation for Rage128 */
1194 make_default_gamma_correction();
1196 besr
.deinterlace_pattern
= 0x900AAAAA;
1197 OUTREG(OV0_DEINTERLACE_PATTERN
,besr
.deinterlace_pattern
);
1198 besr
.deinterlace_on
=1;
1201 besr
.graphics_key_msk
=0;
1202 besr
.graphics_key_clr
=0;
1203 besr
.ckey_cntl
= VIDEO_KEY_FN_TRUE
|GRAPHIC_KEY_FN_TRUE
|CMP_MIX_AND
;
1206 static int find_chip(unsigned chip_id
)
1209 for(i
= 0;i
< sizeof(ati_card_ids
)/sizeof(ati_card_ids_t
);i
++)
1211 if(chip_id
== ati_card_ids
[i
].id
) return i
;
1216 static pciinfo_t pci_info
;
1217 static int probed
=0;
1219 static vidix_capability_t def_cap
=
1222 "BES driver for Rage128 cards",
1224 "BES driver for Radeon cards",
1227 TYPE_OUTPUT
| TYPE_FX
,
1234 FLAG_UPSCALER
| FLAG_DOWNSCALER
| FLAG_EQUALIZER
,
1240 #if !defined(RAGE128) && defined(HAVE_X11)
1241 static void probe_fireGL_driver(void) {
1242 Display
*dp
= XOpenDisplay ((void*)0);
1248 extlist
= XListExtensions (dp
, &n
);
1252 int ext_fgl
= 0, ext_fglrx
= 0;
1253 for (i
= 0; i
< n
; i
++) {
1254 if (!strcmp(extlist
[i
], "ATIFGLEXTENSION")) ext_fgl
= 1;
1255 if (!strcmp(extlist
[i
], "ATIFGLRXDRI")) ext_fglrx
= 1;
1258 printf(RADEON_MSG
" ATI FireGl driver detected");
1259 firegl_shift
= 0x500000;
1261 printf(", but DRI seems not to be activated\n");
1262 printf(RADEON_MSG
" Output may not work correctly, check your DRI configration!");
1270 static int radeon_probe(int verbose
, int force
)
1272 pciinfo_t lst
[MAX_PCI_DEVICES
];
1275 __verbose
= verbose
;
1276 err
= pci_scan(lst
,&num_pci
);
1279 printf(RADEON_MSG
" Error occurred during pci scan: %s\n",strerror(err
));
1285 for(i
=0;i
<num_pci
;i
++)
1287 if(lst
[i
].vendor
== VENDOR_ATI
)
1291 idx
= find_chip(lst
[i
].device
);
1292 if(idx
== -1 && force
== PROBE_NORMAL
) continue;
1293 dname
= pci_device_name(VENDOR_ATI
,lst
[i
].device
);
1294 dname
= dname
? dname
: "Unknown chip";
1295 printf(RADEON_MSG
" Found chip: %s\n",dname
);
1297 if ((lst
[i
].command
& PCI_COMMAND_IO
) == 0)
1299 printf("[radeon] Device is disabled, ignoring\n");
1303 memset(&besr
,0,sizeof(bes_registers_t
));
1304 if(force
> PROBE_NORMAL
)
1306 printf(RADEON_MSG
" Driver was forced. Was found %sknown chip\n",idx
== -1 ? "un" : "");
1309 printf(RADEON_MSG
" Assuming it as Rage128\n");
1311 printf(RADEON_MSG
" Assuming it as Radeon1\n");
1313 besr
.chip_flags
=R_100
|R_OVL_SHIFT
;
1315 #if !defined(RAGE128) && defined(HAVE_X11)
1316 probe_fireGL_driver();
1318 if(idx
!= -1) besr
.chip_flags
=ati_card_ids
[idx
].flags
;
1319 def_cap
.device_id
= lst
[i
].device
;
1321 memcpy(&pci_info
,&lst
[i
],sizeof(pciinfo_t
));
1327 if(err
&& verbose
) printf(RADEON_MSG
" Can't find chip\n");
1331 typedef struct saved_regs_s
1333 uint32_t ov0_vid_key_clr
;
1334 uint32_t ov0_vid_key_msk
;
1335 uint32_t ov0_graphics_key_clr
;
1336 uint32_t ov0_graphics_key_msk
;
1337 uint32_t ov0_key_cntl
;
1338 uint32_t disp_merge_cntl
;
1340 static saved_regs_t savreg
;
1342 static void save_regs( void )
1344 radeon_fifo_wait(6);
1345 savreg
.ov0_vid_key_clr
= INREG(OV0_VID_KEY_CLR
);
1346 savreg
.ov0_vid_key_msk
= INREG(OV0_VID_KEY_MSK
);
1347 savreg
.ov0_graphics_key_clr
= INREG(OV0_GRAPHICS_KEY_CLR
);
1348 savreg
.ov0_graphics_key_msk
= INREG(OV0_GRAPHICS_KEY_MSK
);
1349 savreg
.ov0_key_cntl
= INREG(OV0_KEY_CNTL
);
1350 savreg
.disp_merge_cntl
= INREG(DISP_MERGE_CNTL
);
1353 static void restore_regs( void )
1355 radeon_fifo_wait(6);
1356 OUTREG(OV0_VID_KEY_CLR
,savreg
.ov0_vid_key_clr
);
1357 OUTREG(OV0_VID_KEY_MSK
,savreg
.ov0_vid_key_msk
);
1358 OUTREG(OV0_GRAPHICS_KEY_CLR
,savreg
.ov0_graphics_key_clr
);
1359 OUTREG(OV0_GRAPHICS_KEY_MSK
,savreg
.ov0_graphics_key_msk
);
1360 OUTREG(OV0_KEY_CNTL
,savreg
.ov0_key_cntl
);
1361 OUTREG(DISP_MERGE_CNTL
,savreg
.disp_merge_cntl
);
1364 static int radeon_init(void)
1368 if(__verbose
>0) printf("[radeon_vid] version %d\n", VIDIX_VERSION
);
1372 printf(RADEON_MSG
" Driver was not probed but is being initializing\n");
1375 if((radeon_mmio_base
= map_phys_mem(pci_info
.base2
,0xFFFF))==(void *)-1) return ENOMEM
;
1376 radeon_ram_size
= INREG(CONFIG_MEMSIZE
);
1377 /* mem size is bits [28:0], mask off the rest. Range: from 1Mb up to 512 Mb */
1378 radeon_ram_size
&= CONFIG_MEMSIZE_MASK
;
1380 /* according to XFree86 4.2.0, some production M6's return 0 for 8MB */
1381 if (radeon_ram_size
== 0 &&
1382 (def_cap
.device_id
== DEVICE_ATI_RADEON_MOBILITY_M6
||
1383 def_cap
.device_id
== DEVICE_ATI_RADEON_MOBILITY_M62
))
1385 printf(RADEON_MSG
" Working around buggy Radeon Mobility M6 (0 vs. 8MB ram)\n");
1386 radeon_ram_size
= 8192*1024;
1388 else if (radeon_ram_size
== 0 &&
1389 (def_cap
.device_id
== DEVICE_ATI_RS482_RADEON_XPRESS
))
1391 printf(RADEON_MSG
" Working around buggy RS482 Radeon Xpress 200 Memory Detection\n");
1392 radeon_ram_size
= (INREG(CONFIG_MEMSIZE
) + 0x100000) << 2;
1393 radeon_ram_size
&= CONFIG_MEMSIZE_MASK
;
1396 /* Rage Mobility (rage128) also has memsize bug */
1397 if (radeon_ram_size
== 0 &&
1398 (def_cap
.device_id
== DEVICE_ATI_RAGE_MOBILITY_M3
||
1399 def_cap
.device_id
== DEVICE_ATI_RAGE_MOBILITY_M32
))
1401 printf(RADEON_MSG
" Working around Rage Mobility M3 (0 vs. 8MB ram)\n");
1402 radeon_ram_size
= 8192*1024;
1405 if((radeon_mem_base
= map_phys_mem(pci_info
.base0
,radeon_ram_size
))==(void *)-1) return ENOMEM
;
1406 radeon_vid_make_default();
1407 printf(RADEON_MSG
" Video memory = %uMb\n",radeon_ram_size
/0x100000);
1408 err
= mtrr_set_type(pci_info
.base0
,radeon_ram_size
,MTRR_TYPE_WRCOMB
);
1409 if(!err
) printf(RADEON_MSG
" Set write-combining type of video memory\n");
1412 memset(&rinfo
,0,sizeof(rinfo_t
));
1413 if((besr
.chip_flags
&R_100
) != R_100
) rinfo
.hasCRTC2
= 1;
1415 radeon_get_moninfo(&rinfo
);
1416 if(rinfo
.hasCRTC2
) {
1417 printf(RADEON_MSG
" DVI port has %s monitor connected\n",GET_MON_NAME(rinfo
.dviDispType
));
1418 printf(RADEON_MSG
" CRT port has %s monitor connected\n",GET_MON_NAME(rinfo
.crtDispType
));
1421 printf(RADEON_MSG
" CRT port has %s monitor connected\n",GET_MON_NAME(rinfo
.crtDispType
));
1428 static void radeon_destroy(void)
1431 unmap_phys_mem(radeon_mem_base
,radeon_ram_size
);
1432 unmap_phys_mem(radeon_mmio_base
,0xFFFF);
1435 static int radeon_get_caps(vidix_capability_t
*to
)
1437 memcpy(to
,&def_cap
,sizeof(vidix_capability_t
));
1442 Full list of fourcc which are supported by Win2K radeon driver:
1443 YUY2, UYVY, DDES, OGLT, OGL2, OGLS, OGLB, OGNT, OGNZ, OGNS,
1444 IF09, YVU9, IMC4, M2IA, IYUV, VBID, DXT1, DXT2, DXT3, DXT4, DXT5
1446 typedef struct fourcc_desc_s
1452 static fourcc_desc_t supported_fourcc
[] =
1454 { IMGFMT_Y800
, 1567 },
1455 { IMGFMT_YVU9
, 1567 },
1456 { IMGFMT_IF09
, 1567 },
1457 { IMGFMT_YV12
, 1567 },
1458 { IMGFMT_I420
, 1567 },
1459 { IMGFMT_IYUV
, 1567 },
1460 { IMGFMT_UYVY
, 1551 },
1461 { IMGFMT_YUY2
, 1551 },
1462 { IMGFMT_YVYU
, 1551 },
1463 { IMGFMT_RGB15
, 1551 },
1464 { IMGFMT_BGR15
, 1551 },
1465 { IMGFMT_RGB16
, 1551 },
1466 { IMGFMT_BGR16
, 1551 },
1467 { IMGFMT_RGB32
, 775 },
1468 { IMGFMT_BGR32
, 775 }
1471 __inline__
static int is_supported_fourcc(uint32_t fourcc
)
1474 for(i
=0;i
<sizeof(supported_fourcc
)/sizeof(fourcc_desc_t
);i
++)
1476 if(fourcc
==supported_fourcc
[i
].fourcc
)
1482 static int radeon_query_fourcc(vidix_fourcc_t
*to
)
1484 if(is_supported_fourcc(to
->fourcc
))
1486 to
->depth
= VID_DEPTH_ALL
;
1487 to
->flags
= VID_CAP_EXPAND
| VID_CAP_SHRINK
| VID_CAP_COLORKEY
|
1491 else to
->depth
= to
->flags
= 0;
1495 static double H_scale_ratio
;
1496 static void radeon_vid_dump_regs( void )
1499 printf(RADEON_MSG
"*** Begin of DRIVER variables dump ***\n");
1500 printf(RADEON_MSG
"radeon_mmio_base=%p\n",radeon_mmio_base
);
1501 printf(RADEON_MSG
"radeon_mem_base=%p\n",radeon_mem_base
);
1502 printf(RADEON_MSG
"radeon_overlay_off=%08X\n",radeon_overlay_off
);
1503 printf(RADEON_MSG
"radeon_ram_size=%08X\n",radeon_ram_size
);
1504 printf(RADEON_MSG
"video mode: %ux%u@%u\n",radeon_get_xres(),radeon_get_yres(),radeon_vid_get_dbpp());
1505 printf(RADEON_MSG
"H_scale_ratio=%8.2f\n",H_scale_ratio
);
1506 printf(RADEON_MSG
"*** Begin of OV0 registers dump ***\n");
1507 for(i
=0;i
<sizeof(vregs
)/sizeof(video_registers_t
);i
++)
1508 printf(RADEON_MSG
"%s = %08X\n",vregs
[i
].sname
,INREG(vregs
[i
].name
));
1509 printf(RADEON_MSG
"*** End of OV0 registers dump ***\n");
1512 static void radeon_vid_stop_video( void )
1514 radeon_engine_idle();
1515 OUTREG(OV0_SCALE_CNTL
, SCALER_SOFT_RESET
);
1516 OUTREG(OV0_EXCLUSIVE_HORZ
, 0);
1517 OUTREG(OV0_AUTO_FLIP_CNTL
, 0); /* maybe */
1518 OUTREG(OV0_FILTER_CNTL
, FILTER_HARDCODED_COEF
);
1520 OUTREG(OV0_KEY_CNTL
, GRAPHIC_KEY_FN_NE
);
1522 OUTREG(OV0_KEY_CNTL
, GRAPHIC_KEY_FN_EQ
);
1524 OUTREG(OV0_TEST
, 0);
1527 static void radeon_vid_display_video( void )
1529 int bes_flags
,force_second
;
1530 radeon_fifo_wait(2);
1531 OUTREG(OV0_REG_LOAD_CNTL
, REG_LD_CTL_LOCK
);
1532 radeon_engine_idle();
1533 while(!(INREG(OV0_REG_LOAD_CNTL
)®_LD_CTL_LOCK_READBACK
));
1534 radeon_fifo_wait(15);
1538 /* Shutdown capturing */
1539 OUTREG(FCP_CNTL
, FCP_CNTL__GND
);
1540 OUTREG(CAP0_TRIG_CNTL
, 0);
1542 OUTREG(VID_BUFFER_CONTROL
, (1<<16) | 0x01);
1543 OUTREG(DISP_TEST_DEBUG_CNTL
, 0);
1545 OUTREG(OV0_AUTO_FLIP_CNTL
,OV0_AUTO_FLIP_CNTL_SOFT_BUF_ODD
);
1547 if(besr
.deinterlace_on
) OUTREG(OV0_DEINTERLACE_PATTERN
,besr
.deinterlace_pattern
);
1549 OUTREG(OV0_COLOUR_CNTL
, (besr
.brightness
& 0x7f) |
1550 (besr
.saturation
<< 8) |
1551 (besr
.saturation
<< 16));
1553 radeon_fifo_wait(2);
1554 OUTREG(OV0_GRAPHICS_KEY_MSK
, besr
.graphics_key_msk
);
1555 OUTREG(OV0_GRAPHICS_KEY_CLR
, besr
.graphics_key_clr
);
1556 OUTREG(OV0_KEY_CNTL
,besr
.ckey_cntl
);
1558 OUTREG(OV0_H_INC
, besr
.h_inc
);
1559 OUTREG(OV0_STEP_BY
, besr
.step_by
);
1562 OUTREG(OV1_Y_X_START
, besr
.y_x_start
);
1563 OUTREG(OV1_Y_X_END
, besr
.y_x_end
);
1567 OUTREG(OV0_Y_X_START
, besr
.y_x_start
);
1568 OUTREG(OV0_Y_X_END
, besr
.y_x_end
);
1570 OUTREG(OV0_V_INC
, besr
.v_inc
);
1571 OUTREG(OV0_P1_BLANK_LINES_AT_TOP
, besr
.p1_blank_lines_at_top
);
1572 OUTREG(OV0_P23_BLANK_LINES_AT_TOP
, besr
.p23_blank_lines_at_top
);
1573 OUTREG(OV0_VID_BUF_PITCH0_VALUE
, besr
.vid_buf_pitch0_value
);
1574 OUTREG(OV0_VID_BUF_PITCH1_VALUE
, besr
.vid_buf_pitch1_value
);
1575 OUTREG(OV0_P1_X_START_END
, besr
.p1_x_start_end
);
1576 OUTREG(OV0_P2_X_START_END
, besr
.p2_x_start_end
);
1577 OUTREG(OV0_P3_X_START_END
, besr
.p3_x_start_end
);
1579 OUTREG(OV0_BASE_ADDR
, besr
.base_addr
);
1581 OUTREG(OV0_VID_BUF0_BASE_ADRS
, besr
.vid_buf_base_adrs_y
[0]);
1582 OUTREG(OV0_VID_BUF1_BASE_ADRS
, besr
.vid_buf_base_adrs_v
[0]);
1583 OUTREG(OV0_VID_BUF2_BASE_ADRS
, besr
.vid_buf_base_adrs_u
[0]);
1584 radeon_fifo_wait(9);
1585 OUTREG(OV0_VID_BUF3_BASE_ADRS
, besr
.vid_buf_base_adrs_y
[0]);
1586 OUTREG(OV0_VID_BUF4_BASE_ADRS
, besr
.vid_buf_base_adrs_v
[0]);
1587 OUTREG(OV0_VID_BUF5_BASE_ADRS
, besr
.vid_buf_base_adrs_u
[0]);
1588 OUTREG(OV0_P1_V_ACCUM_INIT
, besr
.p1_v_accum_init
);
1589 OUTREG(OV0_P1_H_ACCUM_INIT
, besr
.p1_h_accum_init
);
1590 OUTREG(OV0_P23_H_ACCUM_INIT
, besr
.p23_h_accum_init
);
1591 OUTREG(OV0_P23_V_ACCUM_INIT
, besr
.p23_v_accum_init
);
1593 bes_flags
= SCALER_ENABLE
|
1594 SCALER_SMART_SWITCH
|
1597 if(besr
.double_buff
) bes_flags
|= SCALER_DOUBLE_BUFFER
;
1598 if(besr
.deinterlace_on
) bes_flags
|= SCALER_ADAPTIVE_DEINT
;
1599 if(besr
.horz_pick_nearest
) bes_flags
|= SCALER_HORZ_PICK_NEAREST
;
1600 if(besr
.vert_pick_nearest
) bes_flags
|= SCALER_VERT_PICK_NEAREST
;
1602 bes_flags
|= SCALER_BURST_PER_PLANE
;
1604 bes_flags
|= (besr
.surf_id
<< 8) & SCALER_SURFAC_FORMAT
;
1605 if(besr
.load_prg_start
) bes_flags
|= SCALER_PRG_LOAD_START
;
1606 if(force_second
) bes_flags
|= SCALER_USE_OV1
;
1607 else bes_flags
&= ~SCALER_USE_OV1
;
1608 OUTREG(OV0_SCALE_CNTL
, bes_flags
);
1609 radeon_fifo_wait(6);
1610 OUTREG(OV0_FILTER_CNTL
,besr
.filter_cntl
);
1611 OUTREG(OV0_FOUR_TAP_COEF_0
,besr
.four_tap_coeff
[0]);
1612 OUTREG(OV0_FOUR_TAP_COEF_1
,besr
.four_tap_coeff
[1]);
1613 OUTREG(OV0_FOUR_TAP_COEF_2
,besr
.four_tap_coeff
[2]);
1614 OUTREG(OV0_FOUR_TAP_COEF_3
,besr
.four_tap_coeff
[3]);
1615 OUTREG(OV0_FOUR_TAP_COEF_4
,besr
.four_tap_coeff
[4]);
1616 if(besr
.swap_uv
) OUTREG(OV0_TEST
,INREG(OV0_TEST
)|OV0_SWAP_UV
);
1617 OUTREG(OV0_REG_LOAD_CNTL
, 0);
1618 if(__verbose
> VERBOSE_LEVEL
) printf(RADEON_MSG
"we wanted: scaler=%08X\n",bes_flags
);
1619 if(__verbose
> VERBOSE_LEVEL
) radeon_vid_dump_regs();
1622 /* Goal of this function: hide RGB background and provide black screen around movie.
1623 Useful in '-vo fbdev:vidix -fs -zoom' mode.
1624 Reverse effect to colorkey */
1626 static void radeon_vid_exclusive( void )
1628 /* this function works only with Rage128.
1629 Radeon should has something the same */
1630 unsigned screenw
,screenh
;
1631 screenw
= radeon_get_xres();
1632 screenh
= radeon_get_yres();
1633 radeon_fifo_wait(2);
1634 OUTREG(OV0_EXCLUSIVE_VERT
,(((screenh
-1)<<16)&EXCL_VERT_END_MASK
));
1635 OUTREG(OV0_EXCLUSIVE_HORZ
,(((screenw
/8+1)<<8)&EXCL_HORZ_END_MASK
)|EXCL_HORZ_EXCLUSIVE_EN
);
1638 static void radeon_vid_non_exclusive( void )
1640 OUTREG(OV0_EXCLUSIVE_HORZ
,0);
1644 static unsigned radeon_query_pitch(unsigned fourcc
,const vidix_yuv_t
*spitch
)
1646 unsigned pitch
,spy
,spv
,spu
;
1647 spy
= spv
= spu
= 0;
1654 case 256: spy
= spitch
->y
; break;
1663 case 256: spu
= spitch
->u
; break;
1672 case 256: spv
= spitch
->v
; break;
1681 if(spy
> 16 && spu
== spy
/2 && spv
== spy
/2) pitch
= spy
;
1686 if(spy
>= 64 && spu
== spy
/4 && spv
== spy
/4) pitch
= spy
;
1690 if(spy
>= 16) pitch
= spy
;
1697 static void Calc_H_INC_STEP_BY (
1698 int fieldvalue_OV0_SURFACE_FORMAT
,
1699 double H_scale_ratio
,
1700 int DisallowFourTapVertFiltering
,
1701 int DisallowFourTapUVVertFiltering
,
1702 uint32_t *val_OV0_P1_H_INC
,
1703 uint32_t *val_OV0_P1_H_STEP_BY
,
1704 uint32_t *val_OV0_P23_H_INC
,
1705 uint32_t *val_OV0_P23_H_STEP_BY
,
1711 double ClocksNeededFor16Pixels
;
1713 switch (fieldvalue_OV0_SURFACE_FORMAT
)
1716 case 4: /*16BPP (ARGB1555 and RGB565) */
1717 /* All colour components are fetched in pairs */
1719 /* We don't support four tap in this mode because G's are split between two bytes. In theory we could support it if */
1720 /* we saved part of the G when fetching the R, and then filter the G, followed by the B in the following cycles. */
1721 if (H_scale_ratio
>=.5)
1723 /* We are actually generating two pixels (but 3 colour components) per tick. Thus we don't have to skip */
1724 /* until we reach .5. P1 and P23 are the same. */
1725 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5);
1726 *val_OV0_P1_H_STEP_BY
= 1;
1727 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5);
1728 *val_OV0_P23_H_STEP_BY
= 1;
1732 else if (H_scale_ratio
>=.25)
1735 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*2)) * (1<<0xc) + 0.5);
1736 *val_OV0_P1_H_STEP_BY
= 2;
1737 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*2)) * (1<<0xc) + 0.5);
1738 *val_OV0_P23_H_STEP_BY
= 2;
1742 else if (H_scale_ratio
>=.125)
1745 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*4)) * (1<<0xc) + 0.5);
1746 *val_OV0_P1_H_STEP_BY
= 3;
1747 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*4)) * (1<<0xc) + 0.5);
1748 *val_OV0_P23_H_STEP_BY
= 3;
1752 else if (H_scale_ratio
>=.0625)
1755 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*8)) * (1<<0xc) + 0.5);
1756 *val_OV0_P1_H_STEP_BY
= 4;
1757 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*8)) * (1<<0xc) + 0.5);
1758 *val_OV0_P23_H_STEP_BY
= 4;
1762 else if (H_scale_ratio
>=0.03125)
1764 /* Step by sixteen */
1765 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*16)) * (1<<0xc) + 0.5);
1766 *val_OV0_P1_H_STEP_BY
= 5;
1767 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*16)) * (1<<0xc) + 0.5);
1768 *val_OV0_P23_H_STEP_BY
= 5;
1774 H_scale_ratio
=0.03125;
1775 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*16)) * (1<<0xc) + 0.5);
1776 *val_OV0_P1_H_STEP_BY
= 5;
1777 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*16)) * (1<<0xc) + 0.5);
1778 *val_OV0_P23_H_STEP_BY
= 5;
1783 case 6: /*32BPP RGB */
1784 if (H_scale_ratio
>=1.5 && !DisallowFourTapVertFiltering
)
1786 /* All colour components are fetched in pairs */
1788 /* With four tap filtering, we can generate two colour components every clock, or two pixels every three */
1789 /* clocks. This means that we will have four tap filtering when scaling 1.5 or more. */
1790 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5);
1791 *val_OV0_P1_H_STEP_BY
= 0;
1792 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5);
1793 *val_OV0_P23_H_STEP_BY
= 0;
1797 else if (H_scale_ratio
>=0.75)
1799 /* Four G colour components are fetched at once */
1801 /* R and B colour components are fetched in pairs */
1802 /* With two tap filtering, we can generate four colour components every clock. */
1803 /* This means that we will have two tap filtering when scaling 1.0 or more. */
1804 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5);
1805 *val_OV0_P1_H_STEP_BY
= 1;
1806 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5);
1807 *val_OV0_P23_H_STEP_BY
= 1;
1811 else if (H_scale_ratio
>=0.375)
1814 /* Four G colour components are fetched at once */
1816 /* R and B colour components are fetched in pairs */
1817 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*2)) * (1<<0xc) + 0.5);
1818 *val_OV0_P1_H_STEP_BY
= 2;
1819 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*2)) * (1<<0xc) + 0.5);
1820 *val_OV0_P23_H_STEP_BY
= 2;
1824 else if (H_scale_ratio
>=0.25)
1827 /* Four G colour components are fetched at once */
1829 /* R and B colour components are fetched in pairs */
1830 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*2)) * (1<<0xc) + 0.5);
1831 *val_OV0_P1_H_STEP_BY
= 2;
1832 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*4)) * (1<<0xc) + 0.5);
1833 *val_OV0_P23_H_STEP_BY
= 3;
1837 else if (H_scale_ratio
>=0.1875)
1840 /* Four G colour components are fetched at once */
1842 /* R and B colour components are fetched in pairs */
1843 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*4)) * (1<<0xc) + 0.5);
1844 *val_OV0_P1_H_STEP_BY
= 3;
1845 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*4)) * (1<<0xc) + 0.5);
1846 *val_OV0_P23_H_STEP_BY
= 3;
1850 else if (H_scale_ratio
>=0.125)
1853 /* Four G colour components are fetched at once */
1855 /* R and B colour components are fetched in pairs */
1856 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*4)) * (1<<0xc) + 0.5);
1857 *val_OV0_P1_H_STEP_BY
= 3;
1858 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*8)) * (1<<0xc) + 0.5);
1859 *val_OV0_P23_H_STEP_BY
= 4;
1863 else if (H_scale_ratio
>=0.09375)
1866 /* Four G colour components are fetched at once */
1868 /* R and B colour components are fetched in pairs */
1869 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*8)) * (1<<0xc) + 0.5);
1870 *val_OV0_P1_H_STEP_BY
= 4;
1871 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*8)) * (1<<0xc) + 0.5);
1872 *val_OV0_P23_H_STEP_BY
= 4;
1876 else if (H_scale_ratio
>=0.0625)
1879 /* Four G colour components are fetched at once */
1881 /* R and B colour components are fetched in pairs */
1882 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*16)) * (1<<0xc) + 0.5);
1883 *val_OV0_P1_H_STEP_BY
= 5;
1884 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*16)) * (1<<0xc) + 0.5);
1885 *val_OV0_P23_H_STEP_BY
= 5;
1891 H_scale_ratio
=0.0625;
1893 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*16)) * (1<<0xc) + 0.5);
1894 *val_OV0_P1_H_STEP_BY
= 5;
1895 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*16)) * (1<<0xc) + 0.5);
1896 *val_OV0_P23_H_STEP_BY
= 5;
1902 /*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. */
1903 /* four tap on both (unless Y is too wide) */
1904 if ((H_scale_ratio
>=(ClocksNeededFor16Pixels
=8+2+2) / 16.0) &&
1905 ((uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5)<=0x3000) &&
1906 ((uint16_t)((1/(H_scale_ratio
*4)) * (1<<0xc) + 0.5)<=0x2000) &&
1907 !DisallowFourTapVertFiltering
&& !DisallowFourTapUVVertFiltering
)
1909 /* Colour components are fetched in pairs */
1911 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5);
1912 *val_OV0_P1_H_STEP_BY
= 0;
1913 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*4)) * (1<<0xc) + 0.5);
1914 *val_OV0_P23_H_STEP_BY
= 0;
1918 /* two tap on Y (because it is too big for four tap), four tap on UV */
1919 else if ((H_scale_ratio
>=(ClocksNeededFor16Pixels
=4+2+2) / 16.0) &&
1920 ((uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5)<=0x3000) &&
1921 ((uint16_t)((1/(H_scale_ratio
*4)) * (1<<0xc) + 0.5)<=0x2000) &&
1922 DisallowFourTapVertFiltering
&& !DisallowFourTapUVVertFiltering
)
1925 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5);
1926 *val_OV0_P1_H_STEP_BY
= 1;
1927 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*4)) * (1<<0xc) + 0.5);
1928 *val_OV0_P23_H_STEP_BY
= 0;
1932 /* We scale the Y with the four tap filters, but UV's are generated
1933 with dual two tap configuration. */
1934 else if ((H_scale_ratio
>=(ClocksNeededFor16Pixels
=8+1+1) / 16.0) &&
1935 ((uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5)<=0x3000) &&
1936 ((uint16_t)((1/(H_scale_ratio
*4)) * (1<<0xc) + 0.5)<=0x2000) &&
1937 !DisallowFourTapVertFiltering
)
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
*4)) * (1<<0xc) + 0.5);
1943 *val_OV0_P23_H_STEP_BY
= 1;
1947 /* We scale the Y, U, and V with the two tap filters */
1948 else if ((H_scale_ratio
>=(ClocksNeededFor16Pixels
=4+1+1) / 16.0) &&
1949 ((uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5)<=0x3000) &&
1950 ((uint16_t)((1/(H_scale_ratio
*4)) * (1<<0xc) + 0.5)<=0x2000))
1953 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5);
1954 *val_OV0_P1_H_STEP_BY
= 1;
1955 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*4)) * (1<<0xc) + 0.5);
1956 *val_OV0_P23_H_STEP_BY
= 1;
1960 /* We scale step the U and V by two to allow more bandwidth for fetching Y's,
1961 thus we won't drop Y's yet. */
1962 else if ((H_scale_ratio
>=(ClocksNeededFor16Pixels
=4+.5+.5) / 16.0) &&
1963 ((uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5)<=0x3000) &&
1964 ((uint16_t)((1/(H_scale_ratio
*4*2)) * (1<<0xc) + 0.5)<=0x2000))
1965 { /*>=0.3125 and >.333333~ */
1967 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5);
1968 *val_OV0_P1_H_STEP_BY
= 1;
1969 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*4*2)) * (1<<0xc) + 0.5);
1970 *val_OV0_P23_H_STEP_BY
= 2;
1974 /* We step the Y, U, and V by two. */
1975 else if ((H_scale_ratio
>=(ClocksNeededFor16Pixels
=2+.5+.5) / 16.0) &&
1976 ((uint16_t)((1/(H_scale_ratio
*2)) * (1<<0xc) + 0.5)<=0x3000) &&
1977 ((uint16_t)((1/(H_scale_ratio
*4*2)) * (1<<0xc) + 0.5)<=0x2000))
1980 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*2)) * (1<<0xc) + 0.5);
1981 *val_OV0_P1_H_STEP_BY
= 2;
1982 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*4*2)) * (1<<0xc) + 0.5);
1983 *val_OV0_P23_H_STEP_BY
= 2;
1987 /* We step the Y by two and the U and V by four. */
1988 else if ((H_scale_ratio
>=(ClocksNeededFor16Pixels
=2+.25+.25) / 16.0) &&
1989 ((uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5)<=0x3000) &&
1990 ((uint16_t)((1/(H_scale_ratio
*4*4)) * (1<<0xc) + 0.5)<=0x2000))
1993 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*2)) * (1<<0xc) + 0.5);
1994 *val_OV0_P1_H_STEP_BY
= 2;
1995 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*4*4)) * (1<<0xc) + 0.5);
1996 *val_OV0_P23_H_STEP_BY
= 3;
2000 /* We step the Y, U, and V by four. */
2001 else if ((H_scale_ratio
>=(ClocksNeededFor16Pixels
=1+.25+.25) / 16.0) &&
2002 ((uint16_t)((1/(H_scale_ratio
*4)) * (1<<0xc) + 0.5)<=0x3000) &&
2003 ((uint16_t)((1/(H_scale_ratio
*4*4)) * (1<<0xc) + 0.5)<=0x2000))
2006 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*4)) * (1<<0xc) + 0.5);
2007 *val_OV0_P1_H_STEP_BY
= 3;
2008 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*4*4)) * (1<<0xc) + 0.5);
2009 *val_OV0_P23_H_STEP_BY
= 3;
2013 /* 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 */
2015 /* We step the Y, U, and V by eight. */
2016 else if ((H_scale_ratio
>=(ClocksNeededFor16Pixels
=.5+.125+.125) / 16.0) &&
2017 ((uint16_t)((1/(H_scale_ratio
*8)) * (1<<0xc) + 0.5)<=0x3000) &&
2018 ((uint16_t)((1/(H_scale_ratio
*4*8)) * (1<<0xc) + 0.5)<=0x2000))
2021 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*8)) * (1<<0xc) + 0.5);
2022 *val_OV0_P1_H_STEP_BY
= 4;
2023 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*4*8)) * (1<<0xc) + 0.5);
2024 *val_OV0_P23_H_STEP_BY
= 4;
2028 /* We step the Y by eight and the U and V by sixteen. */
2029 else if ((H_scale_ratio
>=(ClocksNeededFor16Pixels
=.5+.0625+.0625) / 16.0) &&
2030 ((uint16_t)((1/(H_scale_ratio
*8)) * (1<<0xc) + 0.5)<=0x3000) &&
2031 ((uint16_t)((1/(H_scale_ratio
*4*16)) * (1<<0xc) + 0.5)<=0x2000))
2034 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*8)) * (1<<0xc) + 0.5);
2035 *val_OV0_P1_H_STEP_BY
= 4;
2036 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*4*16)) * (1<<0xc) + 0.5);
2037 *val_OV0_P23_H_STEP_BY
= 5;
2041 /* We step the Y, U, and V by sixteen. */
2042 else if ((H_scale_ratio
>=(ClocksNeededFor16Pixels
=.25+.0625+.0625) / 16.0) &&
2043 ((uint16_t)((1/(H_scale_ratio
*16)) * (1<<0xc) + 0.5)<=0x3000) &&
2044 ((uint16_t)((1/(H_scale_ratio
*4*16)) * (1<<0xc) + 0.5)<=0x2000))
2047 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*16)) * (1<<0xc) + 0.5);
2048 *val_OV0_P1_H_STEP_BY
= 5;
2049 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*4*16)) * (1<<0xc) + 0.5);
2050 *val_OV0_P23_H_STEP_BY
= 5;
2056 H_scale_ratio
=(ClocksNeededFor16Pixels
=.25+.0625+.0625) / 16;
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
*4*16)) * (1<<0xc) + 0.5);
2061 *val_OV0_P23_H_STEP_BY
= 5;
2070 case 14: /* YUV12, VYUY422, YUYV422, YOverPkCRCB12, YWovenWithPkCRCB12 */
2071 /* We scale the Y, U, and V with the four tap filters */
2072 /* four tap on both (unless Y is too wide) */
2073 if ((H_scale_ratio
>=(ClocksNeededFor16Pixels
=8+4+4) / 16.0) &&
2074 !DisallowFourTapVertFiltering
&& !DisallowFourTapUVVertFiltering
)
2077 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5);
2078 *val_OV0_P1_H_STEP_BY
= 0;
2079 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*2)) * (1<<0xc) + 0.5);
2080 *val_OV0_P23_H_STEP_BY
= 0;
2084 /* two tap on Y (because it is too big for four tap), four tap on UV */
2085 else if ((H_scale_ratio
>=(ClocksNeededFor16Pixels
=4+4+4) / 16.0) &&
2086 DisallowFourTapVertFiltering
&& !DisallowFourTapUVVertFiltering
)
2089 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5);
2090 *val_OV0_P1_H_STEP_BY
= 1;
2091 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*2)) * (1<<0xc) + 0.5);
2092 *val_OV0_P23_H_STEP_BY
= 0;
2096 /* We scale the Y with the four tap filters, but UV's are generated
2097 with dual two tap configuration. */
2098 else if ((H_scale_ratio
>=(ClocksNeededFor16Pixels
=8+2+2) / 16.0) &&
2099 !DisallowFourTapVertFiltering
)
2102 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5);
2103 *val_OV0_P1_H_STEP_BY
= 0;
2104 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*2)) * (1<<0xc) + 0.5);
2105 *val_OV0_P23_H_STEP_BY
= 1;
2109 /* We scale the Y, U, and V with the two tap filters */
2110 else if (H_scale_ratio
>=(ClocksNeededFor16Pixels
=4+2+2) / 16.0)
2113 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5);
2114 *val_OV0_P1_H_STEP_BY
= 1;
2115 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*2)) * (1<<0xc) + 0.5);
2116 *val_OV0_P23_H_STEP_BY
= 1;
2120 /* We scale step the U and V by two to allow more bandwidth for
2121 fetching Y's, thus we won't drop Y's yet. */
2122 else if (H_scale_ratio
>=(ClocksNeededFor16Pixels
=4+1+1) / 16.0)
2125 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5);
2126 *val_OV0_P1_H_STEP_BY
= 1;
2127 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*2*2)) * (1<<0xc) + 0.5);
2128 *val_OV0_P23_H_STEP_BY
= 2;
2132 /* We step the Y, U, and V by two. */
2133 else if (H_scale_ratio
>=(ClocksNeededFor16Pixels
=2+1+1) / 16.0)
2136 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*2)) * (1<<0xc) + 0.5);
2137 *val_OV0_P1_H_STEP_BY
= 2;
2138 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*2*2)) * (1<<0xc) + 0.5);
2139 *val_OV0_P23_H_STEP_BY
= 2;
2143 /* We step the Y by two and the U and V by four. */
2144 else if (H_scale_ratio
>=(ClocksNeededFor16Pixels
=2+.5+.5) / 16.0)
2147 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*2)) * (1<<0xc) + 0.5);
2148 *val_OV0_P1_H_STEP_BY
= 2;
2149 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*2*4)) * (1<<0xc) + 0.5);
2150 *val_OV0_P23_H_STEP_BY
= 3;
2154 /* We step the Y, U, and V by four. */
2155 else if (H_scale_ratio
>=(ClocksNeededFor16Pixels
=1+.5+.5) / 16.0)
2158 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*4)) * (1<<0xc) + 0.5);
2159 *val_OV0_P1_H_STEP_BY
= 3;
2160 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*2*4)) * (1<<0xc) + 0.5);
2161 *val_OV0_P23_H_STEP_BY
= 3;
2165 /* We step the Y by four and the U and V by eight. */
2166 else if ((H_scale_ratio
>=(ClocksNeededFor16Pixels
=1+.25+.25) / 16.0) &&
2167 (fieldvalue_OV0_SURFACE_FORMAT
==10))
2170 /* Can't mix step by 3 and step by 4 for packed modes */
2171 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*4)) * (1<<0xc) + 0.5);
2172 *val_OV0_P1_H_STEP_BY
= 3;
2173 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*2*8)) * (1<<0xc) + 0.5);
2174 *val_OV0_P23_H_STEP_BY
= 4;
2178 /* We step the Y, U, and V by eight. */
2179 else if (H_scale_ratio
>=(ClocksNeededFor16Pixels
=.5+.25+.25) / 16.0)
2182 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*8)) * (1<<0xc) + 0.5);
2183 *val_OV0_P1_H_STEP_BY
= 4;
2184 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*2*8)) * (1<<0xc) + 0.5);
2185 *val_OV0_P23_H_STEP_BY
= 4;
2189 /* We step the Y by eight and the U and V by sixteen. */
2190 else if ((H_scale_ratio
>=(ClocksNeededFor16Pixels
=.5+.125+.125) / 16.0) && (fieldvalue_OV0_SURFACE_FORMAT
==10))
2193 /* Step by 5 not supported for packed modes */
2194 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*8)) * (1<<0xc) + 0.5);
2195 *val_OV0_P1_H_STEP_BY
= 4;
2196 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*2*16)) * (1<<0xc) + 0.5);
2197 *val_OV0_P23_H_STEP_BY
= 5;
2201 /* We step the Y, U, and V by sixteen. */
2202 else if ((H_scale_ratio
>=(ClocksNeededFor16Pixels
=.25+.125+.125) / 16.0) &&
2203 (fieldvalue_OV0_SURFACE_FORMAT
==10))
2206 /* Step by 5 not supported for packed modes */
2207 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*16)) * (1<<0xc) + 0.5);
2208 *val_OV0_P1_H_STEP_BY
= 5;
2209 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*2*16)) * (1<<0xc) + 0.5);
2210 *val_OV0_P23_H_STEP_BY
= 5;
2216 if (fieldvalue_OV0_SURFACE_FORMAT
==10)
2218 H_scale_ratio
=(ClocksNeededFor16Pixels
=.25+.125+.125) / 16;
2220 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*16)) * (1<<0xc) + 0.5);
2221 *val_OV0_P1_H_STEP_BY
= 5;
2222 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*2*16)) * (1<<0xc) + 0.5);
2223 *val_OV0_P23_H_STEP_BY
= 5;
2229 H_scale_ratio
=(ClocksNeededFor16Pixels
=.5+.25+.25) / 16;
2231 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*8)) * (1<<0xc) + 0.5);
2232 *val_OV0_P1_H_STEP_BY
= 4;
2233 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*2*8)) * (1<<0xc) + 0.5);
2234 *val_OV0_P23_H_STEP_BY
= 4;
2243 besr
.h_inc
= (*(val_OV0_P1_H_INC
)&0x3fff) | ((*(val_OV0_P23_H_INC
)&0x3fff)<<16);
2244 besr
.step_by
= (*(val_OV0_P1_H_STEP_BY
)&0x7) | ((*(val_OV0_P23_H_STEP_BY
)&0x7)<<8);
2247 /* ********************************************************* */
2248 /* ** Setup Black Bordering */
2249 /* ********************************************************* */
2251 static void ComputeBorders( vidix_playback_t
*config
, int VertUVSubSample
)
2253 double tempBLANK_LINES_AT_TOP
;
2254 unsigned TopLine
,BottomLine
,SourceLinesUsed
,TopUVLine
,BottomUVLine
,SourceUVLinesUsed
;
2255 uint32_t val_OV0_P1_ACTIVE_LINES_M1
,val_OV0_P1_BLNK_LN_AT_TOP_M1
;
2256 uint32_t val_OV0_P23_ACTIVE_LINES_M1
,val_OV0_P23_BLNK_LN_AT_TOP_M1
;
2258 if (floor(config
->src
.y
)<0) {
2259 tempBLANK_LINES_AT_TOP
= -floor(config
->src
.y
);
2263 tempBLANK_LINES_AT_TOP
= 0;
2264 TopLine
= (int)floor(config
->src
.y
);
2266 /* Round rSrcBottom up and subtract one */
2267 if (ceil(config
->src
.y
+config
->src
.h
) > config
->src
.h
)
2269 BottomLine
= config
->src
.h
- 1;
2273 BottomLine
= (int)ceil(config
->src
.y
+config
->src
.h
) - 1;
2276 if (BottomLine
>= TopLine
)
2278 SourceLinesUsed
= BottomLine
- TopLine
+ 1;
2282 /*CYCACC_ASSERT(0, "SourceLinesUsed less than or equal to zero.") */
2283 SourceLinesUsed
= 1;
2287 int SourceHeightInPixels
;
2288 SourceHeightInPixels
= BottomLine
- TopLine
+ 1;
2291 val_OV0_P1_ACTIVE_LINES_M1
= SourceLinesUsed
- 1;
2292 val_OV0_P1_BLNK_LN_AT_TOP_M1
= ((int)tempBLANK_LINES_AT_TOP
-1) & 0xfff;
2294 TopUVLine
= ((int)(config
->src
.y
/VertUVSubSample
) < 0) ? 0: (int)(config
->src
.y
/VertUVSubSample
); /* Round rSrcTop down */
2295 BottomUVLine
= (ceil(((config
->src
.y
+config
->src
.h
)/VertUVSubSample
)) > (config
->src
.h
/VertUVSubSample
))
2296 ? (config
->src
.h
/VertUVSubSample
)-1 : (unsigned int)ceil(((config
->src
.y
+config
->src
.h
)/VertUVSubSample
))-1;
2298 if (BottomUVLine
>= TopUVLine
)
2300 SourceUVLinesUsed
= BottomUVLine
- TopUVLine
+ 1;
2304 /*CYCACC_ASSERT(0, "SourceUVLinesUsed less than or equal to zero.") */
2305 SourceUVLinesUsed
= 1;
2307 val_OV0_P23_ACTIVE_LINES_M1
= SourceUVLinesUsed
- 1;
2308 val_OV0_P23_BLNK_LN_AT_TOP_M1
= ((int)(tempBLANK_LINES_AT_TOP
/VertUVSubSample
)-1) & 0x7ff;
2309 besr
.p1_blank_lines_at_top
= (val_OV0_P1_BLNK_LN_AT_TOP_M1
& 0xfff) |
2310 ((val_OV0_P1_ACTIVE_LINES_M1
& 0xfff) << 16);
2311 besr
.p23_blank_lines_at_top
= (val_OV0_P23_BLNK_LN_AT_TOP_M1
& 0x7ff) |
2312 ((val_OV0_P23_ACTIVE_LINES_M1
& 0x7ff) << 16);
2316 static void ComputeXStartEnd(
2318 uint32_t LeftPixel
,uint32_t LeftUVPixel
,
2319 uint32_t MemWordsInBytes
,uint32_t BytesPerPixel
,
2320 uint32_t SourceWidthInPixels
, uint32_t P1StepSize
,
2321 uint32_t BytesPerUVPixel
,uint32_t SourceUVWidthInPixels
,
2322 uint32_t P23StepSize
, uint32_t *p1_x_start
, uint32_t *p2_x_start
)
2324 uint32_t val_OV0_P1_X_START
,val_OV0_P2_X_START
,val_OV0_P3_X_START
;
2325 uint32_t val_OV0_P1_X_END
,val_OV0_P2_X_END
,val_OV0_P3_X_END
;
2326 /* 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. */
2328 val_OV0_P1_X_START
= (int)LeftPixel
% (MemWordsInBytes
/BytesPerPixel
);
2329 val_OV0_P1_X_END
= (int)((val_OV0_P1_X_START
+ SourceWidthInPixels
- 1) / P1StepSize
) * P1StepSize
;
2331 val_OV0_P2_X_START
= val_OV0_P2_X_END
= 0;
2332 switch (besr
.surf_id
)
2337 case 14: /* ToDo_Active: The driver must insure that the initial value is */
2338 /* a multiple of a power of two when decimating */
2339 val_OV0_P2_X_START
= (int)LeftUVPixel
%
2340 (MemWordsInBytes
/BytesPerUVPixel
);
2341 val_OV0_P2_X_END
= (int)((val_OV0_P2_X_START
+
2342 SourceUVWidthInPixels
- 1) / P23StepSize
) * P23StepSize
;
2345 case 12: val_OV0_P2_X_START
= (int)LeftUVPixel
% (MemWordsInBytes
/(BytesPerPixel
*2));
2346 val_OV0_P2_X_END
= (int)((val_OV0_P2_X_START
+ SourceUVWidthInPixels
- 1) / P23StepSize
) * P23StepSize
;
2349 case 4: val_OV0_P2_X_START
= val_OV0_P1_X_START
;
2350 /* This value is needed only to allow proper setting of */
2351 /* val_OV0_PRESHIFT_P23_TO */
2352 /* val_OV0_P2_X_END = 0; */
2354 case 6: val_OV0_P2_X_START
= (int)LeftPixel
% (MemWordsInBytes
/BytesPerPixel
);
2355 val_OV0_P2_X_END
= (int)((val_OV0_P1_X_START
+ SourceWidthInPixels
- 1) / P23StepSize
) * P23StepSize
;
2357 default: /* insert debug statement here. */
2358 RADEON_ASSERT("unknown fourcc\n");
2361 val_OV0_P3_X_START
= val_OV0_P2_X_START
;
2362 val_OV0_P3_X_END
= val_OV0_P2_X_END
;
2364 besr
.p1_x_start_end
= (val_OV0_P1_X_END
&0x7ff) | ((val_OV0_P1_X_START
&0x7ff)<<16);
2365 besr
.p2_x_start_end
= (val_OV0_P2_X_END
&0x7ff) | ((val_OV0_P2_X_START
&0x7ff)<<16);
2366 besr
.p3_x_start_end
= (val_OV0_P3_X_END
&0x7ff) | ((val_OV0_P3_X_START
&0x7ff)<<16);
2369 besr
.p2_x_start_end
= 0;
2370 besr
.p3_x_start_end
= 0;
2372 *p1_x_start
= val_OV0_P1_X_START
;
2373 *p2_x_start
= val_OV0_P2_X_START
;
2376 static void ComputeAccumInit(
2377 uint32_t val_OV0_P1_X_START
,uint32_t val_OV0_P2_X_START
,
2378 uint32_t val_OV0_P1_H_INC
,uint32_t val_OV0_P23_H_INC
,
2379 uint32_t val_OV0_P1_H_STEP_BY
,uint32_t val_OV0_P23_H_STEP_BY
,
2381 uint32_t P1GroupSize
, uint32_t P23GroupSize
,
2382 uint32_t val_OV0_P1_MAX_LN_IN_PER_LN_OUT
,
2383 uint32_t val_OV0_P23_MAX_LN_IN_PER_LN_OUT
)
2385 uint32_t val_OV0_P1_H_ACCUM_INIT
,val_OV0_PRESHIFT_P1_TO
;
2386 uint32_t val_OV0_P23_H_ACCUM_INIT
,val_OV0_PRESHIFT_P23_TO
;
2387 uint32_t val_OV0_P1_V_ACCUM_INIT
,val_OV0_P23_V_ACCUM_INIT
;
2388 /* 2.5 puts the kernal 50% of the way between the source pixel that is off screen */
2389 /* and the first on-screen source pixel. "(float)valOV0_P?_H_INC / (1<<0xc)" is */
2390 /* the distance (in source pixel coordinates) to the center of the first */
2391 /* destination pixel. Need to add additional pixels depending on how many pixels */
2392 /* are fetched at a time and how many pixels in a set are masked. */
2393 /* P23 values are always fetched in groups of two or four. If the start */
2394 /* pixel does not fall on the boundary, then we need to shift preshift for */
2395 /* some additional pixels */
2398 double ExtraHalfPixel
;
2399 double tempAdditionalShift
;
2400 double tempP1HStartPoint
;
2401 double tempP23HStartPoint
;
2405 if (besr
.horz_pick_nearest
) ExtraHalfPixel
= 0.5;
2406 else ExtraHalfPixel
= 0.0;
2407 tempAdditionalShift
= val_OV0_P1_X_START
% P1GroupSize
+ ExtraHalfPixel
;
2408 tempP1HStartPoint
= tempAdditionalShift
+ 2.5 + ((float)val_OV0_P1_H_INC
/ (1<<0xd));
2409 tempP1Init
= (double)((int)(tempP1HStartPoint
* (1<<0x5) + 0.5)) / (1<<0x5);
2411 /* P23 values are always fetched in pairs. If the start pixel is odd, then we */
2412 /* need to shift an additional pixel */
2413 /* Note that if the pitch is a multiple of two, and if we store fields using */
2414 /* the traditional planer format where the V plane and the U plane share the */
2415 /* same pitch, then OverlayRegFields->val_OV0_P2_X_START % P23Group */
2416 /* OverlayRegFields->val_OV0_P3_X_START % P23GroupSize. Either way */
2417 /* it is a requirement that the U and V start on the same polarity byte */
2418 /* (even or odd). */
2419 tempAdditionalShift
= val_OV0_P2_X_START
% P23GroupSize
+ ExtraHalfPixel
;
2420 tempP23HStartPoint
= tempAdditionalShift
+ 2.5 + ((float)val_OV0_P23_H_INC
/ (1<<0xd));
2421 tempP23Init
= (double)((int)(tempP23HStartPoint
* (1<<0x5) + 0.5)) / (1 << 0x5);
2422 val_OV0_P1_H_ACCUM_INIT
= (int)((tempP1Init
- (int)tempP1Init
) * (1<<0x5));
2423 val_OV0_PRESHIFT_P1_TO
= (int)tempP1Init
;
2424 val_OV0_P23_H_ACCUM_INIT
= (int)((tempP23Init
- (int)tempP23Init
) * (1<<0x5));
2425 val_OV0_PRESHIFT_P23_TO
= (int)tempP23Init
;
2428 /* ************************************************************** */
2429 /* ** Calculate values for initializing the vertical accumulators */
2430 /* ************************************************************** */
2433 double ExtraHalfLine
;
2434 double ExtraFullLine
;
2435 double tempP1VStartPoint
;
2436 double tempP23VStartPoint
;
2438 if (besr
.vert_pick_nearest
) ExtraHalfLine
= 0.5;
2439 else ExtraHalfLine
= 0.0;
2441 if (val_OV0_P1_H_STEP_BY
==0)ExtraFullLine
= 1.0;
2442 else ExtraFullLine
= 0.0;
2444 tempP1VStartPoint
= 1.5 + ExtraFullLine
+ ExtraHalfLine
+ ((float)CRT_V_INC
/ (1<<0xd));
2445 if (tempP1VStartPoint
>2.5 + 2*ExtraFullLine
)
2447 tempP1VStartPoint
= 2.5 + 2*ExtraFullLine
;
2449 val_OV0_P1_V_ACCUM_INIT
= (int)(tempP1VStartPoint
* (1<<0x5) + 0.5);
2451 if (val_OV0_P23_H_STEP_BY
==0)ExtraFullLine
= 1.0;
2452 else ExtraFullLine
= 0.0;
2454 switch (besr
.surf_id
)
2458 case 14: tempP23VStartPoint
= 1.5 + ExtraFullLine
+ ExtraHalfLine
+
2459 ((float)CRT_V_INC
/ (1<<0xe));
2461 case 9: tempP23VStartPoint
= 1.5 + ExtraFullLine
+ ExtraHalfLine
+
2462 ((float)CRT_V_INC
/ (1<<0xf));
2468 case 12: tempP23VStartPoint
= 0;
2470 default: tempP23VStartPoint
= 0xFFFF;/* insert debug statement here */
2474 if (tempP23VStartPoint
>2.5 + 2*ExtraFullLine
)
2476 tempP23VStartPoint
= 2.5 + 2*ExtraFullLine
;
2479 val_OV0_P23_V_ACCUM_INIT
= (int)(tempP23VStartPoint
* (1<<0x5) + 0.5);
2481 besr
.p1_h_accum_init
= ((val_OV0_P1_H_ACCUM_INIT
&0x1f)<<15) |((val_OV0_PRESHIFT_P1_TO
&0xf)<<28);
2482 besr
.p1_v_accum_init
= (val_OV0_P1_MAX_LN_IN_PER_LN_OUT
&0x3) |((val_OV0_P1_V_ACCUM_INIT
&0x7ff)<<15);
2483 besr
.p23_h_accum_init
= ((val_OV0_P23_H_ACCUM_INIT
&0x1f)<<15) |((val_OV0_PRESHIFT_P23_TO
&0xf)<<28);
2484 besr
.p23_v_accum_init
= (val_OV0_P23_MAX_LN_IN_PER_LN_OUT
&0x3)|((val_OV0_P23_V_ACCUM_INIT
&0x3ff)<<15);
2487 typedef struct RangeAndCoefSet
{
2489 signed char CoefSet
[5][4];
2492 /* Filter Setup Routine */
2493 static void FilterSetup ( uint32_t val_OV0_P1_H_INC
)
2495 static RANGEANDCOEFSET ArrayOfSets
[] = {
2496 {0.25, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2497 {0.26, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2498 {0.27, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2499 {0.28, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2500 {0.29, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2501 {0.30, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2502 {0.31, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2503 {0.32, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2504 {0.33, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2505 {0.34, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2506 {0.35, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2507 {0.36, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2508 {0.37, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2509 {0.38, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2510 {0.39, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2511 {0.40, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2512 {0.41, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2513 {0.42, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2514 {0.43, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2515 {0.44, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2516 {0.45, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2517 {0.46, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2518 {0.47, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2519 {0.48, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2520 {0.49, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2521 {0.50, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2522 {0.51, {{ 7, 17, 8, 0}, { 6, 17, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 2, 14, 14, 2}, }},
2523 {0.52, {{ 7, 17, 8, 0}, { 6, 17, 9, 0}, { 5, 16, 11, 0}, { 3, 15, 13, 1}, { 2, 14, 14, 2}, }},
2524 {0.53, {{ 7, 17, 8, 0}, { 6, 17, 9, 0}, { 5, 16, 11, 0}, { 3, 15, 13, 1}, { 2, 14, 14, 2}, }},
2525 {0.54, {{ 7, 17, 8, 0}, { 6, 17, 9, 0}, { 4, 17, 11, 0}, { 3, 15, 13, 1}, { 2, 14, 14, 2}, }},
2526 {0.55, {{ 7, 18, 7, 0}, { 6, 17, 9, 0}, { 4, 17, 11, 0}, { 3, 15, 13, 1}, { 1, 15, 15, 1}, }},
2527 {0.56, {{ 7, 18, 7, 0}, { 5, 18, 9, 0}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }},
2528 {0.57, {{ 7, 18, 7, 0}, { 5, 18, 9, 0}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }},
2529 {0.58, {{ 7, 18, 7, 0}, { 5, 18, 9, 0}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }},
2530 {0.59, {{ 7, 18, 7, 0}, { 5, 18, 9, 0}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }},
2531 {0.60, {{ 7, 18, 8, -1}, { 6, 17, 10, -1}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }},
2532 {0.61, {{ 7, 18, 8, -1}, { 6, 17, 10, -1}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }},
2533 {0.62, {{ 7, 18, 8, -1}, { 6, 17, 10, -1}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }},
2534 {0.63, {{ 7, 18, 8, -1}, { 6, 17, 10, -1}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }},
2535 {0.64, {{ 7, 18, 8, -1}, { 6, 17, 10, -1}, { 4, 17, 12, -1}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }},
2536 {0.65, {{ 7, 18, 8, -1}, { 6, 17, 10, -1}, { 4, 17, 12, -1}, { 2, 17, 13, 0}, { 0, 16, 16, 0}, }},
2537 {0.66, {{ 7, 18, 8, -1}, { 6, 18, 10, -2}, { 4, 17, 12, -1}, { 2, 17, 13, 0}, { 0, 16, 16, 0}, }},
2538 {0.67, {{ 7, 20, 7, -2}, { 5, 19, 10, -2}, { 3, 18, 12, -1}, { 2, 17, 13, 0}, { 0, 16, 16, 0}, }},
2539 {0.68, {{ 7, 20, 7, -2}, { 5, 19, 10, -2}, { 3, 19, 12, -2}, { 1, 18, 14, -1}, { 0, 16, 16, 0}, }},
2540 {0.69, {{ 7, 20, 7, -2}, { 5, 19, 10, -2}, { 3, 19, 12, -2}, { 1, 18, 14, -1}, { 0, 16, 16, 0}, }},
2541 {0.70, {{ 7, 20, 7, -2}, { 5, 20, 9, -2}, { 3, 19, 12, -2}, { 1, 18, 14, -1}, { 0, 16, 16, 0}, }},
2542 {0.71, {{ 7, 20, 7, -2}, { 5, 20, 9, -2}, { 3, 19, 12, -2}, { 1, 18, 14, -1}, { 0, 16, 16, 0}, }},
2543 {0.72, {{ 7, 20, 7, -2}, { 5, 20, 9, -2}, { 2, 20, 12, -2}, { 0, 19, 15, -2}, {-1, 17, 17, -1}, }},
2544 {0.73, {{ 7, 20, 7, -2}, { 4, 21, 9, -2}, { 2, 20, 12, -2}, { 0, 19, 15, -2}, {-1, 17, 17, -1}, }},
2545 {0.74, {{ 6, 22, 6, -2}, { 4, 21, 9, -2}, { 2, 20, 12, -2}, { 0, 19, 15, -2}, {-1, 17, 17, -1}, }},
2546 {0.75, {{ 6, 22, 6, -2}, { 4, 21, 9, -2}, { 1, 21, 12, -2}, { 0, 19, 15, -2}, {-1, 17, 17, -1}, }},
2547 {0.76, {{ 6, 22, 6, -2}, { 4, 21, 9, -2}, { 1, 21, 12, -2}, { 0, 19, 15, -2}, {-1, 17, 17, -1}, }},
2548 {0.77, {{ 6, 22, 6, -2}, { 3, 22, 9, -2}, { 1, 22, 12, -3}, { 0, 19, 15, -2}, {-2, 18, 18, -2}, }},
2549 {0.78, {{ 6, 21, 6, -1}, { 3, 22, 9, -2}, { 1, 22, 12, -3}, { 0, 19, 15, -2}, {-2, 18, 18, -2}, }},
2550 {0.79, {{ 5, 23, 5, -1}, { 3, 22, 9, -2}, { 0, 23, 12, -3}, {-1, 21, 15, -3}, {-2, 18, 18, -2}, }},
2551 {0.80, {{ 5, 23, 5, -1}, { 3, 23, 8, -2}, { 0, 23, 12, -3}, {-1, 21, 15, -3}, {-2, 18, 18, -2}, }},
2552 {0.81, {{ 5, 23, 5, -1}, { 2, 24, 8, -2}, { 0, 23, 12, -3}, {-1, 21, 15, -3}, {-2, 18, 18, -2}, }},
2553 {0.82, {{ 5, 23, 5, -1}, { 2, 24, 8, -2}, { 0, 23, 12, -3}, {-1, 21, 15, -3}, {-3, 19, 19, -3}, }},
2554 {0.83, {{ 5, 23, 5, -1}, { 2, 24, 8, -2}, { 0, 23, 11, -2}, {-2, 22, 15, -3}, {-3, 19, 19, -3}, }},
2555 {0.84, {{ 4, 25, 4, -1}, { 1, 25, 8, -2}, { 0, 23, 11, -2}, {-2, 22, 15, -3}, {-3, 19, 19, -3}, }},
2556 {0.85, {{ 4, 25, 4, -1}, { 1, 25, 8, -2}, { 0, 23, 11, -2}, {-2, 22, 15, -3}, {-3, 19, 19, -3}, }},
2557 {0.86, {{ 4, 24, 4, 0}, { 1, 25, 7, -1}, {-1, 24, 11, -2}, {-2, 22, 15, -3}, {-3, 19, 19, -3}, }},
2558 {0.87, {{ 4, 24, 4, 0}, { 1, 25, 7, -1}, {-1, 24, 11, -2}, {-2, 22, 15, -3}, {-3, 19, 19, -3}, }},
2559 {0.88, {{ 3, 26, 3, 0}, { 0, 26, 7, -1}, {-1, 24, 11, -2}, {-3, 23, 15, -3}, {-3, 19, 19, -3}, }},
2560 {0.89, {{ 3, 26, 3, 0}, { 0, 26, 7, -1}, {-1, 24, 11, -2}, {-3, 23, 15, -3}, {-3, 19, 19, -3}, }},
2561 {0.90, {{ 3, 26, 3, 0}, { 0, 26, 7, -1}, {-2, 25, 11, -2}, {-3, 23, 15, -3}, {-3, 19, 19, -3}, }},
2562 {0.91, {{ 3, 26, 3, 0}, { 0, 27, 6, -1}, {-2, 25, 11, -2}, {-3, 23, 15, -3}, {-3, 19, 19, -3}, }},
2563 {0.92, {{ 2, 28, 2, 0}, { 0, 27, 6, -1}, {-2, 25, 11, -2}, {-3, 23, 15, -3}, {-3, 19, 19, -3}, }},
2564 {0.93, {{ 2, 28, 2, 0}, { 0, 26, 6, 0}, {-2, 25, 10, -1}, {-3, 23, 15, -3}, {-3, 19, 19, -3}, }},
2565 {0.94, {{ 2, 28, 2, 0}, { 0, 26, 6, 0}, {-2, 25, 10, -1}, {-3, 23, 15, -3}, {-3, 19, 19, -3}, }},
2566 {0.95, {{ 1, 30, 1, 0}, {-1, 28, 5, 0}, {-3, 26, 10, -1}, {-3, 23, 14, -2}, {-3, 19, 19, -3}, }},
2567 {0.96, {{ 1, 30, 1, 0}, {-1, 28, 5, 0}, {-3, 26, 10, -1}, {-3, 23, 14, -2}, {-3, 19, 19, -3}, }},
2568 {0.97, {{ 1, 30, 1, 0}, {-1, 28, 5, 0}, {-3, 26, 10, -1}, {-3, 23, 14, -2}, {-3, 19, 19, -3}, }},
2569 {0.98, {{ 1, 30, 1, 0}, {-2, 29, 5, 0}, {-3, 27, 9, -1}, {-3, 23, 14, -2}, {-3, 19, 19, -3}, }},
2570 {0.99, {{ 0, 32, 0, 0}, {-2, 29, 5, 0}, {-3, 27, 9, -1}, {-4, 24, 14, -2}, {-3, 19, 19, -3}, }},
2571 {1.00, {{ 0, 32, 0, 0}, {-2, 29, 5, 0}, {-3, 27, 9, -1}, {-4, 24, 14, -2}, {-3, 19, 19, -3}, }}
2576 unsigned ArrayElement
;
2578 DSR
= (double)(1<<0xc)/val_OV0_P1_H_INC
;
2579 if (DSR
<.25) DSR
=.25;
2582 ArrayElement
= (int)((DSR
-0.25) * 100);
2583 besr
.four_tap_coeff
[0] = (ArrayOfSets
[ArrayElement
].CoefSet
[0][0] & 0xf) |
2584 ((ArrayOfSets
[ArrayElement
].CoefSet
[0][1] & 0x7f)<<8) |
2585 ((ArrayOfSets
[ArrayElement
].CoefSet
[0][2] & 0x7f)<<16) |
2586 ((ArrayOfSets
[ArrayElement
].CoefSet
[0][3] & 0xf)<<24);
2587 besr
.four_tap_coeff
[1] = (ArrayOfSets
[ArrayElement
].CoefSet
[1][0] & 0xf) |
2588 ((ArrayOfSets
[ArrayElement
].CoefSet
[1][1] & 0x7f)<<8) |
2589 ((ArrayOfSets
[ArrayElement
].CoefSet
[1][2] & 0x7f)<<16) |
2590 ((ArrayOfSets
[ArrayElement
].CoefSet
[1][3] & 0xf)<<24);
2591 besr
.four_tap_coeff
[2] = (ArrayOfSets
[ArrayElement
].CoefSet
[2][0] & 0xf) |
2592 ((ArrayOfSets
[ArrayElement
].CoefSet
[2][1] & 0x7f)<<8) |
2593 ((ArrayOfSets
[ArrayElement
].CoefSet
[2][2] & 0x7f)<<16) |
2594 ((ArrayOfSets
[ArrayElement
].CoefSet
[2][3] & 0xf)<<24);
2595 besr
.four_tap_coeff
[3] = (ArrayOfSets
[ArrayElement
].CoefSet
[3][0] & 0xf) |
2596 ((ArrayOfSets
[ArrayElement
].CoefSet
[3][1] & 0x7f)<<8) |
2597 ((ArrayOfSets
[ArrayElement
].CoefSet
[3][2] & 0x7f)<<16) |
2598 ((ArrayOfSets
[ArrayElement
].CoefSet
[3][3] & 0xf)<<24);
2599 besr
.four_tap_coeff
[4] = (ArrayOfSets
[ArrayElement
].CoefSet
[4][0] & 0xf) |
2600 ((ArrayOfSets
[ArrayElement
].CoefSet
[4][1] & 0x7f)<<8) |
2601 ((ArrayOfSets
[ArrayElement
].CoefSet
[4][2] & 0x7f)<<16) |
2602 ((ArrayOfSets
[ArrayElement
].CoefSet
[4][3] & 0xf)<<24);
2604 For more details, refer to Microsoft's draft of PC99.
2608 /* The minimal value of horizontal scale ratio when hard coded coefficients
2609 are suitable for the best quality. */
2610 /* FIXME: Should it be 0.9 for Rage128 ??? */
2611 static const double MinHScaleHard
=0.75;
2613 static int radeon_vid_init_video( vidix_playback_t
*config
)
2615 double V_scale_ratio
;
2616 uint32_t i
,src_w
,src_h
,dest_w
,dest_h
,pitch
,left
,leftUV
,top
,h_inc
;
2617 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;
2618 uint32_t val_OV0_P1_X_START
,val_OV0_P2_X_START
;
2619 uint32_t val_OV0_P1_MAX_LN_IN_PER_LN_OUT
,val_OV0_P23_MAX_LN_IN_PER_LN_OUT
;
2621 uint32_t BytesPerOctWord
,LogMemWordsInBytes
,MemWordsInBytes
,LogTileWidthInMemWords
;
2622 uint32_t TileWidthInMemWords
,TileWidthInBytes
,LogTileHeight
,TileHeight
;
2623 uint32_t PageSizeInBytes
,OV0LB_Rows
;
2624 uint32_t SourceWidthInMemWords
,SourceUVWidthInMemWords
;
2625 uint32_t SourceWidthInPixels
,SourceUVWidthInPixels
;
2626 uint32_t RightPixel
,RightUVPixel
,LeftPixel
,LeftUVPixel
;
2627 int is_400
,is_410
,is_420
,best_pitch
,mpitch
;
2628 int horz_repl_factor
,interlace_factor
;
2629 int BytesPerPixel
,BytesPerUVPixel
,HorzUVSubSample
,VertUVSubSample
;
2630 int DisallowFourTapVertFiltering
,DisallowFourTapUVVertFiltering
;
2632 radeon_vid_stop_video();
2633 left
= config
->src
.x
<< 16;
2634 top
= config
->src
.y
<< 16;
2635 src_h
= config
->src
.h
;
2636 src_w
= config
->src
.w
;
2637 is_400
= is_410
= is_420
= 0;
2638 if(config
->fourcc
== IMGFMT_YV12
||
2639 config
->fourcc
== IMGFMT_I420
||
2640 config
->fourcc
== IMGFMT_IYUV
) is_420
= 1;
2641 if(config
->fourcc
== IMGFMT_YVU9
||
2642 config
->fourcc
== IMGFMT_IF09
) is_410
= 1;
2643 if(config
->fourcc
== IMGFMT_Y800
) is_400
= 1;
2644 best_pitch
= radeon_query_pitch(config
->fourcc
,&config
->src
.pitch
);
2645 mpitch
= best_pitch
-1;
2646 BytesPerOctWord
= 16;
2647 LogMemWordsInBytes
= 4;
2648 MemWordsInBytes
= 1<<LogMemWordsInBytes
;
2649 LogTileWidthInMemWords
= 2;
2650 TileWidthInMemWords
= 1<<LogTileWidthInMemWords
;
2651 TileWidthInBytes
= 1<<(LogTileWidthInMemWords
+LogMemWordsInBytes
);
2653 TileHeight
= 1<<LogTileHeight
;
2654 PageSizeInBytes
= 64*MemWordsInBytes
;
2657 switch(config
->fourcc
)
2667 case IMGFMT_I420
: pitch
= (src_w
+ mpitch
) & ~mpitch
;
2668 config
->dest
.pitch
.y
=
2669 config
->dest
.pitch
.u
=
2670 config
->dest
.pitch
.v
= best_pitch
;
2674 case IMGFMT_BGR32
: pitch
= (src_w
*4 + mpitch
) & ~mpitch
;
2675 config
->dest
.pitch
.y
=
2676 config
->dest
.pitch
.u
=
2677 config
->dest
.pitch
.v
= best_pitch
;
2681 default: /* RGB15, RGB16, YVYU, UYVY, YUY2 */
2682 pitch
= ((src_w
*2) + mpitch
) & ~mpitch
;
2683 config
->dest
.pitch
.y
=
2684 config
->dest
.pitch
.u
=
2685 config
->dest
.pitch
.v
= best_pitch
;
2688 besr
.load_prg_start
=0;
2690 switch(config
->fourcc
)
2694 case IMGFMT_BGR15
: besr
.surf_id
= SCALER_SOURCE_15BPP
>>8;
2695 besr
.load_prg_start
= 1;
2699 case IMGFMT_BGR16
: besr
.surf_id
= SCALER_SOURCE_16BPP
>>8;
2700 besr
.load_prg_start
= 1;
2704 case IMGFMT_BGR32
: besr
.surf_id
= SCALER_SOURCE_32BPP
>>8;
2705 besr
.load_prg_start
= 1;
2709 case IMGFMT_YVU9
: besr
.surf_id
= SCALER_SOURCE_YUV9
>>8;
2716 case IMGFMT_YV12
: besr
.surf_id
= SCALER_SOURCE_YUV12
>>8;
2720 case IMGFMT_UYVY
: besr
.surf_id
= SCALER_SOURCE_YVYU422
>>8;
2723 default: besr
.surf_id
= SCALER_SOURCE_VYUY422
>>8;
2726 switch (besr
.surf_id
)
2731 case 12: BytesPerPixel
= 2;
2733 case 6: BytesPerPixel
= 4;
2738 case 14: BytesPerPixel
= 1;
2740 default: BytesPerPixel
= 0;/*insert a debug statement here. */
2743 switch (besr
.surf_id
)
2746 case 4: BytesPerUVPixel
= 0;
2747 break;/* In RGB modes, the BytesPerUVPixel is don't care */
2749 case 12: BytesPerUVPixel
= 2;
2751 case 6: BytesPerUVPixel
= 0;
2752 break; /* In RGB modes, the BytesPerUVPixel is don't care */
2754 case 10: BytesPerUVPixel
= 1;
2757 case 14: BytesPerUVPixel
= 2;
2759 default: BytesPerUVPixel
= 0;/* insert a debug statement here. */
2763 switch (besr
.surf_id
)
2767 case 6: HorzUVSubSample
= 1;
2769 case 9: HorzUVSubSample
= 4;
2775 case 14: HorzUVSubSample
= 2;
2777 default: HorzUVSubSample
= 0;/* insert debug statement here. */
2780 switch (besr
.surf_id
)
2786 case 12: VertUVSubSample
= 1;
2788 case 9: VertUVSubSample
= 4;
2792 case 14: VertUVSubSample
= 2;
2794 default: VertUVSubSample
= 0;/* insert debug statment here. */
2797 DisallowFourTapVertFiltering
= 0; /* Allow it by default */
2798 DisallowFourTapUVVertFiltering
= 0; /* Allow it by default */
2799 LeftPixel
= config
->src
.x
;
2800 RightPixel
= config
->src
.w
-1;
2801 if(floor(config
->src
.x
/HorzUVSubSample
)<0) LeftUVPixel
= 0;
2802 else LeftUVPixel
= (int)floor(config
->src
.x
/HorzUVSubSample
);
2803 if(ceil((config
->src
.x
+config
->src
.w
)/HorzUVSubSample
) > config
->src
.w
/HorzUVSubSample
)
2804 RightUVPixel
= config
->src
.w
/HorzUVSubSample
- 1;
2805 else RightUVPixel
= (int)ceil((config
->src
.x
+config
->src
.w
)/HorzUVSubSample
) - 1;
2806 /* Top, Bottom and Right Crops can be out of range. The driver will program the hardware
2807 // to create a black border at the top and bottom. This is useful for DVD letterboxing. */
2808 SourceWidthInPixels
= (int)(config
->src
.w
+ 1);
2809 SourceUVWidthInPixels
= (int)(RightUVPixel
- LeftUVPixel
+ 1);
2811 SourceWidthInMemWords
= (int)(ceil(RightPixel
*BytesPerPixel
/ MemWordsInBytes
) -
2812 floor(LeftPixel
*BytesPerPixel
/ MemWordsInBytes
) + 1);
2813 /* SourceUVWidthInMemWords means Source_U_or_V_or_UV_WidthInMemWords depending on whether the UV is packed together of not. */
2814 SourceUVWidthInMemWords
= (int)(ceil(RightUVPixel
*BytesPerUVPixel
/
2815 MemWordsInBytes
) - floor(LeftUVPixel
*BytesPerUVPixel
/
2816 MemWordsInBytes
) + 1);
2818 switch (besr
.surf_id
)
2821 case 10: if ((ceil(SourceWidthInMemWords
/2)-1) * 2 > OV0LB_Rows
-1)
2823 RADEON_ASSERT("ceil(SourceWidthInMemWords/2)-1) * 2 > OV0LB_Rows-1\n");
2825 else if ((SourceWidthInMemWords
-1) * 2 > OV0LB_Rows
-1)
2827 DisallowFourTapVertFiltering
= 1;
2830 if ((ceil(SourceUVWidthInMemWords
/2)-1) * 4 + 1 > OV0LB_Rows
-1)
2832 /*CYCACC_ASSERT(0, "Image U plane width spans more octwords than supported by hardware.") */
2834 else if ((SourceUVWidthInMemWords
-1) * 4 + 1 > OV0LB_Rows
-1)
2836 DisallowFourTapUVVertFiltering
= 1;
2839 if ((ceil(SourceUVWidthInMemWords
/2)-1) * 4 + 3 > OV0LB_Rows
-1)
2841 /*CYCACC_ASSERT(0, "Image V plane width spans more octwords than supported by hardware.") */
2843 else if ((SourceUVWidthInMemWords
-1) * 4 + 3 > OV0LB_Rows
-1)
2845 DisallowFourTapUVVertFiltering
= 1;
2849 case 14: if ((ceil(SourceWidthInMemWords
/2)-1) * 2 > OV0LB_Rows
-1)
2851 RADEON_ASSERT("ceil(SourceWidthInMemWords/2)-1) * 2 > OV0LB_Rows-1\n");
2853 else if ((SourceWidthInMemWords
-1) * 2 > OV0LB_Rows
-1)
2855 DisallowFourTapVertFiltering
= 1;
2858 if ((ceil(SourceUVWidthInMemWords
/2)-1) * 2 + 1 > OV0LB_Rows
-1)
2860 /*CYCACC_ASSERT(0, "Image UV plane width spans more octwords than supported by hardware.") */
2862 else if ((SourceUVWidthInMemWords
-1) * 2 + 1 > OV0LB_Rows
-1)
2864 DisallowFourTapUVVertFiltering
= 1;
2871 case 12: if ((ceil(SourceWidthInMemWords
/2)-1) > OV0LB_Rows
-1)
2873 RADEON_ASSERT("(ceil(SourceWidthInMemWords/2)-1) > OV0LB_Rows-1\n")
2875 else if ((SourceWidthInMemWords
-1) > OV0LB_Rows
-1)
2877 DisallowFourTapVertFiltering
= 1;
2880 default: /* insert debug statement here. */
2883 dest_w
= config
->dest
.w
;
2884 dest_h
= config
->dest
.h
;
2885 if(radeon_is_dbl_scan()) dest_h
*= 2;
2886 besr
.dest_bpp
= radeon_vid_get_dbpp();
2887 besr
.fourcc
= config
->fourcc
;
2888 if(radeon_is_interlace()) interlace_factor
= 2;
2889 else interlace_factor
= 1;
2890 /* TODO: must be checked in doublescan mode!!! */
2891 if((besr
.chip_flags
&R_INTEGRATED
)==R_INTEGRATED
)
2893 /* Force the overlay clock on for integrated chips */
2894 OUTPLL(VCLK_ECP_CNTL
, (INPLL(VCLK_ECP_CNTL
) | (1<<18)));
2896 horz_repl_factor
= 1 << (uint32_t)((INPLL(VCLK_ECP_CNTL
) & 0x300) >> 8);
2897 H_scale_ratio
= (double)ceil(((double)dest_w
+1)/horz_repl_factor
)/src_w
;
2898 V_scale_ratio
= (double)(dest_h
+1)/src_h
;
2899 if(H_scale_ratio
< 0.5 && V_scale_ratio
< 0.5)
2901 val_OV0_P1_MAX_LN_IN_PER_LN_OUT
= 3;
2902 val_OV0_P23_MAX_LN_IN_PER_LN_OUT
= 2;
2905 if(H_scale_ratio
< 1 && V_scale_ratio
< 1)
2907 val_OV0_P1_MAX_LN_IN_PER_LN_OUT
= 2;
2908 val_OV0_P23_MAX_LN_IN_PER_LN_OUT
= 1;
2912 val_OV0_P1_MAX_LN_IN_PER_LN_OUT
= 1;
2913 val_OV0_P23_MAX_LN_IN_PER_LN_OUT
= 1;
2915 /* N.B.: Indeed it has 6.12 format but shifted on 8 to the left!!! */
2916 besr
.v_inc
= (uint16_t)((1./V_scale_ratio
)*(1<<12)*interlace_factor
+0.5);
2917 CRT_V_INC
= besr
.v_inc
/interlace_factor
;
2920 int ThereIsTwoTapVerticalFiltering
,DoNotUseMostRecentlyFetchedLine
;
2921 int P1GroupSize
= 0;
2924 int P23StepSize
= 0;
2929 DisallowFourTapVertFiltering
,
2930 DisallowFourTapUVVertFiltering
,
2932 &val_OV0_P1_H_STEP_BY
,
2934 &val_OV0_P23_H_STEP_BY
,
2939 if(H_scale_ratio
> MinHScaleHard
)
2941 h_inc
= (src_w
<< 12) / dest_w
;
2942 besr
.step_by
= 0x0101;
2943 switch (besr
.surf_id
)
2948 besr
.h_inc
= (h_inc
)|(h_inc
<<16);
2951 besr
.h_inc
= h_inc
| ((h_inc
>> 2) << 16);
2954 besr
.h_inc
= h_inc
| ((h_inc
>> 1) << 16);
2959 P23GroupSize
= 2; /* Current vaue for all modes */
2961 besr
.horz_pick_nearest
=0;
2962 DoNotUseMostRecentlyFetchedLine
=0;
2963 ThereIsTwoTapVerticalFiltering
= (val_OV0_P1_H_STEP_BY
!=0) || (val_OV0_P23_H_STEP_BY
!=0);
2964 if (ThereIsTwoTapVerticalFiltering
&& DoNotUseMostRecentlyFetchedLine
)
2965 besr
.vert_pick_nearest
= 1;
2967 besr
.vert_pick_nearest
= 0;
2969 ComputeXStartEnd(is_400
,LeftPixel
,LeftUVPixel
,MemWordsInBytes
,BytesPerPixel
,
2970 SourceWidthInPixels
,P1StepSize
,BytesPerUVPixel
,
2971 SourceUVWidthInPixels
,P23StepSize
,&val_OV0_P1_X_START
,&val_OV0_P2_X_START
);
2973 if(H_scale_ratio
> MinHScaleHard
)
2976 tmp
= (left
& 0x0003ffff) + 0x00028000 + (h_inc
<< 3);
2977 besr
.p1_h_accum_init
= ((tmp
<< 4) & 0x000f8000) |
2978 ((tmp
<< 12) & 0xf0000000);
2980 tmp
= (top
& 0x0000ffff) + 0x00018000;
2981 besr
.p1_v_accum_init
= ((tmp
<< 4) & OV0_P1_V_ACCUM_INIT_MASK
)
2982 |(OV0_P1_MAX_LN_IN_PER_LN_OUT
& 1);
2983 tmp
= ((left
>> 1) & 0x0001ffff) + 0x00028000 + (h_inc
<< 2);
2984 besr
.p23_h_accum_init
= ((tmp
<< 4) & 0x000f8000) |
2985 ((tmp
<< 12) & 0x70000000);
2987 tmp
= ((top
>> 1) & 0x0000ffff) + 0x00018000;
2988 besr
.p23_v_accum_init
= (is_420
||is_410
) ?
2989 ((tmp
<< 4) & OV0_P23_V_ACCUM_INIT_MASK
)
2990 |(OV0_P23_MAX_LN_IN_PER_LN_OUT
& 1) : 0;
2993 ComputeAccumInit( val_OV0_P1_X_START
,val_OV0_P2_X_START
,
2994 val_OV0_P1_H_INC
,val_OV0_P23_H_INC
,
2995 val_OV0_P1_H_STEP_BY
,val_OV0_P23_H_STEP_BY
,
2996 CRT_V_INC
,P1GroupSize
,P23GroupSize
,
2997 val_OV0_P1_MAX_LN_IN_PER_LN_OUT
,
2998 val_OV0_P23_MAX_LN_IN_PER_LN_OUT
);
3001 /* keep everything in 16.16 */
3002 besr
.base_addr
= INREG(DISPLAY_BASE_ADDR
);
3003 config
->offsets
[0] = 0;
3004 for(i
=1;i
<besr
.vid_nbufs
;i
++)
3005 config
->offsets
[i
] = config
->offsets
[i
-1]+config
->frame_size
;
3006 if(is_420
|| is_410
|| is_400
)
3008 uint32_t d1line
,d2line
,d3line
;
3012 d2line
= src_h
*pitch
+(d1line
>>2);
3013 d3line
= d2line
+((src_h
*pitch
)>>2);
3018 d2line
= src_h
*pitch
+(d1line
>>4);
3019 d3line
= d2line
+((src_h
*pitch
)>>4);
3026 d1line
+= (left
>> 16) & ~15;
3029 d2line
+= (left
>> 17) & ~15;
3030 d3line
+= (left
>> 17) & ~15;
3034 d2line
+= (left
>> 18) & ~15;
3035 d3line
+= (left
>> 18) & ~15;
3037 config
->offset
.y
= d1line
& VIF_BUF0_BASE_ADRS_MASK
;
3040 config
->offset
.v
= 0;
3041 config
->offset
.u
= 0;
3045 config
->offset
.v
= d2line
& VIF_BUF1_BASE_ADRS_MASK
;
3046 config
->offset
.u
= d3line
& VIF_BUF2_BASE_ADRS_MASK
;
3048 for(i
=0;i
<besr
.vid_nbufs
;i
++)
3050 besr
.vid_buf_base_adrs_y
[i
]=((radeon_overlay_off
+config
->offsets
[i
]+config
->offset
.y
)&VIF_BUF0_BASE_ADRS_MASK
);
3053 besr
.vid_buf_base_adrs_v
[i
]=0;
3054 besr
.vid_buf_base_adrs_u
[i
]=0;
3058 if (besr
.fourcc
== IMGFMT_I420
|| besr
.fourcc
== IMGFMT_IYUV
)
3060 besr
.vid_buf_base_adrs_u
[i
]=((radeon_overlay_off
+config
->offsets
[i
]+config
->offset
.v
)&VIF_BUF1_BASE_ADRS_MASK
)|VIF_BUF1_PITCH_SEL
;
3061 besr
.vid_buf_base_adrs_v
[i
]=((radeon_overlay_off
+config
->offsets
[i
]+config
->offset
.u
)&VIF_BUF2_BASE_ADRS_MASK
)|VIF_BUF2_PITCH_SEL
;
3065 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
;
3066 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
;
3070 config
->offset
.y
= ((besr
.vid_buf_base_adrs_y
[0])&VIF_BUF0_BASE_ADRS_MASK
) - radeon_overlay_off
;
3073 config
->offset
.v
= 0;
3074 config
->offset
.u
= 0;
3078 config
->offset
.v
= ((besr
.vid_buf_base_adrs_v
[0])&VIF_BUF1_BASE_ADRS_MASK
) - radeon_overlay_off
;
3079 config
->offset
.u
= ((besr
.vid_buf_base_adrs_u
[0])&VIF_BUF2_BASE_ADRS_MASK
) - radeon_overlay_off
;
3084 config
->offset
.y
= config
->offset
.u
= config
->offset
.v
= ((left
& ~7) << 1)&VIF_BUF0_BASE_ADRS_MASK
;
3085 for(i
=0;i
<besr
.vid_nbufs
;i
++)
3087 besr
.vid_buf_base_adrs_y
[i
] =
3088 besr
.vid_buf_base_adrs_u
[i
] =
3089 besr
.vid_buf_base_adrs_v
[i
] = radeon_overlay_off
+ config
->offsets
[i
] + config
->offset
.y
;
3092 leftUV
= (left
>> (is_410
?18:17)) & 15;
3093 left
= (left
>> 16) & 15;
3094 besr
.y_x_start
= (config
->dest
.x
+X_ADJUST
) | (config
->dest
.y
<< 16);
3095 besr
.y_x_end
= (config
->dest
.x
+ dest_w
+X_ADJUST
) | ((config
->dest
.y
+ dest_h
) << 16);
3096 ComputeBorders(config
,VertUVSubSample
);
3097 besr
.vid_buf_pitch0_value
= pitch
;
3098 besr
.vid_buf_pitch1_value
= is_410
? pitch
>>2 : is_420
? pitch
>>1 : pitch
;
3099 /* ********************************************************* */
3100 /* ** Calculate programmable coefficients as needed */
3101 /* ********************************************************* */
3103 /* ToDo_Active: When in pick nearest mode, we need to program the filter tap zero */
3104 /* coefficients to 0, 32, 0, 0. Or use hard coded coefficients. */
3105 if(H_scale_ratio
> MinHScaleHard
) besr
.filter_cntl
|= FILTER_HARDCODED_COEF
;
3108 FilterSetup (val_OV0_P1_H_INC
);
3109 /* ToDo_Active: Must add the smarts into the driver to decide what type of filtering it */
3110 /* would like to do. For now, we let the test application decide. */
3111 besr
.filter_cntl
= FILTER_PROGRAMMABLE_COEF
;
3112 if(DisallowFourTapVertFiltering
)
3113 besr
.filter_cntl
|= FILTER_HARD_SCALE_VERT_Y
;
3114 if(DisallowFourTapUVVertFiltering
)
3115 besr
.filter_cntl
|= FILTER_HARD_SCALE_VERT_UV
;
3120 static void radeon_compute_framesize(vidix_playback_t
*info
)
3122 unsigned pitch
,awidth
,dbpp
;
3123 pitch
= radeon_query_pitch(info
->fourcc
,&info
->src
.pitch
);
3124 dbpp
= radeon_vid_get_dbpp();
3125 switch(info
->fourcc
)
3128 awidth
= (info
->src
.w
+ (pitch
-1)) & ~(pitch
-1);
3129 info
->frame_size
= awidth
*info
->src
.h
;
3133 awidth
= (info
->src
.w
+ (pitch
-1)) & ~(pitch
-1);
3134 info
->frame_size
= awidth
*(info
->src
.h
+info
->src
.h
/8);
3139 awidth
= (info
->src
.w
+ (pitch
-1)) & ~(pitch
-1);
3140 info
->frame_size
= awidth
*(info
->src
.h
+info
->src
.h
/2);
3144 awidth
= (info
->src
.w
*4 + (pitch
-1)) & ~(pitch
-1);
3145 info
->frame_size
= awidth
*info
->src
.h
;
3147 /* YUY2 YVYU, RGB15, RGB16 */
3149 awidth
= (info
->src
.w
*2 + (pitch
-1)) & ~(pitch
-1);
3150 info
->frame_size
= awidth
*info
->src
.h
;
3153 info
->frame_size
= (info
->frame_size
+4095)&~4095;
3156 static int radeon_config_playback(vidix_playback_t
*info
)
3158 unsigned rgb_size
,nfr
;
3159 uint32_t radeon_video_size
;
3160 if(!is_supported_fourcc(info
->fourcc
)) return ENOSYS
;
3161 if(info
->num_frames
>VID_PLAY_MAXFRAMES
) info
->num_frames
=VID_PLAY_MAXFRAMES
;
3162 if(info
->num_frames
==1) besr
.double_buff
=0;
3163 else besr
.double_buff
=1;
3164 radeon_compute_framesize(info
);
3166 rgb_size
= radeon_get_xres()*radeon_get_yres()*((radeon_vid_get_dbpp()+7)/8);
3167 nfr
= info
->num_frames
;
3168 radeon_video_size
= radeon_ram_size
;
3171 radeon_overlay_off
= radeon_video_size
- info
->frame_size
*nfr
;
3172 #if !defined (RAGE128) && defined(HAVE_X11)
3173 radeon_overlay_off
-= firegl_shift
;
3175 radeon_overlay_off
&= 0xffff0000;
3176 if(radeon_overlay_off
>= (int)rgb_size
) break;
3180 nfr
= info
->num_frames
;
3183 radeon_overlay_off
= radeon_video_size
- info
->frame_size
*nfr
;
3184 #if !defined (RAGE128) && defined(HAVE_X11)
3185 radeon_overlay_off
-= firegl_shift
;
3187 radeon_overlay_off
&= 0xffff0000;
3188 if(radeon_overlay_off
> 0) break;
3191 if(nfr
<= 0) return EINVAL
;
3192 info
->num_frames
= nfr
;
3193 besr
.vid_nbufs
= info
->num_frames
;
3194 info
->dga_addr
= (char *)radeon_mem_base
+ radeon_overlay_off
;
3195 radeon_vid_init_video(info
);
3199 static int radeon_playback_on(void)
3204 radeon_vid_display_video();
3206 dh
= (besr
.y_x_end
>> 16) - (besr
.y_x_start
>> 16);
3207 dw
= (besr
.y_x_end
& 0xFFFF) - (besr
.y_x_start
& 0xFFFF);
3208 if(dw
== radeon_get_xres() || dh
== radeon_get_yres()) radeon_vid_exclusive();
3209 else radeon_vid_non_exclusive();
3214 static int radeon_playback_off(void)
3216 radeon_vid_stop_video();
3220 static int radeon_frame_select(unsigned frame
)
3223 int prev_frame
= (frame
-1+besr
.vid_nbufs
) % besr
.vid_nbufs
;
3225 buf3-5 always should point onto second buffer for better
3226 deinterlacing and TV-in
3228 if(!besr
.double_buff
) return 0;
3229 if(frame
> besr
.vid_nbufs
) frame
= besr
.vid_nbufs
-1;
3230 if(prev_frame
> (int)besr
.vid_nbufs
) prev_frame
= besr
.vid_nbufs
-1;
3231 off
[0] = besr
.vid_buf_base_adrs_y
[frame
];
3232 off
[1] = besr
.vid_buf_base_adrs_v
[frame
];
3233 off
[2] = besr
.vid_buf_base_adrs_u
[frame
];
3234 off
[3] = besr
.vid_buf_base_adrs_y
[prev_frame
];
3235 off
[4] = besr
.vid_buf_base_adrs_v
[prev_frame
];
3236 off
[5] = besr
.vid_buf_base_adrs_u
[prev_frame
];
3237 radeon_fifo_wait(8);
3238 OUTREG(OV0_REG_LOAD_CNTL
, REG_LD_CTL_LOCK
);
3239 radeon_engine_idle();
3240 while(!(INREG(OV0_REG_LOAD_CNTL
)®_LD_CTL_LOCK_READBACK
));
3241 OUTREG(OV0_VID_BUF0_BASE_ADRS
, off
[0]);
3242 OUTREG(OV0_VID_BUF1_BASE_ADRS
, off
[1]);
3243 OUTREG(OV0_VID_BUF2_BASE_ADRS
, off
[2]);
3244 OUTREG(OV0_VID_BUF3_BASE_ADRS
, off
[3]);
3245 OUTREG(OV0_VID_BUF4_BASE_ADRS
, off
[4]);
3246 OUTREG(OV0_VID_BUF5_BASE_ADRS
, off
[5]);
3247 OUTREG(OV0_REG_LOAD_CNTL
, 0);
3248 if(besr
.vid_nbufs
== 2) radeon_wait_vsync();
3249 if(__verbose
> VERBOSE_LEVEL
) radeon_vid_dump_regs();
3253 static vidix_video_eq_t equal
=
3255 VEQ_CAP_BRIGHTNESS
| VEQ_CAP_SATURATION
3257 | VEQ_CAP_CONTRAST
| VEQ_CAP_HUE
| VEQ_CAP_RGB_INTENSITY
3260 0, 0, 0, 0, 0, 0, 0, 0 };
3262 static int radeon_get_eq(vidix_video_eq_t
* eq
)
3264 memcpy(eq
,&equal
,sizeof(vidix_video_eq_t
));
3269 #define RTFSaturation(a) (1.0 + ((a)*1.0)/1000.0)
3270 #define RTFBrightness(a) (((a)*1.0)/2000.0)
3271 #define RTFIntensity(a) (((a)*1.0)/2000.0)
3272 #define RTFContrast(a) (1.0 + ((a)*1.0)/1000.0)
3273 #define RTFHue(a) (((a)*3.1416)/1000.0)
3274 #define RTFCheckParam(a) {if((a)<-1000) (a)=-1000; if((a)>1000) (a)=1000;}
3277 static int radeon_set_eq(const vidix_video_eq_t
* eq
)
3284 if(eq
->cap
& VEQ_CAP_BRIGHTNESS
) equal
.brightness
= eq
->brightness
;
3285 if(eq
->cap
& VEQ_CAP_CONTRAST
) equal
.contrast
= eq
->contrast
;
3286 if(eq
->cap
& VEQ_CAP_SATURATION
) equal
.saturation
= eq
->saturation
;
3287 if(eq
->cap
& VEQ_CAP_HUE
) equal
.hue
= eq
->hue
;
3288 if(eq
->cap
& VEQ_CAP_RGB_INTENSITY
)
3290 equal
.red_intensity
= eq
->red_intensity
;
3291 equal
.green_intensity
= eq
->green_intensity
;
3292 equal
.blue_intensity
= eq
->blue_intensity
;
3294 equal
.flags
= eq
->flags
;
3296 br
= equal
.brightness
* 64 / 1000;
3297 if(br
< -64) br
= -64; if(br
> 63) br
= 63;
3298 sat
= (equal
.saturation
*31 + 31000) / 2000;
3299 if(sat
< 0) sat
= 0; if(sat
> 31) sat
= 31;
3300 OUTREG(OV0_COLOUR_CNTL
, (br
& 0x7f) | (sat
<< 8) | (sat
<< 16));
3302 itu_space
= equal
.flags
== VEQ_FLG_ITU_R_BT_709
? 1 : 0;
3303 RTFCheckParam(equal
.brightness
);
3304 RTFCheckParam(equal
.saturation
);
3305 RTFCheckParam(equal
.contrast
);
3306 RTFCheckParam(equal
.hue
);
3307 RTFCheckParam(equal
.red_intensity
);
3308 RTFCheckParam(equal
.green_intensity
);
3309 RTFCheckParam(equal
.blue_intensity
);
3310 radeon_set_transform(RTFBrightness(equal
.brightness
),
3311 RTFContrast(equal
.contrast
),
3312 RTFSaturation(equal
.saturation
),
3314 RTFIntensity(equal
.red_intensity
),
3315 RTFIntensity(equal
.green_intensity
),
3316 RTFIntensity(equal
.blue_intensity
),
3322 static int radeon_playback_set_deint(const vidix_deinterlace_t
* info
)
3328 case CFG_NON_INTERLACED
:
3329 besr
.deinterlace_on
= 0;
3331 case CFG_EVEN_ODD_INTERLACING
:
3332 case CFG_INTERLACED
:
3333 besr
.deinterlace_on
= 1;
3334 besr
.deinterlace_pattern
= 0x900AAAAA;
3336 case CFG_ODD_EVEN_INTERLACING
:
3337 besr
.deinterlace_on
= 1;
3338 besr
.deinterlace_pattern
= 0x00055555;
3340 case CFG_UNIQUE_INTERLACING
:
3341 besr
.deinterlace_on
= 1;
3342 besr
.deinterlace_pattern
= info
->deinterlace_pattern
;
3345 OUTREG(OV0_REG_LOAD_CNTL
, REG_LD_CTL_LOCK
);
3346 radeon_engine_idle();
3347 while(!(INREG(OV0_REG_LOAD_CNTL
)®_LD_CTL_LOCK_READBACK
));
3348 radeon_fifo_wait(15);
3349 sflg
= INREG(OV0_SCALE_CNTL
);
3350 if(besr
.deinterlace_on
)
3352 OUTREG(OV0_SCALE_CNTL
,sflg
| SCALER_ADAPTIVE_DEINT
);
3353 OUTREG(OV0_DEINTERLACE_PATTERN
,besr
.deinterlace_pattern
);
3355 else OUTREG(OV0_SCALE_CNTL
,sflg
& (~SCALER_ADAPTIVE_DEINT
));
3356 OUTREG(OV0_REG_LOAD_CNTL
, 0);
3360 static int radeon_playback_get_deint(vidix_deinterlace_t
* info
)
3362 if(!besr
.deinterlace_on
) info
->flags
= CFG_NON_INTERLACED
;
3365 info
->flags
= CFG_UNIQUE_INTERLACING
;
3366 info
->deinterlace_pattern
= besr
.deinterlace_pattern
;
3373 static vidix_grkey_t radeon_grkey
;
3375 static int set_gr_key( void )
3379 besr
.merge_cntl
= 0xff000000 | /* overlay alpha */
3380 0x00ff0000; /* graphic alpha */
3381 if(radeon_grkey
.ckey
.op
== CKEY_TRUE
)
3383 int dbpp
=radeon_vid_get_dbpp();
3390 if((besr
.chip_flags
&R_100
)!=R_100
)
3391 besr
.graphics_key_clr
=
3392 ((radeon_grkey
.ckey
.blue
&0xF8))
3393 | ((radeon_grkey
.ckey
.green
&0xF8)<<8)
3394 | ((radeon_grkey
.ckey
.red
&0xF8)<<16);
3397 besr
.graphics_key_clr
=
3398 ((radeon_grkey
.ckey
.blue
&0xF8)>>3)
3399 | ((radeon_grkey
.ckey
.green
&0xF8)<<2)
3400 | ((radeon_grkey
.ckey
.red
&0xF8)<<7);
3404 /* This test may be too general/specific */
3405 if((besr
.chip_flags
&R_100
)!=R_100
)
3406 besr
.graphics_key_clr
=
3407 ((radeon_grkey
.ckey
.blue
&0xF8))
3408 | ((radeon_grkey
.ckey
.green
&0xFC)<<8)
3409 | ((radeon_grkey
.ckey
.red
&0xF8)<<16);
3412 besr
.graphics_key_clr
=
3413 ((radeon_grkey
.ckey
.blue
&0xF8)>>3)
3414 | ((radeon_grkey
.ckey
.green
&0xFC)<<3)
3415 | ((radeon_grkey
.ckey
.red
&0xF8)<<8);
3419 besr
.graphics_key_clr
=
3420 ((radeon_grkey
.ckey
.blue
&0xFF))
3421 | ((radeon_grkey
.ckey
.green
&0xFF)<<8)
3422 | ((radeon_grkey
.ckey
.red
&0xFF)<<16);
3426 besr
.graphics_key_msk
=0;
3427 besr
.graphics_key_clr
=0;
3430 besr
.graphics_key_msk
=(1<<dbpp
)-1;
3431 besr
.ckey_cntl
= VIDEO_KEY_FN_TRUE
|GRAPHIC_KEY_FN_NE
|CMP_MIX_AND
;
3433 besr
.graphics_key_msk
=besr
.graphics_key_clr
;
3434 besr
.ckey_cntl
= VIDEO_KEY_FN_TRUE
|CMP_MIX_AND
|GRAPHIC_KEY_FN_EQ
;
3437 else if(radeon_grkey
.ckey
.op
== CKEY_ALPHA
)
3439 int dbpp
=radeon_vid_get_dbpp();
3446 besr
.graphics_key_msk
=0;
3447 besr
.graphics_key_clr
=0;
3448 besr
.ckey_cntl
= VIDEO_KEY_FN_TRUE
|GRAPHIC_KEY_FN_TRUE
|CMP_MIX_AND
;
3449 besr
.merge_cntl
= 0xff000000 | /* overlay alpha */
3450 0x00ff0000 | /* graphic alpha */
3451 0x00000001; /* DISP_ALPHA_MODE_PER_PIXEL */
3455 besr
.graphics_key_msk
=0;
3456 besr
.graphics_key_clr
=0;
3457 besr
.ckey_cntl
= VIDEO_KEY_FN_TRUE
|GRAPHIC_KEY_FN_TRUE
|CMP_MIX_AND
;
3464 besr
.graphics_key_msk
=0;
3465 besr
.graphics_key_clr
=0;
3466 besr
.ckey_cntl
= VIDEO_KEY_FN_TRUE
|GRAPHIC_KEY_FN_TRUE
|CMP_MIX_AND
;
3468 radeon_fifo_wait(3);
3469 OUTREG(OV0_GRAPHICS_KEY_MSK
, besr
.graphics_key_msk
);
3470 OUTREG(OV0_GRAPHICS_KEY_CLR
, besr
.graphics_key_clr
);
3471 OUTREG(OV0_KEY_CNTL
,besr
.ckey_cntl
);
3472 OUTREG(DISP_MERGE_CNTL
, besr
.merge_cntl
);
3476 static int radeon_get_gkey(vidix_grkey_t
*grkey
)
3478 memcpy(grkey
, &radeon_grkey
, sizeof(vidix_grkey_t
));
3482 static int radeon_set_gkey(const vidix_grkey_t
*grkey
)
3484 memcpy(&radeon_grkey
, grkey
, sizeof(vidix_grkey_t
));
3485 return (set_gr_key());
3489 VDXDriver rage128_drv
= {
3492 VDXDriver radeon_drv
= {
3497 .probe
= radeon_probe
,
3498 .get_caps
= radeon_get_caps
,
3499 .query_fourcc
= radeon_query_fourcc
,
3500 .init
= radeon_init
,
3501 .destroy
= radeon_destroy
,
3502 .config_playback
= radeon_config_playback
,
3503 .playback_on
= radeon_playback_on
,
3504 .playback_off
= radeon_playback_off
,
3505 .frame_sel
= radeon_frame_select
,
3506 .get_eq
= radeon_get_eq
,
3507 .set_eq
= radeon_set_eq
,
3508 .get_deint
= radeon_playback_get_deint
,
3509 .set_deint
= radeon_playback_set_deint
,
3510 .get_gkey
= radeon_get_gkey
,
3511 .set_gkey
= radeon_set_gkey
,