The K3 J7200 SoC family has a revised R5F sub-system and contains a subset of the R5F clusters present on J721E SoCs. The K3 J7200 SoCs only have two dual-core Arm R5F clusters/subsystems with 2 R5F cores each. One cluster is present within the MCU voltage domain (MCU_R5FSS0), while the other is present in the MAIN voltage domain (MAIN_R5FSS0). The revised IP has the following two new features: 1. TCMs are auto-initialized during module power-up, and the behavior is programmable through a MMR bit. 2. The LockStep-mode allows the Core1 TCMs to be combined with the Core0 TCMs effectively doubling the amount of TCMs available. The LockStep-mode on previous SoCs could only use the Core0 TCMs. This combined TCMs appear contiguous at the respective Core0 TCM addresses. Extend the support to these clusters in the K3 R5F remoteproc driver using J7200 specific compatibles. Logic for the second feature is added in the next patch. The integration of these clusters is very much similar to J721E SoCs otherwise. Signed-off-by: Suman Anna <s-anna@xxxxxx> --- drivers/remoteproc/ti_k3_r5_remoteproc.c | 52 +++++++++++++++++++++++- 1 file changed, 50 insertions(+), 2 deletions(-) diff --git a/drivers/remoteproc/ti_k3_r5_remoteproc.c b/drivers/remoteproc/ti_k3_r5_remoteproc.c index 40fa7a4d2ec8..66a32dcdd7d0 100644 --- a/drivers/remoteproc/ti_k3_r5_remoteproc.c +++ b/drivers/remoteproc/ti_k3_r5_remoteproc.c @@ -38,6 +38,8 @@ #define PROC_BOOT_CFG_FLAG_R5_TCM_RSTBASE 0x00000800 #define PROC_BOOT_CFG_FLAG_R5_BTCM_EN 0x00001000 #define PROC_BOOT_CFG_FLAG_R5_ATCM_EN 0x00002000 +/* 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 @@ -67,16 +69,26 @@ enum cluster_mode { CLUSTER_MODE_LOCKSTEP, }; +/** + * struct k3_r5_soc_data - match data to handle SoC variations + * @tcm_ecc_autoinit: flag to denote the auto-initialization of TCMs for ECC + */ +struct k3_r5_soc_data { + bool tcm_ecc_autoinit; +}; + /** * struct k3_r5_cluster - K3 R5F Cluster structure * @dev: cached device pointer * @mode: Mode to configure the Cluster - Split or LockStep * @cores: list of R5 cores within the cluster + * @soc_data: SoC-specific feature data for a R5FSS */ struct k3_r5_cluster { struct device *dev; enum cluster_mode mode; struct list_head cores; + const struct k3_r5_soc_data *soc_data; }; /** @@ -362,8 +374,16 @@ static int k3_r5_rproc_prepare(struct rproc *rproc) struct k3_r5_cluster *cluster = kproc->cluster; struct k3_r5_core *core = kproc->core; struct device *dev = kproc->dev; + u32 ctrl = 0, cfg = 0, stat = 0; + u64 boot_vec = 0; + bool mem_init_dis; int ret; + ret = ti_sci_proc_get_status(core->tsp, &boot_vec, &cfg, &ctrl, &stat); + if (ret < 0) + return ret; + mem_init_dis = !!(cfg & PROC_BOOT_CFG_FLAG_R5_MEM_INIT_DIS); + ret = (cluster->mode == CLUSTER_MODE_LOCKSTEP) ? k3_r5_lockstep_release(cluster) : k3_r5_split_release(core); if (ret) { @@ -372,6 +392,17 @@ static int k3_r5_rproc_prepare(struct rproc *rproc) return ret; } + /* + * Newer IP revisions like on J7200 SoCs support h/w auto-initialization + * of TCMs, so there is no need to perform the s/w memzero. This bit is + * configurable through System Firmware, the default value does perform + * auto-init, but account for it in case it is disabled + */ + if (cluster->soc_data->tcm_ecc_autoinit && !mem_init_dis) { + dev_dbg(dev, "leveraging h/w init for TCM memories\n"); + return 0; + } + /* * Zero out both TCMs unconditionally (access from v8 Arm core is not * affected by ATCM & BTCM enable configuration values) so that ECC @@ -1309,15 +1340,23 @@ static int k3_r5_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct device_node *np = dev_of_node(dev); struct k3_r5_cluster *cluster; + const struct k3_r5_soc_data *data; int ret; int num_cores; + data = of_device_get_match_data(&pdev->dev); + if (!data) { + dev_err(dev, "SoC-specific data is not defined\n"); + return -ENODEV; + } + cluster = devm_kzalloc(dev, sizeof(*cluster), GFP_KERNEL); if (!cluster) return -ENOMEM; cluster->dev = dev; cluster->mode = CLUSTER_MODE_LOCKSTEP; + cluster->soc_data = data; INIT_LIST_HEAD(&cluster->cores); ret = of_property_read_u32(np, "ti,cluster-mode", &cluster->mode); @@ -1367,9 +1406,18 @@ static int k3_r5_probe(struct platform_device *pdev) return 0; } +static const struct k3_r5_soc_data am65_j721e_soc_data = { + .tcm_ecc_autoinit = false, +}; + +static const struct k3_r5_soc_data j7200_soc_data = { + .tcm_ecc_autoinit = true, +}; + static const struct of_device_id k3_r5_of_match[] = { - { .compatible = "ti,am654-r5fss", }, - { .compatible = "ti,j721e-r5fss", }, + { .compatible = "ti,am654-r5fss", .data = &am65_j721e_soc_data, }, + { .compatible = "ti,j721e-r5fss", .data = &am65_j721e_soc_data, }, + { .compatible = "ti,j7200-r5fss", .data = &j7200_soc_data, }, { /* sentinel */ }, }; MODULE_DEVICE_TABLE(of, k3_r5_of_match); -- 2.28.0