[COMMON] iommu/exynos: add slot property setting
authorJanghyuck Kim <janghyuck.kim@samsung.com>
Mon, 2 Jan 2017 11:41:27 +0000 (20:41 +0900)
committerSangwook Ju <sw.ju@samsung.com>
Mon, 14 May 2018 10:45:21 +0000 (19:45 +0900)
This patch added parsing DT about slot properties, and parsed
information is used at the beginning of sysmmu.

Change-Id: I1148177911eff50ee71282c4bba508368b1a4a0b
Signed-off-by: Janghyuck Kim <janghyuck.kim@samsung.com>
drivers/iommu/exynos-iommu.c
drivers/iommu/exynos-iommu.h

index bc5a3add2601b3c096e1a485cf21b215d730e1ca..348674f987ceff09ce259f7e9cb1c4c140b10b20 100644 (file)
@@ -768,11 +768,34 @@ static int __init sysmmu_parse_tlb_port_dt(struct device *sysmmu,
                                struct sysmmu_drvdata *drvdata)
 {
        const char *props_name = "sysmmu,tlb_property";
+       const char *slot_props_name = "sysmmu,slot_property";
        struct tlb_props *tlb_props = &drvdata->tlb_props;
        struct tlb_port_cfg *port_cfg = NULL;
+       unsigned int *slot_cfg = NULL;
        int i, cnt, ret;
        int port_id_cnt = 0;
 
+       cnt = of_property_count_u32_elems(sysmmu->of_node, slot_props_name);
+       if (cnt > 0) {
+               slot_cfg = kzalloc(sizeof(*slot_cfg) * cnt, GFP_KERNEL);
+               if (!slot_cfg)
+                       return -ENOMEM;
+
+               for (i = 0; i < cnt; i++) {
+                       ret = of_property_read_u32_index(sysmmu->of_node,
+                                       slot_props_name, i, &slot_cfg[i]);
+                       if (ret) {
+                               dev_err(sysmmu, "failed to get slot property."
+                                               "cnt = %d, ret = %d\n", i, ret);
+                               ret = -EINVAL;
+                               goto err_slot_prop;
+                       }
+               }
+
+               tlb_props->port_props.slot_cnt = cnt;
+               tlb_props->port_props.slot_cfg = slot_cfg;
+       }
+
        cnt = of_property_count_u32_elems(sysmmu->of_node, props_name);
        if (!cnt || cnt < 0) {
                dev_info(sysmmu, "No TLB port propeties found.\n");
@@ -780,8 +803,10 @@ static int __init sysmmu_parse_tlb_port_dt(struct device *sysmmu,
        }
 
        port_cfg = kzalloc(sizeof(*port_cfg) * (cnt/2), GFP_KERNEL);
-       if (!port_cfg)
-               return -ENOMEM;
+       if (!port_cfg) {
+               ret = -ENOMEM;
+               goto err_slot_prop;
+       }
 
        for (i = 0; i < cnt; i+=2) {
                ret = of_property_read_u32_index(sysmmu->of_node,
@@ -812,6 +837,9 @@ static int __init sysmmu_parse_tlb_port_dt(struct device *sysmmu,
 err_port_prop:
        kfree(port_cfg);
 
+err_slot_prop:
+       kfree(slot_cfg);
+
        return ret;
 }
 
@@ -1114,6 +1142,7 @@ static void __sysmmu_set_tlb_port_dedication(struct sysmmu_drvdata *drvdata)
        struct tlb_props *tlb_props = &drvdata->tlb_props;
        unsigned int i;
        int port_id_cnt = tlb_props->port_props.port_id_cnt;
+       int slot_cnt = tlb_props->port_props.slot_cnt;
 
        if (port_id_cnt > tlb_num) {
                dev_warn(drvdata->sysmmu,
@@ -1124,6 +1153,10 @@ static void __sysmmu_set_tlb_port_dedication(struct sysmmu_drvdata *drvdata)
 
        for (i = 0; i < port_id_cnt; i++)
                __sysmmu_set_tlb_port(drvdata, i);
+
+       for (i = 0; i < slot_cnt; i++)
+               writel_relaxed(tlb_props->port_props.slot_cfg[i],
+                               drvdata->sfrbase + REG_SLOT_RSV(i));
 }
 
 static void __sysmmu_init_config(struct sysmmu_drvdata *drvdata)
index 9526b883bdecd8de578bbc86e7f67195098fd971..89f45636b02cce61af3d3edca515ea9c80bb8ea3 100644 (file)
@@ -182,6 +182,7 @@ typedef u32 sysmmu_pte_t;
 #define REG_CAPA1_SBB_VPN              0x8024
 #define REG_CAPA1_SBB_LINK             0x8028
 #define REG_CAPA1_SBB_ATTR             0x802C
+#define REG_SLOT_RSV(n)                        (0x4000 + ((n) * 0x20))
 #define MMU_CAPA1_SET_TLB_READ_ENTRY(tid, set, way, line)              \
                        ((set) | ((way) << 8) | ((line) << 16) | ((tid) << 20))
 #define MMU_TLB_CFG_MASK(reg)          ((reg) & ((0x7 << 5) | (0x3 << 2) | (0x1 << 1)))
@@ -305,7 +306,9 @@ struct tlb_way_props {
 
 struct tlb_port_props {
        int port_id_cnt;
+       int slot_cnt;
        struct tlb_port_cfg *port_cfg;
+       unsigned int *slot_cfg;
 };
 
 struct tlb_props {