Release develop 251028
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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";
|
||||
};
|
||||
|
||||
@@ -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";
|
||||
};
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -16,6 +16,10 @@
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/zhihe_proc_debug.h>
|
||||
|
||||
#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 <xuhongkun@zhcomputing.com>");
|
||||
MODULE_AUTHOR("xionglue.huang <huangxionglue@zhcomputing.com>");
|
||||
MODULE_DESCRIPTION("ZHIHE firmware protocol driver");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
||||
|
||||
163
drivers/firmware/zhihe/zhihe_proc_debug.c
Executable file
163
drivers/firmware/zhihe/zhihe_proc_debug.c
Executable file
@@ -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 <linux/delay.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/io.h>
|
||||
#include <asm/cacheflush.h>
|
||||
|
||||
#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");
|
||||
}
|
||||
|
||||
@@ -17,6 +17,9 @@
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#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;
|
||||
|
||||
13
include/linux/zhihe_proc_debug.h
Executable file
13
include/linux/zhihe_proc_debug.h
Executable file
@@ -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
|
||||
Reference in New Issue
Block a user