sysreset: Add TI System Control Interface (TI SCI) sysreset driver

Devices from the TI K3 family of SoCs like the AM654x contain a Device
Management and Security Controller (SYSFW) that manages the low-level
device control (like clocks, resets etc) for the various hardware
modules present on the SoC. These device control operations are provided
to the host processor OS through a communication protocol called the TI
System Control Interface (TI SCI) protocol.

This patch adds a system reset driver that communicates to the system
controller over the TI SCI protocol for allowing to perform a system-
wide SoC reset.

Reviewed-by: Tom Rini <trini@konsulko.com>
Signed-off-by: Andreas Dannenberg <dannenberg@ti.com>
Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com>
lime2-spi
Andreas Dannenberg 6 years ago committed by Tom Rini
parent 1a88a04e9f
commit 694b052401
  1. 29
      doc/device-tree-bindings/sysreset/ti,sci-sysreset.txt
  2. 7
      drivers/sysreset/Kconfig
  3. 1
      drivers/sysreset/Makefile
  4. 73
      drivers/sysreset/sysreset-ti-sci.c

@ -0,0 +1,29 @@
Texas Instruments TI SCI System Reset Controller
================================================
Some TI SoCs contain a system controller (like the SYSFW, etc...) that is
responsible for controlling the state of the IPs that are present.
Communication between the host processor running an OS and the system
controller happens through a protocol known as TI SCI [1].
[1] http://processors.wiki.ti.com/index.php/TISCI
System Reset Controller Node
============================
The sysreset controller node represents the reset for the overall SoC
which is managed by the SYSFW. Because this relies on the TI SCI protocol
to communicate with the SYSFW it must be a child of the sysfw node.
Required Properties:
--------------------
- compatible: Must be "ti,sci-sysreset"
Example (AM65x):
----------------
sysfw: sysfw {
compatible = "ti,am654-system-controller";
...
k3_sysreset: sysreset-controller {
compatible = "ti,sci-sysreset";
};
};

@ -36,6 +36,13 @@ config SYSRESET_PSCI
Enable PSCI SYSTEM_RESET function call. To use this, PSCI firmware
must be running on your system.
config SYSRESET_TI_SCI
bool "TI System Control Interface (TI SCI) system reset driver"
depends on TI_SCI_PROTOCOL
help
This enables the system reset driver support over TI System Control
Interface available on some new TI's SoCs.
endif
config SYSRESET_SYSCON

@ -6,6 +6,7 @@ obj-$(CONFIG_SYSRESET) += sysreset-uclass.o
obj-$(CONFIG_SYSRESET_GPIO) += sysreset_gpio.o
obj-$(CONFIG_SYSRESET_MICROBLAZE) += sysreset_microblaze.o
obj-$(CONFIG_SYSRESET_PSCI) += sysreset_psci.o
obj-$(CONFIG_SYSRESET_TI_SCI) += sysreset-ti-sci.o
obj-$(CONFIG_SYSRESET_SYSCON) += sysreset_syscon.o
obj-$(CONFIG_SYSRESET_WATCHDOG) += sysreset_watchdog.o
obj-$(CONFIG_SYSRESET_X86) += sysreset_x86.o

@ -0,0 +1,73 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Texas Instruments System Control Interface (TI SCI) system reset driver
*
* Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/
* Andreas Dannenberg <dannenberg@ti.com>
*/
#include <common.h>
#include <dm.h>
#include <errno.h>
#include <sysreset.h>
#include <linux/soc/ti/ti_sci_protocol.h>
/**
* struct ti_sci_sysreset_data - sysreset controller information structure
* @sci: TI SCI handle used for communication with system controller
*/
struct ti_sci_sysreset_data {
const struct ti_sci_handle *sci;
};
static int ti_sci_sysreset_probe(struct udevice *dev)
{
struct ti_sci_sysreset_data *data = dev_get_priv(dev);
debug("%s(dev=%p)\n", __func__, dev);
if (!data)
return -ENOMEM;
/* Store handle for communication with the system controller */
data->sci = ti_sci_get_handle(dev);
if (IS_ERR(data->sci))
return PTR_ERR(data->sci);
return 0;
}
static int ti_sci_sysreset_request(struct udevice *dev, enum sysreset_t type)
{
struct ti_sci_sysreset_data *data = dev_get_priv(dev);
const struct ti_sci_handle *sci = data->sci;
const struct ti_sci_core_ops *cops = &sci->ops.core_ops;
int ret;
debug("%s(dev=%p, type=%d)\n", __func__, dev, type);
ret = cops->reboot_device(sci);
if (ret)
dev_err(rst->dev, "%s: reboot_device failed (%d)\n",
__func__, ret);
return ret;
}
static struct sysreset_ops ti_sci_sysreset_ops = {
.request = ti_sci_sysreset_request,
};
static const struct udevice_id ti_sci_sysreset_of_match[] = {
{ .compatible = "ti,sci-sysreset", },
{ /* sentinel */ },
};
U_BOOT_DRIVER(ti_sci_sysreset) = {
.name = "ti-sci-sysreset",
.id = UCLASS_SYSRESET,
.of_match = ti_sci_sysreset_of_match,
.probe = ti_sci_sysreset_probe,
.priv_auto_alloc_size = sizeof(struct ti_sci_sysreset_data),
.ops = &ti_sci_sysreset_ops,
};
Loading…
Cancel
Save