From 57e0342c1fbeae18cd2f452af20edca7c9fc2a7f Mon Sep 17 00:00:00 2001 From: hongyi Date: Tue, 28 Oct 2025 14:02:38 +0800 Subject: [PATCH] Release develop 251028 --- arch/riscv/boot/dts/zhihe/a210-dev.dts | 22 +- arch/riscv/boot/dts/zhihe/a210-evb-d2d.dts | 70 +----- arch/riscv/boot/dts/zhihe/a210-soc-peri.dtsi | 2 + arch/riscv/configs/a210_evb_defconfig | 1 + drivers/firmware/zhihe/Kconfig | 4 + drivers/firmware/zhihe/Makefile | 3 +- drivers/firmware/zhihe/zhihe_aon.c | 54 +++++ drivers/firmware/zhihe/zhihe_proc_debug.c | 163 +++++++++++++ drivers/mailbox/zhihe-mailbox.c | 238 +++++++++++++++---- include/linux/zhihe_proc_debug.h | 13 + 10 files changed, 444 insertions(+), 126 deletions(-) create mode 100755 drivers/firmware/zhihe/zhihe_proc_debug.c create mode 100755 include/linux/zhihe_proc_debug.h diff --git a/arch/riscv/boot/dts/zhihe/a210-dev.dts b/arch/riscv/boot/dts/zhihe/a210-dev.dts index 90b399dee..8a2efe7c5 100755 --- a/arch/riscv/boot/dts/zhihe/a210-dev.dts +++ b/arch/riscv/boot/dts/zhihe/a210-dev.dts @@ -277,6 +277,17 @@ slew-rate = <0>; }; }; + pwm0_pins: pwm0-1 { + pwm0-pins { + pins = "GPIO0_30"; // PWM0_CH2 + function = "pwm0"; + bias-disable; + drive-strength = <13>; + input-disable; + input-schmitt-disable; + slew-rate = <0>; + }; + }; gmac1_pins: gmac1-0 { txclk-pins { pins = "GPIO1_2", /* GMAC1_TX_CLK */ @@ -438,17 +449,6 @@ slew-rate = <0>; }; }; - pwm0_pins: pwm0-1 { - pwm0-pins { - pins = "GPIO0_30"; // PWM0_CH2 - function = "pwm0"; - bias-disable; - drive-strength = <13>; - input-disable; - input-schmitt-disable; - slew-rate = <0>; - }; - }; pwm1_pins: pwm1-1 { pwm1-pins { pins = "GPIO2_12"; // PWM1_CH2 diff --git a/arch/riscv/boot/dts/zhihe/a210-evb-d2d.dts b/arch/riscv/boot/dts/zhihe/a210-evb-d2d.dts index 40d79a707..f739ee20e 100644 --- a/arch/riscv/boot/dts/zhihe/a210-evb-d2d.dts +++ b/arch/riscv/boot/dts/zhihe/a210-evb-d2d.dts @@ -19,6 +19,12 @@ numa-node-id = <0>; }; + memory@2080000000 { + device_type = "memory"; + reg = <0x20 0x80000000 0x02 0x00000000>; // 8G + numa-node-id = <1>; + }; + reserved-memory { #address-cells = <2>; #size-cells = <2>; @@ -64,70 +70,6 @@ }; }; -&reset { - control-val = <0x3 0x0 0x3 0x0>; -}; - -&c908_1 { - status = "disable"; -}; - -&c908_2 { - status = "disable"; -}; - -&c908_3 { - status = "disable"; -}; - -&c920_4 { - status = "disable"; -}; - -&c920_5 { - status = "disable"; -}; - -&c920_6 { - status = "disable"; -}; - -&c920_7 { - status = "disable"; -}; - -&c908_8 { - //status = "disable"; -}; - -&c908_9 { - status = "disable"; -}; - -&c908_10 { - status = "disable"; -}; - -&c908_11 { - status = "disable"; -}; - -&c920_12 { - status = "disable"; -}; - -&c920_13 { - status = "disable"; -}; - -&c920_14 { - status = "disable"; -}; - -&c920_15 { - status = "disable"; -}; - &uart0 { status = "disabled"; }; diff --git a/arch/riscv/boot/dts/zhihe/a210-soc-peri.dtsi b/arch/riscv/boot/dts/zhihe/a210-soc-peri.dtsi index 659efbb61..f4e48c8aa 100755 --- a/arch/riscv/boot/dts/zhihe/a210-soc-peri.dtsi +++ b/arch/riscv/boot/dts/zhihe/a210-soc-peri.dtsi @@ -1623,6 +1623,7 @@ interrupts = <336 IRQ_TYPE_LEVEL_HIGH>; icu_cpu_id = <0>; #mbox-cells = <2>; + version = <1>; status = "okay"; }; aon: aon_subsys { @@ -1630,6 +1631,7 @@ mbox-names = "aon0"; mboxes = <&mbox_920 1 0>; //parent / channel / type #mbox-cells = <2>; + version = <1>; status = "okay"; }; diff --git a/arch/riscv/configs/a210_evb_defconfig b/arch/riscv/configs/a210_evb_defconfig index 6b60f032e..68aa83be8 100755 --- a/arch/riscv/configs/a210_evb_defconfig +++ b/arch/riscv/configs/a210_evb_defconfig @@ -87,6 +87,7 @@ CONFIG_PCI=y CONFIG_PCIE_ZH=m CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y +CONFIG_ZHIHE_PROC_DEBUG=y CONFIG_MTD=y CONFIG_MTD_OF_PARTS=m CONFIG_MTD_BLOCK=y diff --git a/drivers/firmware/zhihe/Kconfig b/drivers/firmware/zhihe/Kconfig index 0ff795cfc..88ed1247c 100644 --- a/drivers/firmware/zhihe/Kconfig +++ b/drivers/firmware/zhihe/Kconfig @@ -10,3 +10,7 @@ config ZHIHE_AON This driver manages the IPC interface between host cpu liks thead and the Aon firmware running on thead riscv E902 core. +config ZHIHE_PROC_DEBUG + bool "ZHIHE debug" + help + proc_debug diff --git a/drivers/firmware/zhihe/Makefile b/drivers/firmware/zhihe/Makefile index d723fd0db..7a91433ea 100644 --- a/drivers/firmware/zhihe/Makefile +++ b/drivers/firmware/zhihe/Makefile @@ -1,2 +1,3 @@ # SPDX-License-Identifier: GPL-2.0 -obj-$(CONFIG_ZHIHE_AON) += zhihe_aon.o +obj-$(CONFIG_ZHIHE_AON) += zhihe_aon.o +obj-$(CONFIG_ZHIHE_PROC_DEBUG) += zhihe_proc_debug.o diff --git a/drivers/firmware/zhihe/zhihe_aon.c b/drivers/firmware/zhihe/zhihe_aon.c index decff02d9..a2c3a2501 100644 --- a/drivers/firmware/zhihe/zhihe_aon.c +++ b/drivers/firmware/zhihe/zhihe_aon.c @@ -16,6 +16,10 @@ #include #include #include +#include + +#define ZHIHE_AON_V1 0x0 +#define ZHIHE_AON_V2 0x1 /* wait for response for 3000ms instead of 300ms (fix me pls)*/ #define MAX_RX_TIMEOUT (msecs_to_jiffies(3000)) @@ -207,6 +211,32 @@ out: } EXPORT_SYMBOL(zhihe_aon_call_rpc); +int get_aon_log_mem(struct device *dev, phys_addr_t *mem, size_t *mem_size) +{ + struct resource r; + struct device_node *node; + int ret; + + *mem = 0; + *mem_size = 0; + + node = of_parse_phandle(dev->of_node, "log-memory-region", 0); + if (!node) { + dev_err(dev, "no memory-region specified\n"); + return -EINVAL; + } + + ret = of_address_to_resource(node, 0, &r); + if (ret) { + dev_err(dev, "memory-region get resource faild\n"); + return -EINVAL; + } + + *mem = r.start; + *mem_size = resource_size(&r); + return 0; +} + static int zhihe_aon_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -214,6 +244,7 @@ static int zhihe_aon_probe(struct platform_device *pdev) struct zhihe_aon_chan *aon_chan; struct mbox_client *cl; struct device_node *np; + char dir_name[32] = { 0x0 }; int ret; aon_ipc = devm_kzalloc(dev, sizeof(*aon_ipc), GFP_KERNEL); if (!aon_ipc) @@ -251,6 +282,28 @@ static int zhihe_aon_probe(struct platform_device *pdev) dev_err(dev, "aon_ipc:%s handle num overflow\n",aon_ipc->mbox_name); return -1; } + + ret = get_aon_log_mem(dev, &aon_chan->log_phy, &aon_chan->log_size); + if (!ret) { + aon_chan->log_mem = ioremap(aon_chan->log_phy, aon_chan->log_size); + if (IS_ERR(aon_chan->log_mem)) { + aon_chan->log_mem = NULL; + dev_err(dev, "%s:get aon log region fail\n", __func__); + return -1; + } + + sprintf(dir_name, "aon_proc"); + aon_chan->proc_dir = proc_mkdir(dir_name, NULL); + if (NULL != aon_chan->proc_dir) { + aon_chan->log_ctrl = zhihe_create_panic_log_proc( + aon_chan->log_phy, aon_chan->proc_dir, + aon_chan->log_mem, aon_chan->log_size); + } else { + dev_err(dev, "create %s fail\n", dir_name); + return ret; + } + } + zhihe_aon_ipc_handle[g_aon_ipc_handle_num] = aon_ipc; g_aon_ipc_handle_num++; return devm_of_platform_populate(dev); @@ -291,3 +344,4 @@ MODULE_AUTHOR("hongkun.xu "); MODULE_AUTHOR("xionglue.huang "); MODULE_DESCRIPTION("ZHIHE firmware protocol driver"); MODULE_LICENSE("GPL v2"); + diff --git a/drivers/firmware/zhihe/zhihe_proc_debug.c b/drivers/firmware/zhihe/zhihe_proc_debug.c new file mode 100755 index 000000000..c746c0154 --- /dev/null +++ b/drivers/firmware/zhihe/zhihe_proc_debug.c @@ -0,0 +1,163 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * sys log sys for zhihe c908 and e902 + * Copyright (C) 2021 ZHIHE Group Holding Limited. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define GET_PAGE_NUM(size, offset) \ + ((((size) + ((offset) & ~PAGE_MASK)) + PAGE_SIZE - 1) >> PAGE_SHIFT) + +struct zhihe_log_ring_buffer { + __u32 read; + __u32 write; + __u32 size; + __u32 reserved[1]; + __u8 data[0]; +}; + +struct zhihe_hw_log { + __u32 panic; + __u32 reserved[2]; + struct zhihe_log_ring_buffer rb; +}; + +struct zhihe_proc_log_ctrl { + struct zhihe_hw_log __iomem *log; + struct proc_dir_entry *log_proc_file; + phys_addr_t log_phy; +}; + +static void dump_regs(const char *fn, void *hw_arg) +{ + struct zhihe_proc_log_ctrl *log_ctrl = hw_arg; + + if (!log_ctrl->log) + return; + + pr_debug("%s: panic = 0x%08x\n", fn, + __raw_readl(&log_ctrl->log->panic)); + pr_debug("%s: read = 0x%08x, write = 0x%08x, size = 0x%08x\n", fn, + __raw_readl(&log_ctrl->log->rb.read), + __raw_readl(&log_ctrl->log->rb.write), + __raw_readl(&log_ctrl->log->rb.size)); +} + +static int log_proc_show(struct seq_file *file, void *v) +{ + struct zhihe_proc_log_ctrl *log_ctrl = file->private; + char *buf; + size_t i; + /*dcache clean and invalid*/ + ALT_CMO_OP(flush, (phys_to_virt(log_ctrl->log_phy)), + sizeof(struct zhihe_hw_log), + riscv_cbom_block_size); + + uint32_t write = __raw_readl(&log_ctrl->log->rb.write); + uint32_t read = __raw_readl(&log_ctrl->log->rb.read); + uint32_t size = __raw_readl(&log_ctrl->log->rb.size); + size_t log_size = write >= read ? write - read : size + write - read; + + seq_printf(file, "****************** device log >>>>>>>>>>>>>>>>>\n"); + dump_regs(__func__, log_ctrl); + if (!log_size) { + seq_printf(file, "****************** end device log <<<<<<<<<<<<<<<<<\n"); + return 0; + } + + int page_num = GET_PAGE_NUM(log_size, 0); + + int log_patch_1 = -1, log_patch_2 = -1; + + buf = kmalloc(PAGE_SIZE * page_num, GFP_KERNEL); + if (buf) { + if (read + log_size >= size) { + log_patch_2 = read + log_size - size + 1; + log_patch_1 = log_size - log_patch_2; + } else + log_patch_1 = log_size; + + memcpy_fromio(buf, &log_ctrl->log->rb.data[read], log_patch_1); + if (log_patch_2 > 0) + memcpy_fromio(buf, &log_ctrl->log->rb.data[0], log_patch_2); + + uint8_t last_fame_size = log_size % 64; + + for (i = 0; i < log_size - last_fame_size; i += 64) + seq_printf(file, " %*pEp", 64, buf + i); + + if (last_fame_size) + seq_printf(file, " %*pEp", last_fame_size, buf + log_size - last_fame_size); + + __raw_writel(write, &log_ctrl->log->rb.read); + kfree(buf); + /*dcahce clean*/ + ALT_CMO_OP(clean, (phys_to_virt(log_ctrl->log_phy)), + sizeof(struct zhihe_hw_log), riscv_cbom_block_size); + //seq_printf(file,"\n%d %d %d %d %d\n",log_patch_1, log_patch_2, log_size ,last_fame_size, read); + seq_printf(file, "\n****************** end device log <<<<<<<<<<<<<<<<<\n"); + return 0; + } else { + pr_debug("Fail to alloc buf\n"); + return -1; + } + return 0; +} + +static bool zhihe_panic_init(struct zhihe_hw_log *hw_log, size_t size) +{ + if (size < sizeof(struct zhihe_hw_log)) + return false; + + hw_log->rb.read = 0; + hw_log->rb.size = size - sizeof(struct zhihe_hw_log); + return true; +} + +void *zhihe_create_panic_log_proc(phys_addr_t log_phy, void *dir, + void *log_info_addr, size_t size) +{ + struct zhihe_proc_log_ctrl *log_ctrl = + kmalloc(sizeof(struct zhihe_proc_log_ctrl), GFP_KERNEL); + + if (log_ctrl == NULL) + return NULL; + + log_ctrl->log = log_info_addr; + + zhihe_panic_init(log_ctrl->log, size); + + log_ctrl->log_proc_file = proc_create_single_data( + "proc_log", 0644, dir, &log_proc_show, log_ctrl); + if (log_ctrl->log_proc_file == NULL) { + pr_debug("Error: Could not initialize %s\n", "dsp_log"); + kfree(log_ctrl); + log_ctrl = NULL; + } else + pr_debug("%s create Success!\n", "dsp_log"); + + log_ctrl->log_phy = log_phy; + return log_ctrl; +} + +void zhihe_remove_panic_log_proc(void *arg) +{ + struct zhihe_proc_log_ctrl *log_ctrl = (struct zhihe_proc_log_ctrl *)arg; + + proc_remove(log_ctrl->log_proc_file); + kfree(log_ctrl); + pr_debug("zhihe proc log removed\n"); +} + diff --git a/drivers/mailbox/zhihe-mailbox.c b/drivers/mailbox/zhihe-mailbox.c index 5d0a8dda2..e3c0a342f 100644 --- a/drivers/mailbox/zhihe-mailbox.c +++ b/drivers/mailbox/zhihe-mailbox.c @@ -17,6 +17,9 @@ #include #include +#define ZHIHE_MBOX_V1 0x0 +#define ZHIHE_MBOX_V2 0x1 + /* Status Register */ #define ZHIHE_MBOX_STA 0x0 #define ZHIHE_MBOX_CLR 0x4 @@ -53,27 +56,29 @@ enum zhihe_mbox_chan_type { ZHIHE_MBOX_TYPE_TXRX, /* Tx & Rx chan */ ZHIHE_MBOX_TYPE_DB, /* Tx & Rx doorbell */ }; + enum zhihe_mbox_icu_cpu_id { - ZHIHE_MBOX_ICU_CPU0 = 0, /*die0-908*/ - ZHIHE_MBOX_ICU_CPU1 = 1, - ZHIHE_MBOX_ICU_CPU2 = 2, - ZHIHE_MBOX_ICU_CPU3 = 3, + ZHIHE_MBOX_ICU_CPU0 = 0, /* A200:910T,A210:die0-908 */ + ZHIHE_MBOX_ICU_CPU1 = 1, /* A200:902 */ + ZHIHE_MBOX_ICU_CPU2 = 2, /* A200:906 */ + ZHIHE_MBOX_ICU_CPU3 = 3, /* A200:910R */ }; enum zhihe_mbox_local_id { ZHIHE_MBOX_INTERRUPT = 0, - ZHIHE_MBOX_DATA_CH0 = 1, /* die0-908--die0-902*/ + ZHIHE_MBOX_DATA_CH0 = 1, /* A210:die0-908--die0-902 */ ZHIHE_MBOX_DATA_CH1 = 2, ZHIHE_MBOX_DATA_CH2 = 3, }; enum zhihe_mbox_remote_id { - ZHIHE_MBOX_REMOTE_CH0 = 0, /* die0-908--die0-902*/ + ZHIHE_MBOX_REMOTE_CH0 = 0, /* A210:die0-908--die0-902 */ ZHIHE_MBOX_REMOTE_CH1 = 1, ZHIHE_MBOX_REMOTE_CH2 = 2, }; struct zhihe_mbox_con_priv { - enum zhihe_mbox_local_id idx; + enum zhihe_mbox_icu_cpu_id icu_cpu_idx; + enum zhihe_mbox_local_id local_idx; enum zhihe_mbox_chan_type type; void __iomem *comm_local_base; void __iomem *comm_remote_base; @@ -96,6 +101,7 @@ struct zhihe_mbox_priv { struct zhihe_mbox_con_priv con_priv[ZHIHE_MBOX_CHANS]; struct clk *clk; int irq; + int version; #ifdef CONFIG_PM_SLEEP struct zhihe_mbox_context *ctx; #endif @@ -144,12 +150,10 @@ static void zhihe_mbox_chan_write(struct zhihe_mbox_con_priv *cp, static u32 zhihe_mbox_chan_read(struct zhihe_mbox_con_priv *cp, u32 offs, bool is_remote) { - uint32_t t = 0; if (is_remote) - t = ioread32(cp->comm_remote_base + offs); + return ioread32(cp->comm_remote_base + offs); else - t = ioread32(cp->comm_local_base + offs); - return t; + return ioread32(cp->comm_local_base + offs); } static void zhihe_mbox_chan_rmw(struct zhihe_mbox_con_priv *cp, @@ -213,12 +217,26 @@ static int zhihe_mbox_chan_id_to_mapbit(struct zhihe_mbox_con_priv *cp) { int i; int mapbit = 0; - for (i = 0; i < ZHIHE_MBOX_CHANS; i++) { - if (i == cp->idx) - return mapbit; + struct zhihe_mbox_priv *priv = to_zhihe_mbox_priv(cp->chan->mbox); - if (i != ZHIHE_MBOX_INTERRUPT) - mapbit++; + if (priv->version == ZHIHE_MBOX_V1) { + for (i = 0; i < ZHIHE_MBOX_CHANS; i++) { + if (i == cp->icu_cpu_idx) + return mapbit; + + if (i != priv->cur_icu_cpu_id) + mapbit++; + } + } else if (priv->version == ZHIHE_MBOX_V2) { + for (i = 0; i < ZHIHE_MBOX_CHANS; i++) { + if (i == cp->local_idx) + return mapbit; + + if (i != ZHIHE_MBOX_INTERRUPT) + mapbit++; + } + } else { + dev_err(cp->chan->mbox->dev, "Unknown zhihe mailbox version\n"); } if (i == ZHIHE_MBOX_CHANS) @@ -264,6 +282,14 @@ static irqreturn_t zhihe_mbox_isr(int irq, void *p) zhihe_mbox_chan_write(cp, 0x0, ZHIHE_MBOX_INFO0, false); /* notify remote cpu */ zhihe_mbox_chan_wr_ack(cp, &ack_magic, true); + + if (priv->version == ZHIHE_MBOX_V1) { + /* CPU1 902/906 use polling mode to monitor info7 */ + if (cp->icu_cpu_idx != ZHIHE_MBOX_ICU_CPU1 && + cp->icu_cpu_idx != ZHIHE_MBOX_ICU_CPU2) + zhihe_mbox_chan_rmw(cp, ZHIHE_MBOX_GEN, + ZHIHE_MBOX_GEN_TX_ACK, 0, true); + } /* transfer the data to client */ mbox_chan_received_data(chan, (void *)dat); } @@ -362,6 +388,7 @@ static struct mbox_chan *zhihe_mbox_xlate(struct mbox_controller *mbox, { u32 chan, type; struct zhihe_mbox_con_priv *cp; + struct zhihe_mbox_priv *priv = to_zhihe_mbox_priv(mbox); if (sp->args_count != 2) { dev_err(mbox->dev, @@ -376,6 +403,13 @@ static struct mbox_chan *zhihe_mbox_xlate(struct mbox_controller *mbox, return ERR_PTR(-EINVAL); } + if (priv->version == ZHIHE_MBOX_V1) { + if (chan == priv->cur_icu_cpu_id) { + dev_err(mbox->dev, "Cannot communicate with yourself\n"); + return ERR_PTR(-EINVAL); + } + } + if (type > ZHIHE_MBOX_TYPE_DB) { dev_err(mbox->dev, "Not supported the type for channel[%d]\n", chan); @@ -392,6 +426,7 @@ static int zhihe_mbox_probe(struct platform_device *pdev) { int ret; unsigned int i; + unsigned int mbox_id; struct resource *res; struct zhihe_mbox_priv *priv; unsigned int remote_idx = 0; @@ -402,40 +437,124 @@ static int zhihe_mbox_probe(struct platform_device *pdev) if (!priv) return -ENOMEM; + ret = of_property_read_u32(np, "version", &priv->version); + if (ret) { + priv->version = ZHIHE_MBOX_V1; + } + if (of_property_read_u32(np, "icu_cpu_id", &priv->cur_icu_cpu_id)) { dev_err(dev, "icu_cpu_id is missing\n"); return -EINVAL; } + + if (priv->version == ZHIHE_MBOX_V1) { + if (priv->cur_icu_cpu_id != ZHIHE_MBOX_ICU_CPU0 && + priv->cur_icu_cpu_id != ZHIHE_MBOX_ICU_CPU3) { + dev_err(dev, "icu_cpu_id is invalid\n"); + return -EINVAL; + } + } priv->dev = dev; - - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "interrupt_addr"); - priv->local_icu[ZHIHE_MBOX_INTERRUPT] = devm_ioremap_resource(dev, res); - if (IS_ERR(priv->local_icu[ZHIHE_MBOX_INTERRUPT])) - return PTR_ERR(priv->local_icu[ZHIHE_MBOX_INTERRUPT]); - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "local_addr0"); - priv->local_icu[ZHIHE_MBOX_DATA_CH0] = devm_ioremap_resource(dev, res); - if (IS_ERR(priv->local_icu[ZHIHE_MBOX_DATA_CH0])) - return PTR_ERR(priv->local_icu[ZHIHE_MBOX_DATA_CH0]); - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "remote_icu0"); - priv->remote_icu[ZHIHE_MBOX_REMOTE_CH0] = devm_ioremap_resource(dev, res); - if (IS_ERR(priv->remote_icu[ZHIHE_MBOX_REMOTE_CH0])) - return PTR_ERR(priv->remote_icu[ZHIHE_MBOX_REMOTE_CH0]); - - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "local_addr1"); + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "local_addr0"); if(res!=NULL) { - priv->local_icu[ZHIHE_MBOX_DATA_CH1] = devm_ioremap_resource(dev, res); - if (IS_ERR(priv->local_icu[ZHIHE_MBOX_DATA_CH1])) - return PTR_ERR(priv->local_icu[ZHIHE_MBOX_DATA_CH1]); + if (priv->version == ZHIHE_MBOX_V1) { + mbox_id = ZHIHE_MBOX_ICU_CPU0; + } else if (priv->version == ZHIHE_MBOX_V2) { + mbox_id = ZHIHE_MBOX_DATA_CH0; + } else { + dev_err(dev, "Unknown zhihe mailbox version\n"); + } + priv->local_icu[mbox_id] = devm_ioremap_resource(dev, res); + if (IS_ERR(priv->local_icu[mbox_id])) + return PTR_ERR(priv->local_icu[mbox_id]); + } else { + dev_err(dev, "local_addr0 is NULL\n"); + } + + if (priv->version == ZHIHE_MBOX_V2) { + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "local_addr1"); + if(res!=NULL) { + mbox_id = ZHIHE_MBOX_DATA_CH1; + priv->local_icu[mbox_id] = devm_ioremap_resource(dev, res); + if (IS_ERR(priv->local_icu[mbox_id])) + return PTR_ERR(priv->local_icu[mbox_id]); + } else { + dev_err(dev, "local_addr1 is NULL\n"); + } + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "interrupt_addr"); + if(res!=NULL) { + mbox_id = ZHIHE_MBOX_INTERRUPT; + priv->local_icu[mbox_id] = devm_ioremap_resource(dev, res); + if (IS_ERR(priv->local_icu[mbox_id])) + return PTR_ERR(priv->local_icu[mbox_id]); + } else { + dev_err(dev, "interrupt_addr is NULL\n"); + } + } + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "remote_icu0"); + if(res!=NULL) { + if (priv->version == ZHIHE_MBOX_V1) { + mbox_id = 0; + } else if (priv->version == ZHIHE_MBOX_V2) { + mbox_id = ZHIHE_MBOX_REMOTE_CH0; + } else { + dev_err(dev, "Unknown zhihe mailbox version\n"); + } + priv->remote_icu[mbox_id] = devm_ioremap_resource(dev, res); + if (IS_ERR(priv->remote_icu[mbox_id])) + return PTR_ERR(priv->remote_icu[mbox_id]); + } else { + dev_err(dev, "remote_icu0 is NULL\n"); } res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "remote_icu1"); if(res!=NULL) { - priv->remote_icu[ZHIHE_MBOX_REMOTE_CH1] = devm_ioremap_resource(dev, res); - if (IS_ERR(priv->remote_icu[ZHIHE_MBOX_REMOTE_CH1])) - return PTR_ERR(priv->remote_icu[ZHIHE_MBOX_REMOTE_CH1]); + if (priv->version == ZHIHE_MBOX_V1) { + mbox_id = 1; + } else if (priv->version == ZHIHE_MBOX_V2) { + mbox_id = ZHIHE_MBOX_REMOTE_CH1; + } else { + dev_err(dev, "Unknown zhihe mailbox version\n"); + } + + priv->remote_icu[mbox_id] = devm_ioremap_resource(dev, res); + if (IS_ERR(priv->remote_icu[mbox_id])) + return PTR_ERR(priv->remote_icu[mbox_id]); + } else { + dev_err(dev, "remote_icu1 is NULL\n"); } - - priv->cur_cpu_ch_base = priv->local_icu[ZHIHE_MBOX_INTERRUPT]; + + if (priv->version == ZHIHE_MBOX_V1) { + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "remote_icu2"); + if(res!=NULL) { + mbox_id = 2; + priv->remote_icu[mbox_id] = devm_ioremap_resource(dev, res); + if (IS_ERR(priv->remote_icu[mbox_id])) + return PTR_ERR(priv->remote_icu[mbox_id]); + } else { + dev_err(dev, "remote_icu2 is NULL\n"); + } + + priv->local_icu[ZHIHE_MBOX_ICU_CPU1] = + priv->local_icu[ZHIHE_MBOX_ICU_CPU0] + + ZHIHE_MBOX_CHAN_RES_SIZE; + + priv->local_icu[ZHIHE_MBOX_ICU_CPU2] = + priv->local_icu[ZHIHE_MBOX_ICU_CPU1] + + ZHIHE_MBOX_CHAN_RES_SIZE; + + priv->local_icu[ZHIHE_MBOX_ICU_CPU3] = + priv->local_icu[ZHIHE_MBOX_ICU_CPU2] + + ZHIHE_MBOX_CHAN_RES_SIZE; + mbox_id = priv->cur_icu_cpu_id; + }else { + mbox_id = ZHIHE_MBOX_INTERRUPT; + } + + priv->cur_cpu_ch_base = priv->local_icu[mbox_id]; priv->irq = platform_get_irq(pdev, 0); if (priv->irq < 0) return priv->irq; @@ -451,19 +570,38 @@ static int zhihe_mbox_probe(struct platform_device *pdev) return ret; } /* init the chans */ - for (i = 0; i < ZHIHE_MBOX_CHANS; i++) { - struct zhihe_mbox_con_priv *cp = &priv->con_priv[i]; - cp->idx = i; - cp->chan = &priv->mbox_chans[i]; - priv->mbox_chans[i].con_priv = cp; - snprintf(cp->irq_desc, sizeof(cp->irq_desc), - "zhihe_mbox_chan[%i]", cp->idx); - cp->comm_local_base = priv->local_icu[i]; - if (i != ZHIHE_MBOX_INTERRUPT) { - cp->comm_remote_base = priv->remote_icu[remote_idx]; - remote_idx++; + if (priv->version == ZHIHE_MBOX_V1) { + for (i = 0; i < ZHIHE_MBOX_CHANS; i++) { + struct zhihe_mbox_con_priv *cp = &priv->con_priv[i]; + cp->icu_cpu_idx = i; + cp->chan = &priv->mbox_chans[i]; + priv->mbox_chans[i].con_priv = cp; + snprintf(cp->irq_desc, sizeof(cp->irq_desc), + "zhihe_mbox_chan[%i]", cp->icu_cpu_idx); + cp->comm_local_base = priv->local_icu[i]; + if (i != priv->cur_icu_cpu_id) { + cp->comm_remote_base = priv->remote_icu[remote_idx]; + remote_idx++; + } } + } else if (priv->version == ZHIHE_MBOX_V2) { + for (i = 0; i < ZHIHE_MBOX_CHANS; i++) { + struct zhihe_mbox_con_priv *cp = &priv->con_priv[i]; + cp->local_idx = i; + cp->chan = &priv->mbox_chans[i]; + priv->mbox_chans[i].con_priv = cp; + snprintf(cp->irq_desc, sizeof(cp->irq_desc), + "zhihe_mbox_chan[%i]", cp->local_idx); + cp->comm_local_base = priv->local_icu[i]; + if (i != ZHIHE_MBOX_INTERRUPT) { + cp->comm_remote_base = priv->remote_icu[remote_idx]; + remote_idx++; + } + } + } else { + dev_err(dev, "Unknown zhihe mailbox version\n"); } + spin_lock_init(&priv->mbox_lock); priv->mbox.dev = dev; diff --git a/include/linux/zhihe_proc_debug.h b/include/linux/zhihe_proc_debug.h new file mode 100755 index 000000000..8e7d6dc89 --- /dev/null +++ b/include/linux/zhihe_proc_debug.h @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2021 ZHIHE Group Holding Limited. + */ + +#ifndef __ZHIHE_PROC_DEBUG_H_ +#define __ZHIHE_PROC_DEBUG_H_ + + +void *zhihe_create_panic_log_proc(phys_addr_t log_phy, void *dir, void *log_addr, size_t size); +void zhihe_remove_panic_log_proc(void *arg); + +#endif