diff options
author | Tom Rini | 2020-09-15 15:22:00 -0400 |
---|---|---|
committer | Tom Rini | 2020-09-15 15:22:00 -0400 |
commit | bd4e8944cf7e36f8ad39466c40f8fc197c9df1c5 (patch) | |
tree | 0a600fbc0f5507e6ae5d3ba63759545a916af7db /drivers | |
parent | 23e92c124b878e7c5d9a23c46f363874890260cf (diff) | |
parent | 5ba2883160d15b669957dcc50be2733a9b4abe94 (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.c | 99 | ||||
-rw-r--r-- | drivers/spi/omap3_spi.c | 107 | ||||
-rw-r--r-- | drivers/spi/spi-uclass.c | 2 |
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, |