msm: camera: smmu: Add support for non-contiguous mermory region
Add support to discard a memory region inside the full dma map virtual address space region. CRs-Fixed: 2580128 Change-Id: I76cc778f2437a01a4efabec836ce92c47d983d61 Signed-off-by: Pavan Kumar Chilamkurthi <pchilamk@codeaurora.org>
This commit is contained in:
@@ -32,6 +32,7 @@ struct hfi_mem {
|
|||||||
* @sec_heap: secondary heap hfi memory for firmware
|
* @sec_heap: secondary heap hfi memory for firmware
|
||||||
* @qdss: qdss mapped memory for fw
|
* @qdss: qdss mapped memory for fw
|
||||||
* @io_mem: io memory info
|
* @io_mem: io memory info
|
||||||
|
* @io_mem2: 2nd io memory info
|
||||||
* @icp_base: icp base address
|
* @icp_base: icp base address
|
||||||
*/
|
*/
|
||||||
struct hfi_mem_info {
|
struct hfi_mem_info {
|
||||||
@@ -44,6 +45,7 @@ struct hfi_mem_info {
|
|||||||
struct hfi_mem shmem;
|
struct hfi_mem shmem;
|
||||||
struct hfi_mem qdss;
|
struct hfi_mem qdss;
|
||||||
struct hfi_mem io_mem;
|
struct hfi_mem io_mem;
|
||||||
|
struct hfi_mem io_mem2;
|
||||||
void __iomem *icp_base;
|
void __iomem *icp_base;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -39,6 +39,8 @@
|
|||||||
#define HFI_REG_QDSS_IOVA_SIZE 0x70
|
#define HFI_REG_QDSS_IOVA_SIZE 0x70
|
||||||
#define HFI_REG_IO_REGION_IOVA 0x74
|
#define HFI_REG_IO_REGION_IOVA 0x74
|
||||||
#define HFI_REG_IO_REGION_SIZE 0x78
|
#define HFI_REG_IO_REGION_SIZE 0x78
|
||||||
|
#define HFI_REG_IO2_REGION_IOVA 0x7C
|
||||||
|
#define HFI_REG_IO2_REGION_SIZE 0x80
|
||||||
|
|
||||||
/* end of ICP CSR registers */
|
/* end of ICP CSR registers */
|
||||||
|
|
||||||
|
@@ -669,6 +669,15 @@ int cam_hfi_resume(struct hfi_mem_info *hfi_mem,
|
|||||||
cam_io_w_mb((uint32_t)hfi_mem->io_mem.len,
|
cam_io_w_mb((uint32_t)hfi_mem->io_mem.len,
|
||||||
icp_base + HFI_REG_IO_REGION_SIZE);
|
icp_base + HFI_REG_IO_REGION_SIZE);
|
||||||
|
|
||||||
|
cam_io_w_mb((uint32_t)hfi_mem->io_mem2.iova,
|
||||||
|
icp_base + HFI_REG_IO2_REGION_IOVA);
|
||||||
|
cam_io_w_mb((uint32_t)hfi_mem->io_mem2.len,
|
||||||
|
icp_base + HFI_REG_IO2_REGION_SIZE);
|
||||||
|
|
||||||
|
CAM_INFO(CAM_HFI, "Resume IO1 : [0x%x 0x%x] IO2 [0x%x 0x%x]",
|
||||||
|
hfi_mem->io_mem.iova, hfi_mem->io_mem.len,
|
||||||
|
hfi_mem->io_mem2.iova, hfi_mem->io_mem2.len);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -859,6 +868,14 @@ int cam_hfi_init(uint8_t event_driven_mode, struct hfi_mem_info *hfi_mem,
|
|||||||
icp_base + HFI_REG_IO_REGION_IOVA);
|
icp_base + HFI_REG_IO_REGION_IOVA);
|
||||||
cam_io_w_mb((uint32_t)hfi_mem->io_mem.len,
|
cam_io_w_mb((uint32_t)hfi_mem->io_mem.len,
|
||||||
icp_base + HFI_REG_IO_REGION_SIZE);
|
icp_base + HFI_REG_IO_REGION_SIZE);
|
||||||
|
cam_io_w_mb((uint32_t)hfi_mem->io_mem2.iova,
|
||||||
|
icp_base + HFI_REG_IO2_REGION_IOVA);
|
||||||
|
cam_io_w_mb((uint32_t)hfi_mem->io_mem2.len,
|
||||||
|
icp_base + HFI_REG_IO2_REGION_SIZE);
|
||||||
|
|
||||||
|
CAM_INFO(CAM_HFI, "Init IO1 : [0x%x 0x%x] IO2 [0x%x 0x%x]",
|
||||||
|
hfi_mem->io_mem.iova, hfi_mem->io_mem.len,
|
||||||
|
hfi_mem->io_mem2.iova, hfi_mem->io_mem2.len);
|
||||||
|
|
||||||
hw_version = cam_io_r(icp_base + HFI_REG_A5_HW_VERSION);
|
hw_version = cam_io_r(icp_base + HFI_REG_A5_HW_VERSION);
|
||||||
|
|
||||||
|
@@ -2858,18 +2858,21 @@ static int cam_icp_allocate_qdss_mem(void)
|
|||||||
static int cam_icp_get_io_mem_info(void)
|
static int cam_icp_get_io_mem_info(void)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
size_t len;
|
size_t len, discard_iova_len;
|
||||||
dma_addr_t iova;
|
dma_addr_t iova, discard_iova_start;
|
||||||
|
|
||||||
rc = cam_smmu_get_io_region_info(icp_hw_mgr.iommu_hdl,
|
rc = cam_smmu_get_io_region_info(icp_hw_mgr.iommu_hdl,
|
||||||
&iova, &len);
|
&iova, &len, &discard_iova_start, &discard_iova_len);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
icp_hw_mgr.hfi_mem.io_mem.iova_len = len;
|
icp_hw_mgr.hfi_mem.io_mem.iova_len = len;
|
||||||
icp_hw_mgr.hfi_mem.io_mem.iova_start = iova;
|
icp_hw_mgr.hfi_mem.io_mem.iova_start = iova;
|
||||||
|
icp_hw_mgr.hfi_mem.io_mem.discard_iova_start = discard_iova_start;
|
||||||
|
icp_hw_mgr.hfi_mem.io_mem.discard_iova_len = discard_iova_len;
|
||||||
|
|
||||||
CAM_DBG(CAM_ICP, "iova: %llx, len: %zu", iova, len);
|
CAM_DBG(CAM_ICP, "iova: %llx, len: %zu discard iova %llx len %llx",
|
||||||
|
iova, len, discard_iova_start, discard_iova_len);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@@ -3162,12 +3165,38 @@ static int cam_icp_mgr_hfi_resume(struct cam_icp_hw_mgr *hw_mgr)
|
|||||||
hfi_mem.qdss.iova = icp_hw_mgr.hfi_mem.qdss_buf.iova;
|
hfi_mem.qdss.iova = icp_hw_mgr.hfi_mem.qdss_buf.iova;
|
||||||
hfi_mem.qdss.len = icp_hw_mgr.hfi_mem.qdss_buf.len;
|
hfi_mem.qdss.len = icp_hw_mgr.hfi_mem.qdss_buf.len;
|
||||||
|
|
||||||
hfi_mem.io_mem.iova = icp_hw_mgr.hfi_mem.io_mem.iova_start;
|
if (icp_hw_mgr.hfi_mem.io_mem.discard_iova_start &&
|
||||||
hfi_mem.io_mem.len = icp_hw_mgr.hfi_mem.io_mem.iova_len;
|
icp_hw_mgr.hfi_mem.io_mem.discard_iova_len) {
|
||||||
|
/* IO Region 1 */
|
||||||
|
hfi_mem.io_mem.iova = icp_hw_mgr.hfi_mem.io_mem.iova_start;
|
||||||
|
hfi_mem.io_mem.len =
|
||||||
|
icp_hw_mgr.hfi_mem.io_mem.discard_iova_start -
|
||||||
|
icp_hw_mgr.hfi_mem.io_mem.iova_start;
|
||||||
|
|
||||||
CAM_DBG(CAM_ICP, "IO region IOVA = %X length = %lld",
|
/* IO Region 2 */
|
||||||
hfi_mem.io_mem.iova,
|
hfi_mem.io_mem2.iova =
|
||||||
hfi_mem.io_mem.len);
|
icp_hw_mgr.hfi_mem.io_mem.discard_iova_start +
|
||||||
|
icp_hw_mgr.hfi_mem.io_mem.discard_iova_len;
|
||||||
|
hfi_mem.io_mem2.len =
|
||||||
|
icp_hw_mgr.hfi_mem.io_mem.iova_start +
|
||||||
|
icp_hw_mgr.hfi_mem.io_mem.iova_len -
|
||||||
|
hfi_mem.io_mem2.iova;
|
||||||
|
} else {
|
||||||
|
/* IO Region 1 */
|
||||||
|
hfi_mem.io_mem.iova = icp_hw_mgr.hfi_mem.io_mem.iova_start;
|
||||||
|
hfi_mem.io_mem.len = icp_hw_mgr.hfi_mem.io_mem.iova_len;
|
||||||
|
|
||||||
|
/* IO Region 2 */
|
||||||
|
hfi_mem.io_mem2.iova = 0x0;
|
||||||
|
hfi_mem.io_mem2.len = 0x0;
|
||||||
|
}
|
||||||
|
|
||||||
|
CAM_DBG(CAM_ICP,
|
||||||
|
"IO region1 IOVA = %X length = %lld, IO region2 IOVA = %X length = %lld",
|
||||||
|
hfi_mem.io_mem.iova,
|
||||||
|
hfi_mem.io_mem.len,
|
||||||
|
hfi_mem.io_mem2.iova,
|
||||||
|
hfi_mem.io_mem2.len);
|
||||||
|
|
||||||
return cam_hfi_resume(&hfi_mem,
|
return cam_hfi_resume(&hfi_mem,
|
||||||
a5_dev->soc_info.reg_map[A5_SIERRA_BASE].mem_base,
|
a5_dev->soc_info.reg_map[A5_SIERRA_BASE].mem_base,
|
||||||
@@ -3637,8 +3666,31 @@ static int cam_icp_mgr_hfi_init(struct cam_icp_hw_mgr *hw_mgr)
|
|||||||
hfi_mem.qdss.iova = icp_hw_mgr.hfi_mem.qdss_buf.iova;
|
hfi_mem.qdss.iova = icp_hw_mgr.hfi_mem.qdss_buf.iova;
|
||||||
hfi_mem.qdss.len = icp_hw_mgr.hfi_mem.qdss_buf.len;
|
hfi_mem.qdss.len = icp_hw_mgr.hfi_mem.qdss_buf.len;
|
||||||
|
|
||||||
hfi_mem.io_mem.iova = icp_hw_mgr.hfi_mem.io_mem.iova_start;
|
if (icp_hw_mgr.hfi_mem.io_mem.discard_iova_start &&
|
||||||
hfi_mem.io_mem.len = icp_hw_mgr.hfi_mem.io_mem.iova_len;
|
icp_hw_mgr.hfi_mem.io_mem.discard_iova_len) {
|
||||||
|
/* IO Region 1 */
|
||||||
|
hfi_mem.io_mem.iova = icp_hw_mgr.hfi_mem.io_mem.iova_start;
|
||||||
|
hfi_mem.io_mem.len =
|
||||||
|
icp_hw_mgr.hfi_mem.io_mem.discard_iova_start -
|
||||||
|
icp_hw_mgr.hfi_mem.io_mem.iova_start;
|
||||||
|
|
||||||
|
/* IO Region 2 */
|
||||||
|
hfi_mem.io_mem2.iova =
|
||||||
|
icp_hw_mgr.hfi_mem.io_mem.discard_iova_start +
|
||||||
|
icp_hw_mgr.hfi_mem.io_mem.discard_iova_len;
|
||||||
|
hfi_mem.io_mem2.len =
|
||||||
|
icp_hw_mgr.hfi_mem.io_mem.iova_start +
|
||||||
|
icp_hw_mgr.hfi_mem.io_mem.iova_len -
|
||||||
|
hfi_mem.io_mem2.iova;
|
||||||
|
} else {
|
||||||
|
/* IO Region 1 */
|
||||||
|
hfi_mem.io_mem.iova = icp_hw_mgr.hfi_mem.io_mem.iova_start;
|
||||||
|
hfi_mem.io_mem.len = icp_hw_mgr.hfi_mem.io_mem.iova_len;
|
||||||
|
|
||||||
|
/* IO Region 2 */
|
||||||
|
hfi_mem.io_mem2.iova = 0x0;
|
||||||
|
hfi_mem.io_mem2.len = 0x0;
|
||||||
|
}
|
||||||
|
|
||||||
return cam_hfi_init(0, &hfi_mem,
|
return cam_hfi_init(0, &hfi_mem,
|
||||||
a5_dev->soc_info.reg_map[A5_SIERRA_BASE].mem_base,
|
a5_dev->soc_info.reg_map[A5_SIERRA_BASE].mem_base,
|
||||||
|
@@ -15,6 +15,8 @@
|
|||||||
#include <linux/workqueue.h>
|
#include <linux/workqueue.h>
|
||||||
#include <linux/genalloc.h>
|
#include <linux/genalloc.h>
|
||||||
#include <linux/debugfs.h>
|
#include <linux/debugfs.h>
|
||||||
|
#include <linux/dma-iommu.h>
|
||||||
|
|
||||||
#include <soc/qcom/secure_buffer.h>
|
#include <soc/qcom/secure_buffer.h>
|
||||||
|
|
||||||
#include <media/cam_req_mgr.h>
|
#include <media/cam_req_mgr.h>
|
||||||
@@ -137,6 +139,10 @@ struct cam_context_bank_info {
|
|||||||
bool is_mul_client;
|
bool is_mul_client;
|
||||||
int device_count;
|
int device_count;
|
||||||
int num_shared_hdl;
|
int num_shared_hdl;
|
||||||
|
|
||||||
|
/* discard iova - non-zero values are valid */
|
||||||
|
dma_addr_t discard_iova_start;
|
||||||
|
size_t discard_iova_len;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct cam_iommu_cb_set {
|
struct cam_iommu_cb_set {
|
||||||
@@ -1440,11 +1446,13 @@ end:
|
|||||||
EXPORT_SYMBOL(cam_smmu_dealloc_qdss);
|
EXPORT_SYMBOL(cam_smmu_dealloc_qdss);
|
||||||
|
|
||||||
int cam_smmu_get_io_region_info(int32_t smmu_hdl,
|
int cam_smmu_get_io_region_info(int32_t smmu_hdl,
|
||||||
dma_addr_t *iova, size_t *len)
|
dma_addr_t *iova, size_t *len,
|
||||||
|
dma_addr_t *discard_iova_start, size_t *discard_iova_len)
|
||||||
{
|
{
|
||||||
int32_t idx;
|
int32_t idx;
|
||||||
|
|
||||||
if (!iova || !len || (smmu_hdl == HANDLE_INIT)) {
|
if (!iova || !len || !discard_iova_start || !discard_iova_len ||
|
||||||
|
(smmu_hdl == HANDLE_INIT)) {
|
||||||
CAM_ERR(CAM_SMMU, "Error: Input args are invalid");
|
CAM_ERR(CAM_SMMU, "Error: Input args are invalid");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
@@ -1466,10 +1474,15 @@ int cam_smmu_get_io_region_info(int32_t smmu_hdl,
|
|||||||
mutex_lock(&iommu_cb_set.cb_info[idx].lock);
|
mutex_lock(&iommu_cb_set.cb_info[idx].lock);
|
||||||
*iova = iommu_cb_set.cb_info[idx].io_info.iova_start;
|
*iova = iommu_cb_set.cb_info[idx].io_info.iova_start;
|
||||||
*len = iommu_cb_set.cb_info[idx].io_info.iova_len;
|
*len = iommu_cb_set.cb_info[idx].io_info.iova_len;
|
||||||
|
*discard_iova_start =
|
||||||
|
iommu_cb_set.cb_info[idx].io_info.discard_iova_start;
|
||||||
|
*discard_iova_len =
|
||||||
|
iommu_cb_set.cb_info[idx].io_info.discard_iova_len;
|
||||||
|
|
||||||
CAM_DBG(CAM_SMMU,
|
CAM_DBG(CAM_SMMU,
|
||||||
"I/O area for hdl = %x start addr = %pK len = %zu",
|
"I/O area for hdl = %x Region:[%pK %zu] Discard:[%pK %zu]",
|
||||||
smmu_hdl, *iova, *len);
|
smmu_hdl, *iova, *len,
|
||||||
|
*discard_iova_start, *discard_iova_len);
|
||||||
mutex_unlock(&iommu_cb_set.cb_info[idx].lock);
|
mutex_unlock(&iommu_cb_set.cb_info[idx].lock);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -3339,6 +3352,11 @@ static int cam_smmu_setup_cb(struct cam_context_bank_info *cb,
|
|||||||
rc = -ENODEV;
|
rc = -ENODEV;
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cb->discard_iova_start)
|
||||||
|
iommu_dma_reserve_iova(dev, cb->discard_iova_start,
|
||||||
|
cb->discard_iova_len);
|
||||||
|
|
||||||
cb->state = CAM_SMMU_ATTACH;
|
cb->state = CAM_SMMU_ATTACH;
|
||||||
} else {
|
} else {
|
||||||
CAM_ERR(CAM_SMMU, "Context bank does not have IO region");
|
CAM_ERR(CAM_SMMU, "Context bank does not have IO region");
|
||||||
@@ -3405,6 +3423,52 @@ static int cam_alloc_smmu_context_banks(struct device *dev)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int cam_smmu_get_discard_memory_regions(struct device_node *of_node,
|
||||||
|
dma_addr_t *discard_iova_start, size_t *discard_iova_len)
|
||||||
|
{
|
||||||
|
uint32_t discard_iova[2] = { 0 };
|
||||||
|
int num_values = 0;
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
if (!discard_iova_start || !discard_iova_len)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
*discard_iova_start = 0;
|
||||||
|
*discard_iova_len = 0;
|
||||||
|
|
||||||
|
num_values = of_property_count_u32_elems(of_node,
|
||||||
|
"iova-region-discard");
|
||||||
|
if (num_values <= 0) {
|
||||||
|
CAM_DBG(CAM_UTIL, "No discard region specified");
|
||||||
|
return 0;
|
||||||
|
} else if (num_values != 2) {
|
||||||
|
CAM_ERR(CAM_UTIL, "Invalid discard region specified %d",
|
||||||
|
num_values);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = of_property_read_u32_array(of_node,
|
||||||
|
"iova-region-discard",
|
||||||
|
discard_iova, num_values);
|
||||||
|
if (rc) {
|
||||||
|
CAM_ERR(CAM_UTIL, "Can not read discard region %d", num_values);
|
||||||
|
return rc;
|
||||||
|
} else if (!discard_iova[0] || !discard_iova[1]) {
|
||||||
|
CAM_ERR(CAM_UTIL,
|
||||||
|
"Incorrect Discard region specified [0x%x 0x%x]",
|
||||||
|
discard_iova[0], discard_iova[1]);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
CAM_DBG(CAM_UTIL, "Discard region [0x%x 0x%x]",
|
||||||
|
discard_iova[0], discard_iova[0] + discard_iova[1]);
|
||||||
|
|
||||||
|
*discard_iova_start = discard_iova[0];
|
||||||
|
*discard_iova_len = discard_iova[1];
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int cam_smmu_get_memory_regions_info(struct device_node *of_node,
|
static int cam_smmu_get_memory_regions_info(struct device_node *of_node,
|
||||||
struct cam_context_bank_info *cb)
|
struct cam_context_bank_info *cb)
|
||||||
{
|
{
|
||||||
@@ -3503,6 +3567,16 @@ static int cam_smmu_get_memory_regions_info(struct device_node *of_node,
|
|||||||
cb->io_support = 1;
|
cb->io_support = 1;
|
||||||
cb->io_info.iova_start = region_start;
|
cb->io_info.iova_start = region_start;
|
||||||
cb->io_info.iova_len = region_len;
|
cb->io_info.iova_len = region_len;
|
||||||
|
rc = cam_smmu_get_discard_memory_regions(child_node,
|
||||||
|
&cb->io_info.discard_iova_start,
|
||||||
|
&cb->io_info.discard_iova_len);
|
||||||
|
if (rc) {
|
||||||
|
CAM_ERR(CAM_SMMU,
|
||||||
|
"Invalid Discard region specified in IO region, rc=%d",
|
||||||
|
rc);
|
||||||
|
of_node_put(mem_map_node);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case CAM_SMMU_REGION_SECHEAP:
|
case CAM_SMMU_REGION_SECHEAP:
|
||||||
cb->secheap_support = 1;
|
cb->secheap_support = 1;
|
||||||
@@ -3527,6 +3601,60 @@ static int cam_smmu_get_memory_regions_info(struct device_node *of_node,
|
|||||||
CAM_DBG(CAM_SMMU, "region_len -> %X", region_len);
|
CAM_DBG(CAM_SMMU, "region_len -> %X", region_len);
|
||||||
CAM_DBG(CAM_SMMU, "region_id -> %X", region_id);
|
CAM_DBG(CAM_SMMU, "region_id -> %X", region_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cb->io_support) {
|
||||||
|
rc = cam_smmu_get_discard_memory_regions(of_node,
|
||||||
|
&cb->discard_iova_start,
|
||||||
|
&cb->discard_iova_len);
|
||||||
|
if (rc) {
|
||||||
|
CAM_ERR(CAM_SMMU,
|
||||||
|
"Invalid Discard region specified in CB, rc=%d",
|
||||||
|
rc);
|
||||||
|
of_node_put(mem_map_node);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make sure Discard region is properly specified */
|
||||||
|
if ((cb->discard_iova_start !=
|
||||||
|
cb->io_info.discard_iova_start) ||
|
||||||
|
(cb->discard_iova_len !=
|
||||||
|
cb->io_info.discard_iova_len)) {
|
||||||
|
CAM_ERR(CAM_SMMU,
|
||||||
|
"Mismatch Discard region specified, [0x%x 0x%x] [0x%x 0x%x]",
|
||||||
|
cb->discard_iova_start,
|
||||||
|
cb->discard_iova_len,
|
||||||
|
cb->io_info.discard_iova_start,
|
||||||
|
cb->io_info.discard_iova_len);
|
||||||
|
of_node_put(mem_map_node);
|
||||||
|
return -EINVAL;
|
||||||
|
} else if (cb->discard_iova_start && cb->discard_iova_len) {
|
||||||
|
if ((cb->discard_iova_start <=
|
||||||
|
cb->io_info.iova_start) ||
|
||||||
|
(cb->discard_iova_start >=
|
||||||
|
cb->io_info.iova_start + cb->io_info.iova_len) ||
|
||||||
|
(cb->discard_iova_start + cb->discard_iova_len >=
|
||||||
|
cb->io_info.iova_start + cb->io_info.iova_len)) {
|
||||||
|
CAM_ERR(CAM_SMMU,
|
||||||
|
"[%s] : Incorrect Discard region specified [0x%x 0x%x] in [0x%x 0x%x]",
|
||||||
|
cb->name,
|
||||||
|
cb->discard_iova_start,
|
||||||
|
cb->discard_iova_start + cb->discard_iova_len,
|
||||||
|
cb->io_info.iova_start,
|
||||||
|
cb->io_info.iova_start + cb->io_info.iova_len);
|
||||||
|
of_node_put(mem_map_node);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
CAM_INFO(CAM_SMMU,
|
||||||
|
"[%s] : Discard region specified [0x%x 0x%x] in [0x%x 0x%x]",
|
||||||
|
cb->name,
|
||||||
|
cb->discard_iova_start,
|
||||||
|
cb->discard_iova_start + cb->discard_iova_len,
|
||||||
|
cb->io_info.iova_start,
|
||||||
|
cb->io_info.iova_start + cb->io_info.iova_len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
of_node_put(mem_map_node);
|
of_node_put(mem_map_node);
|
||||||
|
|
||||||
if (!num_regions) {
|
if (!num_regions) {
|
||||||
|
@@ -60,12 +60,16 @@ typedef void (*cam_smmu_client_page_fault_handler)(struct iommu_domain *domain,
|
|||||||
/**
|
/**
|
||||||
* @brief : Structure to store region information
|
* @brief : Structure to store region information
|
||||||
*
|
*
|
||||||
* @param iova_start : Start address of region
|
* @param iova_start : Start address of region
|
||||||
* @param iova_len : length of region
|
* @param iova_len : length of region
|
||||||
|
* @param discard_iova_start : iova addr start from where should not be used
|
||||||
|
* @param discard_iova_len : length of discard iova region
|
||||||
*/
|
*/
|
||||||
struct cam_smmu_region_info {
|
struct cam_smmu_region_info {
|
||||||
dma_addr_t iova_start;
|
dma_addr_t iova_start;
|
||||||
size_t iova_len;
|
size_t iova_len;
|
||||||
|
dma_addr_t discard_iova_start;
|
||||||
|
size_t discard_iova_len;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -387,11 +391,14 @@ int cam_smmu_dealloc_qdss(int32_t smmu_hdl);
|
|||||||
* @param smmu_hdl: SMMU handle identifying the context bank
|
* @param smmu_hdl: SMMU handle identifying the context bank
|
||||||
* @param iova: IOVA address of allocated I/O region
|
* @param iova: IOVA address of allocated I/O region
|
||||||
* @param len: Length of allocated I/O memory
|
* @param len: Length of allocated I/O memory
|
||||||
|
* @param discard_iova_start: Start address of io space to discard
|
||||||
|
* @param discard_iova_len: Length of io space to discard
|
||||||
*
|
*
|
||||||
* @return Status of operation. Negative in case of error. Zero otherwise.
|
* @return Status of operation. Negative in case of error. Zero otherwise.
|
||||||
*/
|
*/
|
||||||
int cam_smmu_get_io_region_info(int32_t smmu_hdl,
|
int cam_smmu_get_io_region_info(int32_t smmu_hdl,
|
||||||
dma_addr_t *iova, size_t *len);
|
dma_addr_t *iova, size_t *len,
|
||||||
|
dma_addr_t *discard_iova_start, size_t *discard_iova_len);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief : API to register SMMU hw to platform framework.
|
* @brief : API to register SMMU hw to platform framework.
|
||||||
|
Reference in New Issue
Block a user