forked from dlink-dir_819/openwrt
		
	Add u-boot bootloader based on 2023.01 to support D1-based boards, currently: - Dongshan Nezha STU - LicheePi RV Dock - MangoPi MQ-Pro - Nezha D1 Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu>
		
			
				
	
	
		
			156 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			156 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| From 7585a12ffec6e42c62222d8ee4085413b3a197f7 Mon Sep 17 00:00:00 2001
 | |
| From: Samuel Holland <samuel@sholland.org>
 | |
| Date: Sat, 9 Oct 2021 14:58:27 -0500
 | |
| Subject: [PATCH 38/90] remoteproc: Add a driver for the Allwinner AR100
 | |
| 
 | |
| Signed-off-by: Samuel Holland <samuel@sholland.org>
 | |
| ---
 | |
|  drivers/remoteproc/Kconfig             |   9 ++
 | |
|  drivers/remoteproc/Makefile            |   1 +
 | |
|  drivers/remoteproc/sun6i_ar100_rproc.c | 111 +++++++++++++++++++++++++
 | |
|  3 files changed, 121 insertions(+)
 | |
|  create mode 100644 drivers/remoteproc/sun6i_ar100_rproc.c
 | |
| 
 | |
| --- a/drivers/remoteproc/Kconfig
 | |
| +++ b/drivers/remoteproc/Kconfig
 | |
| @@ -41,6 +41,15 @@ config REMOTEPROC_STM32_COPRO
 | |
|  	  Say 'y' here to add support for STM32 Cortex-M4 coprocessors via the
 | |
|  	  remoteproc framework.
 | |
|  
 | |
| +config REMOTEPROC_SUN6I_AR100
 | |
| +	bool "Support for Allwinner AR100 SCP"
 | |
| +	select REMOTEPROC
 | |
| +	depends on ARCH_SUNXI
 | |
| +	help
 | |
| +	  Say 'y' here to support Allwinner's AR100 System Control Processor
 | |
| +	  (SCP), found in various sun6i/sun8i/sun50i family SoCs, through the
 | |
| +	  remoteproc framework.
 | |
| +
 | |
|  config REMOTEPROC_TI_K3_ARM64
 | |
|  	bool "Support for TI's K3 based ARM64 remoteproc driver"
 | |
|  	select REMOTEPROC
 | |
| --- a/drivers/remoteproc/Makefile
 | |
| +++ b/drivers/remoteproc/Makefile
 | |
| @@ -10,6 +10,7 @@ obj-$(CONFIG_$(SPL_)REMOTEPROC) += rproc
 | |
|  obj-$(CONFIG_K3_SYSTEM_CONTROLLER) += k3_system_controller.o
 | |
|  obj-$(CONFIG_REMOTEPROC_SANDBOX) += sandbox_testproc.o
 | |
|  obj-$(CONFIG_REMOTEPROC_STM32_COPRO) += stm32_copro.o
 | |
| +obj-$(CONFIG_REMOTEPROC_SUN6I_AR100) += sun6i_ar100_rproc.o
 | |
|  obj-$(CONFIG_REMOTEPROC_TI_K3_ARM64) += ti_k3_arm64_rproc.o
 | |
|  obj-$(CONFIG_REMOTEPROC_TI_K3_DSP) += ti_k3_dsp_rproc.o
 | |
|  obj-$(CONFIG_REMOTEPROC_TI_K3_R5F) += ti_k3_r5f_rproc.o
 | |
| --- /dev/null
 | |
| +++ b/drivers/remoteproc/sun6i_ar100_rproc.c
 | |
| @@ -0,0 +1,111 @@
 | |
| +// SPDX-License-Identifier: GPL-2.0
 | |
| +
 | |
| +#include <dm.h>
 | |
| +#include <errno.h>
 | |
| +#include <remoteproc.h>
 | |
| +#include <asm/io.h>
 | |
| +
 | |
| +#define SUNXI_SCP_MAGIC			0xb4400012
 | |
| +
 | |
| +#define OR1K_VEC_FIRST			0x01
 | |
| +#define OR1K_VEC_LAST			0x0e
 | |
| +#define OR1K_VEC_ADDR(n)		(0x100 * (n))
 | |
| +
 | |
| +struct sun6i_ar100_rproc_priv {
 | |
| +	void	*cfg_base;
 | |
| +	ulong	sram_base;
 | |
| +};
 | |
| +
 | |
| +static int sun6i_ar100_rproc_load(struct udevice *dev, ulong addr, ulong size)
 | |
| +{
 | |
| +	struct sun6i_ar100_rproc_priv *priv = dev_get_priv(dev);
 | |
| +
 | |
| +	/* Check for a valid SCP firmware. */
 | |
| +	if (readl_relaxed(addr) != SUNXI_SCP_MAGIC)
 | |
| +		return -ENOENT;
 | |
| +
 | |
| +	/* Program exception vectors to the firmware entry point. */
 | |
| +	for (u32 i = OR1K_VEC_FIRST; i <= OR1K_VEC_LAST; ++i) {
 | |
| +		ulong vector = priv->sram_base + OR1K_VEC_ADDR(i);
 | |
| +		ulong offset = addr - vector;
 | |
| +
 | |
| +		writel_relaxed(offset >> 2, vector);
 | |
| +	}
 | |
| +
 | |
| +	return 0;
 | |
| +}
 | |
| +
 | |
| +static int sun6i_ar100_rproc_start(struct udevice *dev)
 | |
| +{
 | |
| +	struct sun6i_ar100_rproc_priv *priv = dev_get_priv(dev);
 | |
| +
 | |
| +	setbits_le32(priv->cfg_base, BIT(0));
 | |
| +
 | |
| +	return 0;
 | |
| +}
 | |
| +
 | |
| +static int sun6i_ar100_rproc_stop(struct udevice *dev)
 | |
| +{
 | |
| +	struct sun6i_ar100_rproc_priv *priv = dev_get_priv(dev);
 | |
| +
 | |
| +	clrbits_le32(priv->cfg_base, BIT(0));
 | |
| +
 | |
| +	return 0;
 | |
| +}
 | |
| +
 | |
| +static int sun6i_ar100_rproc_reset(struct udevice *dev)
 | |
| +{
 | |
| +	int ret;
 | |
| +
 | |
| +	ret = sun6i_ar100_rproc_stop(dev);
 | |
| +	if (ret)
 | |
| +		return ret;
 | |
| +
 | |
| +	return sun6i_ar100_rproc_start(dev);
 | |
| +}
 | |
| +
 | |
| +static int sun6i_ar100_rproc_is_running(struct udevice *dev)
 | |
| +{
 | |
| +	struct sun6i_ar100_rproc_priv *priv = dev_get_priv(dev);
 | |
| +
 | |
| +	return !(readl_relaxed(priv->cfg_base) & BIT(0));
 | |
| +}
 | |
| +
 | |
| +static const struct dm_rproc_ops sun6i_ar100_rproc_ops = {
 | |
| +	.load		= sun6i_ar100_rproc_load,
 | |
| +	.start		= sun6i_ar100_rproc_start,
 | |
| +	.stop		= sun6i_ar100_rproc_stop,
 | |
| +	.reset		= sun6i_ar100_rproc_reset,
 | |
| +	.is_running	= sun6i_ar100_rproc_is_running,
 | |
| +};
 | |
| +
 | |
| +static int sun6i_ar100_rproc_probe(struct udevice *dev)
 | |
| +{
 | |
| +	struct sun6i_ar100_rproc_priv *priv = dev_get_priv(dev);
 | |
| +	struct ofnode_phandle_args sram_handle;
 | |
| +	int ret;
 | |
| +
 | |
| +	priv->cfg_base = dev_read_addr_ptr(dev);
 | |
| +
 | |
| +	ret = dev_read_phandle_with_args(dev, "sram", NULL, 0, 0, &sram_handle);
 | |
| +	if (ret)
 | |
| +		return ret;
 | |
| +
 | |
| +	priv->sram_base = ofnode_get_addr(sram_handle.node);
 | |
| +
 | |
| +	return 0;
 | |
| +}
 | |
| +
 | |
| +static const struct udevice_id sun6i_ar100_rproc_ids[] = {
 | |
| +	{ .compatible = "allwinner,sun6i-a31-ar100" },
 | |
| +	{ }
 | |
| +};
 | |
| +
 | |
| +U_BOOT_DRIVER(sun6i_ar100_rproc) = {
 | |
| +	.name		= "sun6i_ar100_rproc",
 | |
| +	.id		= UCLASS_REMOTEPROC,
 | |
| +	.of_match	= sun6i_ar100_rproc_ids,
 | |
| +	.probe		= sun6i_ar100_rproc_probe,
 | |
| +	.priv_auto	= sizeof(struct sun6i_ar100_rproc_priv),
 | |
| +	.ops		= &sun6i_ar100_rproc_ops,
 | |
| +};
 |