BTRFS: Implement BTree::Path and change _Find.
[haiku.git] / src / add-ons / accelerants / radeon / internal_tv_out.c
blob9ff49ecd27fb4d3f380b1faf98eb8a7b6852014b
1 /*
2 Copyright (c) 2002/03, Thomas Kurschel
5 Part of Radeon accelerant
7 Programming of internal TV-out unit
8 */
10 #include "radeon_interface.h"
11 #include "radeon_accelerant.h"
13 #include "tv_out_regs.h"
14 #include "pll_access.h"
15 #include "mmio.h"
16 #include "utils.h"
17 #include "set_mode.h"
19 #include <stdlib.h>
22 // mapping of offset in impactv_regs to register address
23 typedef struct register_mapping {
24 uint16 address; // register address
25 uint16 offset; // offset in impactv_regs
26 } register_mapping;
29 // internal TV-encoder:
31 // registers to write before programming PLL
32 static const register_mapping intern_reg_mapping_before_pll[] = {
33 { RADEON_TV_MASTER_CNTL, offsetof( impactv_regs, tv_master_cntl ) },
34 { RADEON_TV_HRESTART, offsetof( impactv_regs, tv_hrestart ) },
35 { RADEON_TV_VRESTART, offsetof( impactv_regs, tv_vrestart ) },
36 { RADEON_TV_FRESTART, offsetof( impactv_regs, tv_frestart ) },
37 { RADEON_TV_FTOTAL, offsetof( impactv_regs, tv_ftotal ) },
38 { 0, 0 }
41 // PLL registers to program
42 static const register_mapping intern_reg_mapping_pll[] = {
43 { RADEON_TV_PLL_CNTL, offsetof( impactv_regs, tv_tv_pll_cntl ) },
44 { RADEON_TV_PLL_CNTL1, offsetof( impactv_regs, tv_pll_cntl1 ) },
45 { RADEON_TV_PLL_FINE_CNTL, offsetof( impactv_regs, tv_pll_fine_cntl ) },
46 { 0, 0 }
49 // registers to write after programming of PLL
50 static const register_mapping intern_reg_mapping_after_pll[] = {
51 { RADEON_TV_HTOTAL, offsetof( impactv_regs, tv_htotal ) },
52 { RADEON_TV_HDISP, offsetof( impactv_regs, tv_hdisp ) },
53 { RADEON_TV_HSTART, offsetof( impactv_regs, tv_hstart ) },
54 { RADEON_TV_VTOTAL, offsetof( impactv_regs, tv_vtotal ) },
55 { RADEON_TV_VDISP, offsetof( impactv_regs, tv_vdisp ) },
57 { RADEON_TV_TIMING_CNTL, offsetof( impactv_regs, tv_timing_cntl ) },
59 { RADEON_TV_VSCALER_CNTL1, offsetof( impactv_regs, tv_vscaler_cntl1 ) },
60 { RADEON_TV_VSCALER_CNTL2, offsetof( impactv_regs, tv_vscaler_cntl2 ) },
62 { RADEON_TV_Y_SAW_TOOTH_CNTL, offsetof( impactv_regs, tv_y_saw_tooth_cntl ) },
63 { RADEON_TV_Y_RISE_CNTL, offsetof( impactv_regs, tv_y_rise_cntl ) },
64 { RADEON_TV_Y_FALL_CNTL, offsetof( impactv_regs, tv_y_fall_cntl ) },
66 { RADEON_TV_MODULATOR_CNTL1, offsetof( impactv_regs, tv_modulator_cntl1 ) },
67 { RADEON_TV_MODULATOR_CNTL2, offsetof( impactv_regs, tv_modulator_cntl2 ) },
68 { RADEON_TV_RGB_CNTL, offsetof( impactv_regs, tv_rgb_cntl ) },
69 { RADEON_TV_UV_ADR, offsetof( impactv_regs, tv_uv_adr ) },
70 { RADEON_TV_PRE_DAC_MUX_CNTL, offsetof( impactv_regs, tv_pre_dac_mux_cntl ) },
71 { RADEON_TV_CRC_CNTL, offsetof( impactv_regs, tv_crc_cntl ) },
72 { 0, 0 }
75 // registers to write when things settled down
76 static const register_mapping intern_reg_mapping_finish[] = {
77 { RADEON_TV_GAIN_LIMIT_SETTINGS, offsetof( impactv_regs, tv_gain_limit_settings ) },
78 { RADEON_TV_LINEAR_GAIN_SETTINGS, offsetof( impactv_regs, tv_linear_gain_settings ) },
79 { RADEON_TV_UPSAMP_AND_GAIN_CNTL, offsetof( impactv_regs, tv_upsamp_and_gain_cntl ) },
81 { RADEON_TV_DAC_CNTL, offsetof( impactv_regs, tv_dac_cntl ) },
82 { RADEON_TV_MASTER_CNTL, offsetof( impactv_regs, tv_master_cntl ) },
83 { 0, 0 }
89 // write list of MM I/O registers
90 static void writeMMIORegList(
91 accelerator_info *ai, impactv_regs *values, const register_mapping *mapping )
93 vuint8 *regs = ai->regs;
95 for( ; mapping->address != 0 && mapping->offset != 0; ++mapping ) {
96 /*SHOW_FLOW( 2, "%x=%x", mapping->address,
97 *(uint32 *)((char *)(values) + mapping->offset) );*/
99 OUTREG( regs, mapping->address, *(uint32 *)((char *)(values) + mapping->offset) );
102 //snooze( 1000000 );
106 // write list of PLL registers
107 static void writePLLRegList(
108 accelerator_info *ai, impactv_regs *values, const register_mapping *mapping )
110 for( ; mapping->address != 0 && mapping->offset != 0; ++mapping ) {
111 /*SHOW_FLOW( 2, "%x=%x", mapping->address,
112 *(uint32 *)((char *)(values) + mapping->offset) );*/
114 Radeon_OUTPLL( ai->regs, ai->si->asic,
115 mapping->address, *(uint32 *)((char *)(values) + mapping->offset) );
118 //snooze( 1000000 );
124 // read timing FIFO
125 #if 0
126 static uint32 Radeon_InternalTVOutReadFIFO(
127 accelerator_info *ai, uint16 addr )
129 vuint8 *regs = ai->regs;
130 bigtime_t start_time;
131 uint32 res = ~0;
133 //SHOW_FLOW( 2, "addr=%d", addr );
135 OUTREG( regs, RADEON_TV_HOST_RD_WT_CNTL, addr | RADEON_TV_HOST_RD_WT_CNTL_RD);
137 start_time = system_time();
139 do {
140 uint32 status;
142 status = INREG( regs, RADEON_TV_HOST_RD_WT_CNTL );
144 if( (status & RADEON_TV_HOST_RD_WT_CNTL_RD_ACK) != 0 )
145 break;
146 } while( system_time() - start_time < 2000000 );
148 OUTREG( regs, RADEON_TV_HOST_RD_WT_CNTL, 0);
149 res = INREG( regs, RADEON_TV_HOST_READ_DATA );
151 //SHOW_FLOW( 2, "res=%x %x", res >> 14, res & 0x3fff );
153 return res;
155 #endif
157 // write to timing FIFO
158 static void Radeon_InternalTVOutWriteFIFO(
159 accelerator_info *ai, uint16 addr, uint32 value )
161 vuint8 *regs = ai->regs;
162 bigtime_t start_time;
164 //readFIFO( ai, addr, internal_encoder );
166 //SHOW_FLOW( 2, "addr=%d, value=%x %x", addr, value >> 14, value & 0x3fff );
168 OUTREG( regs, RADEON_TV_HOST_WRITE_DATA, value );
169 OUTREG( regs, RADEON_TV_HOST_RD_WT_CNTL, addr | RADEON_TV_HOST_RD_WT_CNTL_WT );
171 start_time = system_time();
173 do {
174 uint32 status;
176 status = INREG( regs, RADEON_TV_HOST_RD_WT_CNTL );
178 if( (status & RADEON_TV_HOST_RD_WT_CNTL_WT_ACK) != 0 )
179 break;
180 } while( system_time() - start_time < 2000000 );
182 OUTREG( regs, RADEON_TV_HOST_RD_WT_CNTL, 0 );
186 // program TV-Out registers
187 void Radeon_InternalTVOutProgramRegisters(
188 accelerator_info *ai, impactv_regs *values )
190 uint32 orig_tv_master_cntl = values->tv_master_cntl;
192 SHOW_FLOW0( 2, "" );
194 // disable TV-out when registers are setup
195 // it gets enabled again when things have settled down
196 values->tv_master_cntl |=
197 RADEON_TV_MASTER_CNTL_TV_ASYNC_RST |
198 RADEON_TV_MASTER_CNTL_CRT_ASYNC_RST |
199 RADEON_TV_MASTER_CNTL_TV_FIFO_ASYNC_RST |
201 RADEON_TV_MASTER_CNTL_VIN_ASYNC_RST |
202 RADEON_TV_MASTER_CNTL_AUD_ASYNC_RST |
203 RADEON_TV_MASTER_CNTL_DVS_ASYNC_RST;
205 writeMMIORegList( ai, values, intern_reg_mapping_before_pll );
206 writePLLRegList( ai, values, intern_reg_mapping_pll );
207 writeMMIORegList( ai, values, intern_reg_mapping_after_pll );
209 // un-reset FIFO to access timing table
210 OUTREG( ai->regs, RADEON_TV_MASTER_CNTL,
211 orig_tv_master_cntl |
212 RADEON_TV_MASTER_CNTL_TV_ASYNC_RST |
213 RADEON_TV_MASTER_CNTL_CRT_ASYNC_RST |
215 RADEON_TV_MASTER_CNTL_VIN_ASYNC_RST |
216 RADEON_TV_MASTER_CNTL_AUD_ASYNC_RST |
217 RADEON_TV_MASTER_CNTL_DVS_ASYNC_RST );
219 Radeon_ImpacTVwriteHorTimingTable( ai, Radeon_InternalTVOutWriteFIFO, values, true );
220 Radeon_ImpacTVwriteVertTimingTable( ai, Radeon_InternalTVOutWriteFIFO, values );
222 snooze( 50000 );
224 values->tv_master_cntl = orig_tv_master_cntl;
225 writeMMIORegList( ai, values, intern_reg_mapping_finish );
229 // read list of MM I/O registers
230 static void readMMIORegList(
231 accelerator_info *ai, impactv_regs *values, const register_mapping *mapping )
233 vuint8 *regs = ai->regs;
235 for( ; mapping->address != 0 && mapping->offset != 0; ++mapping ) {
236 *(uint32 *)((char *)(values) + mapping->offset) =
237 INREG( regs, mapping->address );
239 /*SHOW_FLOW( 2, "%x=%x", mapping->address,
240 *(uint32 *)((char *)(values) + mapping->offset) );*/
243 //snooze( 1000000 );
247 // read list of PLL registers
248 static void readPLLRegList(
249 accelerator_info *ai, impactv_regs *values, const register_mapping *mapping )
251 for( ; mapping->address != 0 && mapping->offset != 0; ++mapping ) {
252 *(uint32 *)((char *)(values) + mapping->offset) =
253 Radeon_INPLL( ai->regs, ai->si->asic, mapping->address );
255 /*SHOW_FLOW( 2, "%x=%x", mapping->address,
256 *(uint32 *)((char *)(values) + mapping->offset) );*/
259 //snooze( 1000000 );
263 // read TV-Out registers
264 void Radeon_InternalTVOutReadRegisters(
265 accelerator_info *ai, impactv_regs *values )
267 readMMIORegList( ai, values, intern_reg_mapping_before_pll );
268 readPLLRegList( ai, values, intern_reg_mapping_pll );
269 readMMIORegList( ai, values, intern_reg_mapping_after_pll );
270 readMMIORegList( ai, values, intern_reg_mapping_finish );
272 //snooze( 1000000 );