Fixed out-by-one error in previous commit.
[AROS.git] / workbench / hidds / hidd.radeon / radeon_accel.c
blob080ee9c11f49c9d5b27657486eb76b4c702ec75e
1 /*
2 Copyright © 2004, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include "ati.h"
7 #include "radeon.h"
8 #include "radeon_reg.h"
9 #include "radeon_bios.h"
10 #include "radeon_accel.h"
11 #include "radeon_macros.h"
14 #define DEBUG 1
15 #include <aros/debug.h>
17 struct __ROP RADEON_ROP[] = {
18 { RADEON_ROP3_ZERO, RADEON_ROP3_ZERO }, /* GXclear */
19 { RADEON_ROP3_DSa, RADEON_ROP3_DPa }, /* Gxand */
20 { RADEON_ROP3_SDna, RADEON_ROP3_PDna }, /* GXandReverse */
21 { RADEON_ROP3_S, RADEON_ROP3_P }, /* GXcopy */
22 { RADEON_ROP3_DSna, RADEON_ROP3_DPna }, /* GXandInverted */
23 { RADEON_ROP3_D, RADEON_ROP3_D }, /* GXnoop */
24 { RADEON_ROP3_DSx, RADEON_ROP3_DPx }, /* GXxor */
25 { RADEON_ROP3_DSo, RADEON_ROP3_DPo }, /* GXor */
26 { RADEON_ROP3_DSon, RADEON_ROP3_DPon }, /* GXnor */
27 { RADEON_ROP3_DSxn, RADEON_ROP3_PDxn }, /* GXequiv */
28 { RADEON_ROP3_Dn, RADEON_ROP3_Dn }, /* GXinvert */
29 { RADEON_ROP3_SDno, RADEON_ROP3_PDno }, /* GXorReverse */
30 { RADEON_ROP3_Sn, RADEON_ROP3_Pn }, /* GXcopyInverted */
31 { RADEON_ROP3_DSno, RADEON_ROP3_DPno }, /* GXorInverted */
32 { RADEON_ROP3_DSan, RADEON_ROP3_DPan }, /* GXnand */
33 { RADEON_ROP3_ONE, RADEON_ROP3_ONE } /* GXset */
36 /* The FIFO has 64 slots. This routines waits until at least `entries'
37 * of these slots are empty.
39 void RADEONWaitForFifoFunction(struct ati_staticdata *sd, int entries)
41 int i;
43 for (;;) {
44 for (i = 0; i < RADEON_TIMEOUT; i++) {
45 sd->Card.FIFOSlots =
46 INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_FIFOCNT_MASK;
47 if (sd->Card.FIFOSlots == 64) sd->Card.Busy = FALSE;
48 if (sd->Card.FIFOSlots >= entries) return;
50 D(bug("[ATI] FIFO timed out: %d entries, stat=0x%08x\n",
51 INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_FIFOCNT_MASK,
52 INREG(RADEON_RBBM_STATUS)));
53 RADEONEngineReset(sd);
54 RADEONEngineRestore(sd);
58 /* The FIFO has 64 slots. This routines waits until at least `entries'
59 * of these slots are empty.
61 void RADEONWaitForIdleMMIO(struct ati_staticdata *sd)
63 int i;
65 /* Wait for the engine to go idle */
66 RADEONWaitForFifoFunction(sd, 64);
68 for (;;) {
69 for (i = 0; i < RADEON_TIMEOUT; i++) {
70 if (!(INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_ACTIVE)) {
71 RADEONEngineFlush(sd);
72 sd->Card.Busy = FALSE;
73 return;
76 D(bug("[ATI] Idle timed out: %d entries, stat=0x%08x\n",
77 INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_FIFOCNT_MASK,
78 INREG(RADEON_RBBM_STATUS)));
79 RADEONEngineReset(sd);
80 RADEONEngineRestore(sd);
84 /* Flush all dirty data in the Pixel Cache to memory */
85 void RADEONEngineFlush(struct ati_staticdata *sd)
87 int i;
89 OUTREGP(RADEON_RB2D_DSTCACHE_CTLSTAT,
90 RADEON_RB2D_DC_FLUSH_ALL,
91 ~RADEON_RB2D_DC_FLUSH_ALL);
92 for (i = 0; i < RADEON_TIMEOUT; i++) {
93 if (!(INREG(RADEON_RB2D_DSTCACHE_CTLSTAT) & RADEON_RB2D_DC_BUSY))
94 break;
98 /* Reset graphics card to known state */
99 void RADEONEngineReset(struct ati_staticdata *sd)
101 ULONG clock_cntl_index;
102 ULONG mclk_cntl;
103 ULONG rbbm_soft_reset;
104 ULONG host_path_cntl;
106 RADEONEngineFlush(sd);
108 clock_cntl_index = INREG(RADEON_CLOCK_CNTL_INDEX);
109 if (sd->Card.R300CGWorkaround) R300CGWorkaround(sd);
111 mclk_cntl = RADEONINPLL(sd, RADEON_MCLK_CNTL);
113 host_path_cntl = INREG(RADEON_HOST_PATH_CNTL);
114 rbbm_soft_reset = INREG(RADEON_RBBM_SOFT_RESET);
116 if (IS_R300_VARIANT) {
117 ULONG tmp;
119 OUTREG(RADEON_RBBM_SOFT_RESET, (rbbm_soft_reset |
120 RADEON_SOFT_RESET_CP |
121 RADEON_SOFT_RESET_HI |
122 RADEON_SOFT_RESET_E2));
123 INREG(RADEON_RBBM_SOFT_RESET);
124 OUTREG(RADEON_RBBM_SOFT_RESET, 0);
125 tmp = INREG(RADEON_RB2D_DSTCACHE_MODE);
126 OUTREG(RADEON_RB2D_DSTCACHE_MODE, tmp | (1 << 17)); /* FIXME */
127 } else {
128 OUTREG(RADEON_RBBM_SOFT_RESET, (rbbm_soft_reset |
129 RADEON_SOFT_RESET_CP |
130 RADEON_SOFT_RESET_SE |
131 RADEON_SOFT_RESET_RE |
132 RADEON_SOFT_RESET_PP |
133 RADEON_SOFT_RESET_E2 |
134 RADEON_SOFT_RESET_RB));
135 INREG(RADEON_RBBM_SOFT_RESET);
136 OUTREG(RADEON_RBBM_SOFT_RESET, (rbbm_soft_reset & (ULONG)
137 ~(RADEON_SOFT_RESET_CP |
138 RADEON_SOFT_RESET_SE |
139 RADEON_SOFT_RESET_RE |
140 RADEON_SOFT_RESET_PP |
141 RADEON_SOFT_RESET_E2 |
142 RADEON_SOFT_RESET_RB)));
143 INREG(RADEON_RBBM_SOFT_RESET);
146 OUTREG(RADEON_HOST_PATH_CNTL, host_path_cntl | RADEON_HDP_SOFT_RESET);
147 INREG(RADEON_HOST_PATH_CNTL);
148 OUTREG(RADEON_HOST_PATH_CNTL, host_path_cntl);
150 if (IS_R300_VARIANT)
151 OUTREG(RADEON_RBBM_SOFT_RESET, rbbm_soft_reset);
153 OUTREG(RADEON_CLOCK_CNTL_INDEX, clock_cntl_index);
154 OUTPLL(RADEON_MCLK_CNTL, mclk_cntl);
155 if (sd->Card.R300CGWorkaround) R300CGWorkaround(sd);
157 OUTREG(RADEON_RB3D_CNTL, 0);
160 /* Restore the acceleration hardware to its previous state */
161 void RADEONEngineRestore(struct ati_staticdata *sd)
163 RADEONWaitForFifo(sd, 1);
165 /* NOTE: The following RB2D_DSTCACHE_MODE setting will cause the
166 * R300 to hang. ATI does not see a reason to change it from the
167 * default BIOS settings (even on non-R300 cards). This setting
168 * might be removed in future versions of the Radeon driver.
171 /* Turn of all automatic flushing - we'll do it all */
172 if (!IS_R300_VARIANT)
173 OUTREG(RADEON_RB2D_DSTCACHE_MODE, 0);
175 RADEONWaitForFifo(sd, 1);
176 #if AROS_BIG_ENDIAN
177 OUTREGP(RADEON_DP_DATATYPE,
178 RADEON_HOST_BIG_ENDIAN_EN,
179 ~RADEON_HOST_BIG_ENDIAN_EN);
180 #else
181 OUTREGP(RADEON_DP_DATATYPE, 0, ~RADEON_HOST_BIG_ENDIAN_EN);
182 #endif
184 RADEONWaitForFifo(sd, 1);
185 OUTREG(RADEON_DEFAULT_SC_BOTTOM_RIGHT, (RADEON_DEFAULT_SC_RIGHT_MAX
186 | RADEON_DEFAULT_SC_BOTTOM_MAX));
188 RADEONWaitForFifo(sd, 7);
189 OUTREG(RADEON_DST_LINE_START, 0);
190 OUTREG(RADEON_DST_LINE_END, 0);
191 OUTREG(RADEON_DP_BRUSH_FRGD_CLR, 0xffffffff);
192 OUTREG(RADEON_DP_BRUSH_BKGD_CLR, 0x00000000);
193 OUTREG(RADEON_DP_SRC_FRGD_CLR, 0xffffffff);
194 OUTREG(RADEON_DP_SRC_BKGD_CLR, 0x00000000);
195 OUTREG(RADEON_DP_WRITE_MASK, 0xffffffff);
197 RADEONWaitForIdleMMIO(sd);