msm: kgsl: Freeze GPU memory objects to be dumped with the snapshot

In addition to the usual objects in a snapshot (registers, ringbuffer,
IBs, etc), there are a handful of indirect GPU buffer objects that are
created and used during draw operations. These include shaders, buffer
objects, and various state buffers.  Taken together, these buffer
objects can be large, much larger then the snapshot region we have set
aside. Fortunately, these buffers are independent and don't need to be
freed or overwritten when the context is reset.

Long story short we can take these buffers, put them in a list at snapshot
time and mark them so they don't get freed.  Then, when the snapshot is
grabbed dump them into the output stream inline and only then free them.
This allows us to snapshot a larger section of the GPU state without having
to worry about having enough memory set aside.  The only downside is that
some GPU memory will stick around, but we hope that hangs are few and far
between and that some entity will grab the dump soon after the hang so the
memory can be released.

Change-Id: Ic0dedbad0629fa483b077e727d512877bbbf81d6
Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
diff --git a/drivers/gpu/msm/kgsl_snapshot.h b/drivers/gpu/msm/kgsl_snapshot.h
index 3b72b0f..8fd3bb7 100644
--- a/drivers/gpu/msm/kgsl_snapshot.h
+++ b/drivers/gpu/msm/kgsl_snapshot.h
@@ -48,6 +48,8 @@
 #define KGSL_SNAPSHOT_SECTION_ISTORE       0x0801
 #define KGSL_SNAPSHOT_SECTION_DEBUG        0x0901
 #define KGSL_SNAPSHOT_SECTION_DEBUGBUS     0x0A01
+#define KGSL_SNAPSHOT_SECTION_GPU_OBJECT   0x0B01
+
 #define KGSL_SNAPSHOT_SECTION_END          0xFFFF
 
 /* OS sub-section header */
@@ -149,6 +151,13 @@
 	int count; /* Number of dwords in the dump */
 } __packed;
 
+struct kgsl_snapshot_gpu_object {
+	int type;      /* Type of GPU object */
+	__u32 gpuaddr; /* GPU address of the the object */
+	__u32 ptbase;  /* Base for the pagetable the GPU address is valid in */
+	int size;    /* Size of the object (in dwords) */
+};
+
 #ifdef __KERNEL__
 
 /* Allocate 512K for each device snapshot */
@@ -272,6 +281,9 @@
 	void *snapshot, int *remain, unsigned int index,
 	unsigned int data, unsigned int start, unsigned int count);
 
+/* Freeze a GPU buffer so it can be dumped in the snapshot */
+int kgsl_snapshot_get_object(struct kgsl_device *device, unsigned int ptbase,
+	unsigned int gpuaddr, unsigned int size, unsigned int type);
 
 #endif
 #endif