| // SPDX-License-Identifier: GPL-2.0 |
| /* |
| * Support for Medifield PNW Camera Imaging ISP subsystem. |
| * |
| * Copyright (c) 2010-2017 Intel Corporation. All Rights Reserved. |
| * |
| * Copyright (c) 2010 Silicon Hive www.siliconhive.com. |
| * |
| * This program is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU General Public License 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. |
| * |
| * |
| */ |
| /* |
| * This file contains entry functions for memory management of ISP driver |
| */ |
| #include <linux/kernel.h> |
| #include <linux/types.h> |
| #include <linux/mm.h> |
| #include <linux/highmem.h> /* for kmap */ |
| #include <linux/io.h> /* for page_to_phys */ |
| #include <linux/sysfs.h> |
| |
| #include "hmm/hmm.h" |
| #include "hmm/hmm_pool.h" |
| #include "hmm/hmm_bo.h" |
| |
| #include "atomisp_internal.h" |
| #include "asm/cacheflush.h" |
| #include "mmu/isp_mmu.h" |
| #include "mmu/sh_mmu_mrfld.h" |
| |
| struct hmm_bo_device bo_device; |
| struct hmm_pool dynamic_pool; |
| struct hmm_pool reserved_pool; |
| static ia_css_ptr dummy_ptr; |
| static bool hmm_initialized; |
| struct _hmm_mem_stat hmm_mem_stat; |
| |
| /* |
| * p: private |
| * s: shared |
| * u: user |
| * i: ion |
| */ |
| static const char hmm_bo_type_string[] = "psui"; |
| |
| static ssize_t bo_show(struct device *dev, struct device_attribute *attr, |
| char *buf, struct list_head *bo_list, bool active) |
| { |
| ssize_t ret = 0; |
| struct hmm_buffer_object *bo; |
| unsigned long flags; |
| int i; |
| long total[HMM_BO_LAST] = { 0 }; |
| long count[HMM_BO_LAST] = { 0 }; |
| int index1 = 0; |
| int index2 = 0; |
| |
| ret = scnprintf(buf, PAGE_SIZE, "type pgnr\n"); |
| if (ret <= 0) |
| return 0; |
| |
| index1 += ret; |
| |
| spin_lock_irqsave(&bo_device.list_lock, flags); |
| list_for_each_entry(bo, bo_list, list) { |
| if ((active && (bo->status & HMM_BO_ALLOCED)) || |
| (!active && !(bo->status & HMM_BO_ALLOCED))) { |
| ret = scnprintf(buf + index1, PAGE_SIZE - index1, |
| "%c %d\n", |
| hmm_bo_type_string[bo->type], bo->pgnr); |
| |
| total[bo->type] += bo->pgnr; |
| count[bo->type]++; |
| if (ret > 0) |
| index1 += ret; |
| } |
| } |
| spin_unlock_irqrestore(&bo_device.list_lock, flags); |
| |
| for (i = 0; i < HMM_BO_LAST; i++) { |
| if (count[i]) { |
| ret = scnprintf(buf + index1 + index2, |
| PAGE_SIZE - index1 - index2, |
| "%ld %c buffer objects: %ld KB\n", |
| count[i], hmm_bo_type_string[i], |
| total[i] * 4); |
| if (ret > 0) |
| index2 += ret; |
| } |
| } |
| |
| /* Add trailing zero, not included by scnprintf */ |
| return index1 + index2 + 1; |
| } |
| |
| static ssize_t active_bo_show(struct device *dev, struct device_attribute *attr, |
| char *buf) |
| { |
| return bo_show(dev, attr, buf, &bo_device.entire_bo_list, true); |
| } |
| |
| static ssize_t free_bo_show(struct device *dev, struct device_attribute *attr, |
| char *buf) |
| { |
| return bo_show(dev, attr, buf, &bo_device.entire_bo_list, false); |
| } |
| |
| static ssize_t reserved_pool_show(struct device *dev, |
| struct device_attribute *attr, |
| char *buf) |
| { |
| ssize_t ret = 0; |
| |
| struct hmm_reserved_pool_info *pinfo = reserved_pool.pool_info; |
| unsigned long flags; |
| |
| if (!pinfo || !pinfo->initialized) |
| return 0; |
| |
| spin_lock_irqsave(&pinfo->list_lock, flags); |
| ret = scnprintf(buf, PAGE_SIZE, "%d out of %d pages available\n", |
| pinfo->index, pinfo->pgnr); |
| spin_unlock_irqrestore(&pinfo->list_lock, flags); |
| |
| if (ret > 0) |
| ret++; /* Add trailing zero, not included by scnprintf */ |
| |
| return ret; |
| }; |
| |
| static ssize_t dynamic_pool_show(struct device *dev, |
| struct device_attribute *attr, |
| char *buf) |
| { |
| ssize_t ret = 0; |
| |
| struct hmm_dynamic_pool_info *pinfo = dynamic_pool.pool_info; |
| unsigned long flags; |
| |
| if (!pinfo || !pinfo->initialized) |
| return 0; |
| |
| spin_lock_irqsave(&pinfo->list_lock, flags); |
| ret = scnprintf(buf, PAGE_SIZE, "%d (max %d) pages available\n", |
| pinfo->pgnr, pinfo->pool_size); |
| spin_unlock_irqrestore(&pinfo->list_lock, flags); |
| |
| if (ret > 0) |
| ret++; /* Add trailing zero, not included by scnprintf */ |
| |
| return ret; |
| }; |
| |
| static DEVICE_ATTR_RO(active_bo); |
| static DEVICE_ATTR_RO(free_bo); |
| static DEVICE_ATTR_RO(reserved_pool); |
| static DEVICE_ATTR_RO(dynamic_pool); |
| |
| static struct attribute *sysfs_attrs_ctrl[] = { |
| &dev_attr_active_bo.attr, |
| &dev_attr_free_bo.attr, |
| &dev_attr_reserved_pool.attr, |
| &dev_attr_dynamic_pool.attr, |
| NULL |
| }; |
| |
| static struct attribute_group atomisp_attribute_group[] = { |
| {.attrs = sysfs_attrs_ctrl }, |
| }; |
| |
| int hmm_init(void) |
| { |
| int ret; |
| |
| ret = hmm_bo_device_init(&bo_device, &sh_mmu_mrfld, |
| ISP_VM_START, ISP_VM_SIZE); |
| if (ret) |
| dev_err(atomisp_dev, "hmm_bo_device_init failed.\n"); |
| |
| hmm_initialized = true; |
| |
| /* |
| * As hmm use NULL to indicate invalid ISP virtual address, |
| * and ISP_VM_START is defined to 0 too, so we allocate |
| * one piece of dummy memory, which should return value 0, |
| * at the beginning, to avoid hmm_alloc return 0 in the |
| * further allocation. |
| */ |
| dummy_ptr = hmm_alloc(1, HMM_BO_PRIVATE, 0, NULL, 0); |
| |
| if (!ret) { |
| ret = sysfs_create_group(&atomisp_dev->kobj, |
| atomisp_attribute_group); |
| if (ret) |
| dev_err(atomisp_dev, |
| "%s Failed to create sysfs\n", __func__); |
| } |
| |
| return ret; |
| } |
| |
| void hmm_cleanup(void) |
| { |
| if (!dummy_ptr) |
| return; |
| sysfs_remove_group(&atomisp_dev->kobj, atomisp_attribute_group); |
| |
| /* free dummy memory first */ |
| hmm_free(dummy_ptr); |
| dummy_ptr = 0; |
| |
| hmm_bo_device_exit(&bo_device); |
| hmm_initialized = false; |
| } |
| |
| ia_css_ptr hmm_alloc(size_t bytes, enum hmm_bo_type type, |
| int from_highmem, const void __user *userptr, |
| const uint16_t attrs) |
| { |
| unsigned int pgnr; |
| struct hmm_buffer_object *bo; |
| bool cached = attrs & ATOMISP_MAP_FLAG_CACHED; |
| int ret; |
| |
| WARN_ON(attrs & ATOMISP_MAP_FLAG_CONTIGUOUS); |
| |
| /* |
| * Check if we are initialized. In the ideal world we wouldn't need |
| * this but we can tackle it once the driver is a lot cleaner |
| */ |
| |
| if (!hmm_initialized) |
| hmm_init(); |
| /* Get page number from size */ |
| pgnr = size_to_pgnr_ceil(bytes); |
| |
| /* Buffer object structure init */ |
| bo = hmm_bo_alloc(&bo_device, pgnr); |
| if (!bo) { |
| dev_err(atomisp_dev, "hmm_bo_create failed.\n"); |
| goto create_bo_err; |
| } |
| |
| /* Allocate pages for memory */ |
| ret = hmm_bo_alloc_pages(bo, type, from_highmem, userptr, cached); |
| if (ret) { |
| dev_err(atomisp_dev, "hmm_bo_alloc_pages failed.\n"); |
| goto alloc_page_err; |
| } |
| |
| /* Combine the virtual address and pages together */ |
| ret = hmm_bo_bind(bo); |
| if (ret) { |
| dev_err(atomisp_dev, "hmm_bo_bind failed.\n"); |
| goto bind_err; |
| } |
| |
| hmm_mem_stat.tol_cnt += pgnr; |
| |
| if (attrs & ATOMISP_MAP_FLAG_CLEARED) |
| hmm_set(bo->start, 0, bytes); |
| |
| dev_dbg(atomisp_dev, |
| "%s: pages: 0x%08x (%ld bytes), type: %d from highmem %d, user ptr %p, cached %d\n", |
| __func__, bo->start, bytes, type, from_highmem, userptr, cached); |
| |
| return bo->start; |
| |
| bind_err: |
| hmm_bo_free_pages(bo); |
| alloc_page_err: |
| hmm_bo_unref(bo); |
| create_bo_err: |
| return 0; |
| } |
| |
| void hmm_free(ia_css_ptr virt) |
| { |
| struct hmm_buffer_object *bo; |
| |
| dev_dbg(atomisp_dev, "%s: free 0x%08x\n", __func__, virt); |
| |
| WARN_ON(!virt); |
| |
| bo = hmm_bo_device_search_start(&bo_device, (unsigned int)virt); |
| |
| if (!bo) { |
| dev_err(atomisp_dev, |
| "can not find buffer object start with address 0x%x\n", |
| (unsigned int)virt); |
| return; |
| } |
| |
| hmm_mem_stat.tol_cnt -= bo->pgnr; |
| |
| hmm_bo_unbind(bo); |
| hmm_bo_free_pages(bo); |
| hmm_bo_unref(bo); |
| } |
| |
| static inline int hmm_check_bo(struct hmm_buffer_object *bo, unsigned int ptr) |
| { |
| if (!bo) { |
| dev_err(atomisp_dev, |
| "can not find buffer object contains address 0x%x\n", |
| ptr); |
| return -EINVAL; |
| } |
| |
| if (!hmm_bo_page_allocated(bo)) { |
| dev_err(atomisp_dev, |
| "buffer object has no page allocated.\n"); |
| return -EINVAL; |
| } |
| |
| if (!hmm_bo_allocated(bo)) { |
| dev_err(atomisp_dev, |
| "buffer object has no virtual address space allocated.\n"); |
| return -EINVAL; |
| } |
| |
| return 0; |
| } |
| |
| /* Read function in ISP memory management */ |
| static int load_and_flush_by_kmap(ia_css_ptr virt, void *data, |
| unsigned int bytes) |
| { |
| struct hmm_buffer_object *bo; |
| unsigned int idx, offset, len; |
| char *src, *des; |
| int ret; |
| |
| bo = hmm_bo_device_search_in_range(&bo_device, virt); |
| ret = hmm_check_bo(bo, virt); |
| if (ret) |
| return ret; |
| |
| des = (char *)data; |
| while (bytes) { |
| idx = (virt - bo->start) >> PAGE_SHIFT; |
| offset = (virt - bo->start) - (idx << PAGE_SHIFT); |
| |
| src = (char *)kmap(bo->page_obj[idx].page) + offset; |
| |
| if ((bytes + offset) >= PAGE_SIZE) { |
| len = PAGE_SIZE - offset; |
| bytes -= len; |
| } else { |
| len = bytes; |
| bytes = 0; |
| } |
| |
| virt += len; /* update virt for next loop */ |
| |
| if (des) { |
| memcpy(des, src, len); |
| des += len; |
| } |
| |
| clflush_cache_range(src, len); |
| |
| kunmap(bo->page_obj[idx].page); |
| } |
| |
| return 0; |
| } |
| |
| /* Read function in ISP memory management */ |
| static int load_and_flush(ia_css_ptr virt, void *data, unsigned int bytes) |
| { |
| struct hmm_buffer_object *bo; |
| int ret; |
| |
| bo = hmm_bo_device_search_in_range(&bo_device, virt); |
| ret = hmm_check_bo(bo, virt); |
| if (ret) |
| return ret; |
| |
| if (bo->status & HMM_BO_VMAPED || bo->status & HMM_BO_VMAPED_CACHED) { |
| void *src = bo->vmap_addr; |
| |
| src += (virt - bo->start); |
| memcpy(data, src, bytes); |
| if (bo->status & HMM_BO_VMAPED_CACHED) |
| clflush_cache_range(src, bytes); |
| } else { |
| void *vptr; |
| |
| vptr = hmm_bo_vmap(bo, true); |
| if (!vptr) |
| return load_and_flush_by_kmap(virt, data, bytes); |
| else |
| vptr = vptr + (virt - bo->start); |
| |
| memcpy(data, vptr, bytes); |
| clflush_cache_range(vptr, bytes); |
| hmm_bo_vunmap(bo); |
| } |
| |
| return 0; |
| } |
| |
| /* Read function in ISP memory management */ |
| int hmm_load(ia_css_ptr virt, void *data, unsigned int bytes) |
| { |
| if (!virt) { |
| dev_warn(atomisp_dev, |
| "hmm_store: address is NULL\n"); |
| return -EINVAL; |
| } |
| if (!data) { |
| dev_err(atomisp_dev, |
| "hmm_store: data is a NULL argument\n"); |
| return -EINVAL; |
| } |
| return load_and_flush(virt, data, bytes); |
| } |
| |
| /* Flush hmm data from the data cache */ |
| int hmm_flush(ia_css_ptr virt, unsigned int bytes) |
| { |
| return load_and_flush(virt, NULL, bytes); |
| } |
| |
| /* Write function in ISP memory management */ |
| int hmm_store(ia_css_ptr virt, const void *data, unsigned int bytes) |
| { |
| struct hmm_buffer_object *bo; |
| unsigned int idx, offset, len; |
| char *src, *des; |
| int ret; |
| |
| if (!virt) { |
| dev_warn(atomisp_dev, |
| "hmm_store: address is NULL\n"); |
| return -EINVAL; |
| } |
| if (!data) { |
| dev_err(atomisp_dev, |
| "hmm_store: data is a NULL argument\n"); |
| return -EINVAL; |
| } |
| |
| bo = hmm_bo_device_search_in_range(&bo_device, virt); |
| ret = hmm_check_bo(bo, virt); |
| if (ret) |
| return ret; |
| |
| if (bo->status & HMM_BO_VMAPED || bo->status & HMM_BO_VMAPED_CACHED) { |
| void *dst = bo->vmap_addr; |
| |
| dst += (virt - bo->start); |
| memcpy(dst, data, bytes); |
| if (bo->status & HMM_BO_VMAPED_CACHED) |
| clflush_cache_range(dst, bytes); |
| } else { |
| void *vptr; |
| |
| vptr = hmm_bo_vmap(bo, true); |
| if (vptr) { |
| vptr = vptr + (virt - bo->start); |
| |
| memcpy(vptr, data, bytes); |
| clflush_cache_range(vptr, bytes); |
| hmm_bo_vunmap(bo); |
| return 0; |
| } |
| } |
| |
| src = (char *)data; |
| while (bytes) { |
| idx = (virt - bo->start) >> PAGE_SHIFT; |
| offset = (virt - bo->start) - (idx << PAGE_SHIFT); |
| |
| if (in_atomic()) |
| des = (char *)kmap_atomic(bo->page_obj[idx].page); |
| else |
| des = (char *)kmap(bo->page_obj[idx].page); |
| |
| if (!des) { |
| dev_err(atomisp_dev, |
| "kmap buffer object page failed: pg_idx = %d\n", |
| idx); |
| return -EINVAL; |
| } |
| |
| des += offset; |
| |
| if ((bytes + offset) >= PAGE_SIZE) { |
| len = PAGE_SIZE - offset; |
| bytes -= len; |
| } else { |
| len = bytes; |
| bytes = 0; |
| } |
| |
| virt += len; |
| |
| memcpy(des, src, len); |
| |
| src += len; |
| |
| clflush_cache_range(des, len); |
| |
| if (in_atomic()) |
| /* |
| * Note: kunmap_atomic requires return addr from |
| * kmap_atomic, not the page. See linux/highmem.h |
| */ |
| kunmap_atomic(des - offset); |
| else |
| kunmap(bo->page_obj[idx].page); |
| } |
| |
| return 0; |
| } |
| |
| /* memset function in ISP memory management */ |
| int hmm_set(ia_css_ptr virt, int c, unsigned int bytes) |
| { |
| struct hmm_buffer_object *bo; |
| unsigned int idx, offset, len; |
| char *des; |
| int ret; |
| |
| bo = hmm_bo_device_search_in_range(&bo_device, virt); |
| ret = hmm_check_bo(bo, virt); |
| if (ret) |
| return ret; |
| |
| if (bo->status & HMM_BO_VMAPED || bo->status & HMM_BO_VMAPED_CACHED) { |
| void *dst = bo->vmap_addr; |
| |
| dst += (virt - bo->start); |
| memset(dst, c, bytes); |
| |
| if (bo->status & HMM_BO_VMAPED_CACHED) |
| clflush_cache_range(dst, bytes); |
| } else { |
| void *vptr; |
| |
| vptr = hmm_bo_vmap(bo, true); |
| if (vptr) { |
| vptr = vptr + (virt - bo->start); |
| memset(vptr, c, bytes); |
| clflush_cache_range(vptr, bytes); |
| hmm_bo_vunmap(bo); |
| return 0; |
| } |
| } |
| |
| while (bytes) { |
| idx = (virt - bo->start) >> PAGE_SHIFT; |
| offset = (virt - bo->start) - (idx << PAGE_SHIFT); |
| |
| des = (char *)kmap(bo->page_obj[idx].page) + offset; |
| |
| if ((bytes + offset) >= PAGE_SIZE) { |
| len = PAGE_SIZE - offset; |
| bytes -= len; |
| } else { |
| len = bytes; |
| bytes = 0; |
| } |
| |
| virt += len; |
| |
| memset(des, c, len); |
| |
| clflush_cache_range(des, len); |
| |
| kunmap(bo->page_obj[idx].page); |
| } |
| |
| return 0; |
| } |
| |
| /* Virtual address to physical address convert */ |
| phys_addr_t hmm_virt_to_phys(ia_css_ptr virt) |
| { |
| unsigned int idx, offset; |
| struct hmm_buffer_object *bo; |
| |
| bo = hmm_bo_device_search_in_range(&bo_device, virt); |
| if (!bo) { |
| dev_err(atomisp_dev, |
| "can not find buffer object contains address 0x%x\n", |
| virt); |
| return -1; |
| } |
| |
| idx = (virt - bo->start) >> PAGE_SHIFT; |
| offset = (virt - bo->start) - (idx << PAGE_SHIFT); |
| |
| return page_to_phys(bo->page_obj[idx].page) + offset; |
| } |
| |
| int hmm_mmap(struct vm_area_struct *vma, ia_css_ptr virt) |
| { |
| struct hmm_buffer_object *bo; |
| |
| bo = hmm_bo_device_search_start(&bo_device, virt); |
| if (!bo) { |
| dev_err(atomisp_dev, |
| "can not find buffer object start with address 0x%x\n", |
| virt); |
| return -EINVAL; |
| } |
| |
| return hmm_bo_mmap(vma, bo); |
| } |
| |
| /* Map ISP virtual address into IA virtual address */ |
| void *hmm_vmap(ia_css_ptr virt, bool cached) |
| { |
| struct hmm_buffer_object *bo; |
| void *ptr; |
| |
| bo = hmm_bo_device_search_in_range(&bo_device, virt); |
| if (!bo) { |
| dev_err(atomisp_dev, |
| "can not find buffer object contains address 0x%x\n", |
| virt); |
| return NULL; |
| } |
| |
| ptr = hmm_bo_vmap(bo, cached); |
| if (ptr) |
| return ptr + (virt - bo->start); |
| else |
| return NULL; |
| } |
| |
| /* Flush the memory which is mapped as cached memory through hmm_vmap */ |
| void hmm_flush_vmap(ia_css_ptr virt) |
| { |
| struct hmm_buffer_object *bo; |
| |
| bo = hmm_bo_device_search_in_range(&bo_device, virt); |
| if (!bo) { |
| dev_warn(atomisp_dev, |
| "can not find buffer object contains address 0x%x\n", |
| virt); |
| return; |
| } |
| |
| hmm_bo_flush_vmap(bo); |
| } |
| |
| void hmm_vunmap(ia_css_ptr virt) |
| { |
| struct hmm_buffer_object *bo; |
| |
| bo = hmm_bo_device_search_in_range(&bo_device, virt); |
| if (!bo) { |
| dev_warn(atomisp_dev, |
| "can not find buffer object contains address 0x%x\n", |
| virt); |
| return; |
| } |
| |
| hmm_bo_vunmap(bo); |
| } |
| |
| int hmm_pool_register(unsigned int pool_size, enum hmm_pool_type pool_type) |
| { |
| #if 0 // Just use the "normal" pool |
| switch (pool_type) { |
| case HMM_POOL_TYPE_RESERVED: |
| reserved_pool.pops = &reserved_pops; |
| return reserved_pool.pops->pool_init(&reserved_pool.pool_info, |
| pool_size); |
| case HMM_POOL_TYPE_DYNAMIC: |
| dynamic_pool.pops = &dynamic_pops; |
| return dynamic_pool.pops->pool_init(&dynamic_pool.pool_info, |
| pool_size); |
| default: |
| dev_err(atomisp_dev, "invalid pool type.\n"); |
| return -EINVAL; |
| } |
| #else |
| return 0; |
| #endif |
| } |
| |
| void hmm_pool_unregister(enum hmm_pool_type pool_type) |
| { |
| #if 0 // Just use the "normal" pool |
| switch (pool_type) { |
| case HMM_POOL_TYPE_RESERVED: |
| if (reserved_pool.pops && reserved_pool.pops->pool_exit) |
| reserved_pool.pops->pool_exit(&reserved_pool.pool_info); |
| break; |
| case HMM_POOL_TYPE_DYNAMIC: |
| if (dynamic_pool.pops && dynamic_pool.pops->pool_exit) |
| dynamic_pool.pops->pool_exit(&dynamic_pool.pool_info); |
| break; |
| default: |
| dev_err(atomisp_dev, "invalid pool type.\n"); |
| break; |
| } |
| #endif |
| |
| return; |
| } |
| |
| void *hmm_isp_vaddr_to_host_vaddr(ia_css_ptr ptr, bool cached) |
| { |
| return hmm_vmap(ptr, cached); |
| /* vmunmap will be done in hmm_bo_release() */ |
| } |
| |
| ia_css_ptr hmm_host_vaddr_to_hrt_vaddr(const void *ptr) |
| { |
| struct hmm_buffer_object *bo; |
| |
| bo = hmm_bo_device_search_vmap_start(&bo_device, ptr); |
| if (bo) |
| return bo->start; |
| |
| dev_err(atomisp_dev, |
| "can not find buffer object whose kernel virtual address is %p\n", |
| ptr); |
| return 0; |
| } |
| |
| void hmm_show_mem_stat(const char *func, const int line) |
| { |
| pr_info("tol_cnt=%d usr_size=%d res_size=%d res_cnt=%d sys_size=%d dyc_thr=%d dyc_size=%d.\n", |
| hmm_mem_stat.tol_cnt, |
| hmm_mem_stat.usr_size, hmm_mem_stat.res_size, |
| hmm_mem_stat.res_cnt, hmm_mem_stat.sys_size, |
| hmm_mem_stat.dyc_thr, hmm_mem_stat.dyc_size); |
| } |
| |
| void hmm_init_mem_stat(int res_pgnr, int dyc_en, int dyc_pgnr) |
| { |
| hmm_mem_stat.res_size = res_pgnr; |
| /* If reserved mem pool is not enabled, set its "mem stat" values as -1. */ |
| if (hmm_mem_stat.res_size == 0) { |
| hmm_mem_stat.res_size = -1; |
| hmm_mem_stat.res_cnt = -1; |
| } |
| |
| /* If dynamic memory pool is not enabled, set its "mem stat" values as -1. */ |
| if (!dyc_en) { |
| hmm_mem_stat.dyc_size = -1; |
| hmm_mem_stat.dyc_thr = -1; |
| } else { |
| hmm_mem_stat.dyc_size = 0; |
| hmm_mem_stat.dyc_thr = dyc_pgnr; |
| } |
| hmm_mem_stat.usr_size = 0; |
| hmm_mem_stat.sys_size = 0; |
| hmm_mem_stat.tol_cnt = 0; |
| } |