aboutsummaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorTom Rini2020-09-15 15:22:00 -0400
committerTom Rini2020-09-15 15:22:00 -0400
commitbd4e8944cf7e36f8ad39466c40f8fc197c9df1c5 (patch)
tree0a600fbc0f5507e6ae5d3ba63759545a916af7db /drivers
parent23e92c124b878e7c5d9a23c46f363874890260cf (diff)
parent5ba2883160d15b669957dcc50be2733a9b4abe94 (diff)
Merge tag 'ti-v2021.01-next' of https://gitlab.denx.de/u-boot/custodians/u-boot-ti into next
- Hyperflash boot for J7200 - Update Main R5FSS lockstep mode - R5F remoteproc support for J7200 - Minor env fixes - Add SPI boot support for am335x-icev2
Diffstat (limited to 'drivers')
-rw-r--r--drivers/remoteproc/ti_k3_r5f_rproc.c99
-rw-r--r--drivers/spi/omap3_spi.c107
-rw-r--r--drivers/spi/spi-uclass.c2
3 files changed, 117 insertions, 91 deletions
diff --git a/drivers/remoteproc/ti_k3_r5f_rproc.c b/drivers/remoteproc/ti_k3_r5f_rproc.c
index 1a7f1f8a005..8e21a38be7f 100644
--- a/drivers/remoteproc/ti_k3_r5f_rproc.c
+++ b/drivers/remoteproc/ti_k3_r5f_rproc.c
@@ -2,8 +2,9 @@
/*
* Texas Instruments' K3 R5 Remoteproc driver
*
- * Copyright (C) 2018-2019 Texas Instruments Incorporated - http://www.ti.com/
+ * Copyright (C) 2018-2020 Texas Instruments Incorporated - https://www.ti.com/
* Lokesh Vutla <lokeshvutla@ti.com>
+ * Suman Anna <s-anna@ti.com>
*/
#include <common.h>
@@ -37,6 +38,8 @@
#define PROC_BOOT_CFG_FLAG_R5_BTCM_EN 0x00001000
#define PROC_BOOT_CFG_FLAG_R5_ATCM_EN 0x00002000
#define PROC_BOOT_CFG_FLAG_GEN_IGN_BOOTVECTOR 0x10000000
+/* Available from J7200 SoCs onwards */
+#define PROC_BOOT_CFG_FLAG_R5_MEM_INIT_DIS 0x00004000
/* R5 TI-SCI Processor Control Flags */
#define PROC_BOOT_CTRL_FLAG_R5_CORE_HALT 0x00000001
@@ -55,6 +58,16 @@ enum cluster_mode {
};
/**
+ * struct k3_r5f_ip_data - internal data structure used for IP variations
+ * @tcm_is_double: flag to denote the larger unified TCMs in certain modes
+ * @tcm_ecc_autoinit: flag to denote the auto-initialization of TCMs for ECC
+ */
+struct k3_r5f_ip_data {
+ bool tcm_is_double;
+ bool tcm_ecc_autoinit;
+};
+
+/**
* struct k3_r5_mem - internal memory structure
* @cpu_addr: MPU virtual address of the memory region
* @bus_addr: Bus address used to access the memory region
@@ -74,6 +87,7 @@ struct k3_r5f_mem {
* @cluster: pointer to the parent cluster.
* @reset: reset control handle
* @tsp: TI-SCI processor control handle
+ * @ipdata: cached pointer to R5F IP specific feature data
* @mem: Array of available internal memories
* @num_mem: Number of available memories
* @atcm_enable: flag to control ATCM enablement
@@ -86,6 +100,7 @@ struct k3_r5f_core {
struct k3_r5f_cluster *cluster;
struct reset_ctl reset;
struct ti_sci_proc tsp;
+ struct k3_r5f_ip_data *ipdata;
struct k3_r5f_mem *mem;
int num_mems;
u32 atcm_enable;
@@ -257,6 +272,18 @@ static int k3_r5f_core_sanity_check(struct k3_r5f_core *core)
return 0;
}
+/* Zero out TCMs so that ECC can be effective on all TCM addresses */
+void k3_r5f_init_tcm_memories(struct k3_r5f_core *core, bool auto_inited)
+{
+ if (core->ipdata->tcm_ecc_autoinit && auto_inited)
+ return;
+
+ if (core->atcm_enable)
+ memset(core->mem[0].cpu_addr, 0x00, core->mem[0].size);
+ if (core->btcm_enable)
+ memset(core->mem[1].cpu_addr, 0x00, core->mem[1].size);
+}
+
/**
* k3_r5f_load() - Load up the Remote processor image
* @dev: rproc device pointer
@@ -268,7 +295,9 @@ static int k3_r5f_core_sanity_check(struct k3_r5f_core *core)
static int k3_r5f_load(struct udevice *dev, ulong addr, ulong size)
{
struct k3_r5f_core *core = dev_get_priv(dev);
- u32 boot_vector;
+ u64 boot_vector;
+ u32 ctrl, sts, cfg = 0;
+ bool mem_auto_init;
int ret;
dev_dbg(dev, "%s addr = 0x%lx, size = 0x%lx\n", __func__, addr, size);
@@ -281,6 +310,12 @@ static int k3_r5f_load(struct udevice *dev, ulong addr, ulong size)
if (ret)
return ret;
+ ret = ti_sci_proc_get_status(&core->tsp, &boot_vector, &cfg, &ctrl,
+ &sts);
+ if (ret)
+ return ret;
+ mem_auto_init = !(cfg & PROC_BOOT_CFG_FLAG_R5_MEM_INIT_DIS);
+
ret = k3_r5f_prepare(dev);
if (ret) {
dev_err(dev, "R5f prepare failed for core %d\n",
@@ -288,11 +323,7 @@ static int k3_r5f_load(struct udevice *dev, ulong addr, ulong size)
goto proc_release;
}
- /* Zero out TCMs so that ECC can be effective on all TCM addresses */
- if (core->atcm_enable)
- memset(core->mem[0].cpu_addr, 0x00, core->mem[0].size);
- if (core->btcm_enable)
- memset(core->mem[1].cpu_addr, 0x00, core->mem[1].size);
+ k3_r5f_init_tcm_memories(core, mem_auto_init);
ret = rproc_elf_load_image(dev, addr, size);
if (ret < 0) {
@@ -302,7 +333,7 @@ static int k3_r5f_load(struct udevice *dev, ulong addr, ulong size)
boot_vector = rproc_elf_get_boot_addr(dev, addr);
- dev_dbg(dev, "%s: Boot vector = 0x%x\n", __func__, boot_vector);
+ dev_dbg(dev, "%s: Boot vector = 0x%llx\n", __func__, boot_vector);
ret = ti_sci_proc_set_config(&core->tsp, boot_vector, 0, 0);
@@ -657,6 +688,8 @@ static int k3_r5f_of_to_priv(struct k3_r5f_core *core)
return ret;
}
+ core->ipdata = (struct k3_r5f_ip_data *)dev_get_driver_data(core->dev);
+
return 0;
}
@@ -702,6 +735,38 @@ static int k3_r5f_core_of_get_memories(struct k3_r5f_core *core)
return 0;
}
+/*
+ * Each R5F core within a typical R5FSS instance has a total of 64 KB of TCMs,
+ * split equally into two 32 KB banks between ATCM and BTCM. The TCMs from both
+ * cores are usable in Split-mode, but only the Core0 TCMs can be used in
+ * LockStep-mode. The newer revisions of the R5FSS IP maximizes these TCMs by
+ * leveraging the Core1 TCMs as well in certain modes where they would have
+ * otherwise been unusable (Eg: LockStep-mode on J7200 SoCs). This is done by
+ * making a Core1 TCM visible immediately after the corresponding Core0 TCM.
+ * The SoC memory map uses the larger 64 KB sizes for the Core0 TCMs, and the
+ * dts representation reflects this increased size on supported SoCs. The Core0
+ * TCM sizes therefore have to be adjusted to only half the original size in
+ * Split mode.
+ */
+static void k3_r5f_core_adjust_tcm_sizes(struct k3_r5f_core *core)
+{
+ struct k3_r5f_cluster *cluster = core->cluster;
+
+ if (cluster->mode == CLUSTER_MODE_LOCKSTEP)
+ return;
+
+ if (!core->ipdata->tcm_is_double)
+ return;
+
+ if (core == cluster->cores[0]) {
+ core->mem[0].size /= 2;
+ core->mem[1].size /= 2;
+
+ dev_dbg(core->dev, "adjusted TCM sizes, ATCM = 0x%zx BTCM = 0x%zx\n",
+ core->mem[0].size, core->mem[1].size);
+ }
+}
+
/**
* k3_r5f_probe() - Basic probe
* @dev: corresponding k3 remote processor device
@@ -755,6 +820,8 @@ static int k3_r5f_probe(struct udevice *dev)
return ret;
}
+ k3_r5f_core_adjust_tcm_sizes(core);
+
dev_dbg(dev, "Remoteproc successfully probed\n");
return 0;
@@ -771,9 +838,20 @@ static int k3_r5f_remove(struct udevice *dev)
return 0;
}
+static const struct k3_r5f_ip_data k3_data = {
+ .tcm_is_double = false,
+ .tcm_ecc_autoinit = false,
+};
+
+static const struct k3_r5f_ip_data j7200_data = {
+ .tcm_is_double = true,
+ .tcm_ecc_autoinit = true,
+};
+
static const struct udevice_id k3_r5f_rproc_ids[] = {
- { .compatible = "ti,am654-r5f"},
- { .compatible = "ti,j721e-r5f"},
+ { .compatible = "ti,am654-r5f", .data = (ulong)&k3_data, },
+ { .compatible = "ti,j721e-r5f", .data = (ulong)&k3_data, },
+ { .compatible = "ti,j7200-r5f", .data = (ulong)&j7200_data, },
{}
};
@@ -810,6 +888,7 @@ static int k3_r5f_cluster_probe(struct udevice *dev)
static const struct udevice_id k3_r5fss_ids[] = {
{ .compatible = "ti,am654-r5fss"},
{ .compatible = "ti,j721e-r5fss"},
+ { .compatible = "ti,j7200-r5fss"},
{}
};
diff --git a/drivers/spi/omap3_spi.c b/drivers/spi/omap3_spi.c
index fbf9575851a..56cb2174868 100644
--- a/drivers/spi/omap3_spi.c
+++ b/drivers/spi/omap3_spi.c
@@ -22,82 +22,14 @@
#include <malloc.h>
#include <asm/io.h>
#include <linux/bitops.h>
+#include <omap3_spi.h>
DECLARE_GLOBAL_DATA_PTR;
-#define OMAP4_MCSPI_REG_OFFSET 0x100
-
struct omap2_mcspi_platform_config {
unsigned int regs_offset;
};
-/* per-register bitmasks */
-#define OMAP3_MCSPI_SYSCONFIG_SMARTIDLE (2 << 3)
-#define OMAP3_MCSPI_SYSCONFIG_ENAWAKEUP BIT(2)
-#define OMAP3_MCSPI_SYSCONFIG_AUTOIDLE BIT(0)
-#define OMAP3_MCSPI_SYSCONFIG_SOFTRESET BIT(1)
-
-#define OMAP3_MCSPI_SYSSTATUS_RESETDONE BIT(0)
-
-#define OMAP3_MCSPI_MODULCTRL_SINGLE BIT(0)
-#define OMAP3_MCSPI_MODULCTRL_MS BIT(2)
-#define OMAP3_MCSPI_MODULCTRL_STEST BIT(3)
-
-#define OMAP3_MCSPI_CHCONF_PHA BIT(0)
-#define OMAP3_MCSPI_CHCONF_POL BIT(1)
-#define OMAP3_MCSPI_CHCONF_CLKD_MASK GENMASK(5, 2)
-#define OMAP3_MCSPI_CHCONF_EPOL BIT(6)
-#define OMAP3_MCSPI_CHCONF_WL_MASK GENMASK(11, 7)
-#define OMAP3_MCSPI_CHCONF_TRM_RX_ONLY BIT(12)
-#define OMAP3_MCSPI_CHCONF_TRM_TX_ONLY BIT(13)
-#define OMAP3_MCSPI_CHCONF_TRM_MASK GENMASK(13, 12)
-#define OMAP3_MCSPI_CHCONF_DMAW BIT(14)
-#define OMAP3_MCSPI_CHCONF_DMAR BIT(15)
-#define OMAP3_MCSPI_CHCONF_DPE0 BIT(16)
-#define OMAP3_MCSPI_CHCONF_DPE1 BIT(17)
-#define OMAP3_MCSPI_CHCONF_IS BIT(18)
-#define OMAP3_MCSPI_CHCONF_TURBO BIT(19)
-#define OMAP3_MCSPI_CHCONF_FORCE BIT(20)
-
-#define OMAP3_MCSPI_CHSTAT_RXS BIT(0)
-#define OMAP3_MCSPI_CHSTAT_TXS BIT(1)
-#define OMAP3_MCSPI_CHSTAT_EOT BIT(2)
-
-#define OMAP3_MCSPI_CHCTRL_EN BIT(0)
-#define OMAP3_MCSPI_CHCTRL_DIS (0 << 0)
-
-#define OMAP3_MCSPI_WAKEUPENABLE_WKEN BIT(0)
-#define MCSPI_PINDIR_D0_IN_D1_OUT 0
-#define MCSPI_PINDIR_D0_OUT_D1_IN 1
-
-#define OMAP3_MCSPI_MAX_FREQ 48000000
-#define SPI_WAIT_TIMEOUT 10
-
-/* OMAP3 McSPI registers */
-struct mcspi_channel {
- unsigned int chconf; /* 0x2C, 0x40, 0x54, 0x68 */
- unsigned int chstat; /* 0x30, 0x44, 0x58, 0x6C */
- unsigned int chctrl; /* 0x34, 0x48, 0x5C, 0x70 */
- unsigned int tx; /* 0x38, 0x4C, 0x60, 0x74 */
- unsigned int rx; /* 0x3C, 0x50, 0x64, 0x78 */
-};
-
-struct mcspi {
- unsigned char res1[0x10];
- unsigned int sysconfig; /* 0x10 */
- unsigned int sysstatus; /* 0x14 */
- unsigned int irqstatus; /* 0x18 */
- unsigned int irqenable; /* 0x1C */
- unsigned int wakeupenable; /* 0x20 */
- unsigned int syst; /* 0x24 */
- unsigned int modulctrl; /* 0x28 */
- struct mcspi_channel channel[4];
- /* channel0: 0x2C - 0x3C, bus 0 & 1 & 2 & 3 */
- /* channel1: 0x40 - 0x50, bus 0 & 1 */
- /* channel2: 0x54 - 0x64, bus 0 & 1 */
- /* channel3: 0x68 - 0x78, bus 0 */
-};
-
struct omap3_spi_priv {
struct mcspi *regs;
unsigned int cs;
@@ -482,17 +414,10 @@ static int omap3_spi_set_wordlen(struct udevice *dev, unsigned int wordlen)
static int omap3_spi_probe(struct udevice *dev)
{
struct omap3_spi_priv *priv = dev_get_priv(dev);
- const void *blob = gd->fdt_blob;
- int node = dev_of_offset(dev);
-
- struct omap2_mcspi_platform_config* data =
- (struct omap2_mcspi_platform_config*)dev_get_driver_data(dev);
+ struct omap3_spi_plat *plat = dev_get_platdata(dev);
- priv->regs = (struct mcspi *)(dev_read_addr(dev) + data->regs_offset);
- if (fdtdec_get_bool(blob, node, "ti,pindir-d0-out-d1-in"))
- priv->pin_dir = MCSPI_PINDIR_D0_OUT_D1_IN;
- else
- priv->pin_dir = MCSPI_PINDIR_D0_IN_D1_OUT;
+ priv->regs = plat->regs;
+ priv->pin_dir = plat->pin_dir;
priv->wordlen = SPI_DEFAULT_WORDLEN;
spi_reset(priv->regs);
@@ -544,6 +469,7 @@ static const struct dm_spi_ops omap3_spi_ops = {
*/
};
+#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
static struct omap2_mcspi_platform_config omap2_pdata = {
.regs_offset = 0,
};
@@ -552,16 +478,37 @@ static struct omap2_mcspi_platform_config omap4_pdata = {
.regs_offset = OMAP4_MCSPI_REG_OFFSET,
};
+static int omap3_spi_ofdata_to_platdata(struct udevice *dev)
+{
+ struct omap2_mcspi_platform_config *data =
+ (struct omap2_mcspi_platform_config *)dev_get_driver_data(dev);
+ struct omap3_spi_plat *plat = dev_get_platdata(dev);
+
+ plat->regs = (struct mcspi *)(dev_read_addr(dev) + data->regs_offset);
+
+ if (dev_read_bool(dev, "ti,pindir-d0-out-d1-in"))
+ plat->pin_dir = MCSPI_PINDIR_D0_OUT_D1_IN;
+ else
+ plat->pin_dir = MCSPI_PINDIR_D0_IN_D1_OUT;
+
+ return 0;
+}
+
static const struct udevice_id omap3_spi_ids[] = {
{ .compatible = "ti,omap2-mcspi", .data = (ulong)&omap2_pdata },
{ .compatible = "ti,omap4-mcspi", .data = (ulong)&omap4_pdata },
{ }
};
-
+#endif
U_BOOT_DRIVER(omap3_spi) = {
.name = "omap3_spi",
.id = UCLASS_SPI,
+ .flags = DM_FLAG_PRE_RELOC,
+#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
.of_match = omap3_spi_ids,
+ .ofdata_to_platdata = omap3_spi_ofdata_to_platdata,
+ .platdata_auto_alloc_size = sizeof(struct omap3_spi_plat),
+#endif
.probe = omap3_spi_probe,
.ops = &omap3_spi_ops,
.priv_auto_alloc_size = sizeof(struct omap3_spi_priv),
diff --git a/drivers/spi/spi-uclass.c b/drivers/spi/spi-uclass.c
index cffd9cf0b0e..55a8eed8901 100644
--- a/drivers/spi/spi-uclass.c
+++ b/drivers/spi/spi-uclass.c
@@ -497,7 +497,7 @@ UCLASS_DRIVER(spi) = {
.id = UCLASS_SPI,
.name = "spi",
.flags = DM_UC_FLAG_SEQ_ALIAS,
-#if !CONFIG_IS_ENABLED(OF_PLATDATA)
+#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
.post_bind = dm_scan_fdt_dev,
#endif
.post_probe = spi_post_probe,