xref: /haiku/src/add-ons/kernel/drivers/graphics/radeon/pll_access.c (revision db10640de90f7f9519ba2da9577b7c1af3c64f6b)
1 /*
2 	Copyright (c) 2002/03, Thomas Kurschel
3 
4 
5 	Part of Radeon driver and accelerant
6 
7 	Basic access of PLL registers
8 */
9 
10 #include "radeon_interface.h"
11 #include "pll_access.h"
12 #include "pll_regs.h"
13 #include "utils.h"
14 
15 // read value "val" from PLL-register "addr"
16 uint32 Radeon_INPLL( vuint8 *regs, radeon_type asic, int addr )
17 {
18 	uint32 res;
19 
20 	OUTREG8( regs, RADEON_CLOCK_CNTL_INDEX, addr & 0x3f );
21 	res = INREG( regs, RADEON_CLOCK_CNTL_DATA );
22 
23 	R300_PLLFix( regs, asic );
24 	return res;
25 }
26 
27 // write value "val" to PLL-register "addr"
28 void Radeon_OUTPLL( vuint8 *regs, radeon_type asic, uint8 addr, uint32 val )
29 {
30 	(void)asic;
31 
32 	OUTREG8( regs, RADEON_CLOCK_CNTL_INDEX, ((addr & 0x3f ) |
33 		RADEON_PLL_WR_EN));
34 
35 	OUTREG( regs, RADEON_CLOCK_CNTL_DATA, val );
36 
37 	// TBD: on XFree, there is no call of R300_PLLFix here,
38 	// though it should as we've accessed CLOCK_CNTL_INDEX
39 	//R300_PLLFix( ai );
40 }
41 
42 // write "val" to PLL-register "addr" keeping bits "mask"
43 void Radeon_OUTPLLP( vuint8 *regs, radeon_type asic, uint8 addr,
44 	uint32 val, uint32 mask )
45 {
46 	uint32 tmp = Radeon_INPLL( regs, asic, addr );
47 	tmp &= mask;
48 	tmp |= val;
49 	Radeon_OUTPLL( regs, asic, addr, tmp );
50 }
51 
52 // r300: to be called after each CLOCK_CNTL_INDEX access
53 // (hardware bug fix suggested by XFree86)
54 void R300_PLLFix( vuint8 *regs, radeon_type asic )
55 {
56 	uint32 save, tmp;
57 
58 	if( asic != rt_r300 )
59 		return;
60 
61     save = INREG( regs, RADEON_CLOCK_CNTL_INDEX );
62     tmp = save & ~(0x3f | RADEON_PLL_WR_EN);
63     OUTREG( regs, RADEON_CLOCK_CNTL_INDEX, tmp );
64     tmp = INREG( regs, RADEON_CLOCK_CNTL_DATA );
65     OUTREG( regs, RADEON_CLOCK_CNTL_INDEX, save );
66 }
67