/* Copyright (c) 2002,2007-2013, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and * only version 2 as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * */ #ifndef __ADRENO_RINGBUFFER_H #define __ADRENO_RINGBUFFER_H /* * Adreno ringbuffer sizes in bytes - these are converted to * the appropriate log2 values in the code */ #define KGSL_RB_SIZE (32 * 1024) #define KGSL_RB_BLKSIZE 16 /* CP timestamp register */ #define REG_CP_TIMESTAMP REG_SCRATCH_REG0 struct kgsl_device; struct kgsl_device_private; struct adreno_ft_data; #define GSL_RB_MEMPTRS_SCRATCH_COUNT 8 struct kgsl_rbmemptrs { int rptr; int wptr_poll; }; #define GSL_RB_MEMPTRS_RPTR_OFFSET \ (offsetof(struct kgsl_rbmemptrs, rptr)) #define GSL_RB_MEMPTRS_WPTRPOLL_OFFSET \ (offsetof(struct kgsl_rbmemptrs, wptr_poll)) struct adreno_ringbuffer { struct kgsl_device *device; uint32_t flags; struct kgsl_memdesc buffer_desc; struct kgsl_memdesc memptrs_desc; struct kgsl_rbmemptrs *memptrs; /*ringbuffer size */ unsigned int sizedwords; unsigned int wptr; /* write pointer offset in dwords from baseaddr */ unsigned int rptr; /* read pointer offset in dwords from baseaddr */ unsigned int timestamp[KGSL_MEMSTORE_MAX]; }; #define GSL_RB_WRITE(device, ring, gpuaddr, data) \ do { \ *ring = data; \ wmb(); \ kgsl_cffdump_setmem(device, gpuaddr, data, 4); \ ring++; \ gpuaddr += sizeof(uint); \ } while (0) /* enable timestamp (...scratch0) memory shadowing */ #define GSL_RB_MEMPTRS_SCRATCH_MASK 0x1 /* mem rptr */ #define GSL_RB_CNTL_NO_UPDATE 0x0 /* enable */ #define GSL_RB_GET_READPTR(rb, data) \ do { \ *(data) = rb->memptrs->rptr; \ } while (0) #define GSL_RB_CNTL_POLL_EN 0x0 /* disable */ /* * protected mode error checking below register address 0x800 * note: if CP_INTERRUPT packet is used then checking needs * to change to below register address 0x7C8 */ #define GSL_RB_PROTECTED_MODE_CONTROL 0x200001F2 int adreno_ringbuffer_issueibcmds(struct kgsl_device_private *dev_priv, struct kgsl_context *context, struct kgsl_ibdesc *ibdesc, unsigned int numibs, uint32_t *timestamp, unsigned int flags); int adreno_ringbuffer_init(struct kgsl_device *device); int adreno_ringbuffer_warm_start(struct adreno_ringbuffer *rb); int adreno_ringbuffer_start(struct adreno_ringbuffer *rb); void adreno_ringbuffer_stop(struct adreno_ringbuffer *rb); void adreno_ringbuffer_close(struct adreno_ringbuffer *rb); unsigned int adreno_ringbuffer_issuecmds(struct kgsl_device *device, struct adreno_context *drawctxt, unsigned int flags, unsigned int *cmdaddr, int sizedwords); void adreno_ringbuffer_submit(struct adreno_ringbuffer *rb); void kgsl_cp_intrcallback(struct kgsl_device *device); void adreno_ringbuffer_extract(struct adreno_ringbuffer *rb, struct adreno_ft_data *ft_data); void adreno_ringbuffer_restore(struct adreno_ringbuffer *rb, unsigned int *rb_buff, int num_rb_contents); unsigned int *adreno_ringbuffer_allocspace(struct adreno_ringbuffer *rb, struct adreno_context *context, unsigned int numcmds); int adreno_ringbuffer_read_pfp_ucode(struct kgsl_device *device); int adreno_ringbuffer_read_pm4_ucode(struct kgsl_device *device); static inline int adreno_ringbuffer_count(struct adreno_ringbuffer *rb, unsigned int rptr) { if (rb->wptr >= rptr) return rb->wptr - rptr; return rb->wptr + rb->sizedwords - rptr; } /* Increment a value by 4 bytes with wrap-around based on size */ static inline unsigned int adreno_ringbuffer_inc_wrapped(unsigned int val, unsigned int size) { return (val + sizeof(unsigned int)) % size; } /* Decrement a value by 4 bytes with wrap-around based on size */ static inline unsigned int adreno_ringbuffer_dec_wrapped(unsigned int val, unsigned int size) { return (val + size - sizeof(unsigned int)) % size; } #endif /* __ADRENO_RINGBUFFER_H */