OSDN Git Service

soc: qcom: hab: add dts parsing into hab driver
[sagit-ice-cold/kernel_xiaomi_msm8998.git] / drivers / soc / qcom / hab / hab_parser.c
index a38d9bc..da0a4a3 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -12,6 +12,7 @@
  */
 
 #include "hab.h"
+#include <linux/of.h>
 
 /*
  * set valid mmid value in tbl to show this is valid entry. All inputs here are
@@ -63,3 +64,98 @@ int fill_default_gvm_settings(struct local_vmid *settings, int vmid_local,
        return fill_vmid_mmid_tbl(settings->vmid_mmid_list, 0, 1,
                mmid_start/100, (mmid_end-mmid_start)/100+1, HABCFG_BE_FALSE);
 }
+
+static int hab_parse_dt(struct local_vmid *settings)
+{
+       int result, i;
+       struct device_node *hab_node = NULL;
+       struct device_node *mmid_grp_node = NULL;
+       const char *role = NULL;
+       int tmp = -1, vmids_num;
+       u32 vmids[16];
+       int32_t grp_start_id, be;
+
+       /* parse device tree*/
+       pr_debug("parsing hab node in device tree...\n");
+       hab_node = of_find_compatible_node(NULL, NULL, "qcom,hab");
+       if (!hab_node) {
+               pr_err("no hab device tree node\n");
+               return -ENODEV;
+       }
+
+       /* read the local vmid of this VM, like 0 for host, 1 for AGL GVM */
+       result = of_property_read_u32(hab_node, "vmid", &tmp);
+       if (result) {
+               pr_err("failed to read local vmid, result = %d\n", result);
+               return result;
+       }
+
+       pr_debug("local vmid = %d\n", tmp);
+       settings->self = tmp;
+
+       for_each_child_of_node(hab_node, mmid_grp_node) {
+               /* read the group starting id */
+               result = of_property_read_u32(mmid_grp_node,
+                               "grp-start-id", &tmp);
+               if (result) {
+                       pr_err("failed to read grp-start-id, result = %d\n",
+                               result);
+                       return result;
+               }
+
+               pr_debug("grp-start-id = %d\n", tmp);
+               grp_start_id = tmp;
+
+               /* read the role(fe/be) of these pchans in this mmid group */
+               result = of_property_read_string(mmid_grp_node, "role", &role);
+               if (result) {
+                       pr_err("failed to get role, result = %d\n", result);
+                       return result;
+               }
+
+               pr_debug("local role of this mmid group is %s\n", role);
+               if (!strcmp(role, "be"))
+                       be = 1;
+               else
+                       be = 0;
+
+               /* read the remote vmids for these pchans in this mmid group */
+               vmids_num = of_property_count_elems_of_size(mmid_grp_node,
+                                       "remote-vmids", sizeof(u32));
+
+               result = of_property_read_u32_array(mmid_grp_node,
+                                       "remote-vmids", vmids, vmids_num);
+               if (result) {
+                       pr_err("failed to read remote-vmids, result = %d\n",
+                               result);
+                       return result;
+               }
+
+               for (i = 0; i < vmids_num; i++) {
+                       pr_debug("vmids_num = %d, vmids[%d] = %d\n",
+                               vmids_num, i, vmids[i]);
+
+                       result = fill_vmid_mmid_tbl(
+                                       settings->vmid_mmid_list,
+                                       vmids[i], 1,
+                                       grp_start_id/100, 1, be);
+                       if (result) {
+                               pr_err("fill_vmid_mmid_tbl failed\n");
+                               return result;
+                       }
+               }
+
+       }
+
+       dump_settings(settings);
+       return 0;
+}
+
+int hab_parse(struct local_vmid *settings)
+{
+       int ret;
+
+       ret = hab_parse_dt(settings);
+
+       return ret;
+}