From 4a15a42ac26513fd7734139cae7598bc2a792373 Mon Sep 17 00:00:00 2001 From: Ziyuan Xu Date: Thu, 28 Jul 2022 10:31:06 +0800 Subject: [PATCH] soc: rockchip: Add rockchip thunder boot service driver It's used for the other processor to signal ARM via mailbox, that's means the other processor is EOL. Signed-off-by: Ziyuan Xu Change-Id: I38ee434ec8ee1bb0841fd0c178f24192f6d74bdf --- drivers/soc/rockchip/Kconfig | 7 + drivers/soc/rockchip/Makefile | 1 + .../rockchip/rockchip_thunderboot_service.c | 128 ++++++++++++++++++ .../rockchip/rockchip_thunderboot_service.h | 26 ++++ 4 files changed, 162 insertions(+) create mode 100644 drivers/soc/rockchip/rockchip_thunderboot_service.c create mode 100644 include/linux/soc/rockchip/rockchip_thunderboot_service.h diff --git a/drivers/soc/rockchip/Kconfig b/drivers/soc/rockchip/Kconfig index 1c784d042e6a..0773f56a9dc4 100644 --- a/drivers/soc/rockchip/Kconfig +++ b/drivers/soc/rockchip/Kconfig @@ -228,6 +228,13 @@ config ROCKCHIP_THUNDER_BOOT_SFC help Say y if boot from SPI Flash from SFC controller. +config ROCKCHIP_THUNDER_BOOT_SERVICE + bool "Rockchip Thunder Boot Service" + depends on ROCKCHIP_THUNDER_BOOT + depends on MAILBOX + help + Say y if MCU need to notify AP. + config ROCKCHIP_NPOR_POWERGOOD bool "Rockchip NPOR Powergood" help diff --git a/drivers/soc/rockchip/Makefile b/drivers/soc/rockchip/Makefile index 15d3a6413a69..8f9439271fc3 100644 --- a/drivers/soc/rockchip/Makefile +++ b/drivers/soc/rockchip/Makefile @@ -24,6 +24,7 @@ obj-$(CONFIG_ROCKCHIP_SUSPEND_MODE) += rockchip_pm_config.o obj-$(CONFIG_ROCKCHIP_SYSTEM_MONITOR) += rockchip_system_monitor.o obj-$(CONFIG_ROCKCHIP_THUNDER_BOOT_MMC) += rockchip_thunderboot_mmc.o obj-$(CONFIG_ROCKCHIP_THUNDER_BOOT_SFC) += rockchip_thunderboot_sfc.o +obj-$(CONFIG_ROCKCHIP_THUNDER_BOOT_SERVICE) += rockchip_thunderboot_service.o obj-$(CONFIG_ROCKCHIP_DEBUG) += rockchip_debug.o obj-$(CONFIG_ROCKCHIP_NPOR_POWERGOOD) += rockchip_npor_powergood.o obj-$(CONFIG_RK_CMA_PROCFS) += rk_cma_procfs.o diff --git a/drivers/soc/rockchip/rockchip_thunderboot_service.c b/drivers/soc/rockchip/rockchip_thunderboot_service.c new file mode 100644 index 000000000000..e552ed162389 --- /dev/null +++ b/drivers/soc/rockchip/rockchip_thunderboot_service.c @@ -0,0 +1,128 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2022 Rockchip Electronics Co., Ltd. + */ +#include +#include +#include +#include +#include +#include +#include + +#define CMD_MCU_STATUS (0x0000f00d) +#define MCU_STATUS_DONE (0xdeadbeef) + +struct rk_tb_serv { + struct device *dev; + struct mbox_chan *mbox_rx_chan; + struct mbox_client mbox_cl; +}; + +static atomic_t mcu_done = ATOMIC_INIT(0); +static LIST_HEAD(clients_list); +static DEFINE_SPINLOCK(lock); + +bool rk_tb_mcu_is_done(void) +{ + return atomic_read(&mcu_done); +} +EXPORT_SYMBOL(rk_tb_mcu_is_done); + +int rk_tb_client_register_cb(struct rk_tb_client *client) +{ + if (!client || !client->cb) + return -EINVAL; + + spin_lock(&lock); + if (rk_tb_mcu_is_done()) { + spin_unlock(&lock); + client->cb(client->data); + return 0; + } + + list_add_tail(&client->node, &clients_list); + spin_unlock(&lock); + + return 0; +} +EXPORT_SYMBOL(rk_tb_client_register_cb); + +static void do_mcu_done(struct rk_tb_serv *serv) +{ + struct rk_tb_client *client, *client_s; + struct rockchip_mbox_msg msg; + + rockchip_mbox_read_msg(serv->mbox_rx_chan, &msg); + if (msg.cmd == CMD_MCU_STATUS && msg.data == MCU_STATUS_DONE) { + spin_lock(&lock); + if (atomic_read(&mcu_done)) { + spin_unlock(&lock); + return; + } + + atomic_set(&mcu_done, 1); + list_for_each_entry_safe(client, client_s, &clients_list, node) { + spin_unlock(&lock); + if (client->cb) + client->cb(client->data); + spin_lock(&lock); + list_del(&client->node); + } + spin_unlock(&lock); + } +} + +static void rk_tb_rx_callback(struct mbox_client *mbox_cl, void *message) +{ + struct rk_tb_serv *serv = dev_get_drvdata(mbox_cl->dev); + + do_mcu_done(serv); + mbox_free_channel(serv->mbox_rx_chan); +} + +static int rk_tb_serv_probe(struct platform_device *pdev) +{ + struct rk_tb_serv *serv; + struct mbox_client *mbox_cl; + + serv = devm_kzalloc(&pdev->dev, sizeof(*serv), GFP_KERNEL); + if (!serv) + return -ENOMEM; + + platform_set_drvdata(pdev, serv); + + mbox_cl = &serv->mbox_cl; + mbox_cl->dev = &pdev->dev; + mbox_cl->rx_callback = rk_tb_rx_callback; + serv->mbox_rx_chan = mbox_request_channel_byname(mbox_cl, "amp-rx"); + if (IS_ERR(serv->mbox_rx_chan)) { + dev_err(mbox_cl->dev, "failed to request mbox rx chan\n"); + return PTR_ERR(serv->mbox_rx_chan); + } + + do_mcu_done(serv); + return 0; +} + +#ifdef CONFIG_OF +static const struct of_device_id rk_tb_serv_dt_match[] = { + { .compatible = "rockchip,thunder-boot-service" }, + {}, +}; +#endif + +static struct platform_driver rk_tb_serv_driver = { + .probe = rk_tb_serv_probe, + .driver = { + .name = "rockchip_thunder_boot_service", + .of_match_table = rk_tb_serv_dt_match, + }, +}; + +static int __init rk_tb_serv_init(void) +{ + return platform_driver_register(&rk_tb_serv_driver); +} + +arch_initcall(rk_tb_serv_init); diff --git a/include/linux/soc/rockchip/rockchip_thunderboot_service.h b/include/linux/soc/rockchip/rockchip_thunderboot_service.h new file mode 100644 index 000000000000..c88f48e0107b --- /dev/null +++ b/include/linux/soc/rockchip/rockchip_thunderboot_service.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* Copyright (c) 2022 Rockchip Electronics Co., Ltd */ + +#ifndef _ROCKCHIP_THUNDERBOOT_SERVICE_H +#define _ROCKCHIP_THUNDERBOOT_SERVICE_H + +struct rk_tb_client { + struct list_head node; + void *data; + void (*cb)(void *data); +}; + +#ifdef CONFIG_ROCKCHIP_THUNDER_BOOT_SERVICE +bool rk_tb_mcu_is_done(void); +int rk_tb_client_register_cb(struct rk_tb_client *client); +#else +static inline bool rk_tb_mcu_is_done(void) +{ + return true; +} +static inline int rk_tb_client_register_cb(struct rk_tb_client *client) +{ + return 0; +} +#endif +#endif