1/*
2 * Copyright 2000 ATI Technologies Inc., Markham, Ontario, and
3 *                VA Linux Systems Inc., Fremont, California.
4 *
5 * All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining
8 * a copy of this software and associated documentation files (the
9 * "Software"), to deal in the Software without restriction, including
10 * without limitation on the rights to use, copy, modify, merge,
11 * publish, distribute, sublicense, and/or sell copies of the Software,
12 * and to permit persons to whom the Software is furnished to do so,
13 * subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice (including the
16 * next paragraph) shall be included in all copies or substantial
17 * portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22 * NON-INFRINGEMENT.  IN NO EVENT SHALL ATI, VA LINUX SYSTEMS AND/OR
23 * THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
24 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26 * DEALINGS IN THE SOFTWARE.
27 */
28
29/*
30 * Authors:
31 *   Kevin E. Martin <martin@xfree86.org>
32 *   Rickard E. Faith <faith@valinux.com>
33 *   Alan Hourihane <alanh@fairlite.demon.co.uk>
34 *
35 * References:
36 *
37 * !!!! FIXME !!!!
38 *   RAGE 128 VR/ RAGE 128 GL Register Reference Manual (Technical
39 *   Reference Manual P/N RRG-G04100-C Rev. 0.04), ATI Technologies: April
40 *   1999.
41 *
42 * !!!! FIXME !!!!
43 *   RAGE 128 Software Development Manual (Technical Reference Manual P/N
44 *   SDK-G04000 Rev. 0.01), ATI Technologies: June 1999.
45 *
46 */
47
48
49#ifndef _RADEON_MACROS_H_
50#define _RADEON_MACROS_H_
51
52#include "compiler.h"
53
54#define RADEON_BIOS8(v)  (info->VBIOS[v])
55#define RADEON_BIOS16(v) (info->VBIOS[v] | \
56                          (info->VBIOS[(v) + 1] << 8))
57#define RADEON_BIOS32(v) (info->VBIOS[v] | \
58                          (info->VBIOS[(v) + 1] << 8) | \
59                          (info->VBIOS[(v) + 2] << 16) | \
60                          (info->VBIOS[(v) + 3] << 24))
61
62				/* Memory mapped register access macros */
63#define INREG8(addr)        MMIO_IN8(RADEONMMIO, addr)
64#define INREG16(addr)       MMIO_IN16(RADEONMMIO, addr)
65#define INREG(addr)         MMIO_IN32(RADEONMMIO, addr)
66#define OUTREG8(addr, val)  MMIO_OUT8(RADEONMMIO, addr, val)
67#define OUTREG16(addr, val) MMIO_OUT16(RADEONMMIO, addr, val)
68#define OUTREG(addr, val)   MMIO_OUT32(RADEONMMIO, addr, val)
69
70#define ADDRREG(addr)       ((volatile uint32_t *)(pointer)(RADEONMMIO + (addr)))
71
72
73#define OUTREGP(addr, val, mask)					\
74do {									\
75    uint32_t tmp = INREG(addr);						\
76    tmp &= (mask);							\
77    tmp |= ((val) & ~(mask));						\
78    OUTREG(addr, tmp);							\
79} while (0)
80
81#define INPLL(pScrn, addr) RADEONINPLL(pScrn, addr)
82
83#define OUTPLL(pScrn, addr, val) RADEONOUTPLL(pScrn, addr, val)
84
85#define OUTPLLP(pScrn, addr, val, mask)					\
86do {									\
87    uint32_t tmp_ = INPLL(pScrn, addr);					\
88    tmp_ &= (mask);							\
89    tmp_ |= ((val) & ~(mask));						\
90    OUTPLL(pScrn, addr, tmp_);						\
91} while (0)
92
93#define OUTPAL_START(idx)						\
94do {									\
95    if (IS_AVIVO_VARIANT) {                                             \
96        OUTREG8(AVIVO_DC_LUT_RW_INDEX, (idx));				\
97    } else {                                                            \
98        OUTREG8(RADEON_PALETTE_INDEX, (idx));				\
99    }								        \
100} while (0)
101
102#define OUTPAL_NEXT(r, g, b)						\
103do {									\
104    if (IS_AVIVO_VARIANT) {                                             \
105        OUTREG(AVIVO_DC_LUT_30_COLOR, ((r) << 20) | ((g) << 10) | (b));	\
106    } else {                                                            \
107        OUTREG(RADEON_PALETTE_30_DATA, ((r) << 20) | ((g) << 10) | (b)); \
108    }								        \
109} while (0)
110
111#define OUTPAL(idx, r, g, b)						\
112do {									\
113    OUTPAL_START((idx));						\
114    OUTPAL_NEXT((r), (g), (b));						\
115} while (0)
116
117#define INPAL_START(idx)						\
118do {									\
119    if (IS_AVIVO_VARIANT) {                                             \
120        OUTREG8(AVIVO_DC_LUT_RW_INDEX, (idx));				\
121    } else {                                                            \
122        OUTREG(RADEON_PALETTE_INDEX, (idx) << 16);			\
123    }								        \
124} while (0)
125
126#define INPAL_NEXT()                                                    \
127do {									\
128    if (IS_AVIVO_VARIANT) {                                             \
129        INREG(AVIVO_DC_LUT_30_COLOR);                                   \
130    } else {                                                            \
131        INREG(RADEON_PALETTE_30_DATA);                                  \
132    }								        \
133} while (0)
134
135#define PAL_SELECT(idx)							\
136do {									\
137    if (IS_AVIVO_VARIANT) {                                             \
138        if (!idx) {							\
139	    OUTREG(AVIVO_DC_LUT_RW_SELECT, 0);                          \
140        } else {						        \
141	    OUTREG(AVIVO_DC_LUT_RW_SELECT, 1);                          \
142        }								\
143    } else {                                                            \
144        if (!idx) {							\
145	    OUTREG(RADEON_DAC_CNTL2, INREG(RADEON_DAC_CNTL2) &		\
146	           (uint32_t)~RADEON_DAC2_PALETTE_ACC_CTL);		\
147        } else {							\
148	    OUTREG(RADEON_DAC_CNTL2, INREG(RADEON_DAC_CNTL2) |		\
149	           RADEON_DAC2_PALETTE_ACC_CTL);			\
150        }								\
151    }								        \
152} while (0)
153
154#define INMC(pScrn, addr) RADEONINMC(pScrn, addr)
155#define OUTMC(pScrn, addr, val) RADEONOUTMC(pScrn, addr, val)
156
157#define INPCIE(pScrn, addr) RADEONINPCIE(pScrn, addr)
158#define OUTPCIE(pScrn, addr, val) RADEONOUTPCIE(pScrn, addr, val)
159
160#define INPCIE_P(pScrn, addr) R600INPCIE_PORT(pScrn, addr)
161#define OUTPCIE_P(pScrn, addr, val) R600OUTPCIE_PORT(pScrn, addr, val)
162
163#define BEGIN_ACCEL_RELOC(n, r) do {		\
164	int _nqw = (n) + (info->cs ? (r) : 0);	\
165	BEGIN_ACCEL(_nqw);			\
166    } while (0)
167
168#define CHECK_OFFSET(pPix, mask, type) do {	\
169    if (!info->cs) {			       \
170	uint32_t _pix_offset = radeonGetPixmapOffset(pPix);	\
171	if ((_pix_offset & mask) != 0)					\
172	    RADEON_FALLBACK(("Bad %s offset 0x%x\n", type, (int)_pix_offset)); \
173    }									\
174    } while(0)
175
176#define EMIT_OFFSET(reg, value, pPix, rd, wd) do {		\
177    if (info->cs) {						\
178	driver_priv = exaGetPixmapDriverPrivate(pPix);		\
179	OUT_ACCEL_REG((reg), (value));				\
180	OUT_RELOC(driver_priv->bo, (rd), (wd));			\
181    } else {							\
182	uint32_t _pix_offset;					\
183	_pix_offset = radeonGetPixmapOffset(pPix);	\
184	OUT_ACCEL_REG((reg), _pix_offset | value);		\
185    }								\
186    } while(0)
187
188#define EMIT_READ_OFFSET(reg, value, pPix) EMIT_OFFSET(reg, value, pPix, (RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT), 0)
189#define EMIT_WRITE_OFFSET(reg, value, pPix) EMIT_OFFSET(reg, value, pPix, 0, RADEON_GEM_DOMAIN_VRAM)
190
191#define OUT_TEXTURE_REG(reg, offset, bo) do {   \
192    if (info->cs) {                                                     \
193      OUT_ACCEL_REG((reg), (offset));                                   \
194      OUT_RELOC((bo), RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT, 0); \
195    } else {                                                            \
196      OUT_ACCEL_REG((reg), (offset) + info->fbLocation + pScrn->fbOffset);} \
197  } while(0)
198
199#define EMIT_COLORPITCH(reg, value, pPix) do {			\
200    if (info->cs) {						\
201	driver_priv = exaGetPixmapDriverPrivate(pPix);			\
202	OUT_ACCEL_REG((reg), value);					\
203	OUT_RELOC(driver_priv->bo, 0, RADEON_GEM_DOMAIN_VRAM);		\
204    } else {								\
205	OUT_ACCEL_REG((reg), value);					\
206    }									\
207}while(0)
208
209#endif
210