2 * VIDIX driver for ATI Rage128 and Radeon chipsets.
4 * This file is based on sources from
5 * GATOS (gatos.sf.net) and X11 (www.xfree86.org)
7 * Copyright (C) 2002 Nick Kurshev
8 * support for fglrx drivers by Marcel Naziri (zwobbl@zwobbl.de)
10 * This file is part of MPlayer.
12 * MPlayer is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * MPlayer is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License along
23 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
24 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
35 #include "libavutil/common.h"
38 #include "pci_names.h"
44 #if !defined(RAGE128) && defined(CONFIG_X11)
46 static uint32_t firegl_shift
= 0;
50 #define RADEON_MSG "[rage128]"
53 #define RADEON_MSG "[radeon]"
54 #define X_ADJUST (((besr.chip_flags&R_OVL_SHIFT)==R_OVL_SHIFT)?8:0)
60 #define RADEON_ASSERT(msg) printf(RADEON_MSG"################# FATAL:"msg);
62 #define VERBOSE_LEVEL 0
63 static int verbosity
= 0;
64 typedef struct bes_registers_s
66 /* base address of yuv framebuffer */
71 int horz_pick_nearest
;
72 int vert_pick_nearest
;
73 int swap_uv
; /* for direct support of bgr fourccs */
75 /* YUV BES registers */
76 uint32_t reg_load_cntl
;
82 uint32_t p1_blank_lines_at_top
;
83 uint32_t p23_blank_lines_at_top
;
84 uint32_t vid_buf_pitch0_value
;
85 uint32_t vid_buf_pitch1_value
;
86 uint32_t p1_x_start_end
;
87 uint32_t p2_x_start_end
;
88 uint32_t p3_x_start_end
;
90 uint32_t vid_buf_base_adrs_y
[VID_PLAY_MAXFRAMES
];
91 uint32_t vid_buf_base_adrs_u
[VID_PLAY_MAXFRAMES
];
92 uint32_t vid_buf_base_adrs_v
[VID_PLAY_MAXFRAMES
];
95 uint32_t p1_v_accum_init
;
96 uint32_t p1_h_accum_init
;
97 uint32_t p23_v_accum_init
;
98 uint32_t p23_h_accum_init
;
100 uint32_t exclusive_horz
;
101 uint32_t auto_flip_cntl
;
102 uint32_t filter_cntl
;
103 uint32_t four_tap_coeff
[5];
106 /* Configurable stuff */
113 uint32_t graphics_key_clr
;
114 uint32_t graphics_key_msk
;
119 uint32_t deinterlace_pattern
;
124 typedef struct video_registers_s
131 static bes_registers_t besr
;
132 #define DECLARE_VREG(name) { #name, name, 0 }
133 static const video_registers_t vregs
[] =
135 DECLARE_VREG(VIDEOMUX_CNTL
),
136 DECLARE_VREG(VIPPAD_MASK
),
137 DECLARE_VREG(VIPPAD1_A
),
138 DECLARE_VREG(VIPPAD1_EN
),
139 DECLARE_VREG(VIPPAD1_Y
),
140 DECLARE_VREG(OV0_Y_X_START
),
141 DECLARE_VREG(OV0_Y_X_END
),
142 DECLARE_VREG(OV1_Y_X_START
),
143 DECLARE_VREG(OV1_Y_X_END
),
144 DECLARE_VREG(OV0_PIPELINE_CNTL
),
145 DECLARE_VREG(OV0_EXCLUSIVE_HORZ
),
146 DECLARE_VREG(OV0_EXCLUSIVE_VERT
),
147 DECLARE_VREG(OV0_REG_LOAD_CNTL
),
148 DECLARE_VREG(OV0_SCALE_CNTL
),
149 DECLARE_VREG(OV0_V_INC
),
150 DECLARE_VREG(OV0_P1_V_ACCUM_INIT
),
151 DECLARE_VREG(OV0_P23_V_ACCUM_INIT
),
152 DECLARE_VREG(OV0_P1_BLANK_LINES_AT_TOP
),
153 DECLARE_VREG(OV0_P23_BLANK_LINES_AT_TOP
),
155 DECLARE_VREG(OV0_BASE_ADDR
),
157 DECLARE_VREG(OV0_VID_BUF0_BASE_ADRS
),
158 DECLARE_VREG(OV0_VID_BUF1_BASE_ADRS
),
159 DECLARE_VREG(OV0_VID_BUF2_BASE_ADRS
),
160 DECLARE_VREG(OV0_VID_BUF3_BASE_ADRS
),
161 DECLARE_VREG(OV0_VID_BUF4_BASE_ADRS
),
162 DECLARE_VREG(OV0_VID_BUF5_BASE_ADRS
),
163 DECLARE_VREG(OV0_VID_BUF_PITCH0_VALUE
),
164 DECLARE_VREG(OV0_VID_BUF_PITCH1_VALUE
),
165 DECLARE_VREG(OV0_AUTO_FLIP_CNTL
),
166 DECLARE_VREG(OV0_DEINTERLACE_PATTERN
),
167 DECLARE_VREG(OV0_SUBMIT_HISTORY
),
168 DECLARE_VREG(OV0_H_INC
),
169 DECLARE_VREG(OV0_STEP_BY
),
170 DECLARE_VREG(OV0_P1_H_ACCUM_INIT
),
171 DECLARE_VREG(OV0_P23_H_ACCUM_INIT
),
172 DECLARE_VREG(OV0_P1_X_START_END
),
173 DECLARE_VREG(OV0_P2_X_START_END
),
174 DECLARE_VREG(OV0_P3_X_START_END
),
175 DECLARE_VREG(OV0_FILTER_CNTL
),
176 DECLARE_VREG(OV0_FOUR_TAP_COEF_0
),
177 DECLARE_VREG(OV0_FOUR_TAP_COEF_1
),
178 DECLARE_VREG(OV0_FOUR_TAP_COEF_2
),
179 DECLARE_VREG(OV0_FOUR_TAP_COEF_3
),
180 DECLARE_VREG(OV0_FOUR_TAP_COEF_4
),
181 DECLARE_VREG(OV0_FLAG_CNTL
),
183 DECLARE_VREG(OV0_COLOUR_CNTL
),
185 DECLARE_VREG(OV0_SLICE_CNTL
),
187 DECLARE_VREG(OV0_VID_KEY_CLR
),
188 DECLARE_VREG(OV0_VID_KEY_MSK
),
189 DECLARE_VREG(OV0_GRAPHICS_KEY_CLR
),
190 DECLARE_VREG(OV0_GRAPHICS_KEY_MSK
),
191 DECLARE_VREG(OV0_KEY_CNTL
),
192 DECLARE_VREG(OV0_TEST
),
193 DECLARE_VREG(OV0_LIN_TRANS_A
),
194 DECLARE_VREG(OV0_LIN_TRANS_B
),
195 DECLARE_VREG(OV0_LIN_TRANS_C
),
196 DECLARE_VREG(OV0_LIN_TRANS_D
),
197 DECLARE_VREG(OV0_LIN_TRANS_E
),
198 DECLARE_VREG(OV0_LIN_TRANS_F
),
199 DECLARE_VREG(OV0_GAMMA_0_F
),
200 DECLARE_VREG(OV0_GAMMA_10_1F
),
201 DECLARE_VREG(OV0_GAMMA_20_3F
),
202 DECLARE_VREG(OV0_GAMMA_40_7F
),
203 DECLARE_VREG(OV0_GAMMA_380_3BF
),
204 DECLARE_VREG(OV0_GAMMA_3C0_3FF
),
205 DECLARE_VREG(SUBPIC_CNTL
),
206 DECLARE_VREG(SUBPIC_DEFCOLCON
),
207 DECLARE_VREG(SUBPIC_Y_X_START
),
208 DECLARE_VREG(SUBPIC_Y_X_END
),
209 DECLARE_VREG(SUBPIC_V_INC
),
210 DECLARE_VREG(SUBPIC_H_INC
),
211 DECLARE_VREG(SUBPIC_BUF0_OFFSET
),
212 DECLARE_VREG(SUBPIC_BUF1_OFFSET
),
213 DECLARE_VREG(SUBPIC_LC0_OFFSET
),
214 DECLARE_VREG(SUBPIC_LC1_OFFSET
),
215 DECLARE_VREG(SUBPIC_PITCH
),
216 DECLARE_VREG(SUBPIC_BTN_HLI_COLCON
),
217 DECLARE_VREG(SUBPIC_BTN_HLI_Y_X_START
),
218 DECLARE_VREG(SUBPIC_BTN_HLI_Y_X_END
),
219 DECLARE_VREG(SUBPIC_PALETTE_INDEX
),
220 DECLARE_VREG(SUBPIC_PALETTE_DATA
),
221 DECLARE_VREG(SUBPIC_H_ACCUM_INIT
),
222 DECLARE_VREG(SUBPIC_V_ACCUM_INIT
),
223 DECLARE_VREG(IDCT_RUNS
),
224 DECLARE_VREG(IDCT_LEVELS
),
225 DECLARE_VREG(IDCT_AUTH_CONTROL
),
226 DECLARE_VREG(IDCT_AUTH
),
227 DECLARE_VREG(IDCT_CONTROL
),
229 DECLARE_VREG(BM_FRAME_BUF_OFFSET
),
230 DECLARE_VREG(BM_SYSTEM_MEM_ADDR
),
231 DECLARE_VREG(BM_COMMAND
),
232 DECLARE_VREG(BM_STATUS
),
233 DECLARE_VREG(BM_QUEUE_STATUS
),
234 DECLARE_VREG(BM_QUEUE_FREE_STATUS
),
235 DECLARE_VREG(BM_CHUNK_0_VAL
),
236 DECLARE_VREG(BM_CHUNK_1_VAL
),
237 DECLARE_VREG(BM_VIP0_BUF
),
238 DECLARE_VREG(BM_VIP0_ACTIVE
),
239 DECLARE_VREG(BM_VIP1_BUF
),
240 DECLARE_VREG(BM_VIP1_ACTIVE
),
241 DECLARE_VREG(BM_VIP2_BUF
),
242 DECLARE_VREG(BM_VIP2_ACTIVE
),
243 DECLARE_VREG(BM_VIP3_BUF
),
244 DECLARE_VREG(BM_VIP3_ACTIVE
),
245 DECLARE_VREG(BM_VIDCAP_BUF0
),
246 DECLARE_VREG(BM_VIDCAP_BUF1
),
247 DECLARE_VREG(BM_VIDCAP_BUF2
),
248 DECLARE_VREG(BM_VIDCAP_ACTIVE
),
249 DECLARE_VREG(BM_GUI
),
250 DECLARE_VREG(BM_ABORT
)
252 DECLARE_VREG(DISP_MERGE_CNTL
),
253 DECLARE_VREG(DMA_GUI_TABLE_ADDR
),
254 DECLARE_VREG(DMA_GUI_SRC_ADDR
),
255 DECLARE_VREG(DMA_GUI_DST_ADDR
),
256 DECLARE_VREG(DMA_GUI_COMMAND
),
257 DECLARE_VREG(DMA_GUI_STATUS
),
258 DECLARE_VREG(DMA_GUI_ACT_DSCRPTR
),
259 DECLARE_VREG(DMA_VID_SRC_ADDR
),
260 DECLARE_VREG(DMA_VID_DST_ADDR
),
261 DECLARE_VREG(DMA_VID_COMMAND
),
262 DECLARE_VREG(DMA_VID_STATUS
),
263 DECLARE_VREG(DMA_VID_ACT_DSCRPTR
),
267 #define R_FAMILY 0x000000FF
268 #define R_100 0x00000001
269 #define R_120 0x00000002
270 #define R_150 0x00000004
271 #define R_200 0x00000008
272 #define R_250 0x00000010
273 #define R_280 0x00000020
274 #define R_300 0x00000040
275 #define R_350 0x00000080
276 #define R_370 0x00000100
277 #define R_380 0x00000200
278 #define R_420 0x00000400
279 #define R_430 0x00000800
280 #define R_480 0x00001000
281 #define R_OVL_SHIFT 0x01000000
282 #define R_INTEGRATED 0x02000000
283 #define R_PCIE 0x04000000
285 typedef struct ati_card_ids_s
291 static const ati_card_ids_t ati_card_ids
[] =
295 This driver should be compatible with Rage128 (pro) chips.
296 (include adaptive deinterlacing!!!).
297 Moreover: the same logic can be used with Mach64 chips.
298 (I mean: mach64xx, 3d rage, 3d rage IIc, 3D rage pro, 3d rage mobility).
299 but they are incompatible by i/o ports. So if enthusiasts will want
300 then they can redefine OUTREG and INREG macros and redefine OV0_*
301 constants. Also it seems that mach64 chips supports only: YUY2, YV12, UYVY
302 fourccs (422 and 420 formats only).
305 { DEVICE_ATI_RAGE_128_PA_PRO
, 0 },
306 { DEVICE_ATI_RAGE_128_PB_PRO
, 0 },
307 { DEVICE_ATI_RAGE_128_PC_PRO
, 0 },
308 { DEVICE_ATI_RAGE_128_PD_PRO
, 0 },
309 { DEVICE_ATI_RAGE_128_PE_PRO
, 0 },
310 { DEVICE_ATI_RAGE_128_PF_PRO
, 0 },
312 { DEVICE_ATI_RAGE_128_PG_PRO
, 0 },
313 { DEVICE_ATI_RAGE_128_PH_PRO
, 0 },
314 { DEVICE_ATI_RAGE_128_PI_PRO
, 0 },
315 { DEVICE_ATI_RAGE_128_PJ_PRO
, 0 },
316 { DEVICE_ATI_RAGE_128_PK_PRO
, 0 },
317 { DEVICE_ATI_RAGE_128_PL_PRO
, 0 },
318 { DEVICE_ATI_RAGE_128_PM_PRO
, 0 },
319 { DEVICE_ATI_RAGE_128_PN_PRO
, 0 },
320 { DEVICE_ATI_RAGE_128_PO_PRO
, 0 },
321 { DEVICE_ATI_RAGE_128_PP_PRO
, 0 },
322 { DEVICE_ATI_RAGE_128_PQ_PRO
, 0 },
323 { DEVICE_ATI_RAGE_128_PR_PRO
, 0 },
324 { DEVICE_ATI_RAGE_128_PS_PRO
, 0 },
325 { DEVICE_ATI_RAGE_128_PT_PRO
, 0 },
326 { DEVICE_ATI_RAGE_128_PU_PRO
, 0 },
327 { DEVICE_ATI_RAGE_128_PV_PRO
, 0 },
328 { DEVICE_ATI_RAGE_128_PW_PRO
, 0 },
329 { DEVICE_ATI_RAGE_128_PX_PRO
, 0 },
331 { DEVICE_ATI_RAGE_128_RE_SG
, 0 },
332 { DEVICE_ATI_RAGE_128_RF_SG
, 0 },
333 { DEVICE_ATI_RAGE_128_RG
, 0 },
334 { DEVICE_ATI_RAGE_128_RK_VR
, 0 },
335 { DEVICE_ATI_RAGE_128_RL_VR
, 0 },
336 { DEVICE_ATI_RAGE_128_SE_4X
, 0 },
337 { DEVICE_ATI_RAGE_128_SF_4X
, 0 },
338 { DEVICE_ATI_RAGE_128_SG_4X
, 0 },
339 { DEVICE_ATI_RAGE_128_SH
, 0 },
340 { DEVICE_ATI_RAGE_128_SK_4X
, 0 },
341 { DEVICE_ATI_RAGE_128_SL_4X
, 0 },
342 { DEVICE_ATI_RAGE_128_SM_4X
, 0 },
343 { DEVICE_ATI_RAGE_128_4X
, 0 },
344 { DEVICE_ATI_RAGE_128_PRO
, 0 },
345 { DEVICE_ATI_RAGE_128_PRO2
, 0 },
346 { DEVICE_ATI_RAGE_128_PRO3
, 0 },
347 /* these seem to be based on rage 128 instead of mach64 */
348 { DEVICE_ATI_RAGE_MOBILITY_M3
, 0 },
349 { DEVICE_ATI_RAGE_MOBILITY_M32
, 0 },
351 /* Radeon1 (indeed: Rage 256 Pro ;) */
352 { DEVICE_ATI_RADEON_R100_QD
, R_100
|R_OVL_SHIFT
},
353 { DEVICE_ATI_RADEON_R100_QE
, R_100
|R_OVL_SHIFT
},
354 { DEVICE_ATI_RADEON_R100_QF
, R_100
|R_OVL_SHIFT
},
355 { DEVICE_ATI_RADEON_R100_QG
, R_100
|R_OVL_SHIFT
},
356 { DEVICE_ATI_RADEON_IGP_320
, R_150
|R_OVL_SHIFT
|R_INTEGRATED
},
357 { DEVICE_ATI_RADEON_MOBILITY_U1
, R_150
|R_OVL_SHIFT
|R_INTEGRATED
},
358 { DEVICE_ATI_RADEON_RV100_QY
, R_120
|R_OVL_SHIFT
},
359 { DEVICE_ATI_RADEON_RV100_QZ
, R_120
|R_OVL_SHIFT
},
360 { DEVICE_ATI_RADEON_MOBILITY_M7
, R_150
|R_OVL_SHIFT
},
361 { DEVICE_ATI_RADEON_RV200_LX
, R_150
|R_OVL_SHIFT
},
362 { DEVICE_ATI_RADEON_MOBILITY_M6
, R_120
|R_OVL_SHIFT
},
363 { DEVICE_ATI_RADEON_MOBILITY_M62
, R_120
|R_OVL_SHIFT
},
364 /* Radeon2 (indeed: Rage 512 Pro ;) */
365 { DEVICE_ATI_R200_BB_RADEON
, R_200
},
366 { DEVICE_ATI_R200_BC_RADEON
, R_200
},
367 { DEVICE_ATI_RADEON_R200_QH
, R_200
},
368 { DEVICE_ATI_RADEON_R200_QI
, R_200
},
369 { DEVICE_ATI_RADEON_R200_QJ
, R_200
},
370 { DEVICE_ATI_RADEON_R200_QK
, R_200
},
371 { DEVICE_ATI_RADEON_R200_QL
, R_200
},
372 { DEVICE_ATI_RADEON_R200_QM
, R_200
},
373 { DEVICE_ATI_RADEON_R200_QN
, R_200
},
374 { DEVICE_ATI_RADEON_R200_QO
, R_200
},
375 { DEVICE_ATI_RADEON_R200_QH2
, R_200
},
376 { DEVICE_ATI_RADEON_R200_QI2
, R_200
},
377 { DEVICE_ATI_RADEON_R200_QJ2
, R_200
},
378 { DEVICE_ATI_RADEON_R200_QK2
, R_200
},
379 { DEVICE_ATI_RADEON_R200_QL2
, R_200
},
380 { DEVICE_ATI_RADEON_RV200_QW
, R_150
|R_OVL_SHIFT
},
381 { DEVICE_ATI_RADEON_RV200_QX
, R_150
|R_OVL_SHIFT
},
382 { DEVICE_ATI_RADEON_IGP330_340_350
,R_200
|R_INTEGRATED
},
383 { DEVICE_ATI_RADEON_IGP_330M_340M_350M
,R_200
|R_INTEGRATED
},
384 { DEVICE_ATI_RADEON_RV250_IG
, R_250
|R_OVL_SHIFT
},
385 { DEVICE_ATI_RADEON_7000_IGP
, R_250
|R_OVL_SHIFT
|R_INTEGRATED
},
386 { DEVICE_ATI_RADEON_MOBILITY_7000
, R_250
|R_OVL_SHIFT
|R_INTEGRATED
},
387 { DEVICE_ATI_RADEON_RV250_ID
, R_250
|R_OVL_SHIFT
},
388 { DEVICE_ATI_RADEON_RV250_IE
, R_250
|R_OVL_SHIFT
},
389 { DEVICE_ATI_RADEON_RV250_IF
, R_250
|R_OVL_SHIFT
},
390 { DEVICE_ATI_RADEON_RV250_IG
, R_250
|R_OVL_SHIFT
},
391 { DEVICE_ATI_RADEON_R250_LD
, R_250
|R_OVL_SHIFT
},
392 { DEVICE_ATI_RADEON_R250_LE
, R_250
|R_OVL_SHIFT
},
393 { DEVICE_ATI_RADEON_R250_MOBILITY
, R_250
|R_OVL_SHIFT
},
394 { DEVICE_ATI_RADEON_R250_LG
, R_250
|R_OVL_SHIFT
},
395 { DEVICE_ATI_RV250_RADEON_9000
, R_250
|R_OVL_SHIFT
},
396 { DEVICE_ATI_RADEON_RV250_RADEON2
, R_250
|R_OVL_SHIFT
},
397 // Only 92006 and 92007 tested to actually require this
398 { DEVICE_ATI_RV280_RADEON_9200
, R_280
|R_OVL_SHIFT
},
399 { DEVICE_ATI_RV280_RADEON_92002
, R_280
|R_OVL_SHIFT
},
400 { DEVICE_ATI_RV280_RADEON_92003
, R_280
|R_OVL_SHIFT
},
401 { DEVICE_ATI_RV280_RADEON_92004
, R_280
|R_OVL_SHIFT
},
402 { DEVICE_ATI_RV280_RADEON_92005
, R_280
|R_OVL_SHIFT
},
403 { DEVICE_ATI_RV280_RADEON_92006
, R_280
|R_OVL_SHIFT
},
404 { DEVICE_ATI_RV280_RADEON_92007
, R_280
|R_OVL_SHIFT
},
405 { DEVICE_ATI_M9_5C61_RADEON
, R_280
|R_OVL_SHIFT
},
406 { DEVICE_ATI_M9_5C63_RADEON
, R_280
|R_OVL_SHIFT
},
407 /* Radeon3 (indeed: Rage 1024 Pro ;) */
408 { DEVICE_ATI_R300_AG_FIREGL
, R_300
},
409 { DEVICE_ATI_RADEON_R300_ND
, R_300
},
410 { DEVICE_ATI_RADEON_R300_NE
, R_300
},
411 { DEVICE_ATI_RADEON_R300_NG
, R_300
},
412 { DEVICE_ATI_R300_AD_RADEON
, R_300
},
413 { DEVICE_ATI_R300_AE_RADEON
, R_300
},
414 { DEVICE_ATI_R300_AF_RADEON
, R_300
},
415 { DEVICE_ATI_RADEON_9100_IGP2
, R_300
|R_OVL_SHIFT
|R_INTEGRATED
},
416 { DEVICE_ATI_RS300M_AGP_RADEON
, R_300
|R_INTEGRATED
},
417 { DEVICE_ATI_RS482_RADEON_XPRESS
, R_350
|R_INTEGRATED
},
418 { DEVICE_ATI_R350_AH_RADEON
, R_350
},
419 { DEVICE_ATI_R350_AI_RADEON
, R_350
},
420 { DEVICE_ATI_R350_AJ_RADEON
, R_350
},
421 { DEVICE_ATI_R350_AK_FIRE
, R_350
},
422 { DEVICE_ATI_RADEON_R350_RADEON2
, R_350
},
423 { DEVICE_ATI_RADEON_R350_RADEON3
, R_350
},
424 { DEVICE_ATI_RV350_NJ_RADEON
, R_350
},
425 { DEVICE_ATI_R350_NK_FIRE
, R_350
},
426 { DEVICE_ATI_RV350_AP_RADEON
, R_350
},
427 { DEVICE_ATI_RV350_AQ_RADEON
, R_350
},
428 { DEVICE_ATI_RV350_AR_RADEON
, R_350
},
429 { DEVICE_ATI_RV350_AS_RADEON
, R_350
},
430 { DEVICE_ATI_RV350_AT_FIRE
, R_350
},
431 { DEVICE_ATI_RV350_AU_FIRE
, R_350
},
432 { DEVICE_ATI_RV350_AV_FIRE
, R_350
},
433 { DEVICE_ATI_RV350_AW_FIRE
, R_350
},
434 { DEVICE_ATI_RV350_MOBILITY_RADEON
, R_350
},
435 { DEVICE_ATI_RV350_NF_RADEON
, R_300
},
436 { DEVICE_ATI_RV350_NJ_RADEON
, R_300
},
437 { DEVICE_ATI_RV350_AS_RADEON2
, R_350
},
438 { DEVICE_ATI_M10_NQ_RADEON
, R_350
},
439 { DEVICE_ATI_M10_NQ_RADEON2
, R_350
},
440 { DEVICE_ATI_RV350_MOBILITY_RADEON2
, R_350
},
441 { DEVICE_ATI_M10_NS_RADEON
, R_350
},
442 { DEVICE_ATI_M10_NT_FIREGL
, R_350
},
443 { DEVICE_ATI_M11_NV_FIREGL
, R_350
},
444 { DEVICE_ATI_RV370_5B60_RADEON
, R_370
|R_PCIE
},
445 { DEVICE_ATI_RV370_SAPPHIRE_X550
, R_370
},
446 { DEVICE_ATI_RV370_5B64_FIREGL
, R_370
|R_PCIE
},
447 { DEVICE_ATI_RV370_5B65_FIREGL
, R_370
|R_PCIE
},
448 { DEVICE_ATI_M24_1P_RADEON
, R_370
},
449 { DEVICE_ATI_M22_RADEON_MOBILITY
, R_370
},
450 { DEVICE_ATI_M24_1T_FIREGL
, R_370
},
451 { DEVICE_ATI_M24_RADEON_MOBILITY
, R_370
},
452 { DEVICE_ATI_RV370_RADEON_X300SE
, R_370
},
453 { DEVICE_ATI_RV370_SECONDARY_SAPPHIRE
, R_370
},
454 { DEVICE_ATI_RV370_5B64_FIREGL2
, R_370
},
455 { DEVICE_ATI_RV380_0X3E50_RADEON
, R_380
|R_PCIE
},
456 { DEVICE_ATI_RV380_0X3E54_FIREGL
, R_380
|R_PCIE
},
457 { DEVICE_ATI_RV380_RADEON_X600
, R_380
|R_PCIE
},
458 { DEVICE_ATI_RV380_RADEON_X6002
, R_380
},
459 { DEVICE_ATI_RV380_RADEON_X6003
, R_380
},
460 { DEVICE_ATI_RV410_FIREGL_V5000
, R_420
},
461 { DEVICE_ATI_RV410_FIREGL_V3300
, R_420
},
462 { DEVICE_ATI_RV410_RADEON_X700XT
, R_420
},
463 { DEVICE_ATI_RV410_RADEON_X700
, R_420
|R_PCIE
},
464 { DEVICE_ATI_RV410_RADEON_X700SE
, R_420
},
465 { DEVICE_ATI_RV410_RADEON_X7002
, R_420
|R_PCIE
},
466 { DEVICE_ATI_RV410_RADEON_X7003
, R_420
},
467 { DEVICE_ATI_RV410_RADEON_X7004
, R_420
|R_PCIE
},
468 { DEVICE_ATI_RV410_RADEON_X7005
, R_420
|R_PCIE
},
469 { DEVICE_ATI_M26_MOBILITY_FIREGL
, R_420
},
470 { DEVICE_ATI_M26_MOBILITY_FIREGL2
, R_420
},
471 { DEVICE_ATI_M26_RADEON_MOBILITY
, R_420
},
472 { DEVICE_ATI_M26_RADEON_MOBILITY2
, R_420
},
473 { DEVICE_ATI_RADEON_MOBILITY_X700
, R_420
},
474 { DEVICE_ATI_R420_JH_RADEON
, R_420
|R_PCIE
},
475 { DEVICE_ATI_R420_JI_RADEON
, R_420
|R_PCIE
},
476 { DEVICE_ATI_R420_JJ_RADEON
, R_420
|R_PCIE
},
477 { DEVICE_ATI_R420_JK_RADEON
, R_420
|R_PCIE
},
478 { DEVICE_ATI_R420_JL_RADEON
, R_420
|R_PCIE
},
479 { DEVICE_ATI_R420_JM_FIREGL
, R_420
|R_PCIE
},
480 { DEVICE_ATI_M18_JN_RADEON
, R_420
|R_PCIE
},
481 { DEVICE_ATI_R420_JP_RADEON
, R_420
|R_PCIE
},
482 { DEVICE_ATI_R420_RADEON_X800
, R_420
|R_PCIE
},
483 { DEVICE_ATI_R420_RADEON_X8002
, R_420
|R_PCIE
},
484 { DEVICE_ATI_R420_RADEON_X8003
, R_420
|R_PCIE
},
485 { DEVICE_ATI_R420_RADEON_X8004
, R_420
|R_PCIE
},
486 { DEVICE_ATI_R420_RADEON_X8005
, R_420
|R_PCIE
},
487 { DEVICE_ATI_R420_JM_FIREGL
, R_420
|R_PCIE
},
488 { DEVICE_ATI_R423_5F57_RADEON
, R_420
|R_PCIE
},
489 { DEVICE_ATI_R423_5F57_RADEON2
, R_420
|R_PCIE
},
490 { DEVICE_ATI_R423_UH_RADEON
, R_420
|R_PCIE
},
491 { DEVICE_ATI_R423_UI_RADEON
, R_420
|R_PCIE
},
492 { DEVICE_ATI_R423_UJ_RADEON
, R_420
|R_PCIE
},
493 { DEVICE_ATI_R423_UK_RADEON
, R_420
|R_PCIE
},
494 { DEVICE_ATI_R423_FIRE_GL
, R_420
|R_PCIE
},
495 { DEVICE_ATI_R423_UQ_FIREGL
, R_420
|R_PCIE
},
496 { DEVICE_ATI_R423_UR_FIREGL
, R_420
|R_PCIE
},
497 { DEVICE_ATI_R423_UT_FIREGL
, R_420
|R_PCIE
},
498 { DEVICE_ATI_R423_UI_RADEON2
, R_420
|R_PCIE
},
499 { DEVICE_ATI_R423GL_SE_ATI_FIREGL
, R_420
|R_PCIE
},
500 { DEVICE_ATI_R423_RADEON_X800XT
, R_420
|R_PCIE
},
501 { DEVICE_ATI_RADEON_R423_UK
, R_420
|R_PCIE
},
502 { DEVICE_ATI_M28_RADEON_MOBILITY
, R_420
},
503 { DEVICE_ATI_M28_MOBILITY_FIREGL
, R_420
},
504 { DEVICE_ATI_MOBILITY_RADEON_X800
, R_420
},
505 { DEVICE_ATI_R430_RADEON_X800
, R_430
|R_PCIE
},
506 { DEVICE_ATI_R430_RADEON_X8002
, R_430
|R_PCIE
},
507 { DEVICE_ATI_R430_RADEON_X8003
, R_430
|R_PCIE
},
508 { DEVICE_ATI_R430_RADEON_X8004
, R_430
|R_PCIE
},
509 { DEVICE_ATI_R480_RADEON_X800
, R_480
},
510 { DEVICE_ATI_R480_RADEON_X8002
, R_480
},
511 { DEVICE_ATI_R480_RADEON_X850XT
, R_480
},
512 { DEVICE_ATI_R480_RADEON_X850PRO
, R_480
},
513 { DEVICE_ATI_R481_RADEON_X850XT_PE
, R_480
|R_PCIE
},
514 { DEVICE_ATI_R480_RADEON_X850XT2
, R_480
},
515 { DEVICE_ATI_R480_RADEON_X850PRO2
, R_480
},
516 { DEVICE_ATI_R481_RADEON_X850XT_PE2
, R_480
|R_PCIE
},
517 { DEVICE_ATI_R480_RADEON_X850XT3
, R_480
|R_PCIE
},
518 { DEVICE_ATI_R480_RADEON_X850XT4
, R_480
|R_PCIE
},
519 { DEVICE_ATI_R480_RADEON_X850XT5
, R_480
|R_PCIE
},
520 { DEVICE_ATI_R480_RADEON_X850XT6
, R_480
|R_PCIE
},
525 static void * radeon_mmio_base
= 0;
526 static void * radeon_mem_base
= 0;
527 static int32_t radeon_overlay_off
= 0;
528 static uint32_t radeon_ram_size
= 0;
530 #define GETREG(TYPE,PTR,OFFZ) (*((volatile TYPE*)((PTR)+(OFFZ))))
531 #define SETREG(TYPE,PTR,OFFZ,VAL) (*((volatile TYPE*)((PTR)+(OFFZ))))=VAL
533 #define INREG8(addr) GETREG(uint8_t,(uint8_t *)(radeon_mmio_base),addr)
534 #define OUTREG8(addr,val) SETREG(uint8_t,(uint8_t *)(radeon_mmio_base),addr,val)
535 static inline uint32_t INREG (uint32_t addr
) {
536 uint32_t tmp
= GETREG(uint32_t,(uint8_t *)(radeon_mmio_base
),addr
);
537 return le2me_32(tmp
);
539 #define OUTREG(addr,val) SETREG(uint32_t,(uint8_t *)(radeon_mmio_base),addr,le2me_32(val))
540 #define OUTREGP(addr,val,mask) \
542 unsigned int _tmp = INREG(addr); \
545 OUTREG(addr, _tmp); \
548 static __inline__
uint32_t INPLL(uint32_t addr
)
550 OUTREG8(CLOCK_CNTL_INDEX
, addr
& 0x0000001f);
551 return INREG(CLOCK_CNTL_DATA
);
554 #define OUTPLL(addr,val) OUTREG8(CLOCK_CNTL_INDEX, (addr & 0x0000001f) | 0x00000080); \
555 OUTREG(CLOCK_CNTL_DATA, val)
556 #define OUTPLLP(addr,val,mask) \
558 unsigned int _tmp = INPLL(addr); \
561 OUTPLL(addr, _tmp); \
568 MT_CRT
, /* CRT-(cathode ray tube) analog monitor. (15-pin VGA connector) */
569 MT_LCD
, /* Liquid Crystal Display */
570 MT_DFP
, /* DFP-digital flat panel monitor. (24-pin DVI-I connector) */
571 MT_CTV
, /* Composite TV out (not in VE) */
572 MT_STV
/* S-Video TV out (probably in VE only) */
575 typedef struct radeon_info_s
582 static rinfo_t rinfo
;
584 static char * GET_MON_NAME(int type
)
589 case MT_NONE
: pret
= "no"; break;
590 case MT_CRT
: pret
= "CRT"; break;
591 case MT_DFP
: pret
= "DFP"; break;
592 case MT_LCD
: pret
= "LCD"; break;
593 case MT_CTV
: pret
= "CTV"; break;
594 case MT_STV
: pret
= "STV"; break;
595 default: pret
= "Unknown";
600 static void radeon_get_moninfo (rinfo_t
*rinfo
)
604 tmp
= INREG(RADEON_BIOS_4_SCRATCH
);
606 if (rinfo
->hasCRTC2
) {
607 /* primary DVI port */
609 rinfo
->dviDispType
= MT_DFP
;
611 rinfo
->dviDispType
= MT_LCD
;
612 else if (tmp
& 0x200)
613 rinfo
->dviDispType
= MT_CRT
;
615 rinfo
->dviDispType
= MT_CTV
;
617 rinfo
->dviDispType
= MT_STV
;
619 /* secondary CRT port */
621 rinfo
->crtDispType
= MT_CRT
;
622 else if (tmp
& 0x800)
623 rinfo
->crtDispType
= MT_DFP
;
624 else if (tmp
& 0x400)
625 rinfo
->crtDispType
= MT_LCD
;
626 else if (tmp
& 0x1000)
627 rinfo
->crtDispType
= MT_CTV
;
628 else if (tmp
& 0x2000)
629 rinfo
->crtDispType
= MT_STV
;
631 rinfo
->dviDispType
= MT_NONE
;
633 tmp
= INREG(FP_GEN_CNTL
);
635 if (tmp
& FP_EN_TMDS
)
636 rinfo
->crtDispType
= MT_DFP
;
638 rinfo
->crtDispType
= MT_CRT
;
643 static uint32_t radeon_vid_get_dbpp( void )
645 uint32_t dbpp
,retval
;
646 dbpp
= (INREG(CRTC_GEN_CNTL
)>>8)& 0xF;
649 case DST_8BPP
: retval
= 8; break;
650 case DST_15BPP
: retval
= 15; break;
651 case DST_16BPP
: retval
= 16; break;
652 case DST_24BPP
: retval
= 24; break;
653 default: retval
=32; break;
658 static int radeon_is_dbl_scan( void )
660 return (INREG(CRTC_GEN_CNTL
))&CRTC_DBL_SCAN_EN
;
663 static int radeon_is_interlace( void )
665 return (INREG(CRTC_GEN_CNTL
))&CRTC_INTERLACE_EN
;
668 static uint32_t radeon_get_xres( void )
670 uint32_t xres
,h_total
;
673 (rinfo
.dviDispType
== MT_CTV
|| rinfo
.dviDispType
== MT_STV
))
674 h_total
= INREG(CRTC2_H_TOTAL_DISP
);
677 h_total
= INREG(CRTC_H_TOTAL_DISP
);
678 xres
= (h_total
>> 16) & 0xffff;
682 static uint32_t radeon_get_yres( void )
684 uint32_t yres
,v_total
;
687 (rinfo
.dviDispType
== MT_CTV
|| rinfo
.dviDispType
== MT_STV
))
688 v_total
= INREG(CRTC2_V_TOTAL_DISP
);
691 v_total
= INREG(CRTC_V_TOTAL_DISP
);
692 yres
= (v_total
>> 16) & 0xffff;
696 static void radeon_wait_vsync(void)
700 OUTREG(GEN_INT_STATUS
, VSYNC_INT_AK
);
701 for (i
= 0; i
< 2000000; i
++)
703 if (INREG(GEN_INT_STATUS
) & VSYNC_INT
) break;
708 static void _radeon_engine_idle(void);
709 static void _radeon_fifo_wait(unsigned);
710 #define radeon_engine_idle() _radeon_engine_idle()
711 #define radeon_fifo_wait(entries) _radeon_fifo_wait(entries)
712 /* Flush all dirty data in the Pixel Cache to memory. */
713 static __inline__
void radeon_engine_flush ( void )
717 OUTREGP(PC_NGUI_CTLSTAT
, PC_FLUSH_ALL
, ~PC_FLUSH_ALL
);
718 for (i
= 0; i
< 2000000; i
++) {
719 if (!(INREG(PC_NGUI_CTLSTAT
) & PC_BUSY
)) break;
723 /* Reset graphics card to known state. */
724 static void radeon_engine_reset( void )
726 uint32_t clock_cntl_index
;
728 uint32_t gen_reset_cntl
;
730 radeon_engine_flush();
732 clock_cntl_index
= INREG(CLOCK_CNTL_INDEX
);
733 mclk_cntl
= INPLL(MCLK_CNTL
);
735 OUTPLL(MCLK_CNTL
, mclk_cntl
| FORCE_GCP
| FORCE_PIPE3D_CP
);
737 gen_reset_cntl
= INREG(GEN_RESET_CNTL
);
739 OUTREG(GEN_RESET_CNTL
, gen_reset_cntl
| SOFT_RESET_GUI
);
740 INREG(GEN_RESET_CNTL
);
741 OUTREG(GEN_RESET_CNTL
,
742 gen_reset_cntl
& (uint32_t)(~SOFT_RESET_GUI
));
743 INREG(GEN_RESET_CNTL
);
745 OUTPLL(MCLK_CNTL
, mclk_cntl
);
746 OUTREG(CLOCK_CNTL_INDEX
, clock_cntl_index
);
747 OUTREG(GEN_RESET_CNTL
, gen_reset_cntl
);
751 static __inline__
void radeon_engine_flush ( void )
756 OUTREGP(RB2D_DSTCACHE_CTLSTAT
, RB2D_DC_FLUSH_ALL
,
759 for (i
=0; i
< 2000000; i
++) {
760 if (!(INREG(RB2D_DSTCACHE_CTLSTAT
) & RB2D_DC_BUSY
))
765 static void _radeon_engine_idle(void);
766 static void _radeon_fifo_wait(unsigned);
767 #define radeon_engine_idle() _radeon_engine_idle()
768 #define radeon_fifo_wait(entries) _radeon_fifo_wait(entries)
770 static void radeon_engine_reset( void )
772 uint32_t clock_cntl_index
, mclk_cntl
, rbbm_soft_reset
;
774 radeon_engine_flush ();
776 clock_cntl_index
= INREG(CLOCK_CNTL_INDEX
);
777 mclk_cntl
= INPLL(MCLK_CNTL
);
779 OUTPLL(MCLK_CNTL
, (mclk_cntl
|
786 rbbm_soft_reset
= INREG(RBBM_SOFT_RESET
);
788 OUTREG(RBBM_SOFT_RESET
, rbbm_soft_reset
|
797 INREG(RBBM_SOFT_RESET
);
798 OUTREG(RBBM_SOFT_RESET
, rbbm_soft_reset
& (uint32_t)
807 INREG(RBBM_SOFT_RESET
);
809 OUTPLL(MCLK_CNTL
, mclk_cntl
);
810 OUTREG(CLOCK_CNTL_INDEX
, clock_cntl_index
);
811 OUTREG(RBBM_SOFT_RESET
, rbbm_soft_reset
);
816 static void radeon_engine_restore( void )
820 uint32_t xres
,yres
,bpp
;
822 xres
= radeon_get_xres();
823 yres
= radeon_get_yres();
824 bpp
= radeon_vid_get_dbpp();
825 /* turn of all automatic flushing - we'll do it all */
826 OUTREG(RB2D_DSTCACHE_MODE
, 0);
828 pitch64
= ((xres
* (bpp
/ 8) + 0x3f)) >> 6;
831 OUTREG(DEFAULT_OFFSET
, (INREG(DEFAULT_OFFSET
) & 0xC0000000) |
837 HOST_BIG_ENDIAN_EN
, ~HOST_BIG_ENDIAN_EN
);
839 OUTREGP(DP_DATATYPE
, 0, ~HOST_BIG_ENDIAN_EN
);
843 OUTREG(DEFAULT_SC_BOTTOM_RIGHT
, (DEFAULT_SC_RIGHT_MAX
844 | DEFAULT_SC_BOTTOM_MAX
));
846 OUTREG(DP_GUI_MASTER_CNTL
, (INREG(DP_GUI_MASTER_CNTL
)
847 | GMC_BRUSH_SOLID_COLOR
848 | GMC_SRC_DATATYPE_COLOR
));
851 OUTREG(DST_LINE_START
, 0);
852 OUTREG(DST_LINE_END
, 0);
853 OUTREG(DP_BRUSH_FRGD_CLR
, 0xffffffff);
854 OUTREG(DP_BRUSH_BKGD_CLR
, 0x00000000);
855 OUTREG(DP_SRC_FRGD_CLR
, 0xffffffff);
856 OUTREG(DP_SRC_BKGD_CLR
, 0x00000000);
857 OUTREG(DP_WRITE_MASK
, 0xffffffff);
859 radeon_engine_idle();
863 static void _radeon_fifo_wait (unsigned entries
)
869 for (i
=0; i
<2000000; i
++)
870 if ((INREG(GUI_STAT
) & GUI_FIFOCNT_MASK
) >= entries
)
872 radeon_engine_reset();
873 radeon_engine_restore();
877 static void _radeon_engine_idle ( void )
881 /* ensure FIFO is empty before waiting for idle */
882 radeon_fifo_wait (64);
885 for (i
=0; i
<2000000; i
++) {
886 if ((INREG(GUI_STAT
) & GUI_ACTIVE
) == 0) {
887 radeon_engine_flush ();
891 radeon_engine_reset();
892 radeon_engine_restore();
896 static void _radeon_fifo_wait (unsigned entries
)
902 for (i
=0; i
<2000000; i
++)
903 if ((INREG(RBBM_STATUS
) & RBBM_FIFOCNT_MASK
) >= entries
)
905 radeon_engine_reset();
906 radeon_engine_restore();
909 static void _radeon_engine_idle ( void )
913 /* ensure FIFO is empty before waiting for idle */
914 radeon_fifo_wait (64);
917 for (i
=0; i
<2000000; i
++) {
918 if (((INREG(RBBM_STATUS
) & RBBM_ACTIVE
)) == 0) {
919 radeon_engine_flush ();
923 radeon_engine_reset();
924 radeon_engine_restore();
930 /* Reference color space transform data */
931 typedef struct tagREF_TRANSFORM
942 /* Parameters for ITU-R BT.601 and ITU-R BT.709 colour spaces */
943 static const REF_TRANSFORM trans
[2] =
945 {1.1678, 0.0, 1.6007, -0.3929, -0.8154, 2.0232, 0.0}, /* BT.601 */
946 {1.1678, 0.0, 1.7980, -0.2139, -0.5345, 2.1186, 0.0} /* BT.709 */
948 /****************************************************************************
950 * Function: Calculates and sets color space transform from supplied *
951 * reference transform, gamma, brightness, contrast, hue and *
953 * Inputs: bright - brightness *
957 * red_intensity - intense of red component *
958 * green_intensity - intense of green component *
959 * blue_intensity - intense of blue component *
960 * ref - index to the table of refernce transforms *
962 ****************************************************************************/
964 static void radeon_set_transform(float bright
, float cont
, float sat
,
965 float hue
, float red_intensity
,
966 float green_intensity
,float blue_intensity
,
969 float OvHueSin
, OvHueCos
;
970 float CAdjLuma
, CAdjOff
;
971 float RedAdj
,GreenAdj
,BlueAdj
;
972 float CAdjRCb
, CAdjRCr
;
973 float CAdjGCb
, CAdjGCr
;
974 float CAdjBCb
, CAdjBCr
;
975 float OvLuma
, OvROff
, OvGOff
, OvBOff
;
982 uint32_t dwOvLuma
, dwOvROff
, dwOvGOff
, dwOvBOff
;
983 uint32_t dwOvRCb
, dwOvRCr
;
984 uint32_t dwOvGCb
, dwOvGCr
;
985 uint32_t dwOvBCb
, dwOvBCr
;
987 if (ref
>= 2) return;
989 OvHueSin
= sin((double)hue
);
990 OvHueCos
= cos((double)hue
);
992 CAdjLuma
= cont
* trans
[ref
].RefLuma
;
993 CAdjOff
= cont
* trans
[ref
].RefLuma
* bright
* 1023.0;
994 RedAdj
= cont
* trans
[ref
].RefLuma
* red_intensity
* 1023.0;
995 GreenAdj
= cont
* trans
[ref
].RefLuma
* green_intensity
* 1023.0;
996 BlueAdj
= cont
* trans
[ref
].RefLuma
* blue_intensity
* 1023.0;
998 CAdjRCb
= sat
* -OvHueSin
* trans
[ref
].RefRCr
;
999 CAdjRCr
= sat
* OvHueCos
* trans
[ref
].RefRCr
;
1000 CAdjGCb
= sat
* (OvHueCos
* trans
[ref
].RefGCb
- OvHueSin
* trans
[ref
].RefGCr
);
1001 CAdjGCr
= sat
* (OvHueSin
* trans
[ref
].RefGCb
+ OvHueCos
* trans
[ref
].RefGCr
);
1002 CAdjBCb
= sat
* OvHueCos
* trans
[ref
].RefBCb
;
1003 CAdjBCr
= sat
* OvHueSin
* trans
[ref
].RefBCb
;
1012 OvROff
= RedAdj
+ CAdjOff
-
1013 OvLuma
* Loff
- (OvRCb
+ OvRCr
) * Coff
;
1014 OvGOff
= GreenAdj
+ CAdjOff
-
1015 OvLuma
* Loff
- (OvGCb
+ OvGCr
) * Coff
;
1016 OvBOff
= BlueAdj
+ CAdjOff
-
1017 OvLuma
* Loff
- (OvBCb
+ OvBCr
) * Coff
;
1019 dwOvROff
= ((int)(OvROff
* 2.0)) & 0x1fff;
1020 dwOvGOff
= (int)(OvGOff
* 2.0) & 0x1fff;
1021 dwOvBOff
= (int)(OvBOff
* 2.0) & 0x1fff;
1022 /* Whatever docs say about R200 having 3.8 format instead of 3.11
1023 as in Radeon is a lie */
1025 dwOvLuma
=(((int)(OvLuma
* 2048.0))&0x7fff)<<17;
1026 dwOvRCb
= (((int)(OvRCb
* 2048.0))&0x7fff)<<1;
1027 dwOvRCr
= (((int)(OvRCr
* 2048.0))&0x7fff)<<17;
1028 dwOvGCb
= (((int)(OvGCb
* 2048.0))&0x7fff)<<1;
1029 dwOvGCr
= (((int)(OvGCr
* 2048.0))&0x7fff)<<17;
1030 dwOvBCb
= (((int)(OvBCb
* 2048.0))&0x7fff)<<1;
1031 dwOvBCr
= (((int)(OvBCr
* 2048.0))&0x7fff)<<17;
1033 OUTREG(OV0_LIN_TRANS_A
, dwOvRCb
| dwOvLuma
);
1034 OUTREG(OV0_LIN_TRANS_B
, dwOvROff
| dwOvRCr
);
1035 OUTREG(OV0_LIN_TRANS_C
, dwOvGCb
| dwOvLuma
);
1036 OUTREG(OV0_LIN_TRANS_D
, dwOvGOff
| dwOvGCr
);
1037 OUTREG(OV0_LIN_TRANS_E
, dwOvBCb
| dwOvLuma
);
1038 OUTREG(OV0_LIN_TRANS_F
, dwOvBOff
| dwOvBCr
);
1041 /* Gamma curve definition */
1044 unsigned int gammaReg
;
1045 unsigned int gammaSlope
;
1046 unsigned int gammaOffset
;
1049 /* Recommended gamma curve parameters */
1050 static const GAMMA_SETTINGS r200_def_gamma
[18] =
1052 {OV0_GAMMA_0_F
, 0x100, 0x0000},
1053 {OV0_GAMMA_10_1F
, 0x100, 0x0020},
1054 {OV0_GAMMA_20_3F
, 0x100, 0x0040},
1055 {OV0_GAMMA_40_7F
, 0x100, 0x0080},
1056 {OV0_GAMMA_80_BF
, 0x100, 0x0100},
1057 {OV0_GAMMA_C0_FF
, 0x100, 0x0100},
1058 {OV0_GAMMA_100_13F
, 0x100, 0x0200},
1059 {OV0_GAMMA_140_17F
, 0x100, 0x0200},
1060 {OV0_GAMMA_180_1BF
, 0x100, 0x0300},
1061 {OV0_GAMMA_1C0_1FF
, 0x100, 0x0300},
1062 {OV0_GAMMA_200_23F
, 0x100, 0x0400},
1063 {OV0_GAMMA_240_27F
, 0x100, 0x0400},
1064 {OV0_GAMMA_280_2BF
, 0x100, 0x0500},
1065 {OV0_GAMMA_2C0_2FF
, 0x100, 0x0500},
1066 {OV0_GAMMA_300_33F
, 0x100, 0x0600},
1067 {OV0_GAMMA_340_37F
, 0x100, 0x0600},
1068 {OV0_GAMMA_380_3BF
, 0x100, 0x0700},
1069 {OV0_GAMMA_3C0_3FF
, 0x100, 0x0700}
1072 static const GAMMA_SETTINGS r100_def_gamma
[6] =
1074 {OV0_GAMMA_0_F
, 0x100, 0x0000},
1075 {OV0_GAMMA_10_1F
, 0x100, 0x0020},
1076 {OV0_GAMMA_20_3F
, 0x100, 0x0040},
1077 {OV0_GAMMA_40_7F
, 0x100, 0x0080},
1078 {OV0_GAMMA_380_3BF
, 0x100, 0x0100},
1079 {OV0_GAMMA_3C0_3FF
, 0x100, 0x0100}
1082 static void make_default_gamma_correction( void )
1085 if((besr
.chip_flags
& R_100
)==R_100
||
1086 (besr
.chip_flags
& R_120
)==R_120
||
1087 (besr
.chip_flags
& R_150
)==R_150
){
1088 OUTREG(OV0_LIN_TRANS_A
, 0x12A00000);
1089 OUTREG(OV0_LIN_TRANS_B
, 0x199018FE);
1090 OUTREG(OV0_LIN_TRANS_C
, 0x12A0F9B0);
1091 OUTREG(OV0_LIN_TRANS_D
, 0xF2F0043B);
1092 OUTREG(OV0_LIN_TRANS_E
, 0x12A02050);
1093 OUTREG(OV0_LIN_TRANS_F
, 0x0000174E);
1095 OUTREG(r100_def_gamma
[i
].gammaReg
,
1096 (r100_def_gamma
[i
].gammaSlope
<<16) |
1097 r100_def_gamma
[i
].gammaOffset
);
1101 OUTREG(OV0_LIN_TRANS_A
, 0x12a20000);
1102 OUTREG(OV0_LIN_TRANS_B
, 0x198a190e);
1103 OUTREG(OV0_LIN_TRANS_C
, 0x12a2f9da);
1104 OUTREG(OV0_LIN_TRANS_D
, 0xf2fe0442);
1105 OUTREG(OV0_LIN_TRANS_E
, 0x12a22046);
1106 OUTREG(OV0_LIN_TRANS_F
, 0x175f);
1108 Of 18 segments for gamma cure, all segments in R200 are programmable,
1109 while only lower 4 and upper 2 segments are programmable in Radeon*/
1110 for(i
=0; i
<18; i
++){
1111 OUTREG(r200_def_gamma
[i
].gammaReg
,
1112 (r200_def_gamma
[i
].gammaSlope
<<16) |
1113 r200_def_gamma
[i
].gammaOffset
);
1119 static void radeon_vid_make_default(void)
1122 besr
.saturation
= 0x0F;
1123 besr
.brightness
= 0;
1124 OUTREG(OV0_COLOUR_CNTL
,0x000F0F00UL
); /* Default brihgtness and saturation for Rage128 */
1126 make_default_gamma_correction();
1128 besr
.deinterlace_pattern
= 0x900AAAAA;
1129 OUTREG(OV0_DEINTERLACE_PATTERN
,besr
.deinterlace_pattern
);
1130 besr
.deinterlace_on
=1;
1133 besr
.graphics_key_msk
=0;
1134 besr
.graphics_key_clr
=0;
1135 besr
.ckey_cntl
= VIDEO_KEY_FN_TRUE
|GRAPHIC_KEY_FN_TRUE
|CMP_MIX_AND
;
1138 static int find_chip(unsigned chip_id
)
1141 for(i
= 0;i
< sizeof(ati_card_ids
)/sizeof(ati_card_ids_t
);i
++)
1143 if(chip_id
== ati_card_ids
[i
].id
) return i
;
1148 static pciinfo_t pci_info
;
1149 static int probed
=0;
1151 static vidix_capability_t def_cap
=
1154 "BES driver for Rage128 cards",
1156 "BES driver for Radeon cards",
1159 TYPE_OUTPUT
| TYPE_FX
,
1166 FLAG_UPSCALER
| FLAG_DOWNSCALER
| FLAG_EQUALIZER
,
1172 #if !defined(RAGE128) && defined(CONFIG_X11)
1173 static void probe_fireGL_driver(void) {
1174 Display
*dp
= XOpenDisplay ((void*)0);
1180 extlist
= XListExtensions (dp
, &n
);
1184 int ext_fgl
= 0, ext_fglrx
= 0;
1185 for (i
= 0; i
< n
; i
++) {
1186 if (!strcmp(extlist
[i
], "ATIFGLEXTENSION")) ext_fgl
= 1;
1187 if (!strcmp(extlist
[i
], "ATIFGLRXDRI")) ext_fglrx
= 1;
1190 printf(RADEON_MSG
" ATI FireGl driver detected");
1191 firegl_shift
= 0x500000;
1193 printf(", but DRI seems not to be activated\n");
1194 printf(RADEON_MSG
" Output may not work correctly, check your DRI configration!");
1202 static int radeon_probe(int verbose
, int force
)
1204 pciinfo_t lst
[MAX_PCI_DEVICES
];
1207 verbosity
= verbose
;
1208 err
= pci_scan(lst
,&num_pci
);
1211 printf(RADEON_MSG
" Error occurred during pci scan: %s\n",strerror(err
));
1217 for(i
=0;i
<num_pci
;i
++)
1219 if(lst
[i
].vendor
== VENDOR_ATI
)
1223 idx
= find_chip(lst
[i
].device
);
1224 if(idx
== -1 && force
== PROBE_NORMAL
) continue;
1225 dname
= pci_device_name(VENDOR_ATI
,lst
[i
].device
);
1226 dname
= dname
? dname
: "Unknown chip";
1227 printf(RADEON_MSG
" Found chip: %s\n",dname
);
1229 if ((lst
[i
].command
& PCI_COMMAND_IO
) == 0)
1231 printf("[radeon] Device is disabled, ignoring\n");
1235 memset(&besr
,0,sizeof(bes_registers_t
));
1236 if(force
> PROBE_NORMAL
)
1238 printf(RADEON_MSG
" Driver was forced. Was found %sknown chip\n",idx
== -1 ? "un" : "");
1241 printf(RADEON_MSG
" Assuming it as Rage128\n");
1243 printf(RADEON_MSG
" Assuming it as Radeon1\n");
1245 besr
.chip_flags
=R_100
|R_OVL_SHIFT
;
1247 #if !defined(RAGE128) && defined(CONFIG_X11)
1248 probe_fireGL_driver();
1250 if(idx
!= -1) besr
.chip_flags
=ati_card_ids
[idx
].flags
;
1251 def_cap
.device_id
= lst
[i
].device
;
1253 memcpy(&pci_info
,&lst
[i
],sizeof(pciinfo_t
));
1259 if(err
&& verbose
) printf(RADEON_MSG
" Can't find chip\n");
1263 typedef struct saved_regs_s
1265 uint32_t ov0_vid_key_clr
;
1266 uint32_t ov0_vid_key_msk
;
1267 uint32_t ov0_graphics_key_clr
;
1268 uint32_t ov0_graphics_key_msk
;
1269 uint32_t ov0_key_cntl
;
1270 uint32_t disp_merge_cntl
;
1271 uint32_t config_cntl
;
1273 static saved_regs_t savreg
;
1275 static void save_regs( void )
1277 radeon_fifo_wait(6);
1278 savreg
.ov0_vid_key_clr
= INREG(OV0_VID_KEY_CLR
);
1279 savreg
.ov0_vid_key_msk
= INREG(OV0_VID_KEY_MSK
);
1280 savreg
.ov0_graphics_key_clr
= INREG(OV0_GRAPHICS_KEY_CLR
);
1281 savreg
.ov0_graphics_key_msk
= INREG(OV0_GRAPHICS_KEY_MSK
);
1282 savreg
.ov0_key_cntl
= INREG(OV0_KEY_CNTL
);
1283 savreg
.disp_merge_cntl
= INREG(DISP_MERGE_CNTL
);
1286 savreg
.config_cntl
= INREG(CONFIG_CNTL
);
1288 savreg
.config_cntl
= INREG(SURFACE_CNTL
);
1293 static void restore_regs( void )
1295 radeon_fifo_wait(6);
1296 OUTREG(OV0_VID_KEY_CLR
,savreg
.ov0_vid_key_clr
);
1297 OUTREG(OV0_VID_KEY_MSK
,savreg
.ov0_vid_key_msk
);
1298 OUTREG(OV0_GRAPHICS_KEY_CLR
,savreg
.ov0_graphics_key_clr
);
1299 OUTREG(OV0_GRAPHICS_KEY_MSK
,savreg
.ov0_graphics_key_msk
);
1300 OUTREG(OV0_KEY_CNTL
,savreg
.ov0_key_cntl
);
1301 OUTREG(DISP_MERGE_CNTL
,savreg
.disp_merge_cntl
);
1304 OUTREG(CONFIG_CNTL
, savreg
.config_cntl
);
1306 OUTREG(SURFACE_CNTL
, savreg
.config_cntl
);
1312 * Clear swap bits of surface data control regs for bigendian
1314 static void clear_swap(void)
1319 savreg
.config_cntl
&
1320 ~(APER_0_BIG_ENDIAN_16BPP_SWAP
| APER_0_BIG_ENDIAN_32BPP_SWAP
));
1322 OUTREG(SURFACE_CNTL
,
1323 savreg
.config_cntl
&
1324 ~(NONSURF_AP0_SWP_32BPP
| NONSURF_AP0_SWP_16BPP
));
1329 static int radeon_init(void)
1335 printf(RADEON_MSG
" Driver was not probed but is being initializing\n");
1338 if((radeon_mmio_base
= map_phys_mem(pci_info
.base2
,0xFFFF))==(void *)-1) return ENOMEM
;
1339 radeon_ram_size
= INREG(CONFIG_MEMSIZE
);
1340 /* mem size is bits [28:0], mask off the rest. Range: from 1Mb up to 512 Mb */
1341 radeon_ram_size
&= CONFIG_MEMSIZE_MASK
;
1343 /* according to XFree86 4.2.0, some production M6's return 0 for 8MB */
1344 if (radeon_ram_size
== 0 &&
1345 (def_cap
.device_id
== DEVICE_ATI_RADEON_MOBILITY_M6
||
1346 def_cap
.device_id
== DEVICE_ATI_RADEON_MOBILITY_M62
))
1348 printf(RADEON_MSG
" Working around buggy Radeon Mobility M6 (0 vs. 8MB ram)\n");
1349 radeon_ram_size
= 8192*1024;
1351 else if (radeon_ram_size
== 0 &&
1352 (def_cap
.device_id
== DEVICE_ATI_RS482_RADEON_XPRESS
))
1354 printf(RADEON_MSG
" Working around buggy RS482 Radeon Xpress 200 Memory Detection\n");
1355 radeon_ram_size
= (INREG(CONFIG_MEMSIZE
) + 0x100000) << 2;
1356 radeon_ram_size
&= CONFIG_MEMSIZE_MASK
;
1359 /* Rage Mobility (rage128) also has memsize bug */
1360 if (radeon_ram_size
== 0 &&
1361 (def_cap
.device_id
== DEVICE_ATI_RAGE_MOBILITY_M3
||
1362 def_cap
.device_id
== DEVICE_ATI_RAGE_MOBILITY_M32
))
1364 printf(RADEON_MSG
" Working around Rage Mobility M3 (0 vs. 8MB ram)\n");
1365 radeon_ram_size
= 8192*1024;
1368 if((radeon_mem_base
= map_phys_mem(pci_info
.base0
,radeon_ram_size
))==(void *)-1) return ENOMEM
;
1369 radeon_vid_make_default();
1370 printf(RADEON_MSG
" Video memory = %uMb\n",radeon_ram_size
/0x100000);
1371 err
= mtrr_set_type(pci_info
.base0
,radeon_ram_size
,MTRR_TYPE_WRCOMB
);
1372 if(!err
) printf(RADEON_MSG
" Set write-combining type of video memory\n");
1375 memset(&rinfo
,0,sizeof(rinfo_t
));
1376 if((besr
.chip_flags
&R_100
) != R_100
) rinfo
.hasCRTC2
= 1;
1378 radeon_get_moninfo(&rinfo
);
1379 if(rinfo
.hasCRTC2
) {
1380 printf(RADEON_MSG
" DVI port has %s monitor connected\n",GET_MON_NAME(rinfo
.dviDispType
));
1381 printf(RADEON_MSG
" CRT port has %s monitor connected\n",GET_MON_NAME(rinfo
.crtDispType
));
1384 printf(RADEON_MSG
" CRT port has %s monitor connected\n",GET_MON_NAME(rinfo
.crtDispType
));
1392 static void radeon_destroy(void)
1395 unmap_phys_mem(radeon_mem_base
,radeon_ram_size
);
1396 unmap_phys_mem(radeon_mmio_base
,0xFFFF);
1399 static int radeon_get_caps(vidix_capability_t
*to
)
1401 memcpy(to
,&def_cap
,sizeof(vidix_capability_t
));
1406 Full list of fourcc which are supported by Win2K radeon driver:
1407 YUY2, UYVY, DDES, OGLT, OGL2, OGLS, OGLB, OGNT, OGNZ, OGNS,
1408 IF09, YVU9, IMC4, M2IA, IYUV, VBID, DXT1, DXT2, DXT3, DXT4, DXT5
1410 typedef struct fourcc_desc_s
1416 static const fourcc_desc_t supported_fourcc
[] =
1418 { IMGFMT_Y800
, 1567 },
1419 { IMGFMT_YVU9
, 1567 },
1420 { IMGFMT_IF09
, 1567 },
1421 { IMGFMT_YV12
, 1567 },
1422 { IMGFMT_I420
, 1567 },
1423 { IMGFMT_IYUV
, 1567 },
1424 { IMGFMT_UYVY
, 1551 },
1425 { IMGFMT_YUY2
, 1551 },
1426 { IMGFMT_YVYU
, 1551 },
1427 { IMGFMT_RGB15
, 1551 },
1428 { IMGFMT_BGR15
, 1551 },
1429 { IMGFMT_RGB16
, 1551 },
1430 { IMGFMT_BGR16
, 1551 },
1431 { IMGFMT_RGB32
, 775 },
1432 { IMGFMT_BGR32
, 775 }
1435 __inline__
static int is_supported_fourcc(uint32_t fourcc
)
1438 for(i
=0;i
<sizeof(supported_fourcc
)/sizeof(fourcc_desc_t
);i
++)
1440 if(fourcc
==supported_fourcc
[i
].fourcc
)
1446 static int radeon_query_fourcc(vidix_fourcc_t
*to
)
1448 if(is_supported_fourcc(to
->fourcc
))
1450 to
->depth
= VID_DEPTH_ALL
;
1451 to
->flags
= VID_CAP_EXPAND
| VID_CAP_SHRINK
| VID_CAP_COLORKEY
|
1455 else to
->depth
= to
->flags
= 0;
1459 static double H_scale_ratio
;
1460 static void radeon_vid_dump_regs( void )
1463 printf(RADEON_MSG
"*** Begin of DRIVER variables dump ***\n");
1464 printf(RADEON_MSG
"radeon_mmio_base=%p\n",radeon_mmio_base
);
1465 printf(RADEON_MSG
"radeon_mem_base=%p\n",radeon_mem_base
);
1466 printf(RADEON_MSG
"radeon_overlay_off=%08X\n",radeon_overlay_off
);
1467 printf(RADEON_MSG
"radeon_ram_size=%08X\n",radeon_ram_size
);
1468 printf(RADEON_MSG
"video mode: %ux%u@%u\n",radeon_get_xres(),radeon_get_yres(),radeon_vid_get_dbpp());
1469 printf(RADEON_MSG
"H_scale_ratio=%8.2f\n",H_scale_ratio
);
1470 printf(RADEON_MSG
"*** Begin of OV0 registers dump ***\n");
1471 for(i
=0;i
<sizeof(vregs
)/sizeof(video_registers_t
);i
++)
1472 printf(RADEON_MSG
"%s = %08X\n",vregs
[i
].sname
,INREG(vregs
[i
].name
));
1473 printf(RADEON_MSG
"*** End of OV0 registers dump ***\n");
1476 static void radeon_vid_stop_video( void )
1478 radeon_engine_idle();
1479 OUTREG(OV0_SCALE_CNTL
, SCALER_SOFT_RESET
);
1480 OUTREG(OV0_EXCLUSIVE_HORZ
, 0);
1481 OUTREG(OV0_AUTO_FLIP_CNTL
, 0); /* maybe */
1482 OUTREG(OV0_FILTER_CNTL
, FILTER_HARDCODED_COEF
);
1484 OUTREG(OV0_KEY_CNTL
, GRAPHIC_KEY_FN_NE
);
1486 OUTREG(OV0_KEY_CNTL
, GRAPHIC_KEY_FN_EQ
);
1488 OUTREG(OV0_TEST
, 0);
1491 static void radeon_vid_display_video( void )
1493 int bes_flags
,force_second
;
1494 radeon_fifo_wait(2);
1495 OUTREG(OV0_REG_LOAD_CNTL
, REG_LD_CTL_LOCK
);
1496 radeon_engine_idle();
1497 while(!(INREG(OV0_REG_LOAD_CNTL
)®_LD_CTL_LOCK_READBACK
));
1498 radeon_fifo_wait(15);
1502 /* Shutdown capturing */
1503 OUTREG(FCP_CNTL
, FCP_CNTL__GND
);
1504 OUTREG(CAP0_TRIG_CNTL
, 0);
1506 OUTREG(VID_BUFFER_CONTROL
, (1<<16) | 0x01);
1507 OUTREG(DISP_TEST_DEBUG_CNTL
, 0);
1509 OUTREG(OV0_AUTO_FLIP_CNTL
,OV0_AUTO_FLIP_CNTL_SOFT_BUF_ODD
);
1511 if(besr
.deinterlace_on
) OUTREG(OV0_DEINTERLACE_PATTERN
,besr
.deinterlace_pattern
);
1513 OUTREG(OV0_COLOUR_CNTL
, (besr
.brightness
& 0x7f) |
1514 (besr
.saturation
<< 8) |
1515 (besr
.saturation
<< 16));
1517 radeon_fifo_wait(2);
1518 OUTREG(OV0_GRAPHICS_KEY_MSK
, besr
.graphics_key_msk
);
1519 OUTREG(OV0_GRAPHICS_KEY_CLR
, besr
.graphics_key_clr
);
1520 OUTREG(OV0_KEY_CNTL
,besr
.ckey_cntl
);
1522 OUTREG(OV0_H_INC
, besr
.h_inc
);
1523 OUTREG(OV0_STEP_BY
, besr
.step_by
);
1526 OUTREG(OV1_Y_X_START
, besr
.y_x_start
);
1527 OUTREG(OV1_Y_X_END
, besr
.y_x_end
);
1531 OUTREG(OV0_Y_X_START
, besr
.y_x_start
);
1532 OUTREG(OV0_Y_X_END
, besr
.y_x_end
);
1534 OUTREG(OV0_V_INC
, besr
.v_inc
);
1535 OUTREG(OV0_P1_BLANK_LINES_AT_TOP
, besr
.p1_blank_lines_at_top
);
1536 OUTREG(OV0_P23_BLANK_LINES_AT_TOP
, besr
.p23_blank_lines_at_top
);
1537 OUTREG(OV0_VID_BUF_PITCH0_VALUE
, besr
.vid_buf_pitch0_value
);
1538 OUTREG(OV0_VID_BUF_PITCH1_VALUE
, besr
.vid_buf_pitch1_value
);
1539 OUTREG(OV0_P1_X_START_END
, besr
.p1_x_start_end
);
1540 OUTREG(OV0_P2_X_START_END
, besr
.p2_x_start_end
);
1541 OUTREG(OV0_P3_X_START_END
, besr
.p3_x_start_end
);
1543 OUTREG(OV0_BASE_ADDR
, besr
.base_addr
);
1545 OUTREG(OV0_VID_BUF0_BASE_ADRS
, besr
.vid_buf_base_adrs_y
[0]);
1546 OUTREG(OV0_VID_BUF1_BASE_ADRS
, besr
.vid_buf_base_adrs_v
[0]);
1547 OUTREG(OV0_VID_BUF2_BASE_ADRS
, besr
.vid_buf_base_adrs_u
[0]);
1548 radeon_fifo_wait(9);
1549 OUTREG(OV0_VID_BUF3_BASE_ADRS
, besr
.vid_buf_base_adrs_y
[0]);
1550 OUTREG(OV0_VID_BUF4_BASE_ADRS
, besr
.vid_buf_base_adrs_v
[0]);
1551 OUTREG(OV0_VID_BUF5_BASE_ADRS
, besr
.vid_buf_base_adrs_u
[0]);
1552 OUTREG(OV0_P1_V_ACCUM_INIT
, besr
.p1_v_accum_init
);
1553 OUTREG(OV0_P1_H_ACCUM_INIT
, besr
.p1_h_accum_init
);
1554 OUTREG(OV0_P23_H_ACCUM_INIT
, besr
.p23_h_accum_init
);
1555 OUTREG(OV0_P23_V_ACCUM_INIT
, besr
.p23_v_accum_init
);
1557 bes_flags
= SCALER_ENABLE
|
1558 SCALER_SMART_SWITCH
|
1561 if(besr
.double_buff
) bes_flags
|= SCALER_DOUBLE_BUFFER
;
1562 if(besr
.deinterlace_on
) bes_flags
|= SCALER_ADAPTIVE_DEINT
;
1563 if(besr
.horz_pick_nearest
) bes_flags
|= SCALER_HORZ_PICK_NEAREST
;
1564 if(besr
.vert_pick_nearest
) bes_flags
|= SCALER_VERT_PICK_NEAREST
;
1566 bes_flags
|= SCALER_BURST_PER_PLANE
;
1568 bes_flags
|= (besr
.surf_id
<< 8) & SCALER_SURFAC_FORMAT
;
1569 if(besr
.load_prg_start
) bes_flags
|= SCALER_PRG_LOAD_START
;
1570 if(force_second
) bes_flags
|= SCALER_USE_OV1
;
1571 else bes_flags
&= ~SCALER_USE_OV1
;
1572 OUTREG(OV0_SCALE_CNTL
, bes_flags
);
1573 radeon_fifo_wait(6);
1574 OUTREG(OV0_FILTER_CNTL
,besr
.filter_cntl
);
1575 OUTREG(OV0_FOUR_TAP_COEF_0
,besr
.four_tap_coeff
[0]);
1576 OUTREG(OV0_FOUR_TAP_COEF_1
,besr
.four_tap_coeff
[1]);
1577 OUTREG(OV0_FOUR_TAP_COEF_2
,besr
.four_tap_coeff
[2]);
1578 OUTREG(OV0_FOUR_TAP_COEF_3
,besr
.four_tap_coeff
[3]);
1579 OUTREG(OV0_FOUR_TAP_COEF_4
,besr
.four_tap_coeff
[4]);
1580 if(besr
.swap_uv
) OUTREG(OV0_TEST
,INREG(OV0_TEST
)|OV0_SWAP_UV
);
1581 OUTREG(OV0_REG_LOAD_CNTL
, 0);
1582 if(verbosity
> VERBOSE_LEVEL
) printf(RADEON_MSG
"we wanted: scaler=%08X\n",bes_flags
);
1583 if(verbosity
> VERBOSE_LEVEL
) radeon_vid_dump_regs();
1586 /* Goal of this function: hide RGB background and provide black screen around movie.
1587 Useful in '-vo fbdev:vidix -fs -zoom' mode.
1588 Reverse effect to colorkey */
1590 static void radeon_vid_exclusive( void )
1592 /* this function works only with Rage128.
1593 Radeon should has something the same */
1594 unsigned screenw
,screenh
;
1595 screenw
= radeon_get_xres();
1596 screenh
= radeon_get_yres();
1597 radeon_fifo_wait(2);
1598 OUTREG(OV0_EXCLUSIVE_VERT
,(((screenh
-1)<<16)&EXCL_VERT_END_MASK
));
1599 OUTREG(OV0_EXCLUSIVE_HORZ
,(((screenw
/8+1)<<8)&EXCL_HORZ_END_MASK
)|EXCL_HORZ_EXCLUSIVE_EN
);
1602 static void radeon_vid_non_exclusive( void )
1604 OUTREG(OV0_EXCLUSIVE_HORZ
,0);
1608 static unsigned radeon_query_pitch(unsigned fourcc
,const vidix_yuv_t
*spitch
)
1610 unsigned pitch
,spy
,spv
,spu
;
1611 spy
= spv
= spu
= 0;
1618 case 256: spy
= spitch
->y
; break;
1627 case 256: spu
= spitch
->u
; break;
1636 case 256: spv
= spitch
->v
; break;
1645 if(spy
> 16 && spu
== spy
/2 && spv
== spy
/2) pitch
= spy
;
1650 if(spy
>= 64 && spu
== spy
/4 && spv
== spy
/4) pitch
= spy
;
1654 if(spy
>= 16) pitch
= spy
;
1661 static void Calc_H_INC_STEP_BY (
1662 int fieldvalue_OV0_SURFACE_FORMAT
,
1663 double H_scale_ratio
,
1664 int DisallowFourTapVertFiltering
,
1665 int DisallowFourTapUVVertFiltering
,
1666 uint32_t *val_OV0_P1_H_INC
,
1667 uint32_t *val_OV0_P1_H_STEP_BY
,
1668 uint32_t *val_OV0_P23_H_INC
,
1669 uint32_t *val_OV0_P23_H_STEP_BY
,
1675 double ClocksNeededFor16Pixels
;
1677 switch (fieldvalue_OV0_SURFACE_FORMAT
)
1680 case 4: /*16BPP (ARGB1555 and RGB565) */
1681 /* All colour components are fetched in pairs */
1683 /* We don't support four tap in this mode because G's are split between two bytes. In theory we could support it if */
1684 /* we saved part of the G when fetching the R, and then filter the G, followed by the B in the following cycles. */
1685 if (H_scale_ratio
>=.5)
1687 /* We are actually generating two pixels (but 3 colour components) per tick. Thus we don't have to skip */
1688 /* until we reach .5. P1 and P23 are the same. */
1689 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5);
1690 *val_OV0_P1_H_STEP_BY
= 1;
1691 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5);
1692 *val_OV0_P23_H_STEP_BY
= 1;
1696 else if (H_scale_ratio
>=.25)
1699 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*2)) * (1<<0xc) + 0.5);
1700 *val_OV0_P1_H_STEP_BY
= 2;
1701 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*2)) * (1<<0xc) + 0.5);
1702 *val_OV0_P23_H_STEP_BY
= 2;
1706 else if (H_scale_ratio
>=.125)
1709 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*4)) * (1<<0xc) + 0.5);
1710 *val_OV0_P1_H_STEP_BY
= 3;
1711 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*4)) * (1<<0xc) + 0.5);
1712 *val_OV0_P23_H_STEP_BY
= 3;
1716 else if (H_scale_ratio
>=.0625)
1719 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*8)) * (1<<0xc) + 0.5);
1720 *val_OV0_P1_H_STEP_BY
= 4;
1721 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*8)) * (1<<0xc) + 0.5);
1722 *val_OV0_P23_H_STEP_BY
= 4;
1726 else if (H_scale_ratio
>=0.03125)
1728 /* Step by sixteen */
1729 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*16)) * (1<<0xc) + 0.5);
1730 *val_OV0_P1_H_STEP_BY
= 5;
1731 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*16)) * (1<<0xc) + 0.5);
1732 *val_OV0_P23_H_STEP_BY
= 5;
1738 H_scale_ratio
=0.03125;
1739 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*16)) * (1<<0xc) + 0.5);
1740 *val_OV0_P1_H_STEP_BY
= 5;
1741 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*16)) * (1<<0xc) + 0.5);
1742 *val_OV0_P23_H_STEP_BY
= 5;
1747 case 6: /*32BPP RGB */
1748 if (H_scale_ratio
>=1.5 && !DisallowFourTapVertFiltering
)
1750 /* All colour components are fetched in pairs */
1752 /* With four tap filtering, we can generate two colour components every clock, or two pixels every three */
1753 /* clocks. This means that we will have four tap filtering when scaling 1.5 or more. */
1754 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5);
1755 *val_OV0_P1_H_STEP_BY
= 0;
1756 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5);
1757 *val_OV0_P23_H_STEP_BY
= 0;
1761 else if (H_scale_ratio
>=0.75)
1763 /* Four G colour components are fetched at once */
1765 /* R and B colour components are fetched in pairs */
1766 /* With two tap filtering, we can generate four colour components every clock. */
1767 /* This means that we will have two tap filtering when scaling 1.0 or more. */
1768 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5);
1769 *val_OV0_P1_H_STEP_BY
= 1;
1770 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5);
1771 *val_OV0_P23_H_STEP_BY
= 1;
1775 else if (H_scale_ratio
>=0.375)
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
*2)) * (1<<0xc) + 0.5);
1782 *val_OV0_P1_H_STEP_BY
= 2;
1783 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*2)) * (1<<0xc) + 0.5);
1784 *val_OV0_P23_H_STEP_BY
= 2;
1788 else if (H_scale_ratio
>=0.25)
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
*2)) * (1<<0xc) + 0.5);
1795 *val_OV0_P1_H_STEP_BY
= 2;
1796 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*4)) * (1<<0xc) + 0.5);
1797 *val_OV0_P23_H_STEP_BY
= 3;
1801 else if (H_scale_ratio
>=0.1875)
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
*4)) * (1<<0xc) + 0.5);
1808 *val_OV0_P1_H_STEP_BY
= 3;
1809 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*4)) * (1<<0xc) + 0.5);
1810 *val_OV0_P23_H_STEP_BY
= 3;
1814 else if (H_scale_ratio
>=0.125)
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
*4)) * (1<<0xc) + 0.5);
1821 *val_OV0_P1_H_STEP_BY
= 3;
1822 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*8)) * (1<<0xc) + 0.5);
1823 *val_OV0_P23_H_STEP_BY
= 4;
1827 else if (H_scale_ratio
>=0.09375)
1830 /* Four G colour components are fetched at once */
1832 /* R and B colour components are fetched in pairs */
1833 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*8)) * (1<<0xc) + 0.5);
1834 *val_OV0_P1_H_STEP_BY
= 4;
1835 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*8)) * (1<<0xc) + 0.5);
1836 *val_OV0_P23_H_STEP_BY
= 4;
1840 else if (H_scale_ratio
>=0.0625)
1843 /* Four G colour components are fetched at once */
1845 /* R and B colour components are fetched in pairs */
1846 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*16)) * (1<<0xc) + 0.5);
1847 *val_OV0_P1_H_STEP_BY
= 5;
1848 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*16)) * (1<<0xc) + 0.5);
1849 *val_OV0_P23_H_STEP_BY
= 5;
1855 H_scale_ratio
=0.0625;
1857 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*16)) * (1<<0xc) + 0.5);
1858 *val_OV0_P1_H_STEP_BY
= 5;
1859 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*16)) * (1<<0xc) + 0.5);
1860 *val_OV0_P23_H_STEP_BY
= 5;
1866 /*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. */
1867 /* four tap on both (unless Y is too wide) */
1868 if ((H_scale_ratio
>=(ClocksNeededFor16Pixels
=8+2+2) / 16.0) &&
1869 ((uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5)<=0x3000) &&
1870 ((uint16_t)((1/(H_scale_ratio
*4)) * (1<<0xc) + 0.5)<=0x2000) &&
1871 !DisallowFourTapVertFiltering
&& !DisallowFourTapUVVertFiltering
)
1873 /* Colour components are fetched in pairs */
1875 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5);
1876 *val_OV0_P1_H_STEP_BY
= 0;
1877 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*4)) * (1<<0xc) + 0.5);
1878 *val_OV0_P23_H_STEP_BY
= 0;
1882 /* two tap on Y (because it is too big for four tap), four tap on UV */
1883 else if ((H_scale_ratio
>=(ClocksNeededFor16Pixels
=4+2+2) / 16.0) &&
1884 ((uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5)<=0x3000) &&
1885 ((uint16_t)((1/(H_scale_ratio
*4)) * (1<<0xc) + 0.5)<=0x2000) &&
1886 DisallowFourTapVertFiltering
&& !DisallowFourTapUVVertFiltering
)
1889 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5);
1890 *val_OV0_P1_H_STEP_BY
= 1;
1891 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*4)) * (1<<0xc) + 0.5);
1892 *val_OV0_P23_H_STEP_BY
= 0;
1896 /* We scale the Y with the four tap filters, but UV's are generated
1897 with dual two tap configuration. */
1898 else if ((H_scale_ratio
>=(ClocksNeededFor16Pixels
=8+1+1) / 16.0) &&
1899 ((uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5)<=0x3000) &&
1900 ((uint16_t)((1/(H_scale_ratio
*4)) * (1<<0xc) + 0.5)<=0x2000) &&
1901 !DisallowFourTapVertFiltering
)
1904 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5);
1905 *val_OV0_P1_H_STEP_BY
= 0;
1906 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*4)) * (1<<0xc) + 0.5);
1907 *val_OV0_P23_H_STEP_BY
= 1;
1911 /* We scale the Y, U, and V with the two tap filters */
1912 else if ((H_scale_ratio
>=(ClocksNeededFor16Pixels
=4+1+1) / 16.0) &&
1913 ((uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5)<=0x3000) &&
1914 ((uint16_t)((1/(H_scale_ratio
*4)) * (1<<0xc) + 0.5)<=0x2000))
1917 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5);
1918 *val_OV0_P1_H_STEP_BY
= 1;
1919 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*4)) * (1<<0xc) + 0.5);
1920 *val_OV0_P23_H_STEP_BY
= 1;
1924 /* We scale step the U and V by two to allow more bandwidth for fetching Y's,
1925 thus we won't drop Y's yet. */
1926 else if ((H_scale_ratio
>=(ClocksNeededFor16Pixels
=4+.5+.5) / 16.0) &&
1927 ((uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5)<=0x3000) &&
1928 ((uint16_t)((1/(H_scale_ratio
*4*2)) * (1<<0xc) + 0.5)<=0x2000))
1929 { /*>=0.3125 and >.333333~ */
1931 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5);
1932 *val_OV0_P1_H_STEP_BY
= 1;
1933 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*4*2)) * (1<<0xc) + 0.5);
1934 *val_OV0_P23_H_STEP_BY
= 2;
1938 /* We step the Y, U, and V by two. */
1939 else if ((H_scale_ratio
>=(ClocksNeededFor16Pixels
=2+.5+.5) / 16.0) &&
1940 ((uint16_t)((1/(H_scale_ratio
*2)) * (1<<0xc) + 0.5)<=0x3000) &&
1941 ((uint16_t)((1/(H_scale_ratio
*4*2)) * (1<<0xc) + 0.5)<=0x2000))
1944 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*2)) * (1<<0xc) + 0.5);
1945 *val_OV0_P1_H_STEP_BY
= 2;
1946 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*4*2)) * (1<<0xc) + 0.5);
1947 *val_OV0_P23_H_STEP_BY
= 2;
1951 /* We step the Y by two and the U and V by four. */
1952 else if ((H_scale_ratio
>=(ClocksNeededFor16Pixels
=2+.25+.25) / 16.0) &&
1953 ((uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5)<=0x3000) &&
1954 ((uint16_t)((1/(H_scale_ratio
*4*4)) * (1<<0xc) + 0.5)<=0x2000))
1957 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*2)) * (1<<0xc) + 0.5);
1958 *val_OV0_P1_H_STEP_BY
= 2;
1959 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*4*4)) * (1<<0xc) + 0.5);
1960 *val_OV0_P23_H_STEP_BY
= 3;
1964 /* We step the Y, U, and V by four. */
1965 else if ((H_scale_ratio
>=(ClocksNeededFor16Pixels
=1+.25+.25) / 16.0) &&
1966 ((uint16_t)((1/(H_scale_ratio
*4)) * (1<<0xc) + 0.5)<=0x3000) &&
1967 ((uint16_t)((1/(H_scale_ratio
*4*4)) * (1<<0xc) + 0.5)<=0x2000))
1970 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*4)) * (1<<0xc) + 0.5);
1971 *val_OV0_P1_H_STEP_BY
= 3;
1972 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*4*4)) * (1<<0xc) + 0.5);
1973 *val_OV0_P23_H_STEP_BY
= 3;
1977 /* 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 */
1979 /* We step the Y, U, and V by eight. */
1980 else if ((H_scale_ratio
>=(ClocksNeededFor16Pixels
=.5+.125+.125) / 16.0) &&
1981 ((uint16_t)((1/(H_scale_ratio
*8)) * (1<<0xc) + 0.5)<=0x3000) &&
1982 ((uint16_t)((1/(H_scale_ratio
*4*8)) * (1<<0xc) + 0.5)<=0x2000))
1985 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*8)) * (1<<0xc) + 0.5);
1986 *val_OV0_P1_H_STEP_BY
= 4;
1987 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*4*8)) * (1<<0xc) + 0.5);
1988 *val_OV0_P23_H_STEP_BY
= 4;
1992 /* We step the Y by eight and the U and V by sixteen. */
1993 else if ((H_scale_ratio
>=(ClocksNeededFor16Pixels
=.5+.0625+.0625) / 16.0) &&
1994 ((uint16_t)((1/(H_scale_ratio
*8)) * (1<<0xc) + 0.5)<=0x3000) &&
1995 ((uint16_t)((1/(H_scale_ratio
*4*16)) * (1<<0xc) + 0.5)<=0x2000))
1998 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*8)) * (1<<0xc) + 0.5);
1999 *val_OV0_P1_H_STEP_BY
= 4;
2000 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*4*16)) * (1<<0xc) + 0.5);
2001 *val_OV0_P23_H_STEP_BY
= 5;
2005 /* We step the Y, U, and V by sixteen. */
2006 else if ((H_scale_ratio
>=(ClocksNeededFor16Pixels
=.25+.0625+.0625) / 16.0) &&
2007 ((uint16_t)((1/(H_scale_ratio
*16)) * (1<<0xc) + 0.5)<=0x3000) &&
2008 ((uint16_t)((1/(H_scale_ratio
*4*16)) * (1<<0xc) + 0.5)<=0x2000))
2011 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*16)) * (1<<0xc) + 0.5);
2012 *val_OV0_P1_H_STEP_BY
= 5;
2013 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*4*16)) * (1<<0xc) + 0.5);
2014 *val_OV0_P23_H_STEP_BY
= 5;
2020 H_scale_ratio
=(ClocksNeededFor16Pixels
=.25+.0625+.0625) / 16;
2022 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*16)) * (1<<0xc) + 0.5);
2023 *val_OV0_P1_H_STEP_BY
= 5;
2024 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*4*16)) * (1<<0xc) + 0.5);
2025 *val_OV0_P23_H_STEP_BY
= 5;
2034 case 14: /* YUV12, VYUY422, YUYV422, YOverPkCRCB12, YWovenWithPkCRCB12 */
2035 /* We scale the Y, U, and V with the four tap filters */
2036 /* four tap on both (unless Y is too wide) */
2037 if ((H_scale_ratio
>=(ClocksNeededFor16Pixels
=8+4+4) / 16.0) &&
2038 !DisallowFourTapVertFiltering
&& !DisallowFourTapUVVertFiltering
)
2041 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5);
2042 *val_OV0_P1_H_STEP_BY
= 0;
2043 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*2)) * (1<<0xc) + 0.5);
2044 *val_OV0_P23_H_STEP_BY
= 0;
2048 /* two tap on Y (because it is too big for four tap), four tap on UV */
2049 else if ((H_scale_ratio
>=(ClocksNeededFor16Pixels
=4+4+4) / 16.0) &&
2050 DisallowFourTapVertFiltering
&& !DisallowFourTapUVVertFiltering
)
2053 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5);
2054 *val_OV0_P1_H_STEP_BY
= 1;
2055 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*2)) * (1<<0xc) + 0.5);
2056 *val_OV0_P23_H_STEP_BY
= 0;
2060 /* We scale the Y with the four tap filters, but UV's are generated
2061 with dual two tap configuration. */
2062 else if ((H_scale_ratio
>=(ClocksNeededFor16Pixels
=8+2+2) / 16.0) &&
2063 !DisallowFourTapVertFiltering
)
2066 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5);
2067 *val_OV0_P1_H_STEP_BY
= 0;
2068 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*2)) * (1<<0xc) + 0.5);
2069 *val_OV0_P23_H_STEP_BY
= 1;
2073 /* We scale the Y, U, and V with the two tap filters */
2074 else if (H_scale_ratio
>=(ClocksNeededFor16Pixels
=4+2+2) / 16.0)
2077 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5);
2078 *val_OV0_P1_H_STEP_BY
= 1;
2079 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*2)) * (1<<0xc) + 0.5);
2080 *val_OV0_P23_H_STEP_BY
= 1;
2084 /* We scale step the U and V by two to allow more bandwidth for
2085 fetching Y's, thus we won't drop Y's yet. */
2086 else if (H_scale_ratio
>=(ClocksNeededFor16Pixels
=4+1+1) / 16.0)
2089 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5);
2090 *val_OV0_P1_H_STEP_BY
= 1;
2091 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*2*2)) * (1<<0xc) + 0.5);
2092 *val_OV0_P23_H_STEP_BY
= 2;
2096 /* We step the Y, U, and V by two. */
2097 else if (H_scale_ratio
>=(ClocksNeededFor16Pixels
=2+1+1) / 16.0)
2100 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*2)) * (1<<0xc) + 0.5);
2101 *val_OV0_P1_H_STEP_BY
= 2;
2102 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*2*2)) * (1<<0xc) + 0.5);
2103 *val_OV0_P23_H_STEP_BY
= 2;
2107 /* We step the Y by two and the U and V by four. */
2108 else if (H_scale_ratio
>=(ClocksNeededFor16Pixels
=2+.5+.5) / 16.0)
2111 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*2)) * (1<<0xc) + 0.5);
2112 *val_OV0_P1_H_STEP_BY
= 2;
2113 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*2*4)) * (1<<0xc) + 0.5);
2114 *val_OV0_P23_H_STEP_BY
= 3;
2118 /* We step the Y, U, and V by four. */
2119 else if (H_scale_ratio
>=(ClocksNeededFor16Pixels
=1+.5+.5) / 16.0)
2122 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*4)) * (1<<0xc) + 0.5);
2123 *val_OV0_P1_H_STEP_BY
= 3;
2124 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*2*4)) * (1<<0xc) + 0.5);
2125 *val_OV0_P23_H_STEP_BY
= 3;
2129 /* We step the Y by four and the U and V by eight. */
2130 else if ((H_scale_ratio
>=(ClocksNeededFor16Pixels
=1+.25+.25) / 16.0) &&
2131 (fieldvalue_OV0_SURFACE_FORMAT
==10))
2134 /* Can't mix step by 3 and step by 4 for packed modes */
2135 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*4)) * (1<<0xc) + 0.5);
2136 *val_OV0_P1_H_STEP_BY
= 3;
2137 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*2*8)) * (1<<0xc) + 0.5);
2138 *val_OV0_P23_H_STEP_BY
= 4;
2142 /* We step the Y, U, and V by eight. */
2143 else if (H_scale_ratio
>=(ClocksNeededFor16Pixels
=.5+.25+.25) / 16.0)
2146 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*8)) * (1<<0xc) + 0.5);
2147 *val_OV0_P1_H_STEP_BY
= 4;
2148 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*2*8)) * (1<<0xc) + 0.5);
2149 *val_OV0_P23_H_STEP_BY
= 4;
2153 /* We step the Y by eight and the U and V by sixteen. */
2154 else if ((H_scale_ratio
>=(ClocksNeededFor16Pixels
=.5+.125+.125) / 16.0) && (fieldvalue_OV0_SURFACE_FORMAT
==10))
2157 /* Step by 5 not supported for packed modes */
2158 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*8)) * (1<<0xc) + 0.5);
2159 *val_OV0_P1_H_STEP_BY
= 4;
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;
2165 /* We step the Y, U, and V by sixteen. */
2166 else if ((H_scale_ratio
>=(ClocksNeededFor16Pixels
=.25+.125+.125) / 16.0) &&
2167 (fieldvalue_OV0_SURFACE_FORMAT
==10))
2170 /* Step by 5 not supported for packed modes */
2171 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*16)) * (1<<0xc) + 0.5);
2172 *val_OV0_P1_H_STEP_BY
= 5;
2173 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*2*16)) * (1<<0xc) + 0.5);
2174 *val_OV0_P23_H_STEP_BY
= 5;
2180 if (fieldvalue_OV0_SURFACE_FORMAT
==10)
2182 H_scale_ratio
=(ClocksNeededFor16Pixels
=.25+.125+.125) / 16;
2184 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*16)) * (1<<0xc) + 0.5);
2185 *val_OV0_P1_H_STEP_BY
= 5;
2186 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*2*16)) * (1<<0xc) + 0.5);
2187 *val_OV0_P23_H_STEP_BY
= 5;
2193 H_scale_ratio
=(ClocksNeededFor16Pixels
=.5+.25+.25) / 16;
2195 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*8)) * (1<<0xc) + 0.5);
2196 *val_OV0_P1_H_STEP_BY
= 4;
2197 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*2*8)) * (1<<0xc) + 0.5);
2198 *val_OV0_P23_H_STEP_BY
= 4;
2207 besr
.h_inc
= (*(val_OV0_P1_H_INC
)&0x3fff) | ((*(val_OV0_P23_H_INC
)&0x3fff)<<16);
2208 besr
.step_by
= (*(val_OV0_P1_H_STEP_BY
)&0x7) | ((*(val_OV0_P23_H_STEP_BY
)&0x7)<<8);
2211 /* ********************************************************* */
2212 /* ** Setup Black Bordering */
2213 /* ********************************************************* */
2215 static void ComputeBorders( vidix_playback_t
*config
, int VertUVSubSample
)
2217 double tempBLANK_LINES_AT_TOP
;
2218 unsigned TopLine
,BottomLine
,SourceLinesUsed
,TopUVLine
,BottomUVLine
,SourceUVLinesUsed
;
2219 uint32_t val_OV0_P1_ACTIVE_LINES_M1
,val_OV0_P1_BLNK_LN_AT_TOP_M1
;
2220 uint32_t val_OV0_P23_ACTIVE_LINES_M1
,val_OV0_P23_BLNK_LN_AT_TOP_M1
;
2222 if (floor(config
->src
.y
)<0) {
2223 tempBLANK_LINES_AT_TOP
= -floor(config
->src
.y
);
2227 tempBLANK_LINES_AT_TOP
= 0;
2228 TopLine
= (int)floor(config
->src
.y
);
2230 /* Round rSrcBottom up and subtract one */
2231 if (ceil(config
->src
.y
+config
->src
.h
) > config
->src
.h
)
2233 BottomLine
= config
->src
.h
- 1;
2237 BottomLine
= (int)ceil(config
->src
.y
+config
->src
.h
) - 1;
2240 if (BottomLine
>= TopLine
)
2242 SourceLinesUsed
= BottomLine
- TopLine
+ 1;
2246 /*CYCACC_ASSERT(0, "SourceLinesUsed less than or equal to zero.") */
2247 SourceLinesUsed
= 1;
2251 int SourceHeightInPixels
;
2252 SourceHeightInPixels
= BottomLine
- TopLine
+ 1;
2255 val_OV0_P1_ACTIVE_LINES_M1
= SourceLinesUsed
- 1;
2256 val_OV0_P1_BLNK_LN_AT_TOP_M1
= ((int)tempBLANK_LINES_AT_TOP
-1) & 0xfff;
2258 TopUVLine
= ((int)(config
->src
.y
/VertUVSubSample
) < 0) ? 0: (int)(config
->src
.y
/VertUVSubSample
); /* Round rSrcTop down */
2259 BottomUVLine
= (ceil(((config
->src
.y
+config
->src
.h
)/VertUVSubSample
)) > (config
->src
.h
/VertUVSubSample
))
2260 ? (config
->src
.h
/VertUVSubSample
)-1 : (unsigned int)ceil(((config
->src
.y
+config
->src
.h
)/VertUVSubSample
))-1;
2262 if (BottomUVLine
>= TopUVLine
)
2264 SourceUVLinesUsed
= BottomUVLine
- TopUVLine
+ 1;
2268 /*CYCACC_ASSERT(0, "SourceUVLinesUsed less than or equal to zero.") */
2269 SourceUVLinesUsed
= 1;
2271 val_OV0_P23_ACTIVE_LINES_M1
= SourceUVLinesUsed
- 1;
2272 val_OV0_P23_BLNK_LN_AT_TOP_M1
= ((int)(tempBLANK_LINES_AT_TOP
/VertUVSubSample
)-1) & 0x7ff;
2273 besr
.p1_blank_lines_at_top
= (val_OV0_P1_BLNK_LN_AT_TOP_M1
& 0xfff) |
2274 ((val_OV0_P1_ACTIVE_LINES_M1
& 0xfff) << 16);
2275 besr
.p23_blank_lines_at_top
= (val_OV0_P23_BLNK_LN_AT_TOP_M1
& 0x7ff) |
2276 ((val_OV0_P23_ACTIVE_LINES_M1
& 0x7ff) << 16);
2280 static void ComputeXStartEnd(
2282 uint32_t LeftPixel
,uint32_t LeftUVPixel
,
2283 uint32_t MemWordsInBytes
,uint32_t BytesPerPixel
,
2284 uint32_t SourceWidthInPixels
, uint32_t P1StepSize
,
2285 uint32_t BytesPerUVPixel
,uint32_t SourceUVWidthInPixels
,
2286 uint32_t P23StepSize
, uint32_t *p1_x_start
, uint32_t *p2_x_start
)
2288 uint32_t val_OV0_P1_X_START
,val_OV0_P2_X_START
,val_OV0_P3_X_START
;
2289 uint32_t val_OV0_P1_X_END
,val_OV0_P2_X_END
,val_OV0_P3_X_END
;
2290 /* 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. */
2292 val_OV0_P1_X_START
= (int)LeftPixel
% (MemWordsInBytes
/BytesPerPixel
);
2293 val_OV0_P1_X_END
= (int)((val_OV0_P1_X_START
+ SourceWidthInPixels
- 1) / P1StepSize
) * P1StepSize
;
2295 val_OV0_P2_X_START
= val_OV0_P2_X_END
= 0;
2296 switch (besr
.surf_id
)
2301 case 14: /* ToDo_Active: The driver must insure that the initial value is */
2302 /* a multiple of a power of two when decimating */
2303 val_OV0_P2_X_START
= (int)LeftUVPixel
%
2304 (MemWordsInBytes
/BytesPerUVPixel
);
2305 val_OV0_P2_X_END
= (int)((val_OV0_P2_X_START
+
2306 SourceUVWidthInPixels
- 1) / P23StepSize
) * P23StepSize
;
2309 case 12: val_OV0_P2_X_START
= (int)LeftUVPixel
% (MemWordsInBytes
/(BytesPerPixel
*2));
2310 val_OV0_P2_X_END
= (int)((val_OV0_P2_X_START
+ SourceUVWidthInPixels
- 1) / P23StepSize
) * P23StepSize
;
2313 case 4: val_OV0_P2_X_START
= val_OV0_P1_X_START
;
2314 /* This value is needed only to allow proper setting of */
2315 /* val_OV0_PRESHIFT_P23_TO */
2316 /* val_OV0_P2_X_END = 0; */
2318 case 6: val_OV0_P2_X_START
= (int)LeftPixel
% (MemWordsInBytes
/BytesPerPixel
);
2319 val_OV0_P2_X_END
= (int)((val_OV0_P1_X_START
+ SourceWidthInPixels
- 1) / P23StepSize
) * P23StepSize
;
2321 default: /* insert debug statement here. */
2322 RADEON_ASSERT("unknown fourcc\n");
2325 val_OV0_P3_X_START
= val_OV0_P2_X_START
;
2326 val_OV0_P3_X_END
= val_OV0_P2_X_END
;
2328 besr
.p1_x_start_end
= (val_OV0_P1_X_END
&0x7ff) | ((val_OV0_P1_X_START
&0x7ff)<<16);
2329 besr
.p2_x_start_end
= (val_OV0_P2_X_END
&0x7ff) | ((val_OV0_P2_X_START
&0x7ff)<<16);
2330 besr
.p3_x_start_end
= (val_OV0_P3_X_END
&0x7ff) | ((val_OV0_P3_X_START
&0x7ff)<<16);
2333 besr
.p2_x_start_end
= 0;
2334 besr
.p3_x_start_end
= 0;
2336 *p1_x_start
= val_OV0_P1_X_START
;
2337 *p2_x_start
= val_OV0_P2_X_START
;
2340 static void ComputeAccumInit(
2341 uint32_t val_OV0_P1_X_START
,uint32_t val_OV0_P2_X_START
,
2342 uint32_t val_OV0_P1_H_INC
,uint32_t val_OV0_P23_H_INC
,
2343 uint32_t val_OV0_P1_H_STEP_BY
,uint32_t val_OV0_P23_H_STEP_BY
,
2345 uint32_t P1GroupSize
, uint32_t P23GroupSize
,
2346 uint32_t val_OV0_P1_MAX_LN_IN_PER_LN_OUT
,
2347 uint32_t val_OV0_P23_MAX_LN_IN_PER_LN_OUT
)
2349 uint32_t val_OV0_P1_H_ACCUM_INIT
,val_OV0_PRESHIFT_P1_TO
;
2350 uint32_t val_OV0_P23_H_ACCUM_INIT
,val_OV0_PRESHIFT_P23_TO
;
2351 uint32_t val_OV0_P1_V_ACCUM_INIT
,val_OV0_P23_V_ACCUM_INIT
;
2352 /* 2.5 puts the kernal 50% of the way between the source pixel that is off screen */
2353 /* and the first on-screen source pixel. "(float)valOV0_P?_H_INC / (1<<0xc)" is */
2354 /* the distance (in source pixel coordinates) to the center of the first */
2355 /* destination pixel. Need to add additional pixels depending on how many pixels */
2356 /* are fetched at a time and how many pixels in a set are masked. */
2357 /* P23 values are always fetched in groups of two or four. If the start */
2358 /* pixel does not fall on the boundary, then we need to shift preshift for */
2359 /* some additional pixels */
2362 double ExtraHalfPixel
;
2363 double tempAdditionalShift
;
2364 double tempP1HStartPoint
;
2365 double tempP23HStartPoint
;
2369 if (besr
.horz_pick_nearest
) ExtraHalfPixel
= 0.5;
2370 else ExtraHalfPixel
= 0.0;
2371 tempAdditionalShift
= val_OV0_P1_X_START
% P1GroupSize
+ ExtraHalfPixel
;
2372 tempP1HStartPoint
= tempAdditionalShift
+ 2.5 + ((float)val_OV0_P1_H_INC
/ (1<<0xd));
2373 tempP1Init
= (double)((int)(tempP1HStartPoint
* (1<<0x5) + 0.5)) / (1<<0x5);
2375 /* P23 values are always fetched in pairs. If the start pixel is odd, then we */
2376 /* need to shift an additional pixel */
2377 /* Note that if the pitch is a multiple of two, and if we store fields using */
2378 /* the traditional planer format where the V plane and the U plane share the */
2379 /* same pitch, then OverlayRegFields->val_OV0_P2_X_START % P23Group */
2380 /* OverlayRegFields->val_OV0_P3_X_START % P23GroupSize. Either way */
2381 /* it is a requirement that the U and V start on the same polarity byte */
2382 /* (even or odd). */
2383 tempAdditionalShift
= val_OV0_P2_X_START
% P23GroupSize
+ ExtraHalfPixel
;
2384 tempP23HStartPoint
= tempAdditionalShift
+ 2.5 + ((float)val_OV0_P23_H_INC
/ (1<<0xd));
2385 tempP23Init
= (double)((int)(tempP23HStartPoint
* (1<<0x5) + 0.5)) / (1 << 0x5);
2386 val_OV0_P1_H_ACCUM_INIT
= (int)((tempP1Init
- (int)tempP1Init
) * (1<<0x5));
2387 val_OV0_PRESHIFT_P1_TO
= (int)tempP1Init
;
2388 val_OV0_P23_H_ACCUM_INIT
= (int)((tempP23Init
- (int)tempP23Init
) * (1<<0x5));
2389 val_OV0_PRESHIFT_P23_TO
= (int)tempP23Init
;
2392 /* ************************************************************** */
2393 /* ** Calculate values for initializing the vertical accumulators */
2394 /* ************************************************************** */
2397 double ExtraHalfLine
;
2398 double ExtraFullLine
;
2399 double tempP1VStartPoint
;
2400 double tempP23VStartPoint
;
2402 if (besr
.vert_pick_nearest
) ExtraHalfLine
= 0.5;
2403 else ExtraHalfLine
= 0.0;
2405 if (val_OV0_P1_H_STEP_BY
==0)ExtraFullLine
= 1.0;
2406 else ExtraFullLine
= 0.0;
2408 tempP1VStartPoint
= 1.5 + ExtraFullLine
+ ExtraHalfLine
+ ((float)CRT_V_INC
/ (1<<0xd));
2409 if (tempP1VStartPoint
>2.5 + 2*ExtraFullLine
)
2411 tempP1VStartPoint
= 2.5 + 2*ExtraFullLine
;
2413 val_OV0_P1_V_ACCUM_INIT
= (int)(tempP1VStartPoint
* (1<<0x5) + 0.5);
2415 if (val_OV0_P23_H_STEP_BY
==0)ExtraFullLine
= 1.0;
2416 else ExtraFullLine
= 0.0;
2418 switch (besr
.surf_id
)
2422 case 14: tempP23VStartPoint
= 1.5 + ExtraFullLine
+ ExtraHalfLine
+
2423 ((float)CRT_V_INC
/ (1<<0xe));
2425 case 9: tempP23VStartPoint
= 1.5 + ExtraFullLine
+ ExtraHalfLine
+
2426 ((float)CRT_V_INC
/ (1<<0xf));
2432 case 12: tempP23VStartPoint
= 0;
2434 default: tempP23VStartPoint
= 0xFFFF;/* insert debug statement here */
2438 if (tempP23VStartPoint
>2.5 + 2*ExtraFullLine
)
2440 tempP23VStartPoint
= 2.5 + 2*ExtraFullLine
;
2443 val_OV0_P23_V_ACCUM_INIT
= (int)(tempP23VStartPoint
* (1<<0x5) + 0.5);
2445 besr
.p1_h_accum_init
= ((val_OV0_P1_H_ACCUM_INIT
&0x1f)<<15) |((val_OV0_PRESHIFT_P1_TO
&0xf)<<28);
2446 besr
.p1_v_accum_init
= (val_OV0_P1_MAX_LN_IN_PER_LN_OUT
&0x3) |((val_OV0_P1_V_ACCUM_INIT
&0x7ff)<<15);
2447 besr
.p23_h_accum_init
= ((val_OV0_P23_H_ACCUM_INIT
&0x1f)<<15) |((val_OV0_PRESHIFT_P23_TO
&0xf)<<28);
2448 besr
.p23_v_accum_init
= (val_OV0_P23_MAX_LN_IN_PER_LN_OUT
&0x3)|((val_OV0_P23_V_ACCUM_INIT
&0x3ff)<<15);
2451 typedef struct RangeAndCoefSet
{
2453 signed char CoefSet
[5][4];
2456 /* Filter Setup Routine */
2457 static void FilterSetup ( uint32_t val_OV0_P1_H_INC
)
2459 static const RANGEANDCOEFSET ArrayOfSets
[] = {
2460 {0.25, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2461 {0.26, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2462 {0.27, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2463 {0.28, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2464 {0.29, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2465 {0.30, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2466 {0.31, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2467 {0.32, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2468 {0.33, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2469 {0.34, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2470 {0.35, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2471 {0.36, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2472 {0.37, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2473 {0.38, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2474 {0.39, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2475 {0.40, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2476 {0.41, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2477 {0.42, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2478 {0.43, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2479 {0.44, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2480 {0.45, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2481 {0.46, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2482 {0.47, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2483 {0.48, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2484 {0.49, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2485 {0.50, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2486 {0.51, {{ 7, 17, 8, 0}, { 6, 17, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 2, 14, 14, 2}, }},
2487 {0.52, {{ 7, 17, 8, 0}, { 6, 17, 9, 0}, { 5, 16, 11, 0}, { 3, 15, 13, 1}, { 2, 14, 14, 2}, }},
2488 {0.53, {{ 7, 17, 8, 0}, { 6, 17, 9, 0}, { 5, 16, 11, 0}, { 3, 15, 13, 1}, { 2, 14, 14, 2}, }},
2489 {0.54, {{ 7, 17, 8, 0}, { 6, 17, 9, 0}, { 4, 17, 11, 0}, { 3, 15, 13, 1}, { 2, 14, 14, 2}, }},
2490 {0.55, {{ 7, 18, 7, 0}, { 6, 17, 9, 0}, { 4, 17, 11, 0}, { 3, 15, 13, 1}, { 1, 15, 15, 1}, }},
2491 {0.56, {{ 7, 18, 7, 0}, { 5, 18, 9, 0}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }},
2492 {0.57, {{ 7, 18, 7, 0}, { 5, 18, 9, 0}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }},
2493 {0.58, {{ 7, 18, 7, 0}, { 5, 18, 9, 0}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }},
2494 {0.59, {{ 7, 18, 7, 0}, { 5, 18, 9, 0}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }},
2495 {0.60, {{ 7, 18, 8, -1}, { 6, 17, 10, -1}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }},
2496 {0.61, {{ 7, 18, 8, -1}, { 6, 17, 10, -1}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }},
2497 {0.62, {{ 7, 18, 8, -1}, { 6, 17, 10, -1}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }},
2498 {0.63, {{ 7, 18, 8, -1}, { 6, 17, 10, -1}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }},
2499 {0.64, {{ 7, 18, 8, -1}, { 6, 17, 10, -1}, { 4, 17, 12, -1}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }},
2500 {0.65, {{ 7, 18, 8, -1}, { 6, 17, 10, -1}, { 4, 17, 12, -1}, { 2, 17, 13, 0}, { 0, 16, 16, 0}, }},
2501 {0.66, {{ 7, 18, 8, -1}, { 6, 18, 10, -2}, { 4, 17, 12, -1}, { 2, 17, 13, 0}, { 0, 16, 16, 0}, }},
2502 {0.67, {{ 7, 20, 7, -2}, { 5, 19, 10, -2}, { 3, 18, 12, -1}, { 2, 17, 13, 0}, { 0, 16, 16, 0}, }},
2503 {0.68, {{ 7, 20, 7, -2}, { 5, 19, 10, -2}, { 3, 19, 12, -2}, { 1, 18, 14, -1}, { 0, 16, 16, 0}, }},
2504 {0.69, {{ 7, 20, 7, -2}, { 5, 19, 10, -2}, { 3, 19, 12, -2}, { 1, 18, 14, -1}, { 0, 16, 16, 0}, }},
2505 {0.70, {{ 7, 20, 7, -2}, { 5, 20, 9, -2}, { 3, 19, 12, -2}, { 1, 18, 14, -1}, { 0, 16, 16, 0}, }},
2506 {0.71, {{ 7, 20, 7, -2}, { 5, 20, 9, -2}, { 3, 19, 12, -2}, { 1, 18, 14, -1}, { 0, 16, 16, 0}, }},
2507 {0.72, {{ 7, 20, 7, -2}, { 5, 20, 9, -2}, { 2, 20, 12, -2}, { 0, 19, 15, -2}, {-1, 17, 17, -1}, }},
2508 {0.73, {{ 7, 20, 7, -2}, { 4, 21, 9, -2}, { 2, 20, 12, -2}, { 0, 19, 15, -2}, {-1, 17, 17, -1}, }},
2509 {0.74, {{ 6, 22, 6, -2}, { 4, 21, 9, -2}, { 2, 20, 12, -2}, { 0, 19, 15, -2}, {-1, 17, 17, -1}, }},
2510 {0.75, {{ 6, 22, 6, -2}, { 4, 21, 9, -2}, { 1, 21, 12, -2}, { 0, 19, 15, -2}, {-1, 17, 17, -1}, }},
2511 {0.76, {{ 6, 22, 6, -2}, { 4, 21, 9, -2}, { 1, 21, 12, -2}, { 0, 19, 15, -2}, {-1, 17, 17, -1}, }},
2512 {0.77, {{ 6, 22, 6, -2}, { 3, 22, 9, -2}, { 1, 22, 12, -3}, { 0, 19, 15, -2}, {-2, 18, 18, -2}, }},
2513 {0.78, {{ 6, 21, 6, -1}, { 3, 22, 9, -2}, { 1, 22, 12, -3}, { 0, 19, 15, -2}, {-2, 18, 18, -2}, }},
2514 {0.79, {{ 5, 23, 5, -1}, { 3, 22, 9, -2}, { 0, 23, 12, -3}, {-1, 21, 15, -3}, {-2, 18, 18, -2}, }},
2515 {0.80, {{ 5, 23, 5, -1}, { 3, 23, 8, -2}, { 0, 23, 12, -3}, {-1, 21, 15, -3}, {-2, 18, 18, -2}, }},
2516 {0.81, {{ 5, 23, 5, -1}, { 2, 24, 8, -2}, { 0, 23, 12, -3}, {-1, 21, 15, -3}, {-2, 18, 18, -2}, }},
2517 {0.82, {{ 5, 23, 5, -1}, { 2, 24, 8, -2}, { 0, 23, 12, -3}, {-1, 21, 15, -3}, {-3, 19, 19, -3}, }},
2518 {0.83, {{ 5, 23, 5, -1}, { 2, 24, 8, -2}, { 0, 23, 11, -2}, {-2, 22, 15, -3}, {-3, 19, 19, -3}, }},
2519 {0.84, {{ 4, 25, 4, -1}, { 1, 25, 8, -2}, { 0, 23, 11, -2}, {-2, 22, 15, -3}, {-3, 19, 19, -3}, }},
2520 {0.85, {{ 4, 25, 4, -1}, { 1, 25, 8, -2}, { 0, 23, 11, -2}, {-2, 22, 15, -3}, {-3, 19, 19, -3}, }},
2521 {0.86, {{ 4, 24, 4, 0}, { 1, 25, 7, -1}, {-1, 24, 11, -2}, {-2, 22, 15, -3}, {-3, 19, 19, -3}, }},
2522 {0.87, {{ 4, 24, 4, 0}, { 1, 25, 7, -1}, {-1, 24, 11, -2}, {-2, 22, 15, -3}, {-3, 19, 19, -3}, }},
2523 {0.88, {{ 3, 26, 3, 0}, { 0, 26, 7, -1}, {-1, 24, 11, -2}, {-3, 23, 15, -3}, {-3, 19, 19, -3}, }},
2524 {0.89, {{ 3, 26, 3, 0}, { 0, 26, 7, -1}, {-1, 24, 11, -2}, {-3, 23, 15, -3}, {-3, 19, 19, -3}, }},
2525 {0.90, {{ 3, 26, 3, 0}, { 0, 26, 7, -1}, {-2, 25, 11, -2}, {-3, 23, 15, -3}, {-3, 19, 19, -3}, }},
2526 {0.91, {{ 3, 26, 3, 0}, { 0, 27, 6, -1}, {-2, 25, 11, -2}, {-3, 23, 15, -3}, {-3, 19, 19, -3}, }},
2527 {0.92, {{ 2, 28, 2, 0}, { 0, 27, 6, -1}, {-2, 25, 11, -2}, {-3, 23, 15, -3}, {-3, 19, 19, -3}, }},
2528 {0.93, {{ 2, 28, 2, 0}, { 0, 26, 6, 0}, {-2, 25, 10, -1}, {-3, 23, 15, -3}, {-3, 19, 19, -3}, }},
2529 {0.94, {{ 2, 28, 2, 0}, { 0, 26, 6, 0}, {-2, 25, 10, -1}, {-3, 23, 15, -3}, {-3, 19, 19, -3}, }},
2530 {0.95, {{ 1, 30, 1, 0}, {-1, 28, 5, 0}, {-3, 26, 10, -1}, {-3, 23, 14, -2}, {-3, 19, 19, -3}, }},
2531 {0.96, {{ 1, 30, 1, 0}, {-1, 28, 5, 0}, {-3, 26, 10, -1}, {-3, 23, 14, -2}, {-3, 19, 19, -3}, }},
2532 {0.97, {{ 1, 30, 1, 0}, {-1, 28, 5, 0}, {-3, 26, 10, -1}, {-3, 23, 14, -2}, {-3, 19, 19, -3}, }},
2533 {0.98, {{ 1, 30, 1, 0}, {-2, 29, 5, 0}, {-3, 27, 9, -1}, {-3, 23, 14, -2}, {-3, 19, 19, -3}, }},
2534 {0.99, {{ 0, 32, 0, 0}, {-2, 29, 5, 0}, {-3, 27, 9, -1}, {-4, 24, 14, -2}, {-3, 19, 19, -3}, }},
2535 {1.00, {{ 0, 32, 0, 0}, {-2, 29, 5, 0}, {-3, 27, 9, -1}, {-4, 24, 14, -2}, {-3, 19, 19, -3}, }}
2540 unsigned ArrayElement
;
2542 DSR
= (double)(1<<0xc)/val_OV0_P1_H_INC
;
2543 if (DSR
<.25) DSR
=.25;
2546 ArrayElement
= (int)((DSR
-0.25) * 100);
2547 besr
.four_tap_coeff
[0] = (ArrayOfSets
[ArrayElement
].CoefSet
[0][0] & 0xf) |
2548 ((ArrayOfSets
[ArrayElement
].CoefSet
[0][1] & 0x7f)<<8) |
2549 ((ArrayOfSets
[ArrayElement
].CoefSet
[0][2] & 0x7f)<<16) |
2550 ((ArrayOfSets
[ArrayElement
].CoefSet
[0][3] & 0xf)<<24);
2551 besr
.four_tap_coeff
[1] = (ArrayOfSets
[ArrayElement
].CoefSet
[1][0] & 0xf) |
2552 ((ArrayOfSets
[ArrayElement
].CoefSet
[1][1] & 0x7f)<<8) |
2553 ((ArrayOfSets
[ArrayElement
].CoefSet
[1][2] & 0x7f)<<16) |
2554 ((ArrayOfSets
[ArrayElement
].CoefSet
[1][3] & 0xf)<<24);
2555 besr
.four_tap_coeff
[2] = (ArrayOfSets
[ArrayElement
].CoefSet
[2][0] & 0xf) |
2556 ((ArrayOfSets
[ArrayElement
].CoefSet
[2][1] & 0x7f)<<8) |
2557 ((ArrayOfSets
[ArrayElement
].CoefSet
[2][2] & 0x7f)<<16) |
2558 ((ArrayOfSets
[ArrayElement
].CoefSet
[2][3] & 0xf)<<24);
2559 besr
.four_tap_coeff
[3] = (ArrayOfSets
[ArrayElement
].CoefSet
[3][0] & 0xf) |
2560 ((ArrayOfSets
[ArrayElement
].CoefSet
[3][1] & 0x7f)<<8) |
2561 ((ArrayOfSets
[ArrayElement
].CoefSet
[3][2] & 0x7f)<<16) |
2562 ((ArrayOfSets
[ArrayElement
].CoefSet
[3][3] & 0xf)<<24);
2563 besr
.four_tap_coeff
[4] = (ArrayOfSets
[ArrayElement
].CoefSet
[4][0] & 0xf) |
2564 ((ArrayOfSets
[ArrayElement
].CoefSet
[4][1] & 0x7f)<<8) |
2565 ((ArrayOfSets
[ArrayElement
].CoefSet
[4][2] & 0x7f)<<16) |
2566 ((ArrayOfSets
[ArrayElement
].CoefSet
[4][3] & 0xf)<<24);
2568 For more details, refer to Microsoft's draft of PC99.
2572 /* The minimal value of horizontal scale ratio when hard coded coefficients
2573 are suitable for the best quality. */
2574 /* FIXME: Should it be 0.9 for Rage128 ??? */
2575 static const double MinHScaleHard
=0.75;
2577 static int radeon_vid_init_video( vidix_playback_t
*config
)
2579 double V_scale_ratio
;
2580 uint32_t i
,src_w
,src_h
,dest_w
,dest_h
,pitch
,left
,leftUV
,top
,h_inc
;
2581 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;
2582 uint32_t val_OV0_P1_X_START
,val_OV0_P2_X_START
;
2583 uint32_t val_OV0_P1_MAX_LN_IN_PER_LN_OUT
,val_OV0_P23_MAX_LN_IN_PER_LN_OUT
;
2585 uint32_t BytesPerOctWord
,LogMemWordsInBytes
,MemWordsInBytes
,LogTileWidthInMemWords
;
2586 uint32_t TileWidthInMemWords
,TileWidthInBytes
,LogTileHeight
,TileHeight
;
2587 uint32_t PageSizeInBytes
,OV0LB_Rows
;
2588 uint32_t SourceWidthInMemWords
,SourceUVWidthInMemWords
;
2589 uint32_t SourceWidthInPixels
,SourceUVWidthInPixels
;
2590 uint32_t RightPixel
,RightUVPixel
,LeftPixel
,LeftUVPixel
;
2591 int is_400
,is_410
,is_420
,best_pitch
,mpitch
;
2592 int horz_repl_factor
,interlace_factor
;
2593 int BytesPerPixel
,BytesPerUVPixel
,HorzUVSubSample
,VertUVSubSample
;
2594 int DisallowFourTapVertFiltering
,DisallowFourTapUVVertFiltering
;
2596 radeon_vid_stop_video();
2597 left
= config
->src
.x
<< 16;
2598 top
= config
->src
.y
<< 16;
2599 src_h
= config
->src
.h
;
2600 src_w
= config
->src
.w
;
2601 is_400
= is_410
= is_420
= 0;
2602 if(config
->fourcc
== IMGFMT_YV12
||
2603 config
->fourcc
== IMGFMT_I420
||
2604 config
->fourcc
== IMGFMT_IYUV
) is_420
= 1;
2605 if(config
->fourcc
== IMGFMT_YVU9
||
2606 config
->fourcc
== IMGFMT_IF09
) is_410
= 1;
2607 if(config
->fourcc
== IMGFMT_Y800
) is_400
= 1;
2608 best_pitch
= radeon_query_pitch(config
->fourcc
,&config
->src
.pitch
);
2609 mpitch
= best_pitch
-1;
2610 BytesPerOctWord
= 16;
2611 LogMemWordsInBytes
= 4;
2612 MemWordsInBytes
= 1<<LogMemWordsInBytes
;
2613 LogTileWidthInMemWords
= 2;
2614 TileWidthInMemWords
= 1<<LogTileWidthInMemWords
;
2615 TileWidthInBytes
= 1<<(LogTileWidthInMemWords
+LogMemWordsInBytes
);
2617 TileHeight
= 1<<LogTileHeight
;
2618 PageSizeInBytes
= 64*MemWordsInBytes
;
2621 switch(config
->fourcc
)
2631 case IMGFMT_I420
: pitch
= (src_w
+ mpitch
) & ~mpitch
;
2632 config
->dest
.pitch
.y
=
2633 config
->dest
.pitch
.u
=
2634 config
->dest
.pitch
.v
= best_pitch
;
2638 case IMGFMT_BGR32
: pitch
= (src_w
*4 + mpitch
) & ~mpitch
;
2639 config
->dest
.pitch
.y
=
2640 config
->dest
.pitch
.u
=
2641 config
->dest
.pitch
.v
= best_pitch
;
2645 default: /* RGB15, RGB16, YVYU, UYVY, YUY2 */
2646 pitch
= ((src_w
*2) + mpitch
) & ~mpitch
;
2647 config
->dest
.pitch
.y
=
2648 config
->dest
.pitch
.u
=
2649 config
->dest
.pitch
.v
= best_pitch
;
2652 besr
.load_prg_start
=0;
2654 switch(config
->fourcc
)
2658 case IMGFMT_BGR15
: besr
.surf_id
= SCALER_SOURCE_15BPP
>>8;
2659 besr
.load_prg_start
= 1;
2663 case IMGFMT_BGR16
: besr
.surf_id
= SCALER_SOURCE_16BPP
>>8;
2664 besr
.load_prg_start
= 1;
2668 case IMGFMT_BGR32
: besr
.surf_id
= SCALER_SOURCE_32BPP
>>8;
2669 besr
.load_prg_start
= 1;
2673 case IMGFMT_YVU9
: besr
.surf_id
= SCALER_SOURCE_YUV9
>>8;
2680 case IMGFMT_YV12
: besr
.surf_id
= SCALER_SOURCE_YUV12
>>8;
2684 case IMGFMT_UYVY
: besr
.surf_id
= SCALER_SOURCE_YVYU422
>>8;
2687 default: besr
.surf_id
= SCALER_SOURCE_VYUY422
>>8;
2690 switch (besr
.surf_id
)
2695 case 12: BytesPerPixel
= 2;
2697 case 6: BytesPerPixel
= 4;
2702 case 14: BytesPerPixel
= 1;
2704 default: BytesPerPixel
= 0;/*insert a debug statement here. */
2707 switch (besr
.surf_id
)
2710 case 4: BytesPerUVPixel
= 0;
2711 break;/* In RGB modes, the BytesPerUVPixel is don't care */
2713 case 12: BytesPerUVPixel
= 2;
2715 case 6: BytesPerUVPixel
= 0;
2716 break; /* In RGB modes, the BytesPerUVPixel is don't care */
2718 case 10: BytesPerUVPixel
= 1;
2721 case 14: BytesPerUVPixel
= 2;
2723 default: BytesPerUVPixel
= 0;/* insert a debug statement here. */
2727 switch (besr
.surf_id
)
2731 case 6: HorzUVSubSample
= 1;
2733 case 9: HorzUVSubSample
= 4;
2739 case 14: HorzUVSubSample
= 2;
2741 default: HorzUVSubSample
= 0;/* insert debug statement here. */
2744 switch (besr
.surf_id
)
2750 case 12: VertUVSubSample
= 1;
2752 case 9: VertUVSubSample
= 4;
2756 case 14: VertUVSubSample
= 2;
2758 default: VertUVSubSample
= 0;/* insert debug statment here. */
2761 DisallowFourTapVertFiltering
= 0; /* Allow it by default */
2762 DisallowFourTapUVVertFiltering
= 0; /* Allow it by default */
2763 LeftPixel
= config
->src
.x
;
2764 RightPixel
= config
->src
.w
-1;
2765 if(floor(config
->src
.x
/HorzUVSubSample
)<0) LeftUVPixel
= 0;
2766 else LeftUVPixel
= (int)floor(config
->src
.x
/HorzUVSubSample
);
2767 if(ceil((config
->src
.x
+config
->src
.w
)/HorzUVSubSample
) > config
->src
.w
/HorzUVSubSample
)
2768 RightUVPixel
= config
->src
.w
/HorzUVSubSample
- 1;
2769 else RightUVPixel
= (int)ceil((config
->src
.x
+config
->src
.w
)/HorzUVSubSample
) - 1;
2770 /* Top, Bottom and Right Crops can be out of range. The driver will program the hardware
2771 // to create a black border at the top and bottom. This is useful for DVD letterboxing. */
2772 SourceWidthInPixels
= (int)(config
->src
.w
+ 1);
2773 SourceUVWidthInPixels
= (int)(RightUVPixel
- LeftUVPixel
+ 1);
2775 SourceWidthInMemWords
= (int)(ceil(RightPixel
*BytesPerPixel
/ MemWordsInBytes
) -
2776 floor(LeftPixel
*BytesPerPixel
/ MemWordsInBytes
) + 1);
2777 /* SourceUVWidthInMemWords means Source_U_or_V_or_UV_WidthInMemWords depending on whether the UV is packed together of not. */
2778 SourceUVWidthInMemWords
= (int)(ceil(RightUVPixel
*BytesPerUVPixel
/
2779 MemWordsInBytes
) - floor(LeftUVPixel
*BytesPerUVPixel
/
2780 MemWordsInBytes
) + 1);
2782 switch (besr
.surf_id
)
2785 case 10: if ((ceil(SourceWidthInMemWords
/2)-1) * 2 > OV0LB_Rows
-1)
2787 RADEON_ASSERT("ceil(SourceWidthInMemWords/2)-1) * 2 > OV0LB_Rows-1\n");
2789 else if ((SourceWidthInMemWords
-1) * 2 > OV0LB_Rows
-1)
2791 DisallowFourTapVertFiltering
= 1;
2794 if ((ceil(SourceUVWidthInMemWords
/2)-1) * 4 + 1 > OV0LB_Rows
-1)
2796 /*CYCACC_ASSERT(0, "Image U plane width spans more octwords than supported by hardware.") */
2798 else if ((SourceUVWidthInMemWords
-1) * 4 + 1 > OV0LB_Rows
-1)
2800 DisallowFourTapUVVertFiltering
= 1;
2803 if ((ceil(SourceUVWidthInMemWords
/2)-1) * 4 + 3 > OV0LB_Rows
-1)
2805 /*CYCACC_ASSERT(0, "Image V plane width spans more octwords than supported by hardware.") */
2807 else if ((SourceUVWidthInMemWords
-1) * 4 + 3 > OV0LB_Rows
-1)
2809 DisallowFourTapUVVertFiltering
= 1;
2813 case 14: if ((ceil(SourceWidthInMemWords
/2)-1) * 2 > OV0LB_Rows
-1)
2815 RADEON_ASSERT("ceil(SourceWidthInMemWords/2)-1) * 2 > OV0LB_Rows-1\n");
2817 else if ((SourceWidthInMemWords
-1) * 2 > OV0LB_Rows
-1)
2819 DisallowFourTapVertFiltering
= 1;
2822 if ((ceil(SourceUVWidthInMemWords
/2)-1) * 2 + 1 > OV0LB_Rows
-1)
2824 /*CYCACC_ASSERT(0, "Image UV plane width spans more octwords than supported by hardware.") */
2826 else if ((SourceUVWidthInMemWords
-1) * 2 + 1 > OV0LB_Rows
-1)
2828 DisallowFourTapUVVertFiltering
= 1;
2835 case 12: if ((ceil(SourceWidthInMemWords
/2)-1) > OV0LB_Rows
-1)
2837 RADEON_ASSERT("(ceil(SourceWidthInMemWords/2)-1) > OV0LB_Rows-1\n")
2839 else if ((SourceWidthInMemWords
-1) > OV0LB_Rows
-1)
2841 DisallowFourTapVertFiltering
= 1;
2844 default: /* insert debug statement here. */
2847 dest_w
= config
->dest
.w
;
2848 dest_h
= config
->dest
.h
;
2849 if(radeon_is_dbl_scan()) dest_h
*= 2;
2850 besr
.dest_bpp
= radeon_vid_get_dbpp();
2851 besr
.fourcc
= config
->fourcc
;
2852 if(radeon_is_interlace()) interlace_factor
= 2;
2853 else interlace_factor
= 1;
2854 /* TODO: must be checked in doublescan mode!!! */
2855 if((besr
.chip_flags
&R_INTEGRATED
)==R_INTEGRATED
)
2857 /* Force the overlay clock on for integrated chips */
2858 OUTPLL(VCLK_ECP_CNTL
, (INPLL(VCLK_ECP_CNTL
) | (1<<18)));
2860 horz_repl_factor
= 1 << (uint32_t)((INPLL(VCLK_ECP_CNTL
) & 0x300) >> 8);
2861 H_scale_ratio
= (double)ceil(((double)dest_w
+1)/horz_repl_factor
)/src_w
;
2862 V_scale_ratio
= (double)(dest_h
+1)/src_h
;
2863 if(H_scale_ratio
< 0.5 && V_scale_ratio
< 0.5)
2865 val_OV0_P1_MAX_LN_IN_PER_LN_OUT
= 3;
2866 val_OV0_P23_MAX_LN_IN_PER_LN_OUT
= 2;
2869 if(H_scale_ratio
< 1 && V_scale_ratio
< 1)
2871 val_OV0_P1_MAX_LN_IN_PER_LN_OUT
= 2;
2872 val_OV0_P23_MAX_LN_IN_PER_LN_OUT
= 1;
2876 val_OV0_P1_MAX_LN_IN_PER_LN_OUT
= 1;
2877 val_OV0_P23_MAX_LN_IN_PER_LN_OUT
= 1;
2879 /* N.B.: Indeed it has 6.12 format but shifted on 8 to the left!!! */
2880 besr
.v_inc
= (uint16_t)((1./V_scale_ratio
)*(1<<12)*interlace_factor
+0.5);
2881 CRT_V_INC
= besr
.v_inc
/interlace_factor
;
2884 int ThereIsTwoTapVerticalFiltering
,DoNotUseMostRecentlyFetchedLine
;
2885 int P1GroupSize
= 0;
2888 int P23StepSize
= 0;
2893 DisallowFourTapVertFiltering
,
2894 DisallowFourTapUVVertFiltering
,
2896 &val_OV0_P1_H_STEP_BY
,
2898 &val_OV0_P23_H_STEP_BY
,
2903 if(H_scale_ratio
> MinHScaleHard
)
2905 h_inc
= (src_w
<< 12) / dest_w
;
2906 besr
.step_by
= 0x0101;
2907 switch (besr
.surf_id
)
2912 besr
.h_inc
= (h_inc
)|(h_inc
<<16);
2915 besr
.h_inc
= h_inc
| ((h_inc
>> 2) << 16);
2918 besr
.h_inc
= h_inc
| ((h_inc
>> 1) << 16);
2923 P23GroupSize
= 2; /* Current vaue for all modes */
2925 besr
.horz_pick_nearest
=0;
2926 DoNotUseMostRecentlyFetchedLine
=0;
2927 ThereIsTwoTapVerticalFiltering
= (val_OV0_P1_H_STEP_BY
!=0) || (val_OV0_P23_H_STEP_BY
!=0);
2928 if (ThereIsTwoTapVerticalFiltering
&& DoNotUseMostRecentlyFetchedLine
)
2929 besr
.vert_pick_nearest
= 1;
2931 besr
.vert_pick_nearest
= 0;
2933 ComputeXStartEnd(is_400
,LeftPixel
,LeftUVPixel
,MemWordsInBytes
,BytesPerPixel
,
2934 SourceWidthInPixels
,P1StepSize
,BytesPerUVPixel
,
2935 SourceUVWidthInPixels
,P23StepSize
,&val_OV0_P1_X_START
,&val_OV0_P2_X_START
);
2937 if(H_scale_ratio
> MinHScaleHard
)
2940 tmp
= (left
& 0x0003ffff) + 0x00028000 + (h_inc
<< 3);
2941 besr
.p1_h_accum_init
= ((tmp
<< 4) & 0x000f8000) |
2942 ((tmp
<< 12) & 0xf0000000);
2944 tmp
= (top
& 0x0000ffff) + 0x00018000;
2945 besr
.p1_v_accum_init
= ((tmp
<< 4) & OV0_P1_V_ACCUM_INIT_MASK
)
2946 |(OV0_P1_MAX_LN_IN_PER_LN_OUT
& 1);
2947 tmp
= ((left
>> 1) & 0x0001ffff) + 0x00028000 + (h_inc
<< 2);
2948 besr
.p23_h_accum_init
= ((tmp
<< 4) & 0x000f8000) |
2949 ((tmp
<< 12) & 0x70000000);
2951 tmp
= ((top
>> 1) & 0x0000ffff) + 0x00018000;
2952 besr
.p23_v_accum_init
= (is_420
||is_410
) ?
2953 ((tmp
<< 4) & OV0_P23_V_ACCUM_INIT_MASK
)
2954 |(OV0_P23_MAX_LN_IN_PER_LN_OUT
& 1) : 0;
2957 ComputeAccumInit( val_OV0_P1_X_START
,val_OV0_P2_X_START
,
2958 val_OV0_P1_H_INC
,val_OV0_P23_H_INC
,
2959 val_OV0_P1_H_STEP_BY
,val_OV0_P23_H_STEP_BY
,
2960 CRT_V_INC
,P1GroupSize
,P23GroupSize
,
2961 val_OV0_P1_MAX_LN_IN_PER_LN_OUT
,
2962 val_OV0_P23_MAX_LN_IN_PER_LN_OUT
);
2965 /* keep everything in 16.16 */
2966 besr
.base_addr
= INREG(DISPLAY_BASE_ADDR
);
2967 config
->offsets
[0] = 0;
2968 for(i
=1;i
<besr
.vid_nbufs
;i
++)
2969 config
->offsets
[i
] = config
->offsets
[i
-1]+config
->frame_size
;
2970 if(is_420
|| is_410
|| is_400
)
2972 uint32_t d1line
,d2line
,d3line
;
2976 d2line
= src_h
*pitch
+(d1line
>>2);
2977 d3line
= d2line
+((src_h
*pitch
)>>2);
2982 d2line
= src_h
*pitch
+(d1line
>>4);
2983 d3line
= d2line
+((src_h
*pitch
)>>4);
2990 d1line
+= (left
>> 16) & ~15;
2993 d2line
+= (left
>> 17) & ~15;
2994 d3line
+= (left
>> 17) & ~15;
2998 d2line
+= (left
>> 18) & ~15;
2999 d3line
+= (left
>> 18) & ~15;
3001 config
->offset
.y
= d1line
& VIF_BUF0_BASE_ADRS_MASK
;
3004 config
->offset
.v
= 0;
3005 config
->offset
.u
= 0;
3009 config
->offset
.v
= d2line
& VIF_BUF1_BASE_ADRS_MASK
;
3010 config
->offset
.u
= d3line
& VIF_BUF2_BASE_ADRS_MASK
;
3012 for(i
=0;i
<besr
.vid_nbufs
;i
++)
3014 besr
.vid_buf_base_adrs_y
[i
]=((radeon_overlay_off
+config
->offsets
[i
]+config
->offset
.y
)&VIF_BUF0_BASE_ADRS_MASK
);
3017 besr
.vid_buf_base_adrs_v
[i
]=0;
3018 besr
.vid_buf_base_adrs_u
[i
]=0;
3022 if (besr
.fourcc
== IMGFMT_I420
|| besr
.fourcc
== IMGFMT_IYUV
)
3024 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
;
3025 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
;
3029 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
;
3030 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
;
3034 config
->offset
.y
= ((besr
.vid_buf_base_adrs_y
[0])&VIF_BUF0_BASE_ADRS_MASK
) - radeon_overlay_off
;
3037 config
->offset
.v
= 0;
3038 config
->offset
.u
= 0;
3042 config
->offset
.v
= ((besr
.vid_buf_base_adrs_v
[0])&VIF_BUF1_BASE_ADRS_MASK
) - radeon_overlay_off
;
3043 config
->offset
.u
= ((besr
.vid_buf_base_adrs_u
[0])&VIF_BUF2_BASE_ADRS_MASK
) - radeon_overlay_off
;
3048 config
->offset
.y
= config
->offset
.u
= config
->offset
.v
= ((left
& ~7) << 1)&VIF_BUF0_BASE_ADRS_MASK
;
3049 for(i
=0;i
<besr
.vid_nbufs
;i
++)
3051 besr
.vid_buf_base_adrs_y
[i
] =
3052 besr
.vid_buf_base_adrs_u
[i
] =
3053 besr
.vid_buf_base_adrs_v
[i
] = radeon_overlay_off
+ config
->offsets
[i
] + config
->offset
.y
;
3056 leftUV
= (left
>> (is_410
?18:17)) & 15;
3057 left
= (left
>> 16) & 15;
3058 besr
.y_x_start
= (config
->dest
.x
+X_ADJUST
) | (config
->dest
.y
<< 16);
3059 besr
.y_x_end
= (config
->dest
.x
+ dest_w
+X_ADJUST
) | ((config
->dest
.y
+ dest_h
) << 16);
3060 ComputeBorders(config
,VertUVSubSample
);
3061 besr
.vid_buf_pitch0_value
= pitch
;
3062 besr
.vid_buf_pitch1_value
= is_410
? pitch
>>2 : is_420
? pitch
>>1 : pitch
;
3063 /* ********************************************************* */
3064 /* ** Calculate programmable coefficients as needed */
3065 /* ********************************************************* */
3067 /* ToDo_Active: When in pick nearest mode, we need to program the filter tap zero */
3068 /* coefficients to 0, 32, 0, 0. Or use hard coded coefficients. */
3069 if(H_scale_ratio
> MinHScaleHard
) besr
.filter_cntl
|= FILTER_HARDCODED_COEF
;
3072 FilterSetup (val_OV0_P1_H_INC
);
3073 /* ToDo_Active: Must add the smarts into the driver to decide what type of filtering it */
3074 /* would like to do. For now, we let the test application decide. */
3075 besr
.filter_cntl
= FILTER_PROGRAMMABLE_COEF
;
3076 if(DisallowFourTapVertFiltering
)
3077 besr
.filter_cntl
|= FILTER_HARD_SCALE_VERT_Y
;
3078 if(DisallowFourTapUVVertFiltering
)
3079 besr
.filter_cntl
|= FILTER_HARD_SCALE_VERT_UV
;
3084 static void radeon_compute_framesize(vidix_playback_t
*info
)
3086 unsigned pitch
,awidth
,dbpp
;
3087 pitch
= radeon_query_pitch(info
->fourcc
,&info
->src
.pitch
);
3088 dbpp
= radeon_vid_get_dbpp();
3089 switch(info
->fourcc
)
3092 awidth
= (info
->src
.w
+ (pitch
-1)) & ~(pitch
-1);
3093 info
->frame_size
= awidth
*info
->src
.h
;
3097 awidth
= (info
->src
.w
+ (pitch
-1)) & ~(pitch
-1);
3098 info
->frame_size
= awidth
*(info
->src
.h
+info
->src
.h
/8);
3103 awidth
= (info
->src
.w
+ (pitch
-1)) & ~(pitch
-1);
3104 info
->frame_size
= awidth
*(info
->src
.h
+info
->src
.h
/2);
3108 awidth
= (info
->src
.w
*4 + (pitch
-1)) & ~(pitch
-1);
3109 info
->frame_size
= awidth
*info
->src
.h
;
3111 /* YUY2 YVYU, RGB15, RGB16 */
3113 awidth
= (info
->src
.w
*2 + (pitch
-1)) & ~(pitch
-1);
3114 info
->frame_size
= awidth
*info
->src
.h
;
3117 info
->frame_size
= (info
->frame_size
+4095)&~4095;
3120 static int radeon_config_playback(vidix_playback_t
*info
)
3122 unsigned rgb_size
,nfr
;
3123 uint32_t radeon_video_size
;
3124 if(!is_supported_fourcc(info
->fourcc
)) return ENOSYS
;
3125 if(info
->num_frames
>VID_PLAY_MAXFRAMES
) info
->num_frames
=VID_PLAY_MAXFRAMES
;
3126 if(info
->num_frames
==1) besr
.double_buff
=0;
3127 else besr
.double_buff
=1;
3128 radeon_compute_framesize(info
);
3130 rgb_size
= radeon_get_xres()*radeon_get_yres()*((radeon_vid_get_dbpp()+7)/8);
3131 nfr
= info
->num_frames
;
3132 radeon_video_size
= radeon_ram_size
;
3135 radeon_overlay_off
= radeon_video_size
- info
->frame_size
*nfr
;
3136 #if !defined (RAGE128) && defined(CONFIG_X11)
3137 radeon_overlay_off
-= firegl_shift
;
3139 radeon_overlay_off
&= 0xffff0000;
3140 if(radeon_overlay_off
>= (int)rgb_size
) break;
3144 nfr
= info
->num_frames
;
3147 radeon_overlay_off
= radeon_video_size
- info
->frame_size
*nfr
;
3148 #if !defined (RAGE128) && defined(CONFIG_X11)
3149 radeon_overlay_off
-= firegl_shift
;
3151 radeon_overlay_off
&= 0xffff0000;
3152 if(radeon_overlay_off
> 0) break;
3155 if(nfr
<= 0) return EINVAL
;
3156 info
->num_frames
= nfr
;
3157 besr
.vid_nbufs
= info
->num_frames
;
3158 info
->dga_addr
= (char *)radeon_mem_base
+ radeon_overlay_off
;
3159 radeon_vid_init_video(info
);
3163 static int radeon_playback_on(void)
3168 radeon_vid_display_video();
3170 dh
= (besr
.y_x_end
>> 16) - (besr
.y_x_start
>> 16);
3171 dw
= (besr
.y_x_end
& 0xFFFF) - (besr
.y_x_start
& 0xFFFF);
3172 if(dw
== radeon_get_xres() || dh
== radeon_get_yres()) radeon_vid_exclusive();
3173 else radeon_vid_non_exclusive();
3178 static int radeon_playback_off(void)
3180 radeon_vid_stop_video();
3184 static int radeon_frame_select(unsigned frame
)
3187 int prev_frame
= (frame
-1+besr
.vid_nbufs
) % besr
.vid_nbufs
;
3188 // This really only needs to be set during data writes,
3189 // however we don't have a hook there.
3190 // The setup at startup is not enough since X11 regularly
3191 // resets this to values to the wrong values for us.
3194 buf3-5 always should point onto second buffer for better
3195 deinterlacing and TV-in
3197 if(!besr
.double_buff
) return 0;
3198 if(frame
> besr
.vid_nbufs
) frame
= besr
.vid_nbufs
-1;
3199 if(prev_frame
> (int)besr
.vid_nbufs
) prev_frame
= besr
.vid_nbufs
-1;
3200 off
[0] = besr
.vid_buf_base_adrs_y
[frame
];
3201 off
[1] = besr
.vid_buf_base_adrs_v
[frame
];
3202 off
[2] = besr
.vid_buf_base_adrs_u
[frame
];
3203 off
[3] = besr
.vid_buf_base_adrs_y
[prev_frame
];
3204 off
[4] = besr
.vid_buf_base_adrs_v
[prev_frame
];
3205 off
[5] = besr
.vid_buf_base_adrs_u
[prev_frame
];
3206 radeon_fifo_wait(8);
3207 OUTREG(OV0_REG_LOAD_CNTL
, REG_LD_CTL_LOCK
);
3208 radeon_engine_idle();
3209 while(!(INREG(OV0_REG_LOAD_CNTL
)®_LD_CTL_LOCK_READBACK
));
3210 OUTREG(OV0_VID_BUF0_BASE_ADRS
, off
[0]);
3211 OUTREG(OV0_VID_BUF1_BASE_ADRS
, off
[1]);
3212 OUTREG(OV0_VID_BUF2_BASE_ADRS
, off
[2]);
3213 OUTREG(OV0_VID_BUF3_BASE_ADRS
, off
[3]);
3214 OUTREG(OV0_VID_BUF4_BASE_ADRS
, off
[4]);
3215 OUTREG(OV0_VID_BUF5_BASE_ADRS
, off
[5]);
3216 OUTREG(OV0_REG_LOAD_CNTL
, 0);
3217 if(besr
.vid_nbufs
== 2) radeon_wait_vsync();
3218 if(verbosity
> VERBOSE_LEVEL
) radeon_vid_dump_regs();
3222 static vidix_video_eq_t equal
=
3224 VEQ_CAP_BRIGHTNESS
| VEQ_CAP_SATURATION
3226 | VEQ_CAP_CONTRAST
| VEQ_CAP_HUE
| VEQ_CAP_RGB_INTENSITY
3229 0, 0, 0, 0, 0, 0, 0, 0 };
3231 static int radeon_get_eq(vidix_video_eq_t
* eq
)
3233 memcpy(eq
,&equal
,sizeof(vidix_video_eq_t
));
3238 #define RTFSaturation(a) (1.0 + ((a)*1.0)/1000.0)
3239 #define RTFBrightness(a) (((a)*1.0)/2000.0)
3240 #define RTFIntensity(a) (((a)*1.0)/2000.0)
3241 #define RTFContrast(a) (1.0 + ((a)*1.0)/1000.0)
3242 #define RTFHue(a) (((a)*3.1416)/1000.0)
3243 #define RTFCheckParam(a) {if((a)<-1000) (a)=-1000; if((a)>1000) (a)=1000;}
3246 static int radeon_set_eq(const vidix_video_eq_t
* eq
)
3253 if(eq
->cap
& VEQ_CAP_BRIGHTNESS
) equal
.brightness
= eq
->brightness
;
3254 if(eq
->cap
& VEQ_CAP_CONTRAST
) equal
.contrast
= eq
->contrast
;
3255 if(eq
->cap
& VEQ_CAP_SATURATION
) equal
.saturation
= eq
->saturation
;
3256 if(eq
->cap
& VEQ_CAP_HUE
) equal
.hue
= eq
->hue
;
3257 if(eq
->cap
& VEQ_CAP_RGB_INTENSITY
)
3259 equal
.red_intensity
= eq
->red_intensity
;
3260 equal
.green_intensity
= eq
->green_intensity
;
3261 equal
.blue_intensity
= eq
->blue_intensity
;
3263 equal
.flags
= eq
->flags
;
3265 br
= equal
.brightness
* 64 / 1000;
3266 if(br
< -64) br
= -64; if(br
> 63) br
= 63;
3267 sat
= (equal
.saturation
*31 + 31000) / 2000;
3268 if(sat
< 0) sat
= 0; if(sat
> 31) sat
= 31;
3269 OUTREG(OV0_COLOUR_CNTL
, (br
& 0x7f) | (sat
<< 8) | (sat
<< 16));
3271 itu_space
= equal
.flags
== VEQ_FLG_ITU_R_BT_709
? 1 : 0;
3272 RTFCheckParam(equal
.brightness
);
3273 RTFCheckParam(equal
.saturation
);
3274 RTFCheckParam(equal
.contrast
);
3275 RTFCheckParam(equal
.hue
);
3276 RTFCheckParam(equal
.red_intensity
);
3277 RTFCheckParam(equal
.green_intensity
);
3278 RTFCheckParam(equal
.blue_intensity
);
3279 radeon_set_transform(RTFBrightness(equal
.brightness
),
3280 RTFContrast(equal
.contrast
),
3281 RTFSaturation(equal
.saturation
),
3283 RTFIntensity(equal
.red_intensity
),
3284 RTFIntensity(equal
.green_intensity
),
3285 RTFIntensity(equal
.blue_intensity
),
3291 static int radeon_playback_set_deint(const vidix_deinterlace_t
* info
)
3297 case CFG_NON_INTERLACED
:
3298 besr
.deinterlace_on
= 0;
3300 case CFG_EVEN_ODD_INTERLACING
:
3301 case CFG_INTERLACED
:
3302 besr
.deinterlace_on
= 1;
3303 besr
.deinterlace_pattern
= 0x900AAAAA;
3305 case CFG_ODD_EVEN_INTERLACING
:
3306 besr
.deinterlace_on
= 1;
3307 besr
.deinterlace_pattern
= 0x00055555;
3309 case CFG_UNIQUE_INTERLACING
:
3310 besr
.deinterlace_on
= 1;
3311 besr
.deinterlace_pattern
= info
->deinterlace_pattern
;
3314 OUTREG(OV0_REG_LOAD_CNTL
, REG_LD_CTL_LOCK
);
3315 radeon_engine_idle();
3316 while(!(INREG(OV0_REG_LOAD_CNTL
)®_LD_CTL_LOCK_READBACK
));
3317 radeon_fifo_wait(15);
3318 sflg
= INREG(OV0_SCALE_CNTL
);
3319 if(besr
.deinterlace_on
)
3321 OUTREG(OV0_SCALE_CNTL
,sflg
| SCALER_ADAPTIVE_DEINT
);
3322 OUTREG(OV0_DEINTERLACE_PATTERN
,besr
.deinterlace_pattern
);
3324 else OUTREG(OV0_SCALE_CNTL
,sflg
& (~SCALER_ADAPTIVE_DEINT
));
3325 OUTREG(OV0_REG_LOAD_CNTL
, 0);
3329 static int radeon_playback_get_deint(vidix_deinterlace_t
* info
)
3331 if(!besr
.deinterlace_on
) info
->flags
= CFG_NON_INTERLACED
;
3334 info
->flags
= CFG_UNIQUE_INTERLACING
;
3335 info
->deinterlace_pattern
= besr
.deinterlace_pattern
;
3342 static vidix_grkey_t radeon_grkey
;
3344 static int set_gr_key( void )
3348 besr
.merge_cntl
= 0xff000000 | /* overlay alpha */
3349 0x00ff0000; /* graphic alpha */
3350 if(radeon_grkey
.ckey
.op
== CKEY_TRUE
)
3352 int dbpp
=radeon_vid_get_dbpp();
3359 if((besr
.chip_flags
&R_100
)!=R_100
)
3360 besr
.graphics_key_clr
=
3361 ((radeon_grkey
.ckey
.blue
&0xF8))
3362 | ((radeon_grkey
.ckey
.green
&0xF8)<<8)
3363 | ((radeon_grkey
.ckey
.red
&0xF8)<<16);
3366 besr
.graphics_key_clr
=
3367 ((radeon_grkey
.ckey
.blue
&0xF8)>>3)
3368 | ((radeon_grkey
.ckey
.green
&0xF8)<<2)
3369 | ((radeon_grkey
.ckey
.red
&0xF8)<<7);
3373 /* This test may be too general/specific */
3374 if((besr
.chip_flags
&R_100
)!=R_100
)
3375 besr
.graphics_key_clr
=
3376 ((radeon_grkey
.ckey
.blue
&0xF8))
3377 | ((radeon_grkey
.ckey
.green
&0xFC)<<8)
3378 | ((radeon_grkey
.ckey
.red
&0xF8)<<16);
3381 besr
.graphics_key_clr
=
3382 ((radeon_grkey
.ckey
.blue
&0xF8)>>3)
3383 | ((radeon_grkey
.ckey
.green
&0xFC)<<3)
3384 | ((radeon_grkey
.ckey
.red
&0xF8)<<8);
3388 besr
.graphics_key_clr
=
3389 ((radeon_grkey
.ckey
.blue
&0xFF))
3390 | ((radeon_grkey
.ckey
.green
&0xFF)<<8)
3391 | ((radeon_grkey
.ckey
.red
&0xFF)<<16);
3395 besr
.graphics_key_msk
=0;
3396 besr
.graphics_key_clr
=0;
3399 besr
.graphics_key_msk
=(1<<dbpp
)-1;
3400 besr
.ckey_cntl
= VIDEO_KEY_FN_TRUE
|GRAPHIC_KEY_FN_NE
|CMP_MIX_AND
;
3402 besr
.graphics_key_msk
=besr
.graphics_key_clr
;
3403 besr
.ckey_cntl
= VIDEO_KEY_FN_TRUE
|CMP_MIX_AND
|GRAPHIC_KEY_FN_EQ
;
3406 else if(radeon_grkey
.ckey
.op
== CKEY_ALPHA
)
3408 int dbpp
=radeon_vid_get_dbpp();
3415 besr
.graphics_key_msk
=0;
3416 besr
.graphics_key_clr
=0;
3417 besr
.ckey_cntl
= VIDEO_KEY_FN_TRUE
|GRAPHIC_KEY_FN_TRUE
|CMP_MIX_AND
;
3418 besr
.merge_cntl
|= 0x00000001; /* DISP_ALPHA_MODE_PER_PIXEL */
3422 besr
.graphics_key_msk
=0;
3423 besr
.graphics_key_clr
=0;
3424 besr
.ckey_cntl
= VIDEO_KEY_FN_TRUE
|GRAPHIC_KEY_FN_TRUE
|CMP_MIX_AND
;
3431 besr
.graphics_key_msk
=0;
3432 besr
.graphics_key_clr
=0;
3433 besr
.ckey_cntl
= VIDEO_KEY_FN_TRUE
|GRAPHIC_KEY_FN_TRUE
|CMP_MIX_AND
;
3434 besr
.merge_cntl
|= 0x00000100; /* DISP_RGB_OFFSET_EN */
3436 radeon_fifo_wait(3);
3437 OUTREG(OV0_GRAPHICS_KEY_MSK
, besr
.graphics_key_msk
);
3438 OUTREG(OV0_GRAPHICS_KEY_CLR
, besr
.graphics_key_clr
);
3439 OUTREG(OV0_KEY_CNTL
,besr
.ckey_cntl
);
3440 OUTREG(DISP_MERGE_CNTL
, besr
.merge_cntl
);
3444 static int radeon_get_gkey(vidix_grkey_t
*grkey
)
3446 memcpy(grkey
, &radeon_grkey
, sizeof(vidix_grkey_t
));
3450 static int radeon_set_gkey(const vidix_grkey_t
*grkey
)
3452 memcpy(&radeon_grkey
, grkey
, sizeof(vidix_grkey_t
));
3453 return set_gr_key();
3457 VDXDriver rage128_drv
= {
3460 VDXDriver radeon_drv
= {
3465 .probe
= radeon_probe
,
3466 .get_caps
= radeon_get_caps
,
3467 .query_fourcc
= radeon_query_fourcc
,
3468 .init
= radeon_init
,
3469 .destroy
= radeon_destroy
,
3470 .config_playback
= radeon_config_playback
,
3471 .playback_on
= radeon_playback_on
,
3472 .playback_off
= radeon_playback_off
,
3473 .frame_sel
= radeon_frame_select
,
3474 .get_eq
= radeon_get_eq
,
3475 .set_eq
= radeon_set_eq
,
3476 .get_deint
= radeon_playback_get_deint
,
3477 .set_deint
= radeon_playback_set_deint
,
3478 .get_gkey
= radeon_get_gkey
,
3479 .set_gkey
= radeon_set_gkey
,