123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321 |
- /* Copyright (c) 2008-2014, 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 __KGSL_H
- #define __KGSL_H
- #include <linux/types.h>
- #include <linux/msm_kgsl.h>
- #include <linux/platform_device.h>
- #include <linux/clk.h>
- #include <linux/interrupt.h>
- #include <linux/mutex.h>
- #include <linux/cdev.h>
- #include <linux/regulator/consumer.h>
- #include <linux/mm.h>
- #include <mach/kgsl.h>
- #define KGSL_NAME "kgsl"
- /* The number of memstore arrays limits the number of contexts allowed.
- * If more contexts are needed, update multiple for MEMSTORE_SIZE
- */
- #define KGSL_MEMSTORE_SIZE ((int)(PAGE_SIZE * 2))
- #define KGSL_MEMSTORE_GLOBAL (0)
- #define KGSL_MEMSTORE_MAX (KGSL_MEMSTORE_SIZE / \
- sizeof(struct kgsl_devmemstore) - 1)
- /* Timestamp window used to detect rollovers (half of integer range) */
- #define KGSL_TIMESTAMP_WINDOW 0x80000000
- /*cache coherency ops */
- #define DRM_KGSL_GEM_CACHE_OP_TO_DEV 0x0001
- #define DRM_KGSL_GEM_CACHE_OP_FROM_DEV 0x0002
- /* The size of each entry in a page table */
- #define KGSL_PAGETABLE_ENTRY_SIZE 4
- /* Pagetable Virtual Address base */
- #ifndef CONFIG_MSM_KGSL_CFF_DUMP
- #define KGSL_PAGETABLE_BASE 0x10000000
- #else
- #define KGSL_PAGETABLE_BASE 0xE0000000
- #endif
- /* Extra accounting entries needed in the pagetable */
- #define KGSL_PT_EXTRA_ENTRIES 16
- #define KGSL_PAGETABLE_ENTRIES(_sz) (((_sz) >> PAGE_SHIFT) + \
- KGSL_PT_EXTRA_ENTRIES)
- #ifdef CONFIG_KGSL_PER_PROCESS_PAGE_TABLE
- #define KGSL_PAGETABLE_COUNT (CONFIG_MSM_KGSL_PAGE_TABLE_COUNT)
- #else
- #define KGSL_PAGETABLE_COUNT 1
- #endif
- /* Casting using container_of() for structures that kgsl owns. */
- #define KGSL_CONTAINER_OF(ptr, type, member) \
- container_of(ptr, type, member)
- /* A macro for memory statistics - add the new size to the stat and if
- the statisic is greater then _max, set _max
- */
- static inline void KGSL_STATS_ADD(uint32_t size, atomic_t *stat,
- atomic_t *max)
- {
- uint32_t ret = atomic_add_return(size, stat);
- if (ret > atomic_read(max))
- atomic_set(max, ret);
- }
- #define KGSL_MAX_NUMIBS 100000
- struct kgsl_device;
- struct kgsl_context;
- struct kgsl_driver {
- struct cdev cdev;
- dev_t major;
- struct class *class;
- /* Virtual device for managing the core */
- struct device virtdev;
- /* Kobjects for storing pagetable and process statistics */
- struct kobject *ptkobj;
- struct kobject *prockobj;
- struct kgsl_device *devp[KGSL_DEVICE_MAX];
- /* Global lilst of open processes */
- struct list_head process_list;
- /* Global list of pagetables */
- struct list_head pagetable_list;
- /* Spinlock for accessing the pagetable list */
- spinlock_t ptlock;
- /* Mutex for accessing the process list */
- struct mutex process_mutex;
- /* Mutex for protecting the device list */
- struct mutex devlock;
- void *ptpool;
- struct {
- atomic_t vmalloc;
- atomic_t vmalloc_max;
- atomic_t page_alloc;
- atomic_t page_alloc_max;
- atomic_t coherent;
- atomic_t coherent_max;
- atomic_t mapped;
- atomic_t mapped_max;
- } stats;
- unsigned int full_cache_threshold;
- };
- extern struct kgsl_driver kgsl_driver;
- struct kgsl_pagetable;
- struct kgsl_memdesc;
- struct kgsl_cmdbatch;
- struct kgsl_memdesc_ops {
- int (*vmflags)(struct kgsl_memdesc *);
- int (*vmfault)(struct kgsl_memdesc *, struct vm_area_struct *,
- struct vm_fault *);
- void (*free)(struct kgsl_memdesc *memdesc);
- int (*map_kernel)(struct kgsl_memdesc *);
- void (*unmap_kernel)(struct kgsl_memdesc *);
- };
- /* Internal definitions for memdesc->priv */
- #define KGSL_MEMDESC_GUARD_PAGE BIT(0)
- /* Set if the memdesc is mapped into all pagetables */
- #define KGSL_MEMDESC_GLOBAL BIT(1)
- /* The memdesc is frozen during a snapshot */
- #define KGSL_MEMDESC_FROZEN BIT(2)
- /* The memdesc is mapped into a pagetable */
- #define KGSL_MEMDESC_MAPPED BIT(3)
- /* shared memory allocation */
- struct kgsl_memdesc {
- struct kgsl_pagetable *pagetable;
- void *hostptr; /* kernel virtual address */
- unsigned int hostptr_count; /* number of threads using hostptr */
- unsigned long useraddr; /* userspace address */
- unsigned int gpuaddr;
- phys_addr_t physaddr;
- unsigned int size;
- unsigned int priv; /* Internal flags and settings */
- struct scatterlist *sg;
- unsigned int sglen; /* Active entries in the sglist */
- unsigned int sglen_alloc; /* Allocated entries in the sglist */
- struct kgsl_memdesc_ops *ops;
- unsigned int flags; /* Flags set from userspace */
- };
- /* List of different memory entry types */
- #define KGSL_MEM_ENTRY_KERNEL 0
- #define KGSL_MEM_ENTRY_PMEM 1
- #define KGSL_MEM_ENTRY_ASHMEM 2
- #define KGSL_MEM_ENTRY_USER 3
- #define KGSL_MEM_ENTRY_ION 4
- #define KGSL_MEM_ENTRY_MAX 5
- struct kgsl_mem_entry {
- struct kref refcount;
- struct kgsl_memdesc memdesc;
- int memtype;
- void *priv_data;
- struct rb_node node;
- unsigned int id;
- unsigned int context_id;
- /* back pointer to private structure under whose context this
- * allocation is made */
- struct kgsl_process_private *priv;
- /* Initialized to 0, set to 1 when entry is marked for freeing */
- int pending_free;
- struct kgsl_device_private *dev_priv;
- };
- #ifdef CONFIG_MSM_KGSL_MMU_PAGE_FAULT
- #define MMU_CONFIG 2
- #else
- #define MMU_CONFIG 1
- #endif
- int kgsl_cmdbatch_add_memobj(struct kgsl_cmdbatch *cmdbatch,
- struct kgsl_ibdesc *ibdesc);
- void kgsl_mem_entry_destroy(struct kref *kref);
- int kgsl_postmortem_dump(struct kgsl_device *device, int manual);
- struct kgsl_mem_entry *kgsl_get_mem_entry(struct kgsl_device *device,
- phys_addr_t ptbase, unsigned int gpuaddr, unsigned int size);
- struct kgsl_mem_entry *kgsl_sharedmem_find_region(
- struct kgsl_process_private *private, unsigned int gpuaddr,
- size_t size);
- void kgsl_get_memory_usage(char *str, size_t len, unsigned int memflags);
- extern const struct dev_pm_ops kgsl_pm_ops;
- int kgsl_suspend_driver(struct platform_device *pdev, pm_message_t state);
- int kgsl_resume_driver(struct platform_device *pdev);
- void kgsl_trace_regwrite(struct kgsl_device *device, unsigned int offset,
- unsigned int value);
- void kgsl_trace_issueibcmds(struct kgsl_device *device, int id,
- struct kgsl_cmdbatch *cmdbatch, unsigned int numibs,
- unsigned int timestamp, unsigned int flags,
- int result, unsigned int type);
- int kgsl_open_device(struct kgsl_device *device);
- int kgsl_close_device(struct kgsl_device *device);
- #ifdef CONFIG_MSM_KGSL_DRM
- extern int kgsl_drm_init(struct platform_device *dev);
- extern void kgsl_drm_exit(void);
- #else
- static inline int kgsl_drm_init(struct platform_device *dev)
- {
- return 0;
- }
- static inline void kgsl_drm_exit(void)
- {
- }
- #endif
- static inline int kgsl_gpuaddr_in_memdesc(const struct kgsl_memdesc *memdesc,
- unsigned int gpuaddr, unsigned int size)
- {
- /* set a minimum size to search for */
- if (!size)
- size = 1;
- /* don't overflow */
- if (size > UINT_MAX - gpuaddr)
- return 0;
- if (gpuaddr >= memdesc->gpuaddr &&
- ((gpuaddr + size) <= (memdesc->gpuaddr + memdesc->size))) {
- return 1;
- }
- return 0;
- }
- static inline void *kgsl_memdesc_map(struct kgsl_memdesc *memdesc)
- {
- if (memdesc->ops && memdesc->ops->map_kernel)
- memdesc->ops->map_kernel(memdesc);
- return memdesc->hostptr;
- }
- static inline void kgsl_memdesc_unmap(struct kgsl_memdesc *memdesc)
- {
- if (memdesc->ops && memdesc->ops->unmap_kernel)
- memdesc->ops->unmap_kernel(memdesc);
- }
- static inline uint8_t *kgsl_gpuaddr_to_vaddr(struct kgsl_memdesc *memdesc,
- unsigned int gpuaddr)
- {
- void *hostptr = NULL;
- if ((gpuaddr >= memdesc->gpuaddr) &&
- (gpuaddr < (memdesc->gpuaddr + memdesc->size)))
- hostptr = kgsl_memdesc_map(memdesc);
- return hostptr != NULL ? hostptr + (gpuaddr - memdesc->gpuaddr) : NULL;
- }
- static inline int timestamp_cmp(unsigned int a, unsigned int b)
- {
- /* check for equal */
- if (a == b)
- return 0;
- /* check for greater-than for non-rollover case */
- if ((a > b) && (a - b < KGSL_TIMESTAMP_WINDOW))
- return 1;
- /* check for greater-than for rollover case
- * note that <= is required to ensure that consistent
- * results are returned for values whose difference is
- * equal to the window size
- */
- a += KGSL_TIMESTAMP_WINDOW;
- b += KGSL_TIMESTAMP_WINDOW;
- return ((a > b) && (a - b <= KGSL_TIMESTAMP_WINDOW)) ? 1 : -1;
- }
- static inline int
- kgsl_mem_entry_get(struct kgsl_mem_entry *entry)
- {
- return kref_get_unless_zero(&entry->refcount);
- }
- static inline void
- kgsl_mem_entry_put(struct kgsl_mem_entry *entry)
- {
- kref_put(&entry->refcount, kgsl_mem_entry_destroy);
- }
- #endif /* __KGSL_H */
|