summaryrefslogtreecommitdiff
path: root/arch/arm/mach-imx/imx8/cpu.c
diff options
context:
space:
mode:
authorYe Li <ye.li@nxp.com>2019-01-30 22:09:23 -0800
committerYe Li <ye.li@nxp.com>2019-02-11 00:07:23 -0800
commit4358b4cdfc4752822066d480dd1c10086c211be7 (patch)
tree5dc931c4cb1ea18cab2a9c22f9af41ef218e80a7 /arch/arm/mach-imx/imx8/cpu.c
parentb19418270a3d532eacb1069606fa2ab100e04601 (diff)
MLK-20886-5 imx8qm/qxp: Implement VService function and buffer pagetable
Override the board_imx_vservice_find_mu for finding MU device for virtual devices. The matching logic is if the M4_0 partition ownes the resource of the device, we select MU8 for this Vservice channel. Otherwise, if the M4_1 partition ownes the resource, we select MU9. We reuse the kernel RPMSG Vring buffer for VService buffer, because it is shared between OS partition and M4 partition. The pagetable is needed for this region, since it is not in memregs of OS partition. board_imx_vservice_get_buffer is also overriden is this patch to divide VService buffer for MU8 and MU9. Signed-off-by: Ye Li <ye.li@nxp.com>
Diffstat (limited to 'arch/arm/mach-imx/imx8/cpu.c')
-rw-r--r--arch/arm/mach-imx/imx8/cpu.c107
1 files changed, 106 insertions, 1 deletions
diff --git a/arch/arm/mach-imx/imx8/cpu.c b/arch/arm/mach-imx/imx8/cpu.c
index a1ffa8043b..64f4d900c1 100644
--- a/arch/arm/mach-imx/imx8/cpu.c
+++ b/arch/arm/mach-imx/imx8/cpu.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2017 NXP
+ * Copyright 2017-2019 NXP
*
* SPDX-License-Identifier: GPL-2.0+
*
@@ -28,6 +28,7 @@
#include <generated/version_autogenerated.h>
#include <asm/setup.h>
#include <asm/arch/lpcg.h>
+#include <asm/mach-imx/imx_vservice.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -1697,6 +1698,16 @@ void enable_caches(void)
PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN;
i = 1;
+
+#ifdef CONFIG_IMX_VSERVICE_SHARED_BUFFER
+ imx8_mem_map[i].virt = CONFIG_IMX_VSERVICE_SHARED_BUFFER;
+ imx8_mem_map[i].phys = CONFIG_IMX_VSERVICE_SHARED_BUFFER;
+ imx8_mem_map[i].size = CONFIG_IMX_VSERVICE_SHARED_BUFFER_SIZE;
+ imx8_mem_map[i].attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN;
+ i++;
+#endif
+
for (mr = 0; mr < 64 && i < MAX_MEM_MAP_REGIONS; mr++) {
err = get_owned_memreg(mr, &start, &end);
if (!err) {
@@ -1806,3 +1817,97 @@ void disconnect_from_pc(void)
return;
}
}
+
+#ifdef CONFIG_IMX_VSERVICE
+struct udevice * board_imx_vservice_find_mu(struct udevice *dev)
+{
+ int ret;
+ const char *m4_mu_name[2] = {
+ "mu@5d230000",
+ "mu@5d240000"
+ };
+ struct udevice *m4_mu[2];
+ sc_rm_pt_t m4_parts[2];
+ sc_ipc_t ipc;
+ sc_err_t err;
+ struct ofnode_phandle_args args;
+ sc_rsrc_t resource_id;
+ sc_rm_pt_t resource_part;
+
+ ipc = gd->arch.ipc_channel_handle;
+
+ /* Get the resource id from its power-domain */
+ ret = dev_read_phandle_with_args(dev, "power-domains",
+ "#power-domain-cells", 0, 0, &args);
+ if (ret) {
+ printf("Can't find the power-domains property for udev %s\n", dev->name);
+ return NULL;
+ }
+
+ /* Get the owner partition for resource*/
+ resource_id = (sc_rsrc_t)ofnode_read_u32_default(args.node, "reg", SC_R_LAST);
+ if (resource_id == SC_R_LAST) {
+ printf("Can't find the resource id for udev %s\n", dev->name);
+ return NULL;
+ }
+
+ err = sc_rm_get_resource_owner(ipc, resource_id, &resource_part);
+ if (err != SC_ERR_NONE) {
+ printf("%s get resource [%d] owner error: %d\n", __func__, resource_id, err);
+ return NULL;
+ }
+
+ debug("udev %s, resource id %d, resource part %d\n", dev->name, resource_id, resource_part);
+
+ /* MU8 for communication between M4_0 and u-boot, MU9 for M4_1 and u-boot */
+ err = sc_rm_get_resource_owner(ipc, SC_R_M4_0_PID0, &m4_parts[0]);
+ if (err != SC_ERR_NONE) {
+ printf("%s get resource [%d] owner error: %d\n", __func__, SC_R_M4_0_PID0, err);
+ return NULL;
+ }
+
+ ret = uclass_find_device_by_name(UCLASS_MISC, m4_mu_name[0], &m4_mu[0]);
+ if (!ret) {
+ /* If the i2c is in m4_0 partition, return the mu8 */
+ if (resource_part == m4_parts[0])
+ return m4_mu[0];
+ }
+
+ if (is_imx8qm()) {
+ err = sc_rm_get_resource_owner(ipc, SC_R_M4_1_PID0, &m4_parts[1]);
+ if (err != SC_ERR_NONE) {
+ printf("%s get resource [%d] owner error: %d\n", __func__, SC_R_M4_1_PID0, err);
+ return NULL;
+ }
+
+ ret = uclass_find_device_by_name(UCLASS_MISC, m4_mu_name[1], &m4_mu[1]);
+ if (!ret) {
+ /* If the i2c is in m4_1 partition, return the mu9 */
+ if (resource_part == m4_parts[1])
+ return m4_mu[1];
+ }
+ }
+
+ return NULL;
+}
+
+void * board_imx_vservice_get_buffer(struct imx_vservice_channel *node, u32 size)
+{
+ const char *m4_mu_name[2] = {
+ "mu@5d230000",
+ "mu@5d240000"
+ };
+
+ /* Each MU ownes 1M buffer */
+ if (size <= 0x100000) {
+ if (!strcmp(node->mu_dev->name, m4_mu_name[0]))
+ return (void * )CONFIG_IMX_VSERVICE_SHARED_BUFFER;
+ else if (!strcmp(node->mu_dev->name, m4_mu_name[1]))
+ return (void * )(CONFIG_IMX_VSERVICE_SHARED_BUFFER + 0x100000);
+ else
+ return NULL;
+ }
+
+ return NULL;
+}
+#endif