1 /* 2 Copyright (c) 2003 Andreas Robinson, All rights reserved. 3 4 This library is free software; you can redistribute it and/or 5 modify it under the terms of the GNU Lesser General Public 6 License as published by the Free Software Foundation; either 7 version 2 of the License, or (at your option) any later version. 8 */ 9 10 #ifndef __UC_FIFO_H__ 11 #define __UC_FIFO_H__ 12 13 // Note to self: remove when added to makefile as -DUC_DEBUG. 14 #define UC_DEBUG 1 15 16 #include <dfb_types.h> 17 18 #include "regs2d.h" 19 #include "regs3d.h" 20 #include "mmio.h" 21 22 /** 23 * uc_fifo - GPU data queue. 24 * 25 * buf: buffer start (userspace address) 26 * head: pointer to first unused entry. 27 * 28 * size: maximum number of entries in the fifo. 29 * prep: number of entries allocated to be used. 30 * used: number of entries currently in use. 31 * 32 * hwregs: GPU register base address 33 * reg_tset: address to GPU TRANSET register 34 * reg_tspace: address to GPU TRANSPACE register 35 * 36 * flush: function pointer to flush function (DMA or CPU) 37 * flush_sys: function pointer to flush_sys (non-DMA) function 38 */ 39 40 struct uc_fifo 41 { 42 u32* buf; 43 u32* head; 44 45 unsigned int size; 46 unsigned int prep; 47 unsigned int used; 48 49 //void (*flush)(struct uc_fifo* fifo, volatile void *hwregs); 50 //void (*flush_sys)(struct uc_fifo* fifo, volatile void *hwregs); 51 }; 52 53 // Help macros --------------------------------------------------------------- 54 55 // For the record: Macros suck maintenance- and debugging-wise, 56 // but provide guaranteed inlining of the code. 57 58 /** 59 * Send the contents of the FIFO buffer to the hardware, and clear 60 * the buffer. The transfer may be performed by the CPU or by DMA. 61 */ 62 63 //#define UC_FIFO_FLUSH(fifo) (fifo)->flush(fifo,ucdrv->hwregs) 64 65 /** 66 * Same as UC_FIFO_FLUSH(), but always uses the CPU to transfer data. 67 */ 68 69 //#define UC_FIFO_FLUSH_SYS(fifo) (fifo)->flush_sys(fifo,ucdrv->hwregs) 70 71 #define UC_FIFO_FLUSH(fifo) uc_fifo_flush_sys(fifo,ucdrv->hwregs) 72 #define UC_FIFO_FLUSH_SYS(fifo) uc_fifo_flush_sys(fifo,ucdrv->hwregs) 73 74 /** 75 * Make sure there is room for dwsize double words in the FIFO. 76 * If necessary, the FIFO is flushed first. 77 * 78 * @param fifo the fifo 79 * @param dwsize number of double words to allocate 80 * 81 * @note It is ok to request more space than you will actually 82 * be using. This is useful when you don't know exactly beforehand 83 * how many entries you need. 84 * 85 * @note equivalent DRI code is in via_ioctl.c::viaCheckDma() 86 */ 87 88 #ifdef UC_DEBUG 89 90 #define UC_FIFO_PREPARE(fifo, dwsize) \ 91 do { \ 92 if ((fifo)->used + dwsize + 32 > (fifo)->size) { \ 93 D_DEBUG("CLE266: FIFO full - flushing it."); \ 94 UC_FIFO_FLUSH(fifo); \ 95 } \ 96 if (dwsize + (fifo)->prep + 32 > (fifo)->size) { \ 97 D_BUG("CLE266: FIFO too small for allocation."); \ 98 } \ 99 (fifo)->prep += dwsize; \ 100 } while(0) 101 102 #else 103 104 #define UC_FIFO_PREPARE(fifo, dwsize) \ 105 do { \ 106 if ((fifo)->used + dwsize + 32 > (fifo)->size) { \ 107 UC_FIFO_FLUSH(fifo); \ 108 } \ 109 (fifo)->prep += dwsize; \ 110 } while(0) 111 112 #endif // UC_FIFO_DEBUG 113 114 /** 115 * Add a 32-bit data word to the FIFO. 116 * Takes one entry in the FIFO. 117 */ 118 119 #define UC_FIFO_ADD(fifo, data) \ 120 do { \ 121 *((fifo)->head) = (data); \ 122 (fifo)->head++; \ 123 (fifo)->used++; \ 124 } while(0) 125 126 /** 127 * Add a command header. (HC_HEADER2 + parameter selection) 128 * Takes two entries in the fifo. 129 */ 130 131 #define UC_FIFO_ADD_HDR(fifo, param) \ 132 do { \ 133 UC_FIFO_ADD(fifo, HC_HEADER2); \ 134 UC_FIFO_ADD(fifo, param); \ 135 } while(0); 136 137 /** 138 * Add a floating point value to the FIFO. 139 * Non-floats (e.g integers) are converted first. 140 * Takes one entry in the FIFO. 141 */ 142 143 #define UC_FIFO_ADD_FLOAT(fifo, val) \ 144 do { \ 145 union {float f; u32 i;} v; \ 146 v.f = (float) (val); \ 147 UC_FIFO_ADD(fifo, v.i); \ 148 } while(0) 149 150 /** 151 * Add a vertex on the form (x, y, color) to the FIFO. 152 * Takes three entries in the FIFO. 153 * The color format is 0xAARRGGBB. 154 */ 155 156 #define UC_FIFO_ADD_XYC(fifo, x, y, color) \ 157 do { \ 158 UC_FIFO_ADD_FLOAT(fifo, x); \ 159 UC_FIFO_ADD_FLOAT(fifo, y); \ 160 UC_FIFO_ADD(fifo, color); \ 161 } while(0) 162 163 /** 164 * Add a vertex on the form (x, y, w, color, s, t) to the FIFO. 165 * Takes six entries in the FIFO. 166 * The color format is 0xAARRGGBB. 167 */ 168 169 #define UC_FIFO_ADD_XYWCST(fifo, x, y, w, color, s, t) \ 170 do { \ 171 UC_FIFO_ADD_FLOAT(fifo, x); \ 172 UC_FIFO_ADD_FLOAT(fifo, y); \ 173 UC_FIFO_ADD_FLOAT(fifo, w); \ 174 UC_FIFO_ADD(fifo, color); \ 175 UC_FIFO_ADD_FLOAT(fifo, s); \ 176 UC_FIFO_ADD_FLOAT(fifo, t); \ 177 } while(0) 178 179 #define UC_FIFO_ADD_XYZWCST(fifo, x, y, z, w, color, s, t) \ 180 do { \ 181 UC_FIFO_ADD_FLOAT(fifo, x); \ 182 UC_FIFO_ADD_FLOAT(fifo, y); \ 183 UC_FIFO_ADD_FLOAT(fifo, z); \ 184 UC_FIFO_ADD_FLOAT(fifo, w); \ 185 UC_FIFO_ADD(fifo, color); \ 186 UC_FIFO_ADD_FLOAT(fifo, s); \ 187 UC_FIFO_ADD_FLOAT(fifo, t); \ 188 } while(0) 189 190 #define UC_FIFO_ADD_XYCST(fifo, x, y, color, s, t) \ 191 do { \ 192 UC_FIFO_ADD_FLOAT(fifo, x); \ 193 UC_FIFO_ADD_FLOAT(fifo, y); \ 194 UC_FIFO_ADD(fifo, color); \ 195 UC_FIFO_ADD_FLOAT(fifo, s); \ 196 UC_FIFO_ADD_FLOAT(fifo, t); \ 197 } while(0) 198 199 200 /** 201 * Add data specifically for the 2D controller, to the fifo. 202 * Takes two entries in the FIFO. 203 * 204 * @param reg 2D register index 205 * @param data 32-bit data to add 206 */ 207 208 #define UC_FIFO_ADD_2D(fifo, reg, data) \ 209 do { \ 210 UC_FIFO_ADD(fifo, ((reg) >> 2) | HALCYON_HEADER1); \ 211 UC_FIFO_ADD(fifo, (data)); \ 212 } while (0) 213 214 /** 215 * Add data specifically for a 3D controller register, to the fifo. 216 * Takes one entry in the FIFO. 217 * 218 * @param reg 3D register index (8 bit) 219 * @param data 24-bit data to add (make sure bits 24 - 31 are cleared!) 220 */ 221 222 #define UC_FIFO_ADD_3D(fifo, reg, data) \ 223 UC_FIFO_ADD(fifo, ((reg) << 24) | (data)) 224 225 /** 226 * Pad the FIFO to an even number of entries. 227 * Takes zero or one entries in the FIFO. 228 */ 229 #define UC_FIFO_PAD_EVEN(fifo) \ 230 if (fifo->used & 1) UC_FIFO_ADD(fifo, HC_DUMMY) 231 232 /** 233 * Check for buffer overruns. 234 * Can be redefined to nothing in release builds. 235 */ 236 237 #ifdef UC_DEBUG 238 239 #define UC_FIFO_CHECK(fifo) \ 240 do { \ 241 if ((fifo)->used > ((fifo)->size) - 32) { \ 242 D_BUG("CLE266: FIFO overrun."); \ 243 } \ 244 if ((fifo)->used > (fifo)->prep) { \ 245 D_BUG("CLE266: FIFO allocation error."); \ 246 } \ 247 } while(0) 248 249 #else 250 251 #define UC_FIFO_CHECK(fifo) do { } while(0) 252 253 #endif // UC_DEBUG 254 255 256 // FIFO functions ------------------------------------------------------------ 257 258 /** Create a FIFO. Returns NULL on failure. */ 259 260 struct uc_fifo* uc_fifo_create(FusionSHMPoolShared *pool, size_t size); 261 262 /** Destroy a FIFO */ 263 264 void uc_fifo_destroy(FusionSHMPoolShared *pool, struct uc_fifo* fifo); 265 266 void uc_fifo_flush_sys(struct uc_fifo* fifo, volatile void *regs); 267 268 #endif // __UC_FIFO_H__ 269