From 390498d3e1d09dbb5142f2de1eae3a17ba4b16ed Mon Sep 17 00:00:00 2001 From: luozhiheng Date: Tue, 11 Mar 2025 06:26:19 +0000 Subject: [PATCH 01/14] fix phytium_defconfig for AMD --- arch/arm64/configs/phytium_defconfig | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/arm64/configs/phytium_defconfig b/arch/arm64/configs/phytium_defconfig index 3cb88a2efeb..2f9d6d2b603 100644 --- a/arch/arm64/configs/phytium_defconfig +++ b/arch/arm64/configs/phytium_defconfig @@ -546,6 +546,12 @@ CONFIG_DRM_I2C_NXP_TDA998X=m CONFIG_DRM_HDLCD=m CONFIG_DRM_MALI_DISPLAY=m CONFIG_DRM_KOMEDA=m +CONFIG_DRM_RADEON=m +CONFIG_DRM_RADEON_USERPTR=y +CONFIG_DRM_AMDGPU=m +CONFIG_DRM_AMDGPU_SI=y +CONFIG_DRM_AMDGPU_CIK=y +CONFIG_HSA_AMD=y CONFIG_DRM_NOUVEAU=m CONFIG_DRM_PANEL_BOE_TV101WUM_NL6=m CONFIG_DRM_PANEL_LVDS=m -- Gitee From 09ded792f364f063b235ba912b991c78db20132b Mon Sep 17 00:00:00 2001 From: Huangjie Date: Mon, 3 Mar 2025 17:27:46 +0800 Subject: [PATCH 02/14] PCI: ep: use of_device_get_match_data() to get deivce data Signed-off-by: Huangjie --- drivers/pci/controller/pcie-phytium-ep.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/pci/controller/pcie-phytium-ep.c b/drivers/pci/controller/pcie-phytium-ep.c index 2f75ee1d2ae..fc96b44d92c 100644 --- a/drivers/pci/controller/pcie-phytium-ep.c +++ b/drivers/pci/controller/pcie-phytium-ep.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -371,10 +372,8 @@ static const struct of_device_id phytium_pcie_ep_of_match[] = { static int phytium_pcie_ep_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; - const struct of_device_id *match = NULL; struct phytium_pcie_ep *priv = NULL; - const struct phytium_pcie_ep_config *pcie_ep_config = - &pcie_ep_2p0_config; + const struct phytium_pcie_ep_config *pcie_ep_config = NULL; struct resource *res; struct device_node *np = dev->of_node; struct pci_epc *epc; @@ -384,10 +383,10 @@ static int phytium_pcie_ep_probe(struct platform_device *pdev) if (!priv) return -ENOMEM; - match = of_match_node(phytium_pcie_ep_of_match, pdev->dev.of_node); - if (match && match->data) { - pcie_ep_config = match->data; - } + pcie_ep_config = of_device_get_match_data(&pdev->dev); + if (!pcie_ep_config) + return -ENODEV; + priv->hpb_perf_base_limit_offs = pcie_ep_config->hpb_perf_base_limit_offs; -- Gitee From 30776f10caabc0a37bed30d1a0c5b79275694ed2 Mon Sep 17 00:00:00 2001 From: huyuming1672 Date: Wed, 24 Apr 2024 14:35:04 +0800 Subject: [PATCH 03/14] driver: remoteproc: improve stop function. The stop function is divided into the following steps: 1. use reserved[0] in resource table as stop flag, and set this flag when the stop function is called; 2. send ipi to remote processor, and wait for the remote processor to shut down the CPU; 3. clear the stop flag. Signed-off-by: huyuming1672 --- drivers/remoteproc/homo_remoteproc.c | 59 ++++++++++++++++++++++++++-- 1 file changed, 55 insertions(+), 4 deletions(-) diff --git a/drivers/remoteproc/homo_remoteproc.c b/drivers/remoteproc/homo_remoteproc.c index ea03bfae81b..7b9e15488c4 100644 --- a/drivers/remoteproc/homo_remoteproc.c +++ b/drivers/remoteproc/homo_remoteproc.c @@ -18,6 +18,9 @@ #include #include #include +#include +#include +#include #include "remoteproc_internal.h" @@ -30,10 +33,16 @@ #define AFFINITY_INFO 0xc4000004 #define MIGRATE 0xc4000005 +#define REMOTE_PROC_STOP 0x0001U + +/* wait for 1s */ +#define HOMO_MAX_WAIT_TIME_NS (1000 * NSEC_PER_MSEC) + /* Resource table for the homo remote processors */ struct homo_resource_table { unsigned int version; unsigned int num; + /* use bit0 of reserved[0] as stop flag */ unsigned int reserved[2]; unsigned int offset[RPROC_RESOURCE_ENTRIES]; @@ -63,6 +72,16 @@ static struct work_struct workqueue; #define MPIDR_TO_SGI_AFFINITY(cluster_id, level) (MPIDR_AFFINITY_LEVEL(cluster_id, level) << ICC_SGI1R_AFFINITY_## level ## _SHIFT) +static bool homo_rproc_wait_cpuoff(struct rproc *rproc, ktime_t stop) +{ + int err = 0; + struct homo_rproc *priv = rproc->priv; + + err = psci_ops.affinity_info(cpu_logical_map(priv->cpu), 0); + + return (err == 1) || ktime_after(ktime_get(), stop); +} + void gicv3_ipi_send_single(int irq, u64 mpidr) { u16 tlist = 0; @@ -86,6 +105,20 @@ void gicv3_ipi_send_single(int irq, u64 mpidr) isb(); } +static void homo_rproc_write_stop_flag(struct homo_resource_table *table_ptr) +{ + unsigned int *flag = table_ptr->reserved; + + *flag |= REMOTE_PROC_STOP; +} + +static void homo_rproc_clear_stop_flag(struct homo_resource_table *table_ptr) +{ + unsigned int *flag = table_ptr->reserved; + + *flag &= ~REMOTE_PROC_STOP; +} + static void homo_rproc_vq_irq(struct work_struct *work) { struct homo_rproc *priv = g_priv; @@ -120,12 +153,30 @@ static int homo_rproc_start(struct rproc *rproc) static int homo_rproc_stop(struct rproc *rproc) { - int err; struct homo_rproc *priv = rproc->priv; + ktime_t stop; - err = psci_ops.affinity_info(cpu_logical_map(priv->cpu), 0); - if (err == 1) - add_cpu(priv->cpu); + if (!priv || !priv->rsc) { + dev_err(&rproc->dev, "cannot find resource table!\n"); + return -1; + } + + homo_rproc_write_stop_flag(priv->rsc); + + gicv3_ipi_send_single(priv->irq, cpu_logical_map(priv->cpu)); + + stop = ktime_add_ns(ktime_get(), HOMO_MAX_WAIT_TIME_NS); + + spin_until_cond(homo_rproc_wait_cpuoff(rproc, stop)); + + if (ktime_after(ktime_get(), stop)) { + dev_err(&rproc->dev, "wait remote processor stop timeout!\n"); + return -1; + } + + add_cpu(priv->cpu); + + homo_rproc_clear_stop_flag(priv->rsc); return 0; } -- Gitee From 9898ac97f6fa7dd814ac47902cd35fd52566ac88 Mon Sep 17 00:00:00 2001 From: huyuming1672 Date: Thu, 13 Mar 2025 10:10:34 +0800 Subject: [PATCH 04/14] driver: remoteproc: delete global variable workqueue Signed-off-by: huyuming1672 --- drivers/remoteproc/homo_remoteproc.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/remoteproc/homo_remoteproc.c b/drivers/remoteproc/homo_remoteproc.c index 7b9e15488c4..5395cc37fe1 100644 --- a/drivers/remoteproc/homo_remoteproc.c +++ b/drivers/remoteproc/homo_remoteproc.c @@ -64,11 +64,11 @@ struct homo_rproc { int irq; int cpu; + struct work_struct vq_work; }; static int homo_rproc_irq; static struct homo_rproc *g_priv; -static struct work_struct workqueue; #define MPIDR_TO_SGI_AFFINITY(cluster_id, level) (MPIDR_AFFINITY_LEVEL(cluster_id, level) << ICC_SGI1R_AFFINITY_## level ## _SHIFT) @@ -119,9 +119,9 @@ static void homo_rproc_clear_stop_flag(struct homo_resource_table *table_ptr) *flag &= ~REMOTE_PROC_STOP; } -static void homo_rproc_vq_irq(struct work_struct *work) +static void homo_rproc_vq_irq(struct work_struct *vq_work) { - struct homo_rproc *priv = g_priv; + struct homo_rproc *priv = container_of(vq_work, struct homo_rproc, vq_work); struct homo_resource_table *rsc = priv->rsc; struct rproc *rproc = priv->rproc; @@ -139,7 +139,7 @@ static int homo_rproc_start(struct rproc *rproc) if (err == 0) remove_cpu(priv->cpu); - INIT_WORK(&workqueue, homo_rproc_vq_irq); + INIT_WORK(&priv->vq_work, homo_rproc_vq_irq); priv->rsc = (struct homo_resource_table *)rproc->table_ptr; @@ -238,7 +238,8 @@ static void __iomem *homo_ioremap_prot(phys_addr_t addr, size_t size, pgprot_t p static irqreturn_t homo_rproc_irq_handler(int irq, void *data) { - schedule_work(&workqueue); + struct homo_rproc *priv = g_priv; + schedule_work(&priv->vq_work); return IRQ_HANDLED; } -- Gitee From 6aed24635c4bf197764422814f07aebfd31b697d Mon Sep 17 00:00:00 2001 From: huyuming1672 Date: Thu, 13 Mar 2025 19:08:51 +0800 Subject: [PATCH 05/14] driver: remoteproc: support two remote processors. Signed-off-by: huyuming1672 --- drivers/remoteproc/homo_remoteproc.c | 183 +++++++++++++++++++++++---- 1 file changed, 159 insertions(+), 24 deletions(-) diff --git a/drivers/remoteproc/homo_remoteproc.c b/drivers/remoteproc/homo_remoteproc.c index 5395cc37fe1..4ab7ef23998 100644 --- a/drivers/remoteproc/homo_remoteproc.c +++ b/drivers/remoteproc/homo_remoteproc.c @@ -21,11 +21,14 @@ #include #include #include +#include #include "remoteproc_internal.h" #define RPROC_RESOURCE_ENTRIES 8 +#define RPROC_CORE_MAX_NUM 2 + #define PSCI_VERSION 0x84000000 #define CPU_SUSPEND 0xc4000001 #define CPU_OFF 0x84000002 @@ -65,13 +68,41 @@ struct homo_rproc { int irq; int cpu; struct work_struct vq_work; + int rproc_irq; }; -static int homo_rproc_irq; -static struct homo_rproc *g_priv; +static struct homo_rproc *g_homo_rproc[RPROC_CORE_MAX_NUM]; +static int homo_rproc_num; +static int homo_rproc_offset; #define MPIDR_TO_SGI_AFFINITY(cluster_id, level) (MPIDR_AFFINITY_LEVEL(cluster_id, level) << ICC_SGI1R_AFFINITY_## level ## _SHIFT) +static int homo_find_rproc_offset_cpu(int cpu) +{ + int i; + + for(i = 0; i < homo_rproc_num; i++) { + if (g_homo_rproc[i]->cpu == cpu) { + return i; + } + } + + return -1; +} + +static int homo_find_rproc_offset_irq(int rproc_irq) +{ + int i; + + for(i = 0; i < homo_rproc_num; i++) { + if (g_homo_rproc[i]->rproc_irq == rproc_irq) { + return i; + } + } + + return -1; +} + static bool homo_rproc_wait_cpuoff(struct rproc *rproc, ktime_t stop) { int err = 0; @@ -134,11 +165,15 @@ static int homo_rproc_start(struct rproc *rproc) struct homo_rproc *priv = rproc->priv; int phys_cpuid = cpu_logical_map(priv->cpu); struct arm_smccc_res smc_res; + int offset; err = psci_ops.affinity_info(phys_cpuid, 0); if (err == 0) remove_cpu(priv->cpu); + offset = homo_find_rproc_offset_cpu(priv->cpu); + homo_rproc_offset = offset; + INIT_WORK(&priv->vq_work, homo_rproc_vq_irq); priv->rsc = (struct homo_resource_table *)rproc->table_ptr; @@ -238,35 +273,59 @@ static void __iomem *homo_ioremap_prot(phys_addr_t addr, size_t size, pgprot_t p static irqreturn_t homo_rproc_irq_handler(int irq, void *data) { - struct homo_rproc *priv = g_priv; + int offset; + struct homo_rproc *priv; + + offset = homo_find_rproc_offset_irq(irq); + priv = g_homo_rproc[offset]; + schedule_work(&priv->vq_work); return IRQ_HANDLED; } static int homo_rproc_starting_cpu(unsigned int cpu) { - enable_percpu_irq(homo_rproc_irq, irq_get_trigger_type(homo_rproc_irq)); + int i; + int irq; + + for(i = 0; i < homo_rproc_num; i++) { + irq = g_homo_rproc[i]->rproc_irq; + enable_percpu_irq(irq, irq_get_trigger_type(irq)); + } + return 0; } static int homo_rproc_dying_cpu(unsigned int cpu) { - disable_percpu_irq(homo_rproc_irq); + int i; + int irq; + + for(i = 0; i < homo_rproc_num; i++) { + irq = g_homo_rproc[i]->rproc_irq; + disable_percpu_irq(irq); + } + return 0; } -static int homo_rproc_probe(struct platform_device *pdev) + +static int homo_core_of_init(struct platform_device *pdev) { struct device *dev = &pdev->dev; - struct device_node *np = dev->of_node, *p; + struct device_node *np = dev_of_node(dev), *p; struct device_node *np_mem; struct resource res; - struct rproc *rproc; - const char *fw_name; struct homo_rproc *priv; - int ret; unsigned int ipi, cpu; + int ret; struct of_phandle_args oirq; + int rproc_irq; + struct rproc *rproc; + const char *fw_name; + + if (!devres_open_group(dev, homo_core_of_init, GFP_KERNEL)) + return -ENOMEM; ret = rproc_of_parse_firmware(dev, 0, &fw_name); if (ret) { @@ -283,7 +342,7 @@ static int homo_rproc_probe(struct platform_device *pdev) platform_set_drvdata(pdev, rproc); - priv = g_priv = rproc->priv; + priv = g_homo_rproc[homo_rproc_num] = rproc->priv; priv->rproc = rproc; /* The following values can be modified through devicetree 'homo_rproc' node */ @@ -334,43 +393,119 @@ static int homo_rproc_probe(struct platform_device *pdev) p = of_irq_find_parent(np); if (p == NULL) { ret = -EINVAL; - goto err; + goto err_free; } oirq.np = p; oirq.args_count = 1; oirq.args[0] = ipi; - homo_rproc_irq = irq_create_of_mapping(&oirq); - if (homo_rproc_irq <= 0) { + rproc_irq = irq_create_of_mapping(&oirq); + if (rproc_irq <= 0) { ret = -EINVAL; goto err; } - ret = request_percpu_irq(homo_rproc_irq, homo_rproc_irq_handler, "homo-rproc-ipi", &cpu_number); - if (ret) { - dev_err(dev, "failed to request percpu irq, status = %d\n", ret); - goto err; - } + priv->rproc_irq = rproc_irq; - ret = cpuhp_setup_state(CPUHP_AP_HOMO_RPROC_STARTING, "remoteproc/homo_rproc:starting", homo_rproc_starting_cpu, homo_rproc_dying_cpu); + ret = request_percpu_irq(rproc_irq, homo_rproc_irq_handler, "homo-rproc-ipi", &cpu_number); if (ret) { - dev_err(dev, "cpuhp setup state failed, status = %d\n", ret); - goto err; + dev_err(dev, "failed to request percpu irq, status = %d\n", ret); + goto err_free; } ret = rproc_add(rproc); if (ret) { dev_err(dev, "failed to add register device with remoteproc core, status = %d\n", ret); - goto err; + goto err_free; } + devres_close_group(dev, homo_core_of_init); + return 0; -err: +err_free: vunmap((void *)((unsigned long)priv->addr & PAGE_MASK)); + +err: + devres_release_group(dev, homo_core_of_init); + return ret; +} + +static int homo_cluster_of_init(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *np = dev_of_node(dev); + struct platform_device *cpdev; + struct device_node *child; + int ret; + + for_each_available_child_of_node(np, child) { + const char *node_name = child->name; + cpdev = of_find_device_by_node(child); + if (!cpdev) { + ret = -ENODEV; + dev_err(dev, "could not get core platform device for node %s\n", node_name); + of_node_put(child); + goto fail; + } + + ret = homo_core_of_init(cpdev); + if (ret) { + dev_err(dev, "homo_core_of_init failed, ret = %d\n", + ret); + put_device(&cpdev->dev); + of_node_put(child); + goto fail; + } + + homo_rproc_num++; + put_device(&cpdev->dev); + } + + return 0; + +fail: return ret; } +static int homo_rproc_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + int ret; + int num_cores; + + num_cores = of_get_available_child_count(np); + + dev_info(dev, "num_cores = %d\n", num_cores); + + if (num_cores > RPROC_CORE_MAX_NUM) { + dev_err(dev, "core number (%d) out of range\n", num_cores); + return -ENODEV; + } + + ret = devm_of_platform_populate(dev); + if (ret) { + dev_err(dev, "devm_of_platform_populate failed, ret = %d\n", + ret); + return ret; + } + + ret = homo_cluster_of_init(pdev); + if (ret) { + dev_err(dev, "homo_cluster_of_init failed, ret = %d\n", ret); + return ret; + } + + ret = cpuhp_setup_state(CPUHP_AP_HOMO_RPROC_STARTING, "remoteproc/homo_rproc:starting", homo_rproc_starting_cpu, homo_rproc_dying_cpu); + if (ret) { + dev_err(dev, "cpuhp setup state failed, status = %d\n", ret); + return ret; + } + + return 0; +} + static int homo_rproc_remove(struct platform_device *pdev) { struct rproc *rproc = platform_get_drvdata(pdev); -- Gitee From 1c1cba44da6903f17c05c5bee286109d4e3b3a19 Mon Sep 17 00:00:00 2001 From: huyuming1672 Date: Tue, 18 Mar 2025 18:56:16 +0800 Subject: [PATCH 06/14] driver: remoteproc: add exit functions to be used when initialization fails. Signed-off-by: huyuming1672 --- drivers/remoteproc/homo_remoteproc.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/drivers/remoteproc/homo_remoteproc.c b/drivers/remoteproc/homo_remoteproc.c index 4ab7ef23998..9f5b6be9672 100644 --- a/drivers/remoteproc/homo_remoteproc.c +++ b/drivers/remoteproc/homo_remoteproc.c @@ -431,6 +431,32 @@ static int homo_core_of_init(struct platform_device *pdev) return ret; } +/* + * free the resources when init fail + */ +static void homo_core_of_exit(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + + platform_set_drvdata(pdev, NULL); + devres_release_group(dev, homo_core_of_init); +} + +static void homo_cluster_of_exit(struct platform_device *pdev) +{ + struct rproc *rproc; + struct platform_device *cpdev; + int i; + + for(i = 0; i < homo_rproc_num; i++) { + rproc = g_homo_rproc[i]->rproc; + cpdev = to_platform_device(rproc->dev.parent); + homo_core_of_exit(cpdev); + } + + homo_rproc_num = 0; +} + static int homo_cluster_of_init(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -465,6 +491,7 @@ static int homo_cluster_of_init(struct platform_device *pdev) return 0; fail: + homo_cluster_of_exit(pdev); return ret; } -- Gitee From e611f161e9d306c1d40a5cade44dc39ec634298e Mon Sep 17 00:00:00 2001 From: huyuming1672 Date: Tue, 18 Mar 2025 19:48:51 +0800 Subject: [PATCH 07/14] driver: remoteproc: add CPU checking in the interrupt handler. Only the specified CPU will execute the code, and other CPUs will return directly. Signed-off-by: huyuming1672 --- drivers/remoteproc/homo_remoteproc.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/remoteproc/homo_remoteproc.c b/drivers/remoteproc/homo_remoteproc.c index 9f5b6be9672..a039dc4530a 100644 --- a/drivers/remoteproc/homo_remoteproc.c +++ b/drivers/remoteproc/homo_remoteproc.c @@ -27,8 +27,12 @@ #define RPROC_RESOURCE_ENTRIES 8 +/* Support up to two cores */ #define RPROC_CORE_MAX_NUM 2 +/* cpu0 handling interrupt */ +#define RPROC_IRQ_HANDLE_CPU 0 + #define PSCI_VERSION 0x84000000 #define CPU_SUSPEND 0xc4000001 #define CPU_OFF 0x84000002 @@ -275,6 +279,12 @@ static irqreturn_t homo_rproc_irq_handler(int irq, void *data) { int offset; struct homo_rproc *priv; + int cpu = smp_processor_id(); + + /* Return immediately if not the designated CPU */ + if (cpu != RPROC_IRQ_HANDLE_CPU) { + return IRQ_HANDLED; + } offset = homo_find_rproc_offset_irq(irq); priv = g_homo_rproc[offset]; -- Gitee From e73248b2cd57b03c51b840e8982ddabe8eaa8400 Mon Sep 17 00:00:00 2001 From: huyuming1672 Date: Tue, 18 Mar 2025 19:52:17 +0800 Subject: [PATCH 08/14] driver: remoteproc: remove redundant code and macro definitions. Signed-off-by: huyuming1672 --- drivers/remoteproc/homo_remoteproc.c | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/drivers/remoteproc/homo_remoteproc.c b/drivers/remoteproc/homo_remoteproc.c index a039dc4530a..997a0a3cba6 100644 --- a/drivers/remoteproc/homo_remoteproc.c +++ b/drivers/remoteproc/homo_remoteproc.c @@ -33,12 +33,7 @@ /* cpu0 handling interrupt */ #define RPROC_IRQ_HANDLE_CPU 0 -#define PSCI_VERSION 0x84000000 -#define CPU_SUSPEND 0xc4000001 -#define CPU_OFF 0x84000002 #define CPU_ON 0xc4000003 -#define AFFINITY_INFO 0xc4000004 -#define MIGRATE 0xc4000005 #define REMOTE_PROC_STOP 0x0001U @@ -77,23 +72,9 @@ struct homo_rproc { static struct homo_rproc *g_homo_rproc[RPROC_CORE_MAX_NUM]; static int homo_rproc_num; -static int homo_rproc_offset; #define MPIDR_TO_SGI_AFFINITY(cluster_id, level) (MPIDR_AFFINITY_LEVEL(cluster_id, level) << ICC_SGI1R_AFFINITY_## level ## _SHIFT) -static int homo_find_rproc_offset_cpu(int cpu) -{ - int i; - - for(i = 0; i < homo_rproc_num; i++) { - if (g_homo_rproc[i]->cpu == cpu) { - return i; - } - } - - return -1; -} - static int homo_find_rproc_offset_irq(int rproc_irq) { int i; @@ -169,15 +150,11 @@ static int homo_rproc_start(struct rproc *rproc) struct homo_rproc *priv = rproc->priv; int phys_cpuid = cpu_logical_map(priv->cpu); struct arm_smccc_res smc_res; - int offset; err = psci_ops.affinity_info(phys_cpuid, 0); if (err == 0) remove_cpu(priv->cpu); - offset = homo_find_rproc_offset_cpu(priv->cpu); - homo_rproc_offset = offset; - INIT_WORK(&priv->vq_work, homo_rproc_vq_irq); priv->rsc = (struct homo_resource_table *)rproc->table_ptr; -- Gitee From f9b9e666e71d33544f6a5cdf7d5635cf42867f06 Mon Sep 17 00:00:00 2001 From: huyuming1672 Date: Wed, 19 Mar 2025 09:39:08 +0800 Subject: [PATCH 09/14] driver: remoteproc: rename the struct variable to indicate it is a mapped interrupt Signed-off-by: huyuming1672 --- drivers/remoteproc/homo_remoteproc.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/remoteproc/homo_remoteproc.c b/drivers/remoteproc/homo_remoteproc.c index 997a0a3cba6..f5e284ee673 100644 --- a/drivers/remoteproc/homo_remoteproc.c +++ b/drivers/remoteproc/homo_remoteproc.c @@ -67,7 +67,7 @@ struct homo_rproc { int irq; int cpu; struct work_struct vq_work; - int rproc_irq; + int mapped_irq; }; static struct homo_rproc *g_homo_rproc[RPROC_CORE_MAX_NUM]; @@ -80,7 +80,7 @@ static int homo_find_rproc_offset_irq(int rproc_irq) int i; for(i = 0; i < homo_rproc_num; i++) { - if (g_homo_rproc[i]->rproc_irq == rproc_irq) { + if (g_homo_rproc[i]->mapped_irq == rproc_irq) { return i; } } @@ -276,7 +276,7 @@ static int homo_rproc_starting_cpu(unsigned int cpu) int irq; for(i = 0; i < homo_rproc_num; i++) { - irq = g_homo_rproc[i]->rproc_irq; + irq = g_homo_rproc[i]->mapped_irq; enable_percpu_irq(irq, irq_get_trigger_type(irq)); } @@ -289,7 +289,7 @@ static int homo_rproc_dying_cpu(unsigned int cpu) int irq; for(i = 0; i < homo_rproc_num; i++) { - irq = g_homo_rproc[i]->rproc_irq; + irq = g_homo_rproc[i]->mapped_irq; disable_percpu_irq(irq); } @@ -392,7 +392,7 @@ static int homo_core_of_init(struct platform_device *pdev) goto err; } - priv->rproc_irq = rproc_irq; + priv->mapped_irq = rproc_irq; ret = request_percpu_irq(rproc_irq, homo_rproc_irq_handler, "homo-rproc-ipi", &cpu_number); if (ret) { -- Gitee From 02d2d004c89fd93a83dcbac879c9ff9f15dee557 Mon Sep 17 00:00:00 2001 From: huyuming1672 Date: Wed, 19 Mar 2025 09:40:16 +0800 Subject: [PATCH 10/14] remoteproc: dt-bindings: add child node descriptions to support up to two remote processors Signed-off-by: huyuming1672 --- .../bindings/remoteproc/homo-rproc.txt | 34 ++++++++++++++----- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/Documentation/devicetree/bindings/remoteproc/homo-rproc.txt b/Documentation/devicetree/bindings/remoteproc/homo-rproc.txt index 00f4c4402ec..3b05c33c331 100644 --- a/Documentation/devicetree/bindings/remoteproc/homo-rproc.txt +++ b/Documentation/devicetree/bindings/remoteproc/homo-rproc.txt @@ -7,13 +7,15 @@ Homogeneous RemoteProc Device Node: ================================= A homo_remoteproc device node is used to represent the remote core instance within SoC. +The parent node defines up to two child nodes, each representing a remote processor. + Required properties: -------------------- - - compatible : should be "homo,rproc" + - compatible : the parent node should be "homo,rproc", and the child node can be "homo,rproc-core" - remote-processor: remote processor's linux cpu logical number - - inter-processor-interrupt: IPI/SGI interrupt number, default is 9 + - inter-processor-interrupt: IPI/SGI interrupt number - memory-region: reserved memory which will be used by remote processor - - firmware-name: the name of openamp image, default is "openamp_core0.elf" + - firmware-name: the name of openamp image Example: -------- @@ -22,18 +24,32 @@ Example: #address-cells = <0x2>; #size-cells = <0x2>; ranges; - - rproc: rproc@b0100000 { + rproc0: rproc0@b0100000 { no-map; reg = <0x0 0xb0100000 0x0 0x19900000>; }; + rproc1: rpro1c@d0100000 { + no-map; + reg = <0x0 0xd0100000 0x0 0x19900000>; + }; }; homo_rproc: homo_rproc@0 { compatible = "homo,rproc"; - remote-processor = <3>; - inter-processor-interrupt = <9>; - memory-region = <&rproc>; - firmware-name = "openamp_core0.elf"; status = "disabled"; + homo_core0: homo_core0@b0100000 { + compatible = "homo,rproc-core"; + remote-processor = <3>; + inter-processor-interrupt = <9>; + memory-region = <&rproc0>; + firmware-name = "openamp_core0.elf"; + }; + homo_core1: homo_core1@d0100000 { + compatible = "homo,rproc-core"; + remote-processor = <2>; + inter-processor-interrupt = <10>; + memory-region = <&rproc1>; + firmware-name = "openamp_core1.elf"; + }; }; + -- Gitee From 85536c920df0e594a9cdfdc42f13a7066f84da44 Mon Sep 17 00:00:00 2001 From: huyuming1672 Date: Wed, 19 Mar 2025 09:56:51 +0800 Subject: [PATCH 11/14] driver: remoteproc: further refine the exception exit When an error occurs during code execution and rproc_alloc has already been executed or when the driver is removed, call functions rproc_del and rproc_free. Signed-off-by: huyuming1672 --- drivers/remoteproc/homo_remoteproc.c | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/drivers/remoteproc/homo_remoteproc.c b/drivers/remoteproc/homo_remoteproc.c index f5e284ee673..f9b5db7c414 100644 --- a/drivers/remoteproc/homo_remoteproc.c +++ b/drivers/remoteproc/homo_remoteproc.c @@ -335,12 +335,14 @@ static int homo_core_of_init(struct platform_device *pdev) /* The following values can be modified through devicetree 'homo_rproc' node */ if (of_property_read_u32(np, "remote-processor", &cpu)) { dev_err(dev, "not found 'remote-processor' property\n"); - return -EINVAL; + ret = -EINVAL; + goto err_add; } if (of_property_read_u32(np, "inter-processor-interrupt", &ipi)) { dev_err(dev, "not found 'inter-processor-interrupt' property\n"); - return -EINVAL; + ret = -EINVAL; + goto err_add; } /* The gic-v3 driver has registered the 0-7 range of SGI interrupt for system purpose */ @@ -358,7 +360,7 @@ static int homo_core_of_init(struct platform_device *pdev) ret = of_address_to_resource(np_mem, 0, &res); if (ret) { dev_err(dev, "can't find memory-region for Baremetal\n"); - return ret; + goto err_add; } priv->rsc = NULL; @@ -371,7 +373,8 @@ static int homo_core_of_init(struct platform_device *pdev) priv->addr = homo_ioremap_prot(priv->phys_addr, priv->size, PAGE_KERNEL_EXEC); if (!priv->addr) { dev_err(dev, "ioremap failed\n"); - return -ENOMEM; + ret = -ENOMEM; + goto err_add; } dev_info(dev, "ioremap: phys_addr = %016llx, addr = %llx, size = %lld\n", priv->phys_addr, (u64)(priv->addr), priv->size); @@ -413,6 +416,10 @@ static int homo_core_of_init(struct platform_device *pdev) err_free: vunmap((void *)((unsigned long)priv->addr & PAGE_MASK)); +err_add: + rproc_del(rproc); + rproc_free(rproc); + err: devres_release_group(dev, homo_core_of_init); return ret; @@ -424,12 +431,16 @@ static int homo_core_of_init(struct platform_device *pdev) static void homo_core_of_exit(struct platform_device *pdev) { struct device *dev = &pdev->dev; + struct rproc *rproc = platform_get_drvdata(pdev); + + rproc_del(rproc); + rproc_free(rproc); platform_set_drvdata(pdev, NULL); devres_release_group(dev, homo_core_of_init); } -static void homo_cluster_of_exit(struct platform_device *pdev) +static void homo_cluster_of_exit(void) { struct rproc *rproc; struct platform_device *cpdev; @@ -478,7 +489,7 @@ static int homo_cluster_of_init(struct platform_device *pdev) return 0; fail: - homo_cluster_of_exit(pdev); + homo_cluster_of_exit(); return ret; } @@ -522,10 +533,7 @@ static int homo_rproc_probe(struct platform_device *pdev) static int homo_rproc_remove(struct platform_device *pdev) { - struct rproc *rproc = platform_get_drvdata(pdev); - - rproc_del(rproc); - rproc_free(rproc); + homo_cluster_of_exit(); return 0; } -- Gitee From 9a5f94767a473cdeabfabedfa631b505c3aec141 Mon Sep 17 00:00:00 2001 From: huyuming1672 Date: Wed, 19 Mar 2025 10:15:29 +0800 Subject: [PATCH 12/14] driver: remoteproc: add explanatory comments and optimize the code Signed-off-by: huyuming1672 --- drivers/remoteproc/homo_remoteproc.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/drivers/remoteproc/homo_remoteproc.c b/drivers/remoteproc/homo_remoteproc.c index f9b5db7c414..b2eff8067de 100644 --- a/drivers/remoteproc/homo_remoteproc.c +++ b/drivers/remoteproc/homo_remoteproc.c @@ -33,8 +33,10 @@ /* cpu0 handling interrupt */ #define RPROC_IRQ_HANDLE_CPU 0 +/* PSCI cpu_on code */ #define CPU_ON 0xc4000003 +/* stop flag use in resource table */ #define REMOTE_PROC_STOP 0x0001U /* wait for 1s */ @@ -79,7 +81,7 @@ static int homo_find_rproc_offset_irq(int rproc_irq) { int i; - for(i = 0; i < homo_rproc_num; i++) { + for (i = 0; i < homo_rproc_num; i++) { if (g_homo_rproc[i]->mapped_irq == rproc_irq) { return i; } @@ -275,7 +277,7 @@ static int homo_rproc_starting_cpu(unsigned int cpu) int i; int irq; - for(i = 0; i < homo_rproc_num; i++) { + for (i = 0; i < homo_rproc_num; i++) { irq = g_homo_rproc[i]->mapped_irq; enable_percpu_irq(irq, irq_get_trigger_type(irq)); } @@ -392,7 +394,7 @@ static int homo_core_of_init(struct platform_device *pdev) rproc_irq = irq_create_of_mapping(&oirq); if (rproc_irq <= 0) { ret = -EINVAL; - goto err; + goto err_free; } priv->mapped_irq = rproc_irq; @@ -420,13 +422,12 @@ static int homo_core_of_init(struct platform_device *pdev) rproc_del(rproc); rproc_free(rproc); -err: devres_release_group(dev, homo_core_of_init); return ret; } /* - * free the resources when init fail + * release each remote processor */ static void homo_core_of_exit(struct platform_device *pdev) { @@ -440,13 +441,16 @@ static void homo_core_of_exit(struct platform_device *pdev) devres_release_group(dev, homo_core_of_init); } +/* + * free the resources when init fail or driver remove + */ static void homo_cluster_of_exit(void) { struct rproc *rproc; struct platform_device *cpdev; int i; - for(i = 0; i < homo_rproc_num; i++) { + for (i = 0; i < homo_rproc_num; i++) { rproc = g_homo_rproc[i]->rproc; cpdev = to_platform_device(rproc->dev.parent); homo_core_of_exit(cpdev); @@ -455,6 +459,9 @@ static void homo_cluster_of_exit(void) homo_rproc_num = 0; } +/* + * Create remote processors by identifying the child nodes of homo_rproc in the dts + */ static int homo_cluster_of_init(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -475,8 +482,7 @@ static int homo_cluster_of_init(struct platform_device *pdev) ret = homo_core_of_init(cpdev); if (ret) { - dev_err(dev, "homo_core_of_init failed, ret = %d\n", - ret); + dev_err(dev, "homo_core_of_init failed, ret = %d\n", ret); put_device(&cpdev->dev); of_node_put(child); goto fail; @@ -502,8 +508,6 @@ static int homo_rproc_probe(struct platform_device *pdev) num_cores = of_get_available_child_count(np); - dev_info(dev, "num_cores = %d\n", num_cores); - if (num_cores > RPROC_CORE_MAX_NUM) { dev_err(dev, "core number (%d) out of range\n", num_cores); return -ENODEV; -- Gitee From 0ef7d9c0849fcb74d2af2aca6c8823e9237d4e90 Mon Sep 17 00:00:00 2001 From: huyuming1672 Date: Wed, 19 Mar 2025 11:03:16 +0800 Subject: [PATCH 13/14] driver: remoteproc: update adaptation and code optimization including: 1. Optimize code by segmenting the reserved memory mapping; 2. Fix bugs by correcting the improper use of 'rproc_del' and 'rproc_free'; 3. Add support for Carveout usage, incorporating the corresponding imgload, vring descriptor, and vring data buffer segments into Carveout during the prepare phase, enabling subsequent DMA allocation in the specified memory. Signed-off-by: huyuming1672 --- drivers/remoteproc/homo_remoteproc.c | 155 +++++++++++++++++++-------- 1 file changed, 110 insertions(+), 45 deletions(-) diff --git a/drivers/remoteproc/homo_remoteproc.c b/drivers/remoteproc/homo_remoteproc.c index b2eff8067de..24d0edb2a04 100644 --- a/drivers/remoteproc/homo_remoteproc.c +++ b/drivers/remoteproc/homo_remoteproc.c @@ -1,8 +1,7 @@ /* * Homogeneous Remote Processor Control Driver * - * Copyright (c) 2022-2024 Phytium Technology Co., Ltd. - * Author: Shaojun Yang + * Copyright (c) 2022-2025 Phytium Technology Co., Ltd. * * This program is free software; you can redistribute it and/or modify it under the terms * of the GNU General Public License version 2 as published by the Free Software Foundation. @@ -40,7 +39,32 @@ #define REMOTE_PROC_STOP 0x0001U /* wait for 1s */ -#define HOMO_MAX_WAIT_TIME_NS (1000 * NSEC_PER_MSEC) +#define HOMO_MAX_WAIT_TIME_NS (1000 * NSEC_PER_MSEC) + +/* offset of the carveout relative to the starting address of the memory region */ +#define HOMO_IMGLOAD_OFFSET 0 +#define HOMO_VDEV_VIRING0_OFFSET 0x10200000 +#define HOMO_VDEV_VIRING1_OFFSET 0x10210000 +#define HOMO_VDEV_BUFFER_OFFSET 0x10220000 + +/* size of each carveout */ +#define HOMO_IMGLOAD_SIZE 0x10200000 +#define HOMO_VDEV_VIRING0_SIZE 0x00008000 +#define HOMO_VDEV_VIRING1_SIZE 0x00008000 +#define HOMO_VDEV_BUFFER_SIZE 0x00080000 + +#define HOMO_ADD_CARVEOUT(dev, base, size, name_fmt) \ + do { \ + struct rproc_mem_entry *mem = rproc_mem_entry_init( \ + dev, NULL, (dma_addr_t)(base), (size), (base), \ + homo_mem_alloc, homo_mem_release, \ + name_fmt); \ + if (!mem) { \ + dev_err(dev, "rproc_mem_entry_init err!\n"); \ + return -ENOMEM; \ + } \ + rproc_add_carveout(rproc, mem); \ + } while (0) /* Resource table for the homo remote processors */ struct homo_resource_table { @@ -162,7 +186,7 @@ static int homo_rproc_start(struct rproc *rproc) priv->rsc = (struct homo_resource_table *)rproc->table_ptr; /* ARMv8 requires to clean D-cache and invalidate I-cache for memory containing new instructions. */ - flush_icache_range((unsigned long)priv->addr, (unsigned long)(priv->addr + priv->size)); + flush_icache_range((unsigned long)priv->addr, (unsigned long)(priv->addr + HOMO_IMGLOAD_SIZE)); arm_smccc_smc(CPU_ON, phys_cpuid, (unsigned long long)priv->phys_addr, 0, 0, 0, 0, 0, &smc_res); @@ -214,16 +238,9 @@ static void homo_rproc_kick(struct rproc *rproc, int vqid) if (rproc->state == RPROC_RUNNING) gicv3_ipi_send_single(priv->irq, cpu_logical_map(priv->cpu)); - return ; + return; } -static const struct rproc_ops homo_rproc_ops = { - .start = homo_rproc_start, - .stop = homo_rproc_stop, - .kick = homo_rproc_kick, - .da_to_va = homo_rproc_da_to_va, -}; - static void __iomem *homo_ioremap_prot(phys_addr_t addr, size_t size, pgprot_t prot) { unsigned long offset, vaddr; @@ -290,7 +307,7 @@ static int homo_rproc_dying_cpu(unsigned int cpu) int i; int irq; - for(i = 0; i < homo_rproc_num; i++) { + for (i = 0; i < homo_rproc_num; i++) { irq = g_homo_rproc[i]->mapped_irq; disable_percpu_irq(irq); } @@ -298,13 +315,84 @@ static int homo_rproc_dying_cpu(unsigned int cpu) return 0; } +static int homo_mem_alloc(struct rproc *rproc, struct rproc_mem_entry *mem) +{ + struct device *dev = rproc->dev.parent; + void *va; + struct homo_rproc *priv = rproc->priv; + char load_name[32]; + + va = homo_ioremap_prot(mem->dma, mem->len, PAGE_KERNEL_EXEC); + if (!va) { + dev_err(dev, "Unable to map memory region: %pa+%zx\n", + &mem->dma, mem->len); + return -ENOMEM; + } + + snprintf(load_name, sizeof(load_name), "imgload"); + if (!strcmp(mem->name, load_name)) { + priv->addr = va; + priv->phys_addr = mem->dma; + } + + dev_dbg(dev, "name: %s, ioremap: phys_addr = %016llx, addr = %llx, size = %lx\n", + mem->name, mem->dma, (u64)va, mem->len); + + /* Update memory entry va */ + mem->va = va; + + return 0; +} + +static int homo_mem_release(struct rproc *rproc, struct rproc_mem_entry *mem) +{ + vunmap(mem->va); + + return 0; +} + +static int homo_rproc_prepare(struct rproc *rproc) +{ + struct device *dev = rproc->dev.parent; + struct device_node *np = dev->of_node; + + struct device_node *np_mem; + struct resource res; + int ret; + struct homo_rproc *priv = rproc->priv; + + np_mem = of_parse_phandle(np, "memory-region", 0); + ret = of_address_to_resource(np_mem, 0, &res); + if (ret) { + dev_err(dev, "can't find memory-region for Baremetal\n"); + return -ENOMEM; + } + + priv->rsc = NULL; + + priv->phys_addr = res.start; + priv->size = resource_size(&res); + + HOMO_ADD_CARVEOUT(dev, priv->phys_addr + HOMO_IMGLOAD_OFFSET, HOMO_IMGLOAD_SIZE, "imgload"); + HOMO_ADD_CARVEOUT(dev, priv->phys_addr + HOMO_VDEV_VIRING0_OFFSET, HOMO_VDEV_VIRING0_SIZE, "vdev0vring0"); + HOMO_ADD_CARVEOUT(dev, priv->phys_addr + HOMO_VDEV_VIRING1_OFFSET, HOMO_VDEV_VIRING1_SIZE, "vdev0vring1"); + HOMO_ADD_CARVEOUT(dev, priv->phys_addr + HOMO_VDEV_BUFFER_OFFSET, HOMO_VDEV_BUFFER_SIZE, "vdev0buffer"); + + return 0; +} + +static const struct rproc_ops homo_rproc_ops = { + .prepare = homo_rproc_prepare, + .start = homo_rproc_start, + .stop = homo_rproc_stop, + .kick = homo_rproc_kick, + .da_to_va = homo_rproc_da_to_va, +}; static int homo_core_of_init(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct device_node *np = dev_of_node(dev), *p; - struct device_node *np_mem; - struct resource res; struct homo_rproc *priv; unsigned int ipi, cpu; int ret; @@ -333,24 +421,27 @@ static int homo_core_of_init(struct platform_device *pdev) priv = g_homo_rproc[homo_rproc_num] = rproc->priv; priv->rproc = rproc; + priv->rsc = NULL; + priv->addr = NULL; /* The following values can be modified through devicetree 'homo_rproc' node */ if (of_property_read_u32(np, "remote-processor", &cpu)) { dev_err(dev, "not found 'remote-processor' property\n"); ret = -EINVAL; - goto err_add; + goto err_free; } if (of_property_read_u32(np, "inter-processor-interrupt", &ipi)) { dev_err(dev, "not found 'inter-processor-interrupt' property\n"); ret = -EINVAL; - goto err_add; + goto err_free; } /* The gic-v3 driver has registered the 0-7 range of SGI interrupt for system purpose */ if (ipi < 8) { dev_err(dev, "'inter-processor-interrupt' is %d, should be between 9~15\n", ipi); - return -EINVAL; + ret = -EINVAL; + goto err_free; } priv->cpu = cpu; @@ -358,29 +449,6 @@ static int homo_core_of_init(struct platform_device *pdev) dev_info(dev, "remote-processor = %d, inter-processor-interrupt = %d\n", cpu, ipi); - np_mem = of_parse_phandle(np, "memory-region", 0); - ret = of_address_to_resource(np_mem, 0, &res); - if (ret) { - dev_err(dev, "can't find memory-region for Baremetal\n"); - goto err_add; - } - - priv->rsc = NULL; - priv->addr = NULL; - - priv->phys_addr = res.start; - priv->size = resource_size(&res); - - /* Map physical memory region reserved for homo remote processor. */ - priv->addr = homo_ioremap_prot(priv->phys_addr, priv->size, PAGE_KERNEL_EXEC); - if (!priv->addr) { - dev_err(dev, "ioremap failed\n"); - ret = -ENOMEM; - goto err_add; - } - dev_info(dev, "ioremap: phys_addr = %016llx, addr = %llx, size = %lld\n", - priv->phys_addr, (u64)(priv->addr), priv->size); - /* Look for the interrupt parent. */ p = of_irq_find_parent(np); if (p == NULL) { @@ -416,10 +484,6 @@ static int homo_core_of_init(struct platform_device *pdev) return 0; err_free: - vunmap((void *)((unsigned long)priv->addr & PAGE_MASK)); - -err_add: - rproc_del(rproc); rproc_free(rproc); devres_release_group(dev, homo_core_of_init); @@ -560,4 +624,5 @@ module_platform_driver(homo_rproc_driver); MODULE_DESCRIPTION("Homogeneous Remote Processor Control Driver"); MODULE_AUTHOR("Shaojun Yang "); +MODULE_AUTHOR("Yuming Hu "); MODULE_LICENSE("GPL v2"); -- Gitee From 4850d0096546d55b0bf9014e572598fd62523f5b Mon Sep 17 00:00:00 2001 From: liutianyu1250 Date: Thu, 20 Mar 2025 08:34:13 +0800 Subject: [PATCH 14/14] Phytium Embedded SDK v3.1 Signed-off-by: liutianyu1250 --- arch/arm64/configs/phytium_defconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/configs/phytium_defconfig b/arch/arm64/configs/phytium_defconfig index 2f9d6d2b603..9797228499f 100644 --- a/arch/arm64/configs/phytium_defconfig +++ b/arch/arm64/configs/phytium_defconfig @@ -1,4 +1,4 @@ -CONFIG_LOCALVERSION="-phytium-embedded-v3.0" +CONFIG_LOCALVERSION="-phytium-embedded-v3.1" # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y -- Gitee