From d062c8ead0a53e0dad16cf731263d5fa780edab4 Mon Sep 17 00:00:00 2001 From: Yong Ding Date: Thu, 11 Jan 2018 17:51:45 +0800 Subject: [PATCH] soc: qcom: hab: add dts parsing into hab driver HAB driver can parse its relevant entries from device tree, and get necessary info, like its local vmid, physical channel groups, and etc. Change-Id: Iab0501a442bd3c89dd4b348570108dbe5ab0adca Signed-off-by: Yong Ding --- .../devicetree/bindings/soc/qcom/hab.txt | 41 ++++++++ drivers/soc/qcom/hab/hab.c | 9 +- drivers/soc/qcom/hab/hab_parser.c | 98 ++++++++++++++++++- 3 files changed, 144 insertions(+), 4 deletions(-) create mode 100644 Documentation/devicetree/bindings/soc/qcom/hab.txt diff --git a/Documentation/devicetree/bindings/soc/qcom/hab.txt b/Documentation/devicetree/bindings/soc/qcom/hab.txt new file mode 100644 index 000000000000..32f79e7ff498 --- /dev/null +++ b/Documentation/devicetree/bindings/soc/qcom/hab.txt @@ -0,0 +1,41 @@ +* HAB + +HAB(Hypervisor ABstraction) is meant to be a cross-platform abstraction layer +for utilizing the underlying hypervisor system. This API can be accessed from +both user and kernel sides. +The intended users of this are primarily the multimedia drivers who want to +communicate with the host OS to use the multimedia hardware. + +Required properties: +- compatible: Must be "qcom,hab" +- vmid: the local VM's ID + It should be unique in a system, and host's ID should be 0. Here is an + example for a system as qvm host + agl gvm + android gvm, and such below + setting is proper, + qvm host's vmid: 0 + agl gvm's vmid: 1 + android gvm's vmid: 2 +- mmid group properties: + - grp-start-id: mmid group starting ID, eg, 100 is for MM_AUD_1~4 + - role: the local role of this group, and must be "fe" or "be" + - remote-vmids: When the local role is "fe", this is to tell which VM is the + relevant BE. When it is "be", this is to tell which VMs it will support as + BE. + +Example: + qcom,hab { + compatible = "qcom,hab"; + vmid = <2>; + + mmid100: mmid-grp@100 { + grp-start-id = <100>; + role = "fe"; + remote-vmids = <0>; + }; + + mmid200: mmid-grp@200 { + grp-start-id = <200>; + role = "fe"; + remote-vmids = <0>; + }; + } diff --git a/drivers/soc/qcom/hab/hab.c b/drivers/soc/qcom/hab/hab.c index 040730d63a83..a48636dc9dbe 100644 --- a/drivers/soc/qcom/hab/hab.c +++ b/drivers/soc/qcom/hab/hab.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-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 @@ -687,9 +687,12 @@ int do_hab_parse(void) memset(&hab_driver.settings, HABCFG_VMID_INVALID, sizeof(hab_driver.settings)); - pr_debug("prepare default gvm 2 settings...\n"); - fill_default_gvm_settings(&hab_driver.settings, 2, + result = hab_parse(&hab_driver.settings); + if (result) { + pr_warn("hab_parse failed and use the default settings\n"); + fill_default_gvm_settings(&hab_driver.settings, 2, MM_AUD_START, MM_ID_MAX); + } /* now generate hab pchan list */ result = hab_generate_pchan_list(&hab_driver.settings); diff --git a/drivers/soc/qcom/hab/hab_parser.c b/drivers/soc/qcom/hab/hab_parser.c index a38d9bcf26b9..da0a4a3830a7 100644 --- a/drivers/soc/qcom/hab/hab_parser.c +++ b/drivers/soc/qcom/hab/hab_parser.c @@ -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 /* * 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; +}