Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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 <tanmay.shah@amd.com>
Link: https://lore.kernel.org/r/20240412183708.4036007-2-tanmay.shah@amd.com
Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>

authored by

Tanmay Shah and committed by
Mathieu Poirier
b31bcda5 fec2601f

+12 -134
+12 -134
drivers/remoteproc/xlnx_r5_remoteproc.c
··· 84 84 {0xffeb0000UL, 0x20000, 0x10000UL, PD_R5_1_BTCM, "btcm1"}, 85 85 }; 86 86 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 */ 88 88 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"}, 93 93 }; 94 94 95 95 /** ··· 541 541 } 542 542 543 543 /* 544 - * add_tcm_carveout_split_mode() 544 + * add_tcm_banks() 545 545 * @rproc: single R5 core's corresponding rproc instance 546 546 * 547 - * allocate and add remoteproc carveout for TCM memory in split mode 547 + * allocate and add remoteproc carveout for TCM memory 548 548 * 549 549 * return 0 on success, otherwise non-zero value on failure 550 550 */ 551 - static int add_tcm_carveout_split_mode(struct rproc *rproc) 551 + static int add_tcm_banks(struct rproc *rproc) 552 552 { 553 553 struct rproc_mem_entry *rproc_mem; 554 554 struct zynqmp_r5_core *r5_core; ··· 581 581 ZYNQMP_PM_REQUEST_ACK_BLOCKING); 582 582 if (ret < 0) { 583 583 dev_err(dev, "failed to turn on TCM 0x%x", pm_domain_id); 584 - goto release_tcm_split; 584 + goto release_tcm; 585 585 } 586 586 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", 588 588 bank_name, bank_addr, da, bank_size); 589 589 590 590 rproc_mem = rproc_mem_entry_init(dev, NULL, bank_addr, ··· 594 594 if (!rproc_mem) { 595 595 ret = -ENOMEM; 596 596 zynqmp_pm_release_node(pm_domain_id); 597 - goto release_tcm_split; 597 + goto release_tcm; 598 598 } 599 599 600 600 rproc_add_carveout(rproc, rproc_mem); ··· 603 603 604 604 return 0; 605 605 606 - release_tcm_split: 606 + release_tcm: 607 607 /* If failed, Turn off all TCM banks turned on before */ 608 608 for (i--; i >= 0; i--) { 609 609 pm_domain_id = r5_core->tcm_banks[i]->pm_domain_id; 610 610 zynqmp_pm_release_node(pm_domain_id); 611 611 } 612 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; 677 - } 678 - 679 - /* If registration is success, add carveouts */ 680 - rproc_add_carveout(rproc, rproc_mem); 681 - 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); 685 - } 686 - 687 - return 0; 688 - 689 - release_tcm_lockstep: 690 - /* If failed, Turn off all TCM banks turned on before */ 691 - for (i--; i >= 0; i--) { 692 - pm_domain_id = r5_core->tcm_banks[i]->pm_domain_id; 693 - zynqmp_pm_release_node(pm_domain_id); 694 - } 695 - return ret; 696 - } 697 - 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 613 } 736 614 737 615 /*