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(DISP_MERGE_CNTL
),
259 DECLARE_VREG(DMA_GUI_TABLE_ADDR
),
260 DECLARE_VREG(DMA_GUI_SRC_ADDR
),
261 DECLARE_VREG(DMA_GUI_DST_ADDR
),
262 DECLARE_VREG(DMA_GUI_COMMAND
),
263 DECLARE_VREG(DMA_GUI_STATUS
),
264 DECLARE_VREG(DMA_GUI_ACT_DSCRPTR
),
265 DECLARE_VREG(DMA_VID_SRC_ADDR
),
266 DECLARE_VREG(DMA_VID_DST_ADDR
),
267 DECLARE_VREG(DMA_VID_COMMAND
),
268 DECLARE_VREG(DMA_VID_STATUS
),
269 DECLARE_VREG(DMA_VID_ACT_DSCRPTR
),
273 #define R_FAMILY 0x000000FF
274 #define R_100 0x00000001
275 #define R_120 0x00000002
276 #define R_150 0x00000004
277 #define R_200 0x00000008
278 #define R_250 0x00000010
279 #define R_280 0x00000020
280 #define R_300 0x00000040
281 #define R_350 0x00000080
282 #define R_370 0x00000100
283 #define R_380 0x00000200
284 #define R_420 0x00000400
285 #define R_430 0x00000800
286 #define R_480 0x00001000
287 #define R_OVL_SHIFT 0x01000000
288 #define R_INTEGRATED 0x02000000
289 #define R_PCIE 0x04000000
291 typedef struct ati_card_ids_s
297 static const ati_card_ids_t ati_card_ids
[] =
301 This driver should be compatible with Rage128 (pro) chips.
302 (include adaptive deinterlacing!!!).
303 Moreover: the same logic can be used with Mach64 chips.
304 (I mean: mach64xx, 3d rage, 3d rage IIc, 3D rage pro, 3d rage mobility).
305 but they are incompatible by i/o ports. So if enthusiasts will want
306 then they can redefine OUTREG and INREG macros and redefine OV0_*
307 constants. Also it seems that mach64 chips supports only: YUY2, YV12, UYVY
308 fourccs (422 and 420 formats only).
311 { DEVICE_ATI_RAGE_128_PA_PRO
, 0 },
312 { DEVICE_ATI_RAGE_128_PB_PRO
, 0 },
313 { DEVICE_ATI_RAGE_128_PC_PRO
, 0 },
314 { DEVICE_ATI_RAGE_128_PD_PRO
, 0 },
315 { DEVICE_ATI_RAGE_128_PE_PRO
, 0 },
316 { DEVICE_ATI_RAGE_128_PF_PRO
, 0 },
318 { DEVICE_ATI_RAGE_128_PG_PRO
, 0 },
319 { DEVICE_ATI_RAGE_128_PH_PRO
, 0 },
320 { DEVICE_ATI_RAGE_128_PI_PRO
, 0 },
321 { DEVICE_ATI_RAGE_128_PJ_PRO
, 0 },
322 { DEVICE_ATI_RAGE_128_PK_PRO
, 0 },
323 { DEVICE_ATI_RAGE_128_PL_PRO
, 0 },
324 { DEVICE_ATI_RAGE_128_PM_PRO
, 0 },
325 { DEVICE_ATI_RAGE_128_PN_PRO
, 0 },
326 { DEVICE_ATI_RAGE_128_PO_PRO
, 0 },
327 { DEVICE_ATI_RAGE_128_PP_PRO
, 0 },
328 { DEVICE_ATI_RAGE_128_PQ_PRO
, 0 },
329 { DEVICE_ATI_RAGE_128_PR_PRO
, 0 },
330 { DEVICE_ATI_RAGE_128_PS_PRO
, 0 },
331 { DEVICE_ATI_RAGE_128_PT_PRO
, 0 },
332 { DEVICE_ATI_RAGE_128_PU_PRO
, 0 },
333 { DEVICE_ATI_RAGE_128_PV_PRO
, 0 },
334 { DEVICE_ATI_RAGE_128_PW_PRO
, 0 },
335 { DEVICE_ATI_RAGE_128_PX_PRO
, 0 },
337 { DEVICE_ATI_RAGE_128_RE_SG
, 0 },
338 { DEVICE_ATI_RAGE_128_RF_SG
, 0 },
339 { DEVICE_ATI_RAGE_128_RG
, 0 },
340 { DEVICE_ATI_RAGE_128_RK_VR
, 0 },
341 { DEVICE_ATI_RAGE_128_RL_VR
, 0 },
342 { DEVICE_ATI_RAGE_128_SE_4X
, 0 },
343 { DEVICE_ATI_RAGE_128_SF_4X
, 0 },
344 { DEVICE_ATI_RAGE_128_SG_4X
, 0 },
345 { DEVICE_ATI_RAGE_128_SH
, 0 },
346 { DEVICE_ATI_RAGE_128_SK_4X
, 0 },
347 { DEVICE_ATI_RAGE_128_SL_4X
, 0 },
348 { DEVICE_ATI_RAGE_128_SM_4X
, 0 },
349 { DEVICE_ATI_RAGE_128_4X
, 0 },
350 { DEVICE_ATI_RAGE_128_PRO
, 0 },
351 { DEVICE_ATI_RAGE_128_PRO2
, 0 },
352 { DEVICE_ATI_RAGE_128_PRO3
, 0 },
353 /* these seem to be based on rage 128 instead of mach64 */
354 { DEVICE_ATI_RAGE_MOBILITY_M3
, 0 },
355 { DEVICE_ATI_RAGE_MOBILITY_M32
, 0 },
357 /* Radeon1 (indeed: Rage 256 Pro ;) */
358 { DEVICE_ATI_RADEON_R100_QD
, R_100
|R_OVL_SHIFT
},
359 { DEVICE_ATI_RADEON_R100_QE
, R_100
|R_OVL_SHIFT
},
360 { DEVICE_ATI_RADEON_R100_QF
, R_100
|R_OVL_SHIFT
},
361 { DEVICE_ATI_RADEON_R100_QG
, R_100
|R_OVL_SHIFT
},
362 { DEVICE_ATI_RADEON_IGP_320
, R_150
|R_OVL_SHIFT
|R_INTEGRATED
},
363 { DEVICE_ATI_RADEON_MOBILITY_U1
, R_150
|R_OVL_SHIFT
|R_INTEGRATED
},
364 { DEVICE_ATI_RADEON_RV100_QY
, R_120
|R_OVL_SHIFT
},
365 { DEVICE_ATI_RADEON_RV100_QZ
, R_120
|R_OVL_SHIFT
},
366 { DEVICE_ATI_RADEON_MOBILITY_M7
, R_150
|R_OVL_SHIFT
},
367 { DEVICE_ATI_RADEON_RV200_LX
, R_150
|R_OVL_SHIFT
},
368 { DEVICE_ATI_RADEON_MOBILITY_M6
, R_120
|R_OVL_SHIFT
},
369 { DEVICE_ATI_RADEON_MOBILITY_M62
, R_120
|R_OVL_SHIFT
},
370 /* Radeon2 (indeed: Rage 512 Pro ;) */
371 { DEVICE_ATI_R200_BB_RADEON
, R_200
},
372 { DEVICE_ATI_R200_BC_RADEON
, R_200
},
373 { DEVICE_ATI_RADEON_R200_QH
, R_200
},
374 { DEVICE_ATI_RADEON_R200_QI
, R_200
},
375 { DEVICE_ATI_RADEON_R200_QJ
, R_200
},
376 { DEVICE_ATI_RADEON_R200_QK
, R_200
},
377 { DEVICE_ATI_RADEON_R200_QL
, R_200
},
378 { DEVICE_ATI_RADEON_R200_QM
, R_200
},
379 { DEVICE_ATI_RADEON_R200_QN
, R_200
},
380 { DEVICE_ATI_RADEON_R200_QO
, R_200
},
381 { DEVICE_ATI_RADEON_R200_QH2
, R_200
},
382 { DEVICE_ATI_RADEON_R200_QI2
, R_200
},
383 { DEVICE_ATI_RADEON_R200_QJ2
, R_200
},
384 { DEVICE_ATI_RADEON_R200_QK2
, R_200
},
385 { DEVICE_ATI_RADEON_R200_QL2
, R_200
},
386 { DEVICE_ATI_RADEON_RV200_QW
, R_150
|R_OVL_SHIFT
},
387 { DEVICE_ATI_RADEON_RV200_QX
, R_150
|R_OVL_SHIFT
},
388 { DEVICE_ATI_RADEON_IGP330_340_350
,R_200
|R_INTEGRATED
},
389 { DEVICE_ATI_RADEON_IGP_330M_340M_350M
,R_200
|R_INTEGRATED
},
390 { DEVICE_ATI_RADEON_RV250_IG
, R_250
|R_OVL_SHIFT
},
391 { DEVICE_ATI_RADEON_7000_IGP
, R_250
|R_OVL_SHIFT
|R_INTEGRATED
},
392 { DEVICE_ATI_RADEON_MOBILITY_7000
, R_250
|R_OVL_SHIFT
|R_INTEGRATED
},
393 { DEVICE_ATI_RADEON_RV250_ID
, R_250
|R_OVL_SHIFT
},
394 { DEVICE_ATI_RADEON_RV250_IE
, R_250
|R_OVL_SHIFT
},
395 { DEVICE_ATI_RADEON_RV250_IF
, R_250
|R_OVL_SHIFT
},
396 { DEVICE_ATI_RADEON_RV250_IG
, R_250
|R_OVL_SHIFT
},
397 { DEVICE_ATI_RADEON_R250_LD
, R_250
|R_OVL_SHIFT
},
398 { DEVICE_ATI_RADEON_R250_LE
, R_250
|R_OVL_SHIFT
},
399 { DEVICE_ATI_RADEON_R250_MOBILITY
, R_250
|R_OVL_SHIFT
},
400 { DEVICE_ATI_RADEON_R250_LG
, R_250
|R_OVL_SHIFT
},
401 { DEVICE_ATI_RV250_RADEON_9000
, R_250
|R_OVL_SHIFT
},
402 { DEVICE_ATI_RADEON_RV250_RADEON2
, R_250
|R_OVL_SHIFT
},
403 { DEVICE_ATI_RV280_RADEON_9200
, R_280
},
404 { DEVICE_ATI_RV280_RADEON_92002
, R_280
},
405 { DEVICE_ATI_RV280_RADEON_92003
, R_280
},
406 { DEVICE_ATI_RV280_RADEON_92004
, R_280
},
407 { DEVICE_ATI_RV280_RADEON_92005
, R_280
},
408 { DEVICE_ATI_RV280_RADEON_92006
, R_280
},
409 { DEVICE_ATI_RV280_RADEON_92007
, R_280
},
410 { DEVICE_ATI_M9_5C61_RADEON
, R_280
},
411 { DEVICE_ATI_M9_5C63_RADEON
, R_280
},
412 /* Radeon3 (indeed: Rage 1024 Pro ;) */
413 { DEVICE_ATI_R300_AG_FIREGL
, R_300
},
414 { DEVICE_ATI_RADEON_R300_ND
, R_300
},
415 { DEVICE_ATI_RADEON_R300_NE
, R_300
},
416 { DEVICE_ATI_RADEON_R300_NG
, R_300
},
417 { DEVICE_ATI_R300_AD_RADEON
, R_300
},
418 { DEVICE_ATI_R300_AE_RADEON
, R_300
},
419 { DEVICE_ATI_R300_AF_RADEON
, R_300
},
420 { DEVICE_ATI_RADEON_9100_IGP2
, R_300
|R_OVL_SHIFT
|R_INTEGRATED
},
421 { DEVICE_ATI_RS300M_AGP_RADEON
, R_300
|R_INTEGRATED
},
422 { DEVICE_ATI_RS482_RADEON_XPRESS
, R_350
|R_INTEGRATED
},
423 { DEVICE_ATI_R350_AH_RADEON
, R_350
},
424 { DEVICE_ATI_R350_AI_RADEON
, R_350
},
425 { DEVICE_ATI_R350_AJ_RADEON
, R_350
},
426 { DEVICE_ATI_R350_AK_FIRE
, R_350
},
427 { DEVICE_ATI_RADEON_R350_RADEON2
, R_350
},
428 { DEVICE_ATI_RADEON_R350_RADEON3
, R_350
},
429 { DEVICE_ATI_RV350_NJ_RADEON
, R_350
},
430 { DEVICE_ATI_R350_NK_FIRE
, R_350
},
431 { DEVICE_ATI_RV350_AP_RADEON
, R_350
},
432 { DEVICE_ATI_RV350_AQ_RADEON
, R_350
},
433 { DEVICE_ATI_RV350_AR_RADEON
, R_350
},
434 { DEVICE_ATI_RV350_AS_RADEON
, R_350
},
435 { DEVICE_ATI_RV350_AT_FIRE
, R_350
},
436 { DEVICE_ATI_RV350_AU_FIRE
, R_350
},
437 { DEVICE_ATI_RV350_AV_FIRE
, R_350
},
438 { DEVICE_ATI_RV350_AW_FIRE
, R_350
},
439 { DEVICE_ATI_RV350_MOBILITY_RADEON
, R_350
},
440 { DEVICE_ATI_RV350_NF_RADEON
, R_300
},
441 { DEVICE_ATI_RV350_NJ_RADEON
, R_300
},
442 { DEVICE_ATI_RV350_AS_RADEON2
, R_350
},
443 { DEVICE_ATI_M10_NQ_RADEON
, R_350
},
444 { DEVICE_ATI_M10_NQ_RADEON2
, R_350
},
445 { DEVICE_ATI_RV350_MOBILITY_RADEON2
, R_350
},
446 { DEVICE_ATI_M10_NS_RADEON
, R_350
},
447 { DEVICE_ATI_M10_NT_FIREGL
, R_350
},
448 { DEVICE_ATI_M11_NV_FIREGL
, R_350
},
449 { DEVICE_ATI_RV370_5B60_RADEON
, R_370
|R_PCIE
},
450 { DEVICE_ATI_RV370_SAPPHIRE_X550
, R_370
},
451 { DEVICE_ATI_RV370_5B64_FIREGL
, R_370
|R_PCIE
},
452 { DEVICE_ATI_RV370_5B65_FIREGL
, R_370
|R_PCIE
},
453 { DEVICE_ATI_M24_1P_RADEON
, R_370
},
454 { DEVICE_ATI_M22_RADEON_MOBILITY
, R_370
},
455 { DEVICE_ATI_M24_1T_FIREGL
, R_370
},
456 { DEVICE_ATI_M24_RADEON_MOBILITY
, R_370
},
457 { DEVICE_ATI_RV370_RADEON_X300SE
, R_370
},
458 { DEVICE_ATI_RV370_SECONDARY_SAPPHIRE
, R_370
},
459 { DEVICE_ATI_RV370_5B64_FIREGL2
, R_370
},
460 { DEVICE_ATI_RV380_0X3E50_RADEON
, R_380
|R_PCIE
},
461 { DEVICE_ATI_RV380_0X3E54_FIREGL
, R_380
|R_PCIE
},
462 { DEVICE_ATI_RV380_RADEON_X600
, R_380
|R_PCIE
},
463 { DEVICE_ATI_RV380_RADEON_X6002
, R_380
},
464 { DEVICE_ATI_RV380_RADEON_X6003
, R_380
},
465 { DEVICE_ATI_RV410_FIREGL_V5000
, R_420
},
466 { DEVICE_ATI_RV410_FIREGL_V3300
, R_420
},
467 { DEVICE_ATI_RV410_RADEON_X700XT
, R_420
},
468 { DEVICE_ATI_RV410_RADEON_X700
, R_420
|R_PCIE
},
469 { DEVICE_ATI_RV410_RADEON_X700SE
, R_420
},
470 { DEVICE_ATI_RV410_RADEON_X7002
, R_420
|R_PCIE
},
471 { DEVICE_ATI_RV410_RADEON_X7003
, R_420
},
472 { DEVICE_ATI_RV410_RADEON_X7004
, R_420
|R_PCIE
},
473 { DEVICE_ATI_RV410_RADEON_X7005
, R_420
|R_PCIE
},
474 { DEVICE_ATI_M26_MOBILITY_FIREGL
, R_420
},
475 { DEVICE_ATI_M26_MOBILITY_FIREGL2
, R_420
},
476 { DEVICE_ATI_M26_RADEON_MOBILITY
, R_420
},
477 { DEVICE_ATI_M26_RADEON_MOBILITY2
, R_420
},
478 { DEVICE_ATI_RADEON_MOBILITY_X700
, R_420
},
479 { DEVICE_ATI_R420_JH_RADEON
, R_420
|R_PCIE
},
480 { DEVICE_ATI_R420_JI_RADEON
, R_420
|R_PCIE
},
481 { DEVICE_ATI_R420_JJ_RADEON
, R_420
|R_PCIE
},
482 { DEVICE_ATI_R420_JK_RADEON
, R_420
|R_PCIE
},
483 { DEVICE_ATI_R420_JL_RADEON
, R_420
|R_PCIE
},
484 { DEVICE_ATI_R420_JM_FIREGL
, R_420
|R_PCIE
},
485 { DEVICE_ATI_M18_JN_RADEON
, R_420
|R_PCIE
},
486 { DEVICE_ATI_R420_JP_RADEON
, R_420
|R_PCIE
},
487 { DEVICE_ATI_R420_RADEON_X800
, R_420
|R_PCIE
},
488 { DEVICE_ATI_R420_RADEON_X8002
, R_420
|R_PCIE
},
489 { DEVICE_ATI_R420_RADEON_X8003
, R_420
|R_PCIE
},
490 { DEVICE_ATI_R420_RADEON_X8004
, R_420
|R_PCIE
},
491 { DEVICE_ATI_R420_RADEON_X8005
, R_420
|R_PCIE
},
492 { DEVICE_ATI_R420_JM_FIREGL
, R_420
|R_PCIE
},
493 { DEVICE_ATI_R423_5F57_RADEON
, R_420
|R_PCIE
},
494 { DEVICE_ATI_R423_5F57_RADEON2
, R_420
|R_PCIE
},
495 { DEVICE_ATI_R423_UH_RADEON
, R_420
|R_PCIE
},
496 { DEVICE_ATI_R423_UI_RADEON
, R_420
|R_PCIE
},
497 { DEVICE_ATI_R423_UJ_RADEON
, R_420
|R_PCIE
},
498 { DEVICE_ATI_R423_UK_RADEON
, R_420
|R_PCIE
},
499 { DEVICE_ATI_R423_FIRE_GL
, R_420
|R_PCIE
},
500 { DEVICE_ATI_R423_UQ_FIREGL
, R_420
|R_PCIE
},
501 { DEVICE_ATI_R423_UR_FIREGL
, R_420
|R_PCIE
},
502 { DEVICE_ATI_R423_UT_FIREGL
, R_420
|R_PCIE
},
503 { DEVICE_ATI_R423_UI_RADEON2
, R_420
|R_PCIE
},
504 { DEVICE_ATI_R423GL_SE_ATI_FIREGL
, R_420
|R_PCIE
},
505 { DEVICE_ATI_R423_RADEON_X800XT
, R_420
|R_PCIE
},
506 { DEVICE_ATI_RADEON_R423_UK
, R_420
|R_PCIE
},
507 { DEVICE_ATI_M28_RADEON_MOBILITY
, R_420
},
508 { DEVICE_ATI_M28_MOBILITY_FIREGL
, R_420
},
509 { DEVICE_ATI_MOBILITY_RADEON_X800
, R_420
},
510 { DEVICE_ATI_R430_RADEON_X800
, R_430
|R_PCIE
},
511 { DEVICE_ATI_R430_RADEON_X8002
, R_430
|R_PCIE
},
512 { DEVICE_ATI_R430_RADEON_X8003
, R_430
|R_PCIE
},
513 { DEVICE_ATI_R430_RADEON_X8004
, R_430
|R_PCIE
},
514 { DEVICE_ATI_R480_RADEON_X800
, R_480
},
515 { DEVICE_ATI_R480_RADEON_X8002
, R_480
},
516 { DEVICE_ATI_R480_RADEON_X850XT
, R_480
},
517 { DEVICE_ATI_R480_RADEON_X850PRO
, R_480
},
518 { DEVICE_ATI_R481_RADEON_X850XT_PE
, R_480
|R_PCIE
},
519 { DEVICE_ATI_R480_RADEON_X850XT2
, R_480
},
520 { DEVICE_ATI_R480_RADEON_X850PRO2
, R_480
},
521 { DEVICE_ATI_R481_RADEON_X850XT_PE2
, R_480
|R_PCIE
},
522 { DEVICE_ATI_R480_RADEON_X850XT3
, R_480
|R_PCIE
},
523 { DEVICE_ATI_R480_RADEON_X850XT4
, R_480
|R_PCIE
},
524 { DEVICE_ATI_R480_RADEON_X850XT5
, R_480
|R_PCIE
},
525 { DEVICE_ATI_R480_RADEON_X850XT6
, R_480
|R_PCIE
},
530 static void * radeon_mmio_base
= 0;
531 static void * radeon_mem_base
= 0;
532 static int32_t radeon_overlay_off
= 0;
533 static uint32_t radeon_ram_size
= 0;
535 #define GETREG(TYPE,PTR,OFFZ) (*((volatile TYPE*)((PTR)+(OFFZ))))
536 #define SETREG(TYPE,PTR,OFFZ,VAL) (*((volatile TYPE*)((PTR)+(OFFZ))))=VAL
538 #define INREG8(addr) GETREG(uint8_t,(uint8_t *)(radeon_mmio_base),addr)
539 #define OUTREG8(addr,val) SETREG(uint8_t,(uint8_t *)(radeon_mmio_base),addr,val)
540 static inline uint32_t INREG (uint32_t addr
) {
541 uint32_t tmp
= GETREG(uint32_t,(uint8_t *)(radeon_mmio_base
),addr
);
542 return le2me_32(tmp
);
544 #define OUTREG(addr,val) SETREG(uint32_t,(uint8_t *)(radeon_mmio_base),addr,le2me_32(val))
545 #define OUTREGP(addr,val,mask) \
547 unsigned int _tmp = INREG(addr); \
550 OUTREG(addr, _tmp); \
553 static __inline__
uint32_t INPLL(uint32_t addr
)
555 OUTREG8(CLOCK_CNTL_INDEX
, addr
& 0x0000001f);
556 return (INREG(CLOCK_CNTL_DATA
));
559 #define OUTPLL(addr,val) OUTREG8(CLOCK_CNTL_INDEX, (addr & 0x0000001f) | 0x00000080); \
560 OUTREG(CLOCK_CNTL_DATA, val)
561 #define OUTPLLP(addr,val,mask) \
563 unsigned int _tmp = INPLL(addr); \
566 OUTPLL(addr, _tmp); \
573 MT_CRT
, /* CRT-(cathode ray tube) analog monitor. (15-pin VGA connector) */
574 MT_LCD
, /* Liquid Crystal Display */
575 MT_DFP
, /* DFP-digital flat panel monitor. (24-pin DVI-I connector) */
576 MT_CTV
, /* Composite TV out (not in VE) */
577 MT_STV
/* S-Video TV out (probably in VE only) */
580 typedef struct radeon_info_s
587 static rinfo_t rinfo
;
589 static char * GET_MON_NAME(int type
)
594 case MT_NONE
: pret
= "no"; break;
595 case MT_CRT
: pret
= "CRT"; break;
596 case MT_DFP
: pret
= "DFP"; break;
597 case MT_LCD
: pret
= "LCD"; break;
598 case MT_CTV
: pret
= "CTV"; break;
599 case MT_STV
: pret
= "STV"; break;
600 default: pret
= "Unknown";
605 static void radeon_get_moninfo (rinfo_t
*rinfo
)
609 tmp
= INREG(RADEON_BIOS_4_SCRATCH
);
611 if (rinfo
->hasCRTC2
) {
612 /* primary DVI port */
614 rinfo
->dviDispType
= MT_DFP
;
616 rinfo
->dviDispType
= MT_LCD
;
617 else if (tmp
& 0x200)
618 rinfo
->dviDispType
= MT_CRT
;
620 rinfo
->dviDispType
= MT_CTV
;
622 rinfo
->dviDispType
= MT_STV
;
624 /* secondary CRT port */
626 rinfo
->crtDispType
= MT_CRT
;
627 else if (tmp
& 0x800)
628 rinfo
->crtDispType
= MT_DFP
;
629 else if (tmp
& 0x400)
630 rinfo
->crtDispType
= MT_LCD
;
631 else if (tmp
& 0x1000)
632 rinfo
->crtDispType
= MT_CTV
;
633 else if (tmp
& 0x2000)
634 rinfo
->crtDispType
= MT_STV
;
636 rinfo
->dviDispType
= MT_NONE
;
638 tmp
= INREG(FP_GEN_CNTL
);
640 if (tmp
& FP_EN_TMDS
)
641 rinfo
->crtDispType
= MT_DFP
;
643 rinfo
->crtDispType
= MT_CRT
;
648 static uint32_t radeon_vid_get_dbpp( void )
650 uint32_t dbpp
,retval
;
651 dbpp
= (INREG(CRTC_GEN_CNTL
)>>8)& 0xF;
654 case DST_8BPP
: retval
= 8; break;
655 case DST_15BPP
: retval
= 15; break;
656 case DST_16BPP
: retval
= 16; break;
657 case DST_24BPP
: retval
= 24; break;
658 default: retval
=32; break;
663 static int radeon_is_dbl_scan( void )
665 return (INREG(CRTC_GEN_CNTL
))&CRTC_DBL_SCAN_EN
;
668 static int radeon_is_interlace( void )
670 return (INREG(CRTC_GEN_CNTL
))&CRTC_INTERLACE_EN
;
673 static uint32_t radeon_get_xres( void )
675 uint32_t xres
,h_total
;
678 (rinfo
.dviDispType
== MT_CTV
|| rinfo
.dviDispType
== MT_STV
))
679 h_total
= INREG(CRTC2_H_TOTAL_DISP
);
682 h_total
= INREG(CRTC_H_TOTAL_DISP
);
683 xres
= (h_total
>> 16) & 0xffff;
687 static uint32_t radeon_get_yres( void )
689 uint32_t yres
,v_total
;
692 (rinfo
.dviDispType
== MT_CTV
|| rinfo
.dviDispType
== MT_STV
))
693 v_total
= INREG(CRTC2_V_TOTAL_DISP
);
696 v_total
= INREG(CRTC_V_TOTAL_DISP
);
697 yres
= (v_total
>> 16) & 0xffff;
701 static void radeon_wait_vsync(void)
705 OUTREG(GEN_INT_STATUS
, VSYNC_INT_AK
);
706 for (i
= 0; i
< 2000000; i
++)
708 if (INREG(GEN_INT_STATUS
) & VSYNC_INT
) break;
713 static void _radeon_engine_idle(void);
714 static void _radeon_fifo_wait(unsigned);
715 #define radeon_engine_idle() _radeon_engine_idle()
716 #define radeon_fifo_wait(entries) _radeon_fifo_wait(entries)
717 /* Flush all dirty data in the Pixel Cache to memory. */
718 static __inline__
void radeon_engine_flush ( void )
722 OUTREGP(PC_NGUI_CTLSTAT
, PC_FLUSH_ALL
, ~PC_FLUSH_ALL
);
723 for (i
= 0; i
< 2000000; i
++) {
724 if (!(INREG(PC_NGUI_CTLSTAT
) & PC_BUSY
)) break;
728 /* Reset graphics card to known state. */
729 static void radeon_engine_reset( void )
731 uint32_t clock_cntl_index
;
733 uint32_t gen_reset_cntl
;
735 radeon_engine_flush();
737 clock_cntl_index
= INREG(CLOCK_CNTL_INDEX
);
738 mclk_cntl
= INPLL(MCLK_CNTL
);
740 OUTPLL(MCLK_CNTL
, mclk_cntl
| FORCE_GCP
| FORCE_PIPE3D_CP
);
742 gen_reset_cntl
= INREG(GEN_RESET_CNTL
);
744 OUTREG(GEN_RESET_CNTL
, gen_reset_cntl
| SOFT_RESET_GUI
);
745 INREG(GEN_RESET_CNTL
);
746 OUTREG(GEN_RESET_CNTL
,
747 gen_reset_cntl
& (uint32_t)(~SOFT_RESET_GUI
));
748 INREG(GEN_RESET_CNTL
);
750 OUTPLL(MCLK_CNTL
, mclk_cntl
);
751 OUTREG(CLOCK_CNTL_INDEX
, clock_cntl_index
);
752 OUTREG(GEN_RESET_CNTL
, gen_reset_cntl
);
756 static __inline__
void radeon_engine_flush ( void )
761 OUTREGP(RB2D_DSTCACHE_CTLSTAT
, RB2D_DC_FLUSH_ALL
,
764 for (i
=0; i
< 2000000; i
++) {
765 if (!(INREG(RB2D_DSTCACHE_CTLSTAT
) & RB2D_DC_BUSY
))
770 static void _radeon_engine_idle(void);
771 static void _radeon_fifo_wait(unsigned);
772 #define radeon_engine_idle() _radeon_engine_idle()
773 #define radeon_fifo_wait(entries) _radeon_fifo_wait(entries)
775 static void radeon_engine_reset( void )
777 uint32_t clock_cntl_index
, mclk_cntl
, rbbm_soft_reset
;
779 radeon_engine_flush ();
781 clock_cntl_index
= INREG(CLOCK_CNTL_INDEX
);
782 mclk_cntl
= INPLL(MCLK_CNTL
);
784 OUTPLL(MCLK_CNTL
, (mclk_cntl
|
791 rbbm_soft_reset
= INREG(RBBM_SOFT_RESET
);
793 OUTREG(RBBM_SOFT_RESET
, rbbm_soft_reset
|
802 INREG(RBBM_SOFT_RESET
);
803 OUTREG(RBBM_SOFT_RESET
, rbbm_soft_reset
& (uint32_t)
812 INREG(RBBM_SOFT_RESET
);
814 OUTPLL(MCLK_CNTL
, mclk_cntl
);
815 OUTREG(CLOCK_CNTL_INDEX
, clock_cntl_index
);
816 OUTREG(RBBM_SOFT_RESET
, rbbm_soft_reset
);
821 static void radeon_engine_restore( void )
825 uint32_t xres
,yres
,bpp
;
827 xres
= radeon_get_xres();
828 yres
= radeon_get_yres();
829 bpp
= radeon_vid_get_dbpp();
830 /* turn of all automatic flushing - we'll do it all */
831 OUTREG(RB2D_DSTCACHE_MODE
, 0);
833 pitch64
= ((xres
* (bpp
/ 8) + 0x3f)) >> 6;
836 OUTREG(DEFAULT_OFFSET
, (INREG(DEFAULT_OFFSET
) & 0xC0000000) |
840 #if defined(WORDS_BIGENDIAN)
842 HOST_BIG_ENDIAN_EN
, ~HOST_BIG_ENDIAN_EN
);
844 OUTREGP(DP_DATATYPE
, 0, ~HOST_BIG_ENDIAN_EN
);
848 OUTREG(DEFAULT_SC_BOTTOM_RIGHT
, (DEFAULT_SC_RIGHT_MAX
849 | DEFAULT_SC_BOTTOM_MAX
));
851 OUTREG(DP_GUI_MASTER_CNTL
, (INREG(DP_GUI_MASTER_CNTL
)
852 | GMC_BRUSH_SOLID_COLOR
853 | GMC_SRC_DATATYPE_COLOR
));
856 OUTREG(DST_LINE_START
, 0);
857 OUTREG(DST_LINE_END
, 0);
858 OUTREG(DP_BRUSH_FRGD_CLR
, 0xffffffff);
859 OUTREG(DP_BRUSH_BKGD_CLR
, 0x00000000);
860 OUTREG(DP_SRC_FRGD_CLR
, 0xffffffff);
861 OUTREG(DP_SRC_BKGD_CLR
, 0x00000000);
862 OUTREG(DP_WRITE_MASK
, 0xffffffff);
864 radeon_engine_idle();
868 static void _radeon_fifo_wait (unsigned entries
)
874 for (i
=0; i
<2000000; i
++)
875 if ((INREG(GUI_STAT
) & GUI_FIFOCNT_MASK
) >= entries
)
877 radeon_engine_reset();
878 radeon_engine_restore();
882 static void _radeon_engine_idle ( void )
886 /* ensure FIFO is empty before waiting for idle */
887 radeon_fifo_wait (64);
890 for (i
=0; i
<2000000; i
++) {
891 if ((INREG(GUI_STAT
) & GUI_ACTIVE
) == 0) {
892 radeon_engine_flush ();
896 radeon_engine_reset();
897 radeon_engine_restore();
901 static void _radeon_fifo_wait (unsigned entries
)
907 for (i
=0; i
<2000000; i
++)
908 if ((INREG(RBBM_STATUS
) & RBBM_FIFOCNT_MASK
) >= entries
)
910 radeon_engine_reset();
911 radeon_engine_restore();
914 static void _radeon_engine_idle ( void )
918 /* ensure FIFO is empty before waiting for idle */
919 radeon_fifo_wait (64);
922 for (i
=0; i
<2000000; i
++) {
923 if (((INREG(RBBM_STATUS
) & RBBM_ACTIVE
)) == 0) {
924 radeon_engine_flush ();
928 radeon_engine_reset();
929 radeon_engine_restore();
935 /* Reference color space transform data */
936 typedef struct tagREF_TRANSFORM
947 /* Parameters for ITU-R BT.601 and ITU-R BT.709 colour spaces */
948 REF_TRANSFORM trans
[2] =
950 {1.1678, 0.0, 1.6007, -0.3929, -0.8154, 2.0232, 0.0}, /* BT.601 */
951 {1.1678, 0.0, 1.7980, -0.2139, -0.5345, 2.1186, 0.0} /* BT.709 */
953 /****************************************************************************
955 * Function: Calculates and sets color space transform from supplied *
956 * reference transform, gamma, brightness, contrast, hue and *
958 * Inputs: bright - brightness *
962 * red_intensity - intense of red component *
963 * green_intensity - intense of green component *
964 * blue_intensity - intense of blue component *
965 * ref - index to the table of refernce transforms *
967 ****************************************************************************/
969 static void radeon_set_transform(float bright
, float cont
, float sat
,
970 float hue
, float red_intensity
,
971 float green_intensity
,float blue_intensity
,
974 float OvHueSin
, OvHueCos
;
975 float CAdjLuma
, CAdjOff
;
976 float RedAdj
,GreenAdj
,BlueAdj
;
977 float CAdjRCb
, CAdjRCr
;
978 float CAdjGCb
, CAdjGCr
;
979 float CAdjBCb
, CAdjBCr
;
980 float OvLuma
, OvROff
, OvGOff
, OvBOff
;
987 uint32_t dwOvLuma
, dwOvROff
, dwOvGOff
, dwOvBOff
;
988 uint32_t dwOvRCb
, dwOvRCr
;
989 uint32_t dwOvGCb
, dwOvGCr
;
990 uint32_t dwOvBCb
, dwOvBCr
;
992 if (ref
>= 2) return;
994 OvHueSin
= sin((double)hue
);
995 OvHueCos
= cos((double)hue
);
997 CAdjLuma
= cont
* trans
[ref
].RefLuma
;
998 CAdjOff
= cont
* trans
[ref
].RefLuma
* bright
* 1023.0;
999 RedAdj
= cont
* trans
[ref
].RefLuma
* red_intensity
* 1023.0;
1000 GreenAdj
= cont
* trans
[ref
].RefLuma
* green_intensity
* 1023.0;
1001 BlueAdj
= cont
* trans
[ref
].RefLuma
* blue_intensity
* 1023.0;
1003 CAdjRCb
= sat
* -OvHueSin
* trans
[ref
].RefRCr
;
1004 CAdjRCr
= sat
* OvHueCos
* trans
[ref
].RefRCr
;
1005 CAdjGCb
= sat
* (OvHueCos
* trans
[ref
].RefGCb
- OvHueSin
* trans
[ref
].RefGCr
);
1006 CAdjGCr
= sat
* (OvHueSin
* trans
[ref
].RefGCb
+ OvHueCos
* trans
[ref
].RefGCr
);
1007 CAdjBCb
= sat
* OvHueCos
* trans
[ref
].RefBCb
;
1008 CAdjBCr
= sat
* OvHueSin
* trans
[ref
].RefBCb
;
1017 OvROff
= RedAdj
+ CAdjOff
-
1018 OvLuma
* Loff
- (OvRCb
+ OvRCr
) * Coff
;
1019 OvGOff
= GreenAdj
+ CAdjOff
-
1020 OvLuma
* Loff
- (OvGCb
+ OvGCr
) * Coff
;
1021 OvBOff
= BlueAdj
+ CAdjOff
-
1022 OvLuma
* Loff
- (OvBCb
+ OvBCr
) * Coff
;
1024 dwOvROff
= ((int)(OvROff
* 2.0)) & 0x1fff;
1025 dwOvGOff
= (int)(OvGOff
* 2.0) & 0x1fff;
1026 dwOvBOff
= (int)(OvBOff
* 2.0) & 0x1fff;
1027 /* Whatever docs say about R200 having 3.8 format instead of 3.11
1028 as in Radeon is a lie */
1030 dwOvLuma
=(((int)(OvLuma
* 2048.0))&0x7fff)<<17;
1031 dwOvRCb
= (((int)(OvRCb
* 2048.0))&0x7fff)<<1;
1032 dwOvRCr
= (((int)(OvRCr
* 2048.0))&0x7fff)<<17;
1033 dwOvGCb
= (((int)(OvGCb
* 2048.0))&0x7fff)<<1;
1034 dwOvGCr
= (((int)(OvGCr
* 2048.0))&0x7fff)<<17;
1035 dwOvBCb
= (((int)(OvBCb
* 2048.0))&0x7fff)<<1;
1036 dwOvBCr
= (((int)(OvBCr
* 2048.0))&0x7fff)<<17;
1038 OUTREG(OV0_LIN_TRANS_A
, dwOvRCb
| dwOvLuma
);
1039 OUTREG(OV0_LIN_TRANS_B
, dwOvROff
| dwOvRCr
);
1040 OUTREG(OV0_LIN_TRANS_C
, dwOvGCb
| dwOvLuma
);
1041 OUTREG(OV0_LIN_TRANS_D
, dwOvGOff
| dwOvGCr
);
1042 OUTREG(OV0_LIN_TRANS_E
, dwOvBCb
| dwOvLuma
);
1043 OUTREG(OV0_LIN_TRANS_F
, dwOvBOff
| dwOvBCr
);
1046 /* Gamma curve definition */
1049 unsigned int gammaReg
;
1050 unsigned int gammaSlope
;
1051 unsigned int gammaOffset
;
1054 /* Recommended gamma curve parameters */
1055 GAMMA_SETTINGS r200_def_gamma
[18] =
1057 {OV0_GAMMA_0_F
, 0x100, 0x0000},
1058 {OV0_GAMMA_10_1F
, 0x100, 0x0020},
1059 {OV0_GAMMA_20_3F
, 0x100, 0x0040},
1060 {OV0_GAMMA_40_7F
, 0x100, 0x0080},
1061 {OV0_GAMMA_80_BF
, 0x100, 0x0100},
1062 {OV0_GAMMA_C0_FF
, 0x100, 0x0100},
1063 {OV0_GAMMA_100_13F
, 0x100, 0x0200},
1064 {OV0_GAMMA_140_17F
, 0x100, 0x0200},
1065 {OV0_GAMMA_180_1BF
, 0x100, 0x0300},
1066 {OV0_GAMMA_1C0_1FF
, 0x100, 0x0300},
1067 {OV0_GAMMA_200_23F
, 0x100, 0x0400},
1068 {OV0_GAMMA_240_27F
, 0x100, 0x0400},
1069 {OV0_GAMMA_280_2BF
, 0x100, 0x0500},
1070 {OV0_GAMMA_2C0_2FF
, 0x100, 0x0500},
1071 {OV0_GAMMA_300_33F
, 0x100, 0x0600},
1072 {OV0_GAMMA_340_37F
, 0x100, 0x0600},
1073 {OV0_GAMMA_380_3BF
, 0x100, 0x0700},
1074 {OV0_GAMMA_3C0_3FF
, 0x100, 0x0700}
1077 GAMMA_SETTINGS r100_def_gamma
[6] =
1079 {OV0_GAMMA_0_F
, 0x100, 0x0000},
1080 {OV0_GAMMA_10_1F
, 0x100, 0x0020},
1081 {OV0_GAMMA_20_3F
, 0x100, 0x0040},
1082 {OV0_GAMMA_40_7F
, 0x100, 0x0080},
1083 {OV0_GAMMA_380_3BF
, 0x100, 0x0100},
1084 {OV0_GAMMA_3C0_3FF
, 0x100, 0x0100}
1087 static void make_default_gamma_correction( void )
1090 if((besr
.chip_flags
& R_100
)==R_100
||
1091 (besr
.chip_flags
& R_120
)==R_120
||
1092 (besr
.chip_flags
& R_150
)==R_150
){
1093 OUTREG(OV0_LIN_TRANS_A
, 0x12A00000);
1094 OUTREG(OV0_LIN_TRANS_B
, 0x199018FE);
1095 OUTREG(OV0_LIN_TRANS_C
, 0x12A0F9B0);
1096 OUTREG(OV0_LIN_TRANS_D
, 0xF2F0043B);
1097 OUTREG(OV0_LIN_TRANS_E
, 0x12A02050);
1098 OUTREG(OV0_LIN_TRANS_F
, 0x0000174E);
1100 OUTREG(r100_def_gamma
[i
].gammaReg
,
1101 (r100_def_gamma
[i
].gammaSlope
<<16) |
1102 r100_def_gamma
[i
].gammaOffset
);
1106 OUTREG(OV0_LIN_TRANS_A
, 0x12a20000);
1107 OUTREG(OV0_LIN_TRANS_B
, 0x198a190e);
1108 OUTREG(OV0_LIN_TRANS_C
, 0x12a2f9da);
1109 OUTREG(OV0_LIN_TRANS_D
, 0xf2fe0442);
1110 OUTREG(OV0_LIN_TRANS_E
, 0x12a22046);
1111 OUTREG(OV0_LIN_TRANS_F
, 0x175f);
1113 Of 18 segments for gamma cure, all segments in R200 are programmable,
1114 while only lower 4 and upper 2 segments are programmable in Radeon*/
1115 for(i
=0; i
<18; i
++){
1116 OUTREG(r200_def_gamma
[i
].gammaReg
,
1117 (r200_def_gamma
[i
].gammaSlope
<<16) |
1118 r200_def_gamma
[i
].gammaOffset
);
1124 static void radeon_vid_make_default(void)
1127 besr
.saturation
= 0x0F;
1128 besr
.brightness
= 0;
1129 OUTREG(OV0_COLOUR_CNTL
,0x000F0F00UL
); /* Default brihgtness and saturation for Rage128 */
1131 make_default_gamma_correction();
1133 besr
.deinterlace_pattern
= 0x900AAAAA;
1134 OUTREG(OV0_DEINTERLACE_PATTERN
,besr
.deinterlace_pattern
);
1135 besr
.deinterlace_on
=1;
1138 besr
.graphics_key_msk
=0;
1139 besr
.graphics_key_clr
=0;
1140 besr
.ckey_cntl
= VIDEO_KEY_FN_TRUE
|GRAPHIC_KEY_FN_TRUE
|CMP_MIX_AND
;
1141 besr
.merge_cntl
|= 0x00000100; /* DISP_RGB_OFFSET_EN */
1144 static int find_chip(unsigned chip_id
)
1147 for(i
= 0;i
< sizeof(ati_card_ids
)/sizeof(ati_card_ids_t
);i
++)
1149 if(chip_id
== ati_card_ids
[i
].id
) return i
;
1154 static pciinfo_t pci_info
;
1155 static int probed
=0;
1157 static vidix_capability_t def_cap
=
1160 "BES driver for Rage128 cards",
1162 "BES driver for Radeon cards",
1165 TYPE_OUTPUT
| TYPE_FX
,
1172 FLAG_UPSCALER
| FLAG_DOWNSCALER
| FLAG_EQUALIZER
,
1178 #if !defined(RAGE128) && defined(HAVE_X11)
1179 static void probe_fireGL_driver(void) {
1180 Display
*dp
= XOpenDisplay ((void*)0);
1186 extlist
= XListExtensions (dp
, &n
);
1190 int ext_fgl
= 0, ext_fglrx
= 0;
1191 for (i
= 0; i
< n
; i
++) {
1192 if (!strcmp(extlist
[i
], "ATIFGLEXTENSION")) ext_fgl
= 1;
1193 if (!strcmp(extlist
[i
], "ATIFGLRXDRI")) ext_fglrx
= 1;
1196 printf(RADEON_MSG
" ATI FireGl driver detected");
1197 firegl_shift
= 0x500000;
1199 printf(", but DRI seems not to be activated\n");
1200 printf(RADEON_MSG
" Output may not work correctly, check your DRI configration!");
1208 static int radeon_probe(int verbose
, int force
)
1210 pciinfo_t lst
[MAX_PCI_DEVICES
];
1213 __verbose
= verbose
;
1214 err
= pci_scan(lst
,&num_pci
);
1217 printf(RADEON_MSG
" Error occurred during pci scan: %s\n",strerror(err
));
1223 for(i
=0;i
<num_pci
;i
++)
1225 if(lst
[i
].vendor
== VENDOR_ATI
)
1229 idx
= find_chip(lst
[i
].device
);
1230 if(idx
== -1 && force
== PROBE_NORMAL
) continue;
1231 dname
= pci_device_name(VENDOR_ATI
,lst
[i
].device
);
1232 dname
= dname
? dname
: "Unknown chip";
1233 printf(RADEON_MSG
" Found chip: %s\n",dname
);
1235 if ((lst
[i
].command
& PCI_COMMAND_IO
) == 0)
1237 printf("[radeon] Device is disabled, ignoring\n");
1241 memset(&besr
,0,sizeof(bes_registers_t
));
1242 if(force
> PROBE_NORMAL
)
1244 printf(RADEON_MSG
" Driver was forced. Was found %sknown chip\n",idx
== -1 ? "un" : "");
1247 printf(RADEON_MSG
" Assuming it as Rage128\n");
1249 printf(RADEON_MSG
" Assuming it as Radeon1\n");
1251 besr
.chip_flags
=R_100
|R_OVL_SHIFT
;
1253 #if !defined(RAGE128) && defined(HAVE_X11)
1254 probe_fireGL_driver();
1256 if(idx
!= -1) besr
.chip_flags
=ati_card_ids
[idx
].flags
;
1257 def_cap
.device_id
= lst
[i
].device
;
1259 memcpy(&pci_info
,&lst
[i
],sizeof(pciinfo_t
));
1265 if(err
&& verbose
) printf(RADEON_MSG
" Can't find chip\n");
1269 typedef struct saved_regs_s
1271 uint32_t ov0_vid_key_clr
;
1272 uint32_t ov0_vid_key_msk
;
1273 uint32_t ov0_graphics_key_clr
;
1274 uint32_t ov0_graphics_key_msk
;
1275 uint32_t ov0_key_cntl
;
1276 uint32_t disp_merge_cntl
;
1278 static saved_regs_t savreg
;
1280 static void save_regs( void )
1282 radeon_fifo_wait(6);
1283 savreg
.ov0_vid_key_clr
= INREG(OV0_VID_KEY_CLR
);
1284 savreg
.ov0_vid_key_msk
= INREG(OV0_VID_KEY_MSK
);
1285 savreg
.ov0_graphics_key_clr
= INREG(OV0_GRAPHICS_KEY_CLR
);
1286 savreg
.ov0_graphics_key_msk
= INREG(OV0_GRAPHICS_KEY_MSK
);
1287 savreg
.ov0_key_cntl
= INREG(OV0_KEY_CNTL
);
1288 savreg
.disp_merge_cntl
= INREG(DISP_MERGE_CNTL
);
1291 static void restore_regs( void )
1293 radeon_fifo_wait(6);
1294 OUTREG(OV0_VID_KEY_CLR
,savreg
.ov0_vid_key_clr
);
1295 OUTREG(OV0_VID_KEY_MSK
,savreg
.ov0_vid_key_msk
);
1296 OUTREG(OV0_GRAPHICS_KEY_CLR
,savreg
.ov0_graphics_key_clr
);
1297 OUTREG(OV0_GRAPHICS_KEY_MSK
,savreg
.ov0_graphics_key_msk
);
1298 OUTREG(OV0_KEY_CNTL
,savreg
.ov0_key_cntl
);
1299 OUTREG(DISP_MERGE_CNTL
,savreg
.disp_merge_cntl
);
1302 static int radeon_init(void)
1306 if(__verbose
>0) printf("[radeon_vid] version %d\n", VIDIX_VERSION
);
1310 printf(RADEON_MSG
" Driver was not probed but is being initializing\n");
1313 if((radeon_mmio_base
= map_phys_mem(pci_info
.base2
,0xFFFF))==(void *)-1) return ENOMEM
;
1314 radeon_ram_size
= INREG(CONFIG_MEMSIZE
);
1315 /* mem size is bits [28:0], mask off the rest. Range: from 1Mb up to 512 Mb */
1316 radeon_ram_size
&= CONFIG_MEMSIZE_MASK
;
1318 /* according to XFree86 4.2.0, some production M6's return 0 for 8MB */
1319 if (radeon_ram_size
== 0 &&
1320 (def_cap
.device_id
== DEVICE_ATI_RADEON_MOBILITY_M6
||
1321 def_cap
.device_id
== DEVICE_ATI_RADEON_MOBILITY_M62
))
1323 printf(RADEON_MSG
" Working around buggy Radeon Mobility M6 (0 vs. 8MB ram)\n");
1324 radeon_ram_size
= 8192*1024;
1326 else if (radeon_ram_size
== 0 &&
1327 (def_cap
.device_id
== DEVICE_ATI_RS482_RADEON_XPRESS
))
1329 printf(RADEON_MSG
" Working around buggy RS482 Radeon Xpress 200 Memory Detection\n");
1330 radeon_ram_size
= (INREG(CONFIG_MEMSIZE
) + 0x100000) << 2;
1331 radeon_ram_size
&= CONFIG_MEMSIZE_MASK
;
1334 /* Rage Mobility (rage128) also has memsize bug */
1335 if (radeon_ram_size
== 0 &&
1336 (def_cap
.device_id
== DEVICE_ATI_RAGE_MOBILITY_M3
||
1337 def_cap
.device_id
== DEVICE_ATI_RAGE_MOBILITY_M32
))
1339 printf(RADEON_MSG
" Working around Rage Mobility M3 (0 vs. 8MB ram)\n");
1340 radeon_ram_size
= 8192*1024;
1343 if((radeon_mem_base
= map_phys_mem(pci_info
.base0
,radeon_ram_size
))==(void *)-1) return ENOMEM
;
1344 radeon_vid_make_default();
1345 printf(RADEON_MSG
" Video memory = %uMb\n",radeon_ram_size
/0x100000);
1346 err
= mtrr_set_type(pci_info
.base0
,radeon_ram_size
,MTRR_TYPE_WRCOMB
);
1347 if(!err
) printf(RADEON_MSG
" Set write-combining type of video memory\n");
1350 memset(&rinfo
,0,sizeof(rinfo_t
));
1351 if((besr
.chip_flags
&R_100
) != R_100
) rinfo
.hasCRTC2
= 1;
1353 radeon_get_moninfo(&rinfo
);
1354 if(rinfo
.hasCRTC2
) {
1355 printf(RADEON_MSG
" DVI port has %s monitor connected\n",GET_MON_NAME(rinfo
.dviDispType
));
1356 printf(RADEON_MSG
" CRT port has %s monitor connected\n",GET_MON_NAME(rinfo
.crtDispType
));
1359 printf(RADEON_MSG
" CRT port has %s monitor connected\n",GET_MON_NAME(rinfo
.crtDispType
));
1366 static void radeon_destroy(void)
1369 unmap_phys_mem(radeon_mem_base
,radeon_ram_size
);
1370 unmap_phys_mem(radeon_mmio_base
,0xFFFF);
1373 static int radeon_get_caps(vidix_capability_t
*to
)
1375 memcpy(to
,&def_cap
,sizeof(vidix_capability_t
));
1380 Full list of fourcc which are supported by Win2K radeon driver:
1381 YUY2, UYVY, DDES, OGLT, OGL2, OGLS, OGLB, OGNT, OGNZ, OGNS,
1382 IF09, YVU9, IMC4, M2IA, IYUV, VBID, DXT1, DXT2, DXT3, DXT4, DXT5
1384 typedef struct fourcc_desc_s
1390 static fourcc_desc_t supported_fourcc
[] =
1392 { IMGFMT_Y800
, 1567 },
1393 { IMGFMT_YVU9
, 1567 },
1394 { IMGFMT_IF09
, 1567 },
1395 { IMGFMT_YV12
, 1567 },
1396 { IMGFMT_I420
, 1567 },
1397 { IMGFMT_IYUV
, 1567 },
1398 { IMGFMT_UYVY
, 1551 },
1399 { IMGFMT_YUY2
, 1551 },
1400 { IMGFMT_YVYU
, 1551 },
1401 { IMGFMT_RGB15
, 1551 },
1402 { IMGFMT_BGR15
, 1551 },
1403 { IMGFMT_RGB16
, 1551 },
1404 { IMGFMT_BGR16
, 1551 },
1405 { IMGFMT_RGB32
, 775 },
1406 { IMGFMT_BGR32
, 775 }
1409 __inline__
static int is_supported_fourcc(uint32_t fourcc
)
1412 for(i
=0;i
<sizeof(supported_fourcc
)/sizeof(fourcc_desc_t
);i
++)
1414 if(fourcc
==supported_fourcc
[i
].fourcc
)
1420 static int radeon_query_fourcc(vidix_fourcc_t
*to
)
1422 if(is_supported_fourcc(to
->fourcc
))
1424 to
->depth
= VID_DEPTH_ALL
;
1425 to
->flags
= VID_CAP_EXPAND
| VID_CAP_SHRINK
| VID_CAP_COLORKEY
|
1429 else to
->depth
= to
->flags
= 0;
1433 static double H_scale_ratio
;
1434 static void radeon_vid_dump_regs( void )
1437 printf(RADEON_MSG
"*** Begin of DRIVER variables dump ***\n");
1438 printf(RADEON_MSG
"radeon_mmio_base=%p\n",radeon_mmio_base
);
1439 printf(RADEON_MSG
"radeon_mem_base=%p\n",radeon_mem_base
);
1440 printf(RADEON_MSG
"radeon_overlay_off=%08X\n",radeon_overlay_off
);
1441 printf(RADEON_MSG
"radeon_ram_size=%08X\n",radeon_ram_size
);
1442 printf(RADEON_MSG
"video mode: %ux%u@%u\n",radeon_get_xres(),radeon_get_yres(),radeon_vid_get_dbpp());
1443 printf(RADEON_MSG
"H_scale_ratio=%8.2f\n",H_scale_ratio
);
1444 printf(RADEON_MSG
"*** Begin of OV0 registers dump ***\n");
1445 for(i
=0;i
<sizeof(vregs
)/sizeof(video_registers_t
);i
++)
1446 printf(RADEON_MSG
"%s = %08X\n",vregs
[i
].sname
,INREG(vregs
[i
].name
));
1447 printf(RADEON_MSG
"*** End of OV0 registers dump ***\n");
1450 static void radeon_vid_stop_video( void )
1452 radeon_engine_idle();
1453 OUTREG(OV0_SCALE_CNTL
, SCALER_SOFT_RESET
);
1454 OUTREG(OV0_EXCLUSIVE_HORZ
, 0);
1455 OUTREG(OV0_AUTO_FLIP_CNTL
, 0); /* maybe */
1456 OUTREG(OV0_FILTER_CNTL
, FILTER_HARDCODED_COEF
);
1458 OUTREG(OV0_KEY_CNTL
, GRAPHIC_KEY_FN_NE
);
1460 OUTREG(OV0_KEY_CNTL
, GRAPHIC_KEY_FN_EQ
);
1462 OUTREG(OV0_TEST
, 0);
1465 static void radeon_vid_display_video( void )
1467 int bes_flags
,force_second
;
1468 radeon_fifo_wait(2);
1469 OUTREG(OV0_REG_LOAD_CNTL
, REG_LD_CTL_LOCK
);
1470 radeon_engine_idle();
1471 while(!(INREG(OV0_REG_LOAD_CNTL
)®_LD_CTL_LOCK_READBACK
));
1472 radeon_fifo_wait(15);
1476 /* Shutdown capturing */
1477 OUTREG(FCP_CNTL
, FCP_CNTL__GND
);
1478 OUTREG(CAP0_TRIG_CNTL
, 0);
1480 OUTREG(VID_BUFFER_CONTROL
, (1<<16) | 0x01);
1481 OUTREG(DISP_TEST_DEBUG_CNTL
, 0);
1483 OUTREG(OV0_AUTO_FLIP_CNTL
,OV0_AUTO_FLIP_CNTL_SOFT_BUF_ODD
);
1485 if(besr
.deinterlace_on
) OUTREG(OV0_DEINTERLACE_PATTERN
,besr
.deinterlace_pattern
);
1487 OUTREG(OV0_COLOUR_CNTL
, (besr
.brightness
& 0x7f) |
1488 (besr
.saturation
<< 8) |
1489 (besr
.saturation
<< 16));
1491 radeon_fifo_wait(2);
1492 OUTREG(OV0_GRAPHICS_KEY_MSK
, besr
.graphics_key_msk
);
1493 OUTREG(OV0_GRAPHICS_KEY_CLR
, besr
.graphics_key_clr
);
1494 OUTREG(OV0_KEY_CNTL
,besr
.ckey_cntl
);
1496 OUTREG(OV0_H_INC
, besr
.h_inc
);
1497 OUTREG(OV0_STEP_BY
, besr
.step_by
);
1500 OUTREG(OV1_Y_X_START
, besr
.y_x_start
);
1501 OUTREG(OV1_Y_X_END
, besr
.y_x_end
);
1505 OUTREG(OV0_Y_X_START
, besr
.y_x_start
);
1506 OUTREG(OV0_Y_X_END
, besr
.y_x_end
);
1508 OUTREG(OV0_V_INC
, besr
.v_inc
);
1509 OUTREG(OV0_P1_BLANK_LINES_AT_TOP
, besr
.p1_blank_lines_at_top
);
1510 OUTREG(OV0_P23_BLANK_LINES_AT_TOP
, besr
.p23_blank_lines_at_top
);
1511 OUTREG(OV0_VID_BUF_PITCH0_VALUE
, besr
.vid_buf_pitch0_value
);
1512 OUTREG(OV0_VID_BUF_PITCH1_VALUE
, besr
.vid_buf_pitch1_value
);
1513 OUTREG(OV0_P1_X_START_END
, besr
.p1_x_start_end
);
1514 OUTREG(OV0_P2_X_START_END
, besr
.p2_x_start_end
);
1515 OUTREG(OV0_P3_X_START_END
, besr
.p3_x_start_end
);
1517 OUTREG(OV0_BASE_ADDR
, besr
.base_addr
);
1519 OUTREG(OV0_VID_BUF0_BASE_ADRS
, besr
.vid_buf_base_adrs_y
[0]);
1520 OUTREG(OV0_VID_BUF1_BASE_ADRS
, besr
.vid_buf_base_adrs_v
[0]);
1521 OUTREG(OV0_VID_BUF2_BASE_ADRS
, besr
.vid_buf_base_adrs_u
[0]);
1522 radeon_fifo_wait(9);
1523 OUTREG(OV0_VID_BUF3_BASE_ADRS
, besr
.vid_buf_base_adrs_y
[0]);
1524 OUTREG(OV0_VID_BUF4_BASE_ADRS
, besr
.vid_buf_base_adrs_v
[0]);
1525 OUTREG(OV0_VID_BUF5_BASE_ADRS
, besr
.vid_buf_base_adrs_u
[0]);
1526 OUTREG(OV0_P1_V_ACCUM_INIT
, besr
.p1_v_accum_init
);
1527 OUTREG(OV0_P1_H_ACCUM_INIT
, besr
.p1_h_accum_init
);
1528 OUTREG(OV0_P23_H_ACCUM_INIT
, besr
.p23_h_accum_init
);
1529 OUTREG(OV0_P23_V_ACCUM_INIT
, besr
.p23_v_accum_init
);
1531 bes_flags
= SCALER_ENABLE
|
1532 SCALER_SMART_SWITCH
|
1535 if(besr
.double_buff
) bes_flags
|= SCALER_DOUBLE_BUFFER
;
1536 if(besr
.deinterlace_on
) bes_flags
|= SCALER_ADAPTIVE_DEINT
;
1537 if(besr
.horz_pick_nearest
) bes_flags
|= SCALER_HORZ_PICK_NEAREST
;
1538 if(besr
.vert_pick_nearest
) bes_flags
|= SCALER_VERT_PICK_NEAREST
;
1540 bes_flags
|= SCALER_BURST_PER_PLANE
;
1542 bes_flags
|= (besr
.surf_id
<< 8) & SCALER_SURFAC_FORMAT
;
1543 if(besr
.load_prg_start
) bes_flags
|= SCALER_PRG_LOAD_START
;
1544 if(force_second
) bes_flags
|= SCALER_USE_OV1
;
1545 else bes_flags
&= ~SCALER_USE_OV1
;
1546 OUTREG(OV0_SCALE_CNTL
, bes_flags
);
1547 radeon_fifo_wait(6);
1548 OUTREG(OV0_FILTER_CNTL
,besr
.filter_cntl
);
1549 OUTREG(OV0_FOUR_TAP_COEF_0
,besr
.four_tap_coeff
[0]);
1550 OUTREG(OV0_FOUR_TAP_COEF_1
,besr
.four_tap_coeff
[1]);
1551 OUTREG(OV0_FOUR_TAP_COEF_2
,besr
.four_tap_coeff
[2]);
1552 OUTREG(OV0_FOUR_TAP_COEF_3
,besr
.four_tap_coeff
[3]);
1553 OUTREG(OV0_FOUR_TAP_COEF_4
,besr
.four_tap_coeff
[4]);
1554 if(besr
.swap_uv
) OUTREG(OV0_TEST
,INREG(OV0_TEST
)|OV0_SWAP_UV
);
1555 OUTREG(OV0_REG_LOAD_CNTL
, 0);
1556 if(__verbose
> VERBOSE_LEVEL
) printf(RADEON_MSG
"we wanted: scaler=%08X\n",bes_flags
);
1557 if(__verbose
> VERBOSE_LEVEL
) radeon_vid_dump_regs();
1560 /* Goal of this function: hide RGB background and provide black screen around movie.
1561 Useful in '-vo fbdev:vidix -fs -zoom' mode.
1562 Reverse effect to colorkey */
1564 static void radeon_vid_exclusive( void )
1566 /* this function works only with Rage128.
1567 Radeon should has something the same */
1568 unsigned screenw
,screenh
;
1569 screenw
= radeon_get_xres();
1570 screenh
= radeon_get_yres();
1571 radeon_fifo_wait(2);
1572 OUTREG(OV0_EXCLUSIVE_VERT
,(((screenh
-1)<<16)&EXCL_VERT_END_MASK
));
1573 OUTREG(OV0_EXCLUSIVE_HORZ
,(((screenw
/8+1)<<8)&EXCL_HORZ_END_MASK
)|EXCL_HORZ_EXCLUSIVE_EN
);
1576 static void radeon_vid_non_exclusive( void )
1578 OUTREG(OV0_EXCLUSIVE_HORZ
,0);
1582 static unsigned radeon_query_pitch(unsigned fourcc
,const vidix_yuv_t
*spitch
)
1584 unsigned pitch
,spy
,spv
,spu
;
1585 spy
= spv
= spu
= 0;
1592 case 256: spy
= spitch
->y
; break;
1601 case 256: spu
= spitch
->u
; break;
1610 case 256: spv
= spitch
->v
; break;
1619 if(spy
> 16 && spu
== spy
/2 && spv
== spy
/2) pitch
= spy
;
1624 if(spy
>= 64 && spu
== spy
/4 && spv
== spy
/4) pitch
= spy
;
1628 if(spy
>= 16) pitch
= spy
;
1635 static void Calc_H_INC_STEP_BY (
1636 int fieldvalue_OV0_SURFACE_FORMAT
,
1637 double H_scale_ratio
,
1638 int DisallowFourTapVertFiltering
,
1639 int DisallowFourTapUVVertFiltering
,
1640 uint32_t *val_OV0_P1_H_INC
,
1641 uint32_t *val_OV0_P1_H_STEP_BY
,
1642 uint32_t *val_OV0_P23_H_INC
,
1643 uint32_t *val_OV0_P23_H_STEP_BY
,
1649 double ClocksNeededFor16Pixels
;
1651 switch (fieldvalue_OV0_SURFACE_FORMAT
)
1654 case 4: /*16BPP (ARGB1555 and RGB565) */
1655 /* All colour components are fetched in pairs */
1657 /* We don't support four tap in this mode because G's are split between two bytes. In theory we could support it if */
1658 /* we saved part of the G when fetching the R, and then filter the G, followed by the B in the following cycles. */
1659 if (H_scale_ratio
>=.5)
1661 /* We are actually generating two pixels (but 3 colour components) per tick. Thus we don't have to skip */
1662 /* until we reach .5. P1 and P23 are the same. */
1663 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5);
1664 *val_OV0_P1_H_STEP_BY
= 1;
1665 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5);
1666 *val_OV0_P23_H_STEP_BY
= 1;
1670 else if (H_scale_ratio
>=.25)
1673 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*2)) * (1<<0xc) + 0.5);
1674 *val_OV0_P1_H_STEP_BY
= 2;
1675 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*2)) * (1<<0xc) + 0.5);
1676 *val_OV0_P23_H_STEP_BY
= 2;
1680 else if (H_scale_ratio
>=.125)
1683 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*4)) * (1<<0xc) + 0.5);
1684 *val_OV0_P1_H_STEP_BY
= 3;
1685 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*4)) * (1<<0xc) + 0.5);
1686 *val_OV0_P23_H_STEP_BY
= 3;
1690 else if (H_scale_ratio
>=.0625)
1693 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*8)) * (1<<0xc) + 0.5);
1694 *val_OV0_P1_H_STEP_BY
= 4;
1695 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*8)) * (1<<0xc) + 0.5);
1696 *val_OV0_P23_H_STEP_BY
= 4;
1700 else if (H_scale_ratio
>=0.03125)
1702 /* Step by sixteen */
1703 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*16)) * (1<<0xc) + 0.5);
1704 *val_OV0_P1_H_STEP_BY
= 5;
1705 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*16)) * (1<<0xc) + 0.5);
1706 *val_OV0_P23_H_STEP_BY
= 5;
1712 H_scale_ratio
=0.03125;
1713 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*16)) * (1<<0xc) + 0.5);
1714 *val_OV0_P1_H_STEP_BY
= 5;
1715 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*16)) * (1<<0xc) + 0.5);
1716 *val_OV0_P23_H_STEP_BY
= 5;
1721 case 6: /*32BPP RGB */
1722 if (H_scale_ratio
>=1.5 && !DisallowFourTapVertFiltering
)
1724 /* All colour components are fetched in pairs */
1726 /* With four tap filtering, we can generate two colour components every clock, or two pixels every three */
1727 /* clocks. This means that we will have four tap filtering when scaling 1.5 or more. */
1728 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5);
1729 *val_OV0_P1_H_STEP_BY
= 0;
1730 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5);
1731 *val_OV0_P23_H_STEP_BY
= 0;
1735 else if (H_scale_ratio
>=0.75)
1737 /* Four G colour components are fetched at once */
1739 /* R and B colour components are fetched in pairs */
1740 /* With two tap filtering, we can generate four colour components every clock. */
1741 /* This means that we will have two tap filtering when scaling 1.0 or more. */
1742 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5);
1743 *val_OV0_P1_H_STEP_BY
= 1;
1744 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5);
1745 *val_OV0_P23_H_STEP_BY
= 1;
1749 else if (H_scale_ratio
>=0.375)
1752 /* Four G colour components are fetched at once */
1754 /* R and B colour components are fetched in pairs */
1755 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*2)) * (1<<0xc) + 0.5);
1756 *val_OV0_P1_H_STEP_BY
= 2;
1757 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*2)) * (1<<0xc) + 0.5);
1758 *val_OV0_P23_H_STEP_BY
= 2;
1762 else if (H_scale_ratio
>=0.25)
1765 /* Four G colour components are fetched at once */
1767 /* R and B colour components are fetched in pairs */
1768 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*2)) * (1<<0xc) + 0.5);
1769 *val_OV0_P1_H_STEP_BY
= 2;
1770 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*4)) * (1<<0xc) + 0.5);
1771 *val_OV0_P23_H_STEP_BY
= 3;
1775 else if (H_scale_ratio
>=0.1875)
1778 /* Four G colour components are fetched at once */
1780 /* R and B colour components are fetched in pairs */
1781 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*4)) * (1<<0xc) + 0.5);
1782 *val_OV0_P1_H_STEP_BY
= 3;
1783 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*4)) * (1<<0xc) + 0.5);
1784 *val_OV0_P23_H_STEP_BY
= 3;
1788 else if (H_scale_ratio
>=0.125)
1791 /* Four G colour components are fetched at once */
1793 /* R and B colour components are fetched in pairs */
1794 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*4)) * (1<<0xc) + 0.5);
1795 *val_OV0_P1_H_STEP_BY
= 3;
1796 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*8)) * (1<<0xc) + 0.5);
1797 *val_OV0_P23_H_STEP_BY
= 4;
1801 else if (H_scale_ratio
>=0.09375)
1804 /* Four G colour components are fetched at once */
1806 /* R and B colour components are fetched in pairs */
1807 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*8)) * (1<<0xc) + 0.5);
1808 *val_OV0_P1_H_STEP_BY
= 4;
1809 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*8)) * (1<<0xc) + 0.5);
1810 *val_OV0_P23_H_STEP_BY
= 4;
1814 else if (H_scale_ratio
>=0.0625)
1817 /* Four G colour components are fetched at once */
1819 /* R and B colour components are fetched in pairs */
1820 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*16)) * (1<<0xc) + 0.5);
1821 *val_OV0_P1_H_STEP_BY
= 5;
1822 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*16)) * (1<<0xc) + 0.5);
1823 *val_OV0_P23_H_STEP_BY
= 5;
1829 H_scale_ratio
=0.0625;
1831 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*16)) * (1<<0xc) + 0.5);
1832 *val_OV0_P1_H_STEP_BY
= 5;
1833 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*16)) * (1<<0xc) + 0.5);
1834 *val_OV0_P23_H_STEP_BY
= 5;
1840 /*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. */
1841 /* four tap on both (unless Y is too wide) */
1842 if ((H_scale_ratio
>=(ClocksNeededFor16Pixels
=8+2+2) / 16.0) &&
1843 ((uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5)<=0x3000) &&
1844 ((uint16_t)((1/(H_scale_ratio
*4)) * (1<<0xc) + 0.5)<=0x2000) &&
1845 !DisallowFourTapVertFiltering
&& !DisallowFourTapUVVertFiltering
)
1847 /* Colour components are fetched in pairs */
1849 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5);
1850 *val_OV0_P1_H_STEP_BY
= 0;
1851 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*4)) * (1<<0xc) + 0.5);
1852 *val_OV0_P23_H_STEP_BY
= 0;
1856 /* two tap on Y (because it is too big for four tap), four tap on UV */
1857 else if ((H_scale_ratio
>=(ClocksNeededFor16Pixels
=4+2+2) / 16.0) &&
1858 ((uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5)<=0x3000) &&
1859 ((uint16_t)((1/(H_scale_ratio
*4)) * (1<<0xc) + 0.5)<=0x2000) &&
1860 DisallowFourTapVertFiltering
&& !DisallowFourTapUVVertFiltering
)
1863 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5);
1864 *val_OV0_P1_H_STEP_BY
= 1;
1865 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*4)) * (1<<0xc) + 0.5);
1866 *val_OV0_P23_H_STEP_BY
= 0;
1870 /* We scale the Y with the four tap filters, but UV's are generated
1871 with dual two tap configuration. */
1872 else if ((H_scale_ratio
>=(ClocksNeededFor16Pixels
=8+1+1) / 16.0) &&
1873 ((uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5)<=0x3000) &&
1874 ((uint16_t)((1/(H_scale_ratio
*4)) * (1<<0xc) + 0.5)<=0x2000) &&
1875 !DisallowFourTapVertFiltering
)
1878 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5);
1879 *val_OV0_P1_H_STEP_BY
= 0;
1880 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*4)) * (1<<0xc) + 0.5);
1881 *val_OV0_P23_H_STEP_BY
= 1;
1885 /* We scale the Y, U, and V with the two tap filters */
1886 else if ((H_scale_ratio
>=(ClocksNeededFor16Pixels
=4+1+1) / 16.0) &&
1887 ((uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5)<=0x3000) &&
1888 ((uint16_t)((1/(H_scale_ratio
*4)) * (1<<0xc) + 0.5)<=0x2000))
1891 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5);
1892 *val_OV0_P1_H_STEP_BY
= 1;
1893 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*4)) * (1<<0xc) + 0.5);
1894 *val_OV0_P23_H_STEP_BY
= 1;
1898 /* We scale step the U and V by two to allow more bandwidth for fetching Y's,
1899 thus we won't drop Y's yet. */
1900 else if ((H_scale_ratio
>=(ClocksNeededFor16Pixels
=4+.5+.5) / 16.0) &&
1901 ((uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5)<=0x3000) &&
1902 ((uint16_t)((1/(H_scale_ratio
*4*2)) * (1<<0xc) + 0.5)<=0x2000))
1903 { /*>=0.3125 and >.333333~ */
1905 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5);
1906 *val_OV0_P1_H_STEP_BY
= 1;
1907 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*4*2)) * (1<<0xc) + 0.5);
1908 *val_OV0_P23_H_STEP_BY
= 2;
1912 /* We step the Y, U, and V by two. */
1913 else if ((H_scale_ratio
>=(ClocksNeededFor16Pixels
=2+.5+.5) / 16.0) &&
1914 ((uint16_t)((1/(H_scale_ratio
*2)) * (1<<0xc) + 0.5)<=0x3000) &&
1915 ((uint16_t)((1/(H_scale_ratio
*4*2)) * (1<<0xc) + 0.5)<=0x2000))
1918 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*2)) * (1<<0xc) + 0.5);
1919 *val_OV0_P1_H_STEP_BY
= 2;
1920 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*4*2)) * (1<<0xc) + 0.5);
1921 *val_OV0_P23_H_STEP_BY
= 2;
1925 /* We step the Y by two and the U and V by four. */
1926 else if ((H_scale_ratio
>=(ClocksNeededFor16Pixels
=2+.25+.25) / 16.0) &&
1927 ((uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5)<=0x3000) &&
1928 ((uint16_t)((1/(H_scale_ratio
*4*4)) * (1<<0xc) + 0.5)<=0x2000))
1931 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*2)) * (1<<0xc) + 0.5);
1932 *val_OV0_P1_H_STEP_BY
= 2;
1933 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*4*4)) * (1<<0xc) + 0.5);
1934 *val_OV0_P23_H_STEP_BY
= 3;
1938 /* We step the Y, U, and V by four. */
1939 else if ((H_scale_ratio
>=(ClocksNeededFor16Pixels
=1+.25+.25) / 16.0) &&
1940 ((uint16_t)((1/(H_scale_ratio
*4)) * (1<<0xc) + 0.5)<=0x3000) &&
1941 ((uint16_t)((1/(H_scale_ratio
*4*4)) * (1<<0xc) + 0.5)<=0x2000))
1944 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*4)) * (1<<0xc) + 0.5);
1945 *val_OV0_P1_H_STEP_BY
= 3;
1946 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*4*4)) * (1<<0xc) + 0.5);
1947 *val_OV0_P23_H_STEP_BY
= 3;
1951 /* 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 */
1953 /* We step the Y, U, and V by eight. */
1954 else if ((H_scale_ratio
>=(ClocksNeededFor16Pixels
=.5+.125+.125) / 16.0) &&
1955 ((uint16_t)((1/(H_scale_ratio
*8)) * (1<<0xc) + 0.5)<=0x3000) &&
1956 ((uint16_t)((1/(H_scale_ratio
*4*8)) * (1<<0xc) + 0.5)<=0x2000))
1959 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*8)) * (1<<0xc) + 0.5);
1960 *val_OV0_P1_H_STEP_BY
= 4;
1961 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*4*8)) * (1<<0xc) + 0.5);
1962 *val_OV0_P23_H_STEP_BY
= 4;
1966 /* We step the Y by eight and the U and V by sixteen. */
1967 else if ((H_scale_ratio
>=(ClocksNeededFor16Pixels
=.5+.0625+.0625) / 16.0) &&
1968 ((uint16_t)((1/(H_scale_ratio
*8)) * (1<<0xc) + 0.5)<=0x3000) &&
1969 ((uint16_t)((1/(H_scale_ratio
*4*16)) * (1<<0xc) + 0.5)<=0x2000))
1972 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*8)) * (1<<0xc) + 0.5);
1973 *val_OV0_P1_H_STEP_BY
= 4;
1974 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*4*16)) * (1<<0xc) + 0.5);
1975 *val_OV0_P23_H_STEP_BY
= 5;
1979 /* We step the Y, U, and V by sixteen. */
1980 else if ((H_scale_ratio
>=(ClocksNeededFor16Pixels
=.25+.0625+.0625) / 16.0) &&
1981 ((uint16_t)((1/(H_scale_ratio
*16)) * (1<<0xc) + 0.5)<=0x3000) &&
1982 ((uint16_t)((1/(H_scale_ratio
*4*16)) * (1<<0xc) + 0.5)<=0x2000))
1985 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*16)) * (1<<0xc) + 0.5);
1986 *val_OV0_P1_H_STEP_BY
= 5;
1987 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*4*16)) * (1<<0xc) + 0.5);
1988 *val_OV0_P23_H_STEP_BY
= 5;
1994 H_scale_ratio
=(ClocksNeededFor16Pixels
=.25+.0625+.0625) / 16;
1996 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*16)) * (1<<0xc) + 0.5);
1997 *val_OV0_P1_H_STEP_BY
= 5;
1998 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*4*16)) * (1<<0xc) + 0.5);
1999 *val_OV0_P23_H_STEP_BY
= 5;
2008 case 14: /* YUV12, VYUY422, YUYV422, YOverPkCRCB12, YWovenWithPkCRCB12 */
2009 /* We scale the Y, U, and V with the four tap filters */
2010 /* four tap on both (unless Y is too wide) */
2011 if ((H_scale_ratio
>=(ClocksNeededFor16Pixels
=8+4+4) / 16.0) &&
2012 !DisallowFourTapVertFiltering
&& !DisallowFourTapUVVertFiltering
)
2015 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5);
2016 *val_OV0_P1_H_STEP_BY
= 0;
2017 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*2)) * (1<<0xc) + 0.5);
2018 *val_OV0_P23_H_STEP_BY
= 0;
2022 /* two tap on Y (because it is too big for four tap), four tap on UV */
2023 else if ((H_scale_ratio
>=(ClocksNeededFor16Pixels
=4+4+4) / 16.0) &&
2024 DisallowFourTapVertFiltering
&& !DisallowFourTapUVVertFiltering
)
2027 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5);
2028 *val_OV0_P1_H_STEP_BY
= 1;
2029 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*2)) * (1<<0xc) + 0.5);
2030 *val_OV0_P23_H_STEP_BY
= 0;
2034 /* We scale the Y with the four tap filters, but UV's are generated
2035 with dual two tap configuration. */
2036 else if ((H_scale_ratio
>=(ClocksNeededFor16Pixels
=8+2+2) / 16.0) &&
2037 !DisallowFourTapVertFiltering
)
2040 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5);
2041 *val_OV0_P1_H_STEP_BY
= 0;
2042 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*2)) * (1<<0xc) + 0.5);
2043 *val_OV0_P23_H_STEP_BY
= 1;
2047 /* We scale the Y, U, and V with the two tap filters */
2048 else if (H_scale_ratio
>=(ClocksNeededFor16Pixels
=4+2+2) / 16.0)
2051 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5);
2052 *val_OV0_P1_H_STEP_BY
= 1;
2053 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*2)) * (1<<0xc) + 0.5);
2054 *val_OV0_P23_H_STEP_BY
= 1;
2058 /* We scale step the U and V by two to allow more bandwidth for
2059 fetching Y's, thus we won't drop Y's yet. */
2060 else if (H_scale_ratio
>=(ClocksNeededFor16Pixels
=4+1+1) / 16.0)
2063 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5);
2064 *val_OV0_P1_H_STEP_BY
= 1;
2065 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*2*2)) * (1<<0xc) + 0.5);
2066 *val_OV0_P23_H_STEP_BY
= 2;
2070 /* We step the Y, U, and V by two. */
2071 else if (H_scale_ratio
>=(ClocksNeededFor16Pixels
=2+1+1) / 16.0)
2074 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*2)) * (1<<0xc) + 0.5);
2075 *val_OV0_P1_H_STEP_BY
= 2;
2076 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*2*2)) * (1<<0xc) + 0.5);
2077 *val_OV0_P23_H_STEP_BY
= 2;
2081 /* We step the Y by two and the U and V by four. */
2082 else if (H_scale_ratio
>=(ClocksNeededFor16Pixels
=2+.5+.5) / 16.0)
2085 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*2)) * (1<<0xc) + 0.5);
2086 *val_OV0_P1_H_STEP_BY
= 2;
2087 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*2*4)) * (1<<0xc) + 0.5);
2088 *val_OV0_P23_H_STEP_BY
= 3;
2092 /* We step the Y, U, and V by four. */
2093 else if (H_scale_ratio
>=(ClocksNeededFor16Pixels
=1+.5+.5) / 16.0)
2096 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*4)) * (1<<0xc) + 0.5);
2097 *val_OV0_P1_H_STEP_BY
= 3;
2098 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*2*4)) * (1<<0xc) + 0.5);
2099 *val_OV0_P23_H_STEP_BY
= 3;
2103 /* We step the Y by four and the U and V by eight. */
2104 else if ((H_scale_ratio
>=(ClocksNeededFor16Pixels
=1+.25+.25) / 16.0) &&
2105 (fieldvalue_OV0_SURFACE_FORMAT
==10))
2108 /* Can't mix step by 3 and step by 4 for packed modes */
2109 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*4)) * (1<<0xc) + 0.5);
2110 *val_OV0_P1_H_STEP_BY
= 3;
2111 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*2*8)) * (1<<0xc) + 0.5);
2112 *val_OV0_P23_H_STEP_BY
= 4;
2116 /* We step the Y, U, and V by eight. */
2117 else if (H_scale_ratio
>=(ClocksNeededFor16Pixels
=.5+.25+.25) / 16.0)
2120 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*8)) * (1<<0xc) + 0.5);
2121 *val_OV0_P1_H_STEP_BY
= 4;
2122 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*2*8)) * (1<<0xc) + 0.5);
2123 *val_OV0_P23_H_STEP_BY
= 4;
2127 /* We step the Y by eight and the U and V by sixteen. */
2128 else if ((H_scale_ratio
>=(ClocksNeededFor16Pixels
=.5+.125+.125) / 16.0) && (fieldvalue_OV0_SURFACE_FORMAT
==10))
2131 /* Step by 5 not supported for packed modes */
2132 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*8)) * (1<<0xc) + 0.5);
2133 *val_OV0_P1_H_STEP_BY
= 4;
2134 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*2*16)) * (1<<0xc) + 0.5);
2135 *val_OV0_P23_H_STEP_BY
= 5;
2139 /* We step the Y, U, and V by sixteen. */
2140 else if ((H_scale_ratio
>=(ClocksNeededFor16Pixels
=.25+.125+.125) / 16.0) &&
2141 (fieldvalue_OV0_SURFACE_FORMAT
==10))
2144 /* Step by 5 not supported for packed modes */
2145 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*16)) * (1<<0xc) + 0.5);
2146 *val_OV0_P1_H_STEP_BY
= 5;
2147 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*2*16)) * (1<<0xc) + 0.5);
2148 *val_OV0_P23_H_STEP_BY
= 5;
2154 if (fieldvalue_OV0_SURFACE_FORMAT
==10)
2156 H_scale_ratio
=(ClocksNeededFor16Pixels
=.25+.125+.125) / 16;
2158 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*16)) * (1<<0xc) + 0.5);
2159 *val_OV0_P1_H_STEP_BY
= 5;
2160 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*2*16)) * (1<<0xc) + 0.5);
2161 *val_OV0_P23_H_STEP_BY
= 5;
2167 H_scale_ratio
=(ClocksNeededFor16Pixels
=.5+.25+.25) / 16;
2169 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*8)) * (1<<0xc) + 0.5);
2170 *val_OV0_P1_H_STEP_BY
= 4;
2171 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*2*8)) * (1<<0xc) + 0.5);
2172 *val_OV0_P23_H_STEP_BY
= 4;
2181 besr
.h_inc
= (*(val_OV0_P1_H_INC
)&0x3fff) | ((*(val_OV0_P23_H_INC
)&0x3fff)<<16);
2182 besr
.step_by
= (*(val_OV0_P1_H_STEP_BY
)&0x7) | ((*(val_OV0_P23_H_STEP_BY
)&0x7)<<8);
2185 /* ********************************************************* */
2186 /* ** Setup Black Bordering */
2187 /* ********************************************************* */
2189 static void ComputeBorders( vidix_playback_t
*config
, int VertUVSubSample
)
2191 double tempBLANK_LINES_AT_TOP
;
2192 unsigned TopLine
,BottomLine
,SourceLinesUsed
,TopUVLine
,BottomUVLine
,SourceUVLinesUsed
;
2193 uint32_t val_OV0_P1_ACTIVE_LINES_M1
,val_OV0_P1_BLNK_LN_AT_TOP_M1
;
2194 uint32_t val_OV0_P23_ACTIVE_LINES_M1
,val_OV0_P23_BLNK_LN_AT_TOP_M1
;
2196 if (floor(config
->src
.y
)<0) {
2197 tempBLANK_LINES_AT_TOP
= -floor(config
->src
.y
);
2201 tempBLANK_LINES_AT_TOP
= 0;
2202 TopLine
= (int)floor(config
->src
.y
);
2204 /* Round rSrcBottom up and subtract one */
2205 if (ceil(config
->src
.y
+config
->src
.h
) > config
->src
.h
)
2207 BottomLine
= config
->src
.h
- 1;
2211 BottomLine
= (int)ceil(config
->src
.y
+config
->src
.h
) - 1;
2214 if (BottomLine
>= TopLine
)
2216 SourceLinesUsed
= BottomLine
- TopLine
+ 1;
2220 /*CYCACC_ASSERT(0, "SourceLinesUsed less than or equal to zero.") */
2221 SourceLinesUsed
= 1;
2225 int SourceHeightInPixels
;
2226 SourceHeightInPixels
= BottomLine
- TopLine
+ 1;
2229 val_OV0_P1_ACTIVE_LINES_M1
= SourceLinesUsed
- 1;
2230 val_OV0_P1_BLNK_LN_AT_TOP_M1
= ((int)tempBLANK_LINES_AT_TOP
-1) & 0xfff;
2232 TopUVLine
= ((int)(config
->src
.y
/VertUVSubSample
) < 0) ? 0: (int)(config
->src
.y
/VertUVSubSample
); /* Round rSrcTop down */
2233 BottomUVLine
= (ceil(((config
->src
.y
+config
->src
.h
)/VertUVSubSample
)) > (config
->src
.h
/VertUVSubSample
))
2234 ? (config
->src
.h
/VertUVSubSample
)-1 : (unsigned int)ceil(((config
->src
.y
+config
->src
.h
)/VertUVSubSample
))-1;
2236 if (BottomUVLine
>= TopUVLine
)
2238 SourceUVLinesUsed
= BottomUVLine
- TopUVLine
+ 1;
2242 /*CYCACC_ASSERT(0, "SourceUVLinesUsed less than or equal to zero.") */
2243 SourceUVLinesUsed
= 1;
2245 val_OV0_P23_ACTIVE_LINES_M1
= SourceUVLinesUsed
- 1;
2246 val_OV0_P23_BLNK_LN_AT_TOP_M1
= ((int)(tempBLANK_LINES_AT_TOP
/VertUVSubSample
)-1) & 0x7ff;
2247 besr
.p1_blank_lines_at_top
= (val_OV0_P1_BLNK_LN_AT_TOP_M1
& 0xfff) |
2248 ((val_OV0_P1_ACTIVE_LINES_M1
& 0xfff) << 16);
2249 besr
.p23_blank_lines_at_top
= (val_OV0_P23_BLNK_LN_AT_TOP_M1
& 0x7ff) |
2250 ((val_OV0_P23_ACTIVE_LINES_M1
& 0x7ff) << 16);
2254 static void ComputeXStartEnd(
2256 uint32_t LeftPixel
,uint32_t LeftUVPixel
,
2257 uint32_t MemWordsInBytes
,uint32_t BytesPerPixel
,
2258 uint32_t SourceWidthInPixels
, uint32_t P1StepSize
,
2259 uint32_t BytesPerUVPixel
,uint32_t SourceUVWidthInPixels
,
2260 uint32_t P23StepSize
, uint32_t *p1_x_start
, uint32_t *p2_x_start
)
2262 uint32_t val_OV0_P1_X_START
,val_OV0_P2_X_START
,val_OV0_P3_X_START
;
2263 uint32_t val_OV0_P1_X_END
,val_OV0_P2_X_END
,val_OV0_P3_X_END
;
2264 /* 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. */
2266 val_OV0_P1_X_START
= (int)LeftPixel
% (MemWordsInBytes
/BytesPerPixel
);
2267 val_OV0_P1_X_END
= (int)((val_OV0_P1_X_START
+ SourceWidthInPixels
- 1) / P1StepSize
) * P1StepSize
;
2269 val_OV0_P2_X_START
= val_OV0_P2_X_END
= 0;
2270 switch (besr
.surf_id
)
2275 case 14: /* ToDo_Active: The driver must insure that the initial value is */
2276 /* a multiple of a power of two when decimating */
2277 val_OV0_P2_X_START
= (int)LeftUVPixel
%
2278 (MemWordsInBytes
/BytesPerUVPixel
);
2279 val_OV0_P2_X_END
= (int)((val_OV0_P2_X_START
+
2280 SourceUVWidthInPixels
- 1) / P23StepSize
) * P23StepSize
;
2283 case 12: val_OV0_P2_X_START
= (int)LeftUVPixel
% (MemWordsInBytes
/(BytesPerPixel
*2));
2284 val_OV0_P2_X_END
= (int)((val_OV0_P2_X_START
+ SourceUVWidthInPixels
- 1) / P23StepSize
) * P23StepSize
;
2287 case 4: val_OV0_P2_X_START
= val_OV0_P1_X_START
;
2288 /* This value is needed only to allow proper setting of */
2289 /* val_OV0_PRESHIFT_P23_TO */
2290 /* val_OV0_P2_X_END = 0; */
2292 case 6: val_OV0_P2_X_START
= (int)LeftPixel
% (MemWordsInBytes
/BytesPerPixel
);
2293 val_OV0_P2_X_END
= (int)((val_OV0_P1_X_START
+ SourceWidthInPixels
- 1) / P23StepSize
) * P23StepSize
;
2295 default: /* insert debug statement here. */
2296 RADEON_ASSERT("unknown fourcc\n");
2299 val_OV0_P3_X_START
= val_OV0_P2_X_START
;
2300 val_OV0_P3_X_END
= val_OV0_P2_X_END
;
2302 besr
.p1_x_start_end
= (val_OV0_P1_X_END
&0x7ff) | ((val_OV0_P1_X_START
&0x7ff)<<16);
2303 besr
.p2_x_start_end
= (val_OV0_P2_X_END
&0x7ff) | ((val_OV0_P2_X_START
&0x7ff)<<16);
2304 besr
.p3_x_start_end
= (val_OV0_P3_X_END
&0x7ff) | ((val_OV0_P3_X_START
&0x7ff)<<16);
2307 besr
.p2_x_start_end
= 0;
2308 besr
.p3_x_start_end
= 0;
2310 *p1_x_start
= val_OV0_P1_X_START
;
2311 *p2_x_start
= val_OV0_P2_X_START
;
2314 static void ComputeAccumInit(
2315 uint32_t val_OV0_P1_X_START
,uint32_t val_OV0_P2_X_START
,
2316 uint32_t val_OV0_P1_H_INC
,uint32_t val_OV0_P23_H_INC
,
2317 uint32_t val_OV0_P1_H_STEP_BY
,uint32_t val_OV0_P23_H_STEP_BY
,
2319 uint32_t P1GroupSize
, uint32_t P23GroupSize
,
2320 uint32_t val_OV0_P1_MAX_LN_IN_PER_LN_OUT
,
2321 uint32_t val_OV0_P23_MAX_LN_IN_PER_LN_OUT
)
2323 uint32_t val_OV0_P1_H_ACCUM_INIT
,val_OV0_PRESHIFT_P1_TO
;
2324 uint32_t val_OV0_P23_H_ACCUM_INIT
,val_OV0_PRESHIFT_P23_TO
;
2325 uint32_t val_OV0_P1_V_ACCUM_INIT
,val_OV0_P23_V_ACCUM_INIT
;
2326 /* 2.5 puts the kernal 50% of the way between the source pixel that is off screen */
2327 /* and the first on-screen source pixel. "(float)valOV0_P?_H_INC / (1<<0xc)" is */
2328 /* the distance (in source pixel coordinates) to the center of the first */
2329 /* destination pixel. Need to add additional pixels depending on how many pixels */
2330 /* are fetched at a time and how many pixels in a set are masked. */
2331 /* P23 values are always fetched in groups of two or four. If the start */
2332 /* pixel does not fall on the boundary, then we need to shift preshift for */
2333 /* some additional pixels */
2336 double ExtraHalfPixel
;
2337 double tempAdditionalShift
;
2338 double tempP1HStartPoint
;
2339 double tempP23HStartPoint
;
2343 if (besr
.horz_pick_nearest
) ExtraHalfPixel
= 0.5;
2344 else ExtraHalfPixel
= 0.0;
2345 tempAdditionalShift
= val_OV0_P1_X_START
% P1GroupSize
+ ExtraHalfPixel
;
2346 tempP1HStartPoint
= tempAdditionalShift
+ 2.5 + ((float)val_OV0_P1_H_INC
/ (1<<0xd));
2347 tempP1Init
= (double)((int)(tempP1HStartPoint
* (1<<0x5) + 0.5)) / (1<<0x5);
2349 /* P23 values are always fetched in pairs. If the start pixel is odd, then we */
2350 /* need to shift an additional pixel */
2351 /* Note that if the pitch is a multiple of two, and if we store fields using */
2352 /* the traditional planer format where the V plane and the U plane share the */
2353 /* same pitch, then OverlayRegFields->val_OV0_P2_X_START % P23Group */
2354 /* OverlayRegFields->val_OV0_P3_X_START % P23GroupSize. Either way */
2355 /* it is a requirement that the U and V start on the same polarity byte */
2356 /* (even or odd). */
2357 tempAdditionalShift
= val_OV0_P2_X_START
% P23GroupSize
+ ExtraHalfPixel
;
2358 tempP23HStartPoint
= tempAdditionalShift
+ 2.5 + ((float)val_OV0_P23_H_INC
/ (1<<0xd));
2359 tempP23Init
= (double)((int)(tempP23HStartPoint
* (1<<0x5) + 0.5)) / (1 << 0x5);
2360 val_OV0_P1_H_ACCUM_INIT
= (int)((tempP1Init
- (int)tempP1Init
) * (1<<0x5));
2361 val_OV0_PRESHIFT_P1_TO
= (int)tempP1Init
;
2362 val_OV0_P23_H_ACCUM_INIT
= (int)((tempP23Init
- (int)tempP23Init
) * (1<<0x5));
2363 val_OV0_PRESHIFT_P23_TO
= (int)tempP23Init
;
2366 /* ************************************************************** */
2367 /* ** Calculate values for initializing the vertical accumulators */
2368 /* ************************************************************** */
2371 double ExtraHalfLine
;
2372 double ExtraFullLine
;
2373 double tempP1VStartPoint
;
2374 double tempP23VStartPoint
;
2376 if (besr
.vert_pick_nearest
) ExtraHalfLine
= 0.5;
2377 else ExtraHalfLine
= 0.0;
2379 if (val_OV0_P1_H_STEP_BY
==0)ExtraFullLine
= 1.0;
2380 else ExtraFullLine
= 0.0;
2382 tempP1VStartPoint
= 1.5 + ExtraFullLine
+ ExtraHalfLine
+ ((float)CRT_V_INC
/ (1<<0xd));
2383 if (tempP1VStartPoint
>2.5 + 2*ExtraFullLine
)
2385 tempP1VStartPoint
= 2.5 + 2*ExtraFullLine
;
2387 val_OV0_P1_V_ACCUM_INIT
= (int)(tempP1VStartPoint
* (1<<0x5) + 0.5);
2389 if (val_OV0_P23_H_STEP_BY
==0)ExtraFullLine
= 1.0;
2390 else ExtraFullLine
= 0.0;
2392 switch (besr
.surf_id
)
2396 case 14: tempP23VStartPoint
= 1.5 + ExtraFullLine
+ ExtraHalfLine
+
2397 ((float)CRT_V_INC
/ (1<<0xe));
2399 case 9: tempP23VStartPoint
= 1.5 + ExtraFullLine
+ ExtraHalfLine
+
2400 ((float)CRT_V_INC
/ (1<<0xf));
2406 case 12: tempP23VStartPoint
= 0;
2408 default: tempP23VStartPoint
= 0xFFFF;/* insert debug statement here */
2412 if (tempP23VStartPoint
>2.5 + 2*ExtraFullLine
)
2414 tempP23VStartPoint
= 2.5 + 2*ExtraFullLine
;
2417 val_OV0_P23_V_ACCUM_INIT
= (int)(tempP23VStartPoint
* (1<<0x5) + 0.5);
2419 besr
.p1_h_accum_init
= ((val_OV0_P1_H_ACCUM_INIT
&0x1f)<<15) |((val_OV0_PRESHIFT_P1_TO
&0xf)<<28);
2420 besr
.p1_v_accum_init
= (val_OV0_P1_MAX_LN_IN_PER_LN_OUT
&0x3) |((val_OV0_P1_V_ACCUM_INIT
&0x7ff)<<15);
2421 besr
.p23_h_accum_init
= ((val_OV0_P23_H_ACCUM_INIT
&0x1f)<<15) |((val_OV0_PRESHIFT_P23_TO
&0xf)<<28);
2422 besr
.p23_v_accum_init
= (val_OV0_P23_MAX_LN_IN_PER_LN_OUT
&0x3)|((val_OV0_P23_V_ACCUM_INIT
&0x3ff)<<15);
2425 typedef struct RangeAndCoefSet
{
2427 signed char CoefSet
[5][4];
2430 /* Filter Setup Routine */
2431 static void FilterSetup ( uint32_t val_OV0_P1_H_INC
)
2433 static RANGEANDCOEFSET ArrayOfSets
[] = {
2434 {0.25, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2435 {0.26, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2436 {0.27, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2437 {0.28, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2438 {0.29, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2439 {0.30, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2440 {0.31, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2441 {0.32, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2442 {0.33, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2443 {0.34, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2444 {0.35, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2445 {0.36, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2446 {0.37, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2447 {0.38, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2448 {0.39, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2449 {0.40, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2450 {0.41, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2451 {0.42, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2452 {0.43, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2453 {0.44, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2454 {0.45, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2455 {0.46, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2456 {0.47, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2457 {0.48, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2458 {0.49, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2459 {0.50, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2460 {0.51, {{ 7, 17, 8, 0}, { 6, 17, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 2, 14, 14, 2}, }},
2461 {0.52, {{ 7, 17, 8, 0}, { 6, 17, 9, 0}, { 5, 16, 11, 0}, { 3, 15, 13, 1}, { 2, 14, 14, 2}, }},
2462 {0.53, {{ 7, 17, 8, 0}, { 6, 17, 9, 0}, { 5, 16, 11, 0}, { 3, 15, 13, 1}, { 2, 14, 14, 2}, }},
2463 {0.54, {{ 7, 17, 8, 0}, { 6, 17, 9, 0}, { 4, 17, 11, 0}, { 3, 15, 13, 1}, { 2, 14, 14, 2}, }},
2464 {0.55, {{ 7, 18, 7, 0}, { 6, 17, 9, 0}, { 4, 17, 11, 0}, { 3, 15, 13, 1}, { 1, 15, 15, 1}, }},
2465 {0.56, {{ 7, 18, 7, 0}, { 5, 18, 9, 0}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }},
2466 {0.57, {{ 7, 18, 7, 0}, { 5, 18, 9, 0}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }},
2467 {0.58, {{ 7, 18, 7, 0}, { 5, 18, 9, 0}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }},
2468 {0.59, {{ 7, 18, 7, 0}, { 5, 18, 9, 0}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }},
2469 {0.60, {{ 7, 18, 8, -1}, { 6, 17, 10, -1}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }},
2470 {0.61, {{ 7, 18, 8, -1}, { 6, 17, 10, -1}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }},
2471 {0.62, {{ 7, 18, 8, -1}, { 6, 17, 10, -1}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }},
2472 {0.63, {{ 7, 18, 8, -1}, { 6, 17, 10, -1}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }},
2473 {0.64, {{ 7, 18, 8, -1}, { 6, 17, 10, -1}, { 4, 17, 12, -1}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }},
2474 {0.65, {{ 7, 18, 8, -1}, { 6, 17, 10, -1}, { 4, 17, 12, -1}, { 2, 17, 13, 0}, { 0, 16, 16, 0}, }},
2475 {0.66, {{ 7, 18, 8, -1}, { 6, 18, 10, -2}, { 4, 17, 12, -1}, { 2, 17, 13, 0}, { 0, 16, 16, 0}, }},
2476 {0.67, {{ 7, 20, 7, -2}, { 5, 19, 10, -2}, { 3, 18, 12, -1}, { 2, 17, 13, 0}, { 0, 16, 16, 0}, }},
2477 {0.68, {{ 7, 20, 7, -2}, { 5, 19, 10, -2}, { 3, 19, 12, -2}, { 1, 18, 14, -1}, { 0, 16, 16, 0}, }},
2478 {0.69, {{ 7, 20, 7, -2}, { 5, 19, 10, -2}, { 3, 19, 12, -2}, { 1, 18, 14, -1}, { 0, 16, 16, 0}, }},
2479 {0.70, {{ 7, 20, 7, -2}, { 5, 20, 9, -2}, { 3, 19, 12, -2}, { 1, 18, 14, -1}, { 0, 16, 16, 0}, }},
2480 {0.71, {{ 7, 20, 7, -2}, { 5, 20, 9, -2}, { 3, 19, 12, -2}, { 1, 18, 14, -1}, { 0, 16, 16, 0}, }},
2481 {0.72, {{ 7, 20, 7, -2}, { 5, 20, 9, -2}, { 2, 20, 12, -2}, { 0, 19, 15, -2}, {-1, 17, 17, -1}, }},
2482 {0.73, {{ 7, 20, 7, -2}, { 4, 21, 9, -2}, { 2, 20, 12, -2}, { 0, 19, 15, -2}, {-1, 17, 17, -1}, }},
2483 {0.74, {{ 6, 22, 6, -2}, { 4, 21, 9, -2}, { 2, 20, 12, -2}, { 0, 19, 15, -2}, {-1, 17, 17, -1}, }},
2484 {0.75, {{ 6, 22, 6, -2}, { 4, 21, 9, -2}, { 1, 21, 12, -2}, { 0, 19, 15, -2}, {-1, 17, 17, -1}, }},
2485 {0.76, {{ 6, 22, 6, -2}, { 4, 21, 9, -2}, { 1, 21, 12, -2}, { 0, 19, 15, -2}, {-1, 17, 17, -1}, }},
2486 {0.77, {{ 6, 22, 6, -2}, { 3, 22, 9, -2}, { 1, 22, 12, -3}, { 0, 19, 15, -2}, {-2, 18, 18, -2}, }},
2487 {0.78, {{ 6, 21, 6, -1}, { 3, 22, 9, -2}, { 1, 22, 12, -3}, { 0, 19, 15, -2}, {-2, 18, 18, -2}, }},
2488 {0.79, {{ 5, 23, 5, -1}, { 3, 22, 9, -2}, { 0, 23, 12, -3}, {-1, 21, 15, -3}, {-2, 18, 18, -2}, }},
2489 {0.80, {{ 5, 23, 5, -1}, { 3, 23, 8, -2}, { 0, 23, 12, -3}, {-1, 21, 15, -3}, {-2, 18, 18, -2}, }},
2490 {0.81, {{ 5, 23, 5, -1}, { 2, 24, 8, -2}, { 0, 23, 12, -3}, {-1, 21, 15, -3}, {-2, 18, 18, -2}, }},
2491 {0.82, {{ 5, 23, 5, -1}, { 2, 24, 8, -2}, { 0, 23, 12, -3}, {-1, 21, 15, -3}, {-3, 19, 19, -3}, }},
2492 {0.83, {{ 5, 23, 5, -1}, { 2, 24, 8, -2}, { 0, 23, 11, -2}, {-2, 22, 15, -3}, {-3, 19, 19, -3}, }},
2493 {0.84, {{ 4, 25, 4, -1}, { 1, 25, 8, -2}, { 0, 23, 11, -2}, {-2, 22, 15, -3}, {-3, 19, 19, -3}, }},
2494 {0.85, {{ 4, 25, 4, -1}, { 1, 25, 8, -2}, { 0, 23, 11, -2}, {-2, 22, 15, -3}, {-3, 19, 19, -3}, }},
2495 {0.86, {{ 4, 24, 4, 0}, { 1, 25, 7, -1}, {-1, 24, 11, -2}, {-2, 22, 15, -3}, {-3, 19, 19, -3}, }},
2496 {0.87, {{ 4, 24, 4, 0}, { 1, 25, 7, -1}, {-1, 24, 11, -2}, {-2, 22, 15, -3}, {-3, 19, 19, -3}, }},
2497 {0.88, {{ 3, 26, 3, 0}, { 0, 26, 7, -1}, {-1, 24, 11, -2}, {-3, 23, 15, -3}, {-3, 19, 19, -3}, }},
2498 {0.89, {{ 3, 26, 3, 0}, { 0, 26, 7, -1}, {-1, 24, 11, -2}, {-3, 23, 15, -3}, {-3, 19, 19, -3}, }},
2499 {0.90, {{ 3, 26, 3, 0}, { 0, 26, 7, -1}, {-2, 25, 11, -2}, {-3, 23, 15, -3}, {-3, 19, 19, -3}, }},
2500 {0.91, {{ 3, 26, 3, 0}, { 0, 27, 6, -1}, {-2, 25, 11, -2}, {-3, 23, 15, -3}, {-3, 19, 19, -3}, }},
2501 {0.92, {{ 2, 28, 2, 0}, { 0, 27, 6, -1}, {-2, 25, 11, -2}, {-3, 23, 15, -3}, {-3, 19, 19, -3}, }},
2502 {0.93, {{ 2, 28, 2, 0}, { 0, 26, 6, 0}, {-2, 25, 10, -1}, {-3, 23, 15, -3}, {-3, 19, 19, -3}, }},
2503 {0.94, {{ 2, 28, 2, 0}, { 0, 26, 6, 0}, {-2, 25, 10, -1}, {-3, 23, 15, -3}, {-3, 19, 19, -3}, }},
2504 {0.95, {{ 1, 30, 1, 0}, {-1, 28, 5, 0}, {-3, 26, 10, -1}, {-3, 23, 14, -2}, {-3, 19, 19, -3}, }},
2505 {0.96, {{ 1, 30, 1, 0}, {-1, 28, 5, 0}, {-3, 26, 10, -1}, {-3, 23, 14, -2}, {-3, 19, 19, -3}, }},
2506 {0.97, {{ 1, 30, 1, 0}, {-1, 28, 5, 0}, {-3, 26, 10, -1}, {-3, 23, 14, -2}, {-3, 19, 19, -3}, }},
2507 {0.98, {{ 1, 30, 1, 0}, {-2, 29, 5, 0}, {-3, 27, 9, -1}, {-3, 23, 14, -2}, {-3, 19, 19, -3}, }},
2508 {0.99, {{ 0, 32, 0, 0}, {-2, 29, 5, 0}, {-3, 27, 9, -1}, {-4, 24, 14, -2}, {-3, 19, 19, -3}, }},
2509 {1.00, {{ 0, 32, 0, 0}, {-2, 29, 5, 0}, {-3, 27, 9, -1}, {-4, 24, 14, -2}, {-3, 19, 19, -3}, }}
2514 unsigned ArrayElement
;
2516 DSR
= (double)(1<<0xc)/val_OV0_P1_H_INC
;
2517 if (DSR
<.25) DSR
=.25;
2520 ArrayElement
= (int)((DSR
-0.25) * 100);
2521 besr
.four_tap_coeff
[0] = (ArrayOfSets
[ArrayElement
].CoefSet
[0][0] & 0xf) |
2522 ((ArrayOfSets
[ArrayElement
].CoefSet
[0][1] & 0x7f)<<8) |
2523 ((ArrayOfSets
[ArrayElement
].CoefSet
[0][2] & 0x7f)<<16) |
2524 ((ArrayOfSets
[ArrayElement
].CoefSet
[0][3] & 0xf)<<24);
2525 besr
.four_tap_coeff
[1] = (ArrayOfSets
[ArrayElement
].CoefSet
[1][0] & 0xf) |
2526 ((ArrayOfSets
[ArrayElement
].CoefSet
[1][1] & 0x7f)<<8) |
2527 ((ArrayOfSets
[ArrayElement
].CoefSet
[1][2] & 0x7f)<<16) |
2528 ((ArrayOfSets
[ArrayElement
].CoefSet
[1][3] & 0xf)<<24);
2529 besr
.four_tap_coeff
[2] = (ArrayOfSets
[ArrayElement
].CoefSet
[2][0] & 0xf) |
2530 ((ArrayOfSets
[ArrayElement
].CoefSet
[2][1] & 0x7f)<<8) |
2531 ((ArrayOfSets
[ArrayElement
].CoefSet
[2][2] & 0x7f)<<16) |
2532 ((ArrayOfSets
[ArrayElement
].CoefSet
[2][3] & 0xf)<<24);
2533 besr
.four_tap_coeff
[3] = (ArrayOfSets
[ArrayElement
].CoefSet
[3][0] & 0xf) |
2534 ((ArrayOfSets
[ArrayElement
].CoefSet
[3][1] & 0x7f)<<8) |
2535 ((ArrayOfSets
[ArrayElement
].CoefSet
[3][2] & 0x7f)<<16) |
2536 ((ArrayOfSets
[ArrayElement
].CoefSet
[3][3] & 0xf)<<24);
2537 besr
.four_tap_coeff
[4] = (ArrayOfSets
[ArrayElement
].CoefSet
[4][0] & 0xf) |
2538 ((ArrayOfSets
[ArrayElement
].CoefSet
[4][1] & 0x7f)<<8) |
2539 ((ArrayOfSets
[ArrayElement
].CoefSet
[4][2] & 0x7f)<<16) |
2540 ((ArrayOfSets
[ArrayElement
].CoefSet
[4][3] & 0xf)<<24);
2542 For more details, refer to Microsoft's draft of PC99.
2546 /* The minimal value of horizontal scale ratio when hard coded coefficients
2547 are suitable for the best quality. */
2548 /* FIXME: Should it be 0.9 for Rage128 ??? */
2549 static const double MinHScaleHard
=0.75;
2551 static int radeon_vid_init_video( vidix_playback_t
*config
)
2553 double V_scale_ratio
;
2554 uint32_t i
,src_w
,src_h
,dest_w
,dest_h
,pitch
,left
,leftUV
,top
,h_inc
;
2555 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;
2556 uint32_t val_OV0_P1_X_START
,val_OV0_P2_X_START
;
2557 uint32_t val_OV0_P1_MAX_LN_IN_PER_LN_OUT
,val_OV0_P23_MAX_LN_IN_PER_LN_OUT
;
2559 uint32_t BytesPerOctWord
,LogMemWordsInBytes
,MemWordsInBytes
,LogTileWidthInMemWords
;
2560 uint32_t TileWidthInMemWords
,TileWidthInBytes
,LogTileHeight
,TileHeight
;
2561 uint32_t PageSizeInBytes
,OV0LB_Rows
;
2562 uint32_t SourceWidthInMemWords
,SourceUVWidthInMemWords
;
2563 uint32_t SourceWidthInPixels
,SourceUVWidthInPixels
;
2564 uint32_t RightPixel
,RightUVPixel
,LeftPixel
,LeftUVPixel
;
2565 int is_400
,is_410
,is_420
,best_pitch
,mpitch
;
2566 int horz_repl_factor
,interlace_factor
;
2567 int BytesPerPixel
,BytesPerUVPixel
,HorzUVSubSample
,VertUVSubSample
;
2568 int DisallowFourTapVertFiltering
,DisallowFourTapUVVertFiltering
;
2570 radeon_vid_stop_video();
2571 left
= config
->src
.x
<< 16;
2572 top
= config
->src
.y
<< 16;
2573 src_h
= config
->src
.h
;
2574 src_w
= config
->src
.w
;
2575 is_400
= is_410
= is_420
= 0;
2576 if(config
->fourcc
== IMGFMT_YV12
||
2577 config
->fourcc
== IMGFMT_I420
||
2578 config
->fourcc
== IMGFMT_IYUV
) is_420
= 1;
2579 if(config
->fourcc
== IMGFMT_YVU9
||
2580 config
->fourcc
== IMGFMT_IF09
) is_410
= 1;
2581 if(config
->fourcc
== IMGFMT_Y800
) is_400
= 1;
2582 best_pitch
= radeon_query_pitch(config
->fourcc
,&config
->src
.pitch
);
2583 mpitch
= best_pitch
-1;
2584 BytesPerOctWord
= 16;
2585 LogMemWordsInBytes
= 4;
2586 MemWordsInBytes
= 1<<LogMemWordsInBytes
;
2587 LogTileWidthInMemWords
= 2;
2588 TileWidthInMemWords
= 1<<LogTileWidthInMemWords
;
2589 TileWidthInBytes
= 1<<(LogTileWidthInMemWords
+LogMemWordsInBytes
);
2591 TileHeight
= 1<<LogTileHeight
;
2592 PageSizeInBytes
= 64*MemWordsInBytes
;
2595 switch(config
->fourcc
)
2605 case IMGFMT_I420
: pitch
= (src_w
+ mpitch
) & ~mpitch
;
2606 config
->dest
.pitch
.y
=
2607 config
->dest
.pitch
.u
=
2608 config
->dest
.pitch
.v
= best_pitch
;
2612 case IMGFMT_BGR32
: pitch
= (src_w
*4 + mpitch
) & ~mpitch
;
2613 config
->dest
.pitch
.y
=
2614 config
->dest
.pitch
.u
=
2615 config
->dest
.pitch
.v
= best_pitch
;
2619 default: /* RGB15, RGB16, YVYU, UYVY, YUY2 */
2620 pitch
= ((src_w
*2) + mpitch
) & ~mpitch
;
2621 config
->dest
.pitch
.y
=
2622 config
->dest
.pitch
.u
=
2623 config
->dest
.pitch
.v
= best_pitch
;
2626 besr
.load_prg_start
=0;
2628 switch(config
->fourcc
)
2632 case IMGFMT_BGR15
: besr
.surf_id
= SCALER_SOURCE_15BPP
>>8;
2633 besr
.load_prg_start
= 1;
2637 case IMGFMT_BGR16
: besr
.surf_id
= SCALER_SOURCE_16BPP
>>8;
2638 besr
.load_prg_start
= 1;
2642 case IMGFMT_BGR32
: besr
.surf_id
= SCALER_SOURCE_32BPP
>>8;
2643 besr
.load_prg_start
= 1;
2647 case IMGFMT_YVU9
: besr
.surf_id
= SCALER_SOURCE_YUV9
>>8;
2654 case IMGFMT_YV12
: besr
.surf_id
= SCALER_SOURCE_YUV12
>>8;
2658 case IMGFMT_UYVY
: besr
.surf_id
= SCALER_SOURCE_YVYU422
>>8;
2661 default: besr
.surf_id
= SCALER_SOURCE_VYUY422
>>8;
2664 switch (besr
.surf_id
)
2669 case 12: BytesPerPixel
= 2;
2671 case 6: BytesPerPixel
= 4;
2676 case 14: BytesPerPixel
= 1;
2678 default: BytesPerPixel
= 0;/*insert a debug statement here. */
2681 switch (besr
.surf_id
)
2684 case 4: BytesPerUVPixel
= 0;
2685 break;/* In RGB modes, the BytesPerUVPixel is don't care */
2687 case 12: BytesPerUVPixel
= 2;
2689 case 6: BytesPerUVPixel
= 0;
2690 break; /* In RGB modes, the BytesPerUVPixel is don't care */
2692 case 10: BytesPerUVPixel
= 1;
2695 case 14: BytesPerUVPixel
= 2;
2697 default: BytesPerUVPixel
= 0;/* insert a debug statement here. */
2701 switch (besr
.surf_id
)
2705 case 6: HorzUVSubSample
= 1;
2707 case 9: HorzUVSubSample
= 4;
2713 case 14: HorzUVSubSample
= 2;
2715 default: HorzUVSubSample
= 0;/* insert debug statement here. */
2718 switch (besr
.surf_id
)
2724 case 12: VertUVSubSample
= 1;
2726 case 9: VertUVSubSample
= 4;
2730 case 14: VertUVSubSample
= 2;
2732 default: VertUVSubSample
= 0;/* insert debug statment here. */
2735 DisallowFourTapVertFiltering
= 0; /* Allow it by default */
2736 DisallowFourTapUVVertFiltering
= 0; /* Allow it by default */
2737 LeftPixel
= config
->src
.x
;
2738 RightPixel
= config
->src
.w
-1;
2739 if(floor(config
->src
.x
/HorzUVSubSample
)<0) LeftUVPixel
= 0;
2740 else LeftUVPixel
= (int)floor(config
->src
.x
/HorzUVSubSample
);
2741 if(ceil((config
->src
.x
+config
->src
.w
)/HorzUVSubSample
) > config
->src
.w
/HorzUVSubSample
)
2742 RightUVPixel
= config
->src
.w
/HorzUVSubSample
- 1;
2743 else RightUVPixel
= (int)ceil((config
->src
.x
+config
->src
.w
)/HorzUVSubSample
) - 1;
2744 /* Top, Bottom and Right Crops can be out of range. The driver will program the hardware
2745 // to create a black border at the top and bottom. This is useful for DVD letterboxing. */
2746 SourceWidthInPixels
= (int)(config
->src
.w
+ 1);
2747 SourceUVWidthInPixels
= (int)(RightUVPixel
- LeftUVPixel
+ 1);
2749 SourceWidthInMemWords
= (int)(ceil(RightPixel
*BytesPerPixel
/ MemWordsInBytes
) -
2750 floor(LeftPixel
*BytesPerPixel
/ MemWordsInBytes
) + 1);
2751 /* SourceUVWidthInMemWords means Source_U_or_V_or_UV_WidthInMemWords depending on whether the UV is packed together of not. */
2752 SourceUVWidthInMemWords
= (int)(ceil(RightUVPixel
*BytesPerUVPixel
/
2753 MemWordsInBytes
) - floor(LeftUVPixel
*BytesPerUVPixel
/
2754 MemWordsInBytes
) + 1);
2756 switch (besr
.surf_id
)
2759 case 10: if ((ceil(SourceWidthInMemWords
/2)-1) * 2 > OV0LB_Rows
-1)
2761 RADEON_ASSERT("ceil(SourceWidthInMemWords/2)-1) * 2 > OV0LB_Rows-1\n");
2763 else if ((SourceWidthInMemWords
-1) * 2 > OV0LB_Rows
-1)
2765 DisallowFourTapVertFiltering
= 1;
2768 if ((ceil(SourceUVWidthInMemWords
/2)-1) * 4 + 1 > OV0LB_Rows
-1)
2770 /*CYCACC_ASSERT(0, "Image U plane width spans more octwords than supported by hardware.") */
2772 else if ((SourceUVWidthInMemWords
-1) * 4 + 1 > OV0LB_Rows
-1)
2774 DisallowFourTapUVVertFiltering
= 1;
2777 if ((ceil(SourceUVWidthInMemWords
/2)-1) * 4 + 3 > OV0LB_Rows
-1)
2779 /*CYCACC_ASSERT(0, "Image V plane width spans more octwords than supported by hardware.") */
2781 else if ((SourceUVWidthInMemWords
-1) * 4 + 3 > OV0LB_Rows
-1)
2783 DisallowFourTapUVVertFiltering
= 1;
2787 case 14: if ((ceil(SourceWidthInMemWords
/2)-1) * 2 > OV0LB_Rows
-1)
2789 RADEON_ASSERT("ceil(SourceWidthInMemWords/2)-1) * 2 > OV0LB_Rows-1\n");
2791 else if ((SourceWidthInMemWords
-1) * 2 > OV0LB_Rows
-1)
2793 DisallowFourTapVertFiltering
= 1;
2796 if ((ceil(SourceUVWidthInMemWords
/2)-1) * 2 + 1 > OV0LB_Rows
-1)
2798 /*CYCACC_ASSERT(0, "Image UV plane width spans more octwords than supported by hardware.") */
2800 else if ((SourceUVWidthInMemWords
-1) * 2 + 1 > OV0LB_Rows
-1)
2802 DisallowFourTapUVVertFiltering
= 1;
2809 case 12: if ((ceil(SourceWidthInMemWords
/2)-1) > OV0LB_Rows
-1)
2811 RADEON_ASSERT("(ceil(SourceWidthInMemWords/2)-1) > OV0LB_Rows-1\n")
2813 else if ((SourceWidthInMemWords
-1) > OV0LB_Rows
-1)
2815 DisallowFourTapVertFiltering
= 1;
2818 default: /* insert debug statement here. */
2821 dest_w
= config
->dest
.w
;
2822 dest_h
= config
->dest
.h
;
2823 if(radeon_is_dbl_scan()) dest_h
*= 2;
2824 besr
.dest_bpp
= radeon_vid_get_dbpp();
2825 besr
.fourcc
= config
->fourcc
;
2826 if(radeon_is_interlace()) interlace_factor
= 2;
2827 else interlace_factor
= 1;
2828 /* TODO: must be checked in doublescan mode!!! */
2829 if((besr
.chip_flags
&R_INTEGRATED
)==R_INTEGRATED
)
2831 /* Force the overlay clock on for integrated chips */
2832 OUTPLL(VCLK_ECP_CNTL
, (INPLL(VCLK_ECP_CNTL
) | (1<<18)));
2834 horz_repl_factor
= 1 << (uint32_t)((INPLL(VCLK_ECP_CNTL
) & 0x300) >> 8);
2835 H_scale_ratio
= (double)ceil(((double)dest_w
+1)/horz_repl_factor
)/src_w
;
2836 V_scale_ratio
= (double)(dest_h
+1)/src_h
;
2837 if(H_scale_ratio
< 0.5 && V_scale_ratio
< 0.5)
2839 val_OV0_P1_MAX_LN_IN_PER_LN_OUT
= 3;
2840 val_OV0_P23_MAX_LN_IN_PER_LN_OUT
= 2;
2843 if(H_scale_ratio
< 1 && V_scale_ratio
< 1)
2845 val_OV0_P1_MAX_LN_IN_PER_LN_OUT
= 2;
2846 val_OV0_P23_MAX_LN_IN_PER_LN_OUT
= 1;
2850 val_OV0_P1_MAX_LN_IN_PER_LN_OUT
= 1;
2851 val_OV0_P23_MAX_LN_IN_PER_LN_OUT
= 1;
2853 /* N.B.: Indeed it has 6.12 format but shifted on 8 to the left!!! */
2854 besr
.v_inc
= (uint16_t)((1./V_scale_ratio
)*(1<<12)*interlace_factor
+0.5);
2855 CRT_V_INC
= besr
.v_inc
/interlace_factor
;
2858 int ThereIsTwoTapVerticalFiltering
,DoNotUseMostRecentlyFetchedLine
;
2859 int P1GroupSize
= 0;
2862 int P23StepSize
= 0;
2867 DisallowFourTapVertFiltering
,
2868 DisallowFourTapUVVertFiltering
,
2870 &val_OV0_P1_H_STEP_BY
,
2872 &val_OV0_P23_H_STEP_BY
,
2877 if(H_scale_ratio
> MinHScaleHard
)
2879 h_inc
= (src_w
<< 12) / dest_w
;
2880 besr
.step_by
= 0x0101;
2881 switch (besr
.surf_id
)
2886 besr
.h_inc
= (h_inc
)|(h_inc
<<16);
2889 besr
.h_inc
= h_inc
| ((h_inc
>> 2) << 16);
2892 besr
.h_inc
= h_inc
| ((h_inc
>> 1) << 16);
2897 P23GroupSize
= 2; /* Current vaue for all modes */
2899 besr
.horz_pick_nearest
=0;
2900 DoNotUseMostRecentlyFetchedLine
=0;
2901 ThereIsTwoTapVerticalFiltering
= (val_OV0_P1_H_STEP_BY
!=0) || (val_OV0_P23_H_STEP_BY
!=0);
2902 if (ThereIsTwoTapVerticalFiltering
&& DoNotUseMostRecentlyFetchedLine
)
2903 besr
.vert_pick_nearest
= 1;
2905 besr
.vert_pick_nearest
= 0;
2907 ComputeXStartEnd(is_400
,LeftPixel
,LeftUVPixel
,MemWordsInBytes
,BytesPerPixel
,
2908 SourceWidthInPixels
,P1StepSize
,BytesPerUVPixel
,
2909 SourceUVWidthInPixels
,P23StepSize
,&val_OV0_P1_X_START
,&val_OV0_P2_X_START
);
2911 if(H_scale_ratio
> MinHScaleHard
)
2914 tmp
= (left
& 0x0003ffff) + 0x00028000 + (h_inc
<< 3);
2915 besr
.p1_h_accum_init
= ((tmp
<< 4) & 0x000f8000) |
2916 ((tmp
<< 12) & 0xf0000000);
2918 tmp
= (top
& 0x0000ffff) + 0x00018000;
2919 besr
.p1_v_accum_init
= ((tmp
<< 4) & OV0_P1_V_ACCUM_INIT_MASK
)
2920 |(OV0_P1_MAX_LN_IN_PER_LN_OUT
& 1);
2921 tmp
= ((left
>> 1) & 0x0001ffff) + 0x00028000 + (h_inc
<< 2);
2922 besr
.p23_h_accum_init
= ((tmp
<< 4) & 0x000f8000) |
2923 ((tmp
<< 12) & 0x70000000);
2925 tmp
= ((top
>> 1) & 0x0000ffff) + 0x00018000;
2926 besr
.p23_v_accum_init
= (is_420
||is_410
) ?
2927 ((tmp
<< 4) & OV0_P23_V_ACCUM_INIT_MASK
)
2928 |(OV0_P23_MAX_LN_IN_PER_LN_OUT
& 1) : 0;
2931 ComputeAccumInit( val_OV0_P1_X_START
,val_OV0_P2_X_START
,
2932 val_OV0_P1_H_INC
,val_OV0_P23_H_INC
,
2933 val_OV0_P1_H_STEP_BY
,val_OV0_P23_H_STEP_BY
,
2934 CRT_V_INC
,P1GroupSize
,P23GroupSize
,
2935 val_OV0_P1_MAX_LN_IN_PER_LN_OUT
,
2936 val_OV0_P23_MAX_LN_IN_PER_LN_OUT
);
2939 /* keep everything in 16.16 */
2940 besr
.base_addr
= INREG(DISPLAY_BASE_ADDR
);
2941 config
->offsets
[0] = 0;
2942 for(i
=1;i
<besr
.vid_nbufs
;i
++)
2943 config
->offsets
[i
] = config
->offsets
[i
-1]+config
->frame_size
;
2944 if(is_420
|| is_410
|| is_400
)
2946 uint32_t d1line
,d2line
,d3line
;
2950 d2line
= src_h
*pitch
+(d1line
>>2);
2951 d3line
= d2line
+((src_h
*pitch
)>>2);
2956 d2line
= src_h
*pitch
+(d1line
>>4);
2957 d3line
= d2line
+((src_h
*pitch
)>>4);
2964 d1line
+= (left
>> 16) & ~15;
2967 d2line
+= (left
>> 17) & ~15;
2968 d3line
+= (left
>> 17) & ~15;
2972 d2line
+= (left
>> 18) & ~15;
2973 d3line
+= (left
>> 18) & ~15;
2975 config
->offset
.y
= d1line
& VIF_BUF0_BASE_ADRS_MASK
;
2978 config
->offset
.v
= 0;
2979 config
->offset
.u
= 0;
2983 config
->offset
.v
= d2line
& VIF_BUF1_BASE_ADRS_MASK
;
2984 config
->offset
.u
= d3line
& VIF_BUF2_BASE_ADRS_MASK
;
2986 for(i
=0;i
<besr
.vid_nbufs
;i
++)
2988 besr
.vid_buf_base_adrs_y
[i
]=((radeon_overlay_off
+config
->offsets
[i
]+config
->offset
.y
)&VIF_BUF0_BASE_ADRS_MASK
);
2991 besr
.vid_buf_base_adrs_v
[i
]=0;
2992 besr
.vid_buf_base_adrs_u
[i
]=0;
2996 if (besr
.fourcc
== IMGFMT_I420
|| besr
.fourcc
== IMGFMT_IYUV
)
2998 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
;
2999 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
;
3003 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
;
3004 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
;
3008 config
->offset
.y
= ((besr
.vid_buf_base_adrs_y
[0])&VIF_BUF0_BASE_ADRS_MASK
) - radeon_overlay_off
;
3011 config
->offset
.v
= 0;
3012 config
->offset
.u
= 0;
3016 config
->offset
.v
= ((besr
.vid_buf_base_adrs_v
[0])&VIF_BUF1_BASE_ADRS_MASK
) - radeon_overlay_off
;
3017 config
->offset
.u
= ((besr
.vid_buf_base_adrs_u
[0])&VIF_BUF2_BASE_ADRS_MASK
) - radeon_overlay_off
;
3022 config
->offset
.y
= config
->offset
.u
= config
->offset
.v
= ((left
& ~7) << 1)&VIF_BUF0_BASE_ADRS_MASK
;
3023 for(i
=0;i
<besr
.vid_nbufs
;i
++)
3025 besr
.vid_buf_base_adrs_y
[i
] =
3026 besr
.vid_buf_base_adrs_u
[i
] =
3027 besr
.vid_buf_base_adrs_v
[i
] = radeon_overlay_off
+ config
->offsets
[i
] + config
->offset
.y
;
3030 leftUV
= (left
>> (is_410
?18:17)) & 15;
3031 left
= (left
>> 16) & 15;
3032 besr
.y_x_start
= (config
->dest
.x
+X_ADJUST
) | (config
->dest
.y
<< 16);
3033 besr
.y_x_end
= (config
->dest
.x
+ dest_w
+X_ADJUST
) | ((config
->dest
.y
+ dest_h
) << 16);
3034 ComputeBorders(config
,VertUVSubSample
);
3035 besr
.vid_buf_pitch0_value
= pitch
;
3036 besr
.vid_buf_pitch1_value
= is_410
? pitch
>>2 : is_420
? pitch
>>1 : pitch
;
3037 /* ********************************************************* */
3038 /* ** Calculate programmable coefficients as needed */
3039 /* ********************************************************* */
3041 /* ToDo_Active: When in pick nearest mode, we need to program the filter tap zero */
3042 /* coefficients to 0, 32, 0, 0. Or use hard coded coefficients. */
3043 if(H_scale_ratio
> MinHScaleHard
) besr
.filter_cntl
|= FILTER_HARDCODED_COEF
;
3046 FilterSetup (val_OV0_P1_H_INC
);
3047 /* ToDo_Active: Must add the smarts into the driver to decide what type of filtering it */
3048 /* would like to do. For now, we let the test application decide. */
3049 besr
.filter_cntl
= FILTER_PROGRAMMABLE_COEF
;
3050 if(DisallowFourTapVertFiltering
)
3051 besr
.filter_cntl
|= FILTER_HARD_SCALE_VERT_Y
;
3052 if(DisallowFourTapUVVertFiltering
)
3053 besr
.filter_cntl
|= FILTER_HARD_SCALE_VERT_UV
;
3058 static void radeon_compute_framesize(vidix_playback_t
*info
)
3060 unsigned pitch
,awidth
,dbpp
;
3061 pitch
= radeon_query_pitch(info
->fourcc
,&info
->src
.pitch
);
3062 dbpp
= radeon_vid_get_dbpp();
3063 switch(info
->fourcc
)
3066 awidth
= (info
->src
.w
+ (pitch
-1)) & ~(pitch
-1);
3067 info
->frame_size
= awidth
*info
->src
.h
;
3071 awidth
= (info
->src
.w
+ (pitch
-1)) & ~(pitch
-1);
3072 info
->frame_size
= awidth
*(info
->src
.h
+info
->src
.h
/8);
3077 awidth
= (info
->src
.w
+ (pitch
-1)) & ~(pitch
-1);
3078 info
->frame_size
= awidth
*(info
->src
.h
+info
->src
.h
/2);
3082 awidth
= (info
->src
.w
*4 + (pitch
-1)) & ~(pitch
-1);
3083 info
->frame_size
= awidth
*info
->src
.h
;
3085 /* YUY2 YVYU, RGB15, RGB16 */
3087 awidth
= (info
->src
.w
*2 + (pitch
-1)) & ~(pitch
-1);
3088 info
->frame_size
= awidth
*info
->src
.h
;
3091 info
->frame_size
= (info
->frame_size
+4095)&~4095;
3094 static int radeon_config_playback(vidix_playback_t
*info
)
3096 unsigned rgb_size
,nfr
;
3097 uint32_t radeon_video_size
;
3098 if(!is_supported_fourcc(info
->fourcc
)) return ENOSYS
;
3099 if(info
->num_frames
>VID_PLAY_MAXFRAMES
) info
->num_frames
=VID_PLAY_MAXFRAMES
;
3100 if(info
->num_frames
==1) besr
.double_buff
=0;
3101 else besr
.double_buff
=1;
3102 radeon_compute_framesize(info
);
3104 rgb_size
= radeon_get_xres()*radeon_get_yres()*((radeon_vid_get_dbpp()+7)/8);
3105 nfr
= info
->num_frames
;
3106 radeon_video_size
= radeon_ram_size
;
3109 radeon_overlay_off
= radeon_video_size
- info
->frame_size
*nfr
;
3110 #if !defined (RAGE128) && defined(HAVE_X11)
3111 radeon_overlay_off
-= firegl_shift
;
3113 radeon_overlay_off
&= 0xffff0000;
3114 if(radeon_overlay_off
>= (int)rgb_size
) break;
3118 nfr
= info
->num_frames
;
3121 radeon_overlay_off
= radeon_video_size
- info
->frame_size
*nfr
;
3122 #if !defined (RAGE128) && defined(HAVE_X11)
3123 radeon_overlay_off
-= firegl_shift
;
3125 radeon_overlay_off
&= 0xffff0000;
3126 if(radeon_overlay_off
> 0) break;
3129 if(nfr
<= 0) return EINVAL
;
3130 info
->num_frames
= nfr
;
3131 besr
.vid_nbufs
= info
->num_frames
;
3132 info
->dga_addr
= (char *)radeon_mem_base
+ radeon_overlay_off
;
3133 radeon_vid_init_video(info
);
3137 static int radeon_playback_on(void)
3142 radeon_vid_display_video();
3144 dh
= (besr
.y_x_end
>> 16) - (besr
.y_x_start
>> 16);
3145 dw
= (besr
.y_x_end
& 0xFFFF) - (besr
.y_x_start
& 0xFFFF);
3146 if(dw
== radeon_get_xres() || dh
== radeon_get_yres()) radeon_vid_exclusive();
3147 else radeon_vid_non_exclusive();
3152 static int radeon_playback_off(void)
3154 radeon_vid_stop_video();
3158 static int radeon_frame_select(unsigned frame
)
3161 int prev_frame
= (frame
-1+besr
.vid_nbufs
) % besr
.vid_nbufs
;
3163 buf3-5 always should point onto second buffer for better
3164 deinterlacing and TV-in
3166 if(!besr
.double_buff
) return 0;
3167 if(frame
> besr
.vid_nbufs
) frame
= besr
.vid_nbufs
-1;
3168 if(prev_frame
> (int)besr
.vid_nbufs
) prev_frame
= besr
.vid_nbufs
-1;
3169 off
[0] = besr
.vid_buf_base_adrs_y
[frame
];
3170 off
[1] = besr
.vid_buf_base_adrs_v
[frame
];
3171 off
[2] = besr
.vid_buf_base_adrs_u
[frame
];
3172 off
[3] = besr
.vid_buf_base_adrs_y
[prev_frame
];
3173 off
[4] = besr
.vid_buf_base_adrs_v
[prev_frame
];
3174 off
[5] = besr
.vid_buf_base_adrs_u
[prev_frame
];
3175 radeon_fifo_wait(8);
3176 OUTREG(OV0_REG_LOAD_CNTL
, REG_LD_CTL_LOCK
);
3177 radeon_engine_idle();
3178 while(!(INREG(OV0_REG_LOAD_CNTL
)®_LD_CTL_LOCK_READBACK
));
3179 OUTREG(OV0_VID_BUF0_BASE_ADRS
, off
[0]);
3180 OUTREG(OV0_VID_BUF1_BASE_ADRS
, off
[1]);
3181 OUTREG(OV0_VID_BUF2_BASE_ADRS
, off
[2]);
3182 OUTREG(OV0_VID_BUF3_BASE_ADRS
, off
[3]);
3183 OUTREG(OV0_VID_BUF4_BASE_ADRS
, off
[4]);
3184 OUTREG(OV0_VID_BUF5_BASE_ADRS
, off
[5]);
3185 OUTREG(OV0_REG_LOAD_CNTL
, 0);
3186 if(besr
.vid_nbufs
== 2) radeon_wait_vsync();
3187 if(__verbose
> VERBOSE_LEVEL
) radeon_vid_dump_regs();
3191 static vidix_video_eq_t equal
=
3193 VEQ_CAP_BRIGHTNESS
| VEQ_CAP_SATURATION
3195 | VEQ_CAP_CONTRAST
| VEQ_CAP_HUE
| VEQ_CAP_RGB_INTENSITY
3198 0, 0, 0, 0, 0, 0, 0, 0 };
3200 static int radeon_get_eq(vidix_video_eq_t
* eq
)
3202 memcpy(eq
,&equal
,sizeof(vidix_video_eq_t
));
3207 #define RTFSaturation(a) (1.0 + ((a)*1.0)/1000.0)
3208 #define RTFBrightness(a) (((a)*1.0)/2000.0)
3209 #define RTFIntensity(a) (((a)*1.0)/2000.0)
3210 #define RTFContrast(a) (1.0 + ((a)*1.0)/1000.0)
3211 #define RTFHue(a) (((a)*3.1416)/1000.0)
3212 #define RTFCheckParam(a) {if((a)<-1000) (a)=-1000; if((a)>1000) (a)=1000;}
3215 static int radeon_set_eq(const vidix_video_eq_t
* eq
)
3222 if(eq
->cap
& VEQ_CAP_BRIGHTNESS
) equal
.brightness
= eq
->brightness
;
3223 if(eq
->cap
& VEQ_CAP_CONTRAST
) equal
.contrast
= eq
->contrast
;
3224 if(eq
->cap
& VEQ_CAP_SATURATION
) equal
.saturation
= eq
->saturation
;
3225 if(eq
->cap
& VEQ_CAP_HUE
) equal
.hue
= eq
->hue
;
3226 if(eq
->cap
& VEQ_CAP_RGB_INTENSITY
)
3228 equal
.red_intensity
= eq
->red_intensity
;
3229 equal
.green_intensity
= eq
->green_intensity
;
3230 equal
.blue_intensity
= eq
->blue_intensity
;
3232 equal
.flags
= eq
->flags
;
3234 br
= equal
.brightness
* 64 / 1000;
3235 if(br
< -64) br
= -64; if(br
> 63) br
= 63;
3236 sat
= (equal
.saturation
*31 + 31000) / 2000;
3237 if(sat
< 0) sat
= 0; if(sat
> 31) sat
= 31;
3238 OUTREG(OV0_COLOUR_CNTL
, (br
& 0x7f) | (sat
<< 8) | (sat
<< 16));
3240 itu_space
= equal
.flags
== VEQ_FLG_ITU_R_BT_709
? 1 : 0;
3241 RTFCheckParam(equal
.brightness
);
3242 RTFCheckParam(equal
.saturation
);
3243 RTFCheckParam(equal
.contrast
);
3244 RTFCheckParam(equal
.hue
);
3245 RTFCheckParam(equal
.red_intensity
);
3246 RTFCheckParam(equal
.green_intensity
);
3247 RTFCheckParam(equal
.blue_intensity
);
3248 radeon_set_transform(RTFBrightness(equal
.brightness
),
3249 RTFContrast(equal
.contrast
),
3250 RTFSaturation(equal
.saturation
),
3252 RTFIntensity(equal
.red_intensity
),
3253 RTFIntensity(equal
.green_intensity
),
3254 RTFIntensity(equal
.blue_intensity
),
3260 static int radeon_playback_set_deint(const vidix_deinterlace_t
* info
)
3266 case CFG_NON_INTERLACED
:
3267 besr
.deinterlace_on
= 0;
3269 case CFG_EVEN_ODD_INTERLACING
:
3270 case CFG_INTERLACED
:
3271 besr
.deinterlace_on
= 1;
3272 besr
.deinterlace_pattern
= 0x900AAAAA;
3274 case CFG_ODD_EVEN_INTERLACING
:
3275 besr
.deinterlace_on
= 1;
3276 besr
.deinterlace_pattern
= 0x00055555;
3278 case CFG_UNIQUE_INTERLACING
:
3279 besr
.deinterlace_on
= 1;
3280 besr
.deinterlace_pattern
= info
->deinterlace_pattern
;
3283 OUTREG(OV0_REG_LOAD_CNTL
, REG_LD_CTL_LOCK
);
3284 radeon_engine_idle();
3285 while(!(INREG(OV0_REG_LOAD_CNTL
)®_LD_CTL_LOCK_READBACK
));
3286 radeon_fifo_wait(15);
3287 sflg
= INREG(OV0_SCALE_CNTL
);
3288 if(besr
.deinterlace_on
)
3290 OUTREG(OV0_SCALE_CNTL
,sflg
| SCALER_ADAPTIVE_DEINT
);
3291 OUTREG(OV0_DEINTERLACE_PATTERN
,besr
.deinterlace_pattern
);
3293 else OUTREG(OV0_SCALE_CNTL
,sflg
& (~SCALER_ADAPTIVE_DEINT
));
3294 OUTREG(OV0_REG_LOAD_CNTL
, 0);
3298 static int radeon_playback_get_deint(vidix_deinterlace_t
* info
)
3300 if(!besr
.deinterlace_on
) info
->flags
= CFG_NON_INTERLACED
;
3303 info
->flags
= CFG_UNIQUE_INTERLACING
;
3304 info
->deinterlace_pattern
= besr
.deinterlace_pattern
;
3311 static vidix_grkey_t radeon_grkey
;
3313 static int set_gr_key( void )
3317 besr
.merge_cntl
= 0xff000000 | /* overlay alpha */
3318 0x00ff0000; /* graphic alpha */
3319 if(radeon_grkey
.ckey
.op
== CKEY_TRUE
)
3321 int dbpp
=radeon_vid_get_dbpp();
3328 if((besr
.chip_flags
&R_100
)!=R_100
)
3329 besr
.graphics_key_clr
=
3330 ((radeon_grkey
.ckey
.blue
&0xF8))
3331 | ((radeon_grkey
.ckey
.green
&0xF8)<<8)
3332 | ((radeon_grkey
.ckey
.red
&0xF8)<<16);
3335 besr
.graphics_key_clr
=
3336 ((radeon_grkey
.ckey
.blue
&0xF8)>>3)
3337 | ((radeon_grkey
.ckey
.green
&0xF8)<<2)
3338 | ((radeon_grkey
.ckey
.red
&0xF8)<<7);
3342 /* This test may be too general/specific */
3343 if((besr
.chip_flags
&R_100
)!=R_100
)
3344 besr
.graphics_key_clr
=
3345 ((radeon_grkey
.ckey
.blue
&0xF8))
3346 | ((radeon_grkey
.ckey
.green
&0xFC)<<8)
3347 | ((radeon_grkey
.ckey
.red
&0xF8)<<16);
3350 besr
.graphics_key_clr
=
3351 ((radeon_grkey
.ckey
.blue
&0xF8)>>3)
3352 | ((radeon_grkey
.ckey
.green
&0xFC)<<3)
3353 | ((radeon_grkey
.ckey
.red
&0xF8)<<8);
3357 besr
.graphics_key_clr
=
3358 ((radeon_grkey
.ckey
.blue
&0xFF))
3359 | ((radeon_grkey
.ckey
.green
&0xFF)<<8)
3360 | ((radeon_grkey
.ckey
.red
&0xFF)<<16);
3364 besr
.graphics_key_msk
=0;
3365 besr
.graphics_key_clr
=0;
3368 besr
.graphics_key_msk
=(1<<dbpp
)-1;
3369 besr
.ckey_cntl
= VIDEO_KEY_FN_TRUE
|GRAPHIC_KEY_FN_NE
|CMP_MIX_AND
;
3371 besr
.graphics_key_msk
=besr
.graphics_key_clr
;
3372 besr
.ckey_cntl
= VIDEO_KEY_FN_TRUE
|CMP_MIX_AND
|GRAPHIC_KEY_FN_EQ
;
3375 else if(radeon_grkey
.ckey
.op
== CKEY_ALPHA
)
3377 int dbpp
=radeon_vid_get_dbpp();
3384 besr
.graphics_key_msk
=0;
3385 besr
.graphics_key_clr
=0;
3386 besr
.ckey_cntl
= VIDEO_KEY_FN_TRUE
|GRAPHIC_KEY_FN_TRUE
|CMP_MIX_AND
;
3387 besr
.merge_cntl
= 0xff000000 | /* overlay alpha */
3388 0x00ff0000 | /* graphic alpha */
3389 0x00000001; /* DISP_ALPHA_MODE_PER_PIXEL */
3393 besr
.graphics_key_msk
=0;
3394 besr
.graphics_key_clr
=0;
3395 besr
.ckey_cntl
= VIDEO_KEY_FN_TRUE
|GRAPHIC_KEY_FN_TRUE
|CMP_MIX_AND
;
3402 besr
.graphics_key_msk
=0;
3403 besr
.graphics_key_clr
=0;
3404 besr
.ckey_cntl
= VIDEO_KEY_FN_TRUE
|GRAPHIC_KEY_FN_TRUE
|CMP_MIX_AND
;
3406 radeon_fifo_wait(3);
3407 OUTREG(OV0_GRAPHICS_KEY_MSK
, besr
.graphics_key_msk
);
3408 OUTREG(OV0_GRAPHICS_KEY_CLR
, besr
.graphics_key_clr
);
3409 OUTREG(OV0_KEY_CNTL
,besr
.ckey_cntl
);
3410 OUTREG(DISP_MERGE_CNTL
, besr
.merge_cntl
);
3414 static int radeon_get_gkey(vidix_grkey_t
*grkey
)
3416 memcpy(grkey
, &radeon_grkey
, sizeof(vidix_grkey_t
));
3420 static int radeon_set_gkey(const vidix_grkey_t
*grkey
)
3422 memcpy(&radeon_grkey
, grkey
, sizeof(vidix_grkey_t
));
3423 return (set_gr_key());
3427 VDXDriver rage128_drv
= {
3430 VDXDriver radeon_drv
= {
3435 .probe
= radeon_probe
,
3436 .get_caps
= radeon_get_caps
,
3437 .query_fourcc
= radeon_query_fourcc
,
3438 .init
= radeon_init
,
3439 .destroy
= radeon_destroy
,
3440 .config_playback
= radeon_config_playback
,
3441 .playback_on
= radeon_playback_on
,
3442 .playback_off
= radeon_playback_off
,
3443 .frame_sel
= radeon_frame_select
,
3444 .get_eq
= radeon_get_eq
,
3445 .set_eq
= radeon_set_eq
,
3446 .get_deint
= radeon_playback_get_deint
,
3447 .set_deint
= radeon_playback_set_deint
,
3448 .get_gkey
= radeon_get_gkey
,
3449 .set_gkey
= radeon_set_gkey
,