summaryrefslogtreecommitdiff
path: root/linux-core/drm_memory.c
diff options
context:
space:
mode:
authorNian Wu <nian.wu@intel.com>2006-11-09 21:21:17 -0800
committerNian Wu <nian.wu@intel.com>2006-11-09 21:21:17 -0800
commit14e3f2711e90fe9a9c315d96abd4c7681539936a (patch)
tree6a562d9035e56671eb7905bac1f3829597f109a9 /linux-core/drm_memory.c
parente2ea72187e470c2c13adbd3fba4177bd4a0ecc37 (diff)
parentd51e1bb56ca2f7858cdeac6f61a7b747c1e15b1e (diff)
Merge branch 'master' into crestline
Conflicts: shared-core/i915_dma.c
Diffstat (limited to 'linux-core/drm_memory.c')
-rw-r--r--linux-core/drm_memory.c70
1 files changed, 69 insertions, 1 deletions
diff --git a/linux-core/drm_memory.c b/linux-core/drm_memory.c
index 9125cd47..3370c279 100644
--- a/linux-core/drm_memory.c
+++ b/linux-core/drm_memory.c
@@ -33,10 +33,78 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
-#include <linux/config.h>
#include <linux/highmem.h>
#include "drmP.h"
+static struct {
+ spinlock_t lock;
+ drm_u64_t cur_used;
+ drm_u64_t low_threshold;
+ drm_u64_t high_threshold;
+} drm_memctl = {
+ .lock = SPIN_LOCK_UNLOCKED
+};
+
+static inline size_t drm_size_align(size_t size) {
+
+ register size_t tmpSize = 4;
+ if (size > PAGE_SIZE)
+ return PAGE_ALIGN(size);
+
+ while(tmpSize < size)
+ tmpSize <<= 1;
+
+ return (size_t) tmpSize;
+}
+
+int drm_alloc_memctl(size_t size)
+{
+ int ret;
+ unsigned long a_size = drm_size_align(size);
+
+ spin_lock(&drm_memctl.lock);
+ ret = ((drm_memctl.cur_used + a_size) > drm_memctl.high_threshold) ?
+ -ENOMEM : 0;
+ if (!ret)
+ drm_memctl.cur_used += a_size;
+ spin_unlock(&drm_memctl.lock);
+ return ret;
+}
+EXPORT_SYMBOL(drm_alloc_memctl);
+
+void drm_free_memctl(size_t size)
+{
+ unsigned long a_size = drm_size_align(size);
+
+ spin_lock(&drm_memctl.lock);
+ drm_memctl.cur_used -= a_size;
+ spin_unlock(&drm_memctl.lock);
+}
+EXPORT_SYMBOL(drm_free_memctl);
+
+void drm_query_memctl(drm_u64_t *cur_used,
+ drm_u64_t *low_threshold,
+ drm_u64_t *high_threshold)
+{
+ spin_lock(&drm_memctl.lock);
+ *cur_used = drm_memctl.cur_used;
+ *low_threshold = drm_memctl.low_threshold;
+ *high_threshold = drm_memctl.high_threshold;
+ spin_unlock(&drm_memctl.lock);
+}
+EXPORT_SYMBOL(drm_query_memctl);
+
+void drm_init_memctl(size_t p_low_threshold,
+ size_t p_high_threshold)
+{
+ spin_lock(&drm_memctl.lock);
+ drm_memctl.cur_used = 0;
+ drm_memctl.low_threshold = p_low_threshold << PAGE_SHIFT;
+ drm_memctl.high_threshold = p_high_threshold << PAGE_SHIFT;
+ spin_unlock(&drm_memctl.lock);
+}
+
+
#ifndef DEBUG_MEMORY
/** No-op. */