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 { DEVICE_ATI_RV280_RADEON_9200
, R_280
},
398 { DEVICE_ATI_RV280_RADEON_92002
, R_280
},
399 { DEVICE_ATI_RV280_RADEON_92003
, R_280
},
400 { DEVICE_ATI_RV280_RADEON_92004
, R_280
},
401 { DEVICE_ATI_RV280_RADEON_92005
, R_280
},
402 { DEVICE_ATI_RV280_RADEON_92006
, R_280
},
403 { DEVICE_ATI_RV280_RADEON_92007
, R_280
},
404 { DEVICE_ATI_M9_5C61_RADEON
, R_280
},
405 { DEVICE_ATI_M9_5C63_RADEON
, R_280
},
406 /* Radeon3 (indeed: Rage 1024 Pro ;) */
407 { DEVICE_ATI_R300_AG_FIREGL
, R_300
},
408 { DEVICE_ATI_RADEON_R300_ND
, R_300
},
409 { DEVICE_ATI_RADEON_R300_NE
, R_300
},
410 { DEVICE_ATI_RADEON_R300_NG
, R_300
},
411 { DEVICE_ATI_R300_AD_RADEON
, R_300
},
412 { DEVICE_ATI_R300_AE_RADEON
, R_300
},
413 { DEVICE_ATI_R300_AF_RADEON
, R_300
},
414 { DEVICE_ATI_RADEON_9100_IGP2
, R_300
|R_OVL_SHIFT
|R_INTEGRATED
},
415 { DEVICE_ATI_RS300M_AGP_RADEON
, R_300
|R_INTEGRATED
},
416 { DEVICE_ATI_RS482_RADEON_XPRESS
, R_350
|R_INTEGRATED
},
417 { DEVICE_ATI_R350_AH_RADEON
, R_350
},
418 { DEVICE_ATI_R350_AI_RADEON
, R_350
},
419 { DEVICE_ATI_R350_AJ_RADEON
, R_350
},
420 { DEVICE_ATI_R350_AK_FIRE
, R_350
},
421 { DEVICE_ATI_RADEON_R350_RADEON2
, R_350
},
422 { DEVICE_ATI_RADEON_R350_RADEON3
, R_350
},
423 { DEVICE_ATI_RV350_NJ_RADEON
, R_350
},
424 { DEVICE_ATI_R350_NK_FIRE
, R_350
},
425 { DEVICE_ATI_RV350_AP_RADEON
, R_350
},
426 { DEVICE_ATI_RV350_AQ_RADEON
, R_350
},
427 { DEVICE_ATI_RV350_AR_RADEON
, R_350
},
428 { DEVICE_ATI_RV350_AS_RADEON
, R_350
},
429 { DEVICE_ATI_RV350_AT_FIRE
, R_350
},
430 { DEVICE_ATI_RV350_AU_FIRE
, R_350
},
431 { DEVICE_ATI_RV350_AV_FIRE
, R_350
},
432 { DEVICE_ATI_RV350_AW_FIRE
, R_350
},
433 { DEVICE_ATI_RV350_MOBILITY_RADEON
, R_350
},
434 { DEVICE_ATI_RV350_NF_RADEON
, R_300
},
435 { DEVICE_ATI_RV350_NJ_RADEON
, R_300
},
436 { DEVICE_ATI_RV350_AS_RADEON2
, R_350
},
437 { DEVICE_ATI_M10_NQ_RADEON
, R_350
},
438 { DEVICE_ATI_M10_NQ_RADEON2
, R_350
},
439 { DEVICE_ATI_RV350_MOBILITY_RADEON2
, R_350
},
440 { DEVICE_ATI_M10_NS_RADEON
, R_350
},
441 { DEVICE_ATI_M10_NT_FIREGL
, R_350
},
442 { DEVICE_ATI_M11_NV_FIREGL
, R_350
},
443 { DEVICE_ATI_RV370_5B60_RADEON
, R_370
|R_PCIE
},
444 { DEVICE_ATI_RV370_SAPPHIRE_X550
, R_370
},
445 { DEVICE_ATI_RV370_5B64_FIREGL
, R_370
|R_PCIE
},
446 { DEVICE_ATI_RV370_5B65_FIREGL
, R_370
|R_PCIE
},
447 { DEVICE_ATI_M24_1P_RADEON
, R_370
},
448 { DEVICE_ATI_M22_RADEON_MOBILITY
, R_370
},
449 { DEVICE_ATI_M24_1T_FIREGL
, R_370
},
450 { DEVICE_ATI_M24_RADEON_MOBILITY
, R_370
},
451 { DEVICE_ATI_RV370_RADEON_X300SE
, R_370
},
452 { DEVICE_ATI_RV370_SECONDARY_SAPPHIRE
, R_370
},
453 { DEVICE_ATI_RV370_5B64_FIREGL2
, R_370
},
454 { DEVICE_ATI_RV380_0X3E50_RADEON
, R_380
|R_PCIE
},
455 { DEVICE_ATI_RV380_0X3E54_FIREGL
, R_380
|R_PCIE
},
456 { DEVICE_ATI_RV380_RADEON_X600
, R_380
|R_PCIE
},
457 { DEVICE_ATI_RV380_RADEON_X6002
, R_380
},
458 { DEVICE_ATI_RV380_RADEON_X6003
, R_380
},
459 { DEVICE_ATI_RV410_FIREGL_V5000
, R_420
},
460 { DEVICE_ATI_RV410_FIREGL_V3300
, R_420
},
461 { DEVICE_ATI_RV410_RADEON_X700XT
, R_420
},
462 { DEVICE_ATI_RV410_RADEON_X700
, R_420
|R_PCIE
},
463 { DEVICE_ATI_RV410_RADEON_X700SE
, R_420
},
464 { DEVICE_ATI_RV410_RADEON_X7002
, R_420
|R_PCIE
},
465 { DEVICE_ATI_RV410_RADEON_X7003
, R_420
},
466 { DEVICE_ATI_RV410_RADEON_X7004
, R_420
|R_PCIE
},
467 { DEVICE_ATI_RV410_RADEON_X7005
, R_420
|R_PCIE
},
468 { DEVICE_ATI_M26_MOBILITY_FIREGL
, R_420
},
469 { DEVICE_ATI_M26_MOBILITY_FIREGL2
, R_420
},
470 { DEVICE_ATI_M26_RADEON_MOBILITY
, R_420
},
471 { DEVICE_ATI_M26_RADEON_MOBILITY2
, R_420
},
472 { DEVICE_ATI_RADEON_MOBILITY_X700
, R_420
},
473 { DEVICE_ATI_R420_JH_RADEON
, R_420
|R_PCIE
},
474 { DEVICE_ATI_R420_JI_RADEON
, R_420
|R_PCIE
},
475 { DEVICE_ATI_R420_JJ_RADEON
, R_420
|R_PCIE
},
476 { DEVICE_ATI_R420_JK_RADEON
, R_420
|R_PCIE
},
477 { DEVICE_ATI_R420_JL_RADEON
, R_420
|R_PCIE
},
478 { DEVICE_ATI_R420_JM_FIREGL
, R_420
|R_PCIE
},
479 { DEVICE_ATI_M18_JN_RADEON
, R_420
|R_PCIE
},
480 { DEVICE_ATI_R420_JP_RADEON
, R_420
|R_PCIE
},
481 { DEVICE_ATI_R420_RADEON_X800
, R_420
|R_PCIE
},
482 { DEVICE_ATI_R420_RADEON_X8002
, R_420
|R_PCIE
},
483 { DEVICE_ATI_R420_RADEON_X8003
, R_420
|R_PCIE
},
484 { DEVICE_ATI_R420_RADEON_X8004
, R_420
|R_PCIE
},
485 { DEVICE_ATI_R420_RADEON_X8005
, R_420
|R_PCIE
},
486 { DEVICE_ATI_R420_JM_FIREGL
, R_420
|R_PCIE
},
487 { DEVICE_ATI_R423_5F57_RADEON
, R_420
|R_PCIE
},
488 { DEVICE_ATI_R423_5F57_RADEON2
, R_420
|R_PCIE
},
489 { DEVICE_ATI_R423_UH_RADEON
, R_420
|R_PCIE
},
490 { DEVICE_ATI_R423_UI_RADEON
, R_420
|R_PCIE
},
491 { DEVICE_ATI_R423_UJ_RADEON
, R_420
|R_PCIE
},
492 { DEVICE_ATI_R423_UK_RADEON
, R_420
|R_PCIE
},
493 { DEVICE_ATI_R423_FIRE_GL
, R_420
|R_PCIE
},
494 { DEVICE_ATI_R423_UQ_FIREGL
, R_420
|R_PCIE
},
495 { DEVICE_ATI_R423_UR_FIREGL
, R_420
|R_PCIE
},
496 { DEVICE_ATI_R423_UT_FIREGL
, R_420
|R_PCIE
},
497 { DEVICE_ATI_R423_UI_RADEON2
, R_420
|R_PCIE
},
498 { DEVICE_ATI_R423GL_SE_ATI_FIREGL
, R_420
|R_PCIE
},
499 { DEVICE_ATI_R423_RADEON_X800XT
, R_420
|R_PCIE
},
500 { DEVICE_ATI_RADEON_R423_UK
, R_420
|R_PCIE
},
501 { DEVICE_ATI_M28_RADEON_MOBILITY
, R_420
},
502 { DEVICE_ATI_M28_MOBILITY_FIREGL
, R_420
},
503 { DEVICE_ATI_MOBILITY_RADEON_X800
, R_420
},
504 { DEVICE_ATI_R430_RADEON_X800
, R_430
|R_PCIE
},
505 { DEVICE_ATI_R430_RADEON_X8002
, R_430
|R_PCIE
},
506 { DEVICE_ATI_R430_RADEON_X8003
, R_430
|R_PCIE
},
507 { DEVICE_ATI_R430_RADEON_X8004
, R_430
|R_PCIE
},
508 { DEVICE_ATI_R480_RADEON_X800
, R_480
},
509 { DEVICE_ATI_R480_RADEON_X8002
, R_480
},
510 { DEVICE_ATI_R480_RADEON_X850XT
, R_480
},
511 { DEVICE_ATI_R480_RADEON_X850PRO
, R_480
},
512 { DEVICE_ATI_R481_RADEON_X850XT_PE
, R_480
|R_PCIE
},
513 { DEVICE_ATI_R480_RADEON_X850XT2
, R_480
},
514 { DEVICE_ATI_R480_RADEON_X850PRO2
, R_480
},
515 { DEVICE_ATI_R481_RADEON_X850XT_PE2
, R_480
|R_PCIE
},
516 { DEVICE_ATI_R480_RADEON_X850XT3
, R_480
|R_PCIE
},
517 { DEVICE_ATI_R480_RADEON_X850XT4
, R_480
|R_PCIE
},
518 { DEVICE_ATI_R480_RADEON_X850XT5
, R_480
|R_PCIE
},
519 { DEVICE_ATI_R480_RADEON_X850XT6
, R_480
|R_PCIE
},
524 static void * radeon_mmio_base
= 0;
525 static void * radeon_mem_base
= 0;
526 static int32_t radeon_overlay_off
= 0;
527 static uint32_t radeon_ram_size
= 0;
529 #define GETREG(TYPE,PTR,OFFZ) (*((volatile TYPE*)((PTR)+(OFFZ))))
530 #define SETREG(TYPE,PTR,OFFZ,VAL) (*((volatile TYPE*)((PTR)+(OFFZ))))=VAL
532 #define INREG8(addr) GETREG(uint8_t,(uint8_t *)(radeon_mmio_base),addr)
533 #define OUTREG8(addr,val) SETREG(uint8_t,(uint8_t *)(radeon_mmio_base),addr,val)
534 static inline uint32_t INREG (uint32_t addr
) {
535 uint32_t tmp
= GETREG(uint32_t,(uint8_t *)(radeon_mmio_base
),addr
);
536 return le2me_32(tmp
);
538 #define OUTREG(addr,val) SETREG(uint32_t,(uint8_t *)(radeon_mmio_base),addr,le2me_32(val))
539 #define OUTREGP(addr,val,mask) \
541 unsigned int _tmp = INREG(addr); \
544 OUTREG(addr, _tmp); \
547 static __inline__
uint32_t INPLL(uint32_t addr
)
549 OUTREG8(CLOCK_CNTL_INDEX
, addr
& 0x0000001f);
550 return INREG(CLOCK_CNTL_DATA
);
553 #define OUTPLL(addr,val) OUTREG8(CLOCK_CNTL_INDEX, (addr & 0x0000001f) | 0x00000080); \
554 OUTREG(CLOCK_CNTL_DATA, val)
555 #define OUTPLLP(addr,val,mask) \
557 unsigned int _tmp = INPLL(addr); \
560 OUTPLL(addr, _tmp); \
567 MT_CRT
, /* CRT-(cathode ray tube) analog monitor. (15-pin VGA connector) */
568 MT_LCD
, /* Liquid Crystal Display */
569 MT_DFP
, /* DFP-digital flat panel monitor. (24-pin DVI-I connector) */
570 MT_CTV
, /* Composite TV out (not in VE) */
571 MT_STV
/* S-Video TV out (probably in VE only) */
574 typedef struct radeon_info_s
581 static rinfo_t rinfo
;
583 static char * GET_MON_NAME(int type
)
588 case MT_NONE
: pret
= "no"; break;
589 case MT_CRT
: pret
= "CRT"; break;
590 case MT_DFP
: pret
= "DFP"; break;
591 case MT_LCD
: pret
= "LCD"; break;
592 case MT_CTV
: pret
= "CTV"; break;
593 case MT_STV
: pret
= "STV"; break;
594 default: pret
= "Unknown";
599 static void radeon_get_moninfo (rinfo_t
*rinfo
)
603 tmp
= INREG(RADEON_BIOS_4_SCRATCH
);
605 if (rinfo
->hasCRTC2
) {
606 /* primary DVI port */
608 rinfo
->dviDispType
= MT_DFP
;
610 rinfo
->dviDispType
= MT_LCD
;
611 else if (tmp
& 0x200)
612 rinfo
->dviDispType
= MT_CRT
;
614 rinfo
->dviDispType
= MT_CTV
;
616 rinfo
->dviDispType
= MT_STV
;
618 /* secondary CRT port */
620 rinfo
->crtDispType
= MT_CRT
;
621 else if (tmp
& 0x800)
622 rinfo
->crtDispType
= MT_DFP
;
623 else if (tmp
& 0x400)
624 rinfo
->crtDispType
= MT_LCD
;
625 else if (tmp
& 0x1000)
626 rinfo
->crtDispType
= MT_CTV
;
627 else if (tmp
& 0x2000)
628 rinfo
->crtDispType
= MT_STV
;
630 rinfo
->dviDispType
= MT_NONE
;
632 tmp
= INREG(FP_GEN_CNTL
);
634 if (tmp
& FP_EN_TMDS
)
635 rinfo
->crtDispType
= MT_DFP
;
637 rinfo
->crtDispType
= MT_CRT
;
642 static uint32_t radeon_vid_get_dbpp( void )
644 uint32_t dbpp
,retval
;
645 dbpp
= (INREG(CRTC_GEN_CNTL
)>>8)& 0xF;
648 case DST_8BPP
: retval
= 8; break;
649 case DST_15BPP
: retval
= 15; break;
650 case DST_16BPP
: retval
= 16; break;
651 case DST_24BPP
: retval
= 24; break;
652 default: retval
=32; break;
657 static int radeon_is_dbl_scan( void )
659 return (INREG(CRTC_GEN_CNTL
))&CRTC_DBL_SCAN_EN
;
662 static int radeon_is_interlace( void )
664 return (INREG(CRTC_GEN_CNTL
))&CRTC_INTERLACE_EN
;
667 static uint32_t radeon_get_xres( void )
669 uint32_t xres
,h_total
;
672 (rinfo
.dviDispType
== MT_CTV
|| rinfo
.dviDispType
== MT_STV
))
673 h_total
= INREG(CRTC2_H_TOTAL_DISP
);
676 h_total
= INREG(CRTC_H_TOTAL_DISP
);
677 xres
= (h_total
>> 16) & 0xffff;
681 static uint32_t radeon_get_yres( void )
683 uint32_t yres
,v_total
;
686 (rinfo
.dviDispType
== MT_CTV
|| rinfo
.dviDispType
== MT_STV
))
687 v_total
= INREG(CRTC2_V_TOTAL_DISP
);
690 v_total
= INREG(CRTC_V_TOTAL_DISP
);
691 yres
= (v_total
>> 16) & 0xffff;
695 static void radeon_wait_vsync(void)
699 OUTREG(GEN_INT_STATUS
, VSYNC_INT_AK
);
700 for (i
= 0; i
< 2000000; i
++)
702 if (INREG(GEN_INT_STATUS
) & VSYNC_INT
) break;
707 static void _radeon_engine_idle(void);
708 static void _radeon_fifo_wait(unsigned);
709 #define radeon_engine_idle() _radeon_engine_idle()
710 #define radeon_fifo_wait(entries) _radeon_fifo_wait(entries)
711 /* Flush all dirty data in the Pixel Cache to memory. */
712 static __inline__
void radeon_engine_flush ( void )
716 OUTREGP(PC_NGUI_CTLSTAT
, PC_FLUSH_ALL
, ~PC_FLUSH_ALL
);
717 for (i
= 0; i
< 2000000; i
++) {
718 if (!(INREG(PC_NGUI_CTLSTAT
) & PC_BUSY
)) break;
722 /* Reset graphics card to known state. */
723 static void radeon_engine_reset( void )
725 uint32_t clock_cntl_index
;
727 uint32_t gen_reset_cntl
;
729 radeon_engine_flush();
731 clock_cntl_index
= INREG(CLOCK_CNTL_INDEX
);
732 mclk_cntl
= INPLL(MCLK_CNTL
);
734 OUTPLL(MCLK_CNTL
, mclk_cntl
| FORCE_GCP
| FORCE_PIPE3D_CP
);
736 gen_reset_cntl
= INREG(GEN_RESET_CNTL
);
738 OUTREG(GEN_RESET_CNTL
, gen_reset_cntl
| SOFT_RESET_GUI
);
739 INREG(GEN_RESET_CNTL
);
740 OUTREG(GEN_RESET_CNTL
,
741 gen_reset_cntl
& (uint32_t)(~SOFT_RESET_GUI
));
742 INREG(GEN_RESET_CNTL
);
744 OUTPLL(MCLK_CNTL
, mclk_cntl
);
745 OUTREG(CLOCK_CNTL_INDEX
, clock_cntl_index
);
746 OUTREG(GEN_RESET_CNTL
, gen_reset_cntl
);
750 static __inline__
void radeon_engine_flush ( void )
755 OUTREGP(RB2D_DSTCACHE_CTLSTAT
, RB2D_DC_FLUSH_ALL
,
758 for (i
=0; i
< 2000000; i
++) {
759 if (!(INREG(RB2D_DSTCACHE_CTLSTAT
) & RB2D_DC_BUSY
))
764 static void _radeon_engine_idle(void);
765 static void _radeon_fifo_wait(unsigned);
766 #define radeon_engine_idle() _radeon_engine_idle()
767 #define radeon_fifo_wait(entries) _radeon_fifo_wait(entries)
769 static void radeon_engine_reset( void )
771 uint32_t clock_cntl_index
, mclk_cntl
, rbbm_soft_reset
;
773 radeon_engine_flush ();
775 clock_cntl_index
= INREG(CLOCK_CNTL_INDEX
);
776 mclk_cntl
= INPLL(MCLK_CNTL
);
778 OUTPLL(MCLK_CNTL
, (mclk_cntl
|
785 rbbm_soft_reset
= INREG(RBBM_SOFT_RESET
);
787 OUTREG(RBBM_SOFT_RESET
, rbbm_soft_reset
|
796 INREG(RBBM_SOFT_RESET
);
797 OUTREG(RBBM_SOFT_RESET
, rbbm_soft_reset
& (uint32_t)
806 INREG(RBBM_SOFT_RESET
);
808 OUTPLL(MCLK_CNTL
, mclk_cntl
);
809 OUTREG(CLOCK_CNTL_INDEX
, clock_cntl_index
);
810 OUTREG(RBBM_SOFT_RESET
, rbbm_soft_reset
);
815 static void radeon_engine_restore( void )
819 uint32_t xres
,yres
,bpp
;
821 xres
= radeon_get_xres();
822 yres
= radeon_get_yres();
823 bpp
= radeon_vid_get_dbpp();
824 /* turn of all automatic flushing - we'll do it all */
825 OUTREG(RB2D_DSTCACHE_MODE
, 0);
827 pitch64
= ((xres
* (bpp
/ 8) + 0x3f)) >> 6;
830 OUTREG(DEFAULT_OFFSET
, (INREG(DEFAULT_OFFSET
) & 0xC0000000) |
836 HOST_BIG_ENDIAN_EN
, ~HOST_BIG_ENDIAN_EN
);
838 OUTREGP(DP_DATATYPE
, 0, ~HOST_BIG_ENDIAN_EN
);
842 OUTREG(DEFAULT_SC_BOTTOM_RIGHT
, (DEFAULT_SC_RIGHT_MAX
843 | DEFAULT_SC_BOTTOM_MAX
));
845 OUTREG(DP_GUI_MASTER_CNTL
, (INREG(DP_GUI_MASTER_CNTL
)
846 | GMC_BRUSH_SOLID_COLOR
847 | GMC_SRC_DATATYPE_COLOR
));
850 OUTREG(DST_LINE_START
, 0);
851 OUTREG(DST_LINE_END
, 0);
852 OUTREG(DP_BRUSH_FRGD_CLR
, 0xffffffff);
853 OUTREG(DP_BRUSH_BKGD_CLR
, 0x00000000);
854 OUTREG(DP_SRC_FRGD_CLR
, 0xffffffff);
855 OUTREG(DP_SRC_BKGD_CLR
, 0x00000000);
856 OUTREG(DP_WRITE_MASK
, 0xffffffff);
858 radeon_engine_idle();
862 static void _radeon_fifo_wait (unsigned entries
)
868 for (i
=0; i
<2000000; i
++)
869 if ((INREG(GUI_STAT
) & GUI_FIFOCNT_MASK
) >= entries
)
871 radeon_engine_reset();
872 radeon_engine_restore();
876 static void _radeon_engine_idle ( void )
880 /* ensure FIFO is empty before waiting for idle */
881 radeon_fifo_wait (64);
884 for (i
=0; i
<2000000; i
++) {
885 if ((INREG(GUI_STAT
) & GUI_ACTIVE
) == 0) {
886 radeon_engine_flush ();
890 radeon_engine_reset();
891 radeon_engine_restore();
895 static void _radeon_fifo_wait (unsigned entries
)
901 for (i
=0; i
<2000000; i
++)
902 if ((INREG(RBBM_STATUS
) & RBBM_FIFOCNT_MASK
) >= entries
)
904 radeon_engine_reset();
905 radeon_engine_restore();
908 static void _radeon_engine_idle ( void )
912 /* ensure FIFO is empty before waiting for idle */
913 radeon_fifo_wait (64);
916 for (i
=0; i
<2000000; i
++) {
917 if (((INREG(RBBM_STATUS
) & RBBM_ACTIVE
)) == 0) {
918 radeon_engine_flush ();
922 radeon_engine_reset();
923 radeon_engine_restore();
929 /* Reference color space transform data */
930 typedef struct tagREF_TRANSFORM
941 /* Parameters for ITU-R BT.601 and ITU-R BT.709 colour spaces */
942 static const REF_TRANSFORM trans
[2] =
944 {1.1678, 0.0, 1.6007, -0.3929, -0.8154, 2.0232, 0.0}, /* BT.601 */
945 {1.1678, 0.0, 1.7980, -0.2139, -0.5345, 2.1186, 0.0} /* BT.709 */
947 /****************************************************************************
949 * Function: Calculates and sets color space transform from supplied *
950 * reference transform, gamma, brightness, contrast, hue and *
952 * Inputs: bright - brightness *
956 * red_intensity - intense of red component *
957 * green_intensity - intense of green component *
958 * blue_intensity - intense of blue component *
959 * ref - index to the table of refernce transforms *
961 ****************************************************************************/
963 static void radeon_set_transform(float bright
, float cont
, float sat
,
964 float hue
, float red_intensity
,
965 float green_intensity
,float blue_intensity
,
968 float OvHueSin
, OvHueCos
;
969 float CAdjLuma
, CAdjOff
;
970 float RedAdj
,GreenAdj
,BlueAdj
;
971 float CAdjRCb
, CAdjRCr
;
972 float CAdjGCb
, CAdjGCr
;
973 float CAdjBCb
, CAdjBCr
;
974 float OvLuma
, OvROff
, OvGOff
, OvBOff
;
981 uint32_t dwOvLuma
, dwOvROff
, dwOvGOff
, dwOvBOff
;
982 uint32_t dwOvRCb
, dwOvRCr
;
983 uint32_t dwOvGCb
, dwOvGCr
;
984 uint32_t dwOvBCb
, dwOvBCr
;
986 if (ref
>= 2) return;
988 OvHueSin
= sin((double)hue
);
989 OvHueCos
= cos((double)hue
);
991 CAdjLuma
= cont
* trans
[ref
].RefLuma
;
992 CAdjOff
= cont
* trans
[ref
].RefLuma
* bright
* 1023.0;
993 RedAdj
= cont
* trans
[ref
].RefLuma
* red_intensity
* 1023.0;
994 GreenAdj
= cont
* trans
[ref
].RefLuma
* green_intensity
* 1023.0;
995 BlueAdj
= cont
* trans
[ref
].RefLuma
* blue_intensity
* 1023.0;
997 CAdjRCb
= sat
* -OvHueSin
* trans
[ref
].RefRCr
;
998 CAdjRCr
= sat
* OvHueCos
* trans
[ref
].RefRCr
;
999 CAdjGCb
= sat
* (OvHueCos
* trans
[ref
].RefGCb
- OvHueSin
* trans
[ref
].RefGCr
);
1000 CAdjGCr
= sat
* (OvHueSin
* trans
[ref
].RefGCb
+ OvHueCos
* trans
[ref
].RefGCr
);
1001 CAdjBCb
= sat
* OvHueCos
* trans
[ref
].RefBCb
;
1002 CAdjBCr
= sat
* OvHueSin
* trans
[ref
].RefBCb
;
1011 OvROff
= RedAdj
+ CAdjOff
-
1012 OvLuma
* Loff
- (OvRCb
+ OvRCr
) * Coff
;
1013 OvGOff
= GreenAdj
+ CAdjOff
-
1014 OvLuma
* Loff
- (OvGCb
+ OvGCr
) * Coff
;
1015 OvBOff
= BlueAdj
+ CAdjOff
-
1016 OvLuma
* Loff
- (OvBCb
+ OvBCr
) * Coff
;
1018 dwOvROff
= ((int)(OvROff
* 2.0)) & 0x1fff;
1019 dwOvGOff
= (int)(OvGOff
* 2.0) & 0x1fff;
1020 dwOvBOff
= (int)(OvBOff
* 2.0) & 0x1fff;
1021 /* Whatever docs say about R200 having 3.8 format instead of 3.11
1022 as in Radeon is a lie */
1024 dwOvLuma
=(((int)(OvLuma
* 2048.0))&0x7fff)<<17;
1025 dwOvRCb
= (((int)(OvRCb
* 2048.0))&0x7fff)<<1;
1026 dwOvRCr
= (((int)(OvRCr
* 2048.0))&0x7fff)<<17;
1027 dwOvGCb
= (((int)(OvGCb
* 2048.0))&0x7fff)<<1;
1028 dwOvGCr
= (((int)(OvGCr
* 2048.0))&0x7fff)<<17;
1029 dwOvBCb
= (((int)(OvBCb
* 2048.0))&0x7fff)<<1;
1030 dwOvBCr
= (((int)(OvBCr
* 2048.0))&0x7fff)<<17;
1032 OUTREG(OV0_LIN_TRANS_A
, dwOvRCb
| dwOvLuma
);
1033 OUTREG(OV0_LIN_TRANS_B
, dwOvROff
| dwOvRCr
);
1034 OUTREG(OV0_LIN_TRANS_C
, dwOvGCb
| dwOvLuma
);
1035 OUTREG(OV0_LIN_TRANS_D
, dwOvGOff
| dwOvGCr
);
1036 OUTREG(OV0_LIN_TRANS_E
, dwOvBCb
| dwOvLuma
);
1037 OUTREG(OV0_LIN_TRANS_F
, dwOvBOff
| dwOvBCr
);
1040 /* Gamma curve definition */
1043 unsigned int gammaReg
;
1044 unsigned int gammaSlope
;
1045 unsigned int gammaOffset
;
1048 /* Recommended gamma curve parameters */
1049 static const GAMMA_SETTINGS r200_def_gamma
[18] =
1051 {OV0_GAMMA_0_F
, 0x100, 0x0000},
1052 {OV0_GAMMA_10_1F
, 0x100, 0x0020},
1053 {OV0_GAMMA_20_3F
, 0x100, 0x0040},
1054 {OV0_GAMMA_40_7F
, 0x100, 0x0080},
1055 {OV0_GAMMA_80_BF
, 0x100, 0x0100},
1056 {OV0_GAMMA_C0_FF
, 0x100, 0x0100},
1057 {OV0_GAMMA_100_13F
, 0x100, 0x0200},
1058 {OV0_GAMMA_140_17F
, 0x100, 0x0200},
1059 {OV0_GAMMA_180_1BF
, 0x100, 0x0300},
1060 {OV0_GAMMA_1C0_1FF
, 0x100, 0x0300},
1061 {OV0_GAMMA_200_23F
, 0x100, 0x0400},
1062 {OV0_GAMMA_240_27F
, 0x100, 0x0400},
1063 {OV0_GAMMA_280_2BF
, 0x100, 0x0500},
1064 {OV0_GAMMA_2C0_2FF
, 0x100, 0x0500},
1065 {OV0_GAMMA_300_33F
, 0x100, 0x0600},
1066 {OV0_GAMMA_340_37F
, 0x100, 0x0600},
1067 {OV0_GAMMA_380_3BF
, 0x100, 0x0700},
1068 {OV0_GAMMA_3C0_3FF
, 0x100, 0x0700}
1071 static const GAMMA_SETTINGS r100_def_gamma
[6] =
1073 {OV0_GAMMA_0_F
, 0x100, 0x0000},
1074 {OV0_GAMMA_10_1F
, 0x100, 0x0020},
1075 {OV0_GAMMA_20_3F
, 0x100, 0x0040},
1076 {OV0_GAMMA_40_7F
, 0x100, 0x0080},
1077 {OV0_GAMMA_380_3BF
, 0x100, 0x0100},
1078 {OV0_GAMMA_3C0_3FF
, 0x100, 0x0100}
1081 static void make_default_gamma_correction( void )
1084 if((besr
.chip_flags
& R_100
)==R_100
||
1085 (besr
.chip_flags
& R_120
)==R_120
||
1086 (besr
.chip_flags
& R_150
)==R_150
){
1087 OUTREG(OV0_LIN_TRANS_A
, 0x12A00000);
1088 OUTREG(OV0_LIN_TRANS_B
, 0x199018FE);
1089 OUTREG(OV0_LIN_TRANS_C
, 0x12A0F9B0);
1090 OUTREG(OV0_LIN_TRANS_D
, 0xF2F0043B);
1091 OUTREG(OV0_LIN_TRANS_E
, 0x12A02050);
1092 OUTREG(OV0_LIN_TRANS_F
, 0x0000174E);
1094 OUTREG(r100_def_gamma
[i
].gammaReg
,
1095 (r100_def_gamma
[i
].gammaSlope
<<16) |
1096 r100_def_gamma
[i
].gammaOffset
);
1100 OUTREG(OV0_LIN_TRANS_A
, 0x12a20000);
1101 OUTREG(OV0_LIN_TRANS_B
, 0x198a190e);
1102 OUTREG(OV0_LIN_TRANS_C
, 0x12a2f9da);
1103 OUTREG(OV0_LIN_TRANS_D
, 0xf2fe0442);
1104 OUTREG(OV0_LIN_TRANS_E
, 0x12a22046);
1105 OUTREG(OV0_LIN_TRANS_F
, 0x175f);
1107 Of 18 segments for gamma cure, all segments in R200 are programmable,
1108 while only lower 4 and upper 2 segments are programmable in Radeon*/
1109 for(i
=0; i
<18; i
++){
1110 OUTREG(r200_def_gamma
[i
].gammaReg
,
1111 (r200_def_gamma
[i
].gammaSlope
<<16) |
1112 r200_def_gamma
[i
].gammaOffset
);
1118 static void radeon_vid_make_default(void)
1121 besr
.saturation
= 0x0F;
1122 besr
.brightness
= 0;
1123 OUTREG(OV0_COLOUR_CNTL
,0x000F0F00UL
); /* Default brihgtness and saturation for Rage128 */
1125 make_default_gamma_correction();
1127 besr
.deinterlace_pattern
= 0x900AAAAA;
1128 OUTREG(OV0_DEINTERLACE_PATTERN
,besr
.deinterlace_pattern
);
1129 besr
.deinterlace_on
=1;
1132 besr
.graphics_key_msk
=0;
1133 besr
.graphics_key_clr
=0;
1134 besr
.ckey_cntl
= VIDEO_KEY_FN_TRUE
|GRAPHIC_KEY_FN_TRUE
|CMP_MIX_AND
;
1137 static int find_chip(unsigned chip_id
)
1140 for(i
= 0;i
< sizeof(ati_card_ids
)/sizeof(ati_card_ids_t
);i
++)
1142 if(chip_id
== ati_card_ids
[i
].id
) return i
;
1147 static pciinfo_t pci_info
;
1148 static int probed
=0;
1150 static vidix_capability_t def_cap
=
1153 "BES driver for Rage128 cards",
1155 "BES driver for Radeon cards",
1158 TYPE_OUTPUT
| TYPE_FX
,
1165 FLAG_UPSCALER
| FLAG_DOWNSCALER
| FLAG_EQUALIZER
,
1171 #if !defined(RAGE128) && defined(CONFIG_X11)
1172 static void probe_fireGL_driver(void) {
1173 Display
*dp
= XOpenDisplay ((void*)0);
1179 extlist
= XListExtensions (dp
, &n
);
1183 int ext_fgl
= 0, ext_fglrx
= 0;
1184 for (i
= 0; i
< n
; i
++) {
1185 if (!strcmp(extlist
[i
], "ATIFGLEXTENSION")) ext_fgl
= 1;
1186 if (!strcmp(extlist
[i
], "ATIFGLRXDRI")) ext_fglrx
= 1;
1189 printf(RADEON_MSG
" ATI FireGl driver detected");
1190 firegl_shift
= 0x500000;
1192 printf(", but DRI seems not to be activated\n");
1193 printf(RADEON_MSG
" Output may not work correctly, check your DRI configration!");
1201 static int radeon_probe(int verbose
, int force
)
1203 pciinfo_t lst
[MAX_PCI_DEVICES
];
1206 verbosity
= verbose
;
1207 err
= pci_scan(lst
,&num_pci
);
1210 printf(RADEON_MSG
" Error occurred during pci scan: %s\n",strerror(err
));
1216 for(i
=0;i
<num_pci
;i
++)
1218 if(lst
[i
].vendor
== VENDOR_ATI
)
1222 idx
= find_chip(lst
[i
].device
);
1223 if(idx
== -1 && force
== PROBE_NORMAL
) continue;
1224 dname
= pci_device_name(VENDOR_ATI
,lst
[i
].device
);
1225 dname
= dname
? dname
: "Unknown chip";
1226 printf(RADEON_MSG
" Found chip: %s\n",dname
);
1228 if ((lst
[i
].command
& PCI_COMMAND_IO
) == 0)
1230 printf("[radeon] Device is disabled, ignoring\n");
1234 memset(&besr
,0,sizeof(bes_registers_t
));
1235 if(force
> PROBE_NORMAL
)
1237 printf(RADEON_MSG
" Driver was forced. Was found %sknown chip\n",idx
== -1 ? "un" : "");
1240 printf(RADEON_MSG
" Assuming it as Rage128\n");
1242 printf(RADEON_MSG
" Assuming it as Radeon1\n");
1244 besr
.chip_flags
=R_100
|R_OVL_SHIFT
;
1246 #if !defined(RAGE128) && defined(CONFIG_X11)
1247 probe_fireGL_driver();
1249 if(idx
!= -1) besr
.chip_flags
=ati_card_ids
[idx
].flags
;
1250 def_cap
.device_id
= lst
[i
].device
;
1252 memcpy(&pci_info
,&lst
[i
],sizeof(pciinfo_t
));
1258 if(err
&& verbose
) printf(RADEON_MSG
" Can't find chip\n");
1262 typedef struct saved_regs_s
1264 uint32_t ov0_vid_key_clr
;
1265 uint32_t ov0_vid_key_msk
;
1266 uint32_t ov0_graphics_key_clr
;
1267 uint32_t ov0_graphics_key_msk
;
1268 uint32_t ov0_key_cntl
;
1269 uint32_t disp_merge_cntl
;
1271 static saved_regs_t savreg
;
1273 static void save_regs( void )
1275 radeon_fifo_wait(6);
1276 savreg
.ov0_vid_key_clr
= INREG(OV0_VID_KEY_CLR
);
1277 savreg
.ov0_vid_key_msk
= INREG(OV0_VID_KEY_MSK
);
1278 savreg
.ov0_graphics_key_clr
= INREG(OV0_GRAPHICS_KEY_CLR
);
1279 savreg
.ov0_graphics_key_msk
= INREG(OV0_GRAPHICS_KEY_MSK
);
1280 savreg
.ov0_key_cntl
= INREG(OV0_KEY_CNTL
);
1281 savreg
.disp_merge_cntl
= INREG(DISP_MERGE_CNTL
);
1284 static void restore_regs( void )
1286 radeon_fifo_wait(6);
1287 OUTREG(OV0_VID_KEY_CLR
,savreg
.ov0_vid_key_clr
);
1288 OUTREG(OV0_VID_KEY_MSK
,savreg
.ov0_vid_key_msk
);
1289 OUTREG(OV0_GRAPHICS_KEY_CLR
,savreg
.ov0_graphics_key_clr
);
1290 OUTREG(OV0_GRAPHICS_KEY_MSK
,savreg
.ov0_graphics_key_msk
);
1291 OUTREG(OV0_KEY_CNTL
,savreg
.ov0_key_cntl
);
1292 OUTREG(DISP_MERGE_CNTL
,savreg
.disp_merge_cntl
);
1295 static int radeon_init(void)
1301 printf(RADEON_MSG
" Driver was not probed but is being initializing\n");
1304 if((radeon_mmio_base
= map_phys_mem(pci_info
.base2
,0xFFFF))==(void *)-1) return ENOMEM
;
1305 radeon_ram_size
= INREG(CONFIG_MEMSIZE
);
1306 /* mem size is bits [28:0], mask off the rest. Range: from 1Mb up to 512 Mb */
1307 radeon_ram_size
&= CONFIG_MEMSIZE_MASK
;
1309 /* according to XFree86 4.2.0, some production M6's return 0 for 8MB */
1310 if (radeon_ram_size
== 0 &&
1311 (def_cap
.device_id
== DEVICE_ATI_RADEON_MOBILITY_M6
||
1312 def_cap
.device_id
== DEVICE_ATI_RADEON_MOBILITY_M62
))
1314 printf(RADEON_MSG
" Working around buggy Radeon Mobility M6 (0 vs. 8MB ram)\n");
1315 radeon_ram_size
= 8192*1024;
1317 else if (radeon_ram_size
== 0 &&
1318 (def_cap
.device_id
== DEVICE_ATI_RS482_RADEON_XPRESS
))
1320 printf(RADEON_MSG
" Working around buggy RS482 Radeon Xpress 200 Memory Detection\n");
1321 radeon_ram_size
= (INREG(CONFIG_MEMSIZE
) + 0x100000) << 2;
1322 radeon_ram_size
&= CONFIG_MEMSIZE_MASK
;
1325 /* Rage Mobility (rage128) also has memsize bug */
1326 if (radeon_ram_size
== 0 &&
1327 (def_cap
.device_id
== DEVICE_ATI_RAGE_MOBILITY_M3
||
1328 def_cap
.device_id
== DEVICE_ATI_RAGE_MOBILITY_M32
))
1330 printf(RADEON_MSG
" Working around Rage Mobility M3 (0 vs. 8MB ram)\n");
1331 radeon_ram_size
= 8192*1024;
1334 if((radeon_mem_base
= map_phys_mem(pci_info
.base0
,radeon_ram_size
))==(void *)-1) return ENOMEM
;
1335 radeon_vid_make_default();
1336 printf(RADEON_MSG
" Video memory = %uMb\n",radeon_ram_size
/0x100000);
1337 err
= mtrr_set_type(pci_info
.base0
,radeon_ram_size
,MTRR_TYPE_WRCOMB
);
1338 if(!err
) printf(RADEON_MSG
" Set write-combining type of video memory\n");
1341 memset(&rinfo
,0,sizeof(rinfo_t
));
1342 if((besr
.chip_flags
&R_100
) != R_100
) rinfo
.hasCRTC2
= 1;
1344 radeon_get_moninfo(&rinfo
);
1345 if(rinfo
.hasCRTC2
) {
1346 printf(RADEON_MSG
" DVI port has %s monitor connected\n",GET_MON_NAME(rinfo
.dviDispType
));
1347 printf(RADEON_MSG
" CRT port has %s monitor connected\n",GET_MON_NAME(rinfo
.crtDispType
));
1350 printf(RADEON_MSG
" CRT port has %s monitor connected\n",GET_MON_NAME(rinfo
.crtDispType
));
1357 static void radeon_destroy(void)
1360 unmap_phys_mem(radeon_mem_base
,radeon_ram_size
);
1361 unmap_phys_mem(radeon_mmio_base
,0xFFFF);
1364 static int radeon_get_caps(vidix_capability_t
*to
)
1366 memcpy(to
,&def_cap
,sizeof(vidix_capability_t
));
1371 Full list of fourcc which are supported by Win2K radeon driver:
1372 YUY2, UYVY, DDES, OGLT, OGL2, OGLS, OGLB, OGNT, OGNZ, OGNS,
1373 IF09, YVU9, IMC4, M2IA, IYUV, VBID, DXT1, DXT2, DXT3, DXT4, DXT5
1375 typedef struct fourcc_desc_s
1381 static const fourcc_desc_t supported_fourcc
[] =
1383 { IMGFMT_Y800
, 1567 },
1384 { IMGFMT_YVU9
, 1567 },
1385 { IMGFMT_IF09
, 1567 },
1386 { IMGFMT_YV12
, 1567 },
1387 { IMGFMT_I420
, 1567 },
1388 { IMGFMT_IYUV
, 1567 },
1389 { IMGFMT_UYVY
, 1551 },
1390 { IMGFMT_YUY2
, 1551 },
1391 { IMGFMT_YVYU
, 1551 },
1392 { IMGFMT_RGB15
, 1551 },
1393 { IMGFMT_BGR15
, 1551 },
1394 { IMGFMT_RGB16
, 1551 },
1395 { IMGFMT_BGR16
, 1551 },
1396 { IMGFMT_RGB32
, 775 },
1397 { IMGFMT_BGR32
, 775 }
1400 __inline__
static int is_supported_fourcc(uint32_t fourcc
)
1403 for(i
=0;i
<sizeof(supported_fourcc
)/sizeof(fourcc_desc_t
);i
++)
1405 if(fourcc
==supported_fourcc
[i
].fourcc
)
1411 static int radeon_query_fourcc(vidix_fourcc_t
*to
)
1413 if(is_supported_fourcc(to
->fourcc
))
1415 to
->depth
= VID_DEPTH_ALL
;
1416 to
->flags
= VID_CAP_EXPAND
| VID_CAP_SHRINK
| VID_CAP_COLORKEY
|
1420 else to
->depth
= to
->flags
= 0;
1424 static double H_scale_ratio
;
1425 static void radeon_vid_dump_regs( void )
1428 printf(RADEON_MSG
"*** Begin of DRIVER variables dump ***\n");
1429 printf(RADEON_MSG
"radeon_mmio_base=%p\n",radeon_mmio_base
);
1430 printf(RADEON_MSG
"radeon_mem_base=%p\n",radeon_mem_base
);
1431 printf(RADEON_MSG
"radeon_overlay_off=%08X\n",radeon_overlay_off
);
1432 printf(RADEON_MSG
"radeon_ram_size=%08X\n",radeon_ram_size
);
1433 printf(RADEON_MSG
"video mode: %ux%u@%u\n",radeon_get_xres(),radeon_get_yres(),radeon_vid_get_dbpp());
1434 printf(RADEON_MSG
"H_scale_ratio=%8.2f\n",H_scale_ratio
);
1435 printf(RADEON_MSG
"*** Begin of OV0 registers dump ***\n");
1436 for(i
=0;i
<sizeof(vregs
)/sizeof(video_registers_t
);i
++)
1437 printf(RADEON_MSG
"%s = %08X\n",vregs
[i
].sname
,INREG(vregs
[i
].name
));
1438 printf(RADEON_MSG
"*** End of OV0 registers dump ***\n");
1441 static void radeon_vid_stop_video( void )
1443 radeon_engine_idle();
1444 OUTREG(OV0_SCALE_CNTL
, SCALER_SOFT_RESET
);
1445 OUTREG(OV0_EXCLUSIVE_HORZ
, 0);
1446 OUTREG(OV0_AUTO_FLIP_CNTL
, 0); /* maybe */
1447 OUTREG(OV0_FILTER_CNTL
, FILTER_HARDCODED_COEF
);
1449 OUTREG(OV0_KEY_CNTL
, GRAPHIC_KEY_FN_NE
);
1451 OUTREG(OV0_KEY_CNTL
, GRAPHIC_KEY_FN_EQ
);
1453 OUTREG(OV0_TEST
, 0);
1456 static void radeon_vid_display_video( void )
1458 int bes_flags
,force_second
;
1459 radeon_fifo_wait(2);
1460 OUTREG(OV0_REG_LOAD_CNTL
, REG_LD_CTL_LOCK
);
1461 radeon_engine_idle();
1462 while(!(INREG(OV0_REG_LOAD_CNTL
)®_LD_CTL_LOCK_READBACK
));
1463 radeon_fifo_wait(15);
1467 /* Shutdown capturing */
1468 OUTREG(FCP_CNTL
, FCP_CNTL__GND
);
1469 OUTREG(CAP0_TRIG_CNTL
, 0);
1471 OUTREG(VID_BUFFER_CONTROL
, (1<<16) | 0x01);
1472 OUTREG(DISP_TEST_DEBUG_CNTL
, 0);
1474 OUTREG(OV0_AUTO_FLIP_CNTL
,OV0_AUTO_FLIP_CNTL_SOFT_BUF_ODD
);
1476 if(besr
.deinterlace_on
) OUTREG(OV0_DEINTERLACE_PATTERN
,besr
.deinterlace_pattern
);
1478 OUTREG(OV0_COLOUR_CNTL
, (besr
.brightness
& 0x7f) |
1479 (besr
.saturation
<< 8) |
1480 (besr
.saturation
<< 16));
1482 radeon_fifo_wait(2);
1483 OUTREG(OV0_GRAPHICS_KEY_MSK
, besr
.graphics_key_msk
);
1484 OUTREG(OV0_GRAPHICS_KEY_CLR
, besr
.graphics_key_clr
);
1485 OUTREG(OV0_KEY_CNTL
,besr
.ckey_cntl
);
1487 OUTREG(OV0_H_INC
, besr
.h_inc
);
1488 OUTREG(OV0_STEP_BY
, besr
.step_by
);
1491 OUTREG(OV1_Y_X_START
, besr
.y_x_start
);
1492 OUTREG(OV1_Y_X_END
, besr
.y_x_end
);
1496 OUTREG(OV0_Y_X_START
, besr
.y_x_start
);
1497 OUTREG(OV0_Y_X_END
, besr
.y_x_end
);
1499 OUTREG(OV0_V_INC
, besr
.v_inc
);
1500 OUTREG(OV0_P1_BLANK_LINES_AT_TOP
, besr
.p1_blank_lines_at_top
);
1501 OUTREG(OV0_P23_BLANK_LINES_AT_TOP
, besr
.p23_blank_lines_at_top
);
1502 OUTREG(OV0_VID_BUF_PITCH0_VALUE
, besr
.vid_buf_pitch0_value
);
1503 OUTREG(OV0_VID_BUF_PITCH1_VALUE
, besr
.vid_buf_pitch1_value
);
1504 OUTREG(OV0_P1_X_START_END
, besr
.p1_x_start_end
);
1505 OUTREG(OV0_P2_X_START_END
, besr
.p2_x_start_end
);
1506 OUTREG(OV0_P3_X_START_END
, besr
.p3_x_start_end
);
1508 OUTREG(OV0_BASE_ADDR
, besr
.base_addr
);
1510 OUTREG(OV0_VID_BUF0_BASE_ADRS
, besr
.vid_buf_base_adrs_y
[0]);
1511 OUTREG(OV0_VID_BUF1_BASE_ADRS
, besr
.vid_buf_base_adrs_v
[0]);
1512 OUTREG(OV0_VID_BUF2_BASE_ADRS
, besr
.vid_buf_base_adrs_u
[0]);
1513 radeon_fifo_wait(9);
1514 OUTREG(OV0_VID_BUF3_BASE_ADRS
, besr
.vid_buf_base_adrs_y
[0]);
1515 OUTREG(OV0_VID_BUF4_BASE_ADRS
, besr
.vid_buf_base_adrs_v
[0]);
1516 OUTREG(OV0_VID_BUF5_BASE_ADRS
, besr
.vid_buf_base_adrs_u
[0]);
1517 OUTREG(OV0_P1_V_ACCUM_INIT
, besr
.p1_v_accum_init
);
1518 OUTREG(OV0_P1_H_ACCUM_INIT
, besr
.p1_h_accum_init
);
1519 OUTREG(OV0_P23_H_ACCUM_INIT
, besr
.p23_h_accum_init
);
1520 OUTREG(OV0_P23_V_ACCUM_INIT
, besr
.p23_v_accum_init
);
1522 bes_flags
= SCALER_ENABLE
|
1523 SCALER_SMART_SWITCH
|
1526 if(besr
.double_buff
) bes_flags
|= SCALER_DOUBLE_BUFFER
;
1527 if(besr
.deinterlace_on
) bes_flags
|= SCALER_ADAPTIVE_DEINT
;
1528 if(besr
.horz_pick_nearest
) bes_flags
|= SCALER_HORZ_PICK_NEAREST
;
1529 if(besr
.vert_pick_nearest
) bes_flags
|= SCALER_VERT_PICK_NEAREST
;
1531 bes_flags
|= SCALER_BURST_PER_PLANE
;
1533 bes_flags
|= (besr
.surf_id
<< 8) & SCALER_SURFAC_FORMAT
;
1534 if(besr
.load_prg_start
) bes_flags
|= SCALER_PRG_LOAD_START
;
1535 if(force_second
) bes_flags
|= SCALER_USE_OV1
;
1536 else bes_flags
&= ~SCALER_USE_OV1
;
1537 OUTREG(OV0_SCALE_CNTL
, bes_flags
);
1538 radeon_fifo_wait(6);
1539 OUTREG(OV0_FILTER_CNTL
,besr
.filter_cntl
);
1540 OUTREG(OV0_FOUR_TAP_COEF_0
,besr
.four_tap_coeff
[0]);
1541 OUTREG(OV0_FOUR_TAP_COEF_1
,besr
.four_tap_coeff
[1]);
1542 OUTREG(OV0_FOUR_TAP_COEF_2
,besr
.four_tap_coeff
[2]);
1543 OUTREG(OV0_FOUR_TAP_COEF_3
,besr
.four_tap_coeff
[3]);
1544 OUTREG(OV0_FOUR_TAP_COEF_4
,besr
.four_tap_coeff
[4]);
1545 if(besr
.swap_uv
) OUTREG(OV0_TEST
,INREG(OV0_TEST
)|OV0_SWAP_UV
);
1546 OUTREG(OV0_REG_LOAD_CNTL
, 0);
1547 if(verbosity
> VERBOSE_LEVEL
) printf(RADEON_MSG
"we wanted: scaler=%08X\n",bes_flags
);
1548 if(verbosity
> VERBOSE_LEVEL
) radeon_vid_dump_regs();
1551 /* Goal of this function: hide RGB background and provide black screen around movie.
1552 Useful in '-vo fbdev:vidix -fs -zoom' mode.
1553 Reverse effect to colorkey */
1555 static void radeon_vid_exclusive( void )
1557 /* this function works only with Rage128.
1558 Radeon should has something the same */
1559 unsigned screenw
,screenh
;
1560 screenw
= radeon_get_xres();
1561 screenh
= radeon_get_yres();
1562 radeon_fifo_wait(2);
1563 OUTREG(OV0_EXCLUSIVE_VERT
,(((screenh
-1)<<16)&EXCL_VERT_END_MASK
));
1564 OUTREG(OV0_EXCLUSIVE_HORZ
,(((screenw
/8+1)<<8)&EXCL_HORZ_END_MASK
)|EXCL_HORZ_EXCLUSIVE_EN
);
1567 static void radeon_vid_non_exclusive( void )
1569 OUTREG(OV0_EXCLUSIVE_HORZ
,0);
1573 static unsigned radeon_query_pitch(unsigned fourcc
,const vidix_yuv_t
*spitch
)
1575 unsigned pitch
,spy
,spv
,spu
;
1576 spy
= spv
= spu
= 0;
1583 case 256: spy
= spitch
->y
; break;
1592 case 256: spu
= spitch
->u
; break;
1601 case 256: spv
= spitch
->v
; break;
1610 if(spy
> 16 && spu
== spy
/2 && spv
== spy
/2) pitch
= spy
;
1615 if(spy
>= 64 && spu
== spy
/4 && spv
== spy
/4) pitch
= spy
;
1619 if(spy
>= 16) pitch
= spy
;
1626 static void Calc_H_INC_STEP_BY (
1627 int fieldvalue_OV0_SURFACE_FORMAT
,
1628 double H_scale_ratio
,
1629 int DisallowFourTapVertFiltering
,
1630 int DisallowFourTapUVVertFiltering
,
1631 uint32_t *val_OV0_P1_H_INC
,
1632 uint32_t *val_OV0_P1_H_STEP_BY
,
1633 uint32_t *val_OV0_P23_H_INC
,
1634 uint32_t *val_OV0_P23_H_STEP_BY
,
1640 double ClocksNeededFor16Pixels
;
1642 switch (fieldvalue_OV0_SURFACE_FORMAT
)
1645 case 4: /*16BPP (ARGB1555 and RGB565) */
1646 /* All colour components are fetched in pairs */
1648 /* We don't support four tap in this mode because G's are split between two bytes. In theory we could support it if */
1649 /* we saved part of the G when fetching the R, and then filter the G, followed by the B in the following cycles. */
1650 if (H_scale_ratio
>=.5)
1652 /* We are actually generating two pixels (but 3 colour components) per tick. Thus we don't have to skip */
1653 /* until we reach .5. P1 and P23 are the same. */
1654 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5);
1655 *val_OV0_P1_H_STEP_BY
= 1;
1656 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5);
1657 *val_OV0_P23_H_STEP_BY
= 1;
1661 else if (H_scale_ratio
>=.25)
1664 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*2)) * (1<<0xc) + 0.5);
1665 *val_OV0_P1_H_STEP_BY
= 2;
1666 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*2)) * (1<<0xc) + 0.5);
1667 *val_OV0_P23_H_STEP_BY
= 2;
1671 else if (H_scale_ratio
>=.125)
1674 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*4)) * (1<<0xc) + 0.5);
1675 *val_OV0_P1_H_STEP_BY
= 3;
1676 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*4)) * (1<<0xc) + 0.5);
1677 *val_OV0_P23_H_STEP_BY
= 3;
1681 else if (H_scale_ratio
>=.0625)
1684 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*8)) * (1<<0xc) + 0.5);
1685 *val_OV0_P1_H_STEP_BY
= 4;
1686 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*8)) * (1<<0xc) + 0.5);
1687 *val_OV0_P23_H_STEP_BY
= 4;
1691 else if (H_scale_ratio
>=0.03125)
1693 /* Step by sixteen */
1694 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*16)) * (1<<0xc) + 0.5);
1695 *val_OV0_P1_H_STEP_BY
= 5;
1696 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*16)) * (1<<0xc) + 0.5);
1697 *val_OV0_P23_H_STEP_BY
= 5;
1703 H_scale_ratio
=0.03125;
1704 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*16)) * (1<<0xc) + 0.5);
1705 *val_OV0_P1_H_STEP_BY
= 5;
1706 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*16)) * (1<<0xc) + 0.5);
1707 *val_OV0_P23_H_STEP_BY
= 5;
1712 case 6: /*32BPP RGB */
1713 if (H_scale_ratio
>=1.5 && !DisallowFourTapVertFiltering
)
1715 /* All colour components are fetched in pairs */
1717 /* With four tap filtering, we can generate two colour components every clock, or two pixels every three */
1718 /* clocks. This means that we will have four tap filtering when scaling 1.5 or more. */
1719 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5);
1720 *val_OV0_P1_H_STEP_BY
= 0;
1721 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5);
1722 *val_OV0_P23_H_STEP_BY
= 0;
1726 else if (H_scale_ratio
>=0.75)
1728 /* Four G colour components are fetched at once */
1730 /* R and B colour components are fetched in pairs */
1731 /* With two tap filtering, we can generate four colour components every clock. */
1732 /* This means that we will have two tap filtering when scaling 1.0 or more. */
1733 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5);
1734 *val_OV0_P1_H_STEP_BY
= 1;
1735 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5);
1736 *val_OV0_P23_H_STEP_BY
= 1;
1740 else if (H_scale_ratio
>=0.375)
1743 /* Four G colour components are fetched at once */
1745 /* R and B colour components are fetched in pairs */
1746 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*2)) * (1<<0xc) + 0.5);
1747 *val_OV0_P1_H_STEP_BY
= 2;
1748 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*2)) * (1<<0xc) + 0.5);
1749 *val_OV0_P23_H_STEP_BY
= 2;
1753 else if (H_scale_ratio
>=0.25)
1756 /* Four G colour components are fetched at once */
1758 /* R and B colour components are fetched in pairs */
1759 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*2)) * (1<<0xc) + 0.5);
1760 *val_OV0_P1_H_STEP_BY
= 2;
1761 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*4)) * (1<<0xc) + 0.5);
1762 *val_OV0_P23_H_STEP_BY
= 3;
1766 else if (H_scale_ratio
>=0.1875)
1769 /* Four G colour components are fetched at once */
1771 /* R and B colour components are fetched in pairs */
1772 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*4)) * (1<<0xc) + 0.5);
1773 *val_OV0_P1_H_STEP_BY
= 3;
1774 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*4)) * (1<<0xc) + 0.5);
1775 *val_OV0_P23_H_STEP_BY
= 3;
1779 else if (H_scale_ratio
>=0.125)
1782 /* Four G colour components are fetched at once */
1784 /* R and B colour components are fetched in pairs */
1785 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*4)) * (1<<0xc) + 0.5);
1786 *val_OV0_P1_H_STEP_BY
= 3;
1787 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*8)) * (1<<0xc) + 0.5);
1788 *val_OV0_P23_H_STEP_BY
= 4;
1792 else if (H_scale_ratio
>=0.09375)
1795 /* Four G colour components are fetched at once */
1797 /* R and B colour components are fetched in pairs */
1798 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*8)) * (1<<0xc) + 0.5);
1799 *val_OV0_P1_H_STEP_BY
= 4;
1800 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*8)) * (1<<0xc) + 0.5);
1801 *val_OV0_P23_H_STEP_BY
= 4;
1805 else if (H_scale_ratio
>=0.0625)
1808 /* Four G colour components are fetched at once */
1810 /* R and B colour components are fetched in pairs */
1811 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*16)) * (1<<0xc) + 0.5);
1812 *val_OV0_P1_H_STEP_BY
= 5;
1813 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*16)) * (1<<0xc) + 0.5);
1814 *val_OV0_P23_H_STEP_BY
= 5;
1820 H_scale_ratio
=0.0625;
1822 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*16)) * (1<<0xc) + 0.5);
1823 *val_OV0_P1_H_STEP_BY
= 5;
1824 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*16)) * (1<<0xc) + 0.5);
1825 *val_OV0_P23_H_STEP_BY
= 5;
1831 /*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. */
1832 /* four tap on both (unless Y is too wide) */
1833 if ((H_scale_ratio
>=(ClocksNeededFor16Pixels
=8+2+2) / 16.0) &&
1834 ((uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5)<=0x3000) &&
1835 ((uint16_t)((1/(H_scale_ratio
*4)) * (1<<0xc) + 0.5)<=0x2000) &&
1836 !DisallowFourTapVertFiltering
&& !DisallowFourTapUVVertFiltering
)
1838 /* Colour components are fetched in pairs */
1840 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5);
1841 *val_OV0_P1_H_STEP_BY
= 0;
1842 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*4)) * (1<<0xc) + 0.5);
1843 *val_OV0_P23_H_STEP_BY
= 0;
1847 /* two tap on Y (because it is too big for four tap), four tap on UV */
1848 else if ((H_scale_ratio
>=(ClocksNeededFor16Pixels
=4+2+2) / 16.0) &&
1849 ((uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5)<=0x3000) &&
1850 ((uint16_t)((1/(H_scale_ratio
*4)) * (1<<0xc) + 0.5)<=0x2000) &&
1851 DisallowFourTapVertFiltering
&& !DisallowFourTapUVVertFiltering
)
1854 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5);
1855 *val_OV0_P1_H_STEP_BY
= 1;
1856 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*4)) * (1<<0xc) + 0.5);
1857 *val_OV0_P23_H_STEP_BY
= 0;
1861 /* We scale the Y with the four tap filters, but UV's are generated
1862 with dual two tap configuration. */
1863 else if ((H_scale_ratio
>=(ClocksNeededFor16Pixels
=8+1+1) / 16.0) &&
1864 ((uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5)<=0x3000) &&
1865 ((uint16_t)((1/(H_scale_ratio
*4)) * (1<<0xc) + 0.5)<=0x2000) &&
1866 !DisallowFourTapVertFiltering
)
1869 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5);
1870 *val_OV0_P1_H_STEP_BY
= 0;
1871 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*4)) * (1<<0xc) + 0.5);
1872 *val_OV0_P23_H_STEP_BY
= 1;
1876 /* We scale the Y, U, and V with the two tap filters */
1877 else if ((H_scale_ratio
>=(ClocksNeededFor16Pixels
=4+1+1) / 16.0) &&
1878 ((uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5)<=0x3000) &&
1879 ((uint16_t)((1/(H_scale_ratio
*4)) * (1<<0xc) + 0.5)<=0x2000))
1882 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5);
1883 *val_OV0_P1_H_STEP_BY
= 1;
1884 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*4)) * (1<<0xc) + 0.5);
1885 *val_OV0_P23_H_STEP_BY
= 1;
1889 /* We scale step the U and V by two to allow more bandwidth for fetching Y's,
1890 thus we won't drop Y's yet. */
1891 else if ((H_scale_ratio
>=(ClocksNeededFor16Pixels
=4+.5+.5) / 16.0) &&
1892 ((uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5)<=0x3000) &&
1893 ((uint16_t)((1/(H_scale_ratio
*4*2)) * (1<<0xc) + 0.5)<=0x2000))
1894 { /*>=0.3125 and >.333333~ */
1896 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5);
1897 *val_OV0_P1_H_STEP_BY
= 1;
1898 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*4*2)) * (1<<0xc) + 0.5);
1899 *val_OV0_P23_H_STEP_BY
= 2;
1903 /* We step the Y, U, and V by two. */
1904 else if ((H_scale_ratio
>=(ClocksNeededFor16Pixels
=2+.5+.5) / 16.0) &&
1905 ((uint16_t)((1/(H_scale_ratio
*2)) * (1<<0xc) + 0.5)<=0x3000) &&
1906 ((uint16_t)((1/(H_scale_ratio
*4*2)) * (1<<0xc) + 0.5)<=0x2000))
1909 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*2)) * (1<<0xc) + 0.5);
1910 *val_OV0_P1_H_STEP_BY
= 2;
1911 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*4*2)) * (1<<0xc) + 0.5);
1912 *val_OV0_P23_H_STEP_BY
= 2;
1916 /* We step the Y by two and the U and V by four. */
1917 else if ((H_scale_ratio
>=(ClocksNeededFor16Pixels
=2+.25+.25) / 16.0) &&
1918 ((uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5)<=0x3000) &&
1919 ((uint16_t)((1/(H_scale_ratio
*4*4)) * (1<<0xc) + 0.5)<=0x2000))
1922 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*2)) * (1<<0xc) + 0.5);
1923 *val_OV0_P1_H_STEP_BY
= 2;
1924 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*4*4)) * (1<<0xc) + 0.5);
1925 *val_OV0_P23_H_STEP_BY
= 3;
1929 /* We step the Y, U, and V by four. */
1930 else if ((H_scale_ratio
>=(ClocksNeededFor16Pixels
=1+.25+.25) / 16.0) &&
1931 ((uint16_t)((1/(H_scale_ratio
*4)) * (1<<0xc) + 0.5)<=0x3000) &&
1932 ((uint16_t)((1/(H_scale_ratio
*4*4)) * (1<<0xc) + 0.5)<=0x2000))
1935 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*4)) * (1<<0xc) + 0.5);
1936 *val_OV0_P1_H_STEP_BY
= 3;
1937 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*4*4)) * (1<<0xc) + 0.5);
1938 *val_OV0_P23_H_STEP_BY
= 3;
1942 /* 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 */
1944 /* We step the Y, U, and V by eight. */
1945 else if ((H_scale_ratio
>=(ClocksNeededFor16Pixels
=.5+.125+.125) / 16.0) &&
1946 ((uint16_t)((1/(H_scale_ratio
*8)) * (1<<0xc) + 0.5)<=0x3000) &&
1947 ((uint16_t)((1/(H_scale_ratio
*4*8)) * (1<<0xc) + 0.5)<=0x2000))
1950 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*8)) * (1<<0xc) + 0.5);
1951 *val_OV0_P1_H_STEP_BY
= 4;
1952 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*4*8)) * (1<<0xc) + 0.5);
1953 *val_OV0_P23_H_STEP_BY
= 4;
1957 /* We step the Y by eight and the U and V by sixteen. */
1958 else if ((H_scale_ratio
>=(ClocksNeededFor16Pixels
=.5+.0625+.0625) / 16.0) &&
1959 ((uint16_t)((1/(H_scale_ratio
*8)) * (1<<0xc) + 0.5)<=0x3000) &&
1960 ((uint16_t)((1/(H_scale_ratio
*4*16)) * (1<<0xc) + 0.5)<=0x2000))
1963 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*8)) * (1<<0xc) + 0.5);
1964 *val_OV0_P1_H_STEP_BY
= 4;
1965 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*4*16)) * (1<<0xc) + 0.5);
1966 *val_OV0_P23_H_STEP_BY
= 5;
1970 /* We step the Y, U, and V by sixteen. */
1971 else if ((H_scale_ratio
>=(ClocksNeededFor16Pixels
=.25+.0625+.0625) / 16.0) &&
1972 ((uint16_t)((1/(H_scale_ratio
*16)) * (1<<0xc) + 0.5)<=0x3000) &&
1973 ((uint16_t)((1/(H_scale_ratio
*4*16)) * (1<<0xc) + 0.5)<=0x2000))
1976 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*16)) * (1<<0xc) + 0.5);
1977 *val_OV0_P1_H_STEP_BY
= 5;
1978 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*4*16)) * (1<<0xc) + 0.5);
1979 *val_OV0_P23_H_STEP_BY
= 5;
1985 H_scale_ratio
=(ClocksNeededFor16Pixels
=.25+.0625+.0625) / 16;
1987 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*16)) * (1<<0xc) + 0.5);
1988 *val_OV0_P1_H_STEP_BY
= 5;
1989 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*4*16)) * (1<<0xc) + 0.5);
1990 *val_OV0_P23_H_STEP_BY
= 5;
1999 case 14: /* YUV12, VYUY422, YUYV422, YOverPkCRCB12, YWovenWithPkCRCB12 */
2000 /* We scale the Y, U, and V with the four tap filters */
2001 /* four tap on both (unless Y is too wide) */
2002 if ((H_scale_ratio
>=(ClocksNeededFor16Pixels
=8+4+4) / 16.0) &&
2003 !DisallowFourTapVertFiltering
&& !DisallowFourTapUVVertFiltering
)
2006 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5);
2007 *val_OV0_P1_H_STEP_BY
= 0;
2008 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*2)) * (1<<0xc) + 0.5);
2009 *val_OV0_P23_H_STEP_BY
= 0;
2013 /* two tap on Y (because it is too big for four tap), four tap on UV */
2014 else if ((H_scale_ratio
>=(ClocksNeededFor16Pixels
=4+4+4) / 16.0) &&
2015 DisallowFourTapVertFiltering
&& !DisallowFourTapUVVertFiltering
)
2018 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5);
2019 *val_OV0_P1_H_STEP_BY
= 1;
2020 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*2)) * (1<<0xc) + 0.5);
2021 *val_OV0_P23_H_STEP_BY
= 0;
2025 /* We scale the Y with the four tap filters, but UV's are generated
2026 with dual two tap configuration. */
2027 else if ((H_scale_ratio
>=(ClocksNeededFor16Pixels
=8+2+2) / 16.0) &&
2028 !DisallowFourTapVertFiltering
)
2031 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5);
2032 *val_OV0_P1_H_STEP_BY
= 0;
2033 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*2)) * (1<<0xc) + 0.5);
2034 *val_OV0_P23_H_STEP_BY
= 1;
2038 /* We scale the Y, U, and V with the two tap filters */
2039 else if (H_scale_ratio
>=(ClocksNeededFor16Pixels
=4+2+2) / 16.0)
2042 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5);
2043 *val_OV0_P1_H_STEP_BY
= 1;
2044 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*2)) * (1<<0xc) + 0.5);
2045 *val_OV0_P23_H_STEP_BY
= 1;
2049 /* We scale step the U and V by two to allow more bandwidth for
2050 fetching Y's, thus we won't drop Y's yet. */
2051 else if (H_scale_ratio
>=(ClocksNeededFor16Pixels
=4+1+1) / 16.0)
2054 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
)) * (1<<0xc) + 0.5);
2055 *val_OV0_P1_H_STEP_BY
= 1;
2056 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*2*2)) * (1<<0xc) + 0.5);
2057 *val_OV0_P23_H_STEP_BY
= 2;
2061 /* We step the Y, U, and V by two. */
2062 else if (H_scale_ratio
>=(ClocksNeededFor16Pixels
=2+1+1) / 16.0)
2065 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*2)) * (1<<0xc) + 0.5);
2066 *val_OV0_P1_H_STEP_BY
= 2;
2067 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*2*2)) * (1<<0xc) + 0.5);
2068 *val_OV0_P23_H_STEP_BY
= 2;
2072 /* We step the Y by two and the U and V by four. */
2073 else if (H_scale_ratio
>=(ClocksNeededFor16Pixels
=2+.5+.5) / 16.0)
2076 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*2)) * (1<<0xc) + 0.5);
2077 *val_OV0_P1_H_STEP_BY
= 2;
2078 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*2*4)) * (1<<0xc) + 0.5);
2079 *val_OV0_P23_H_STEP_BY
= 3;
2083 /* We step the Y, U, and V by four. */
2084 else if (H_scale_ratio
>=(ClocksNeededFor16Pixels
=1+.5+.5) / 16.0)
2087 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*4)) * (1<<0xc) + 0.5);
2088 *val_OV0_P1_H_STEP_BY
= 3;
2089 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*2*4)) * (1<<0xc) + 0.5);
2090 *val_OV0_P23_H_STEP_BY
= 3;
2094 /* We step the Y by four and the U and V by eight. */
2095 else if ((H_scale_ratio
>=(ClocksNeededFor16Pixels
=1+.25+.25) / 16.0) &&
2096 (fieldvalue_OV0_SURFACE_FORMAT
==10))
2099 /* Can't mix step by 3 and step by 4 for packed modes */
2100 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*4)) * (1<<0xc) + 0.5);
2101 *val_OV0_P1_H_STEP_BY
= 3;
2102 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*2*8)) * (1<<0xc) + 0.5);
2103 *val_OV0_P23_H_STEP_BY
= 4;
2107 /* We step the Y, U, and V by eight. */
2108 else if (H_scale_ratio
>=(ClocksNeededFor16Pixels
=.5+.25+.25) / 16.0)
2111 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*8)) * (1<<0xc) + 0.5);
2112 *val_OV0_P1_H_STEP_BY
= 4;
2113 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*2*8)) * (1<<0xc) + 0.5);
2114 *val_OV0_P23_H_STEP_BY
= 4;
2118 /* We step the Y by eight and the U and V by sixteen. */
2119 else if ((H_scale_ratio
>=(ClocksNeededFor16Pixels
=.5+.125+.125) / 16.0) && (fieldvalue_OV0_SURFACE_FORMAT
==10))
2122 /* Step by 5 not supported for packed modes */
2123 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*8)) * (1<<0xc) + 0.5);
2124 *val_OV0_P1_H_STEP_BY
= 4;
2125 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*2*16)) * (1<<0xc) + 0.5);
2126 *val_OV0_P23_H_STEP_BY
= 5;
2130 /* We step the Y, U, and V by sixteen. */
2131 else if ((H_scale_ratio
>=(ClocksNeededFor16Pixels
=.25+.125+.125) / 16.0) &&
2132 (fieldvalue_OV0_SURFACE_FORMAT
==10))
2135 /* Step by 5 not supported for packed modes */
2136 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*16)) * (1<<0xc) + 0.5);
2137 *val_OV0_P1_H_STEP_BY
= 5;
2138 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*2*16)) * (1<<0xc) + 0.5);
2139 *val_OV0_P23_H_STEP_BY
= 5;
2145 if (fieldvalue_OV0_SURFACE_FORMAT
==10)
2147 H_scale_ratio
=(ClocksNeededFor16Pixels
=.25+.125+.125) / 16;
2149 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*16)) * (1<<0xc) + 0.5);
2150 *val_OV0_P1_H_STEP_BY
= 5;
2151 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*2*16)) * (1<<0xc) + 0.5);
2152 *val_OV0_P23_H_STEP_BY
= 5;
2158 H_scale_ratio
=(ClocksNeededFor16Pixels
=.5+.25+.25) / 16;
2160 *val_OV0_P1_H_INC
= (uint16_t)((1/(H_scale_ratio
*8)) * (1<<0xc) + 0.5);
2161 *val_OV0_P1_H_STEP_BY
= 4;
2162 *val_OV0_P23_H_INC
= (uint16_t)((1/(H_scale_ratio
*2*8)) * (1<<0xc) + 0.5);
2163 *val_OV0_P23_H_STEP_BY
= 4;
2172 besr
.h_inc
= (*(val_OV0_P1_H_INC
)&0x3fff) | ((*(val_OV0_P23_H_INC
)&0x3fff)<<16);
2173 besr
.step_by
= (*(val_OV0_P1_H_STEP_BY
)&0x7) | ((*(val_OV0_P23_H_STEP_BY
)&0x7)<<8);
2176 /* ********************************************************* */
2177 /* ** Setup Black Bordering */
2178 /* ********************************************************* */
2180 static void ComputeBorders( vidix_playback_t
*config
, int VertUVSubSample
)
2182 double tempBLANK_LINES_AT_TOP
;
2183 unsigned TopLine
,BottomLine
,SourceLinesUsed
,TopUVLine
,BottomUVLine
,SourceUVLinesUsed
;
2184 uint32_t val_OV0_P1_ACTIVE_LINES_M1
,val_OV0_P1_BLNK_LN_AT_TOP_M1
;
2185 uint32_t val_OV0_P23_ACTIVE_LINES_M1
,val_OV0_P23_BLNK_LN_AT_TOP_M1
;
2187 if (floor(config
->src
.y
)<0) {
2188 tempBLANK_LINES_AT_TOP
= -floor(config
->src
.y
);
2192 tempBLANK_LINES_AT_TOP
= 0;
2193 TopLine
= (int)floor(config
->src
.y
);
2195 /* Round rSrcBottom up and subtract one */
2196 if (ceil(config
->src
.y
+config
->src
.h
) > config
->src
.h
)
2198 BottomLine
= config
->src
.h
- 1;
2202 BottomLine
= (int)ceil(config
->src
.y
+config
->src
.h
) - 1;
2205 if (BottomLine
>= TopLine
)
2207 SourceLinesUsed
= BottomLine
- TopLine
+ 1;
2211 /*CYCACC_ASSERT(0, "SourceLinesUsed less than or equal to zero.") */
2212 SourceLinesUsed
= 1;
2216 int SourceHeightInPixels
;
2217 SourceHeightInPixels
= BottomLine
- TopLine
+ 1;
2220 val_OV0_P1_ACTIVE_LINES_M1
= SourceLinesUsed
- 1;
2221 val_OV0_P1_BLNK_LN_AT_TOP_M1
= ((int)tempBLANK_LINES_AT_TOP
-1) & 0xfff;
2223 TopUVLine
= ((int)(config
->src
.y
/VertUVSubSample
) < 0) ? 0: (int)(config
->src
.y
/VertUVSubSample
); /* Round rSrcTop down */
2224 BottomUVLine
= (ceil(((config
->src
.y
+config
->src
.h
)/VertUVSubSample
)) > (config
->src
.h
/VertUVSubSample
))
2225 ? (config
->src
.h
/VertUVSubSample
)-1 : (unsigned int)ceil(((config
->src
.y
+config
->src
.h
)/VertUVSubSample
))-1;
2227 if (BottomUVLine
>= TopUVLine
)
2229 SourceUVLinesUsed
= BottomUVLine
- TopUVLine
+ 1;
2233 /*CYCACC_ASSERT(0, "SourceUVLinesUsed less than or equal to zero.") */
2234 SourceUVLinesUsed
= 1;
2236 val_OV0_P23_ACTIVE_LINES_M1
= SourceUVLinesUsed
- 1;
2237 val_OV0_P23_BLNK_LN_AT_TOP_M1
= ((int)(tempBLANK_LINES_AT_TOP
/VertUVSubSample
)-1) & 0x7ff;
2238 besr
.p1_blank_lines_at_top
= (val_OV0_P1_BLNK_LN_AT_TOP_M1
& 0xfff) |
2239 ((val_OV0_P1_ACTIVE_LINES_M1
& 0xfff) << 16);
2240 besr
.p23_blank_lines_at_top
= (val_OV0_P23_BLNK_LN_AT_TOP_M1
& 0x7ff) |
2241 ((val_OV0_P23_ACTIVE_LINES_M1
& 0x7ff) << 16);
2245 static void ComputeXStartEnd(
2247 uint32_t LeftPixel
,uint32_t LeftUVPixel
,
2248 uint32_t MemWordsInBytes
,uint32_t BytesPerPixel
,
2249 uint32_t SourceWidthInPixels
, uint32_t P1StepSize
,
2250 uint32_t BytesPerUVPixel
,uint32_t SourceUVWidthInPixels
,
2251 uint32_t P23StepSize
, uint32_t *p1_x_start
, uint32_t *p2_x_start
)
2253 uint32_t val_OV0_P1_X_START
,val_OV0_P2_X_START
,val_OV0_P3_X_START
;
2254 uint32_t val_OV0_P1_X_END
,val_OV0_P2_X_END
,val_OV0_P3_X_END
;
2255 /* 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. */
2257 val_OV0_P1_X_START
= (int)LeftPixel
% (MemWordsInBytes
/BytesPerPixel
);
2258 val_OV0_P1_X_END
= (int)((val_OV0_P1_X_START
+ SourceWidthInPixels
- 1) / P1StepSize
) * P1StepSize
;
2260 val_OV0_P2_X_START
= val_OV0_P2_X_END
= 0;
2261 switch (besr
.surf_id
)
2266 case 14: /* ToDo_Active: The driver must insure that the initial value is */
2267 /* a multiple of a power of two when decimating */
2268 val_OV0_P2_X_START
= (int)LeftUVPixel
%
2269 (MemWordsInBytes
/BytesPerUVPixel
);
2270 val_OV0_P2_X_END
= (int)((val_OV0_P2_X_START
+
2271 SourceUVWidthInPixels
- 1) / P23StepSize
) * P23StepSize
;
2274 case 12: val_OV0_P2_X_START
= (int)LeftUVPixel
% (MemWordsInBytes
/(BytesPerPixel
*2));
2275 val_OV0_P2_X_END
= (int)((val_OV0_P2_X_START
+ SourceUVWidthInPixels
- 1) / P23StepSize
) * P23StepSize
;
2278 case 4: val_OV0_P2_X_START
= val_OV0_P1_X_START
;
2279 /* This value is needed only to allow proper setting of */
2280 /* val_OV0_PRESHIFT_P23_TO */
2281 /* val_OV0_P2_X_END = 0; */
2283 case 6: val_OV0_P2_X_START
= (int)LeftPixel
% (MemWordsInBytes
/BytesPerPixel
);
2284 val_OV0_P2_X_END
= (int)((val_OV0_P1_X_START
+ SourceWidthInPixels
- 1) / P23StepSize
) * P23StepSize
;
2286 default: /* insert debug statement here. */
2287 RADEON_ASSERT("unknown fourcc\n");
2290 val_OV0_P3_X_START
= val_OV0_P2_X_START
;
2291 val_OV0_P3_X_END
= val_OV0_P2_X_END
;
2293 besr
.p1_x_start_end
= (val_OV0_P1_X_END
&0x7ff) | ((val_OV0_P1_X_START
&0x7ff)<<16);
2294 besr
.p2_x_start_end
= (val_OV0_P2_X_END
&0x7ff) | ((val_OV0_P2_X_START
&0x7ff)<<16);
2295 besr
.p3_x_start_end
= (val_OV0_P3_X_END
&0x7ff) | ((val_OV0_P3_X_START
&0x7ff)<<16);
2298 besr
.p2_x_start_end
= 0;
2299 besr
.p3_x_start_end
= 0;
2301 *p1_x_start
= val_OV0_P1_X_START
;
2302 *p2_x_start
= val_OV0_P2_X_START
;
2305 static void ComputeAccumInit(
2306 uint32_t val_OV0_P1_X_START
,uint32_t val_OV0_P2_X_START
,
2307 uint32_t val_OV0_P1_H_INC
,uint32_t val_OV0_P23_H_INC
,
2308 uint32_t val_OV0_P1_H_STEP_BY
,uint32_t val_OV0_P23_H_STEP_BY
,
2310 uint32_t P1GroupSize
, uint32_t P23GroupSize
,
2311 uint32_t val_OV0_P1_MAX_LN_IN_PER_LN_OUT
,
2312 uint32_t val_OV0_P23_MAX_LN_IN_PER_LN_OUT
)
2314 uint32_t val_OV0_P1_H_ACCUM_INIT
,val_OV0_PRESHIFT_P1_TO
;
2315 uint32_t val_OV0_P23_H_ACCUM_INIT
,val_OV0_PRESHIFT_P23_TO
;
2316 uint32_t val_OV0_P1_V_ACCUM_INIT
,val_OV0_P23_V_ACCUM_INIT
;
2317 /* 2.5 puts the kernal 50% of the way between the source pixel that is off screen */
2318 /* and the first on-screen source pixel. "(float)valOV0_P?_H_INC / (1<<0xc)" is */
2319 /* the distance (in source pixel coordinates) to the center of the first */
2320 /* destination pixel. Need to add additional pixels depending on how many pixels */
2321 /* are fetched at a time and how many pixels in a set are masked. */
2322 /* P23 values are always fetched in groups of two or four. If the start */
2323 /* pixel does not fall on the boundary, then we need to shift preshift for */
2324 /* some additional pixels */
2327 double ExtraHalfPixel
;
2328 double tempAdditionalShift
;
2329 double tempP1HStartPoint
;
2330 double tempP23HStartPoint
;
2334 if (besr
.horz_pick_nearest
) ExtraHalfPixel
= 0.5;
2335 else ExtraHalfPixel
= 0.0;
2336 tempAdditionalShift
= val_OV0_P1_X_START
% P1GroupSize
+ ExtraHalfPixel
;
2337 tempP1HStartPoint
= tempAdditionalShift
+ 2.5 + ((float)val_OV0_P1_H_INC
/ (1<<0xd));
2338 tempP1Init
= (double)((int)(tempP1HStartPoint
* (1<<0x5) + 0.5)) / (1<<0x5);
2340 /* P23 values are always fetched in pairs. If the start pixel is odd, then we */
2341 /* need to shift an additional pixel */
2342 /* Note that if the pitch is a multiple of two, and if we store fields using */
2343 /* the traditional planer format where the V plane and the U plane share the */
2344 /* same pitch, then OverlayRegFields->val_OV0_P2_X_START % P23Group */
2345 /* OverlayRegFields->val_OV0_P3_X_START % P23GroupSize. Either way */
2346 /* it is a requirement that the U and V start on the same polarity byte */
2347 /* (even or odd). */
2348 tempAdditionalShift
= val_OV0_P2_X_START
% P23GroupSize
+ ExtraHalfPixel
;
2349 tempP23HStartPoint
= tempAdditionalShift
+ 2.5 + ((float)val_OV0_P23_H_INC
/ (1<<0xd));
2350 tempP23Init
= (double)((int)(tempP23HStartPoint
* (1<<0x5) + 0.5)) / (1 << 0x5);
2351 val_OV0_P1_H_ACCUM_INIT
= (int)((tempP1Init
- (int)tempP1Init
) * (1<<0x5));
2352 val_OV0_PRESHIFT_P1_TO
= (int)tempP1Init
;
2353 val_OV0_P23_H_ACCUM_INIT
= (int)((tempP23Init
- (int)tempP23Init
) * (1<<0x5));
2354 val_OV0_PRESHIFT_P23_TO
= (int)tempP23Init
;
2357 /* ************************************************************** */
2358 /* ** Calculate values for initializing the vertical accumulators */
2359 /* ************************************************************** */
2362 double ExtraHalfLine
;
2363 double ExtraFullLine
;
2364 double tempP1VStartPoint
;
2365 double tempP23VStartPoint
;
2367 if (besr
.vert_pick_nearest
) ExtraHalfLine
= 0.5;
2368 else ExtraHalfLine
= 0.0;
2370 if (val_OV0_P1_H_STEP_BY
==0)ExtraFullLine
= 1.0;
2371 else ExtraFullLine
= 0.0;
2373 tempP1VStartPoint
= 1.5 + ExtraFullLine
+ ExtraHalfLine
+ ((float)CRT_V_INC
/ (1<<0xd));
2374 if (tempP1VStartPoint
>2.5 + 2*ExtraFullLine
)
2376 tempP1VStartPoint
= 2.5 + 2*ExtraFullLine
;
2378 val_OV0_P1_V_ACCUM_INIT
= (int)(tempP1VStartPoint
* (1<<0x5) + 0.5);
2380 if (val_OV0_P23_H_STEP_BY
==0)ExtraFullLine
= 1.0;
2381 else ExtraFullLine
= 0.0;
2383 switch (besr
.surf_id
)
2387 case 14: tempP23VStartPoint
= 1.5 + ExtraFullLine
+ ExtraHalfLine
+
2388 ((float)CRT_V_INC
/ (1<<0xe));
2390 case 9: tempP23VStartPoint
= 1.5 + ExtraFullLine
+ ExtraHalfLine
+
2391 ((float)CRT_V_INC
/ (1<<0xf));
2397 case 12: tempP23VStartPoint
= 0;
2399 default: tempP23VStartPoint
= 0xFFFF;/* insert debug statement here */
2403 if (tempP23VStartPoint
>2.5 + 2*ExtraFullLine
)
2405 tempP23VStartPoint
= 2.5 + 2*ExtraFullLine
;
2408 val_OV0_P23_V_ACCUM_INIT
= (int)(tempP23VStartPoint
* (1<<0x5) + 0.5);
2410 besr
.p1_h_accum_init
= ((val_OV0_P1_H_ACCUM_INIT
&0x1f)<<15) |((val_OV0_PRESHIFT_P1_TO
&0xf)<<28);
2411 besr
.p1_v_accum_init
= (val_OV0_P1_MAX_LN_IN_PER_LN_OUT
&0x3) |((val_OV0_P1_V_ACCUM_INIT
&0x7ff)<<15);
2412 besr
.p23_h_accum_init
= ((val_OV0_P23_H_ACCUM_INIT
&0x1f)<<15) |((val_OV0_PRESHIFT_P23_TO
&0xf)<<28);
2413 besr
.p23_v_accum_init
= (val_OV0_P23_MAX_LN_IN_PER_LN_OUT
&0x3)|((val_OV0_P23_V_ACCUM_INIT
&0x3ff)<<15);
2416 typedef struct RangeAndCoefSet
{
2418 signed char CoefSet
[5][4];
2421 /* Filter Setup Routine */
2422 static void FilterSetup ( uint32_t val_OV0_P1_H_INC
)
2424 static const RANGEANDCOEFSET ArrayOfSets
[] = {
2425 {0.25, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2426 {0.26, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2427 {0.27, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2428 {0.28, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2429 {0.29, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2430 {0.30, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2431 {0.31, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2432 {0.32, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2433 {0.33, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2434 {0.34, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2435 {0.35, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2436 {0.36, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2437 {0.37, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2438 {0.38, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2439 {0.39, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2440 {0.40, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2441 {0.41, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2442 {0.42, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2443 {0.43, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2444 {0.44, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2445 {0.45, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2446 {0.46, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2447 {0.47, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2448 {0.48, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2449 {0.49, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2450 {0.50, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
2451 {0.51, {{ 7, 17, 8, 0}, { 6, 17, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 2, 14, 14, 2}, }},
2452 {0.52, {{ 7, 17, 8, 0}, { 6, 17, 9, 0}, { 5, 16, 11, 0}, { 3, 15, 13, 1}, { 2, 14, 14, 2}, }},
2453 {0.53, {{ 7, 17, 8, 0}, { 6, 17, 9, 0}, { 5, 16, 11, 0}, { 3, 15, 13, 1}, { 2, 14, 14, 2}, }},
2454 {0.54, {{ 7, 17, 8, 0}, { 6, 17, 9, 0}, { 4, 17, 11, 0}, { 3, 15, 13, 1}, { 2, 14, 14, 2}, }},
2455 {0.55, {{ 7, 18, 7, 0}, { 6, 17, 9, 0}, { 4, 17, 11, 0}, { 3, 15, 13, 1}, { 1, 15, 15, 1}, }},
2456 {0.56, {{ 7, 18, 7, 0}, { 5, 18, 9, 0}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }},
2457 {0.57, {{ 7, 18, 7, 0}, { 5, 18, 9, 0}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }},
2458 {0.58, {{ 7, 18, 7, 0}, { 5, 18, 9, 0}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }},
2459 {0.59, {{ 7, 18, 7, 0}, { 5, 18, 9, 0}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }},
2460 {0.60, {{ 7, 18, 8, -1}, { 6, 17, 10, -1}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }},
2461 {0.61, {{ 7, 18, 8, -1}, { 6, 17, 10, -1}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }},
2462 {0.62, {{ 7, 18, 8, -1}, { 6, 17, 10, -1}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }},
2463 {0.63, {{ 7, 18, 8, -1}, { 6, 17, 10, -1}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }},
2464 {0.64, {{ 7, 18, 8, -1}, { 6, 17, 10, -1}, { 4, 17, 12, -1}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }},
2465 {0.65, {{ 7, 18, 8, -1}, { 6, 17, 10, -1}, { 4, 17, 12, -1}, { 2, 17, 13, 0}, { 0, 16, 16, 0}, }},
2466 {0.66, {{ 7, 18, 8, -1}, { 6, 18, 10, -2}, { 4, 17, 12, -1}, { 2, 17, 13, 0}, { 0, 16, 16, 0}, }},
2467 {0.67, {{ 7, 20, 7, -2}, { 5, 19, 10, -2}, { 3, 18, 12, -1}, { 2, 17, 13, 0}, { 0, 16, 16, 0}, }},
2468 {0.68, {{ 7, 20, 7, -2}, { 5, 19, 10, -2}, { 3, 19, 12, -2}, { 1, 18, 14, -1}, { 0, 16, 16, 0}, }},
2469 {0.69, {{ 7, 20, 7, -2}, { 5, 19, 10, -2}, { 3, 19, 12, -2}, { 1, 18, 14, -1}, { 0, 16, 16, 0}, }},
2470 {0.70, {{ 7, 20, 7, -2}, { 5, 20, 9, -2}, { 3, 19, 12, -2}, { 1, 18, 14, -1}, { 0, 16, 16, 0}, }},
2471 {0.71, {{ 7, 20, 7, -2}, { 5, 20, 9, -2}, { 3, 19, 12, -2}, { 1, 18, 14, -1}, { 0, 16, 16, 0}, }},
2472 {0.72, {{ 7, 20, 7, -2}, { 5, 20, 9, -2}, { 2, 20, 12, -2}, { 0, 19, 15, -2}, {-1, 17, 17, -1}, }},
2473 {0.73, {{ 7, 20, 7, -2}, { 4, 21, 9, -2}, { 2, 20, 12, -2}, { 0, 19, 15, -2}, {-1, 17, 17, -1}, }},
2474 {0.74, {{ 6, 22, 6, -2}, { 4, 21, 9, -2}, { 2, 20, 12, -2}, { 0, 19, 15, -2}, {-1, 17, 17, -1}, }},
2475 {0.75, {{ 6, 22, 6, -2}, { 4, 21, 9, -2}, { 1, 21, 12, -2}, { 0, 19, 15, -2}, {-1, 17, 17, -1}, }},
2476 {0.76, {{ 6, 22, 6, -2}, { 4, 21, 9, -2}, { 1, 21, 12, -2}, { 0, 19, 15, -2}, {-1, 17, 17, -1}, }},
2477 {0.77, {{ 6, 22, 6, -2}, { 3, 22, 9, -2}, { 1, 22, 12, -3}, { 0, 19, 15, -2}, {-2, 18, 18, -2}, }},
2478 {0.78, {{ 6, 21, 6, -1}, { 3, 22, 9, -2}, { 1, 22, 12, -3}, { 0, 19, 15, -2}, {-2, 18, 18, -2}, }},
2479 {0.79, {{ 5, 23, 5, -1}, { 3, 22, 9, -2}, { 0, 23, 12, -3}, {-1, 21, 15, -3}, {-2, 18, 18, -2}, }},
2480 {0.80, {{ 5, 23, 5, -1}, { 3, 23, 8, -2}, { 0, 23, 12, -3}, {-1, 21, 15, -3}, {-2, 18, 18, -2}, }},
2481 {0.81, {{ 5, 23, 5, -1}, { 2, 24, 8, -2}, { 0, 23, 12, -3}, {-1, 21, 15, -3}, {-2, 18, 18, -2}, }},
2482 {0.82, {{ 5, 23, 5, -1}, { 2, 24, 8, -2}, { 0, 23, 12, -3}, {-1, 21, 15, -3}, {-3, 19, 19, -3}, }},
2483 {0.83, {{ 5, 23, 5, -1}, { 2, 24, 8, -2}, { 0, 23, 11, -2}, {-2, 22, 15, -3}, {-3, 19, 19, -3}, }},
2484 {0.84, {{ 4, 25, 4, -1}, { 1, 25, 8, -2}, { 0, 23, 11, -2}, {-2, 22, 15, -3}, {-3, 19, 19, -3}, }},
2485 {0.85, {{ 4, 25, 4, -1}, { 1, 25, 8, -2}, { 0, 23, 11, -2}, {-2, 22, 15, -3}, {-3, 19, 19, -3}, }},
2486 {0.86, {{ 4, 24, 4, 0}, { 1, 25, 7, -1}, {-1, 24, 11, -2}, {-2, 22, 15, -3}, {-3, 19, 19, -3}, }},
2487 {0.87, {{ 4, 24, 4, 0}, { 1, 25, 7, -1}, {-1, 24, 11, -2}, {-2, 22, 15, -3}, {-3, 19, 19, -3}, }},
2488 {0.88, {{ 3, 26, 3, 0}, { 0, 26, 7, -1}, {-1, 24, 11, -2}, {-3, 23, 15, -3}, {-3, 19, 19, -3}, }},
2489 {0.89, {{ 3, 26, 3, 0}, { 0, 26, 7, -1}, {-1, 24, 11, -2}, {-3, 23, 15, -3}, {-3, 19, 19, -3}, }},
2490 {0.90, {{ 3, 26, 3, 0}, { 0, 26, 7, -1}, {-2, 25, 11, -2}, {-3, 23, 15, -3}, {-3, 19, 19, -3}, }},
2491 {0.91, {{ 3, 26, 3, 0}, { 0, 27, 6, -1}, {-2, 25, 11, -2}, {-3, 23, 15, -3}, {-3, 19, 19, -3}, }},
2492 {0.92, {{ 2, 28, 2, 0}, { 0, 27, 6, -1}, {-2, 25, 11, -2}, {-3, 23, 15, -3}, {-3, 19, 19, -3}, }},
2493 {0.93, {{ 2, 28, 2, 0}, { 0, 26, 6, 0}, {-2, 25, 10, -1}, {-3, 23, 15, -3}, {-3, 19, 19, -3}, }},
2494 {0.94, {{ 2, 28, 2, 0}, { 0, 26, 6, 0}, {-2, 25, 10, -1}, {-3, 23, 15, -3}, {-3, 19, 19, -3}, }},
2495 {0.95, {{ 1, 30, 1, 0}, {-1, 28, 5, 0}, {-3, 26, 10, -1}, {-3, 23, 14, -2}, {-3, 19, 19, -3}, }},
2496 {0.96, {{ 1, 30, 1, 0}, {-1, 28, 5, 0}, {-3, 26, 10, -1}, {-3, 23, 14, -2}, {-3, 19, 19, -3}, }},
2497 {0.97, {{ 1, 30, 1, 0}, {-1, 28, 5, 0}, {-3, 26, 10, -1}, {-3, 23, 14, -2}, {-3, 19, 19, -3}, }},
2498 {0.98, {{ 1, 30, 1, 0}, {-2, 29, 5, 0}, {-3, 27, 9, -1}, {-3, 23, 14, -2}, {-3, 19, 19, -3}, }},
2499 {0.99, {{ 0, 32, 0, 0}, {-2, 29, 5, 0}, {-3, 27, 9, -1}, {-4, 24, 14, -2}, {-3, 19, 19, -3}, }},
2500 {1.00, {{ 0, 32, 0, 0}, {-2, 29, 5, 0}, {-3, 27, 9, -1}, {-4, 24, 14, -2}, {-3, 19, 19, -3}, }}
2505 unsigned ArrayElement
;
2507 DSR
= (double)(1<<0xc)/val_OV0_P1_H_INC
;
2508 if (DSR
<.25) DSR
=.25;
2511 ArrayElement
= (int)((DSR
-0.25) * 100);
2512 besr
.four_tap_coeff
[0] = (ArrayOfSets
[ArrayElement
].CoefSet
[0][0] & 0xf) |
2513 ((ArrayOfSets
[ArrayElement
].CoefSet
[0][1] & 0x7f)<<8) |
2514 ((ArrayOfSets
[ArrayElement
].CoefSet
[0][2] & 0x7f)<<16) |
2515 ((ArrayOfSets
[ArrayElement
].CoefSet
[0][3] & 0xf)<<24);
2516 besr
.four_tap_coeff
[1] = (ArrayOfSets
[ArrayElement
].CoefSet
[1][0] & 0xf) |
2517 ((ArrayOfSets
[ArrayElement
].CoefSet
[1][1] & 0x7f)<<8) |
2518 ((ArrayOfSets
[ArrayElement
].CoefSet
[1][2] & 0x7f)<<16) |
2519 ((ArrayOfSets
[ArrayElement
].CoefSet
[1][3] & 0xf)<<24);
2520 besr
.four_tap_coeff
[2] = (ArrayOfSets
[ArrayElement
].CoefSet
[2][0] & 0xf) |
2521 ((ArrayOfSets
[ArrayElement
].CoefSet
[2][1] & 0x7f)<<8) |
2522 ((ArrayOfSets
[ArrayElement
].CoefSet
[2][2] & 0x7f)<<16) |
2523 ((ArrayOfSets
[ArrayElement
].CoefSet
[2][3] & 0xf)<<24);
2524 besr
.four_tap_coeff
[3] = (ArrayOfSets
[ArrayElement
].CoefSet
[3][0] & 0xf) |
2525 ((ArrayOfSets
[ArrayElement
].CoefSet
[3][1] & 0x7f)<<8) |
2526 ((ArrayOfSets
[ArrayElement
].CoefSet
[3][2] & 0x7f)<<16) |
2527 ((ArrayOfSets
[ArrayElement
].CoefSet
[3][3] & 0xf)<<24);
2528 besr
.four_tap_coeff
[4] = (ArrayOfSets
[ArrayElement
].CoefSet
[4][0] & 0xf) |
2529 ((ArrayOfSets
[ArrayElement
].CoefSet
[4][1] & 0x7f)<<8) |
2530 ((ArrayOfSets
[ArrayElement
].CoefSet
[4][2] & 0x7f)<<16) |
2531 ((ArrayOfSets
[ArrayElement
].CoefSet
[4][3] & 0xf)<<24);
2533 For more details, refer to Microsoft's draft of PC99.
2537 /* The minimal value of horizontal scale ratio when hard coded coefficients
2538 are suitable for the best quality. */
2539 /* FIXME: Should it be 0.9 for Rage128 ??? */
2540 static const double MinHScaleHard
=0.75;
2542 static int radeon_vid_init_video( vidix_playback_t
*config
)
2544 double V_scale_ratio
;
2545 uint32_t i
,src_w
,src_h
,dest_w
,dest_h
,pitch
,left
,leftUV
,top
,h_inc
;
2546 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;
2547 uint32_t val_OV0_P1_X_START
,val_OV0_P2_X_START
;
2548 uint32_t val_OV0_P1_MAX_LN_IN_PER_LN_OUT
,val_OV0_P23_MAX_LN_IN_PER_LN_OUT
;
2550 uint32_t BytesPerOctWord
,LogMemWordsInBytes
,MemWordsInBytes
,LogTileWidthInMemWords
;
2551 uint32_t TileWidthInMemWords
,TileWidthInBytes
,LogTileHeight
,TileHeight
;
2552 uint32_t PageSizeInBytes
,OV0LB_Rows
;
2553 uint32_t SourceWidthInMemWords
,SourceUVWidthInMemWords
;
2554 uint32_t SourceWidthInPixels
,SourceUVWidthInPixels
;
2555 uint32_t RightPixel
,RightUVPixel
,LeftPixel
,LeftUVPixel
;
2556 int is_400
,is_410
,is_420
,best_pitch
,mpitch
;
2557 int horz_repl_factor
,interlace_factor
;
2558 int BytesPerPixel
,BytesPerUVPixel
,HorzUVSubSample
,VertUVSubSample
;
2559 int DisallowFourTapVertFiltering
,DisallowFourTapUVVertFiltering
;
2561 radeon_vid_stop_video();
2562 left
= config
->src
.x
<< 16;
2563 top
= config
->src
.y
<< 16;
2564 src_h
= config
->src
.h
;
2565 src_w
= config
->src
.w
;
2566 is_400
= is_410
= is_420
= 0;
2567 if(config
->fourcc
== IMGFMT_YV12
||
2568 config
->fourcc
== IMGFMT_I420
||
2569 config
->fourcc
== IMGFMT_IYUV
) is_420
= 1;
2570 if(config
->fourcc
== IMGFMT_YVU9
||
2571 config
->fourcc
== IMGFMT_IF09
) is_410
= 1;
2572 if(config
->fourcc
== IMGFMT_Y800
) is_400
= 1;
2573 best_pitch
= radeon_query_pitch(config
->fourcc
,&config
->src
.pitch
);
2574 mpitch
= best_pitch
-1;
2575 BytesPerOctWord
= 16;
2576 LogMemWordsInBytes
= 4;
2577 MemWordsInBytes
= 1<<LogMemWordsInBytes
;
2578 LogTileWidthInMemWords
= 2;
2579 TileWidthInMemWords
= 1<<LogTileWidthInMemWords
;
2580 TileWidthInBytes
= 1<<(LogTileWidthInMemWords
+LogMemWordsInBytes
);
2582 TileHeight
= 1<<LogTileHeight
;
2583 PageSizeInBytes
= 64*MemWordsInBytes
;
2586 switch(config
->fourcc
)
2596 case IMGFMT_I420
: pitch
= (src_w
+ mpitch
) & ~mpitch
;
2597 config
->dest
.pitch
.y
=
2598 config
->dest
.pitch
.u
=
2599 config
->dest
.pitch
.v
= best_pitch
;
2603 case IMGFMT_BGR32
: pitch
= (src_w
*4 + mpitch
) & ~mpitch
;
2604 config
->dest
.pitch
.y
=
2605 config
->dest
.pitch
.u
=
2606 config
->dest
.pitch
.v
= best_pitch
;
2610 default: /* RGB15, RGB16, YVYU, UYVY, YUY2 */
2611 pitch
= ((src_w
*2) + mpitch
) & ~mpitch
;
2612 config
->dest
.pitch
.y
=
2613 config
->dest
.pitch
.u
=
2614 config
->dest
.pitch
.v
= best_pitch
;
2617 besr
.load_prg_start
=0;
2619 switch(config
->fourcc
)
2623 case IMGFMT_BGR15
: besr
.surf_id
= SCALER_SOURCE_15BPP
>>8;
2624 besr
.load_prg_start
= 1;
2628 case IMGFMT_BGR16
: besr
.surf_id
= SCALER_SOURCE_16BPP
>>8;
2629 besr
.load_prg_start
= 1;
2633 case IMGFMT_BGR32
: besr
.surf_id
= SCALER_SOURCE_32BPP
>>8;
2634 besr
.load_prg_start
= 1;
2638 case IMGFMT_YVU9
: besr
.surf_id
= SCALER_SOURCE_YUV9
>>8;
2645 case IMGFMT_YV12
: besr
.surf_id
= SCALER_SOURCE_YUV12
>>8;
2649 case IMGFMT_UYVY
: besr
.surf_id
= SCALER_SOURCE_YVYU422
>>8;
2652 default: besr
.surf_id
= SCALER_SOURCE_VYUY422
>>8;
2655 switch (besr
.surf_id
)
2660 case 12: BytesPerPixel
= 2;
2662 case 6: BytesPerPixel
= 4;
2667 case 14: BytesPerPixel
= 1;
2669 default: BytesPerPixel
= 0;/*insert a debug statement here. */
2672 switch (besr
.surf_id
)
2675 case 4: BytesPerUVPixel
= 0;
2676 break;/* In RGB modes, the BytesPerUVPixel is don't care */
2678 case 12: BytesPerUVPixel
= 2;
2680 case 6: BytesPerUVPixel
= 0;
2681 break; /* In RGB modes, the BytesPerUVPixel is don't care */
2683 case 10: BytesPerUVPixel
= 1;
2686 case 14: BytesPerUVPixel
= 2;
2688 default: BytesPerUVPixel
= 0;/* insert a debug statement here. */
2692 switch (besr
.surf_id
)
2696 case 6: HorzUVSubSample
= 1;
2698 case 9: HorzUVSubSample
= 4;
2704 case 14: HorzUVSubSample
= 2;
2706 default: HorzUVSubSample
= 0;/* insert debug statement here. */
2709 switch (besr
.surf_id
)
2715 case 12: VertUVSubSample
= 1;
2717 case 9: VertUVSubSample
= 4;
2721 case 14: VertUVSubSample
= 2;
2723 default: VertUVSubSample
= 0;/* insert debug statment here. */
2726 DisallowFourTapVertFiltering
= 0; /* Allow it by default */
2727 DisallowFourTapUVVertFiltering
= 0; /* Allow it by default */
2728 LeftPixel
= config
->src
.x
;
2729 RightPixel
= config
->src
.w
-1;
2730 if(floor(config
->src
.x
/HorzUVSubSample
)<0) LeftUVPixel
= 0;
2731 else LeftUVPixel
= (int)floor(config
->src
.x
/HorzUVSubSample
);
2732 if(ceil((config
->src
.x
+config
->src
.w
)/HorzUVSubSample
) > config
->src
.w
/HorzUVSubSample
)
2733 RightUVPixel
= config
->src
.w
/HorzUVSubSample
- 1;
2734 else RightUVPixel
= (int)ceil((config
->src
.x
+config
->src
.w
)/HorzUVSubSample
) - 1;
2735 /* Top, Bottom and Right Crops can be out of range. The driver will program the hardware
2736 // to create a black border at the top and bottom. This is useful for DVD letterboxing. */
2737 SourceWidthInPixels
= (int)(config
->src
.w
+ 1);
2738 SourceUVWidthInPixels
= (int)(RightUVPixel
- LeftUVPixel
+ 1);
2740 SourceWidthInMemWords
= (int)(ceil(RightPixel
*BytesPerPixel
/ MemWordsInBytes
) -
2741 floor(LeftPixel
*BytesPerPixel
/ MemWordsInBytes
) + 1);
2742 /* SourceUVWidthInMemWords means Source_U_or_V_or_UV_WidthInMemWords depending on whether the UV is packed together of not. */
2743 SourceUVWidthInMemWords
= (int)(ceil(RightUVPixel
*BytesPerUVPixel
/
2744 MemWordsInBytes
) - floor(LeftUVPixel
*BytesPerUVPixel
/
2745 MemWordsInBytes
) + 1);
2747 switch (besr
.surf_id
)
2750 case 10: if ((ceil(SourceWidthInMemWords
/2)-1) * 2 > OV0LB_Rows
-1)
2752 RADEON_ASSERT("ceil(SourceWidthInMemWords/2)-1) * 2 > OV0LB_Rows-1\n");
2754 else if ((SourceWidthInMemWords
-1) * 2 > OV0LB_Rows
-1)
2756 DisallowFourTapVertFiltering
= 1;
2759 if ((ceil(SourceUVWidthInMemWords
/2)-1) * 4 + 1 > OV0LB_Rows
-1)
2761 /*CYCACC_ASSERT(0, "Image U plane width spans more octwords than supported by hardware.") */
2763 else if ((SourceUVWidthInMemWords
-1) * 4 + 1 > OV0LB_Rows
-1)
2765 DisallowFourTapUVVertFiltering
= 1;
2768 if ((ceil(SourceUVWidthInMemWords
/2)-1) * 4 + 3 > OV0LB_Rows
-1)
2770 /*CYCACC_ASSERT(0, "Image V plane width spans more octwords than supported by hardware.") */
2772 else if ((SourceUVWidthInMemWords
-1) * 4 + 3 > OV0LB_Rows
-1)
2774 DisallowFourTapUVVertFiltering
= 1;
2778 case 14: if ((ceil(SourceWidthInMemWords
/2)-1) * 2 > OV0LB_Rows
-1)
2780 RADEON_ASSERT("ceil(SourceWidthInMemWords/2)-1) * 2 > OV0LB_Rows-1\n");
2782 else if ((SourceWidthInMemWords
-1) * 2 > OV0LB_Rows
-1)
2784 DisallowFourTapVertFiltering
= 1;
2787 if ((ceil(SourceUVWidthInMemWords
/2)-1) * 2 + 1 > OV0LB_Rows
-1)
2789 /*CYCACC_ASSERT(0, "Image UV plane width spans more octwords than supported by hardware.") */
2791 else if ((SourceUVWidthInMemWords
-1) * 2 + 1 > OV0LB_Rows
-1)
2793 DisallowFourTapUVVertFiltering
= 1;
2800 case 12: if ((ceil(SourceWidthInMemWords
/2)-1) > OV0LB_Rows
-1)
2802 RADEON_ASSERT("(ceil(SourceWidthInMemWords/2)-1) > OV0LB_Rows-1\n")
2804 else if ((SourceWidthInMemWords
-1) > OV0LB_Rows
-1)
2806 DisallowFourTapVertFiltering
= 1;
2809 default: /* insert debug statement here. */
2812 dest_w
= config
->dest
.w
;
2813 dest_h
= config
->dest
.h
;
2814 if(radeon_is_dbl_scan()) dest_h
*= 2;
2815 besr
.dest_bpp
= radeon_vid_get_dbpp();
2816 besr
.fourcc
= config
->fourcc
;
2817 if(radeon_is_interlace()) interlace_factor
= 2;
2818 else interlace_factor
= 1;
2819 /* TODO: must be checked in doublescan mode!!! */
2820 if((besr
.chip_flags
&R_INTEGRATED
)==R_INTEGRATED
)
2822 /* Force the overlay clock on for integrated chips */
2823 OUTPLL(VCLK_ECP_CNTL
, (INPLL(VCLK_ECP_CNTL
) | (1<<18)));
2825 horz_repl_factor
= 1 << (uint32_t)((INPLL(VCLK_ECP_CNTL
) & 0x300) >> 8);
2826 H_scale_ratio
= (double)ceil(((double)dest_w
+1)/horz_repl_factor
)/src_w
;
2827 V_scale_ratio
= (double)(dest_h
+1)/src_h
;
2828 if(H_scale_ratio
< 0.5 && V_scale_ratio
< 0.5)
2830 val_OV0_P1_MAX_LN_IN_PER_LN_OUT
= 3;
2831 val_OV0_P23_MAX_LN_IN_PER_LN_OUT
= 2;
2834 if(H_scale_ratio
< 1 && V_scale_ratio
< 1)
2836 val_OV0_P1_MAX_LN_IN_PER_LN_OUT
= 2;
2837 val_OV0_P23_MAX_LN_IN_PER_LN_OUT
= 1;
2841 val_OV0_P1_MAX_LN_IN_PER_LN_OUT
= 1;
2842 val_OV0_P23_MAX_LN_IN_PER_LN_OUT
= 1;
2844 /* N.B.: Indeed it has 6.12 format but shifted on 8 to the left!!! */
2845 besr
.v_inc
= (uint16_t)((1./V_scale_ratio
)*(1<<12)*interlace_factor
+0.5);
2846 CRT_V_INC
= besr
.v_inc
/interlace_factor
;
2849 int ThereIsTwoTapVerticalFiltering
,DoNotUseMostRecentlyFetchedLine
;
2850 int P1GroupSize
= 0;
2853 int P23StepSize
= 0;
2858 DisallowFourTapVertFiltering
,
2859 DisallowFourTapUVVertFiltering
,
2861 &val_OV0_P1_H_STEP_BY
,
2863 &val_OV0_P23_H_STEP_BY
,
2868 if(H_scale_ratio
> MinHScaleHard
)
2870 h_inc
= (src_w
<< 12) / dest_w
;
2871 besr
.step_by
= 0x0101;
2872 switch (besr
.surf_id
)
2877 besr
.h_inc
= (h_inc
)|(h_inc
<<16);
2880 besr
.h_inc
= h_inc
| ((h_inc
>> 2) << 16);
2883 besr
.h_inc
= h_inc
| ((h_inc
>> 1) << 16);
2888 P23GroupSize
= 2; /* Current vaue for all modes */
2890 besr
.horz_pick_nearest
=0;
2891 DoNotUseMostRecentlyFetchedLine
=0;
2892 ThereIsTwoTapVerticalFiltering
= (val_OV0_P1_H_STEP_BY
!=0) || (val_OV0_P23_H_STEP_BY
!=0);
2893 if (ThereIsTwoTapVerticalFiltering
&& DoNotUseMostRecentlyFetchedLine
)
2894 besr
.vert_pick_nearest
= 1;
2896 besr
.vert_pick_nearest
= 0;
2898 ComputeXStartEnd(is_400
,LeftPixel
,LeftUVPixel
,MemWordsInBytes
,BytesPerPixel
,
2899 SourceWidthInPixels
,P1StepSize
,BytesPerUVPixel
,
2900 SourceUVWidthInPixels
,P23StepSize
,&val_OV0_P1_X_START
,&val_OV0_P2_X_START
);
2902 if(H_scale_ratio
> MinHScaleHard
)
2905 tmp
= (left
& 0x0003ffff) + 0x00028000 + (h_inc
<< 3);
2906 besr
.p1_h_accum_init
= ((tmp
<< 4) & 0x000f8000) |
2907 ((tmp
<< 12) & 0xf0000000);
2909 tmp
= (top
& 0x0000ffff) + 0x00018000;
2910 besr
.p1_v_accum_init
= ((tmp
<< 4) & OV0_P1_V_ACCUM_INIT_MASK
)
2911 |(OV0_P1_MAX_LN_IN_PER_LN_OUT
& 1);
2912 tmp
= ((left
>> 1) & 0x0001ffff) + 0x00028000 + (h_inc
<< 2);
2913 besr
.p23_h_accum_init
= ((tmp
<< 4) & 0x000f8000) |
2914 ((tmp
<< 12) & 0x70000000);
2916 tmp
= ((top
>> 1) & 0x0000ffff) + 0x00018000;
2917 besr
.p23_v_accum_init
= (is_420
||is_410
) ?
2918 ((tmp
<< 4) & OV0_P23_V_ACCUM_INIT_MASK
)
2919 |(OV0_P23_MAX_LN_IN_PER_LN_OUT
& 1) : 0;
2922 ComputeAccumInit( val_OV0_P1_X_START
,val_OV0_P2_X_START
,
2923 val_OV0_P1_H_INC
,val_OV0_P23_H_INC
,
2924 val_OV0_P1_H_STEP_BY
,val_OV0_P23_H_STEP_BY
,
2925 CRT_V_INC
,P1GroupSize
,P23GroupSize
,
2926 val_OV0_P1_MAX_LN_IN_PER_LN_OUT
,
2927 val_OV0_P23_MAX_LN_IN_PER_LN_OUT
);
2930 /* keep everything in 16.16 */
2931 besr
.base_addr
= INREG(DISPLAY_BASE_ADDR
);
2932 config
->offsets
[0] = 0;
2933 for(i
=1;i
<besr
.vid_nbufs
;i
++)
2934 config
->offsets
[i
] = config
->offsets
[i
-1]+config
->frame_size
;
2935 if(is_420
|| is_410
|| is_400
)
2937 uint32_t d1line
,d2line
,d3line
;
2941 d2line
= src_h
*pitch
+(d1line
>>2);
2942 d3line
= d2line
+((src_h
*pitch
)>>2);
2947 d2line
= src_h
*pitch
+(d1line
>>4);
2948 d3line
= d2line
+((src_h
*pitch
)>>4);
2955 d1line
+= (left
>> 16) & ~15;
2958 d2line
+= (left
>> 17) & ~15;
2959 d3line
+= (left
>> 17) & ~15;
2963 d2line
+= (left
>> 18) & ~15;
2964 d3line
+= (left
>> 18) & ~15;
2966 config
->offset
.y
= d1line
& VIF_BUF0_BASE_ADRS_MASK
;
2969 config
->offset
.v
= 0;
2970 config
->offset
.u
= 0;
2974 config
->offset
.v
= d2line
& VIF_BUF1_BASE_ADRS_MASK
;
2975 config
->offset
.u
= d3line
& VIF_BUF2_BASE_ADRS_MASK
;
2977 for(i
=0;i
<besr
.vid_nbufs
;i
++)
2979 besr
.vid_buf_base_adrs_y
[i
]=((radeon_overlay_off
+config
->offsets
[i
]+config
->offset
.y
)&VIF_BUF0_BASE_ADRS_MASK
);
2982 besr
.vid_buf_base_adrs_v
[i
]=0;
2983 besr
.vid_buf_base_adrs_u
[i
]=0;
2987 if (besr
.fourcc
== IMGFMT_I420
|| besr
.fourcc
== IMGFMT_IYUV
)
2989 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
;
2990 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
;
2994 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
;
2995 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
;
2999 config
->offset
.y
= ((besr
.vid_buf_base_adrs_y
[0])&VIF_BUF0_BASE_ADRS_MASK
) - radeon_overlay_off
;
3002 config
->offset
.v
= 0;
3003 config
->offset
.u
= 0;
3007 config
->offset
.v
= ((besr
.vid_buf_base_adrs_v
[0])&VIF_BUF1_BASE_ADRS_MASK
) - radeon_overlay_off
;
3008 config
->offset
.u
= ((besr
.vid_buf_base_adrs_u
[0])&VIF_BUF2_BASE_ADRS_MASK
) - radeon_overlay_off
;
3013 config
->offset
.y
= config
->offset
.u
= config
->offset
.v
= ((left
& ~7) << 1)&VIF_BUF0_BASE_ADRS_MASK
;
3014 for(i
=0;i
<besr
.vid_nbufs
;i
++)
3016 besr
.vid_buf_base_adrs_y
[i
] =
3017 besr
.vid_buf_base_adrs_u
[i
] =
3018 besr
.vid_buf_base_adrs_v
[i
] = radeon_overlay_off
+ config
->offsets
[i
] + config
->offset
.y
;
3021 leftUV
= (left
>> (is_410
?18:17)) & 15;
3022 left
= (left
>> 16) & 15;
3023 besr
.y_x_start
= (config
->dest
.x
+X_ADJUST
) | (config
->dest
.y
<< 16);
3024 besr
.y_x_end
= (config
->dest
.x
+ dest_w
+X_ADJUST
) | ((config
->dest
.y
+ dest_h
) << 16);
3025 ComputeBorders(config
,VertUVSubSample
);
3026 besr
.vid_buf_pitch0_value
= pitch
;
3027 besr
.vid_buf_pitch1_value
= is_410
? pitch
>>2 : is_420
? pitch
>>1 : pitch
;
3028 /* ********************************************************* */
3029 /* ** Calculate programmable coefficients as needed */
3030 /* ********************************************************* */
3032 /* ToDo_Active: When in pick nearest mode, we need to program the filter tap zero */
3033 /* coefficients to 0, 32, 0, 0. Or use hard coded coefficients. */
3034 if(H_scale_ratio
> MinHScaleHard
) besr
.filter_cntl
|= FILTER_HARDCODED_COEF
;
3037 FilterSetup (val_OV0_P1_H_INC
);
3038 /* ToDo_Active: Must add the smarts into the driver to decide what type of filtering it */
3039 /* would like to do. For now, we let the test application decide. */
3040 besr
.filter_cntl
= FILTER_PROGRAMMABLE_COEF
;
3041 if(DisallowFourTapVertFiltering
)
3042 besr
.filter_cntl
|= FILTER_HARD_SCALE_VERT_Y
;
3043 if(DisallowFourTapUVVertFiltering
)
3044 besr
.filter_cntl
|= FILTER_HARD_SCALE_VERT_UV
;
3049 static void radeon_compute_framesize(vidix_playback_t
*info
)
3051 unsigned pitch
,awidth
,dbpp
;
3052 pitch
= radeon_query_pitch(info
->fourcc
,&info
->src
.pitch
);
3053 dbpp
= radeon_vid_get_dbpp();
3054 switch(info
->fourcc
)
3057 awidth
= (info
->src
.w
+ (pitch
-1)) & ~(pitch
-1);
3058 info
->frame_size
= awidth
*info
->src
.h
;
3062 awidth
= (info
->src
.w
+ (pitch
-1)) & ~(pitch
-1);
3063 info
->frame_size
= awidth
*(info
->src
.h
+info
->src
.h
/8);
3068 awidth
= (info
->src
.w
+ (pitch
-1)) & ~(pitch
-1);
3069 info
->frame_size
= awidth
*(info
->src
.h
+info
->src
.h
/2);
3073 awidth
= (info
->src
.w
*4 + (pitch
-1)) & ~(pitch
-1);
3074 info
->frame_size
= awidth
*info
->src
.h
;
3076 /* YUY2 YVYU, RGB15, RGB16 */
3078 awidth
= (info
->src
.w
*2 + (pitch
-1)) & ~(pitch
-1);
3079 info
->frame_size
= awidth
*info
->src
.h
;
3082 info
->frame_size
= (info
->frame_size
+4095)&~4095;
3085 static int radeon_config_playback(vidix_playback_t
*info
)
3087 unsigned rgb_size
,nfr
;
3088 uint32_t radeon_video_size
;
3089 if(!is_supported_fourcc(info
->fourcc
)) return ENOSYS
;
3090 if(info
->num_frames
>VID_PLAY_MAXFRAMES
) info
->num_frames
=VID_PLAY_MAXFRAMES
;
3091 if(info
->num_frames
==1) besr
.double_buff
=0;
3092 else besr
.double_buff
=1;
3093 radeon_compute_framesize(info
);
3095 rgb_size
= radeon_get_xres()*radeon_get_yres()*((radeon_vid_get_dbpp()+7)/8);
3096 nfr
= info
->num_frames
;
3097 radeon_video_size
= radeon_ram_size
;
3100 radeon_overlay_off
= radeon_video_size
- info
->frame_size
*nfr
;
3101 #if !defined (RAGE128) && defined(CONFIG_X11)
3102 radeon_overlay_off
-= firegl_shift
;
3104 radeon_overlay_off
&= 0xffff0000;
3105 if(radeon_overlay_off
>= (int)rgb_size
) break;
3109 nfr
= info
->num_frames
;
3112 radeon_overlay_off
= radeon_video_size
- info
->frame_size
*nfr
;
3113 #if !defined (RAGE128) && defined(CONFIG_X11)
3114 radeon_overlay_off
-= firegl_shift
;
3116 radeon_overlay_off
&= 0xffff0000;
3117 if(radeon_overlay_off
> 0) break;
3120 if(nfr
<= 0) return EINVAL
;
3121 info
->num_frames
= nfr
;
3122 besr
.vid_nbufs
= info
->num_frames
;
3123 info
->dga_addr
= (char *)radeon_mem_base
+ radeon_overlay_off
;
3124 radeon_vid_init_video(info
);
3128 static int radeon_playback_on(void)
3133 radeon_vid_display_video();
3135 dh
= (besr
.y_x_end
>> 16) - (besr
.y_x_start
>> 16);
3136 dw
= (besr
.y_x_end
& 0xFFFF) - (besr
.y_x_start
& 0xFFFF);
3137 if(dw
== radeon_get_xres() || dh
== radeon_get_yres()) radeon_vid_exclusive();
3138 else radeon_vid_non_exclusive();
3143 static int radeon_playback_off(void)
3145 radeon_vid_stop_video();
3149 static int radeon_frame_select(unsigned frame
)
3152 int prev_frame
= (frame
-1+besr
.vid_nbufs
) % besr
.vid_nbufs
;
3154 buf3-5 always should point onto second buffer for better
3155 deinterlacing and TV-in
3157 if(!besr
.double_buff
) return 0;
3158 if(frame
> besr
.vid_nbufs
) frame
= besr
.vid_nbufs
-1;
3159 if(prev_frame
> (int)besr
.vid_nbufs
) prev_frame
= besr
.vid_nbufs
-1;
3160 off
[0] = besr
.vid_buf_base_adrs_y
[frame
];
3161 off
[1] = besr
.vid_buf_base_adrs_v
[frame
];
3162 off
[2] = besr
.vid_buf_base_adrs_u
[frame
];
3163 off
[3] = besr
.vid_buf_base_adrs_y
[prev_frame
];
3164 off
[4] = besr
.vid_buf_base_adrs_v
[prev_frame
];
3165 off
[5] = besr
.vid_buf_base_adrs_u
[prev_frame
];
3166 radeon_fifo_wait(8);
3167 OUTREG(OV0_REG_LOAD_CNTL
, REG_LD_CTL_LOCK
);
3168 radeon_engine_idle();
3169 while(!(INREG(OV0_REG_LOAD_CNTL
)®_LD_CTL_LOCK_READBACK
));
3170 OUTREG(OV0_VID_BUF0_BASE_ADRS
, off
[0]);
3171 OUTREG(OV0_VID_BUF1_BASE_ADRS
, off
[1]);
3172 OUTREG(OV0_VID_BUF2_BASE_ADRS
, off
[2]);
3173 OUTREG(OV0_VID_BUF3_BASE_ADRS
, off
[3]);
3174 OUTREG(OV0_VID_BUF4_BASE_ADRS
, off
[4]);
3175 OUTREG(OV0_VID_BUF5_BASE_ADRS
, off
[5]);
3176 OUTREG(OV0_REG_LOAD_CNTL
, 0);
3177 if(besr
.vid_nbufs
== 2) radeon_wait_vsync();
3178 if(verbosity
> VERBOSE_LEVEL
) radeon_vid_dump_regs();
3182 static vidix_video_eq_t equal
=
3184 VEQ_CAP_BRIGHTNESS
| VEQ_CAP_SATURATION
3186 | VEQ_CAP_CONTRAST
| VEQ_CAP_HUE
| VEQ_CAP_RGB_INTENSITY
3189 0, 0, 0, 0, 0, 0, 0, 0 };
3191 static int radeon_get_eq(vidix_video_eq_t
* eq
)
3193 memcpy(eq
,&equal
,sizeof(vidix_video_eq_t
));
3198 #define RTFSaturation(a) (1.0 + ((a)*1.0)/1000.0)
3199 #define RTFBrightness(a) (((a)*1.0)/2000.0)
3200 #define RTFIntensity(a) (((a)*1.0)/2000.0)
3201 #define RTFContrast(a) (1.0 + ((a)*1.0)/1000.0)
3202 #define RTFHue(a) (((a)*3.1416)/1000.0)
3203 #define RTFCheckParam(a) {if((a)<-1000) (a)=-1000; if((a)>1000) (a)=1000;}
3206 static int radeon_set_eq(const vidix_video_eq_t
* eq
)
3213 if(eq
->cap
& VEQ_CAP_BRIGHTNESS
) equal
.brightness
= eq
->brightness
;
3214 if(eq
->cap
& VEQ_CAP_CONTRAST
) equal
.contrast
= eq
->contrast
;
3215 if(eq
->cap
& VEQ_CAP_SATURATION
) equal
.saturation
= eq
->saturation
;
3216 if(eq
->cap
& VEQ_CAP_HUE
) equal
.hue
= eq
->hue
;
3217 if(eq
->cap
& VEQ_CAP_RGB_INTENSITY
)
3219 equal
.red_intensity
= eq
->red_intensity
;
3220 equal
.green_intensity
= eq
->green_intensity
;
3221 equal
.blue_intensity
= eq
->blue_intensity
;
3223 equal
.flags
= eq
->flags
;
3225 br
= equal
.brightness
* 64 / 1000;
3226 if(br
< -64) br
= -64; if(br
> 63) br
= 63;
3227 sat
= (equal
.saturation
*31 + 31000) / 2000;
3228 if(sat
< 0) sat
= 0; if(sat
> 31) sat
= 31;
3229 OUTREG(OV0_COLOUR_CNTL
, (br
& 0x7f) | (sat
<< 8) | (sat
<< 16));
3231 itu_space
= equal
.flags
== VEQ_FLG_ITU_R_BT_709
? 1 : 0;
3232 RTFCheckParam(equal
.brightness
);
3233 RTFCheckParam(equal
.saturation
);
3234 RTFCheckParam(equal
.contrast
);
3235 RTFCheckParam(equal
.hue
);
3236 RTFCheckParam(equal
.red_intensity
);
3237 RTFCheckParam(equal
.green_intensity
);
3238 RTFCheckParam(equal
.blue_intensity
);
3239 radeon_set_transform(RTFBrightness(equal
.brightness
),
3240 RTFContrast(equal
.contrast
),
3241 RTFSaturation(equal
.saturation
),
3243 RTFIntensity(equal
.red_intensity
),
3244 RTFIntensity(equal
.green_intensity
),
3245 RTFIntensity(equal
.blue_intensity
),
3251 static int radeon_playback_set_deint(const vidix_deinterlace_t
* info
)
3257 case CFG_NON_INTERLACED
:
3258 besr
.deinterlace_on
= 0;
3260 case CFG_EVEN_ODD_INTERLACING
:
3261 case CFG_INTERLACED
:
3262 besr
.deinterlace_on
= 1;
3263 besr
.deinterlace_pattern
= 0x900AAAAA;
3265 case CFG_ODD_EVEN_INTERLACING
:
3266 besr
.deinterlace_on
= 1;
3267 besr
.deinterlace_pattern
= 0x00055555;
3269 case CFG_UNIQUE_INTERLACING
:
3270 besr
.deinterlace_on
= 1;
3271 besr
.deinterlace_pattern
= info
->deinterlace_pattern
;
3274 OUTREG(OV0_REG_LOAD_CNTL
, REG_LD_CTL_LOCK
);
3275 radeon_engine_idle();
3276 while(!(INREG(OV0_REG_LOAD_CNTL
)®_LD_CTL_LOCK_READBACK
));
3277 radeon_fifo_wait(15);
3278 sflg
= INREG(OV0_SCALE_CNTL
);
3279 if(besr
.deinterlace_on
)
3281 OUTREG(OV0_SCALE_CNTL
,sflg
| SCALER_ADAPTIVE_DEINT
);
3282 OUTREG(OV0_DEINTERLACE_PATTERN
,besr
.deinterlace_pattern
);
3284 else OUTREG(OV0_SCALE_CNTL
,sflg
& (~SCALER_ADAPTIVE_DEINT
));
3285 OUTREG(OV0_REG_LOAD_CNTL
, 0);
3289 static int radeon_playback_get_deint(vidix_deinterlace_t
* info
)
3291 if(!besr
.deinterlace_on
) info
->flags
= CFG_NON_INTERLACED
;
3294 info
->flags
= CFG_UNIQUE_INTERLACING
;
3295 info
->deinterlace_pattern
= besr
.deinterlace_pattern
;
3302 static vidix_grkey_t radeon_grkey
;
3304 static int set_gr_key( void )
3308 besr
.merge_cntl
= 0xff000000 | /* overlay alpha */
3309 0x00ff0000; /* graphic alpha */
3310 if(radeon_grkey
.ckey
.op
== CKEY_TRUE
)
3312 int dbpp
=radeon_vid_get_dbpp();
3319 if((besr
.chip_flags
&R_100
)!=R_100
)
3320 besr
.graphics_key_clr
=
3321 ((radeon_grkey
.ckey
.blue
&0xF8))
3322 | ((radeon_grkey
.ckey
.green
&0xF8)<<8)
3323 | ((radeon_grkey
.ckey
.red
&0xF8)<<16);
3326 besr
.graphics_key_clr
=
3327 ((radeon_grkey
.ckey
.blue
&0xF8)>>3)
3328 | ((radeon_grkey
.ckey
.green
&0xF8)<<2)
3329 | ((radeon_grkey
.ckey
.red
&0xF8)<<7);
3333 /* This test may be too general/specific */
3334 if((besr
.chip_flags
&R_100
)!=R_100
)
3335 besr
.graphics_key_clr
=
3336 ((radeon_grkey
.ckey
.blue
&0xF8))
3337 | ((radeon_grkey
.ckey
.green
&0xFC)<<8)
3338 | ((radeon_grkey
.ckey
.red
&0xF8)<<16);
3341 besr
.graphics_key_clr
=
3342 ((radeon_grkey
.ckey
.blue
&0xF8)>>3)
3343 | ((radeon_grkey
.ckey
.green
&0xFC)<<3)
3344 | ((radeon_grkey
.ckey
.red
&0xF8)<<8);
3348 besr
.graphics_key_clr
=
3349 ((radeon_grkey
.ckey
.blue
&0xFF))
3350 | ((radeon_grkey
.ckey
.green
&0xFF)<<8)
3351 | ((radeon_grkey
.ckey
.red
&0xFF)<<16);
3355 besr
.graphics_key_msk
=0;
3356 besr
.graphics_key_clr
=0;
3359 besr
.graphics_key_msk
=(1<<dbpp
)-1;
3360 besr
.ckey_cntl
= VIDEO_KEY_FN_TRUE
|GRAPHIC_KEY_FN_NE
|CMP_MIX_AND
;
3362 besr
.graphics_key_msk
=besr
.graphics_key_clr
;
3363 besr
.ckey_cntl
= VIDEO_KEY_FN_TRUE
|CMP_MIX_AND
|GRAPHIC_KEY_FN_EQ
;
3366 else if(radeon_grkey
.ckey
.op
== CKEY_ALPHA
)
3368 int dbpp
=radeon_vid_get_dbpp();
3375 besr
.graphics_key_msk
=0;
3376 besr
.graphics_key_clr
=0;
3377 besr
.ckey_cntl
= VIDEO_KEY_FN_TRUE
|GRAPHIC_KEY_FN_TRUE
|CMP_MIX_AND
;
3378 besr
.merge_cntl
|= 0x00000001; /* DISP_ALPHA_MODE_PER_PIXEL */
3382 besr
.graphics_key_msk
=0;
3383 besr
.graphics_key_clr
=0;
3384 besr
.ckey_cntl
= VIDEO_KEY_FN_TRUE
|GRAPHIC_KEY_FN_TRUE
|CMP_MIX_AND
;
3391 besr
.graphics_key_msk
=0;
3392 besr
.graphics_key_clr
=0;
3393 besr
.ckey_cntl
= VIDEO_KEY_FN_TRUE
|GRAPHIC_KEY_FN_TRUE
|CMP_MIX_AND
;
3394 besr
.merge_cntl
|= 0x00000100; /* DISP_RGB_OFFSET_EN */
3396 radeon_fifo_wait(3);
3397 OUTREG(OV0_GRAPHICS_KEY_MSK
, besr
.graphics_key_msk
);
3398 OUTREG(OV0_GRAPHICS_KEY_CLR
, besr
.graphics_key_clr
);
3399 OUTREG(OV0_KEY_CNTL
,besr
.ckey_cntl
);
3400 OUTREG(DISP_MERGE_CNTL
, besr
.merge_cntl
);
3404 static int radeon_get_gkey(vidix_grkey_t
*grkey
)
3406 memcpy(grkey
, &radeon_grkey
, sizeof(vidix_grkey_t
));
3410 static int radeon_set_gkey(const vidix_grkey_t
*grkey
)
3412 memcpy(&radeon_grkey
, grkey
, sizeof(vidix_grkey_t
));
3413 return set_gr_key();
3417 VDXDriver rage128_drv
= {
3420 VDXDriver radeon_drv
= {
3425 .probe
= radeon_probe
,
3426 .get_caps
= radeon_get_caps
,
3427 .query_fourcc
= radeon_query_fourcc
,
3428 .init
= radeon_init
,
3429 .destroy
= radeon_destroy
,
3430 .config_playback
= radeon_config_playback
,
3431 .playback_on
= radeon_playback_on
,
3432 .playback_off
= radeon_playback_off
,
3433 .frame_sel
= radeon_frame_select
,
3434 .get_eq
= radeon_get_eq
,
3435 .set_eq
= radeon_set_eq
,
3436 .get_deint
= radeon_playback_get_deint
,
3437 .set_deint
= radeon_playback_set_deint
,
3438 .get_gkey
= radeon_get_gkey
,
3439 .set_gkey
= radeon_set_gkey
,