├── LICENCE ├── Makefile ├── fragment.s ├── mailbox.c ├── mailbox.h ├── test.cpp └── v3d.h /LICENCE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Scott Mansell 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | SOFTWARE. 21 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | 2 | test: test.cpp mailbox.o v3d.h 3 | g++ -o test -Wall -Wextra test.cpp mailbox.o -g 4 | 5 | mailbox.o: mailbox.c mailbox.h 6 | g++ -c -o mailbox.o -Wall -Wextra mailbox.c -g 7 | 8 | -------------------------------------------------------------------------------- /fragment.s: -------------------------------------------------------------------------------- 1 | # Assemble with qpuasm.js from github.com/hermanhermitage/videocoreiv-qpu 2 | 3 | .global entry 4 | 5 | entry: 6 | mov r0, vary; mov r3.8d, 1.0 # Load red varying AB partial to r0; set colour alpha to 1.0 7 | fadd r0, r0, r5; mov r1, vary; sbwait # add C component of red varying (r5); load green varying AB partial; Request access to tile buffer 8 | fadd r1, r1, r5; mov r2, vary # add C component of green varying; load blue varying AB partial 9 | fadd r2, r2, r5; mov r3.8a, r0 # add C component of blue varying; pack red varying to color 10 | nop; mov r3.8b, r1 # pack green varying to color 11 | nop; mov r3.8c, r2 # pack blue varying to color 12 | mov tlbc, r3; nop; thrend # write pixel colour to tile buffer; signal end of thread 13 | nop 14 | nop; nop; sbdone # Signal that we are finished with tile buffer 15 | -------------------------------------------------------------------------------- /mailbox.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012, Broadcom Europe Ltd. 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above copyright 10 | notice, this list of conditions and the following disclaimer in the 11 | documentation and/or other materials provided with the distribution. 12 | * Neither the name of the copyright holder nor the 13 | names of its contributors may be used to endorse or promote products 14 | derived from this software without specific prior written permission. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY 20 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | 38 | #include "mailbox.h" 39 | 40 | #define PAGE_SIZE (4*1024) 41 | 42 | void *mapmem(unsigned int base, unsigned int size) 43 | { 44 | int mem_fd; 45 | unsigned offset = base % PAGE_SIZE; 46 | base = base - offset; 47 | /* open /dev/mem */ 48 | if ((mem_fd = open("/dev/mem", O_RDWR|O_SYNC) ) < 0) { 49 | printf("can't open /dev/mem\nThis program should be run as root. Try prefixing command with: sudo\n"); 50 | exit (-1); 51 | } 52 | void *mem = mmap( 53 | 0, 54 | size, 55 | PROT_READ|PROT_WRITE, 56 | MAP_SHARED/*|MAP_FIXED*/, 57 | mem_fd, 58 | base); 59 | #ifdef DEBUG 60 | printf("base=0x%x, mem=%p\n", base, mem); 61 | #endif 62 | if (mem == MAP_FAILED) { 63 | printf("mmap error %d\n", (int)mem); 64 | exit (-1); 65 | } 66 | close(mem_fd); 67 | return (char *)mem + offset; 68 | } 69 | 70 | void *unmapmem(void *addr, unsigned int size) 71 | { 72 | int s = munmap(addr, size); 73 | if (s != 0) { 74 | printf("munmap error %d\n", s); 75 | exit (-1); 76 | } 77 | } 78 | 79 | /* 80 | * use ioctl to send mbox property message 81 | */ 82 | 83 | static int mbox_property(int file_desc, void *buf) 84 | { 85 | int ret_val = ioctl(file_desc, IOCTL_MBOX_PROPERTY, buf); 86 | 87 | if (ret_val < 0) { 88 | printf("ioctl_set_msg failed:%d\n", ret_val); 89 | } 90 | 91 | #ifdef DEBUG 92 | unsigned int *p = buf; int i; unsigned int size = *(unsigned int *)buf; 93 | for (i=0; i 33 | 34 | #define MAJOR_NUM 100 35 | #define IOCTL_MBOX_PROPERTY _IOWR(MAJOR_NUM, 0, char *) 36 | #define DEVICE_FILE_NAME "char_dev" 37 | 38 | int mbox_open(); 39 | void mbox_close(int file_desc); 40 | 41 | unsigned int get_version(int file_desc); 42 | unsigned int mem_alloc(int file_desc, unsigned int size, unsigned int align, unsigned int flags); 43 | unsigned int mem_free(int file_desc, unsigned int handle); 44 | unsigned int mem_lock(int file_desc, unsigned int handle); 45 | unsigned int mem_unlock(int file_desc, unsigned int handle); 46 | void *mapmem(unsigned int base, unsigned int size); 47 | void *unmapmem(void *addr, unsigned int size); 48 | 49 | unsigned int execute_code(int file_desc, unsigned int code, unsigned int r0, unsigned int r1, unsigned int r2, unsigned int r3, unsigned int r4, unsigned int r5); 50 | unsigned int execute_qpu(int file_desc, unsigned int num_qpus, unsigned int control, unsigned int noflush, unsigned int timeout); 51 | unsigned int qpu_enable(int file_desc, unsigned int enable); 52 | 53 | 54 | // Flags for allocate memory. 55 | enum { 56 | MEM_FLAG_DISCARDABLE = 1 << 0, /* can be resized to 0 at any time. Use for cached data */ 57 | MEM_FLAG_NORMAL = 0 << 2, /* normal allocating alias. Don't use from ARM */ 58 | MEM_FLAG_DIRECT = 1 << 2, /* 0xC alias uncached */ 59 | MEM_FLAG_COHERENT = 2 << 2, /* 0x8 alias. Non-allocating in L2 but coherent */ 60 | MEM_FLAG_L1_NONALLOCATING = (MEM_FLAG_DIRECT | MEM_FLAG_COHERENT), /* Allocating in L2 */ 61 | MEM_FLAG_ZERO = 1 << 4, /* initialise buffer to all zeros */ 62 | MEM_FLAG_NO_INIT = 1 << 5, /* don't initialise (default is initialise to all ones */ 63 | MEM_FLAG_HINT_PERMALOCK = 1 << 6, /* Likely to be locked for long periods of time. */ 64 | }; 65 | 66 | #ifdef C_PLUS_PLUS 67 | } 68 | #endif 69 | -------------------------------------------------------------------------------- /test.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "mailbox.h" 10 | #include "v3d.h" 11 | 12 | // I/O access 13 | volatile unsigned *v3d; 14 | int mbox; 15 | 16 | // Execute a nop control list to prove that we have contol. 17 | void testControlLists() { 18 | // First we allocate and map some videocore memory to build our control list in. 19 | 20 | // ask the blob to allocate us 256 bytes with 4k alignment, zero it. 21 | unsigned int handle = mem_alloc(mbox, 0x100, 0x1000, MEM_FLAG_COHERENT | MEM_FLAG_ZERO); 22 | if (!handle) { 23 | printf("Error: Unable to allocate memory"); 24 | return; 25 | } 26 | // ask the blob to lock our memory at a single location at give is that address. 27 | uint32_t bus_addr = mem_lock(mbox, handle); 28 | // map that address into our local address space. 29 | uint8_t *list = (uint8_t*) mapmem(bus_addr, 0x100); 30 | 31 | // Now we construct our control list. 32 | // 255 nops, with a halt somewhere in the middle 33 | for(int i = 0; i < 0xff; i++) { 34 | list[i] = 1; // NOP 35 | } 36 | list[0xbb] = 0; // Halt. 37 | 38 | // And then we setup the v3d pipeline to execute the control list. 39 | printf("V3D_CT0CS: 0x%08x\n", v3d[V3D_CT0CS]); 40 | printf("Start Address: 0x%08x\n", bus_addr); 41 | // Current Address = start of our list (bus address) 42 | v3d[V3D_CT0CA] = bus_addr; 43 | // End Address = just after the end of our list (bus address) 44 | // This also starts execution. 45 | v3d[V3D_CT0EA] = bus_addr + 0x100; 46 | 47 | // print status while running 48 | printf("V3D_CT0CS: 0x%08x, Address: 0x%08x\n", v3d[V3D_CT0CS], v3d[V3D_CT0CA]); 49 | 50 | // Wait a second to be sure the contorl list execution has finished 51 | while(v3d[V3D_CT0CS] & 0x20); 52 | 53 | // print the status again. 54 | printf("V3D_CT0CS: 0x%08x, Address: 0x%08x\n", v3d[V3D_CT0CS], v3d[V3D_CT0CA]); 55 | 56 | // Release memory; 57 | unmapmem((void *) list, 0x100); 58 | mem_unlock(mbox, handle); 59 | mem_free(mbox, handle); 60 | } 61 | 62 | void addbyte(uint8_t **list, uint8_t d) { 63 | *((*list)++) = d; 64 | } 65 | 66 | void addshort(uint8_t **list, uint16_t d) { 67 | *((*list)++) = (d) & 0xff; 68 | *((*list)++) = (d >> 8) & 0xff; 69 | } 70 | 71 | void addword(uint8_t **list, uint32_t d) { 72 | *((*list)++) = (d) & 0xff; 73 | *((*list)++) = (d >> 8) & 0xff; 74 | *((*list)++) = (d >> 16) & 0xff; 75 | *((*list)++) = (d >> 24) & 0xff; 76 | } 77 | 78 | void addfloat(uint8_t **list, float f) { 79 | uint32_t d = *((uint32_t *)&f); 80 | *((*list)++) = (d) & 0xff; 81 | *((*list)++) = (d >> 8) & 0xff; 82 | *((*list)++) = (d >> 16) & 0xff; 83 | *((*list)++) = (d >> 24) & 0xff; 84 | } 85 | 86 | // Render a single triangle to memory. 87 | void testTriangle() { 88 | // Like above, we allocate/lock/map some videocore memory 89 | // I'm just shoving everything in a single buffer because I'm lazy 90 | // 8Mb, 4k alignment 91 | unsigned int handle = mem_alloc(mbox, 0x800000, 0x1000, MEM_FLAG_COHERENT | MEM_FLAG_ZERO); 92 | if (!handle) { 93 | printf("Error: Unable to allocate memory"); 94 | return; 95 | } 96 | uint32_t bus_addr = mem_lock(mbox, handle); 97 | uint8_t *list = (uint8_t*) mapmem(bus_addr, 0x800000); 98 | 99 | uint8_t *p = list; 100 | 101 | // Configuration stuff 102 | // Tile Binning Configuration. 103 | // Tile state data is 48 bytes per tile, I think it can be thrown away 104 | // as soon as binning is finished. 105 | addbyte(&p, 112); 106 | addword(&p, bus_addr + 0x6200); // tile allocation memory address 107 | addword(&p, 0x8000); // tile allocation memory size 108 | addword(&p, bus_addr + 0x100); // Tile state data address 109 | addbyte(&p, 30); // 1920/64 110 | addbyte(&p, 17); // 1080/64 (16.875) 111 | addbyte(&p, 0x04); // config 112 | 113 | // Start tile binning. 114 | addbyte(&p, 6); 115 | 116 | // Primitive type 117 | addbyte(&p, 56); 118 | addbyte(&p, 0x32); // 16 bit triangle 119 | 120 | // Clip Window 121 | addbyte(&p, 102); 122 | addshort(&p, 0); 123 | addshort(&p, 0); 124 | addshort(&p, 1920); // width 125 | addshort(&p, 1080); // height 126 | 127 | // State 128 | addbyte(&p, 96); 129 | addbyte(&p, 0x03); // enable both foward and back facing polygons 130 | addbyte(&p, 0x00); // depth testing disabled 131 | addbyte(&p, 0x02); // enable early depth write 132 | 133 | // Viewport offset 134 | addbyte(&p, 103); 135 | addshort(&p, 0); 136 | addshort(&p, 0); 137 | 138 | // The triangle 139 | // No Vertex Shader state (takes pre-transformed vertexes, 140 | // so we don't have to supply a working coordinate shader to test the binner. 141 | addbyte(&p, 65); 142 | addword(&p, bus_addr + 0x80); // Shader Record 143 | 144 | // primitive index list 145 | addbyte(&p, 32); 146 | addbyte(&p, 0x04); // 8bit index, trinagles 147 | addword(&p, 3); // Length 148 | addword(&p, bus_addr + 0x70); // address 149 | addword(&p, 2); // Maximum index 150 | 151 | // End of bin list 152 | // Flush 153 | addbyte(&p, 5); 154 | // Nop 155 | addbyte(&p, 1); 156 | // Halt 157 | addbyte(&p, 0); 158 | 159 | int length = p - list; 160 | assert(length < 0x80); 161 | 162 | // Shader Record 163 | p = list + 0x80; 164 | addbyte(&p, 0x01); // flags 165 | addbyte(&p, 6*4); // stride 166 | addbyte(&p, 0xcc); // num uniforms (not used) 167 | addbyte(&p, 3); // num varyings 168 | addword(&p, bus_addr + 0xfe00); // Fragment shader code 169 | addword(&p, bus_addr + 0xff00); // Fragment shader uniforms 170 | addword(&p, bus_addr + 0xa0); // Vertex Data 171 | 172 | // Vertex Data 173 | p = list + 0xa0; 174 | // Vertex: Top, red 175 | addshort(&p, (1920/2) << 4); // X in 12.4 fixed point 176 | addshort(&p, 200 << 4); // Y in 12.4 fixed point 177 | addfloat(&p, 1.0f); // Z 178 | addfloat(&p, 1.0f); // 1/W 179 | addfloat(&p, 1.0f); // Varying 0 (Red) 180 | addfloat(&p, 0.0f); // Varying 1 (Green) 181 | addfloat(&p, 0.0f); // Varying 2 (Blue) 182 | 183 | // Vertex: bottom left, Green 184 | addshort(&p, 560 << 4); // X in 12.4 fixed point 185 | addshort(&p, 800 << 4); // Y in 12.4 fixed point 186 | addfloat(&p, 1.0f); // Z 187 | addfloat(&p, 1.0f); // 1/W 188 | addfloat(&p, 0.0f); // Varying 0 (Red) 189 | addfloat(&p, 1.0f); // Varying 1 (Green) 190 | addfloat(&p, 0.0f); // Varying 2 (Blue) 191 | 192 | // Vertex: bottom right, Blue 193 | addshort(&p, 1360 << 4); // X in 12.4 fixed point 194 | addshort(&p, 800 << 4); // Y in 12.4 fixed point 195 | addfloat(&p, 1.0f); // Z 196 | addfloat(&p, 1.0f); // 1/W 197 | addfloat(&p, 0.0f); // Varying 0 (Red) 198 | addfloat(&p, 0.0f); // Varying 1 (Green) 199 | addfloat(&p, 1.0f); // Varying 2 (Blue) 200 | 201 | // Vertex list 202 | p = list + 0x70; 203 | addbyte(&p, 0); // top 204 | addbyte(&p, 1); // bottom left 205 | addbyte(&p, 2); // bottom right 206 | 207 | // fragment shader 208 | p = list + 0xfe00; 209 | addword(&p, 0x958e0dbf); 210 | addword(&p, 0xd1724823); /* mov r0, vary; mov r3.8d, 1.0 */ 211 | addword(&p, 0x818e7176); 212 | addword(&p, 0x40024821); /* fadd r0, r0, r5; mov r1, vary */ 213 | addword(&p, 0x818e7376); 214 | addword(&p, 0x10024862); /* fadd r1, r1, r5; mov r2, vary */ 215 | addword(&p, 0x819e7540); 216 | addword(&p, 0x114248a3); /* fadd r2, r2, r5; mov r3.8a, r0 */ 217 | addword(&p, 0x809e7009); 218 | addword(&p, 0x115049e3); /* nop; mov r3.8b, r1 */ 219 | addword(&p, 0x809e7012); 220 | addword(&p, 0x116049e3); /* nop; mov r3.8c, r2 */ 221 | addword(&p, 0x159e76c0); 222 | addword(&p, 0x30020ba7); /* mov tlbc, r3; nop; thrend */ 223 | addword(&p, 0x009e7000); 224 | addword(&p, 0x100009e7); /* nop; nop; nop */ 225 | addword(&p, 0x009e7000); 226 | addword(&p, 0x500009e7); /* nop; nop; sbdone */ 227 | 228 | // Render control list 229 | p = list + 0xe200; 230 | 231 | // Clear color 232 | addbyte(&p, 114); 233 | addword(&p, 0xff000000); // Opaque Black 234 | addword(&p, 0xff000000); // 32 bit clear colours need to be repeated twice 235 | addword(&p, 0); 236 | addbyte(&p, 0); 237 | 238 | // Tile Rendering Mode Configuration 239 | addbyte(&p, 113); 240 | addword(&p, bus_addr + 0x10000); // framebuffer addresss 241 | addshort(&p, 1920); // width 242 | addshort(&p, 1080); // height 243 | addbyte(&p, 0x04); // framebuffer mode (linear rgba8888) 244 | addbyte(&p, 0x00); 245 | 246 | // Do a store of the first tile to force the tile buffer to be cleared 247 | // Tile Coordinates 248 | addbyte(&p, 115); 249 | addbyte(&p, 0); 250 | addbyte(&p, 0); 251 | // Store Tile Buffer General 252 | addbyte(&p, 28); 253 | addshort(&p, 0); // Store nothing (just clear) 254 | addword(&p, 0); // no address is needed 255 | 256 | // Link all binned lists together 257 | for(int x = 0; x < 30; x++) { 258 | for(int y = 0; y < 17; y++) { 259 | 260 | // Tile Coordinates 261 | addbyte(&p, 115); 262 | addbyte(&p, x); 263 | addbyte(&p, y); 264 | 265 | // Call Tile sublist 266 | addbyte(&p, 17); 267 | addword(&p, bus_addr + 0x6200 + (y * 30 + x) * 32); 268 | 269 | // Last tile needs a special store instruction 270 | if(x == 29 && y == 16) { 271 | // Store resolved tile color buffer and signal end of frame 272 | addbyte(&p, 25); 273 | } else { 274 | // Store resolved tile color buffer 275 | addbyte(&p, 24); 276 | } 277 | } 278 | } 279 | 280 | int render_length = p - (list + 0xe200); 281 | 282 | 283 | // Run our control list 284 | printf("Binner control list constructed\n"); 285 | printf("Start Address: 0x%08x, length: 0x%x\n", bus_addr, length); 286 | 287 | v3d[V3D_CT0CA] = bus_addr; 288 | v3d[V3D_CT0EA] = bus_addr + length; 289 | printf("V3D_CT0CS: 0x%08x, Address: 0x%08x\n", v3d[V3D_CT0CS], v3d[V3D_CT0CA]); 290 | 291 | // Wait for control list to execute 292 | while(v3d[V3D_CT0CS] & 0x20); 293 | 294 | printf("V3D_CT0CS: 0x%08x, Address: 0x%08x\n", v3d[V3D_CT0CS], v3d[V3D_CT0CA]); 295 | printf("V3D_CT1CS: 0x%08x, Address: 0x%08x\n", v3d[V3D_CT1CS], v3d[V3D_CT1CA]); 296 | 297 | 298 | v3d[V3D_CT1CA] = bus_addr + 0xe200; 299 | v3d[V3D_CT1EA] = bus_addr + 0xe200 + render_length; 300 | 301 | while(v3d[V3D_CT1CS] & 0x20); 302 | 303 | printf("V3D_CT1CS: 0x%08x, Address: 0x%08x\n", v3d[V3D_CT1CS], v3d[V3D_CT1CA]); 304 | v3d[V3D_CT1CS] = 0x20; 305 | 306 | // just dump the frame to a file 307 | FILE *f = fopen("frame.data", "w"); 308 | fwrite(list + 0x10000, (1920*1080*4), 1, f); 309 | fclose(f); 310 | printf("frame buffer memory dumpped to frame.data\n"); 311 | 312 | // Release resources 313 | unmapmem((void *) list, 0x800000); 314 | mem_unlock(mbox, handle); 315 | mem_free(mbox, handle); 316 | } 317 | 318 | int main(int argc, char **argv) { 319 | mbox = mbox_open(); 320 | 321 | // The blob now has this nice handy call which powers up the v3d pipeline. 322 | qpu_enable(mbox, 1); 323 | 324 | // map v3d's registers into our address space. 325 | v3d = (unsigned *) mapmem(0x20c00000, 0x1000); 326 | 327 | if(v3d[V3D_IDENT0] != 0x02443356) { // Magic number. 328 | printf("Error: V3D pipeline isn't powered up and accessable.\n"); 329 | exit(-1); 330 | } 331 | 332 | // We now have access to the v3d registers, we should do something. 333 | testTriangle(); 334 | 335 | return 0; 336 | } 337 | 338 | 339 | 340 | 341 | 342 | -------------------------------------------------------------------------------- /v3d.h: -------------------------------------------------------------------------------- 1 | 2 | // Defines for v3d register offsets 3 | #define V3D_IDENT0 (0x000>>2) // V3D Identification 0 (V3D block identity) 4 | #define V3D_IDENT1 (0x004>>2) // V3D Identification 1 (V3D Configuration A) 5 | #define V3D_IDENT2 (0x008>>2) // V3D Identification 1 (V3D Configuration B) 6 | 7 | #define V3D_SCRATCH (0x010>>2) // Scratch Register 8 | 9 | #define V3D_L2CACTL (0x020>>2) // 2 Cache Control 10 | #define V3D_SLCACTL (0x024>>2) // Slices Cache Control 11 | 12 | #define V3D_INTCTL (0x030>>2) // Interrupt Control 13 | #define V3D_INTENA (0x034>>2) // Interrupt Enables 14 | #define V3D_INTDIS (0x038>>2) // Interrupt Disables 15 | 16 | #define V3D_CT0CS (0x100>>2) // Control List Executor Thread 0 Control and Status. 17 | #define V3D_CT1CS (0x104>>2) // Control List Executor Thread 1 Control and Status. 18 | #define V3D_CT0EA (0x108>>2) // Control List Executor Thread 0 End Address. 19 | #define V3D_CT1EA (0x10c>>2) // Control List Executor Thread 1 End Address. 20 | #define V3D_CT0CA (0x110>>2) // Control List Executor Thread 0 Current Address. 21 | #define V3D_CT1CA (0x114>>2) // Control List Executor Thread 1 Current Address. 22 | #define V3D_CT00RA0 (0x118>>2) // Control List Executor Thread 0 Return Address. 23 | #define V3D_CT01RA0 (0x11c>>2) // Control List Executor Thread 1 Return Address. 24 | #define V3D_CT0LC (0x120>>2) // Control List Executor Thread 0 List Counter 25 | #define V3D_CT1LC (0x124>>2) // Control List Executor Thread 1 List Counter 26 | #define V3D_CT0PC (0x128>>2) // Control List Executor Thread 0 Primitive List Counter 27 | #define V3D_CT1PC (0x12c>>2) // Control List Executor Thread 1 Primitive List Counter 28 | 29 | #define V3D_PCS (0x130>>2) // V3D Pipeline Control and Status 30 | #define V3D_BFC (0x134>>2) // Binning Mode Flush Count 31 | #define V3D_RFC (0x138>>2) // Rendering Mode Frame Count 32 | 33 | #define V3D_BPCA (0x300>>2) // Current Address of Binning Memory Pool 34 | #define V3D_BPCS (0x304>>2) // Remaining Size of Binning Memory Pool 35 | #define V3D_BPOA (0x308>>2) // Address of Overspill Binning Memory Block 36 | #define V3D_BPOS (0x30c>>2) // Size of Overspill Binning Memory Block 37 | #define V3D_BXCF (0x310>>2) // Binner Debug 38 | 39 | #define V3D_SQRSV0 (0x410>>2) // Reserve QPUs 0-7 40 | #define V3D_SQRSV1 (0x414>>2) // Reserve QPUs 8-15 41 | #define V3D_SQCNTL (0x418>>2) // QPU Scheduler Control 42 | 43 | #define V3D_SRQPC (0x430>>2) // QPU User Program Request Program Address 44 | #define V3D_SRQUA (0x434>>2) // QPU User Program Request Uniforms Address 45 | #define V3D_SRQUL (0x438>>2) // QPU User Program Request Uniforms Length 46 | #define V3D_SRQCS (0x43c>>2) // QPU User Program Request Control and Status 47 | 48 | #define V3D_VPACNTL (0x500>>2) // VPM Allocator Control 49 | #define V3D_VPMBASE (0x504>>2) // VPM base (user) memory reservation 50 | 51 | #define V3D_PCTRC (0x670>>2) // Performance Counter Clear 52 | #define V3D_PCTRE (0x674>>2) // Performance Counter Enables 53 | 54 | #define V3D_PCTR0 (0x680>>2) // Performance Counter Count 0 55 | #define V3D_PCTRS0 (0x684>>2) // Performance Counter Mapping 0 56 | #define V3D_PCTR1 (0x688>>2) // Performance Counter Count 1 57 | #define V3D_PCTRS1 (0x68c>>2) // Performance Counter Mapping 1 58 | #define V3D_PCTR2 (0x690>>2) // Performance Counter Count 2 59 | #define V3D_PCTRS2 (0x694>>2) // Performance Counter Mapping 2 60 | #define V3D_PCTR3 (0x698>>2) // Performance Counter Count 3 61 | #define V3D_PCTRS3 (0x69c>>2) // Performance Counter Mapping 3 62 | #define V3D_PCTR4 (0x6a0>>2) // Performance Counter Count 4 63 | #define V3D_PCTRS4 (0x6a4>>2) // Performance Counter Mapping 4 64 | #define V3D_PCTR5 (0x6a8>>2) // Performance Counter Count 5 65 | #define V3D_PCTRS5 (0x6ac>>2) // Performance Counter Mapping 5 66 | #define V3D_PCTR6 (0x6b0>>2) // Performance Counter Count 6 67 | #define V3D_PCTRS6 (0x6b4>>2) // Performance Counter Mapping 6 68 | #define V3D_PCTR7 (0x6b8>>2) // Performance Counter Count 7 69 | #define V3D_PCTRS7 (0x6bc>>2) // Performance Counter Mapping 7 70 | #define V3D_PCTR8 (0x6c0>>2) // Performance Counter Count 8 71 | #define V3D_PCTRS8 (0x6c4>>2) // Performance Counter Mapping 8 72 | #define V3D_PCTR9 (0x6c8>>2) // Performance Counter Count 9 73 | #define V3D_PCTRS9 (0x6cc>>2) // Performance Counter Mapping 9 74 | #define V3D_PCTR10 (0x6d0>>2) // Performance Counter Count 10 75 | #define V3D_PCTRS10 (0x6d4>>2) // Performance Counter Mapping 10 76 | #define V3D_PCTR11 (0x6d8>>2) // Performance Counter Count 11 77 | #define V3D_PCTRS11 (0x6dc>>2) // Performance Counter Mapping 11 78 | #define V3D_PCTR12 (0x6e0>>2) // Performance Counter Count 12 79 | #define V3D_PCTRS12 (0x6e4>>2) // Performance Counter Mapping 12 80 | #define V3D_PCTR13 (0x6e8>>2) // Performance Counter Count 13 81 | #define V3D_PCTRS13 (0x6ec>>2) // Performance Counter Mapping 13 82 | #define V3D_PCTR14 (0x6f0>>2) // Performance Counter Count 14 83 | #define V3D_PCTRS14 (0x6f4>>2) // Performance Counter Mapping 14 84 | #define V3D_PCTR15 (0x6f8>>2) // Performance Counter Count 15 85 | #define V3D_PCTRS15 (0x6fc>>2) // Performance Counter Mapping 15 86 | 87 | #define V3D_DBGE (0xf00>>2) // PSE Error Signals 88 | #define V3D_FDBGO (0xf04>>2) // FEP Overrun Error Signals 89 | #define V3D_FDBGB (0xf08>>2) // FEP Interface Ready and Stall Signals, FEP Busy Signals 90 | #define V3D_FDBGR (0xf0c>>2) // FEP Internal Ready Signals 91 | #define V3D_FDBGS (0xf10>>2) // FEP Internal Stall Input Signals 92 | 93 | #define V3D_ERRSTAT (0xf20>>2) // Miscellaneous Error Signals (VPM, VDW, VCD, VCM, L2C) 94 | --------------------------------------------------------------------------------