Skip to content

Commit b31bcda

Browse files
tnmyshmathieupoirier
authored andcommitted
remoteproc: zynqmp: fix lockstep mode memory region
In lockstep mode, r5 core0 uses TCM of R5 core1. Following is lockstep mode memory region as per hardware reference manual. | *TCM* | *R5 View* | *Linux view* | | R5_0 ATCM (128 KB) | 0x0000_0000 | 0xFFE0_0000 | | R5_0 BTCM (128 KB) | 0x0002_0000 | 0xFFE2_0000 | However, driver shouldn't model it as above because R5 core0 TCM and core1 TCM has different power-domains mapped to it. Hence, TCM address space in lockstep mode should be modeled as 64KB regions only where each region has its own power-domain as following: | *TCM* | *R5 View* | *Linux view* | | R5_0 ATCM0 (64 KB) | 0x0000_0000 | 0xFFE0_0000 | | R5_0 BTCM0 (64 KB) | 0x0002_0000 | 0xFFE2_0000 | | R5_0 ATCM1 (64 KB) | 0x0001_0000 | 0xFFE1_0000 | | R5_0 BTCM1 (64 KB) | 0x0003_0000 | 0xFFE3_0000 | This makes driver maintanance easy and makes design robust for future platorms as well. Signed-off-by: Tanmay Shah <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Mathieu Poirier <[email protected]>
1 parent fec2601 commit b31bcda

File tree

1 file changed

+12
-134
lines changed

1 file changed

+12
-134
lines changed

drivers/remoteproc/xlnx_r5_remoteproc.c

Lines changed: 12 additions & 134 deletions
Original file line numberDiff line numberDiff line change
@@ -84,12 +84,12 @@ static const struct mem_bank_data zynqmp_tcm_banks_split[] = {
8484
{0xffeb0000UL, 0x20000, 0x10000UL, PD_R5_1_BTCM, "btcm1"},
8585
};
8686

87-
/* In lockstep mode cluster combines each 64KB TCM and makes 128KB TCM */
87+
/* In lockstep mode cluster uses each 64KB TCM from second core as well */
8888
static const struct mem_bank_data zynqmp_tcm_banks_lockstep[] = {
89-
{0xffe00000UL, 0x0, 0x20000UL, PD_R5_0_ATCM, "atcm0"}, /* TCM 128KB each */
90-
{0xffe20000UL, 0x20000, 0x20000UL, PD_R5_0_BTCM, "btcm0"},
91-
{0, 0, 0, PD_R5_1_ATCM, ""},
92-
{0, 0, 0, PD_R5_1_BTCM, ""},
89+
{0xffe00000UL, 0x0, 0x10000UL, PD_R5_0_ATCM, "atcm0"}, /* TCM 64KB each */
90+
{0xffe20000UL, 0x20000, 0x10000UL, PD_R5_0_BTCM, "btcm0"},
91+
{0xffe10000UL, 0x10000, 0x10000UL, PD_R5_1_ATCM, "atcm1"},
92+
{0xffe30000UL, 0x30000, 0x10000UL, PD_R5_1_BTCM, "btcm1"},
9393
};
9494

9595
/**
@@ -541,14 +541,14 @@ static int tcm_mem_map(struct rproc *rproc,
541541
}
542542

543543
/*
544-
* add_tcm_carveout_split_mode()
544+
* add_tcm_banks()
545545
* @rproc: single R5 core's corresponding rproc instance
546546
*
547-
* allocate and add remoteproc carveout for TCM memory in split mode
547+
* allocate and add remoteproc carveout for TCM memory
548548
*
549549
* return 0 on success, otherwise non-zero value on failure
550550
*/
551-
static int add_tcm_carveout_split_mode(struct rproc *rproc)
551+
static int add_tcm_banks(struct rproc *rproc)
552552
{
553553
struct rproc_mem_entry *rproc_mem;
554554
struct zynqmp_r5_core *r5_core;
@@ -581,10 +581,10 @@ static int add_tcm_carveout_split_mode(struct rproc *rproc)
581581
ZYNQMP_PM_REQUEST_ACK_BLOCKING);
582582
if (ret < 0) {
583583
dev_err(dev, "failed to turn on TCM 0x%x", pm_domain_id);
584-
goto release_tcm_split;
584+
goto release_tcm;
585585
}
586586

587-
dev_dbg(dev, "TCM carveout split mode %s addr=%llx, da=0x%x, size=0x%lx",
587+
dev_dbg(dev, "TCM carveout %s addr=%llx, da=0x%x, size=0x%lx",
588588
bank_name, bank_addr, da, bank_size);
589589

590590
rproc_mem = rproc_mem_entry_init(dev, NULL, bank_addr,
@@ -594,99 +594,16 @@ static int add_tcm_carveout_split_mode(struct rproc *rproc)
594594
if (!rproc_mem) {
595595
ret = -ENOMEM;
596596
zynqmp_pm_release_node(pm_domain_id);
597-
goto release_tcm_split;
598-
}
599-
600-
rproc_add_carveout(rproc, rproc_mem);
601-
rproc_coredump_add_segment(rproc, da, bank_size);
602-
}
603-
604-
return 0;
605-
606-
release_tcm_split:
607-
/* If failed, Turn off all TCM banks turned on before */
608-
for (i--; i >= 0; i--) {
609-
pm_domain_id = r5_core->tcm_banks[i]->pm_domain_id;
610-
zynqmp_pm_release_node(pm_domain_id);
611-
}
612-
return ret;
613-
}
614-
615-
/*
616-
* add_tcm_carveout_lockstep_mode()
617-
* @rproc: single R5 core's corresponding rproc instance
618-
*
619-
* allocate and add remoteproc carveout for TCM memory in lockstep mode
620-
*
621-
* return 0 on success, otherwise non-zero value on failure
622-
*/
623-
static int add_tcm_carveout_lockstep_mode(struct rproc *rproc)
624-
{
625-
struct rproc_mem_entry *rproc_mem;
626-
struct zynqmp_r5_core *r5_core;
627-
int i, num_banks, ret;
628-
phys_addr_t bank_addr;
629-
size_t bank_size = 0;
630-
struct device *dev;
631-
u32 pm_domain_id;
632-
char *bank_name;
633-
u32 da;
634-
635-
r5_core = rproc->priv;
636-
dev = r5_core->dev;
637-
638-
/* Go through zynqmp banks for r5 node */
639-
num_banks = r5_core->tcm_bank_count;
640-
641-
/*
642-
* In lockstep mode, TCM is contiguous memory block
643-
* However, each TCM block still needs to be enabled individually.
644-
* So, Enable each TCM block individually.
645-
* Although ATCM and BTCM is contiguous memory block, add two separate
646-
* carveouts for both.
647-
*/
648-
for (i = 0; i < num_banks; i++) {
649-
pm_domain_id = r5_core->tcm_banks[i]->pm_domain_id;
650-
651-
/* Turn on each TCM bank individually */
652-
ret = zynqmp_pm_request_node(pm_domain_id,
653-
ZYNQMP_PM_CAPABILITY_ACCESS, 0,
654-
ZYNQMP_PM_REQUEST_ACK_BLOCKING);
655-
if (ret < 0) {
656-
dev_err(dev, "failed to turn on TCM 0x%x", pm_domain_id);
657-
goto release_tcm_lockstep;
658-
}
659-
660-
bank_size = r5_core->tcm_banks[i]->size;
661-
if (bank_size == 0)
662-
continue;
663-
664-
bank_addr = r5_core->tcm_banks[i]->addr;
665-
da = r5_core->tcm_banks[i]->da;
666-
bank_name = r5_core->tcm_banks[i]->bank_name;
667-
668-
/* Register TCM address range, TCM map and unmap functions */
669-
rproc_mem = rproc_mem_entry_init(dev, NULL, bank_addr,
670-
bank_size, da,
671-
tcm_mem_map, tcm_mem_unmap,
672-
bank_name);
673-
if (!rproc_mem) {
674-
ret = -ENOMEM;
675-
zynqmp_pm_release_node(pm_domain_id);
676-
goto release_tcm_lockstep;
597+
goto release_tcm;
677598
}
678599

679-
/* If registration is success, add carveouts */
680600
rproc_add_carveout(rproc, rproc_mem);
681601
rproc_coredump_add_segment(rproc, da, bank_size);
682-
683-
dev_dbg(dev, "TCM carveout lockstep mode %s addr=0x%llx, da=0x%x, size=0x%lx",
684-
bank_name, bank_addr, da, bank_size);
685602
}
686603

687604
return 0;
688605

689-
release_tcm_lockstep:
606+
release_tcm:
690607
/* If failed, Turn off all TCM banks turned on before */
691608
for (i--; i >= 0; i--) {
692609
pm_domain_id = r5_core->tcm_banks[i]->pm_domain_id;
@@ -695,45 +612,6 @@ static int add_tcm_carveout_lockstep_mode(struct rproc *rproc)
695612
return ret;
696613
}
697614

698-
/*
699-
* add_tcm_banks()
700-
* @rproc: single R5 core's corresponding rproc instance
701-
*
702-
* allocate and add remoteproc carveouts for TCM memory based on cluster mode
703-
*
704-
* return 0 on success, otherwise non-zero value on failure
705-
*/
706-
static int add_tcm_banks(struct rproc *rproc)
707-
{
708-
struct zynqmp_r5_cluster *cluster;
709-
struct zynqmp_r5_core *r5_core;
710-
struct device *dev;
711-
712-
r5_core = rproc->priv;
713-
if (!r5_core)
714-
return -EINVAL;
715-
716-
dev = r5_core->dev;
717-
718-
cluster = dev_get_drvdata(dev->parent);
719-
if (!cluster) {
720-
dev_err(dev->parent, "Invalid driver data\n");
721-
return -EINVAL;
722-
}
723-
724-
/*
725-
* In lockstep mode TCM banks are one contiguous memory region of 256Kb
726-
* In split mode, each TCM bank is 64Kb and not contiguous.
727-
* We add memory carveouts accordingly.
728-
*/
729-
if (cluster->mode == SPLIT_MODE)
730-
return add_tcm_carveout_split_mode(rproc);
731-
else if (cluster->mode == LOCKSTEP_MODE)
732-
return add_tcm_carveout_lockstep_mode(rproc);
733-
734-
return -EINVAL;
735-
}
736-
737615
/*
738616
* zynqmp_r5_parse_fw()
739617
* @rproc: single R5 core's corresponding rproc instance

0 commit comments

Comments
 (0)