From ab2eb455d64d4813da8eb72276e5fa1868e84233 Mon Sep 17 00:00:00 2001 From: Puneet Saxena Date: Fri, 4 Aug 2017 17:19:55 +0530 Subject: [PATCH 01/27] Tegra: memctrl_v2: platform handlers to program MSS Introduce platform handlers to program the MSS settings. This allows the current driver to scale to future chips. Change-Id: I40a27648a1a3c73b1ce38dafddc1babb6f0b0d9b Signed-off-by: Puneet Saxena Signed-off-by: Krishna Reddy --- .../tegra/common/drivers/memctrl/memctrl_v2.c | 332 +---------------- .../nvidia/tegra/include/drivers/memctrl_v2.h | 337 ++---------------- plat/nvidia/tegra/include/t186/tegra_mc_def.h | 285 +++++++++++++++ plat/nvidia/tegra/soc/t186/plat_memctrl.c | 319 ++++++++++++++++- plat/nvidia/tegra/soc/t186/plat_smmu.c | 1 + 5 files changed, 658 insertions(+), 616 deletions(-) create mode 100644 plat/nvidia/tegra/include/t186/tegra_mc_def.h diff --git a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c index 1b221c2f6..b1ccf5073 100644 --- a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c +++ b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c @@ -25,318 +25,6 @@ static uint64_t video_mem_base; static uint64_t video_mem_size_mb; -static void tegra_memctrl_reconfig_mss_clients(void) -{ -#if ENABLE_ROC_FOR_ORDERING_CLIENT_REQUESTS - uint32_t val, wdata_0, wdata_1; - - /* - * Assert Memory Controller's HOTRESET_FLUSH_ENABLE signal for - * boot and strongly ordered MSS clients to flush existing memory - * traffic and stall future requests. - */ - val = tegra_mc_read_32(MC_CLIENT_HOTRESET_CTRL0); - assert(val == MC_CLIENT_HOTRESET_CTRL0_RESET_VAL); - - wdata_0 = MC_CLIENT_HOTRESET_CTRL0_HDA_FLUSH_ENB | -#if ENABLE_AFI_DEVICE - MC_CLIENT_HOTRESET_CTRL0_AFI_FLUSH_ENB | -#endif - MC_CLIENT_HOTRESET_CTRL0_SATA_FLUSH_ENB | - MC_CLIENT_HOTRESET_CTRL0_XUSB_HOST_FLUSH_ENB | - MC_CLIENT_HOTRESET_CTRL0_XUSB_DEV_FLUSH_ENB; - tegra_mc_write_32(MC_CLIENT_HOTRESET_CTRL0, wdata_0); - - /* Wait for HOTRESET STATUS to indicate FLUSH_DONE */ - do { - val = tegra_mc_read_32(MC_CLIENT_HOTRESET_STATUS0); - } while ((val & wdata_0) != wdata_0); - - /* Wait one more time due to SW WAR for known legacy issue */ - do { - val = tegra_mc_read_32(MC_CLIENT_HOTRESET_STATUS0); - } while ((val & wdata_0) != wdata_0); - - val = tegra_mc_read_32(MC_CLIENT_HOTRESET_CTRL1); - assert(val == MC_CLIENT_HOTRESET_CTRL1_RESET_VAL); - - wdata_1 = MC_CLIENT_HOTRESET_CTRL1_SDMMC4A_FLUSH_ENB | - MC_CLIENT_HOTRESET_CTRL1_APE_FLUSH_ENB | - MC_CLIENT_HOTRESET_CTRL1_SE_FLUSH_ENB | - MC_CLIENT_HOTRESET_CTRL1_ETR_FLUSH_ENB | - MC_CLIENT_HOTRESET_CTRL1_AXIS_FLUSH_ENB | - MC_CLIENT_HOTRESET_CTRL1_EQOS_FLUSH_ENB | - MC_CLIENT_HOTRESET_CTRL1_UFSHC_FLUSH_ENB | - MC_CLIENT_HOTRESET_CTRL1_BPMP_FLUSH_ENB | - MC_CLIENT_HOTRESET_CTRL1_AON_FLUSH_ENB | - MC_CLIENT_HOTRESET_CTRL1_SCE_FLUSH_ENB; - tegra_mc_write_32(MC_CLIENT_HOTRESET_CTRL1, wdata_1); - - /* Wait for HOTRESET STATUS to indicate FLUSH_DONE */ - do { - val = tegra_mc_read_32(MC_CLIENT_HOTRESET_STATUS1); - } while ((val & wdata_1) != wdata_1); - - /* Wait one more time due to SW WAR for known legacy issue */ - do { - val = tegra_mc_read_32(MC_CLIENT_HOTRESET_STATUS1); - } while ((val & wdata_1) != wdata_1); - - /* - * Change MEMTYPE_OVERRIDE from SO_DEV -> PASSTHRU for boot and - * strongly ordered MSS clients. ROC needs to be single point - * of control on overriding the memory type. So, remove TSA's - * memtype override. - * - * MC clients with default SO_DEV override still enabled at TSA: - * AONW, BPMPW, SCEW, APEW - */ -#if ENABLE_AFI_DEVICE - mc_set_tsa_passthrough(AFIW); -#endif - mc_set_tsa_passthrough(HDAW); - mc_set_tsa_passthrough(SATAW); - mc_set_tsa_passthrough(XUSB_HOSTW); - mc_set_tsa_passthrough(XUSB_DEVW); - mc_set_tsa_passthrough(SDMMCWAB); - mc_set_tsa_passthrough(APEDMAW); - mc_set_tsa_passthrough(SESWR); - mc_set_tsa_passthrough(ETRW); - mc_set_tsa_passthrough(AXISW); - mc_set_tsa_passthrough(EQOSW); - mc_set_tsa_passthrough(UFSHCW); - mc_set_tsa_passthrough(BPMPDMAW); - mc_set_tsa_passthrough(AONDMAW); - mc_set_tsa_passthrough(SCEDMAW); - - /* Parker has no IO Coherency support and need the following: - * Ordered MC Clients on Parker are AFI, EQOS, SATA, XUSB. - * ISO clients(DISP, VI, EQOS) should never snoop caches and - * don't need ROC/PCFIFO ordering. - * ISO clients(EQOS) that need ordering should use PCFIFO ordering - * and bypass ROC ordering by using FORCE_NON_COHERENT path. - * FORCE_NON_COHERENT/FORCE_COHERENT config take precedence - * over SMMU attributes. - * Force all Normal memory transactions from ISO and non-ISO to be - * non-coherent(bypass ROC, avoid cache snoop to avoid perf hit). - * Force the SO_DEV transactions from ordered ISO clients(EQOS) to - * non-coherent path and enable MC PCFIFO interlock for ordering. - * Force the SO_DEV transactions from ordered non-ISO clients (PCIe, - * XUSB, SATA) to coherent so that the transactions are - * ordered by ROC. - * PCFIFO ensure write ordering. - * Read after Write ordering is maintained/enforced by MC clients. - * Clients that need PCIe type write ordering must - * go through ROC ordering. - * Ordering enable for Read clients is not necessary. - * R5's and A9 would get necessary ordering from AXI and - * don't need ROC ordering enable: - * - MMIO ordering is through dev mapping and MMIO - * accesses bypass SMMU. - * - Normal memory is accessed through SMMU and ordering is - * ensured by client and AXI. - * - Ack point for Normal memory is WCAM in MC. - * - MMIO's can be early acked and AXI ensures dev memory ordering, - * Client ensures read/write direction change ordering. - * - See Bug 200312466 for more details. - * - * CGID_TAG_ADR is only present from T186 A02. As this code is common - * between A01 and A02, tegra_memctrl_set_overrides() programs - * CGID_TAG_ADR for the necessary clients on A02. - */ - mc_set_txn_override(HDAR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - mc_set_txn_override(BPMPW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - mc_set_txn_override(PTCR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - mc_set_txn_override(NVDISPLAYR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - mc_set_txn_override(EQOSW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - mc_set_txn_override(NVJPGSWR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - mc_set_txn_override(ISPRA, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - mc_set_txn_override(SDMMCWAA, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - mc_set_txn_override(VICSRD, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - mc_set_txn_override(MPCOREW, CGID_TAG_DEFAULT, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE); - mc_set_txn_override(GPUSRD, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - mc_set_txn_override(AXISR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - mc_set_txn_override(SCEDMAW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - mc_set_txn_override(SDMMCW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - mc_set_txn_override(EQOSR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - /* See bug 200131110 comment #35*/ - mc_set_txn_override(APEDMAR, CGID_TAG_CLIENT_AXI_ID, SO_DEV_CLIENT_AXI_ID, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - mc_set_txn_override(NVENCSRD, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - mc_set_txn_override(SDMMCRAB, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - mc_set_txn_override(VICSRD1, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - mc_set_txn_override(BPMPDMAR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - mc_set_txn_override(VIW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - mc_set_txn_override(SDMMCRAA, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - mc_set_txn_override(AXISW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - mc_set_txn_override(XUSB_DEVR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - mc_set_txn_override(UFSHCR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - mc_set_txn_override(TSECSWR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - mc_set_txn_override(GPUSWR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - mc_set_txn_override(SATAR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - mc_set_txn_override(XUSB_HOSTW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_COHERENT); - mc_set_txn_override(TSECSWRB, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - mc_set_txn_override(GPUSRD2, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - mc_set_txn_override(SCEDMAR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - mc_set_txn_override(GPUSWR2, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - mc_set_txn_override(AONDMAW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - /* See bug 200131110 comment #35*/ - mc_set_txn_override(APEDMAW, CGID_TAG_CLIENT_AXI_ID, SO_DEV_CLIENT_AXI_ID, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - mc_set_txn_override(AONW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - mc_set_txn_override(HOST1XDMAR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - mc_set_txn_override(ETRR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - mc_set_txn_override(SESWR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - mc_set_txn_override(NVJPGSRD, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - mc_set_txn_override(NVDECSRD, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - mc_set_txn_override(TSECSRDB, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - mc_set_txn_override(BPMPDMAW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - mc_set_txn_override(APER, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - mc_set_txn_override(NVDECSRD1, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - mc_set_txn_override(XUSB_HOSTR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - mc_set_txn_override(ISPWA, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - mc_set_txn_override(SESRD, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - mc_set_txn_override(SCER, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - mc_set_txn_override(AONR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - mc_set_txn_override(MPCORER, CGID_TAG_DEFAULT, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE); - mc_set_txn_override(SDMMCWA, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - mc_set_txn_override(HDAW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - mc_set_txn_override(NVDECSWR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - mc_set_txn_override(UFSHCW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - mc_set_txn_override(AONDMAR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - mc_set_txn_override(SATAW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_COHERENT); - mc_set_txn_override(ETRW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - mc_set_txn_override(VICSWR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - mc_set_txn_override(NVENCSWR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - /* See bug 200131110 comment #35 */ - mc_set_txn_override(AFIR, CGID_TAG_DEFAULT, SO_DEV_CLIENT_AXI_ID, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - mc_set_txn_override(SDMMCWAB, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - mc_set_txn_override(SDMMCRA, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - mc_set_txn_override(NVDISPLAYR1, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - mc_set_txn_override(ISPWB, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - mc_set_txn_override(BPMPR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - mc_set_txn_override(APEW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - mc_set_txn_override(SDMMCR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - mc_set_txn_override(XUSB_DEVW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_COHERENT); - mc_set_txn_override(TSECSRD, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - /* - * See bug 200131110 comment #35 - there are no normal requests - * and AWID for SO/DEV requests is hardcoded in RTL for a - * particular PCIE controller - */ - mc_set_txn_override(AFIW, CGID_TAG_DEFAULT, SO_DEV_CLIENT_AXI_ID, FORCE_NON_COHERENT, FORCE_COHERENT); - mc_set_txn_override(SCEW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); - - /* - * At this point, ordering can occur at ROC. So, remove PCFIFO's - * control over ordering requests. - * - * Change PCFIFO_*_ORDERED_CLIENT from ORDERED -> UNORDERED for - * boot and strongly ordered MSS clients - */ - val = MC_PCFIFO_CLIENT_CONFIG1_RESET_VAL & -#if ENABLE_AFI_DEVICE - mc_set_pcfifo_unordered_boot_so_mss(1, AFIW) & -#endif - mc_set_pcfifo_unordered_boot_so_mss(1, HDAW) & - mc_set_pcfifo_unordered_boot_so_mss(1, SATAW); - tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG1, val); - - val = MC_PCFIFO_CLIENT_CONFIG2_RESET_VAL & - mc_set_pcfifo_unordered_boot_so_mss(2, XUSB_HOSTW) & - mc_set_pcfifo_unordered_boot_so_mss(2, XUSB_DEVW); - tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG2, val); - - val = MC_PCFIFO_CLIENT_CONFIG3_RESET_VAL & - mc_set_pcfifo_unordered_boot_so_mss(3, SDMMCWAB); - tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG3, val); - - val = MC_PCFIFO_CLIENT_CONFIG4_RESET_VAL & - mc_set_pcfifo_unordered_boot_so_mss(4, SESWR) & - mc_set_pcfifo_unordered_boot_so_mss(4, ETRW) & - mc_set_pcfifo_unordered_boot_so_mss(4, AXISW) & - mc_set_pcfifo_unordered_boot_so_mss(4, UFSHCW) & - mc_set_pcfifo_unordered_boot_so_mss(4, BPMPDMAW) & - mc_set_pcfifo_unordered_boot_so_mss(4, AONDMAW) & - mc_set_pcfifo_unordered_boot_so_mss(4, SCEDMAW); - /* EQOSW is the only client that has PCFIFO order enabled. */ - val |= mc_set_pcfifo_ordered_boot_so_mss(4, EQOSW); - tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG4, val); - - val = MC_PCFIFO_CLIENT_CONFIG5_RESET_VAL & - mc_set_pcfifo_unordered_boot_so_mss(5, APEDMAW); - tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG5, val); - - /* - * Deassert HOTRESET FLUSH_ENABLE for boot and strongly ordered MSS - * clients to allow memory traffic from all clients to start passing - * through ROC - */ - val = tegra_mc_read_32(MC_CLIENT_HOTRESET_CTRL0); - assert(val == wdata_0); - - wdata_0 = MC_CLIENT_HOTRESET_CTRL0_RESET_VAL; - tegra_mc_write_32(MC_CLIENT_HOTRESET_CTRL0, wdata_0); - - val = tegra_mc_read_32(MC_CLIENT_HOTRESET_CTRL1); - assert(val == wdata_1); - - wdata_1 = MC_CLIENT_HOTRESET_CTRL1_RESET_VAL; - tegra_mc_write_32(MC_CLIENT_HOTRESET_CTRL1, wdata_1); - -#endif -} - -static void tegra_memctrl_set_overrides(void) -{ - const tegra_mc_settings_t *plat_mc_settings = tegra_get_mc_settings(); - const mc_txn_override_cfg_t *mc_txn_override_cfgs; - uint32_t num_txn_override_cfgs; - uint32_t i, val; - - /* Get the settings from the platform */ - assert(plat_mc_settings != NULL); - mc_txn_override_cfgs = plat_mc_settings->txn_override_cfg; - num_txn_override_cfgs = plat_mc_settings->num_txn_override_cfgs; - - /* - * Set the MC_TXN_OVERRIDE registers for write clients. - */ - if ((tegra_chipid_is_t186()) && - (!tegra_platform_is_silicon() || - (tegra_platform_is_silicon() && (tegra_get_chipid_minor() == 1U)))) { - - /* - * GPU and NVENC settings for Tegra186 simulation and - * Silicon rev. A01 - */ - val = tegra_mc_read_32(MC_TXN_OVERRIDE_CONFIG_GPUSWR); - val &= (uint32_t)~MC_TXN_OVERRIDE_CGID_TAG_MASK; - tegra_mc_write_32(MC_TXN_OVERRIDE_CONFIG_GPUSWR, - val | MC_TXN_OVERRIDE_CGID_TAG_ZERO); - - val = tegra_mc_read_32(MC_TXN_OVERRIDE_CONFIG_GPUSWR2); - val &= (uint32_t)~MC_TXN_OVERRIDE_CGID_TAG_MASK; - tegra_mc_write_32(MC_TXN_OVERRIDE_CONFIG_GPUSWR2, - val | MC_TXN_OVERRIDE_CGID_TAG_ZERO); - - val = tegra_mc_read_32(MC_TXN_OVERRIDE_CONFIG_NVENCSWR); - val &= (uint32_t)~MC_TXN_OVERRIDE_CGID_TAG_MASK; - tegra_mc_write_32(MC_TXN_OVERRIDE_CONFIG_NVENCSWR, - val | MC_TXN_OVERRIDE_CGID_TAG_CLIENT_AXI_ID); - - } else { - - /* - * Settings for Tegra186 silicon rev. A02 and onwards. - */ - for (i = 0; i < num_txn_override_cfgs; i++) { - val = tegra_mc_read_32(mc_txn_override_cfgs[i].offset); - val &= (uint32_t)~MC_TXN_OVERRIDE_CGID_TAG_MASK; - tegra_mc_write_32(mc_txn_override_cfgs[i].offset, - val | mc_txn_override_cfgs[i].cgid_tag); - } - } -} - /* * Init Memory controller during boot. */ @@ -398,10 +86,14 @@ void tegra_memctrl_setup(void) * boots with MSS having all control, but ROC provides a performance * boost as compared to MSS. */ - tegra_memctrl_reconfig_mss_clients(); + if (plat_mc_settings->reconfig_mss_clients != NULL) { + plat_mc_settings->reconfig_mss_clients(); + } /* Program overrides for MC transactions */ - tegra_memctrl_set_overrides(); + if (plat_mc_settings->set_txn_overrides != NULL) { + plat_mc_settings->set_txn_overrides(); + } } /* @@ -409,16 +101,24 @@ void tegra_memctrl_setup(void) */ void tegra_memctrl_restore_settings(void) { + const tegra_mc_settings_t *plat_mc_settings = tegra_get_mc_settings(); + + assert(plat_mc_settings != NULL); + /* * Re-configure MSS to allow ROC to deal with ordering of the * Memory Controller traffic. This is needed as the Memory Controller * resets during System Suspend with MSS having all control, but ROC * provides a performance boost as compared to MSS. */ - tegra_memctrl_reconfig_mss_clients(); + if (plat_mc_settings->reconfig_mss_clients != NULL) { + plat_mc_settings->reconfig_mss_clients(); + } /* Program overrides for MC transactions */ - tegra_memctrl_set_overrides(); + if (plat_mc_settings->set_txn_overrides != NULL) { + plat_mc_settings->set_txn_overrides(); + } /* video memory carveout region */ if (video_mem_base != 0ULL) { diff --git a/plat/nvidia/tegra/include/drivers/memctrl_v2.h b/plat/nvidia/tegra/include/drivers/memctrl_v2.h index 7eb29529a..22f05f487 100644 --- a/plat/nvidia/tegra/include/drivers/memctrl_v2.h +++ b/plat/nvidia/tegra/include/drivers/memctrl_v2.h @@ -11,184 +11,9 @@ #ifndef __ASSEMBLY__ +#include #include -/******************************************************************************* - * StreamID to indicate no SMMU translations (requests to be steered on the - * SMMU bypass path) - ******************************************************************************/ -#define MC_STREAM_ID_MAX 0x7FU - -/******************************************************************************* - * Stream ID Override Config registers - ******************************************************************************/ -#define MC_STREAMID_OVERRIDE_CFG_PTCR 0x000U -#define MC_STREAMID_OVERRIDE_CFG_AFIR 0x070U -#define MC_STREAMID_OVERRIDE_CFG_HDAR 0x0A8U -#define MC_STREAMID_OVERRIDE_CFG_HOST1XDMAR 0x0B0U -#define MC_STREAMID_OVERRIDE_CFG_NVENCSRD 0x0E0U -#define MC_STREAMID_OVERRIDE_CFG_SATAR 0x0F8U -#define MC_STREAMID_OVERRIDE_CFG_MPCORER 0x138U -#define MC_STREAMID_OVERRIDE_CFG_NVENCSWR 0x158U -#define MC_STREAMID_OVERRIDE_CFG_AFIW 0x188U -#define MC_STREAMID_OVERRIDE_CFG_HDAW 0x1A8U -#define MC_STREAMID_OVERRIDE_CFG_MPCOREW 0x1C8U -#define MC_STREAMID_OVERRIDE_CFG_SATAW 0x1E8U -#define MC_STREAMID_OVERRIDE_CFG_ISPRA 0x220U -#define MC_STREAMID_OVERRIDE_CFG_ISPWA 0x230U -#define MC_STREAMID_OVERRIDE_CFG_ISPWB 0x238U -#define MC_STREAMID_OVERRIDE_CFG_XUSB_HOSTR 0x250U -#define MC_STREAMID_OVERRIDE_CFG_XUSB_HOSTW 0x258U -#define MC_STREAMID_OVERRIDE_CFG_XUSB_DEVR 0x260U -#define MC_STREAMID_OVERRIDE_CFG_XUSB_DEVW 0x268U -#define MC_STREAMID_OVERRIDE_CFG_TSECSRD 0x2A0U -#define MC_STREAMID_OVERRIDE_CFG_TSECSWR 0x2A8U -#define MC_STREAMID_OVERRIDE_CFG_GPUSRD 0x2C0U -#define MC_STREAMID_OVERRIDE_CFG_GPUSWR 0x2C8U -#define MC_STREAMID_OVERRIDE_CFG_SDMMCRA 0x300U -#define MC_STREAMID_OVERRIDE_CFG_SDMMCRAA 0x308U -#define MC_STREAMID_OVERRIDE_CFG_SDMMCR 0x310U -#define MC_STREAMID_OVERRIDE_CFG_SDMMCRAB 0x318U -#define MC_STREAMID_OVERRIDE_CFG_SDMMCWA 0x320U -#define MC_STREAMID_OVERRIDE_CFG_SDMMCWAA 0x328U -#define MC_STREAMID_OVERRIDE_CFG_SDMMCW 0x330U -#define MC_STREAMID_OVERRIDE_CFG_SDMMCWAB 0x338U -#define MC_STREAMID_OVERRIDE_CFG_VICSRD 0x360U -#define MC_STREAMID_OVERRIDE_CFG_VICSWR 0x368U -#define MC_STREAMID_OVERRIDE_CFG_VIW 0x390U -#define MC_STREAMID_OVERRIDE_CFG_NVDECSRD 0x3C0U -#define MC_STREAMID_OVERRIDE_CFG_NVDECSWR 0x3C8U -#define MC_STREAMID_OVERRIDE_CFG_APER 0x3D0U -#define MC_STREAMID_OVERRIDE_CFG_APEW 0x3D8U -#define MC_STREAMID_OVERRIDE_CFG_NVJPGSRD 0x3F0U -#define MC_STREAMID_OVERRIDE_CFG_NVJPGSWR 0x3F8U -#define MC_STREAMID_OVERRIDE_CFG_SESRD 0x400U -#define MC_STREAMID_OVERRIDE_CFG_SESWR 0x408U -#define MC_STREAMID_OVERRIDE_CFG_ETRR 0x420U -#define MC_STREAMID_OVERRIDE_CFG_ETRW 0x428U -#define MC_STREAMID_OVERRIDE_CFG_TSECSRDB 0x430U -#define MC_STREAMID_OVERRIDE_CFG_TSECSWRB 0x438U -#define MC_STREAMID_OVERRIDE_CFG_GPUSRD2 0x440U -#define MC_STREAMID_OVERRIDE_CFG_GPUSWR2 0x448U -#define MC_STREAMID_OVERRIDE_CFG_AXISR 0x460U -#define MC_STREAMID_OVERRIDE_CFG_AXISW 0x468U -#define MC_STREAMID_OVERRIDE_CFG_EQOSR 0x470U -#define MC_STREAMID_OVERRIDE_CFG_EQOSW 0x478U -#define MC_STREAMID_OVERRIDE_CFG_UFSHCR 0x480U -#define MC_STREAMID_OVERRIDE_CFG_UFSHCW 0x488U -#define MC_STREAMID_OVERRIDE_CFG_NVDISPLAYR 0x490U -#define MC_STREAMID_OVERRIDE_CFG_BPMPR 0x498U -#define MC_STREAMID_OVERRIDE_CFG_BPMPW 0x4A0U -#define MC_STREAMID_OVERRIDE_CFG_BPMPDMAR 0x4A8U -#define MC_STREAMID_OVERRIDE_CFG_BPMPDMAW 0x4B0U -#define MC_STREAMID_OVERRIDE_CFG_AONR 0x4B8U -#define MC_STREAMID_OVERRIDE_CFG_AONW 0x4C0U -#define MC_STREAMID_OVERRIDE_CFG_AONDMAR 0x4C8U -#define MC_STREAMID_OVERRIDE_CFG_AONDMAW 0x4D0U -#define MC_STREAMID_OVERRIDE_CFG_SCER 0x4D8U -#define MC_STREAMID_OVERRIDE_CFG_SCEW 0x4E0U -#define MC_STREAMID_OVERRIDE_CFG_SCEDMAR 0x4E8U -#define MC_STREAMID_OVERRIDE_CFG_SCEDMAW 0x4F0U -#define MC_STREAMID_OVERRIDE_CFG_APEDMAR 0x4F8U -#define MC_STREAMID_OVERRIDE_CFG_APEDMAW 0x500U -#define MC_STREAMID_OVERRIDE_CFG_NVDISPLAYR1 0x508U -#define MC_STREAMID_OVERRIDE_CFG_VICSRD1 0x510U -#define MC_STREAMID_OVERRIDE_CFG_NVDECSRD1 0x518U - -/******************************************************************************* - * Macro to calculate Security cfg register addr from StreamID Override register - ******************************************************************************/ -#define MC_STREAMID_OVERRIDE_TO_SECURITY_CFG(addr) ((addr) + (uint32_t)sizeof(uint32_t)) - -#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_NO_OVERRIDE_SO_DEV (0U << 4) -#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_NON_COHERENT_SO_DEV (1U << 4) -#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_COHERENT_SO_DEV (2U << 4) -#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_COHERENT_SNOOP_SO_DEV (3U << 4) - -#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_NO_OVERRIDE_NORMAL (0U << 8) -#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_NON_COHERENT_NORMAL (1U << 8) -#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_COHERENT_NORMAL (2U << 8) -#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_COHERENT_SNOOP_NORMAL (3U << 8) - -#define MC_TXN_OVERRIDE_CONFIG_CGID_SO_DEV_ZERO (0U << 12) -#define MC_TXN_OVERRIDE_CONFIG_CGID_SO_DEV_CLIENT_AXI_ID (1U << 12) - -/******************************************************************************* - * Memory Controller transaction override config registers - ******************************************************************************/ -#define MC_TXN_OVERRIDE_CONFIG_HDAR 0x10a8U -#define MC_TXN_OVERRIDE_CONFIG_BPMPW 0x14a0U -#define MC_TXN_OVERRIDE_CONFIG_PTCR 0x1000U -#define MC_TXN_OVERRIDE_CONFIG_NVDISPLAYR 0x1490U -#define MC_TXN_OVERRIDE_CONFIG_EQOSW 0x1478U -#define MC_TXN_OVERRIDE_CONFIG_NVJPGSWR 0x13f8U -#define MC_TXN_OVERRIDE_CONFIG_ISPRA 0x1220U -#define MC_TXN_OVERRIDE_CONFIG_SDMMCWAA 0x1328U -#define MC_TXN_OVERRIDE_CONFIG_VICSRD 0x1360U -#define MC_TXN_OVERRIDE_CONFIG_MPCOREW 0x11c8U -#define MC_TXN_OVERRIDE_CONFIG_GPUSRD 0x12c0U -#define MC_TXN_OVERRIDE_CONFIG_AXISR 0x1460U -#define MC_TXN_OVERRIDE_CONFIG_SCEDMAW 0x14f0U -#define MC_TXN_OVERRIDE_CONFIG_SDMMCW 0x1330U -#define MC_TXN_OVERRIDE_CONFIG_EQOSR 0x1470U -#define MC_TXN_OVERRIDE_CONFIG_APEDMAR 0x14f8U -#define MC_TXN_OVERRIDE_CONFIG_NVENCSRD 0x10e0U -#define MC_TXN_OVERRIDE_CONFIG_SDMMCRAB 0x1318U -#define MC_TXN_OVERRIDE_CONFIG_VICSRD1 0x1510U -#define MC_TXN_OVERRIDE_CONFIG_BPMPDMAR 0x14a8U -#define MC_TXN_OVERRIDE_CONFIG_VIW 0x1390U -#define MC_TXN_OVERRIDE_CONFIG_SDMMCRAA 0x1308U -#define MC_TXN_OVERRIDE_CONFIG_AXISW 0x1468U -#define MC_TXN_OVERRIDE_CONFIG_XUSB_DEVR 0x1260U -#define MC_TXN_OVERRIDE_CONFIG_UFSHCR 0x1480U -#define MC_TXN_OVERRIDE_CONFIG_TSECSWR 0x12a8U -#define MC_TXN_OVERRIDE_CONFIG_GPUSWR 0x12c8U -#define MC_TXN_OVERRIDE_CONFIG_SATAR 0x10f8U -#define MC_TXN_OVERRIDE_CONFIG_XUSB_HOSTW 0x1258U -#define MC_TXN_OVERRIDE_CONFIG_TSECSWRB 0x1438U -#define MC_TXN_OVERRIDE_CONFIG_GPUSRD2 0x1440U -#define MC_TXN_OVERRIDE_CONFIG_SCEDMAR 0x14e8U -#define MC_TXN_OVERRIDE_CONFIG_GPUSWR2 0x1448U -#define MC_TXN_OVERRIDE_CONFIG_AONDMAW 0x14d0U -#define MC_TXN_OVERRIDE_CONFIG_APEDMAW 0x1500U -#define MC_TXN_OVERRIDE_CONFIG_AONW 0x14c0U -#define MC_TXN_OVERRIDE_CONFIG_HOST1XDMAR 0x10b0U -#define MC_TXN_OVERRIDE_CONFIG_ETRR 0x1420U -#define MC_TXN_OVERRIDE_CONFIG_SESWR 0x1408U -#define MC_TXN_OVERRIDE_CONFIG_NVJPGSRD 0x13f0U -#define MC_TXN_OVERRIDE_CONFIG_NVDECSRD 0x13c0U -#define MC_TXN_OVERRIDE_CONFIG_TSECSRDB 0x1430U -#define MC_TXN_OVERRIDE_CONFIG_BPMPDMAW 0x14b0U -#define MC_TXN_OVERRIDE_CONFIG_APER 0x13d0U -#define MC_TXN_OVERRIDE_CONFIG_NVDECSRD1 0x1518U -#define MC_TXN_OVERRIDE_CONFIG_XUSB_HOSTR 0x1250U -#define MC_TXN_OVERRIDE_CONFIG_ISPWA 0x1230U -#define MC_TXN_OVERRIDE_CONFIG_SESRD 0x1400U -#define MC_TXN_OVERRIDE_CONFIG_SCER 0x14d8U -#define MC_TXN_OVERRIDE_CONFIG_AONR 0x14b8U -#define MC_TXN_OVERRIDE_CONFIG_MPCORER 0x1138U -#define MC_TXN_OVERRIDE_CONFIG_SDMMCWA 0x1320U -#define MC_TXN_OVERRIDE_CONFIG_HDAW 0x11a8U -#define MC_TXN_OVERRIDE_CONFIG_NVDECSWR 0x13c8U -#define MC_TXN_OVERRIDE_CONFIG_UFSHCW 0x1488U -#define MC_TXN_OVERRIDE_CONFIG_AONDMAR 0x14c8U -#define MC_TXN_OVERRIDE_CONFIG_SATAW 0x11e8U -#define MC_TXN_OVERRIDE_CONFIG_ETRW 0x1428U -#define MC_TXN_OVERRIDE_CONFIG_VICSWR 0x1368U -#define MC_TXN_OVERRIDE_CONFIG_NVENCSWR 0x1158U -#define MC_TXN_OVERRIDE_CONFIG_AFIR 0x1070U -#define MC_TXN_OVERRIDE_CONFIG_SDMMCWAB 0x1338U -#define MC_TXN_OVERRIDE_CONFIG_SDMMCRA 0x1300U -#define MC_TXN_OVERRIDE_CONFIG_NVDISPLAYR1 0x1508U -#define MC_TXN_OVERRIDE_CONFIG_ISPWB 0x1238U -#define MC_TXN_OVERRIDE_CONFIG_BPMPR 0x1498U -#define MC_TXN_OVERRIDE_CONFIG_APEW 0x13d8U -#define MC_TXN_OVERRIDE_CONFIG_SDMMCR 0x1310U -#define MC_TXN_OVERRIDE_CONFIG_XUSB_DEVW 0x1268U -#define MC_TXN_OVERRIDE_CONFIG_TSECSRD 0x12a0U -#define MC_TXN_OVERRIDE_CONFIG_AFIW 0x1188U -#define MC_TXN_OVERRIDE_CONFIG_SCEW 0x14e0U - /******************************************************************************* * Structure to hold the transaction override settings to use to override * client inputs @@ -229,6 +54,25 @@ typedef struct mc_streamid_security_cfg { #define CLIENT_FLAG_NON_SECURE 1U #define CLIENT_INPUTS_OVERRIDE 1U #define CLIENT_INPUTS_NO_OVERRIDE 0U +/******************************************************************************* + * StreamID to indicate no SMMU translations (requests to be steered on the + * SMMU bypass path) + ******************************************************************************/ +#define MC_STREAM_ID_MAX 0x7FU + +/******************************************************************************* + * Memory Controller SMMU Bypass config register + ******************************************************************************/ +#define MC_SMMU_BYPASS_CONFIG 0x1820U +#define MC_SMMU_BYPASS_CTRL_MASK 0x3U +#define MC_SMMU_BYPASS_CTRL_SHIFT 0U +#define MC_SMMU_CTRL_TBU_BYPASS_ALL (0U << MC_SMMU_BYPASS_CTRL_SHIFT) +#define MC_SMMU_CTRL_TBU_RSVD (1U << MC_SMMU_BYPASS_CTRL_SHIFT) +#define MC_SMMU_CTRL_TBU_BYPASS_SPL_STREAMID (2U << MC_SMMU_BYPASS_CTRL_SHIFT) +#define MC_SMMU_CTRL_TBU_BYPASS_NONE (3U << MC_SMMU_BYPASS_CTRL_SHIFT) +#define MC_SMMU_BYPASS_CONFIG_WRITE_ACCESS_BIT (1U << 31) +#define MC_SMMU_BYPASS_CONFIG_SETTINGS (MC_SMMU_BYPASS_CONFIG_WRITE_ACCESS_BIT | \ + MC_SMMU_CTRL_TBU_BYPASS_SPL_STREAMID) #define mc_make_sec_cfg(off, ns, ovrrd, access) \ { \ @@ -250,131 +94,10 @@ typedef struct tegra_mc_settings { uint32_t num_streamid_security_cfgs; const mc_txn_override_cfg_t *txn_override_cfg; uint32_t num_txn_override_cfgs; + void (*reconfig_mss_clients)(void); + void (*set_txn_overrides)(void); } tegra_mc_settings_t; -#endif /* __ASSEMBLY__ */ - -/******************************************************************************* - * Memory Controller SMMU Bypass config register - ******************************************************************************/ -#define MC_SMMU_BYPASS_CONFIG 0x1820U -#define MC_SMMU_BYPASS_CTRL_MASK 0x3U -#define MC_SMMU_BYPASS_CTRL_SHIFT 0U -#define MC_SMMU_CTRL_TBU_BYPASS_ALL (0U << MC_SMMU_BYPASS_CTRL_SHIFT) -#define MC_SMMU_CTRL_TBU_RSVD (1U << MC_SMMU_BYPASS_CTRL_SHIFT) -#define MC_SMMU_CTRL_TBU_BYPASS_SPL_STREAMID (2U << MC_SMMU_BYPASS_CTRL_SHIFT) -#define MC_SMMU_CTRL_TBU_BYPASS_NONE (3U << MC_SMMU_BYPASS_CTRL_SHIFT) -#define MC_SMMU_BYPASS_CONFIG_WRITE_ACCESS_BIT (1U << 31) -#define MC_SMMU_BYPASS_CONFIG_SETTINGS (MC_SMMU_BYPASS_CONFIG_WRITE_ACCESS_BIT | \ - MC_SMMU_CTRL_TBU_BYPASS_SPL_STREAMID) - -#define MC_TXN_OVERRIDE_CONFIG_AXID_OVERRIDE_CGID (1U << 0) -#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_OVERRIDE_SO_DEV (2U << 4) -#define MC_TXN_OVERRIDE_CONFIG_AXID_OVERRIDE_SO_DEV_CGID_SO_DEV_CLIENT (1U << 12) - -/******************************************************************************* - * Non-SO_DEV transactions override values for CGID_TAG bitfield for the - * MC_TXN_OVERRIDE_CONFIG_{module} registers - ******************************************************************************/ -#define MC_TXN_OVERRIDE_CGID_TAG_DEFAULT 0U -#define MC_TXN_OVERRIDE_CGID_TAG_CLIENT_AXI_ID 1U -#define MC_TXN_OVERRIDE_CGID_TAG_ZERO 2U -#define MC_TXN_OVERRIDE_CGID_TAG_ADR 3U -#define MC_TXN_OVERRIDE_CGID_TAG_MASK 3U - -/******************************************************************************* - * Memory Controller Reset Control registers - ******************************************************************************/ -#define MC_CLIENT_HOTRESET_CTRL0 0x200U -#define MC_CLIENT_HOTRESET_CTRL0_RESET_VAL 0U -#define MC_CLIENT_HOTRESET_CTRL0_AFI_FLUSH_ENB (1U << 0) -#define MC_CLIENT_HOTRESET_CTRL0_HC_FLUSH_ENB (1U << 6) -#define MC_CLIENT_HOTRESET_CTRL0_HDA_FLUSH_ENB (1U << 7) -#define MC_CLIENT_HOTRESET_CTRL0_ISP2_FLUSH_ENB (1U << 8) -#define MC_CLIENT_HOTRESET_CTRL0_MPCORE_FLUSH_ENB (1U << 9) -#define MC_CLIENT_HOTRESET_CTRL0_NVENC_FLUSH_ENB (1U << 11) -#define MC_CLIENT_HOTRESET_CTRL0_SATA_FLUSH_ENB (1U << 15) -#define MC_CLIENT_HOTRESET_CTRL0_VI_FLUSH_ENB (1U << 17) -#define MC_CLIENT_HOTRESET_CTRL0_VIC_FLUSH_ENB (1U << 18) -#define MC_CLIENT_HOTRESET_CTRL0_XUSB_HOST_FLUSH_ENB (1U << 19) -#define MC_CLIENT_HOTRESET_CTRL0_XUSB_DEV_FLUSH_ENB (1U << 20) -#define MC_CLIENT_HOTRESET_CTRL0_TSEC_FLUSH_ENB (1U << 22) -#define MC_CLIENT_HOTRESET_CTRL0_SDMMC1A_FLUSH_ENB (1U << 29) -#define MC_CLIENT_HOTRESET_CTRL0_SDMMC2A_FLUSH_ENB (1U << 30) -#define MC_CLIENT_HOTRESET_CTRL0_SDMMC3A_FLUSH_ENB (1U << 31) -#define MC_CLIENT_HOTRESET_STATUS0 0x204U -#define MC_CLIENT_HOTRESET_CTRL1 0x970U -#define MC_CLIENT_HOTRESET_CTRL1_RESET_VAL 0U -#define MC_CLIENT_HOTRESET_CTRL1_SDMMC4A_FLUSH_ENB (1U << 0) -#define MC_CLIENT_HOTRESET_CTRL1_GPU_FLUSH_ENB (1U << 2) -#define MC_CLIENT_HOTRESET_CTRL1_NVDEC_FLUSH_ENB (1U << 5) -#define MC_CLIENT_HOTRESET_CTRL1_APE_FLUSH_ENB (1U << 6) -#define MC_CLIENT_HOTRESET_CTRL1_SE_FLUSH_ENB (1U << 7) -#define MC_CLIENT_HOTRESET_CTRL1_NVJPG_FLUSH_ENB (1U << 8) -#define MC_CLIENT_HOTRESET_CTRL1_ETR_FLUSH_ENB (1U << 12) -#define MC_CLIENT_HOTRESET_CTRL1_TSECB_FLUSH_ENB (1U << 13) -#define MC_CLIENT_HOTRESET_CTRL1_AXIS_FLUSH_ENB (1U << 18) -#define MC_CLIENT_HOTRESET_CTRL1_EQOS_FLUSH_ENB (1U << 19) -#define MC_CLIENT_HOTRESET_CTRL1_UFSHC_FLUSH_ENB (1U << 20) -#define MC_CLIENT_HOTRESET_CTRL1_NVDISPLAY_FLUSH_ENB (1U << 21) -#define MC_CLIENT_HOTRESET_CTRL1_BPMP_FLUSH_ENB (1U << 22) -#define MC_CLIENT_HOTRESET_CTRL1_AON_FLUSH_ENB (1U << 23) -#define MC_CLIENT_HOTRESET_CTRL1_SCE_FLUSH_ENB (1U << 24) -#define MC_CLIENT_HOTRESET_STATUS1 0x974U - -/******************************************************************************* - * Memory Controller's PCFIFO client configuration registers - ******************************************************************************/ -#define MC_PCFIFO_CLIENT_CONFIG1 0xdd4UL -#define MC_PCFIFO_CLIENT_CONFIG1_RESET_VAL 0x20000UL -#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_AFIW_UNORDERED (0UL << 17) -#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_AFIW_MASK (1UL << 17) -#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_HDAW_UNORDERED (0UL << 21) -#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_HDAW_MASK (1UL << 21) -#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_SATAW_UNORDERED (0UL << 29) -#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_SATAW_MASK (1UL << 29) - -#define MC_PCFIFO_CLIENT_CONFIG2 0xdd8UL -#define MC_PCFIFO_CLIENT_CONFIG2_RESET_VAL 0x20000UL -#define MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_HOSTW_UNORDERED (0UL << 11) -#define MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_HOSTW_MASK (1UL << 11) -#define MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_DEVW_UNORDERED (0UL << 13) -#define MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_DEVW_MASK (1UL << 13) - -#define MC_PCFIFO_CLIENT_CONFIG3 0xddcUL -#define MC_PCFIFO_CLIENT_CONFIG3_RESET_VAL 0UL -#define MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_SDMMCWAB_UNORDERED (0UL << 7) -#define MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_SDMMCWAB_MASK (1UL << 7) - -#define MC_PCFIFO_CLIENT_CONFIG4 0xde0UL -#define MC_PCFIFO_CLIENT_CONFIG4_RESET_VAL 0UL -#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SESWR_UNORDERED (0UL << 1) -#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SESWR_MASK (1UL << 1) -#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_ETRW_UNORDERED (0UL << 5) -#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_ETRW_MASK (1UL << 5) -#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AXISW_UNORDERED (0UL << 13) -#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AXISW_MASK (1UL << 13) -#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_EQOSW_UNORDERED (0UL << 15) -#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_EQOSW_ORDERED (1UL << 15) -#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_EQOSW_MASK (1UL << 15) -#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_UFSHCW_UNORDERED (0UL << 17) -#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_UFSHCW_MASK (1UL << 17) -#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_BPMPDMAW_UNORDERED (0UL << 22) -#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_BPMPDMAW_MASK (1UL << 22) -#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AONDMAW_UNORDERED (0UL << 26) -#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AONDMAW_MASK (1UL << 26) -#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SCEDMAW_UNORDERED (0UL << 30) -#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SCEDMAW_MASK (1UL << 30) - -#define MC_PCFIFO_CLIENT_CONFIG5 0xbf4UL -#define MC_PCFIFO_CLIENT_CONFIG5_RESET_VAL 0UL -#define MC_PCFIFO_CLIENT_CONFIG5_PCFIFO_APEDMAW_UNORDERED (0UL << 0) -#define MC_PCFIFO_CLIENT_CONFIG5_PCFIFO_APEDMAW_MASK (1UL << 0) - -#ifndef __ASSEMBLY__ - -#include - static inline uint32_t tegra_mc_read_32(uint32_t off) { return mmio_read_32(TEGRA_MC_BASE + off); @@ -410,6 +133,22 @@ static inline void tegra_mc_streamid_write_32(uint32_t off, uint32_t val) (uint32_t)TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_PASTHRU); \ } +#define mc_set_tsa_w_passthrough(client) \ + { \ + mmio_write_32(TEGRA_TSA_BASE + TSA_CONFIG_STATIC0_CSW_##client, \ + (TSA_CONFIG_STATIC0_CSW_RESET_W & \ + (uint32_t)~TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_MASK) | \ + (uint32_t)TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_PASTHRU); \ + } + +#define mc_set_tsa_r_passthrough(client) \ + { \ + mmio_write_32(TEGRA_TSA_BASE + TSA_CONFIG_STATIC0_CSR_##client, \ + (TSA_CONFIG_STATIC0_CSR_RESET_R & \ + (uint32_t)~TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_MASK) | \ + (uint32_t)TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_PASTHRU); \ + } + #define mc_set_txn_override(client, normal_axi_id, so_dev_axi_id, normal_override, so_dev_override) \ { \ tegra_mc_write_32(MC_TXN_OVERRIDE_CONFIG_##client, \ diff --git a/plat/nvidia/tegra/include/t186/tegra_mc_def.h b/plat/nvidia/tegra/include/t186/tegra_mc_def.h new file mode 100644 index 000000000..d051a150a --- /dev/null +++ b/plat/nvidia/tegra/include/t186/tegra_mc_def.h @@ -0,0 +1,285 @@ +/* + * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef TEGRA_MC_DEF_H +#define TEGRA_MC_DEF_H + +/******************************************************************************* + * Memory Controller's PCFIFO client configuration registers + ******************************************************************************/ +#define MC_PCFIFO_CLIENT_CONFIG0 0xdd0U + +#define MC_PCFIFO_CLIENT_CONFIG1 0xdd4U +#define MC_PCFIFO_CLIENT_CONFIG1_RESET_VAL 0x20000U +#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_AFIW_UNORDERED (0U << 17) +#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_AFIW_MASK (1U << 17) +#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_HDAW_UNORDERED (0U << 21) +#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_HDAW_MASK (1U << 21) +#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_SATAW_UNORDERED (0U << 29) +#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_SATAW_MASK (1U << 29) + +#define MC_PCFIFO_CLIENT_CONFIG2 0xdd8U +#define MC_PCFIFO_CLIENT_CONFIG2_RESET_VAL 0x20000U +#define MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_HOSTW_UNORDERED (0U << 11) +#define MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_HOSTW_MASK (1U << 11) +#define MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_DEVW_UNORDERED (0U << 13) +#define MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_DEVW_MASK (1U << 13) + +#define MC_PCFIFO_CLIENT_CONFIG3 0xddcU +#define MC_PCFIFO_CLIENT_CONFIG3_RESET_VAL 0U +#define MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_SDMMCWAB_UNORDERED (0U << 7) +#define MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_SDMMCWAB_MASK (1U << 7) + +#define MC_PCFIFO_CLIENT_CONFIG4 0xde0U +#define MC_PCFIFO_CLIENT_CONFIG4_RESET_VAL 0U +#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SESWR_UNORDERED (0U << 1) +#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SESWR_MASK (1U << 1) +#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_ETRW_UNORDERED (0U << 5) +#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_ETRW_MASK (1U << 5) +#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AXISW_UNORDERED (0U << 13) +#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AXISW_MASK (1U << 13) +#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_EQOSW_UNORDERED (0U << 15) +#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_EQOSW_ORDERED (1U << 15) +#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_EQOSW_MASK (1U << 15) +#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_UFSHCW_UNORDERED (0U << 17) +#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_UFSHCW_MASK (1U << 17) +#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_BPMPDMAW_UNORDERED (0U << 22) +#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_BPMPDMAW_MASK (1U << 22) +#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AONDMAW_UNORDERED (0U << 26) +#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AONDMAW_MASK (1U << 26) +#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SCEDMAW_UNORDERED (0U << 30) +#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SCEDMAW_MASK (1U << 30) + +#define MC_PCFIFO_CLIENT_CONFIG5 0xbf4U +#define MC_PCFIFO_CLIENT_CONFIG5_RESET_VAL 0U +#define MC_PCFIFO_CLIENT_CONFIG5_PCFIFO_APEDMAW_UNORDERED (0U << 0) +#define MC_PCFIFO_CLIENT_CONFIG5_PCFIFO_APEDMAW_MASK (1U << 0) + +/******************************************************************************* + * Stream ID Override Config registers + ******************************************************************************/ +#define MC_STREAMID_OVERRIDE_CFG_PTCR 0x000U +#define MC_STREAMID_OVERRIDE_CFG_AFIR 0x070U +#define MC_STREAMID_OVERRIDE_CFG_HDAR 0x0A8U +#define MC_STREAMID_OVERRIDE_CFG_HOST1XDMAR 0x0B0U +#define MC_STREAMID_OVERRIDE_CFG_NVENCSRD 0x0E0U +#define MC_STREAMID_OVERRIDE_CFG_SATAR 0x0F8U +#define MC_STREAMID_OVERRIDE_CFG_MPCORER 0x138U +#define MC_STREAMID_OVERRIDE_CFG_NVENCSWR 0x158U +#define MC_STREAMID_OVERRIDE_CFG_AFIW 0x188U +#define MC_STREAMID_OVERRIDE_CFG_HDAW 0x1A8U +#define MC_STREAMID_OVERRIDE_CFG_MPCOREW 0x1C8U +#define MC_STREAMID_OVERRIDE_CFG_SATAW 0x1E8U +#define MC_STREAMID_OVERRIDE_CFG_ISPRA 0x220U +#define MC_STREAMID_OVERRIDE_CFG_ISPWA 0x230U +#define MC_STREAMID_OVERRIDE_CFG_ISPWB 0x238U +#define MC_STREAMID_OVERRIDE_CFG_XUSB_HOSTR 0x250U +#define MC_STREAMID_OVERRIDE_CFG_XUSB_HOSTW 0x258U +#define MC_STREAMID_OVERRIDE_CFG_XUSB_DEVR 0x260U +#define MC_STREAMID_OVERRIDE_CFG_XUSB_DEVW 0x268U +#define MC_STREAMID_OVERRIDE_CFG_TSECSRD 0x2A0U +#define MC_STREAMID_OVERRIDE_CFG_TSECSWR 0x2A8U +#define MC_STREAMID_OVERRIDE_CFG_GPUSRD 0x2C0U +#define MC_STREAMID_OVERRIDE_CFG_GPUSWR 0x2C8U +#define MC_STREAMID_OVERRIDE_CFG_SDMMCRA 0x300U +#define MC_STREAMID_OVERRIDE_CFG_SDMMCRAA 0x308U +#define MC_STREAMID_OVERRIDE_CFG_SDMMCR 0x310U +#define MC_STREAMID_OVERRIDE_CFG_SDMMCRAB 0x318U +#define MC_STREAMID_OVERRIDE_CFG_SDMMCWA 0x320U +#define MC_STREAMID_OVERRIDE_CFG_SDMMCWAA 0x328U +#define MC_STREAMID_OVERRIDE_CFG_SDMMCW 0x330U +#define MC_STREAMID_OVERRIDE_CFG_SDMMCWAB 0x338U +#define MC_STREAMID_OVERRIDE_CFG_VICSRD 0x360U +#define MC_STREAMID_OVERRIDE_CFG_VICSWR 0x368U +#define MC_STREAMID_OVERRIDE_CFG_VIW 0x390U +#define MC_STREAMID_OVERRIDE_CFG_NVDECSRD 0x3C0U +#define MC_STREAMID_OVERRIDE_CFG_NVDECSWR 0x3C8U +#define MC_STREAMID_OVERRIDE_CFG_APER 0x3D0U +#define MC_STREAMID_OVERRIDE_CFG_APEW 0x3D8U +#define MC_STREAMID_OVERRIDE_CFG_NVJPGSRD 0x3F0U +#define MC_STREAMID_OVERRIDE_CFG_NVJPGSWR 0x3F8U +#define MC_STREAMID_OVERRIDE_CFG_SESRD 0x400U +#define MC_STREAMID_OVERRIDE_CFG_SESWR 0x408U +#define MC_STREAMID_OVERRIDE_CFG_ETRR 0x420U +#define MC_STREAMID_OVERRIDE_CFG_ETRW 0x428U +#define MC_STREAMID_OVERRIDE_CFG_TSECSRDB 0x430U +#define MC_STREAMID_OVERRIDE_CFG_TSECSWRB 0x438U +#define MC_STREAMID_OVERRIDE_CFG_GPUSRD2 0x440U +#define MC_STREAMID_OVERRIDE_CFG_GPUSWR2 0x448U +#define MC_STREAMID_OVERRIDE_CFG_AXISR 0x460U +#define MC_STREAMID_OVERRIDE_CFG_AXISW 0x468U +#define MC_STREAMID_OVERRIDE_CFG_EQOSR 0x470U +#define MC_STREAMID_OVERRIDE_CFG_EQOSW 0x478U +#define MC_STREAMID_OVERRIDE_CFG_UFSHCR 0x480U +#define MC_STREAMID_OVERRIDE_CFG_UFSHCW 0x488U +#define MC_STREAMID_OVERRIDE_CFG_NVDISPLAYR 0x490U +#define MC_STREAMID_OVERRIDE_CFG_BPMPR 0x498U +#define MC_STREAMID_OVERRIDE_CFG_BPMPW 0x4A0U +#define MC_STREAMID_OVERRIDE_CFG_BPMPDMAR 0x4A8U +#define MC_STREAMID_OVERRIDE_CFG_BPMPDMAW 0x4B0U +#define MC_STREAMID_OVERRIDE_CFG_AONR 0x4B8U +#define MC_STREAMID_OVERRIDE_CFG_AONW 0x4C0U +#define MC_STREAMID_OVERRIDE_CFG_AONDMAR 0x4C8U +#define MC_STREAMID_OVERRIDE_CFG_AONDMAW 0x4D0U +#define MC_STREAMID_OVERRIDE_CFG_SCER 0x4D8U +#define MC_STREAMID_OVERRIDE_CFG_SCEW 0x4E0U +#define MC_STREAMID_OVERRIDE_CFG_SCEDMAR 0x4E8U +#define MC_STREAMID_OVERRIDE_CFG_SCEDMAW 0x4F0U +#define MC_STREAMID_OVERRIDE_CFG_APEDMAR 0x4F8U +#define MC_STREAMID_OVERRIDE_CFG_APEDMAW 0x500U +#define MC_STREAMID_OVERRIDE_CFG_NVDISPLAYR1 0x508U +#define MC_STREAMID_OVERRIDE_CFG_VICSRD1 0x510U +#define MC_STREAMID_OVERRIDE_CFG_NVDECSRD1 0x518U + +/******************************************************************************* + * Macro to calculate Security cfg register addr from StreamID Override register + ******************************************************************************/ +#define MC_STREAMID_OVERRIDE_TO_SECURITY_CFG(addr) ((addr) + (uint32_t)sizeof(uint32_t)) + +#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_NO_OVERRIDE_SO_DEV (0U << 4) +#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_NON_COHERENT_SO_DEV (1U << 4) +#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_COHERENT_SO_DEV (2U << 4) +#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_COHERENT_SNOOP_SO_DEV (3U << 4) + +#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_NO_OVERRIDE_NORMAL (0U << 8) +#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_NON_COHERENT_NORMAL (1U << 8) +#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_COHERENT_NORMAL (2U << 8) +#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_COHERENT_SNOOP_NORMAL (3U << 8) + +#define MC_TXN_OVERRIDE_CONFIG_CGID_SO_DEV_ZERO (0U << 12) +#define MC_TXN_OVERRIDE_CONFIG_CGID_SO_DEV_CLIENT_AXI_ID (1U << 12) + +/******************************************************************************* + * Memory Controller transaction override config registers + ******************************************************************************/ +#define MC_TXN_OVERRIDE_CONFIG_HDAR 0x10a8U +#define MC_TXN_OVERRIDE_CONFIG_BPMPW 0x14a0U +#define MC_TXN_OVERRIDE_CONFIG_PTCR 0x1000U +#define MC_TXN_OVERRIDE_CONFIG_NVDISPLAYR 0x1490U +#define MC_TXN_OVERRIDE_CONFIG_EQOSW 0x1478U +#define MC_TXN_OVERRIDE_CONFIG_NVJPGSWR 0x13f8U +#define MC_TXN_OVERRIDE_CONFIG_ISPRA 0x1220U +#define MC_TXN_OVERRIDE_CONFIG_SDMMCWAA 0x1328U +#define MC_TXN_OVERRIDE_CONFIG_VICSRD 0x1360U +#define MC_TXN_OVERRIDE_CONFIG_MPCOREW 0x11c8U +#define MC_TXN_OVERRIDE_CONFIG_GPUSRD 0x12c0U +#define MC_TXN_OVERRIDE_CONFIG_AXISR 0x1460U +#define MC_TXN_OVERRIDE_CONFIG_SCEDMAW 0x14f0U +#define MC_TXN_OVERRIDE_CONFIG_SDMMCW 0x1330U +#define MC_TXN_OVERRIDE_CONFIG_EQOSR 0x1470U +#define MC_TXN_OVERRIDE_CONFIG_APEDMAR 0x14f8U +#define MC_TXN_OVERRIDE_CONFIG_NVENCSRD 0x10e0U +#define MC_TXN_OVERRIDE_CONFIG_SDMMCRAB 0x1318U +#define MC_TXN_OVERRIDE_CONFIG_VICSRD1 0x1510U +#define MC_TXN_OVERRIDE_CONFIG_BPMPDMAR 0x14a8U +#define MC_TXN_OVERRIDE_CONFIG_VIW 0x1390U +#define MC_TXN_OVERRIDE_CONFIG_SDMMCRAA 0x1308U +#define MC_TXN_OVERRIDE_CONFIG_AXISW 0x1468U +#define MC_TXN_OVERRIDE_CONFIG_XUSB_DEVR 0x1260U +#define MC_TXN_OVERRIDE_CONFIG_UFSHCR 0x1480U +#define MC_TXN_OVERRIDE_CONFIG_TSECSWR 0x12a8U +#define MC_TXN_OVERRIDE_CONFIG_GPUSWR 0x12c8U +#define MC_TXN_OVERRIDE_CONFIG_SATAR 0x10f8U +#define MC_TXN_OVERRIDE_CONFIG_XUSB_HOSTW 0x1258U +#define MC_TXN_OVERRIDE_CONFIG_TSECSWRB 0x1438U +#define MC_TXN_OVERRIDE_CONFIG_GPUSRD2 0x1440U +#define MC_TXN_OVERRIDE_CONFIG_SCEDMAR 0x14e8U +#define MC_TXN_OVERRIDE_CONFIG_GPUSWR2 0x1448U +#define MC_TXN_OVERRIDE_CONFIG_AONDMAW 0x14d0U +#define MC_TXN_OVERRIDE_CONFIG_APEDMAW 0x1500U +#define MC_TXN_OVERRIDE_CONFIG_AONW 0x14c0U +#define MC_TXN_OVERRIDE_CONFIG_HOST1XDMAR 0x10b0U +#define MC_TXN_OVERRIDE_CONFIG_ETRR 0x1420U +#define MC_TXN_OVERRIDE_CONFIG_SESWR 0x1408U +#define MC_TXN_OVERRIDE_CONFIG_NVJPGSRD 0x13f0U +#define MC_TXN_OVERRIDE_CONFIG_NVDECSRD 0x13c0U +#define MC_TXN_OVERRIDE_CONFIG_TSECSRDB 0x1430U +#define MC_TXN_OVERRIDE_CONFIG_BPMPDMAW 0x14b0U +#define MC_TXN_OVERRIDE_CONFIG_APER 0x13d0U +#define MC_TXN_OVERRIDE_CONFIG_NVDECSRD1 0x1518U +#define MC_TXN_OVERRIDE_CONFIG_XUSB_HOSTR 0x1250U +#define MC_TXN_OVERRIDE_CONFIG_ISPWA 0x1230U +#define MC_TXN_OVERRIDE_CONFIG_SESRD 0x1400U +#define MC_TXN_OVERRIDE_CONFIG_SCER 0x14d8U +#define MC_TXN_OVERRIDE_CONFIG_AONR 0x14b8U +#define MC_TXN_OVERRIDE_CONFIG_MPCORER 0x1138U +#define MC_TXN_OVERRIDE_CONFIG_SDMMCWA 0x1320U +#define MC_TXN_OVERRIDE_CONFIG_HDAW 0x11a8U +#define MC_TXN_OVERRIDE_CONFIG_NVDECSWR 0x13c8U +#define MC_TXN_OVERRIDE_CONFIG_UFSHCW 0x1488U +#define MC_TXN_OVERRIDE_CONFIG_AONDMAR 0x14c8U +#define MC_TXN_OVERRIDE_CONFIG_SATAW 0x11e8U +#define MC_TXN_OVERRIDE_CONFIG_ETRW 0x1428U +#define MC_TXN_OVERRIDE_CONFIG_VICSWR 0x1368U +#define MC_TXN_OVERRIDE_CONFIG_NVENCSWR 0x1158U +#define MC_TXN_OVERRIDE_CONFIG_AFIR 0x1070U +#define MC_TXN_OVERRIDE_CONFIG_SDMMCWAB 0x1338U +#define MC_TXN_OVERRIDE_CONFIG_SDMMCRA 0x1300U +#define MC_TXN_OVERRIDE_CONFIG_NVDISPLAYR1 0x1508U +#define MC_TXN_OVERRIDE_CONFIG_ISPWB 0x1238U +#define MC_TXN_OVERRIDE_CONFIG_BPMPR 0x1498U +#define MC_TXN_OVERRIDE_CONFIG_APEW 0x13d8U +#define MC_TXN_OVERRIDE_CONFIG_SDMMCR 0x1310U +#define MC_TXN_OVERRIDE_CONFIG_XUSB_DEVW 0x1268U +#define MC_TXN_OVERRIDE_CONFIG_TSECSRD 0x12a0U +#define MC_TXN_OVERRIDE_CONFIG_AFIW 0x1188U +#define MC_TXN_OVERRIDE_CONFIG_SCEW 0x14e0U + +#define MC_TXN_OVERRIDE_CONFIG_AXID_OVERRIDE_CGID (1U << 0) +#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_OVERRIDE_SO_DEV (2U << 4) +#define MC_TXN_OVERRIDE_CONFIG_AXID_OVERRIDE_SO_DEV_CGID_SO_DEV_CLIENT (1U << 12) + +/******************************************************************************* + * Non-SO_DEV transactions override values for CGID_TAG bitfield for the + * MC_TXN_OVERRIDE_CONFIG_{module} registers + ******************************************************************************/ +#define MC_TXN_OVERRIDE_CGID_TAG_DEFAULT 0U +#define MC_TXN_OVERRIDE_CGID_TAG_CLIENT_AXI_ID 1U +#define MC_TXN_OVERRIDE_CGID_TAG_ZERO 2U +#define MC_TXN_OVERRIDE_CGID_TAG_ADR 3U +#define MC_TXN_OVERRIDE_CGID_TAG_MASK 3ULL + +/******************************************************************************* + * Memory Controller Reset Control registers + ******************************************************************************/ +#define MC_CLIENT_HOTRESET_CTRL0 0x200U +#define MC_CLIENT_HOTRESET_CTRL0_RESET_VAL 0U +#define MC_CLIENT_HOTRESET_CTRL0_AFI_FLUSH_ENB (1U << 0) +#define MC_CLIENT_HOTRESET_CTRL0_HC_FLUSH_ENB (1U << 6) +#define MC_CLIENT_HOTRESET_CTRL0_HDA_FLUSH_ENB (1U << 7) +#define MC_CLIENT_HOTRESET_CTRL0_ISP2_FLUSH_ENB (1U << 8) +#define MC_CLIENT_HOTRESET_CTRL0_MPCORE_FLUSH_ENB (1U << 9) +#define MC_CLIENT_HOTRESET_CTRL0_NVENC_FLUSH_ENB (1U << 11) +#define MC_CLIENT_HOTRESET_CTRL0_SATA_FLUSH_ENB (1U << 15) +#define MC_CLIENT_HOTRESET_CTRL0_VI_FLUSH_ENB (1U << 17) +#define MC_CLIENT_HOTRESET_CTRL0_VIC_FLUSH_ENB (1U << 18) +#define MC_CLIENT_HOTRESET_CTRL0_XUSB_HOST_FLUSH_ENB (1U << 19) +#define MC_CLIENT_HOTRESET_CTRL0_XUSB_DEV_FLUSH_ENB (1U << 20) +#define MC_CLIENT_HOTRESET_CTRL0_TSEC_FLUSH_ENB (1U << 22) +#define MC_CLIENT_HOTRESET_CTRL0_SDMMC1A_FLUSH_ENB (1U << 29) +#define MC_CLIENT_HOTRESET_CTRL0_SDMMC2A_FLUSH_ENB (1U << 30) +#define MC_CLIENT_HOTRESET_CTRL0_SDMMC3A_FLUSH_ENB (1U << 31) +#define MC_CLIENT_HOTRESET_STATUS0 0x204U +#define MC_CLIENT_HOTRESET_CTRL1 0x970U +#define MC_CLIENT_HOTRESET_CTRL1_RESET_VAL 0U +#define MC_CLIENT_HOTRESET_CTRL1_SDMMC4A_FLUSH_ENB (1U << 0) +#define MC_CLIENT_HOTRESET_CTRL1_GPU_FLUSH_ENB (1U << 2) +#define MC_CLIENT_HOTRESET_CTRL1_NVDEC_FLUSH_ENB (1U << 5) +#define MC_CLIENT_HOTRESET_CTRL1_APE_FLUSH_ENB (1U << 6) +#define MC_CLIENT_HOTRESET_CTRL1_SE_FLUSH_ENB (1U << 7) +#define MC_CLIENT_HOTRESET_CTRL1_NVJPG_FLUSH_ENB (1U << 8) +#define MC_CLIENT_HOTRESET_CTRL1_ETR_FLUSH_ENB (1U << 12) +#define MC_CLIENT_HOTRESET_CTRL1_TSECB_FLUSH_ENB (1U << 13) +#define MC_CLIENT_HOTRESET_CTRL1_AXIS_FLUSH_ENB (1U << 18) +#define MC_CLIENT_HOTRESET_CTRL1_EQOS_FLUSH_ENB (1U << 19) +#define MC_CLIENT_HOTRESET_CTRL1_UFSHC_FLUSH_ENB (1U << 20) +#define MC_CLIENT_HOTRESET_CTRL1_NVDISPLAY_FLUSH_ENB (1U << 21) +#define MC_CLIENT_HOTRESET_CTRL1_BPMP_FLUSH_ENB (1U << 22) +#define MC_CLIENT_HOTRESET_CTRL1_AON_FLUSH_ENB (1U << 23) +#define MC_CLIENT_HOTRESET_CTRL1_SCE_FLUSH_ENB (1U << 24) +#define MC_CLIENT_HOTRESET_STATUS1 0x974U + +#endif /* TEGRA_MC_DEF_H */ diff --git a/plat/nvidia/tegra/soc/t186/plat_memctrl.c b/plat/nvidia/tegra/soc/t186/plat_memctrl.c index 1e8d482a9..74811aee0 100644 --- a/plat/nvidia/tegra/soc/t186/plat_memctrl.c +++ b/plat/nvidia/tegra/soc/t186/plat_memctrl.c @@ -4,9 +4,12 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#include #include #include +#include +#include /******************************************************************************* * Array to hold stream_id override config register offsets @@ -201,6 +204,318 @@ const static mc_txn_override_cfg_t tegra186_txn_override_cfgs[] = { mc_make_txn_override_cfg(SCEW, CGID_TAG_ADR), }; +static void tegra186_memctrl_reconfig_mss_clients(void) +{ +#if ENABLE_ROC_FOR_ORDERING_CLIENT_REQUESTS + uint32_t val, wdata_0, wdata_1; + + /* + * Assert Memory Controller's HOTRESET_FLUSH_ENABLE signal for + * boot and strongly ordered MSS clients to flush existing memory + * traffic and stall future requests. + */ + val = tegra_mc_read_32(MC_CLIENT_HOTRESET_CTRL0); + assert(val == MC_CLIENT_HOTRESET_CTRL0_RESET_VAL); + + wdata_0 = MC_CLIENT_HOTRESET_CTRL0_HDA_FLUSH_ENB | +#if ENABLE_AFI_DEVICE + MC_CLIENT_HOTRESET_CTRL0_AFI_FLUSH_ENB | +#endif + MC_CLIENT_HOTRESET_CTRL0_SATA_FLUSH_ENB | + MC_CLIENT_HOTRESET_CTRL0_XUSB_HOST_FLUSH_ENB | + MC_CLIENT_HOTRESET_CTRL0_XUSB_DEV_FLUSH_ENB; + tegra_mc_write_32(MC_CLIENT_HOTRESET_CTRL0, wdata_0); + + /* Wait for HOTRESET STATUS to indicate FLUSH_DONE */ + do { + val = tegra_mc_read_32(MC_CLIENT_HOTRESET_STATUS0); + } while ((val & wdata_0) != wdata_0); + + /* Wait one more time due to SW WAR for known legacy issue */ + do { + val = tegra_mc_read_32(MC_CLIENT_HOTRESET_STATUS0); + } while ((val & wdata_0) != wdata_0); + + val = tegra_mc_read_32(MC_CLIENT_HOTRESET_CTRL1); + assert(val == MC_CLIENT_HOTRESET_CTRL1_RESET_VAL); + + wdata_1 = MC_CLIENT_HOTRESET_CTRL1_SDMMC4A_FLUSH_ENB | + MC_CLIENT_HOTRESET_CTRL1_APE_FLUSH_ENB | + MC_CLIENT_HOTRESET_CTRL1_SE_FLUSH_ENB | + MC_CLIENT_HOTRESET_CTRL1_ETR_FLUSH_ENB | + MC_CLIENT_HOTRESET_CTRL1_AXIS_FLUSH_ENB | + MC_CLIENT_HOTRESET_CTRL1_EQOS_FLUSH_ENB | + MC_CLIENT_HOTRESET_CTRL1_UFSHC_FLUSH_ENB | + MC_CLIENT_HOTRESET_CTRL1_BPMP_FLUSH_ENB | + MC_CLIENT_HOTRESET_CTRL1_AON_FLUSH_ENB | + MC_CLIENT_HOTRESET_CTRL1_SCE_FLUSH_ENB; + tegra_mc_write_32(MC_CLIENT_HOTRESET_CTRL1, wdata_1); + + /* Wait for HOTRESET STATUS to indicate FLUSH_DONE */ + do { + val = tegra_mc_read_32(MC_CLIENT_HOTRESET_STATUS1); + } while ((val & wdata_1) != wdata_1); + + /* Wait one more time due to SW WAR for known legacy issue */ + do { + val = tegra_mc_read_32(MC_CLIENT_HOTRESET_STATUS1); + } while ((val & wdata_1) != wdata_1); + + /* + * Change MEMTYPE_OVERRIDE from SO_DEV -> PASSTHRU for boot and + * strongly ordered MSS clients. ROC needs to be single point + * of control on overriding the memory type. So, remove TSA's + * memtype override. + * + * MC clients with default SO_DEV override still enabled at TSA: + * AONW, BPMPW, SCEW, APEW + */ +#if ENABLE_AFI_DEVICE + mc_set_tsa_passthrough(AFIW); +#endif + mc_set_tsa_passthrough(HDAW); + mc_set_tsa_passthrough(SATAW); + mc_set_tsa_passthrough(XUSB_HOSTW); + mc_set_tsa_passthrough(XUSB_DEVW); + mc_set_tsa_passthrough(SDMMCWAB); + mc_set_tsa_passthrough(APEDMAW); + mc_set_tsa_passthrough(SESWR); + mc_set_tsa_passthrough(ETRW); + mc_set_tsa_passthrough(AXISW); + mc_set_tsa_passthrough(EQOSW); + mc_set_tsa_passthrough(UFSHCW); + mc_set_tsa_passthrough(BPMPDMAW); + mc_set_tsa_passthrough(AONDMAW); + mc_set_tsa_passthrough(SCEDMAW); + + /* Parker has no IO Coherency support and need the following: + * Ordered MC Clients on Parker are AFI, EQOS, SATA, XUSB. + * ISO clients(DISP, VI, EQOS) should never snoop caches and + * don't need ROC/PCFIFO ordering. + * ISO clients(EQOS) that need ordering should use PCFIFO ordering + * and bypass ROC ordering by using FORCE_NON_COHERENT path. + * FORCE_NON_COHERENT/FORCE_COHERENT config take precedence + * over SMMU attributes. + * Force all Normal memory transactions from ISO and non-ISO to be + * non-coherent(bypass ROC, avoid cache snoop to avoid perf hit). + * Force the SO_DEV transactions from ordered ISO clients(EQOS) to + * non-coherent path and enable MC PCFIFO interlock for ordering. + * Force the SO_DEV transactions from ordered non-ISO clients (PCIe, + * XUSB, SATA) to coherent so that the transactions are + * ordered by ROC. + * PCFIFO ensure write ordering. + * Read after Write ordering is maintained/enforced by MC clients. + * Clients that need PCIe type write ordering must + * go through ROC ordering. + * Ordering enable for Read clients is not necessary. + * R5's and A9 would get necessary ordering from AXI and + * don't need ROC ordering enable: + * - MMIO ordering is through dev mapping and MMIO + * accesses bypass SMMU. + * - Normal memory is accessed through SMMU and ordering is + * ensured by client and AXI. + * - Ack point for Normal memory is WCAM in MC. + * - MMIO's can be early acked and AXI ensures dev memory ordering, + * Client ensures read/write direction change ordering. + * - See Bug 200312466 for more details. + * + * CGID_TAG_ADR is only present from T186 A02. As this code is common + * between A01 and A02, tegra_memctrl_set_overrides() programs + * CGID_TAG_ADR for the necessary clients on A02. + */ + mc_set_txn_override(HDAR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + mc_set_txn_override(BPMPW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + mc_set_txn_override(PTCR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + mc_set_txn_override(NVDISPLAYR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + mc_set_txn_override(EQOSW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + mc_set_txn_override(NVJPGSWR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + mc_set_txn_override(ISPRA, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + mc_set_txn_override(SDMMCWAA, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + mc_set_txn_override(VICSRD, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + mc_set_txn_override(MPCOREW, CGID_TAG_DEFAULT, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE); + mc_set_txn_override(GPUSRD, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + mc_set_txn_override(AXISR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + mc_set_txn_override(SCEDMAW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + mc_set_txn_override(SDMMCW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + mc_set_txn_override(EQOSR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + /* See bug 200131110 comment #35*/ + mc_set_txn_override(APEDMAR, CGID_TAG_CLIENT_AXI_ID, SO_DEV_CLIENT_AXI_ID, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + mc_set_txn_override(NVENCSRD, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + mc_set_txn_override(SDMMCRAB, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + mc_set_txn_override(VICSRD1, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + mc_set_txn_override(BPMPDMAR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + mc_set_txn_override(VIW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + mc_set_txn_override(SDMMCRAA, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + mc_set_txn_override(AXISW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + mc_set_txn_override(XUSB_DEVR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + mc_set_txn_override(UFSHCR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + mc_set_txn_override(TSECSWR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + mc_set_txn_override(GPUSWR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + mc_set_txn_override(SATAR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + mc_set_txn_override(XUSB_HOSTW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_COHERENT); + mc_set_txn_override(TSECSWRB, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + mc_set_txn_override(GPUSRD2, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + mc_set_txn_override(SCEDMAR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + mc_set_txn_override(GPUSWR2, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + mc_set_txn_override(AONDMAW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + /* See bug 200131110 comment #35*/ + mc_set_txn_override(APEDMAW, CGID_TAG_CLIENT_AXI_ID, SO_DEV_CLIENT_AXI_ID, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + mc_set_txn_override(AONW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + mc_set_txn_override(HOST1XDMAR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + mc_set_txn_override(ETRR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + mc_set_txn_override(SESWR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + mc_set_txn_override(NVJPGSRD, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + mc_set_txn_override(NVDECSRD, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + mc_set_txn_override(TSECSRDB, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + mc_set_txn_override(BPMPDMAW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + mc_set_txn_override(APER, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + mc_set_txn_override(NVDECSRD1, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + mc_set_txn_override(XUSB_HOSTR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + mc_set_txn_override(ISPWA, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + mc_set_txn_override(SESRD, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + mc_set_txn_override(SCER, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + mc_set_txn_override(AONR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + mc_set_txn_override(MPCORER, CGID_TAG_DEFAULT, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE); + mc_set_txn_override(SDMMCWA, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + mc_set_txn_override(HDAW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + mc_set_txn_override(NVDECSWR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + mc_set_txn_override(UFSHCW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + mc_set_txn_override(AONDMAR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + mc_set_txn_override(SATAW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_COHERENT); + mc_set_txn_override(ETRW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + mc_set_txn_override(VICSWR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + mc_set_txn_override(NVENCSWR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + /* See bug 200131110 comment #35 */ + mc_set_txn_override(AFIR, CGID_TAG_DEFAULT, SO_DEV_CLIENT_AXI_ID, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + mc_set_txn_override(SDMMCWAB, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + mc_set_txn_override(SDMMCRA, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + mc_set_txn_override(NVDISPLAYR1, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + mc_set_txn_override(ISPWB, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + mc_set_txn_override(BPMPR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + mc_set_txn_override(APEW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + mc_set_txn_override(SDMMCR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + mc_set_txn_override(XUSB_DEVW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_COHERENT); + mc_set_txn_override(TSECSRD, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + /* + * See bug 200131110 comment #35 - there are no normal requests + * and AWID for SO/DEV requests is hardcoded in RTL for a + * particular PCIE controller + */ + mc_set_txn_override(AFIW, CGID_TAG_DEFAULT, SO_DEV_CLIENT_AXI_ID, FORCE_NON_COHERENT, FORCE_COHERENT); + mc_set_txn_override(SCEW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + + /* + * At this point, ordering can occur at ROC. So, remove PCFIFO's + * control over ordering requests. + * + * Change PCFIFO_*_ORDERED_CLIENT from ORDERED -> UNORDERED for + * boot and strongly ordered MSS clients + */ + val = MC_PCFIFO_CLIENT_CONFIG1_RESET_VAL & +#if ENABLE_AFI_DEVICE + mc_set_pcfifo_unordered_boot_so_mss(1, AFIW) & +#endif + mc_set_pcfifo_unordered_boot_so_mss(1, HDAW) & + mc_set_pcfifo_unordered_boot_so_mss(1, SATAW); + tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG1, val); + + val = MC_PCFIFO_CLIENT_CONFIG2_RESET_VAL & + mc_set_pcfifo_unordered_boot_so_mss(2, XUSB_HOSTW) & + mc_set_pcfifo_unordered_boot_so_mss(2, XUSB_DEVW); + tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG2, val); + + val = MC_PCFIFO_CLIENT_CONFIG3_RESET_VAL & + mc_set_pcfifo_unordered_boot_so_mss(3, SDMMCWAB); + tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG3, val); + + val = MC_PCFIFO_CLIENT_CONFIG4_RESET_VAL & + mc_set_pcfifo_unordered_boot_so_mss(4, SESWR) & + mc_set_pcfifo_unordered_boot_so_mss(4, ETRW) & + mc_set_pcfifo_unordered_boot_so_mss(4, AXISW) & + mc_set_pcfifo_unordered_boot_so_mss(4, UFSHCW) & + mc_set_pcfifo_unordered_boot_so_mss(4, BPMPDMAW) & + mc_set_pcfifo_unordered_boot_so_mss(4, AONDMAW) & + mc_set_pcfifo_unordered_boot_so_mss(4, SCEDMAW); + /* EQOSW is the only client that has PCFIFO order enabled. */ + val |= mc_set_pcfifo_ordered_boot_so_mss(4, EQOSW); + tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG4, val); + + val = MC_PCFIFO_CLIENT_CONFIG5_RESET_VAL & + mc_set_pcfifo_unordered_boot_so_mss(5, APEDMAW); + tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG5, val); + + /* + * Deassert HOTRESET FLUSH_ENABLE for boot and strongly ordered MSS + * clients to allow memory traffic from all clients to start passing + * through ROC + */ + val = tegra_mc_read_32(MC_CLIENT_HOTRESET_CTRL0); + assert(val == wdata_0); + + wdata_0 = MC_CLIENT_HOTRESET_CTRL0_RESET_VAL; + tegra_mc_write_32(MC_CLIENT_HOTRESET_CTRL0, wdata_0); + + val = tegra_mc_read_32(MC_CLIENT_HOTRESET_CTRL1); + assert(val == wdata_1); + + wdata_1 = MC_CLIENT_HOTRESET_CTRL1_RESET_VAL; + tegra_mc_write_32(MC_CLIENT_HOTRESET_CTRL1, wdata_1); + +#endif +} + +static void tegra186_memctrl_set_overrides(void) +{ + const tegra_mc_settings_t *plat_mc_settings = tegra_get_mc_settings(); + const mc_txn_override_cfg_t *mc_txn_override_cfgs; + uint32_t num_txn_override_cfgs; + uint32_t i, val; + + /* Get the settings from the platform */ + assert(plat_mc_settings != NULL); + mc_txn_override_cfgs = plat_mc_settings->txn_override_cfg; + num_txn_override_cfgs = plat_mc_settings->num_txn_override_cfgs; + + /* + * Set the MC_TXN_OVERRIDE registers for write clients. + */ + if ((tegra_chipid_is_t186()) && + (!tegra_platform_is_silicon() || + (tegra_platform_is_silicon() && (tegra_get_chipid_minor() == 1U)))) { + + /* + * GPU and NVENC settings for Tegra186 simulation and + * Silicon rev. A01 + */ + val = tegra_mc_read_32(MC_TXN_OVERRIDE_CONFIG_GPUSWR); + val &= (uint32_t)~MC_TXN_OVERRIDE_CGID_TAG_MASK; + tegra_mc_write_32(MC_TXN_OVERRIDE_CONFIG_GPUSWR, + val | MC_TXN_OVERRIDE_CGID_TAG_ZERO); + + val = tegra_mc_read_32(MC_TXN_OVERRIDE_CONFIG_GPUSWR2); + val &= (uint32_t)~MC_TXN_OVERRIDE_CGID_TAG_MASK; + tegra_mc_write_32(MC_TXN_OVERRIDE_CONFIG_GPUSWR2, + val | MC_TXN_OVERRIDE_CGID_TAG_ZERO); + + val = tegra_mc_read_32(MC_TXN_OVERRIDE_CONFIG_NVENCSWR); + val &= (uint32_t)~MC_TXN_OVERRIDE_CGID_TAG_MASK; + tegra_mc_write_32(MC_TXN_OVERRIDE_CONFIG_NVENCSWR, + val | MC_TXN_OVERRIDE_CGID_TAG_CLIENT_AXI_ID); + + } else { + + /* + * Settings for Tegra186 silicon rev. A02 and onwards. + */ + for (i = 0; i < num_txn_override_cfgs; i++) { + val = tegra_mc_read_32(mc_txn_override_cfgs[i].offset); + val &= (uint32_t)~MC_TXN_OVERRIDE_CGID_TAG_MASK; + tegra_mc_write_32(mc_txn_override_cfgs[i].offset, + val | mc_txn_override_cfgs[i].cgid_tag); + } + } +} + /******************************************************************************* * Struct to hold the memory controller settings ******************************************************************************/ @@ -210,7 +525,9 @@ static tegra_mc_settings_t tegra186_mc_settings = { .streamid_security_cfg = tegra186_streamid_sec_cfgs, .num_streamid_security_cfgs = (uint32_t)ARRAY_SIZE(tegra186_streamid_sec_cfgs), .txn_override_cfg = tegra186_txn_override_cfgs, - .num_txn_override_cfgs = (uint32_t)ARRAY_SIZE(tegra186_txn_override_cfgs) + .num_txn_override_cfgs = (uint32_t)ARRAY_SIZE(tegra186_txn_override_cfgs), + .reconfig_mss_clients = tegra186_memctrl_reconfig_mss_clients, + .set_txn_overrides = tegra186_memctrl_set_overrides, }; /******************************************************************************* diff --git a/plat/nvidia/tegra/soc/t186/plat_smmu.c b/plat/nvidia/tegra/soc/t186/plat_smmu.c index b9541e830..95f6def9b 100644 --- a/plat/nvidia/tegra/soc/t186/plat_smmu.c +++ b/plat/nvidia/tegra/soc/t186/plat_smmu.c @@ -8,6 +8,7 @@ #include #include +#include #define MAX_NUM_SMMU_DEVICES U(1) From e4e97f1db9f2379777381ec8a6ec091f67ffa842 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Wed, 23 Jan 2019 09:41:28 -0800 Subject: [PATCH 02/27] Helper function to read ID_AFR0_EL1 system register This patch provides helper function to read the ID_AFR0_EL1 system register for platforms. Change-Id: Id5491b18e3bf9f619d98d6cc8efd9d2cf5918c9d Signed-off-by: Varun Wadekar --- include/arch/aarch64/arch_helpers.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/arch/aarch64/arch_helpers.h b/include/arch/aarch64/arch_helpers.h index d3f0df71d..4e459bbb9 100644 --- a/include/arch/aarch64/arch_helpers.h +++ b/include/arch/aarch64/arch_helpers.h @@ -185,6 +185,7 @@ DEFINE_SYSREG_READ_FUNC(id_pfr1_el1) DEFINE_SYSREG_READ_FUNC(id_aa64isar1_el1) DEFINE_SYSREG_READ_FUNC(id_aa64pfr0_el1) DEFINE_SYSREG_READ_FUNC(id_aa64dfr0_el1) +DEFINE_SYSREG_READ_FUNC(id_afr0_el1) DEFINE_SYSREG_READ_FUNC(CurrentEl) DEFINE_SYSREG_READ_FUNC(ctr_el0) DEFINE_SYSREG_RW_FUNCS(daif) From 8dc9278382515e4d84934ad8c43ccc7274caa774 Mon Sep 17 00:00:00 2001 From: Anthony Zhou Date: Tue, 29 Aug 2017 17:00:56 +0800 Subject: [PATCH 03/27] Tegra186: fix MISRA Rule 8.3 violation MISRA Rule 8.3, All declarations of an object or function shall use the same names and type qualifiers. This patch removes unused function(s). Change-Id: I90865c003d46f1dc08bfb5f4fe8a327ea42a2bb7 Signed-off-by: Anthony Zhou --- plat/nvidia/tegra/soc/t186/plat_psci_handlers.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c index a490bccd7..bd13dc2a1 100644 --- a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c +++ b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c @@ -25,8 +25,6 @@ #include extern void memcpy16(void *dest, const void *src, unsigned int length); - -extern void prepare_cpu_pwr_dwn(void); extern void tegra186_cpu_reset_handler(void); extern uint64_t __tegra186_cpu_reset_handler_end, __tegra186_smmu_context; From f9f620d6ac26288600780896837db83d5d2eb44f Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Thu, 31 Aug 2017 17:14:22 -0700 Subject: [PATCH 04/27] Tegra186: mce: use udelay() to calculate timeouts This patch modifies the timeout loop to use udelay() instead of mdelay(). This helps with the boot time on some platforms which issue a lot of MCE calls and every mdelay adds up increasing the boot time by a lot. Change-Id: Ic50081b73e1cbc2714361235b5c396e294b8f752 Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/soc/t186/drivers/mce/ari.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/plat/nvidia/tegra/soc/t186/drivers/mce/ari.c b/plat/nvidia/tegra/soc/t186/drivers/mce/ari.c index 9c4e57cae..602a0562d 100644 --- a/plat/nvidia/tegra/soc/t186/drivers/mce/ari.c +++ b/plat/nvidia/tegra/soc/t186/drivers/mce/ari.c @@ -35,8 +35,8 @@ #define ARI_REQUEST_VALID_BIT (1U << 8) #define ARI_EVT_MASK_STANDBYWFI_BIT (1U << 7) -/* default timeout (ms) to wait for ARI completion */ -#define ARI_MAX_RETRY_COUNT 2000 +/* default timeout (us) to wait for ARI completion */ +#define ARI_MAX_RETRY_COUNT U(2000000) /******************************************************************************* * ARI helper functions @@ -80,7 +80,7 @@ static inline void ari_clobber_response(uint32_t ari_base) static int32_t ari_request_wait(uint32_t ari_base, uint32_t evt_mask, uint32_t req, uint32_t lo, uint32_t hi) { - uint32_t retries = ARI_MAX_RETRY_COUNT; + uint32_t retries = (uint32_t)ARI_MAX_RETRY_COUNT; uint32_t status; int32_t ret = 0; @@ -115,8 +115,8 @@ static int32_t ari_request_wait(uint32_t ari_base, uint32_t evt_mask, uint32_t r break; } - /* delay 1 ms */ - mdelay(1); + /* delay 1 us */ + udelay(1); /* decrement the retry count */ retries--; From f8f400d2e5a0cf1728374daf207ad966d880ecef Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Wed, 6 Sep 2017 10:48:27 -0700 Subject: [PATCH 05/27] Tegra186: mce: get the "right" uncore command/response bits This patch corrects the logic to read the uncore command/response bits from the command/response values. The previous logic tapped into incorrect bits leading to garbage counter values. Change-Id: Ib8327ca3cb3d2086bb268e9a5366865cdf35b493 Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/soc/t186/drivers/include/mce_private.h | 4 +--- plat/nvidia/tegra/soc/t186/drivers/mce/ari.c | 4 ++-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/plat/nvidia/tegra/soc/t186/drivers/include/mce_private.h b/plat/nvidia/tegra/soc/t186/drivers/include/mce_private.h index 96a5525a6..203f61a5d 100644 --- a/plat/nvidia/tegra/soc/t186/drivers/include/mce_private.h +++ b/plat/nvidia/tegra/soc/t186/drivers/include/mce_private.h @@ -64,19 +64,17 @@ #define MCA_ARG_FINISH_MASK U(0xFF) /******************************************************************************* - * Uncore PERFMON ARI struct + * Uncore PERFMON ARI macros ******************************************************************************/ #define UNCORE_PERFMON_CMD_READ U(0) #define UNCORE_PERFMON_CMD_WRITE U(1) #define UNCORE_PERFMON_CMD_MASK U(0xFF) -#define UNCORE_PERFMON_CMD_SHIFT U(24) #define UNCORE_PERFMON_UNIT_GRP_MASK U(0xF) #define UNCORE_PERFMON_SELECTOR_MASK U(0xF) #define UNCORE_PERFMON_REG_MASK U(0xFF) #define UNCORE_PERFMON_CTR_MASK U(0xFF) #define UNCORE_PERFMON_RESP_STATUS_MASK U(0xFF) -#define UNCORE_PERFMON_RESP_STATUS_SHIFT U(24) /******************************************************************************* * Structure populated by arch specific code to export routines which perform diff --git a/plat/nvidia/tegra/soc/t186/drivers/mce/ari.c b/plat/nvidia/tegra/soc/t186/drivers/mce/ari.c index 602a0562d..a57bc11b9 100644 --- a/plat/nvidia/tegra/soc/t186/drivers/mce/ari.c +++ b/plat/nvidia/tegra/soc/t186/drivers/mce/ari.c @@ -503,7 +503,7 @@ int32_t ari_read_write_uncore_perfmon(uint32_t ari_base, uint64_t req, uint32_t val, req_status; uint8_t req_cmd; - req_cmd = (uint8_t)(req >> UNCORE_PERFMON_CMD_SHIFT); + req_cmd = (uint8_t)(req & UNCORE_PERFMON_CMD_MASK); /* clean the previous response state */ ari_clobber_response(ari_base); @@ -533,7 +533,7 @@ int32_t ari_read_write_uncore_perfmon(uint32_t ari_base, uint64_t req, * For "read" commands get the data from the uncore * perfmon registers */ - req_status >>= UNCORE_PERFMON_RESP_STATUS_SHIFT; + req_status &= UNCORE_PERFMON_RESP_STATUS_MASK; if ((req_status == 0U) && (req_cmd == UNCORE_PERFMON_CMD_READ)) { *data = ari_get_response_low(ari_base); } From 7f9d75d236116a4b6f2f2bf249fefa2a1baed5c0 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Wed, 6 Sep 2017 17:17:12 -0700 Subject: [PATCH 06/27] Tegra: enable -nostdlib flag This patch enables the '-nostdlib' flag to instruct the compiler to not use the standard system libraries and startup files. Change-Id: Ibf34856f7579ed686280cee19c35d08448cf921c Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/platform.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plat/nvidia/tegra/platform.mk b/plat/nvidia/tegra/platform.mk index ac110cc05..614d2a26d 100644 --- a/plat/nvidia/tegra/platform.mk +++ b/plat/nvidia/tegra/platform.mk @@ -40,5 +40,5 @@ include ${SOC_DIR}/platform_${TARGET_SOC}.mk # modify BUILD_PLAT to point to SoC specific build directory BUILD_PLAT := ${BUILD_BASE}/${PLAT}/${TARGET_SOC}/${BUILD_TYPE} -# enable signed comparison checks -TF_CFLAGS += -Wsign-compare +# platform cflags (enable signed comparisons, disable stdlib) +TF_CFLAGS += -Wsign-compare -nostdlib From b886c7c5f4e5170543844c62d8dd336f47d0225f Mon Sep 17 00:00:00 2001 From: Harvey Hsieh Date: Mon, 18 Sep 2017 19:22:01 +0800 Subject: [PATCH 07/27] Tegra: memctrl_v2: pack TZDRAM base to RSVD55_SCRATCH This patch saves the TZDRAM_BASE value to secure RSVD55 scratch register. The warmboot code uses this register to restore the settings on exiting System Suspend. Change-Id: Id76175c2a7d931227589468511365599e2908411 Signed-off-by: Harvey Hsieh --- plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c | 2 -- plat/nvidia/tegra/include/t186/tegra_def.h | 1 - 2 files changed, 3 deletions(-) diff --git a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c index b1ccf5073..bd601e4b3 100644 --- a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c +++ b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c @@ -167,8 +167,6 @@ void tegra_memctrl_tzdram_setup(uint64_t phys_base, uint32_t size_in_bytes) */ val = tegra_mc_read_32(MC_SECURITY_CFG1_0) & MC_SECURITY_SIZE_MB_MASK; - mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV54_HI, val); - val |= tegra_mc_read_32(MC_SECURITY_CFG0_0) & MC_SECURITY_BOM_MASK; mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV55_LO, val); diff --git a/plat/nvidia/tegra/include/t186/tegra_def.h b/plat/nvidia/tegra/include/t186/tegra_def.h index 20a799475..6a0912e54 100644 --- a/plat/nvidia/tegra/include/t186/tegra_def.h +++ b/plat/nvidia/tegra/include/t186/tegra_def.h @@ -232,7 +232,6 @@ #define SECURE_SCRATCH_RSV11_HI U(0x6AC) #define SECURE_SCRATCH_RSV53_LO U(0x7F8) #define SECURE_SCRATCH_RSV53_HI U(0x7FC) -#define SECURE_SCRATCH_RSV54_HI U(0x804) #define SECURE_SCRATCH_RSV55_LO U(0x808) #define SECURE_SCRATCH_RSV55_HI U(0x80C) From 91196b02a6f48477f0b0bfa30e06bc212d1a83d2 Mon Sep 17 00:00:00 2001 From: Anthony Zhou Date: Fri, 8 Sep 2017 15:53:40 +0800 Subject: [PATCH 08/27] Tegra: lib: debug: fix MISRA violation Rule 21.6 MISRA Rule 21.6, The standard library input/output functions shall not be used. This patch removes headers that are not really needed. Change-Id: I746138ce7ee95d7ca985d020f89b2738d997a7a2 Signed-off-by: Anthony Zhou --- plat/nvidia/tegra/common/lib/debug/profiler.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/plat/nvidia/tegra/common/lib/debug/profiler.c b/plat/nvidia/tegra/common/lib/debug/profiler.c index f40244be1..d4c3f9595 100644 --- a/plat/nvidia/tegra/common/lib/debug/profiler.c +++ b/plat/nvidia/tegra/common/lib/debug/profiler.c @@ -26,8 +26,6 @@ #include #include #include -#include -#include #include #include #include From d6306d14bd4fe50aac29dd422a4c5a5c29fb1166 Mon Sep 17 00:00:00 2001 From: Steven Kao Date: Wed, 6 Sep 2017 13:32:21 +0800 Subject: [PATCH 09/27] Tegra: memctrl_v2: allow CPU accesses to TZRAM This patch enables CPU access configuration register to allow accesses to the TZRAM aperture on chips after Tegra186. Change-Id: I0898582f8bd6fd35360ecf8ca5cee21fe35f7aab Signed-off-by: Steven Kao --- .../tegra/common/drivers/memctrl/memctrl_v2.c | 14 +++++++++++++- plat/nvidia/tegra/include/t186/tegra_def.h | 6 +++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c index bd601e4b3..e12031441 100644 --- a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c +++ b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c @@ -199,12 +199,21 @@ void tegra_memctrl_tzram_setup(uint64_t phys_base, uint32_t size_in_bytes) * Reset the access configuration registers to restrict access * to the TZRAM aperture */ - for (index = MC_TZRAM_CLIENT_ACCESS_CFG0; + for (index = MC_TZRAM_CLIENT_ACCESS0_CFG0; index < ((uint32_t)MC_TZRAM_CARVEOUT_CFG + (uint32_t)MC_GSC_CONFIG_REGS_SIZE); index += 4U) { tegra_mc_write_32(index, 0); } + /* + * Enable CPU access configuration registers to access the TZRAM aperture + */ + if (!tegra_chipid_is_t186()) { + val = tegra_mc_read_32(MC_TZRAM_CLIENT_ACCESS1_CFG0); + val |= TZRAM_ALLOW_MPCORER | TZRAM_ALLOW_MPCOREW; + tegra_mc_write_32(MC_TZRAM_CLIENT_ACCESS1_CFG0, val); + } + /* * Set the TZRAM base. TZRAM base must be 4k aligned, at least. */ @@ -232,6 +241,9 @@ void tegra_memctrl_tzram_setup(uint64_t phys_base, uint32_t size_in_bytes) val = tegra_mc_read_32(MC_TZRAM_CARVEOUT_CFG); val &= (uint32_t)~MC_GSC_ENABLE_TZ_LOCK_BIT; val |= MC_GSC_LOCK_CFG_SETTINGS_BIT; + if (!tegra_chipid_is_t186()) { + val |= MC_GSC_ENABLE_CPU_SECURE_BIT; + } tegra_mc_write_32(MC_TZRAM_CARVEOUT_CFG, val); /* diff --git a/plat/nvidia/tegra/include/t186/tegra_def.h b/plat/nvidia/tegra/include/t186/tegra_def.h index 6a0912e54..8dee50704 100644 --- a/plat/nvidia/tegra/include/t186/tegra_def.h +++ b/plat/nvidia/tegra/include/t186/tegra_def.h @@ -135,6 +135,7 @@ #define MC_GSC_BASE_LO_MASK U(0xFFFFF) #define MC_GSC_BASE_HI_SHIFT U(0) #define MC_GSC_BASE_HI_MASK U(3) +#define MC_GSC_ENABLE_CPU_SECURE_BIT (U(1) << 31) /* TZDRAM carveout configuration registers */ #define MC_SECURITY_CFG0_0 U(0x70) @@ -165,7 +166,10 @@ #define MC_TZRAM_BASE_LO U(0x2194) #define MC_TZRAM_BASE_HI U(0x2198) #define MC_TZRAM_SIZE U(0x219C) -#define MC_TZRAM_CLIENT_ACCESS_CFG0 U(0x21A0) +#define MC_TZRAM_CLIENT_ACCESS0_CFG0 U(0x21A0) +#define MC_TZRAM_CLIENT_ACCESS1_CFG0 U(0x21A4) +#define TZRAM_ALLOW_MPCORER (U(1) << 7) +#define TZRAM_ALLOW_MPCOREW (U(1) << 25) /******************************************************************************* * Tegra UART Controller constants From 591054a3757d480af05a5c15234be4e1e3792699 Mon Sep 17 00:00:00 2001 From: Anthony Zhou Date: Tue, 19 Sep 2017 16:36:22 +0800 Subject: [PATCH 10/27] spd: trusty : fix defects flagged by MISRA scan Main Fixes: Use int32_t replace int [Rule 4.6] Added explicit casts (e.g. 0U) to integers in order for them to be compatible with whatever operation they're used in [Rule 10.1] Force operands of an operator to the same type category [Rule 10.4] Fixed if statement conditional to be essentially boolean [Rule 14.4] Voided non c-library functions whose return types are not used [Rule 17.7] Change-Id: I98caa330c371757eb2dfb9438448cb99115ed907 Signed-off-by: Anthony Zhou --- services/spd/trusty/smcall.h | 91 ++++++++++++++------------- services/spd/trusty/trusty.c | 117 ++++++++++++++++++----------------- 2 files changed, 106 insertions(+), 102 deletions(-) diff --git a/services/spd/trusty/smcall.h b/services/spd/trusty/smcall.h index 742c8c43e..9c1c38c74 100644 --- a/services/spd/trusty/smcall.h +++ b/services/spd/trusty/smcall.h @@ -7,69 +7,68 @@ #ifndef SMCALL_H #define SMCALL_H -#define SMC_NUM_ENTITIES 64 -#define SMC_NUM_ARGS 4 -#define SMC_NUM_PARAMS (SMC_NUM_ARGS - 1) +#define SMC_NUM_ENTITIES 64U +#define SMC_NUM_ARGS 4U +#define SMC_NUM_PARAMS (SMC_NUM_ARGS - 1U) -#define SMC_IS_FASTCALL(smc_nr) ((smc_nr) & 0x80000000) -#define SMC_IS_SMC64(smc_nr) ((smc_nr) & 0x40000000) -#define SMC_ENTITY(smc_nr) (((smc_nr) & 0x3F000000) >> 24) -#define SMC_FUNCTION(smc_nr) ((smc_nr) & 0x0000FFFF) +#define SMC_IS_FASTCALL(smc_nr) ((smc_nr) & 0x80000000U) +#define SMC_IS_SMC64(smc_nr) ((smc_nr) & 0x40000000U) +#define SMC_ENTITY(smc_nr) (((smc_nr) & 0x3F000000U) >> 24U) +#define SMC_FUNCTION(smc_nr) ((smc_nr) & 0x0000FFFFU) #define SMC_NR(entity, fn, fastcall, smc64) \ - (((((unsigned int) (fastcall)) & 0x1) << 31) | \ - (((smc64) & 0x1) << 30) | \ - (((entity) & 0x3F) << 24) | \ - ((fn) & 0xFFFF) \ - ) + (((((uint32_t)(fastcall)) & 0x1U) << 31U) | \ + (((smc64) & 0x1U) << 30U) | \ + (((entity) & 0x3FU) << 24U) | \ + ((fn) & 0xFFFFU)) -#define SMC_FASTCALL_NR(entity, fn) SMC_NR((entity), (fn), 1, 0) -#define SMC_FASTCALL64_NR(entity, fn) SMC_NR((entity), (fn), 1, 1) -#define SMC_YIELDCALL_NR(entity, fn) SMC_NR((entity), (fn), 0, 0) -#define SMC_YIELDCALL64_NR(entity, fn) SMC_NR((entity), (fn), 0, 1) +#define SMC_FASTCALL_NR(entity, fn) SMC_NR((entity), (fn), 1U, 0U) +#define SMC_FASTCALL64_NR(entity, fn) SMC_NR((entity), (fn), 1U, 1U) +#define SMC_YIELDCALL_NR(entity, fn) SMC_NR((entity), (fn), 0U, 0U) +#define SMC_YIELDCALL64_NR(entity, fn) SMC_NR((entity), (fn), 0U, 1U) -#define SMC_ENTITY_ARCH 0 /* ARM Architecture calls */ -#define SMC_ENTITY_CPU 1 /* CPU Service calls */ -#define SMC_ENTITY_SIP 2 /* SIP Service calls */ -#define SMC_ENTITY_OEM 3 /* OEM Service calls */ -#define SMC_ENTITY_STD 4 /* Standard Service calls */ -#define SMC_ENTITY_RESERVED 5 /* Reserved for future use */ -#define SMC_ENTITY_TRUSTED_APP 48 /* Trusted Application calls */ -#define SMC_ENTITY_TRUSTED_OS 50 /* Trusted OS calls */ -#define SMC_ENTITY_LOGGING 51 /* Used for secure -> nonsecure logging */ -#define SMC_ENTITY_SECURE_MONITOR 60 /* Trusted OS calls internal to secure monitor */ +#define SMC_ENTITY_ARCH 0U /* ARM Architecture calls */ +#define SMC_ENTITY_CPU 1U /* CPU Service calls */ +#define SMC_ENTITY_SIP 2U /* SIP Service calls */ +#define SMC_ENTITY_OEM 3U /* OEM Service calls */ +#define SMC_ENTITY_STD 4U /* Standard Service calls */ +#define SMC_ENTITY_RESERVED 5U /* Reserved for future use */ +#define SMC_ENTITY_TRUSTED_APP 48U /* Trusted Application calls */ +#define SMC_ENTITY_TRUSTED_OS 50U /* Trusted OS calls */ +#define SMC_ENTITY_LOGGING 51U /* Used for secure -> nonsecure logging */ +#define SMC_ENTITY_SECURE_MONITOR 60U /* Trusted OS calls internal to secure monitor */ /* FC = Fast call, YC = Yielding call */ -#define SMC_YC_RESTART_LAST SMC_YIELDCALL_NR (SMC_ENTITY_SECURE_MONITOR, 0) -#define SMC_YC_NOP SMC_YIELDCALL_NR (SMC_ENTITY_SECURE_MONITOR, 1) +#define SMC_YC_RESTART_LAST SMC_YIELDCALL_NR (SMC_ENTITY_SECURE_MONITOR, 0U) +#define SMC_YC_NOP SMC_YIELDCALL_NR (SMC_ENTITY_SECURE_MONITOR, 1U) /* * Return from secure os to non-secure os with return value in r1 */ -#define SMC_YC_NS_RETURN SMC_YIELDCALL_NR (SMC_ENTITY_SECURE_MONITOR, 0) +#define SMC_YC_NS_RETURN SMC_YIELDCALL_NR (SMC_ENTITY_SECURE_MONITOR, 0U) -#define SMC_FC_RESERVED SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 0) -#define SMC_FC_FIQ_EXIT SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 1) -#define SMC_FC_REQUEST_FIQ SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 2) -#define SMC_FC_GET_NEXT_IRQ SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 3) -#define SMC_FC_FIQ_ENTER SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 4) +#define SMC_FC_RESERVED SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 0U) +#define SMC_FC_FIQ_EXIT SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 1U) +#define SMC_FC_REQUEST_FIQ SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 2U) +#define SMC_FC_GET_NEXT_IRQ SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 3U) +#define SMC_FC_FIQ_ENTER SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 4U) -#define SMC_FC64_SET_FIQ_HANDLER SMC_FASTCALL64_NR(SMC_ENTITY_SECURE_MONITOR, 5) -#define SMC_FC64_GET_FIQ_REGS SMC_FASTCALL64_NR (SMC_ENTITY_SECURE_MONITOR, 6) +#define SMC_FC64_SET_FIQ_HANDLER SMC_FASTCALL64_NR(SMC_ENTITY_SECURE_MONITOR, 5U) +#define SMC_FC64_GET_FIQ_REGS SMC_FASTCALL64_NR (SMC_ENTITY_SECURE_MONITOR, 6U) -#define SMC_FC_CPU_SUSPEND SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 7) -#define SMC_FC_CPU_RESUME SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 8) +#define SMC_FC_CPU_SUSPEND SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 7U) +#define SMC_FC_CPU_RESUME SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 8U) -#define SMC_FC_AARCH_SWITCH SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 9) -#define SMC_FC_GET_VERSION_STR SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 10) +#define SMC_FC_AARCH_SWITCH SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 9U) +#define SMC_FC_GET_VERSION_STR SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 10U) /* Trusted OS entity calls */ -#define SMC_YC_VIRTIO_GET_DESCR SMC_YIELDCALL_NR(SMC_ENTITY_TRUSTED_OS, 20) -#define SMC_YC_VIRTIO_START SMC_YIELDCALL_NR(SMC_ENTITY_TRUSTED_OS, 21) -#define SMC_YC_VIRTIO_STOP SMC_YIELDCALL_NR(SMC_ENTITY_TRUSTED_OS, 22) +#define SMC_YC_VIRTIO_GET_DESCR SMC_YIELDCALL_NR(SMC_ENTITY_TRUSTED_OS, 20U) +#define SMC_YC_VIRTIO_START SMC_YIELDCALL_NR(SMC_ENTITY_TRUSTED_OS, 21U) +#define SMC_YC_VIRTIO_STOP SMC_YIELDCALL_NR(SMC_ENTITY_TRUSTED_OS, 22U) -#define SMC_YC_VDEV_RESET SMC_YIELDCALL_NR(SMC_ENTITY_TRUSTED_OS, 23) -#define SMC_YC_VDEV_KICK_VQ SMC_YIELDCALL_NR(SMC_ENTITY_TRUSTED_OS, 24) -#define SMC_YC_SET_ROT_PARAMS SMC_YIELDCALL_NR(SMC_ENTITY_TRUSTED_OS, 65535) +#define SMC_YC_VDEV_RESET SMC_YIELDCALL_NR(SMC_ENTITY_TRUSTED_OS, 23U) +#define SMC_YC_VDEV_KICK_VQ SMC_YIELDCALL_NR(SMC_ENTITY_TRUSTED_OS, 24U) +#define SMC_YC_SET_ROT_PARAMS SMC_YIELDCALL_NR(SMC_ENTITY_TRUSTED_OS, 65535U) #endif /* SMCALL_H */ diff --git a/services/spd/trusty/trusty.c b/services/spd/trusty/trusty.c index c9d73f0eb..0305143dc 100644 --- a/services/spd/trusty/trusty.c +++ b/services/spd/trusty/trusty.c @@ -21,7 +21,10 @@ #include "smcall.h" /* macro to check if Hypervisor is enabled in the HCR_EL2 register */ -#define HYP_ENABLE_FLAG 0x286001 +#define HYP_ENABLE_FLAG 0x286001U + +/* length of Trusty's input parameters (in bytes) */ +#define TRUSTY_PARAMS_LEN_BYTES (4096U * 2) struct trusty_stack { uint8_t space[PLATFORM_STACK_SIZE] __aligned(16); @@ -32,7 +35,7 @@ struct trusty_cpu_ctx { cpu_context_t cpu_ctx; void *saved_sp; uint32_t saved_security_state; - int fiq_handler_active; + int32_t fiq_handler_active; uint64_t fiq_handler_pc; uint64_t fiq_handler_cpsr; uint64_t fiq_handler_sp; @@ -43,7 +46,7 @@ struct trusty_cpu_ctx { struct trusty_stack secure_stack; }; -struct args { +struct smc_args { uint64_t r0; uint64_t r1; uint64_t r2; @@ -56,8 +59,8 @@ struct args { static struct trusty_cpu_ctx trusty_cpu_ctx[PLATFORM_CORE_COUNT]; -struct args trusty_init_context_stack(void **sp, void *new_stack); -struct args trusty_context_switch_helper(void **sp, void *smc_params); +struct smc_args trusty_init_context_stack(void **sp, void *new_stack); +struct smc_args trusty_context_switch_helper(void **sp, void *smc_params); static uint32_t current_vmid; @@ -66,37 +69,37 @@ static struct trusty_cpu_ctx *get_trusty_ctx(void) return &trusty_cpu_ctx[plat_my_core_pos()]; } -static uint32_t is_hypervisor_mode(void) +static bool is_hypervisor_mode(void) { uint64_t hcr = read_hcr(); - return !!(hcr & HYP_ENABLE_FLAG); + return ((hcr & HYP_ENABLE_FLAG) != 0U) ? true : false; } -static struct args trusty_context_switch(uint32_t security_state, uint64_t r0, +static struct smc_args trusty_context_switch(uint32_t security_state, uint64_t r0, uint64_t r1, uint64_t r2, uint64_t r3) { - struct args ret; + struct smc_args args, ret_args; struct trusty_cpu_ctx *ctx = get_trusty_ctx(); struct trusty_cpu_ctx *ctx_smc; assert(ctx->saved_security_state != security_state); - ret.r7 = 0; + args.r7 = 0; if (is_hypervisor_mode()) { /* According to the ARM DEN0028A spec, VMID is stored in x7 */ ctx_smc = cm_get_context(NON_SECURE); - assert(ctx_smc); - ret.r7 = SMC_GET_GP(ctx_smc, CTX_GPREG_X7); + assert(ctx_smc != NULL); + args.r7 = SMC_GET_GP(ctx_smc, CTX_GPREG_X7); } /* r4, r5, r6 reserved for future use. */ - ret.r6 = 0; - ret.r5 = 0; - ret.r4 = 0; - ret.r3 = r3; - ret.r2 = r2; - ret.r1 = r1; - ret.r0 = r0; + args.r6 = 0; + args.r5 = 0; + args.r4 = 0; + args.r3 = r3; + args.r2 = r2; + args.r1 = r1; + args.r0 = r0; /* * To avoid the additional overhead in PSCI flow, skip FP context @@ -109,9 +112,9 @@ static struct args trusty_context_switch(uint32_t security_state, uint64_t r0, cm_el1_sysregs_context_save(security_state); ctx->saved_security_state = security_state; - ret = trusty_context_switch_helper(&ctx->saved_sp, &ret); + ret_args = trusty_context_switch_helper(&ctx->saved_sp, &args); - assert(ctx->saved_security_state == !security_state); + assert(ctx->saved_security_state == ((security_state == 0U) ? 1U : 0U)); cm_el1_sysregs_context_restore(security_state); if (r0 != SMC_FC_CPU_SUSPEND && r0 != SMC_FC_CPU_RESUME) @@ -119,7 +122,7 @@ static struct args trusty_context_switch(uint32_t security_state, uint64_t r0, cm_set_next_eret_context(security_state); - return ret; + return ret_args; } static uint64_t trusty_fiq_handler(uint32_t id, @@ -127,29 +130,29 @@ static uint64_t trusty_fiq_handler(uint32_t id, void *handle, void *cookie) { - struct args ret; + struct smc_args ret; struct trusty_cpu_ctx *ctx = get_trusty_ctx(); assert(!is_caller_secure(flags)); ret = trusty_context_switch(NON_SECURE, SMC_FC_FIQ_ENTER, 0, 0, 0); - if (ret.r0) { + if (ret.r0 != 0U) { SMC_RET0(handle); } - if (ctx->fiq_handler_active) { + if (ctx->fiq_handler_active != 0) { INFO("%s: fiq handler already active\n", __func__); SMC_RET0(handle); } ctx->fiq_handler_active = 1; - memcpy(&ctx->fiq_gpregs, get_gpregs_ctx(handle), sizeof(ctx->fiq_gpregs)); + (void)memcpy(&ctx->fiq_gpregs, get_gpregs_ctx(handle), sizeof(ctx->fiq_gpregs)); ctx->fiq_pc = SMC_GET_EL3(handle, CTX_ELR_EL3); ctx->fiq_cpsr = SMC_GET_EL3(handle, CTX_SPSR_EL3); ctx->fiq_sp_el1 = read_ctx_reg(get_sysregs_ctx(handle), CTX_SP_EL1); write_ctx_reg(get_sysregs_ctx(handle), CTX_SP_EL1, ctx->fiq_handler_sp); - cm_set_elr_spsr_el3(NON_SECURE, ctx->fiq_handler_pc, ctx->fiq_handler_cpsr); + cm_set_elr_spsr_el3(NON_SECURE, ctx->fiq_handler_pc, (uint32_t)ctx->fiq_handler_cpsr); SMC_RET0(handle); } @@ -159,9 +162,9 @@ static uint64_t trusty_set_fiq_handler(void *handle, uint64_t cpu, { struct trusty_cpu_ctx *ctx; - if (cpu >= PLATFORM_CORE_COUNT) { + if (cpu >= (uint64_t)PLATFORM_CORE_COUNT) { ERROR("%s: cpu %lld >= %d\n", __func__, cpu, PLATFORM_CORE_COUNT); - return SM_ERR_INVALID_PARAMETERS; + return (uint64_t)SM_ERR_INVALID_PARAMETERS; } ctx = &trusty_cpu_ctx[cpu]; @@ -182,16 +185,16 @@ static uint64_t trusty_get_fiq_regs(void *handle) static uint64_t trusty_fiq_exit(void *handle, uint64_t x1, uint64_t x2, uint64_t x3) { - struct args ret; + struct smc_args ret; struct trusty_cpu_ctx *ctx = get_trusty_ctx(); - if (!ctx->fiq_handler_active) { + if (ctx->fiq_handler_active == 0) { NOTICE("%s: fiq handler not active\n", __func__); - SMC_RET1(handle, SM_ERR_INVALID_PARAMETERS); + SMC_RET1(handle, (uint64_t)SM_ERR_INVALID_PARAMETERS); } ret = trusty_context_switch(NON_SECURE, SMC_FC_FIQ_EXIT, 0, 0, 0); - if (ret.r0 != 1) { + if (ret.r0 != 1U) { INFO("%s(%p) SMC_FC_FIQ_EXIT returned unexpected value, %lld\n", __func__, handle, ret.r0); } @@ -205,10 +208,10 @@ static uint64_t trusty_fiq_exit(void *handle, uint64_t x1, uint64_t x2, uint64_t * x1-x4 and x8-x17 need to be restored here because smc_handler64 * corrupts them (el1 code also restored them). */ - memcpy(get_gpregs_ctx(handle), &ctx->fiq_gpregs, sizeof(ctx->fiq_gpregs)); + (void)memcpy(get_gpregs_ctx(handle), &ctx->fiq_gpregs, sizeof(ctx->fiq_gpregs)); ctx->fiq_handler_active = 0; write_ctx_reg(get_sysregs_ctx(handle), CTX_SP_EL1, ctx->fiq_sp_el1); - cm_set_elr_spsr_el3(NON_SECURE, ctx->fiq_pc, ctx->fiq_cpsr); + cm_set_elr_spsr_el3(NON_SECURE, ctx->fiq_pc, (uint32_t)ctx->fiq_cpsr); SMC_RET0(handle); } @@ -222,8 +225,8 @@ static uintptr_t trusty_smc_handler(uint32_t smc_fid, void *handle, u_register_t flags) { - struct args ret; - uint32_t vmid = 0; + struct smc_args ret; + uint32_t vmid = 0U; entry_point_info_t *ep_info = bl31_plat_get_next_image_ep_info(SECURE); /* @@ -231,10 +234,12 @@ static uintptr_t trusty_smc_handler(uint32_t smc_fid, * Verified Boot is not even supported and returning success here * would not compromise the boot process. */ - if (!ep_info && (smc_fid == SMC_YC_SET_ROT_PARAMS)) { + if ((ep_info == NULL) && (smc_fid == SMC_YC_SET_ROT_PARAMS)) { SMC_RET1(handle, 0); - } else if (!ep_info) { + } else if (ep_info == NULL) { SMC_RET1(handle, SMC_UNK); + } else { + ; /* do nothing */ } if (is_caller_secure(flags)) { @@ -279,12 +284,11 @@ static uintptr_t trusty_smc_handler(uint32_t smc_fid, static int32_t trusty_init(void) { - void el3_exit(void); entry_point_info_t *ep_info; - struct args zero_args = {0}; + struct smc_args zero_args = {0}; struct trusty_cpu_ctx *ctx = get_trusty_ctx(); uint32_t cpu = plat_my_core_pos(); - int reg_width = GET_RW(read_ctx_reg(get_el3state_ctx(&ctx->cpu_ctx), + uint64_t reg_width = GET_RW(read_ctx_reg(get_el3state_ctx(&ctx->cpu_ctx), CTX_SPSR_EL3)); /* @@ -292,7 +296,7 @@ static int32_t trusty_init(void) * failure. */ ep_info = bl31_plat_get_next_image_ep_info(SECURE); - assert(ep_info); + assert(ep_info != NULL); fpregs_context_save(get_fpregs_ctx(cm_get_context(NON_SECURE))); cm_el1_sysregs_context_save(NON_SECURE); @@ -304,7 +308,7 @@ static int32_t trusty_init(void) * Adjust secondary cpu entry point for 32 bit images to the * end of exception vectors */ - if ((cpu != 0) && (reg_width == MODE_RW_32)) { + if ((cpu != 0U) && (reg_width == MODE_RW_32)) { INFO("trusty: cpu %d, adjust entry point to 0x%lx\n", cpu, ep_info->pc + (1U << 5)); cm_set_elr_el3(SECURE, ep_info->pc + (1U << 5)); @@ -314,10 +318,10 @@ static int32_t trusty_init(void) fpregs_context_restore(get_fpregs_ctx(cm_get_context(SECURE))); cm_set_next_eret_context(SECURE); - ctx->saved_security_state = ~0; /* initial saved state is invalid */ - trusty_init_context_stack(&ctx->saved_sp, &ctx->secure_stack.end); + ctx->saved_security_state = ~0U; /* initial saved state is invalid */ + (void)trusty_init_context_stack(&ctx->saved_sp, &ctx->secure_stack.end); - trusty_context_switch_helper(&ctx->saved_sp, &zero_args); + (void)trusty_context_switch_helper(&ctx->saved_sp, &zero_args); cm_el1_sysregs_context_restore(NON_SECURE); fpregs_context_restore(get_fpregs_ctx(cm_get_context(NON_SECURE))); @@ -328,10 +332,10 @@ static int32_t trusty_init(void) static void trusty_cpu_suspend(uint32_t off) { - struct args ret; + struct smc_args ret; ret = trusty_context_switch(NON_SECURE, SMC_FC_CPU_SUSPEND, off, 0, 0); - if (ret.r0 != 0) { + if (ret.r0 != 0U) { INFO("%s: cpu %d, SMC_FC_CPU_SUSPEND returned unexpected value, %lld\n", __func__, plat_my_core_pos(), ret.r0); } @@ -339,10 +343,10 @@ static void trusty_cpu_suspend(uint32_t off) static void trusty_cpu_resume(uint32_t on) { - struct args ret; + struct smc_args ret; ret = trusty_context_switch(NON_SECURE, SMC_FC_CPU_RESUME, on, 0, 0); - if (ret.r0 != 0) { + if (ret.r0 != 0U) { INFO("%s: cpu %d, SMC_FC_CPU_RESUME returned unexpected value, %lld\n", __func__, plat_my_core_pos(), ret.r0); } @@ -359,8 +363,8 @@ static void trusty_cpu_on_finish_handler(u_register_t unused) { struct trusty_cpu_ctx *ctx = get_trusty_ctx(); - if (!ctx->saved_sp) { - trusty_init(); + if (ctx->saved_sp == NULL) { + (void)trusty_init(); } else { trusty_cpu_resume(1); } @@ -398,12 +402,12 @@ static int32_t trusty_setup(void) entry_point_info_t *ep_info; uint32_t instr; uint32_t flags; - int ret; + int32_t ret; bool aarch32 = false; /* Get trusty's entry point info */ ep_info = bl31_plat_get_next_image_ep_info(SECURE); - if (!ep_info) { + if (ep_info == NULL) { INFO("Trusty image missing.\n"); return -1; } @@ -444,8 +448,9 @@ static int32_t trusty_setup(void) ret = register_interrupt_type_handler(INTR_TYPE_S_EL1, trusty_fiq_handler, flags); - if (ret) + if (ret != 0) { ERROR("trusty: failed to register fiq handler, ret = %d\n", ret); + } if (aarch32) { entry_point_info_t *ns_ep_info; From 01da3bd2db5b9940fda3c84e31486473d75d185f Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Wed, 20 Sep 2017 15:09:38 -0700 Subject: [PATCH 11/27] Tegra: call 'early_init' handler earlier during boot This patch calls the 'early_init' handler earlier during boot. This allows the platforms using Tegra186 onwards to init the BPMP interface earlier. Change-Id: I0d540df39de7864ce9051ebe11eca5432c462ebf Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/common/tegra_bl31_setup.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plat/nvidia/tegra/common/tegra_bl31_setup.c b/plat/nvidia/tegra/common/tegra_bl31_setup.c index afb10fef4..4712b8ab6 100644 --- a/plat/nvidia/tegra/common/tegra_bl31_setup.c +++ b/plat/nvidia/tegra/common/tegra_bl31_setup.c @@ -227,6 +227,9 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, */ tegra_delay_timer_init(); + /* Early platform setup for Tegra SoCs */ + plat_early_platform_setup(); + /* * Do initial security configuration to allow DRAM/device access. */ @@ -269,9 +272,6 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, } } - /* Early platform setup for Tegra SoCs */ - plat_early_platform_setup(); - /* * Add timestamp for platform early setup exit. */ From 26e2b93a85a772a4098c93422a41ddae50e3e918 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Mon, 25 Sep 2017 13:27:45 -0700 Subject: [PATCH 12/27] Tegra: bpmp_ipc: IPC driver to communicate with BPMP firmware This patch adds the driver to communicate with the BPMP firmware on Tegra SoCs, starting Tegra186. BPMP firmware is responsible for clock enable/ disable requests, module resets among other things. MRQ is short for Message ReQuest. This is the general purpose, multi channel messaging protocol that is widely used to communicate with BPMP. This is further divided into a common high level protocol and a peer-specific low level protocol. The higher level protocol specifies the peer identification, channel definition and allocation, message structure, message semantics and message dispatch process whereas the lower level protocol defines actual message transfer implementation details. Currently, BPMP supports two lower level protocols - Token Mail Operations (TMO), IVC Mail Operations (IMO). This driver implements the IMO protocol. IMO is implemented using the IVC (Inter-VM Communication) protocol which is a lockless, shared memory messaging queue management protocol. The IVC peer is expected to perform the following as part of establishing a connection with BPMP. 1. Initialize the channels with tegra_ivc_init() or its equivalent. 2. Reset the channel with tegra_ivc_channel_reset. The peer should also ensure that BPMP is notified via the doorbell. 3. Poll until the channel connection is established [tegra_ivc_channel_notified() return 0]. Interrupt BPMP with doorbell each time after tegra_ivc_channel_notified() return non zero. The IPC driver currently supports reseting the GPCDMAand XUSB_PADCTL hardware blocks. In future, more hardware blocks would be supported. Change-Id: I52a4bd3a853de6c4fa410904b6614ff1c63df364 Signed-off-by: Varun Wadekar --- .../tegra/common/drivers/bpmp_ipc/intf.c | 304 ++++++++ .../tegra/common/drivers/bpmp_ipc/intf.h | 74 ++ .../tegra/common/drivers/bpmp_ipc/ivc.c | 653 ++++++++++++++++++ .../tegra/common/drivers/bpmp_ipc/ivc.h | 51 ++ plat/nvidia/tegra/include/drivers/bpmp_ipc.h | 30 + 5 files changed, 1112 insertions(+) create mode 100644 plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.c create mode 100644 plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.h create mode 100644 plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.c create mode 100644 plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.h create mode 100644 plat/nvidia/tegra/include/drivers/bpmp_ipc.h diff --git a/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.c b/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.c new file mode 100644 index 000000000..7faa2f09e --- /dev/null +++ b/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.c @@ -0,0 +1,304 @@ +/* + * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "intf.h" +#include "ivc.h" + +/** + * Holds IVC channel data + */ +struct ccplex_bpmp_channel_data { + /* Buffer for incoming data */ + struct frame_data *ib; + + /* Buffer for outgoing data */ + struct frame_data *ob; +}; + +static struct ccplex_bpmp_channel_data s_channel; +static struct ivc ivc_ccplex_bpmp_channel; + +/* + * Helper functions to access the HSP doorbell registers + */ +static inline uint32_t hsp_db_read(uint32_t reg) +{ + return mmio_read_32((uint32_t)(TEGRA_HSP_DBELL_BASE + reg)); +} + +static inline void hsp_db_write(uint32_t reg, uint32_t val) +{ + mmio_write_32((uint32_t)(TEGRA_HSP_DBELL_BASE + reg), val); +} + +/******************************************************************************* + * IVC wrappers for CCPLEX <-> BPMP communication. + ******************************************************************************/ + +static void tegra_bpmp_ring_bpmp_doorbell(void); + +/* + * Get the next frame where data can be written. + */ +static struct frame_data *tegra_bpmp_get_next_out_frame(void) +{ + struct frame_data *frame; + const struct ivc *ch = &ivc_ccplex_bpmp_channel; + + frame = (struct frame_data *)tegra_ivc_write_get_next_frame(ch); + if (frame == NULL) { + ERROR("%s: Error in getting next frame, exiting\n", __func__); + } else { + s_channel.ob = frame; + } + + return frame; +} + +static void tegra_bpmp_signal_slave(void) +{ + (void)tegra_ivc_write_advance(&ivc_ccplex_bpmp_channel); + tegra_bpmp_ring_bpmp_doorbell(); +} + +static int32_t tegra_bpmp_free_master(void) +{ + return tegra_ivc_read_advance(&ivc_ccplex_bpmp_channel); +} + +static bool tegra_bpmp_slave_acked(void) +{ + struct frame_data *frame; + bool ret = true; + + frame = (struct frame_data *)tegra_ivc_read_get_next_frame(&ivc_ccplex_bpmp_channel); + if (frame == NULL) { + ret = false; + } else { + s_channel.ib = frame; + } + + return ret; +} + +static struct frame_data *tegra_bpmp_get_cur_in_frame(void) +{ + return s_channel.ib; +} + +/* + * Enables BPMP to ring CCPlex doorbell + */ +static void tegra_bpmp_enable_ccplex_doorbell(void) +{ + uint32_t reg; + + reg = hsp_db_read(HSP_DBELL_1_ENABLE); + reg |= HSP_MASTER_BPMP_BIT; + hsp_db_write(HSP_DBELL_1_ENABLE, reg); +} + +/* + * CCPlex rings the BPMP doorbell + */ +static void tegra_bpmp_ring_bpmp_doorbell(void) +{ + /* + * Any writes to this register has the same effect, + * uses master ID of the write transaction and set + * corresponding flag. + */ + hsp_db_write(HSP_DBELL_3_TRIGGER, HSP_MASTER_CCPLEX_BIT); +} + +/* + * Returns true if CCPLex can ring BPMP doorbell, otherwise false. + * This also signals that BPMP is up and ready. + */ +static bool tegra_bpmp_can_ccplex_ring_doorbell(void) +{ + uint32_t reg; + + /* check if ccplex can communicate with bpmp */ + reg = hsp_db_read(HSP_DBELL_3_ENABLE); + + return ((reg & HSP_MASTER_CCPLEX_BIT) != 0U); +} + +static int32_t tegra_bpmp_wait_for_slave_ack(void) +{ + uint32_t timeout = TIMEOUT_RESPONSE_FROM_BPMP_US; + + while (!tegra_bpmp_slave_acked() && (timeout != 0U)) { + udelay(1); + timeout--; + }; + + return ((timeout == 0U) ? -ETIMEDOUT : 0); +} + +/* + * Notification from the ivc layer + */ +static void tegra_bpmp_ivc_notify(const struct ivc *ivc) +{ + (void)(ivc); + + tegra_bpmp_ring_bpmp_doorbell(); +} + +/* + * Atomic send/receive API, which means it waits until slave acks + */ +static int32_t tegra_bpmp_ipc_send_req_atomic(uint32_t mrq, void *p_out, + uint32_t size_out, void *p_in, uint32_t size_in) +{ + struct frame_data *frame = tegra_bpmp_get_next_out_frame(); + const struct frame_data *f_in = NULL; + int32_t ret = 0; + void *p_fdata; + + if ((p_out == NULL) || (size_out > IVC_DATA_SZ_BYTES) || + (frame == NULL)) { + ERROR("%s: invalid parameters, exiting\n", __func__); + ret = -EINVAL; + } + + if (ret == 0) { + + /* prepare the command frame */ + frame->mrq = mrq; + frame->flags = FLAG_DO_ACK; + p_fdata = frame->data; + (void)memcpy(p_fdata, p_out, (size_t)size_out); + + /* signal the slave */ + tegra_bpmp_signal_slave(); + + /* wait for slave to ack */ + ret = tegra_bpmp_wait_for_slave_ack(); + if (ret != 0) { + ERROR("failed waiting for the slave to ack\n"); + } + + /* retrieve the response frame */ + if ((size_in <= IVC_DATA_SZ_BYTES) && (p_in != NULL) && + (ret == 0)) { + + f_in = tegra_bpmp_get_cur_in_frame(); + if (f_in != NULL) { + ERROR("Failed to get next input frame!\n"); + } else { + (void)memcpy(p_in, p_fdata, (size_t)size_in); + } + } + + if (ret == 0) { + ret = tegra_bpmp_free_master(); + if (ret != 0) { + ERROR("Failed to free master\n"); + } + } + } + + return ret; +} + +/* + * Initializes the BPMP<--->CCPlex communication path. + */ +int32_t tegra_bpmp_ipc_init(void) +{ + size_t msg_size; + uint32_t frame_size, timeout; + int32_t error = 0; + + /* allow bpmp to ring CCPLEX's doorbell */ + tegra_bpmp_enable_ccplex_doorbell(); + + /* wait for BPMP to actually ring the doorbell */ + timeout = TIMEOUT_RESPONSE_FROM_BPMP_US; + while ((timeout != 0U) && !tegra_bpmp_can_ccplex_ring_doorbell()) { + udelay(1); /* bpmp turn-around time */ + timeout--; + } + + if (timeout == 0U) { + ERROR("%s: BPMP firmware is not ready\n", __func__); + return -ENOTSUP; + } + + INFO("%s: BPMP handshake completed\n", __func__); + + msg_size = tegra_ivc_align(IVC_CMD_SZ_BYTES); + frame_size = (uint32_t)tegra_ivc_total_queue_size(msg_size); + if (frame_size > TEGRA_BPMP_IPC_CH_MAP_SIZE) { + ERROR("%s: carveout size is not sufficient\n", __func__); + return -EINVAL; + } + + error = tegra_ivc_init(&ivc_ccplex_bpmp_channel, + (uint32_t)TEGRA_BPMP_IPC_RX_PHYS_BASE, + (uint32_t)TEGRA_BPMP_IPC_TX_PHYS_BASE, + 1U, frame_size, tegra_bpmp_ivc_notify); + if (error != 0) { + + ERROR("%s: IVC init failed (%d)\n", __func__, error); + + } else { + + /* reset channel */ + tegra_ivc_channel_reset(&ivc_ccplex_bpmp_channel); + + /* wait for notification from BPMP */ + while (tegra_ivc_channel_notified(&ivc_ccplex_bpmp_channel) != 0) { + /* + * Interrupt BPMP with doorbell each time after + * tegra_ivc_channel_notified() returns non zero + * value. + */ + tegra_bpmp_ring_bpmp_doorbell(); + } + + INFO("%s: All communication channels initialized\n", __func__); + } + + return error; +} + +/* Handler to reset a hardware module */ +int32_t tegra_bpmp_ipc_reset_module(uint32_t rst_id) +{ + int32_t ret; + struct mrq_reset_request req = { + .cmd = (uint32_t)CMD_RESET_MODULE, + .reset_id = rst_id + }; + + /* only GPCDMA/XUSB_PADCTL resets are supported */ + assert((rst_id == TEGRA_RESET_ID_XUSB_PADCTL) || + (rst_id == TEGRA_RESET_ID_GPCDMA)); + + ret = tegra_bpmp_ipc_send_req_atomic(MRQ_RESET, &req, + (uint32_t)sizeof(req), NULL, 0); + if (ret != 0) { + ERROR("%s: failed for module %d with error %d\n", __func__, + rst_id, ret); + } + + return ret; +} diff --git a/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.h b/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.h new file mode 100644 index 000000000..689f8bbb8 --- /dev/null +++ b/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef INTF_H +#define INTF_H + +/** + * Flags used in IPC req + */ +#define FLAG_DO_ACK (U(1) << 0) +#define FLAG_RING_DOORBELL (U(1) << 1) + +/* Bit 1 is designated for CCPlex in secure world */ +#define HSP_MASTER_CCPLEX_BIT (U(1) << 1) +/* Bit 19 is designated for BPMP in non-secure world */ +#define HSP_MASTER_BPMP_BIT (U(1) << 19) +/* Timeout to receive response from BPMP is 1 sec */ +#define TIMEOUT_RESPONSE_FROM_BPMP_US U(1000000) /* in microseconds */ + +/** + * IVC protocol defines and command/response frame + */ + +/** + * IVC specific defines + */ +#define IVC_CMD_SZ_BYTES U(128) +#define IVC_DATA_SZ_BYTES U(120) + +/** + * Holds frame data for an IPC request + */ +struct frame_data { + /* Identification as to what kind of data is being transmitted */ + uint32_t mrq; + + /* Flags for slave as to how to respond back */ + uint32_t flags; + + /* Actual data being sent */ + uint8_t data[IVC_DATA_SZ_BYTES]; +}; + +/** + * Commands send to the BPMP firmware + */ + +/** + * MRQ code to issue a module reset command to BPMP + */ +#define MRQ_RESET U(20) + +/** + * Reset sub-commands + */ +#define CMD_RESET_ASSERT U(1) +#define CMD_RESET_DEASSERT U(2) +#define CMD_RESET_MODULE U(3) + +/** + * Used by the sender of an #MRQ_RESET message to request BPMP to + * assert or deassert a given reset line. + */ +struct __attribute__((packed)) mrq_reset_request { + /* reset action to perform (mrq_reset_commands) */ + uint32_t cmd; + /* id of the reset to affected */ + uint32_t reset_id; +}; + +#endif /* INTF_H */ diff --git a/plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.c b/plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.c new file mode 100644 index 000000000..4212eca1d --- /dev/null +++ b/plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.c @@ -0,0 +1,653 @@ +/* + * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include + +#include "ivc.h" + +/* + * IVC channel reset protocol. + * + * Each end uses its tx_channel.state to indicate its synchronization state. + */ +enum { + /* + * This value is zero for backwards compatibility with services that + * assume channels to be initially zeroed. Such channels are in an + * initially valid state, but cannot be asynchronously reset, and must + * maintain a valid state at all times. + * + * The transmitting end can enter the established state from the sync or + * ack state when it observes the receiving endpoint in the ack or + * established state, indicating that has cleared the counters in our + * rx_channel. + */ + ivc_state_established = U(0), + + /* + * If an endpoint is observed in the sync state, the remote endpoint is + * allowed to clear the counters it owns asynchronously with respect to + * the current endpoint. Therefore, the current endpoint is no longer + * allowed to communicate. + */ + ivc_state_sync = U(1), + + /* + * When the transmitting end observes the receiving end in the sync + * state, it can clear the w_count and r_count and transition to the ack + * state. If the remote endpoint observes us in the ack state, it can + * return to the established state once it has cleared its counters. + */ + ivc_state_ack = U(2) +}; + +/* + * This structure is divided into two-cache aligned parts, the first is only + * written through the tx_channel pointer, while the second is only written + * through the rx_channel pointer. This delineates ownership of the cache lines, + * which is critical to performance and necessary in non-cache coherent + * implementations. + */ +struct ivc_channel_header { + struct { + /* fields owned by the transmitting end */ + uint32_t w_count; + uint32_t state; + uint32_t w_rsvd[IVC_CHHDR_TX_FIELDS - 2]; + }; + struct { + /* fields owned by the receiving end */ + uint32_t r_count; + uint32_t r_rsvd[IVC_CHHDR_RX_FIELDS - 1]; + }; +}; + +static inline bool ivc_channel_empty(const struct ivc *ivc, + volatile const struct ivc_channel_header *ch) +{ + /* + * This function performs multiple checks on the same values with + * security implications, so sample the counters' current values in + * shared memory to ensure that these checks use the same values. + */ + uint32_t wr_count = ch->w_count; + uint32_t rd_count = ch->r_count; + bool ret = false; + + (void)ivc; + + /* + * Perform an over-full check to prevent denial of service attacks where + * a server could be easily fooled into believing that there's an + * extremely large number of frames ready, since receivers are not + * expected to check for full or over-full conditions. + * + * Although the channel isn't empty, this is an invalid case caused by + * a potentially malicious peer, so returning empty is safer, because it + * gives the impression that the channel has gone silent. + */ + if (((wr_count - rd_count) > ivc->nframes) || (wr_count == rd_count)) { + ret = true; + } + + return ret; +} + +static inline bool ivc_channel_full(const struct ivc *ivc, + volatile const struct ivc_channel_header *ch) +{ + uint32_t wr_count = ch->w_count; + uint32_t rd_count = ch->r_count; + + (void)ivc; + + /* + * Invalid cases where the counters indicate that the queue is over + * capacity also appear full. + */ + return ((wr_count - rd_count) >= ivc->nframes); +} + +static inline uint32_t ivc_channel_avail_count(const struct ivc *ivc, + volatile const struct ivc_channel_header *ch) +{ + uint32_t wr_count = ch->w_count; + uint32_t rd_count = ch->r_count; + + (void)ivc; + + /* + * This function isn't expected to be used in scenarios where an + * over-full situation can lead to denial of service attacks. See the + * comment in ivc_channel_empty() for an explanation about special + * over-full considerations. + */ + return (wr_count - rd_count); +} + +static inline void ivc_advance_tx(struct ivc *ivc) +{ + ivc->tx_channel->w_count++; + + if (ivc->w_pos == (ivc->nframes - (uint32_t)1U)) { + ivc->w_pos = 0U; + } else { + ivc->w_pos++; + } +} + +static inline void ivc_advance_rx(struct ivc *ivc) +{ + ivc->rx_channel->r_count++; + + if (ivc->r_pos == (ivc->nframes - (uint32_t)1U)) { + ivc->r_pos = 0U; + } else { + ivc->r_pos++; + } +} + +static inline int32_t ivc_check_read(const struct ivc *ivc) +{ + /* + * tx_channel->state is set locally, so it is not synchronized with + * state from the remote peer. The remote peer cannot reset its + * transmit counters until we've acknowledged its synchronization + * request, so no additional synchronization is required because an + * asynchronous transition of rx_channel->state to ivc_state_ack is not + * allowed. + */ + if (ivc->tx_channel->state != ivc_state_established) { + return -ECONNRESET; + } + + /* + * Avoid unnecessary invalidations when performing repeated accesses to + * an IVC channel by checking the old queue pointers first. + * Synchronization is only necessary when these pointers indicate empty + * or full. + */ + if (!ivc_channel_empty(ivc, ivc->rx_channel)) { + return 0; + } + + return ivc_channel_empty(ivc, ivc->rx_channel) ? -ENOMEM : 0; +} + +static inline int32_t ivc_check_write(const struct ivc *ivc) +{ + if (ivc->tx_channel->state != ivc_state_established) { + return -ECONNRESET; + } + + if (!ivc_channel_full(ivc, ivc->tx_channel)) { + return 0; + } + + return ivc_channel_full(ivc, ivc->tx_channel) ? -ENOMEM : 0; +} + +bool tegra_ivc_can_read(const struct ivc *ivc) +{ + return ivc_check_read(ivc) == 0; +} + +bool tegra_ivc_can_write(const struct ivc *ivc) +{ + return ivc_check_write(ivc) == 0; +} + +bool tegra_ivc_tx_empty(const struct ivc *ivc) +{ + return ivc_channel_empty(ivc, ivc->tx_channel); +} + +static inline uintptr_t calc_frame_offset(uint32_t frame_index, + uint32_t frame_size, uint32_t frame_offset) +{ + return ((uintptr_t)frame_index * (uintptr_t)frame_size) + + (uintptr_t)frame_offset; +} + +static void *ivc_frame_pointer(const struct ivc *ivc, + volatile const struct ivc_channel_header *ch, + uint32_t frame) +{ + assert(frame < ivc->nframes); + return (void *)((uintptr_t)(&ch[1]) + + calc_frame_offset(frame, ivc->frame_size, 0)); +} + +int32_t tegra_ivc_read(struct ivc *ivc, void *buf, size_t max_read) +{ + const void *src; + int32_t result; + + if (buf == NULL) { + return -EINVAL; + } + + if (max_read > ivc->frame_size) { + return -E2BIG; + } + + result = ivc_check_read(ivc); + if (result != 0) { + return result; + } + + /* + * Order observation of w_pos potentially indicating new data before + * data read. + */ + dmbish(); + + src = ivc_frame_pointer(ivc, ivc->rx_channel, ivc->r_pos); + + (void)memcpy(buf, src, max_read); + + ivc_advance_rx(ivc); + + /* + * Ensure our write to r_pos occurs before our read from w_pos. + */ + dmbish(); + + /* + * Notify only upon transition from full to non-full. + * The available count can only asynchronously increase, so the + * worst possible side-effect will be a spurious notification. + */ + if (ivc_channel_avail_count(ivc, ivc->rx_channel) == (ivc->nframes - (uint32_t)1U)) { + ivc->notify(ivc); + } + + return (int32_t)max_read; +} + +/* directly peek at the next frame rx'ed */ +void *tegra_ivc_read_get_next_frame(const struct ivc *ivc) +{ + if (ivc_check_read(ivc) != 0) { + return NULL; + } + + /* + * Order observation of w_pos potentially indicating new data before + * data read. + */ + dmbld(); + + return ivc_frame_pointer(ivc, ivc->rx_channel, ivc->r_pos); +} + +int32_t tegra_ivc_read_advance(struct ivc *ivc) +{ + /* + * No read barriers or synchronization here: the caller is expected to + * have already observed the channel non-empty. This check is just to + * catch programming errors. + */ + int32_t result = ivc_check_read(ivc); + if (result != 0) { + return result; + } + + ivc_advance_rx(ivc); + + /* + * Ensure our write to r_pos occurs before our read from w_pos. + */ + dmbish(); + + /* + * Notify only upon transition from full to non-full. + * The available count can only asynchronously increase, so the + * worst possible side-effect will be a spurious notification. + */ + if (ivc_channel_avail_count(ivc, ivc->rx_channel) == (ivc->nframes - (uint32_t)1U)) { + ivc->notify(ivc); + } + + return 0; +} + +int32_t tegra_ivc_write(struct ivc *ivc, const void *buf, size_t size) +{ + void *p; + int32_t result; + + if ((buf == NULL) || (ivc == NULL)) { + return -EINVAL; + } + + if (size > ivc->frame_size) { + return -E2BIG; + } + + result = ivc_check_write(ivc); + if (result != 0) { + return result; + } + + p = ivc_frame_pointer(ivc, ivc->tx_channel, ivc->w_pos); + + (void)memset(p, 0, ivc->frame_size); + (void)memcpy(p, buf, size); + + /* + * Ensure that updated data is visible before the w_pos counter + * indicates that it is ready. + */ + dmbst(); + + ivc_advance_tx(ivc); + + /* + * Ensure our write to w_pos occurs before our read from r_pos. + */ + dmbish(); + + /* + * Notify only upon transition from empty to non-empty. + * The available count can only asynchronously decrease, so the + * worst possible side-effect will be a spurious notification. + */ + if (ivc_channel_avail_count(ivc, ivc->tx_channel) == 1U) { + ivc->notify(ivc); + } + + return (int32_t)size; +} + +/* directly poke at the next frame to be tx'ed */ +void *tegra_ivc_write_get_next_frame(const struct ivc *ivc) +{ + if (ivc_check_write(ivc) != 0) { + return NULL; + } + + return ivc_frame_pointer(ivc, ivc->tx_channel, ivc->w_pos); +} + +/* advance the tx buffer */ +int32_t tegra_ivc_write_advance(struct ivc *ivc) +{ + int32_t result = ivc_check_write(ivc); + + if (result != 0) { + return result; + } + + /* + * Order any possible stores to the frame before update of w_pos. + */ + dmbst(); + + ivc_advance_tx(ivc); + + /* + * Ensure our write to w_pos occurs before our read from r_pos. + */ + dmbish(); + + /* + * Notify only upon transition from empty to non-empty. + * The available count can only asynchronously decrease, so the + * worst possible side-effect will be a spurious notification. + */ + if (ivc_channel_avail_count(ivc, ivc->tx_channel) == (uint32_t)1U) { + ivc->notify(ivc); + } + + return 0; +} + +void tegra_ivc_channel_reset(const struct ivc *ivc) +{ + ivc->tx_channel->state = ivc_state_sync; + ivc->notify(ivc); +} + +/* + * =============================================================== + * IVC State Transition Table - see tegra_ivc_channel_notified() + * =============================================================== + * + * local remote action + * ----- ------ ----------------------------------- + * SYNC EST + * SYNC ACK reset counters; move to EST; notify + * SYNC SYNC reset counters; move to ACK; notify + * ACK EST move to EST; notify + * ACK ACK move to EST; notify + * ACK SYNC reset counters; move to ACK; notify + * EST EST + * EST ACK + * EST SYNC reset counters; move to ACK; notify + * + * =============================================================== + */ +int32_t tegra_ivc_channel_notified(struct ivc *ivc) +{ + uint32_t peer_state; + + /* Copy the receiver's state out of shared memory. */ + peer_state = ivc->rx_channel->state; + + if (peer_state == (uint32_t)ivc_state_sync) { + /* + * Order observation of ivc_state_sync before stores clearing + * tx_channel. + */ + dmbld(); + + /* + * Reset tx_channel counters. The remote end is in the SYNC + * state and won't make progress until we change our state, + * so the counters are not in use at this time. + */ + ivc->tx_channel->w_count = 0U; + ivc->rx_channel->r_count = 0U; + + ivc->w_pos = 0U; + ivc->r_pos = 0U; + + /* + * Ensure that counters appear cleared before new state can be + * observed. + */ + dmbst(); + + /* + * Move to ACK state. We have just cleared our counters, so it + * is now safe for the remote end to start using these values. + */ + ivc->tx_channel->state = ivc_state_ack; + + /* + * Notify remote end to observe state transition. + */ + ivc->notify(ivc); + + } else if ((ivc->tx_channel->state == (uint32_t)ivc_state_sync) && + (peer_state == (uint32_t)ivc_state_ack)) { + /* + * Order observation of ivc_state_sync before stores clearing + * tx_channel. + */ + dmbld(); + + /* + * Reset tx_channel counters. The remote end is in the ACK + * state and won't make progress until we change our state, + * so the counters are not in use at this time. + */ + ivc->tx_channel->w_count = 0U; + ivc->rx_channel->r_count = 0U; + + ivc->w_pos = 0U; + ivc->r_pos = 0U; + + /* + * Ensure that counters appear cleared before new state can be + * observed. + */ + dmbst(); + + /* + * Move to ESTABLISHED state. We know that the remote end has + * already cleared its counters, so it is safe to start + * writing/reading on this channel. + */ + ivc->tx_channel->state = ivc_state_established; + + /* + * Notify remote end to observe state transition. + */ + ivc->notify(ivc); + + } else if (ivc->tx_channel->state == (uint32_t)ivc_state_ack) { + /* + * At this point, we have observed the peer to be in either + * the ACK or ESTABLISHED state. Next, order observation of + * peer state before storing to tx_channel. + */ + dmbld(); + + /* + * Move to ESTABLISHED state. We know that we have previously + * cleared our counters, and we know that the remote end has + * cleared its counters, so it is safe to start writing/reading + * on this channel. + */ + ivc->tx_channel->state = ivc_state_established; + + /* + * Notify remote end to observe state transition. + */ + ivc->notify(ivc); + + } else { + /* + * There is no need to handle any further action. Either the + * channel is already fully established, or we are waiting for + * the remote end to catch up with our current state. Refer + * to the diagram in "IVC State Transition Table" above. + */ + } + + return ((ivc->tx_channel->state == (uint32_t)ivc_state_established) ? 0 : -EAGAIN); +} + +size_t tegra_ivc_align(size_t size) +{ + return (size + (IVC_ALIGN - 1U)) & ~(IVC_ALIGN - 1U); +} + +size_t tegra_ivc_total_queue_size(size_t queue_size) +{ + if ((queue_size & (IVC_ALIGN - 1U)) != 0U) { + ERROR("queue_size (%d) must be %d-byte aligned\n", + (int32_t)queue_size, IVC_ALIGN); + return 0; + } + return queue_size + sizeof(struct ivc_channel_header); +} + +static int32_t check_ivc_params(uintptr_t queue_base1, uintptr_t queue_base2, + uint32_t nframes, uint32_t frame_size) +{ + assert((offsetof(struct ivc_channel_header, w_count) + & (IVC_ALIGN - 1U)) == 0U); + assert((offsetof(struct ivc_channel_header, r_count) + & (IVC_ALIGN - 1U)) == 0U); + assert((sizeof(struct ivc_channel_header) & (IVC_ALIGN - 1U)) == 0U); + + if (((uint64_t)nframes * (uint64_t)frame_size) >= 0x100000000ULL) { + ERROR("nframes * frame_size overflows\n"); + return -EINVAL; + } + + /* + * The headers must at least be aligned enough for counters + * to be accessed atomically. + */ + if ((queue_base1 & (IVC_ALIGN - 1U)) != 0U) { + ERROR("ivc channel start not aligned: %lx\n", queue_base1); + return -EINVAL; + } + if ((queue_base2 & (IVC_ALIGN - 1U)) != 0U) { + ERROR("ivc channel start not aligned: %lx\n", queue_base2); + return -EINVAL; + } + + if ((frame_size & (IVC_ALIGN - 1U)) != 0U) { + ERROR("frame size not adequately aligned: %u\n", + frame_size); + return -EINVAL; + } + + if (queue_base1 < queue_base2) { + if ((queue_base1 + ((uint64_t)frame_size * nframes)) > queue_base2) { + ERROR("queue regions overlap: %lx + %x, %x\n", + queue_base1, frame_size, + frame_size * nframes); + return -EINVAL; + } + } else { + if ((queue_base2 + ((uint64_t)frame_size * nframes)) > queue_base1) { + ERROR("queue regions overlap: %lx + %x, %x\n", + queue_base2, frame_size, + frame_size * nframes); + return -EINVAL; + } + } + + return 0; +} + +int32_t tegra_ivc_init(struct ivc *ivc, uintptr_t rx_base, uintptr_t tx_base, + uint32_t nframes, uint32_t frame_size, + ivc_notify_function notify) +{ + int32_t result; + + /* sanity check input params */ + if ((ivc == NULL) || (notify == NULL)) { + return -EINVAL; + } + + result = check_ivc_params(rx_base, tx_base, nframes, frame_size); + if (result != 0) { + return result; + } + + /* + * All sizes that can be returned by communication functions should + * fit in a 32-bit integer. + */ + if (frame_size > (1u << 31)) { + return -E2BIG; + } + + ivc->rx_channel = (struct ivc_channel_header *)rx_base; + ivc->tx_channel = (struct ivc_channel_header *)tx_base; + ivc->notify = notify; + ivc->frame_size = frame_size; + ivc->nframes = nframes; + ivc->w_pos = 0U; + ivc->r_pos = 0U; + + INFO("%s: done\n", __func__); + + return 0; +} diff --git a/plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.h b/plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.h new file mode 100644 index 000000000..f34d6cf0c --- /dev/null +++ b/plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef IVC_H +#define IVC_H + +#include +#include +#include + +#define IVC_ALIGN U(64) +#define IVC_CHHDR_TX_FIELDS U(16) +#define IVC_CHHDR_RX_FIELDS U(16) + +struct ivc; +struct ivc_channel_header; + +/* callback handler for notify on receiving a response */ +typedef void (* ivc_notify_function)(const struct ivc *); + +struct ivc { + struct ivc_channel_header *rx_channel; + struct ivc_channel_header *tx_channel; + uint32_t w_pos; + uint32_t r_pos; + ivc_notify_function notify; + uint32_t nframes; + uint32_t frame_size; +}; + +int32_t tegra_ivc_init(struct ivc *ivc, uintptr_t rx_base, uintptr_t tx_base, + uint32_t nframes, uint32_t frame_size, + ivc_notify_function notify); +size_t tegra_ivc_total_queue_size(size_t queue_size); +size_t tegra_ivc_align(size_t size); +int32_t tegra_ivc_channel_notified(struct ivc *ivc); +void tegra_ivc_channel_reset(const struct ivc *ivc); +int32_t tegra_ivc_write_advance(struct ivc *ivc); +void *tegra_ivc_write_get_next_frame(const struct ivc *ivc); +int32_t tegra_ivc_write(struct ivc *ivc, const void *buf, size_t size); +int32_t tegra_ivc_read_advance(struct ivc *ivc); +void *tegra_ivc_read_get_next_frame(const struct ivc *ivc); +int32_t tegra_ivc_read(struct ivc *ivc, void *buf, size_t max_read); +bool tegra_ivc_tx_empty(const struct ivc *ivc); +bool tegra_ivc_can_write(const struct ivc *ivc); +bool tegra_ivc_can_read(const struct ivc *ivc); + +#endif /* IVC_H */ diff --git a/plat/nvidia/tegra/include/drivers/bpmp_ipc.h b/plat/nvidia/tegra/include/drivers/bpmp_ipc.h new file mode 100644 index 000000000..9304150e9 --- /dev/null +++ b/plat/nvidia/tegra/include/drivers/bpmp_ipc.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __BPMP_IPC_H__ +#define __BPMP_IPC_H__ + +#include +#include +#include + +/** + * Currently supported reset identifiers + */ +#define TEGRA_RESET_ID_XUSB_PADCTL U(114) +#define TEGRA_RESET_ID_GPCDMA U(70) + +/** + * Function to initialise the IPC with the bpmp + */ +int32_t tegra_bpmp_ipc_init(void); + +/** + * Handler to reset a module + */ +int32_t tegra_bpmp_ipc_reset_module(uint32_t rst_id); + +#endif /* __BPMP_IPC_H__ */ From ad67f8c56d76174c585a6d2a0e1b378062315bfa Mon Sep 17 00:00:00 2001 From: Anthony Zhou Date: Fri, 22 Sep 2017 16:52:02 +0800 Subject: [PATCH 13/27] Tegra186: setup: Fix MISRA Rule 8.4 violation MISRA Rule 8.4, A compatible declaration shall be visible when an object or function with external linkage is defined. This patch adds static for local array to fix this defect. Change-Id: I8231448bf1bc0b1e59611d7645ca983b83d5c8e3 Signed-off-by: Anthony Zhou --- plat/nvidia/tegra/soc/t186/plat_setup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plat/nvidia/tegra/soc/t186/plat_setup.c b/plat/nvidia/tegra/soc/t186/plat_setup.c index bbd19c1c8..bd6d7647a 100644 --- a/plat/nvidia/tegra/soc/t186/plat_setup.c +++ b/plat/nvidia/tegra/soc/t186/plat_setup.c @@ -40,7 +40,7 @@ * the number of power domains at the highest power level. ******************************************************************************* */ -const uint8_t tegra_power_domain_tree_desc[] = { +static const uint8_t tegra_power_domain_tree_desc[] = { /* No of root nodes */ 1, /* No of clusters */ From b6d1757b82a3d8e120e7f8079a23a9e1f5290415 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Tue, 17 Oct 2017 10:29:24 -0700 Subject: [PATCH 14/27] Tegra186: sanity check target cluster during core power on This patch sanity checks the target cluster value, during core power on, by comparing it against the maximum number of clusters supported by the platform. Reported by: Rohit Khanna Change-Id: Ia73ccf04bd246403de4ffff6e5c99e3b00fb98ca Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/soc/t186/plat_psci_handlers.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c index bd13dc2a1..e0b5d2b9c 100644 --- a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c +++ b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c @@ -295,7 +295,7 @@ int32_t tegra_soc_pwr_domain_on(u_register_t mpidr) uint64_t target_cluster = (mpidr & MPIDR_CLUSTER_MASK) >> MPIDR_AFFINITY_BITS; - if (target_cluster > MPIDR_AFFLVL1) { + if (target_cluster > ((uint32_t)PLATFORM_CLUSTER_COUNT - 1U)) { ERROR("%s: unsupported CPU (0x%lx)\n", __func__, mpidr); ret = PSCI_E_NOT_PRESENT; From 7191566c696e3f9070db9f2b9b8503a5617fa6db Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Wed, 25 Oct 2017 11:52:07 -0700 Subject: [PATCH 15/27] Tegra186: secondary: fix MISRA violations for Rules 8.6, 11.1 This patch fixes the following MISRA violations: Rule 8.6: Externally-linked object or function has "no" definition(s). Rule 11.1: A cast shall not convert a pointer to a function to any other type. Change-Id: Ic1f6fc14c744e54ff782c6987dab9c9430410f5e Signed-off-by: Varun Wadekar --- .../tegra/include/t186/tegra186_private.h | 14 +++++++ plat/nvidia/tegra/soc/t186/plat_secondary.c | 37 ++++++++----------- plat/nvidia/tegra/soc/t186/plat_trampoline.S | 17 +++++++++ 3 files changed, 46 insertions(+), 22 deletions(-) create mode 100644 plat/nvidia/tegra/include/t186/tegra186_private.h diff --git a/plat/nvidia/tegra/include/t186/tegra186_private.h b/plat/nvidia/tegra/include/t186/tegra186_private.h new file mode 100644 index 000000000..cb52f084e --- /dev/null +++ b/plat/nvidia/tegra/include/t186/tegra186_private.h @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef TEGRA186_PRIVATE_H +#define TEGRA186_PRIVATE_H + +void tegra186_cpu_reset_handler(void); +uint64_t tegra186_get_cpu_reset_handler_base(void); +uint64_t tegra186_get_cpu_reset_handler_size(void); + +#endif /* TEGRA186_PRIVATE_H */ diff --git a/plat/nvidia/tegra/soc/t186/plat_secondary.c b/plat/nvidia/tegra/soc/t186/plat_secondary.c index 577cc38b2..19ca4fd07 100644 --- a/plat/nvidia/tegra/soc/t186/plat_secondary.c +++ b/plat/nvidia/tegra/soc/t186/plat_secondary.c @@ -11,6 +11,7 @@ #include #include +#include #include #include @@ -24,9 +25,6 @@ extern void memcpy16(void *dest, const void *src, unsigned int length); -extern uint64_t tegra_bl31_phys_base; -extern uint64_t __tegra186_cpu_reset_handler_end; - /******************************************************************************* * Setup secondary CPU vectors ******************************************************************************/ @@ -34,29 +32,24 @@ void plat_secondary_setup(void) { uint32_t addr_low, addr_high; const plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params(); - uint64_t cpu_reset_handler_base; + uint64_t cpu_reset_handler_base, cpu_reset_handler_size; INFO("Setting up secondary CPU boot\n"); - if ((tegra_bl31_phys_base >= TEGRA_TZRAM_BASE) && - (tegra_bl31_phys_base <= (TEGRA_TZRAM_BASE + TEGRA_TZRAM_SIZE))) { + /* + * The BL31 code resides in the TZSRAM which loses state + * when we enter System Suspend. Copy the wakeup trampoline + * code to TZDRAM to help us exit from System Suspend. + */ + cpu_reset_handler_base = tegra186_get_cpu_reset_handler_base(); + cpu_reset_handler_size = tegra186_get_cpu_reset_handler_size(); + (void)memcpy16((void *)(uintptr_t)params_from_bl2->tzdram_base, + (const void *)(uintptr_t)cpu_reset_handler_base, + cpu_reset_handler_size); - /* - * The BL31 code resides in the TZSRAM which loses state - * when we enter System Suspend. Copy the wakeup trampoline - * code to TZDRAM to help us exit from System Suspend. - */ - cpu_reset_handler_base = params_from_bl2->tzdram_base; - memcpy16((void *)((uintptr_t)cpu_reset_handler_base), - (void *)(uintptr_t)tegra186_cpu_reset_handler, - (uintptr_t)&tegra186_cpu_reset_handler); - - } else { - cpu_reset_handler_base = (uintptr_t)&tegra_secure_entrypoint; - } - - addr_low = (uint32_t)cpu_reset_handler_base | CPU_RESET_MODE_AA64; - addr_high = (uint32_t)((cpu_reset_handler_base >> 32U) & 0x7ffU); + /* TZDRAM base will be used as the "resume" address */ + addr_low = (uint32_t)params_from_bl2->tzdram_base | CPU_RESET_MODE_AA64; + addr_high = (uint32_t)((params_from_bl2->tzdram_base >> 32U) & 0x7ffU); /* write lower 32 bits first, then the upper 11 bits */ mmio_write_32(TEGRA_MISC_BASE + MISCREG_AA64_RST_LOW, addr_low); diff --git a/plat/nvidia/tegra/soc/t186/plat_trampoline.S b/plat/nvidia/tegra/soc/t186/plat_trampoline.S index 69ca798f9..3ed2940ca 100644 --- a/plat/nvidia/tegra/soc/t186/plat_trampoline.S +++ b/plat/nvidia/tegra/soc/t186/plat_trampoline.S @@ -80,3 +80,20 @@ __tegra186_smmu_context: .align 4 .globl __tegra186_cpu_reset_handler_end __tegra186_cpu_reset_handler_end: + + .globl tegra186_get_cpu_reset_handler_size + .globl tegra186_get_cpu_reset_handler_base + +/* return size of the CPU reset handler */ +func tegra186_get_cpu_reset_handler_size + adr x0, __tegra186_cpu_reset_handler_end + adr x1, tegra186_cpu_reset_handler + sub x0, x0, x1 + ret +endfunc tegra186_get_cpu_reset_handler_size + +/* return the start address of the CPU reset handler */ +func tegra186_get_cpu_reset_handler_base + adr x0, tegra186_cpu_reset_handler + ret +endfunc tegra186_get_cpu_reset_handler_base From d5bd0de6275e0a00f8b5c0c5076180ecc21f8da6 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Mon, 30 Oct 2017 14:35:17 -0700 Subject: [PATCH 16/27] Tegra: memctrl_v2: platform handler for TZDRAM settings The Tegra memctrl driver sets up the TZDRAM fence during boot and system suspend exit. This patch provides individual platforms with handlers to perform platform specific steps, e.g. enable encryption, save base/size to secure scratch registers. Change-Id: Ifaa2e0eac20b50f77ec734256544c36dd511bd63 Signed-off-by: Varun Wadekar --- .../tegra/common/drivers/memctrl/memctrl_v2.c | 28 ++++++++---------- .../nvidia/tegra/include/drivers/memctrl_v2.h | 10 ++++++- plat/nvidia/tegra/soc/t186/plat_memctrl.c | 29 +++++++++++++++++++ 3 files changed, 50 insertions(+), 17 deletions(-) diff --git a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c index e12031441..0567aa9af 100644 --- a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c +++ b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c @@ -25,6 +25,16 @@ static uint64_t video_mem_base; static uint64_t video_mem_size_mb; +/* + * The following platform setup functions are weakly defined. They + * provide typical implementations that will be overridden by a SoC. + */ +#pragma weak plat_memctrl_tzdram_setup +void plat_memctrl_tzdram_setup(uint64_t phys_base, uint64_t size_in_bytes) +{ + ; /* do nothing */ +} + /* * Init Memory controller during boot. */ @@ -144,8 +154,6 @@ void tegra_memctrl_restore_settings(void) */ void tegra_memctrl_tzdram_setup(uint64_t phys_base, uint32_t size_in_bytes) { - uint32_t val; - /* * Setup the Memory controller to allow only secure accesses to * the TZDRAM carveout @@ -157,21 +165,9 @@ void tegra_memctrl_tzdram_setup(uint64_t phys_base, uint32_t size_in_bytes) tegra_mc_write_32(MC_SECURITY_CFG1_0, size_in_bytes >> 20); /* - * When TZ encryption enabled, - * We need setup TZDRAM before CPU to access TZ Carveout, - * otherwise CPU will fetch non-decrypted data. - * So save TZDRAM setting for restore by SC7 resume FW. - * Scratch registers map: - * RSV55_0 = CFG1[12:0] | CFG0[31:20] - * RSV55_1 = CFG3[1:0] + * Perform platform specific steps. */ - - val = tegra_mc_read_32(MC_SECURITY_CFG1_0) & MC_SECURITY_SIZE_MB_MASK; - val |= tegra_mc_read_32(MC_SECURITY_CFG0_0) & MC_SECURITY_BOM_MASK; - mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV55_LO, val); - - val = tegra_mc_read_32(MC_SECURITY_CFG3_0) & MC_SECURITY_BOM_HI_MASK; - mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV55_HI, val); + plat_memctrl_tzdram_setup(phys_base, size_in_bytes); /* * MCE propagates the security configuration values across the diff --git a/plat/nvidia/tegra/include/drivers/memctrl_v2.h b/plat/nvidia/tegra/include/drivers/memctrl_v2.h index 22f05f487..f5b0ed4d3 100644 --- a/plat/nvidia/tegra/include/drivers/memctrl_v2.h +++ b/plat/nvidia/tegra/include/drivers/memctrl_v2.h @@ -165,6 +165,14 @@ static inline void tegra_mc_streamid_write_32(uint32_t off, uint32_t val) ******************************************************************************/ tegra_mc_settings_t *tegra_get_mc_settings(void); -#endif /* __ASSMEBLY__ */ +/******************************************************************************* + * Handler to program the scratch registers with TZDRAM settings for the + * resume firmware. + * + * Implemented by SoCs under tegra/soc/txxx + ******************************************************************************/ +void plat_memctrl_tzdram_setup(uint64_t phys_base, uint64_t size_in_bytes); + +#endif /* __ASSEMBLY__ */ #endif /* MEMCTRL_V2_H */ diff --git a/plat/nvidia/tegra/soc/t186/plat_memctrl.c b/plat/nvidia/tegra/soc/t186/plat_memctrl.c index 74811aee0..a2a815548 100644 --- a/plat/nvidia/tegra/soc/t186/plat_memctrl.c +++ b/plat/nvidia/tegra/soc/t186/plat_memctrl.c @@ -537,3 +537,32 @@ tegra_mc_settings_t *tegra_get_mc_settings(void) { return &tegra186_mc_settings; } + +/******************************************************************************* + * Handler to program the scratch registers with TZDRAM settings for the + * resume firmware + ******************************************************************************/ +void plat_memctrl_tzdram_setup(uint64_t phys_base, uint64_t size_in_bytes) +{ + uint32_t val; + + (void)phys_base; + (void)size_in_bytes; + + /* + * When TZ encryption is enabled, we need to setup TZDRAM + * before CPU accesses TZ Carveout, else CPU will fetch + * non-decrypted data. So save TZDRAM setting for SC7 resume + * FW to restore. + * + * Scratch registers map: + * RSV55_0 = CFG1[12:0] | CFG0[31:20] + * RSV55_1 = CFG3[1:0] + */ + val = tegra_mc_read_32(MC_SECURITY_CFG1_0) & MC_SECURITY_SIZE_MB_MASK; + val |= tegra_mc_read_32(MC_SECURITY_CFG0_0) & MC_SECURITY_BOM_MASK; + mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV55_LO, val); + + val = tegra_mc_read_32(MC_SECURITY_CFG3_0) & MC_SECURITY_BOM_HI_MASK; + mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV55_HI, val); +} From 601a8e549544ea85f478f43b68c4afdc3430a9e7 Mon Sep 17 00:00:00 2001 From: Steven Kao Date: Mon, 23 Oct 2017 18:22:09 +0800 Subject: [PATCH 17/27] Tegra: rename secure scratch register macros This patch renames all the secure scratch registers to reflect their usage. This is a list of all the macros being renamed: - SECURE_SCRATCH_RSV1_* -> SCRATCH_RESET_VECTOR_* - SECURE_SCRATCH_RSV6 -> SCRATCH_SECURE_BOOTP_FCFG - SECURE_SCRATCH_RSV11_* -> SCRATCH_SMMU_TABLE_ADDR_* - SECURE_SCRATCH_RSV53_* -> SCRATCH_BOOT_PARAMS_ADDR_* - SECURE_SCRATCH_RSV55_* -> SCRATCH_TZDRAM_ADDR_* NOTE: Future SoCs will have to define these macros to keep the drivers functioning. Change-Id: Ib3ba40dd32e77b92b47825f19c420e6fdfa8b987 Signed-off-by: Steven Kao --- plat/nvidia/tegra/common/drivers/smmu/smmu.c | 4 ++-- plat/nvidia/tegra/include/t186/tegra_def.h | 10 ++++++++++ plat/nvidia/tegra/soc/t186/plat_memctrl.c | 4 ++-- plat/nvidia/tegra/soc/t186/plat_psci_handlers.c | 2 +- plat/nvidia/tegra/soc/t186/plat_secondary.c | 4 ++-- plat/nvidia/tegra/soc/t186/plat_setup.c | 4 ++-- 6 files changed, 19 insertions(+), 9 deletions(-) diff --git a/plat/nvidia/tegra/common/drivers/smmu/smmu.c b/plat/nvidia/tegra/common/drivers/smmu/smmu.c index 789f11c8d..333d7d163 100644 --- a/plat/nvidia/tegra/common/drivers/smmu/smmu.c +++ b/plat/nvidia/tegra/common/drivers/smmu/smmu.c @@ -123,9 +123,9 @@ void tegra_smmu_save_context(uint64_t smmu_ctx_addr) (sizeof(smmu_regs_t) * num_entries)); /* save the SMMU table address */ - mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV11_LO, + mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_SMMU_TABLE_ADDR_LO, (uint32_t)smmu_ctx_addr); - mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV11_HI, + mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_SMMU_TABLE_ADDR_HI, (uint32_t)(smmu_ctx_addr >> 32)); } diff --git a/plat/nvidia/tegra/include/t186/tegra_def.h b/plat/nvidia/tegra/include/t186/tegra_def.h index 8dee50704..231f93ac8 100644 --- a/plat/nvidia/tegra/include/t186/tegra_def.h +++ b/plat/nvidia/tegra/include/t186/tegra_def.h @@ -239,6 +239,16 @@ #define SECURE_SCRATCH_RSV55_LO U(0x808) #define SECURE_SCRATCH_RSV55_HI U(0x80C) +#define SCRATCH_RESET_VECTOR_LO SECURE_SCRATCH_RSV1_LO +#define SCRATCH_RESET_VECTOR_HI SECURE_SCRATCH_RSV1_HI +#define SCRATCH_SECURE_BOOTP_FCFG SECURE_SCRATCH_RSV6 +#define SCRATCH_SMMU_TABLE_ADDR_LO SECURE_SCRATCH_RSV11_LO +#define SCRATCH_SMMU_TABLE_ADDR_HI SECURE_SCRATCH_RSV11_HI +#define SCRATCH_BL31_PARAMS_ADDR SECURE_SCRATCH_RSV53_LO +#define SCRATCH_BL31_PLAT_PARAMS_ADDR SECURE_SCRATCH_RSV53_HI +#define SCRATCH_TZDRAM_ADDR_LO SECURE_SCRATCH_RSV55_LO +#define SCRATCH_TZDRAM_ADDR_HI SECURE_SCRATCH_RSV55_HI + /******************************************************************************* * Tegra Memory Mapped Control Register Access constants ******************************************************************************/ diff --git a/plat/nvidia/tegra/soc/t186/plat_memctrl.c b/plat/nvidia/tegra/soc/t186/plat_memctrl.c index a2a815548..71904a8f6 100644 --- a/plat/nvidia/tegra/soc/t186/plat_memctrl.c +++ b/plat/nvidia/tegra/soc/t186/plat_memctrl.c @@ -561,8 +561,8 @@ void plat_memctrl_tzdram_setup(uint64_t phys_base, uint64_t size_in_bytes) */ val = tegra_mc_read_32(MC_SECURITY_CFG1_0) & MC_SECURITY_SIZE_MB_MASK; val |= tegra_mc_read_32(MC_SECURITY_CFG0_0) & MC_SECURITY_BOM_MASK; - mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV55_LO, val); + mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_TZDRAM_ADDR_LO, val); val = tegra_mc_read_32(MC_SECURITY_CFG3_0) & MC_SECURITY_BOM_HI_MASK; - mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV55_HI, val); + mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_TZDRAM_ADDR_HI, val); } diff --git a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c index e0b5d2b9c..5d3cdfaf5 100644 --- a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c +++ b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c @@ -123,7 +123,7 @@ int32_t tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state) /* save 'Secure Boot' Processor Feature Config Register */ val = mmio_read_32(TEGRA_MISC_BASE + MISCREG_PFCFG); - mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV6, val); + mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_SECURE_BOOTP_FCFG, val); /* save SMMU context to TZDRAM */ smmu_ctx_base = params_from_bl2->tzdram_base + diff --git a/plat/nvidia/tegra/soc/t186/plat_secondary.c b/plat/nvidia/tegra/soc/t186/plat_secondary.c index 19ca4fd07..16508093e 100644 --- a/plat/nvidia/tegra/soc/t186/plat_secondary.c +++ b/plat/nvidia/tegra/soc/t186/plat_secondary.c @@ -56,9 +56,9 @@ void plat_secondary_setup(void) mmio_write_32(TEGRA_MISC_BASE + MISCREG_AA64_RST_HIGH, addr_high); /* save reset vector to be used during SYSTEM_SUSPEND exit */ - mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_SECURE_RSV1_SCRATCH_0, + mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_RESET_VECTOR_LO, addr_low); - mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_SECURE_RSV1_SCRATCH_1, + mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_RESET_VECTOR_HI, addr_high); /* update reset vector address to the CCPLEX */ diff --git a/plat/nvidia/tegra/soc/t186/plat_setup.c b/plat/nvidia/tegra/soc/t186/plat_setup.c index bd6d7647a..fd109e563 100644 --- a/plat/nvidia/tegra/soc/t186/plat_setup.c +++ b/plat/nvidia/tegra/soc/t186/plat_setup.c @@ -211,7 +211,7 @@ struct tegra_bl31_params *plat_get_bl31_params(void) { uint32_t val; - val = mmio_read_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV53_LO); + val = mmio_read_32(TEGRA_SCRATCH_BASE + SCRATCH_BL31_PARAMS_ADDR); return (struct tegra_bl31_params *)(uintptr_t)val; } @@ -223,7 +223,7 @@ plat_params_from_bl2_t *plat_get_bl31_plat_params(void) { uint32_t val; - val = mmio_read_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV53_HI); + val = mmio_read_32(TEGRA_SCRATCH_BASE + SCRATCH_BL31_PLAT_PARAMS_ADDR); return (plat_params_from_bl2_t *)(uintptr_t)val; } From d7be5e2e3af87c059bd692459ce8c4a493f404bb Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Wed, 23 Aug 2017 10:19:25 -0700 Subject: [PATCH 18/27] Tegra: bpmp: return error if BPMP init fails This patch returns error if BPMP initialization fails. The platform code marks the cluster as "runnning" since we wont be able to get it into the low power state without BPMP. Change-Id: I86f51d478626240bb7b4ccede8907674290c5dc1 Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/common/drivers/bpmp/bpmp.c | 5 +- .../tegra/soc/t210/plat_psci_handlers.c | 62 ++++++++++++------- 2 files changed, 40 insertions(+), 27 deletions(-) diff --git a/plat/nvidia/tegra/common/drivers/bpmp/bpmp.c b/plat/nvidia/tegra/common/drivers/bpmp/bpmp.c index 1867511cb..1c5d2e159 100644 --- a/plat/nvidia/tegra/common/drivers/bpmp/bpmp.c +++ b/plat/nvidia/tegra/common/drivers/bpmp/bpmp.c @@ -125,7 +125,7 @@ int tegra_bpmp_init(void) val = mmio_read_32(TEGRA_RES_SEMA_BASE + STA_OFFSET); if (val != SIGN_OF_LIFE) { ERROR("BPMP precessor not available\n"); - ret = -ENOTSUP; + return -ENOTSUP; } /* check if clock for the atomics block is enabled */ @@ -158,8 +158,7 @@ int tegra_bpmp_init(void) } /* mark state as "initialized" */ - if (ret == 0) - bpmp_init_state = BPMP_INIT_COMPLETE; + bpmp_init_state = BPMP_INIT_COMPLETE; /* the channel values have to be visible across all cpus */ flush_dcache_range((uint64_t)channel_base, sizeof(channel_base)); diff --git a/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c index 958aa9256..f52d975d8 100644 --- a/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c +++ b/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c @@ -104,41 +104,55 @@ plat_local_state_t tegra_soc_get_target_pwr_state(unsigned int lvl, if ((lvl == MPIDR_AFFLVL1) && (target == PSTATE_ID_CLUSTER_IDLE)) { /* initialize the bpmp interface */ - (void)tegra_bpmp_init(); - - /* Cluster idle */ - data[0] = (uint32_t)cpu; - data[1] = TEGRA_PM_CC6; - data[2] = TEGRA_PM_SC1; - ret = tegra_bpmp_send_receive_atomic(MRQ_DO_IDLE, - (void *)&data, (int)sizeof(data), - (void *)&bpmp_reply, (int)sizeof(bpmp_reply)); - - /* check if cluster idle entry is allowed */ - if ((ret != 0L) || (bpmp_reply != BPMP_CCx_ALLOWED)) { + ret = tegra_bpmp_init(); + if (ret != 0U) { /* Cluster idle not allowed */ target = PSCI_LOCAL_STATE_RUN; + } else { + + /* Cluster idle */ + data[0] = (uint32_t)cpu; + data[1] = TEGRA_PM_CC6; + data[2] = TEGRA_PM_SC1; + ret = tegra_bpmp_send_receive_atomic(MRQ_DO_IDLE, + (void *)&data, (int)sizeof(data), + (void *)&bpmp_reply, + (int)sizeof(bpmp_reply)); + + /* check if cluster idle entry is allowed */ + if ((ret != 0L) || (bpmp_reply != BPMP_CCx_ALLOWED)) { + + /* Cluster idle not allowed */ + target = PSCI_LOCAL_STATE_RUN; + } } } else if ((lvl == MPIDR_AFFLVL1) && (target == PSTATE_ID_CLUSTER_POWERDN)) { /* initialize the bpmp interface */ - (void)tegra_bpmp_init(); - - /* Cluster power-down */ - data[0] = (uint32_t)cpu; - data[1] = TEGRA_PM_CC7; - data[2] = TEGRA_PM_SC1; - ret = tegra_bpmp_send_receive_atomic(MRQ_DO_IDLE, - (void *)&data, (int)sizeof(data), - (void *)&bpmp_reply, (int)sizeof(bpmp_reply)); - - /* check if cluster power down is allowed */ - if ((ret != 0L) || (bpmp_reply != BPMP_CCx_ALLOWED)) { + ret = tegra_bpmp_init(); + if (ret != 0U) { /* Cluster power down not allowed */ target = PSCI_LOCAL_STATE_RUN; + } else { + + /* Cluster power-down */ + data[0] = (uint32_t)cpu; + data[1] = TEGRA_PM_CC7; + data[2] = TEGRA_PM_SC1; + ret = tegra_bpmp_send_receive_atomic(MRQ_DO_IDLE, + (void *)&data, (int)sizeof(data), + (void *)&bpmp_reply, + (int)sizeof(bpmp_reply)); + + /* check if cluster power down is allowed */ + if ((ret != 0L) || (bpmp_reply != BPMP_CCx_ALLOWED)) { + + /* Cluster power down not allowed */ + target = PSCI_LOCAL_STATE_RUN; + } } } else if (((lvl == MPIDR_AFFLVL2) || (lvl == MPIDR_AFFLVL1)) && From 889c07c7b1a9739bcc907ad1f988fa484d22f84c Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Wed, 8 Nov 2017 14:45:08 -0800 Subject: [PATCH 19/27] Tegra186: helper functions for CPU rst handler and SMMU ctx offset This patch adds a helper function to get the SMMU context's offset and uses another helper function to get the CPU trampoline offset. These helper functions are used by the System Suspend entry sequence to save the SMMU context and CPU reset handler to TZDRAM. Change-Id: I95e2862fe37ccad00fa48ec165c6e4024df01147 Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/include/t186/tegra186_private.h | 1 + plat/nvidia/tegra/soc/t186/plat_psci_handlers.c | 10 +++------- plat/nvidia/tegra/soc/t186/plat_trampoline.S | 11 +++++++++++ 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/plat/nvidia/tegra/include/t186/tegra186_private.h b/plat/nvidia/tegra/include/t186/tegra186_private.h index cb52f084e..30b1595e8 100644 --- a/plat/nvidia/tegra/include/t186/tegra186_private.h +++ b/plat/nvidia/tegra/include/t186/tegra186_private.h @@ -10,5 +10,6 @@ void tegra186_cpu_reset_handler(void); uint64_t tegra186_get_cpu_reset_handler_base(void); uint64_t tegra186_get_cpu_reset_handler_size(void); +uint64_t tegra186_get_smmu_ctx_offset(void); #endif /* TEGRA186_PRIVATE_H */ diff --git a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c index 5d3cdfaf5..162a2833a 100644 --- a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c +++ b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c @@ -22,12 +22,10 @@ #include #include #include +#include #include extern void memcpy16(void *dest, const void *src, unsigned int length); -extern void tegra186_cpu_reset_handler(void); -extern uint64_t __tegra186_cpu_reset_handler_end, - __tegra186_smmu_context; /* state id mask */ #define TEGRA186_STATE_ID_MASK 0xFU @@ -127,8 +125,7 @@ int32_t tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state) /* save SMMU context to TZDRAM */ smmu_ctx_base = params_from_bl2->tzdram_base + - ((uintptr_t)&__tegra186_smmu_context - - (uintptr_t)&tegra186_cpu_reset_handler); + tegra186_get_smmu_ctx_offset(); tegra_smmu_save_context((uintptr_t)smmu_ctx_base); /* Prepare for system suspend */ @@ -279,8 +276,7 @@ int32_t tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_sta * BL3-1 over to TZDRAM. */ val = params_from_bl2->tzdram_base + - ((uintptr_t)&__tegra186_cpu_reset_handler_end - - (uintptr_t)&tegra186_cpu_reset_handler); + tegra186_get_cpu_reset_handler_size(); memcpy16((void *)(uintptr_t)val, (void *)(uintptr_t)BL31_BASE, (uintptr_t)&__BL31_END__ - (uintptr_t)BL31_BASE); } diff --git a/plat/nvidia/tegra/soc/t186/plat_trampoline.S b/plat/nvidia/tegra/soc/t186/plat_trampoline.S index 3ed2940ca..d609a144b 100644 --- a/plat/nvidia/tegra/soc/t186/plat_trampoline.S +++ b/plat/nvidia/tegra/soc/t186/plat_trampoline.S @@ -69,6 +69,8 @@ endfunc tegra186_cpu_reset_handler __tegra186_cpu_reset_handler_data: .quad tegra_secure_entrypoint .quad __BL31_END__ - BL31_BASE + + .align 4 .globl __tegra186_smmu_context __tegra186_smmu_context: .rept TEGRA186_SMMU_CTX_SIZE @@ -83,6 +85,7 @@ __tegra186_cpu_reset_handler_end: .globl tegra186_get_cpu_reset_handler_size .globl tegra186_get_cpu_reset_handler_base + .globl tegra186_get_smmu_ctx_offset /* return size of the CPU reset handler */ func tegra186_get_cpu_reset_handler_size @@ -97,3 +100,11 @@ func tegra186_get_cpu_reset_handler_base adr x0, tegra186_cpu_reset_handler ret endfunc tegra186_get_cpu_reset_handler_base + +/* return the size of the SMMU context */ +func tegra186_get_smmu_ctx_offset + adr x0, __tegra186_smmu_context + adr x1, tegra186_cpu_reset_handler + sub x0, x0, x1 + ret +endfunc tegra186_get_smmu_ctx_offset From 539c62d7b3d31612e4c6a4a9a1ba8fc80b3874c9 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Fri, 10 Nov 2017 10:26:57 -0800 Subject: [PATCH 20/27] Tegra186: save system suspend entry marker to TZDRAM This patch adds support to save the system suspend entry and exit markers to TZDRAM to help the trampoline code decide if the current warmboot is actually an exit from System Suspend. The Tegra186 platform handler sets the system suspend entry marker before entering SC7 state and the trampoline flips the state back to system resume, on exiting SC7. Change-Id: I29d73f1693c89ebc8d19d7abb1df1e460eb5558e Signed-off-by: Varun Wadekar --- .../tegra/include/t186/tegra186_private.h | 1 + .../tegra/soc/t186/plat_psci_handlers.c | 5 ++ plat/nvidia/tegra/soc/t186/plat_trampoline.S | 54 +++++++++++++++---- 3 files changed, 50 insertions(+), 10 deletions(-) diff --git a/plat/nvidia/tegra/include/t186/tegra186_private.h b/plat/nvidia/tegra/include/t186/tegra186_private.h index 30b1595e8..9e2c02b4b 100644 --- a/plat/nvidia/tegra/include/t186/tegra186_private.h +++ b/plat/nvidia/tegra/include/t186/tegra186_private.h @@ -11,5 +11,6 @@ void tegra186_cpu_reset_handler(void); uint64_t tegra186_get_cpu_reset_handler_base(void); uint64_t tegra186_get_cpu_reset_handler_size(void); uint64_t tegra186_get_smmu_ctx_offset(void); +void tegra186_set_system_suspend_entry(void); #endif /* TEGRA186_PRIVATE_H */ diff --git a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c index 162a2833a..09e257d53 100644 --- a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c +++ b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c @@ -134,6 +134,7 @@ int32_t tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state) cstate_info.system_state_force = 1; cstate_info.update_wake_mask = 1; mce_update_cstate_info(&cstate_info); + /* Loop until system suspend is allowed */ do { val = (uint32_t)mce_command_handler( @@ -146,6 +147,10 @@ int32_t tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state) /* Instruct the MCE to enter system suspend state */ (void)mce_command_handler((uint64_t)MCE_CMD_ENTER_CSTATE, (uint64_t)TEGRA_ARI_CORE_C7, MCE_CORE_SLEEP_TIME_INFINITE, 0U); + + /* set system suspend state for house-keeping */ + tegra186_set_system_suspend_entry(); + } else { ; /* do nothing */ } diff --git a/plat/nvidia/tegra/soc/t186/plat_trampoline.S b/plat/nvidia/tegra/soc/t186/plat_trampoline.S index d609a144b..e3393e90e 100644 --- a/plat/nvidia/tegra/soc/t186/plat_trampoline.S +++ b/plat/nvidia/tegra/soc/t186/plat_trampoline.S @@ -10,23 +10,32 @@ #include #include +#define TEGRA186_STATE_SYSTEM_SUSPEND 0x5C7 +#define TEGRA186_STATE_SYSTEM_RESUME 0x600D #define TEGRA186_SMMU_CTX_SIZE 0x420 .globl tegra186_cpu_reset_handler /* CPU reset handler routine */ func tegra186_cpu_reset_handler _align=4 - /* - * The TZRAM loses state during System Suspend. We use this - * information to decide if the reset handler is running after a - * System Suspend. Resume from system suspend requires restoring - * the entire state from TZDRAM to TZRAM. - */ - mov x0, #BL31_BASE - ldr x0, [x0] - cbnz x0, boot_cpu + /* check if we are exiting system suspend state */ + adr x0, __tegra186_system_suspend_state + ldr x1, [x0] + mov x2, #TEGRA186_STATE_SYSTEM_SUSPEND + lsl x2, x2, #16 + add x2, x2, #TEGRA186_STATE_SYSTEM_SUSPEND + cmp x1, x2 + bne boot_cpu - /* resume from system suspend */ + /* set system resume state */ + mov x1, #TEGRA186_STATE_SYSTEM_RESUME + lsl x1, x1, #16 + mov x2, #TEGRA186_STATE_SYSTEM_RESUME + add x1, x1, x2 + str x1, [x0] + dsb sy + + /* prepare to relocate to TZSRAM */ mov x0, #BL31_BASE adr x1, __tegra186_cpu_reset_handler_end adr x2, __tegra186_cpu_reset_handler_data @@ -70,6 +79,10 @@ __tegra186_cpu_reset_handler_data: .quad tegra_secure_entrypoint .quad __BL31_END__ - BL31_BASE + .globl __tegra186_system_suspend_state +__tegra186_system_suspend_state: + .quad 0 + .align 4 .globl __tegra186_smmu_context __tegra186_smmu_context: @@ -86,6 +99,7 @@ __tegra186_cpu_reset_handler_end: .globl tegra186_get_cpu_reset_handler_size .globl tegra186_get_cpu_reset_handler_base .globl tegra186_get_smmu_ctx_offset + .globl tegra186_set_system_suspend_entry /* return size of the CPU reset handler */ func tegra186_get_cpu_reset_handler_size @@ -108,3 +122,23 @@ func tegra186_get_smmu_ctx_offset sub x0, x0, x1 ret endfunc tegra186_get_smmu_ctx_offset + +/* set system suspend state before SC7 entry */ +func tegra186_set_system_suspend_entry + mov x0, #TEGRA_MC_BASE + mov x3, #MC_SECURITY_CFG3_0 + ldr w1, [x0, x3] + lsl x1, x1, #32 + mov x3, #MC_SECURITY_CFG0_0 + ldr w2, [x0, x3] + orr x3, x1, x2 /* TZDRAM base */ + adr x0, __tegra186_system_suspend_state + adr x1, tegra186_cpu_reset_handler + sub x2, x0, x1 /* offset in TZDRAM */ + mov x0, #TEGRA186_STATE_SYSTEM_SUSPEND + lsl x0, x0, #16 + add x0, x0, #TEGRA186_STATE_SYSTEM_SUSPEND + str x0, [x3, x2] /* set value in TZDRAM */ + dsb sy + ret +endfunc tegra186_set_system_suspend_entry From c63ec2639aea24641da342a4b5bc7126762241f0 Mon Sep 17 00:00:00 2001 From: Steven Kao Date: Tue, 14 Nov 2017 18:52:05 +0800 Subject: [PATCH 21/27] Tegra: memctrl_v2: platform handler for TZDRAM setup The Tegra memctrl driver sets up the TZDRAM fence during boot and system suspend exit. This patch provides individual platforms with handlers to perform custom steps during TZDRAM setup. Change-Id: Iee094d6ca189c6dd24f1147003c33c99ff3a953b Signed-off-by: Steven Kao --- .../tegra/common/drivers/memctrl/memctrl_v2.c | 17 +---------------- plat/nvidia/tegra/soc/t186/plat_memctrl.c | 18 ++++++++++++++++-- 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c index 0567aa9af..15314e722 100644 --- a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c +++ b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c @@ -30,6 +30,7 @@ static uint64_t video_mem_size_mb; * provide typical implementations that will be overridden by a SoC. */ #pragma weak plat_memctrl_tzdram_setup + void plat_memctrl_tzdram_setup(uint64_t phys_base, uint64_t size_in_bytes) { ; /* do nothing */ @@ -154,26 +155,10 @@ void tegra_memctrl_restore_settings(void) */ void tegra_memctrl_tzdram_setup(uint64_t phys_base, uint32_t size_in_bytes) { - /* - * Setup the Memory controller to allow only secure accesses to - * the TZDRAM carveout - */ - INFO("Configuring TrustZone DRAM Memory Carveout\n"); - - tegra_mc_write_32(MC_SECURITY_CFG0_0, (uint32_t)phys_base); - tegra_mc_write_32(MC_SECURITY_CFG3_0, (uint32_t)(phys_base >> 32)); - tegra_mc_write_32(MC_SECURITY_CFG1_0, size_in_bytes >> 20); - /* * Perform platform specific steps. */ plat_memctrl_tzdram_setup(phys_base, size_in_bytes); - - /* - * MCE propagates the security configuration values across the - * CCPLEX. - */ - mce_update_gsc_tzdram(); } /* diff --git a/plat/nvidia/tegra/soc/t186/plat_memctrl.c b/plat/nvidia/tegra/soc/t186/plat_memctrl.c index 71904a8f6..376ee86df 100644 --- a/plat/nvidia/tegra/soc/t186/plat_memctrl.c +++ b/plat/nvidia/tegra/soc/t186/plat_memctrl.c @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -546,8 +547,15 @@ void plat_memctrl_tzdram_setup(uint64_t phys_base, uint64_t size_in_bytes) { uint32_t val; - (void)phys_base; - (void)size_in_bytes; + /* + * Setup the Memory controller to allow only secure accesses to + * the TZDRAM carveout + */ + INFO("Configuring TrustZone DRAM Memory Carveout\n"); + + tegra_mc_write_32(MC_SECURITY_CFG0_0, (uint32_t)phys_base); + tegra_mc_write_32(MC_SECURITY_CFG3_0, (uint32_t)(phys_base >> 32)); + tegra_mc_write_32(MC_SECURITY_CFG1_0, size_in_bytes >> 20); /* * When TZ encryption is enabled, we need to setup TZDRAM @@ -565,4 +573,10 @@ void plat_memctrl_tzdram_setup(uint64_t phys_base, uint64_t size_in_bytes) val = tegra_mc_read_32(MC_SECURITY_CFG3_0) & MC_SECURITY_BOM_HI_MASK; mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_TZDRAM_ADDR_HI, val); + + /* + * MCE propagates the security configuration values across the + * CCPLEX. + */ + (void)mce_update_gsc_tzdram(); } From 2ad1bddca9272d622696d882c9439aaa06e359ff Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Wed, 8 Nov 2017 14:03:16 -0800 Subject: [PATCH 22/27] Tegra: smmu: change exit criteria for context size calculation Tegra SoCs currently do not have a SMMU register at address 0xFFFFFFFF. This patch changes the search criteria, to look for this marker, to calculate the size of the saved context. Change-Id: I15d91945ecb78267f91c45f37985dbb2327ca3ae Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/common/drivers/smmu/smmu.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plat/nvidia/tegra/common/drivers/smmu/smmu.c b/plat/nvidia/tegra/common/drivers/smmu/smmu.c index 333d7d163..8c1b899f7 100644 --- a/plat/nvidia/tegra/common/drivers/smmu/smmu.c +++ b/plat/nvidia/tegra/common/drivers/smmu/smmu.c @@ -101,12 +101,13 @@ void tegra_smmu_save_context(uint64_t smmu_ctx_addr) * the last entry. Sanity check the table size before we start with * the context save operation. */ - while (smmu_ctx_regs[num_entries].val != 0xFFFFFFFFU) { + while ((smmu_ctx_regs[num_entries].reg != 0xFFFFFFFFU)) { num_entries++; } /* panic if the sizes do not match */ if (num_entries != smmu_ctx_regs[0].val) { + ERROR("SMMU context size mismatch!"); panic(); } From 4cba6985671323e19f6a6d8a7eb7e6f7125527a1 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Wed, 15 Nov 2017 15:46:38 -0800 Subject: [PATCH 23/27] Tegra: console driver compilation from platform makefiles This patch includes the console driver from individual platform makefiles and removes it from tegra_common.mk. This allows future platforms to include consoles of their choice. Change-Id: I7506562bfac78421a80fb6782ac8472fbef6cfb0 Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/common/tegra_common.mk | 1 - plat/nvidia/tegra/soc/t132/platform_t132.mk | 3 ++- plat/nvidia/tegra/soc/t186/platform_t186.mk | 3 ++- plat/nvidia/tegra/soc/t210/platform_t210.mk | 5 +++-- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/plat/nvidia/tegra/common/tegra_common.mk b/plat/nvidia/tegra/common/tegra_common.mk index 9428f43a7..d9eec4d37 100644 --- a/plat/nvidia/tegra/common/tegra_common.mk +++ b/plat/nvidia/tegra/common/tegra_common.mk @@ -22,7 +22,6 @@ TEGRA_GICv2_SOURCES := drivers/arm/gic/common/gic_common.c \ BL31_SOURCES += drivers/console/aarch64/console.S \ drivers/delay_timer/delay_timer.c \ - drivers/ti/uart/aarch64/16550_console.S \ ${TEGRA_GICv2_SOURCES} \ ${COMMON_DIR}/aarch64/tegra_helpers.S \ ${COMMON_DIR}/drivers/pmc/pmc.c \ diff --git a/plat/nvidia/tegra/soc/t132/platform_t132.mk b/plat/nvidia/tegra/soc/t132/platform_t132.mk index f15ee747b..bb7b7ee66 100644 --- a/plat/nvidia/tegra/soc/t132/platform_t132.mk +++ b/plat/nvidia/tegra/soc/t132/platform_t132.mk @@ -19,7 +19,8 @@ $(eval $(call add_define,MAX_XLAT_TABLES)) MAX_MMAP_REGIONS := 8 $(eval $(call add_define,MAX_MMAP_REGIONS)) -BL31_SOURCES += lib/cpus/aarch64/denver.S \ +BL31_SOURCES += drivers/ti/uart/aarch64/16550_console.S \ + lib/cpus/aarch64/denver.S \ ${COMMON_DIR}/drivers/flowctrl/flowctrl.c \ ${COMMON_DIR}/drivers/memctrl/memctrl_v1.c \ ${SOC_DIR}/plat_psci_handlers.c \ diff --git a/plat/nvidia/tegra/soc/t186/platform_t186.mk b/plat/nvidia/tegra/soc/t186/platform_t186.mk index 9dae8cd67..643443529 100644 --- a/plat/nvidia/tegra/soc/t186/platform_t186.mk +++ b/plat/nvidia/tegra/soc/t186/platform_t186.mk @@ -45,7 +45,8 @@ $(eval $(call add_define,MAX_MMAP_REGIONS)) # platform files PLAT_INCLUDES += -I${SOC_DIR}/drivers/include -BL31_SOURCES += lib/cpus/aarch64/denver.S \ +BL31_SOURCES += drivers/ti/uart/aarch64/16550_console.S \ + lib/cpus/aarch64/denver.S \ lib/cpus/aarch64/cortex_a57.S \ ${COMMON_DIR}/drivers/gpcdma/gpcdma.c \ ${COMMON_DIR}/drivers/memctrl/memctrl_v2.c \ diff --git a/plat/nvidia/tegra/soc/t210/platform_t210.mk b/plat/nvidia/tegra/soc/t210/platform_t210.mk index b8dbf1836..e23d7e360 100644 --- a/plat/nvidia/tegra/soc/t210/platform_t210.mk +++ b/plat/nvidia/tegra/soc/t210/platform_t210.mk @@ -24,9 +24,10 @@ $(eval $(call add_define,MAX_MMAP_REGIONS)) PLAT_INCLUDES += -I${SOC_DIR}/drivers/se -BL31_SOURCES += lib/cpus/aarch64/cortex_a53.S \ +BL31_SOURCES += drivers/ti/uart/aarch64/16550_console.S \ + lib/cpus/aarch64/cortex_a53.S \ lib/cpus/aarch64/cortex_a57.S \ - ${COMMON_DIR}/drivers/bpmp/bpmp.c \ + ${COMMON_DIR}/drivers/bpmp/bpmp.c \ ${COMMON_DIR}/drivers/flowctrl/flowctrl.c \ ${COMMON_DIR}/drivers/memctrl/memctrl_v1.c \ ${SOC_DIR}/plat_psci_handlers.c \ From dd20f5b3d927a5af48bb4d8904c81a265da5678f Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Wed, 15 Nov 2017 15:48:51 -0800 Subject: [PATCH 24/27] Tegra: spe: shared console for Tegra platforms There are Tegra platforms which have limited UART ports and so all the components have to share the console. The SPE helps out by collecting all the logs in such cases and prints them on the shared UART port. This patch adds a driver to communicate with the SPE driver, which in turn provides the console. Change-Id: Ie750520b936b8bed0ab1d876f03fc0a3490a85a3 Signed-off-by: Varun Wadekar --- .../tegra/common/drivers/spe/shared_console.S | 118 ++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 plat/nvidia/tegra/common/drivers/spe/shared_console.S diff --git a/plat/nvidia/tegra/common/drivers/spe/shared_console.S b/plat/nvidia/tegra/common/drivers/spe/shared_console.S new file mode 100644 index 000000000..a9f0334f1 --- /dev/null +++ b/plat/nvidia/tegra/common/drivers/spe/shared_console.S @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#include + +#define CONSOLE_NUM_BYTES_SHIFT 24 +#define CONSOLE_FLUSH_DATA_TO_PORT (1 << 26) +#define CONSOLE_RING_DOORBELL (1 << 31) +#define CONSOLE_IS_BUSY (1 << 31) +#define CONSOLE_WRITE (CONSOLE_RING_DOORBELL | CONSOLE_FLUSH_DATA_TO_PORT) + + /* + * This file contains a driver implementation to make use of the + * real console implementation provided by the SPE firmware running + * SoCs after Tegra186. + * + * This console is shared by multiple components and the SPE firmware + * finally displays everything on the UART port. + */ + + .globl console_core_init + .globl console_core_putc + .globl console_core_getc + .globl console_core_flush + + /* ----------------------------------------------- + * int console_core_init(uintptr_t base_addr, + * unsigned int uart_clk, unsigned int baud_rate) + * Function to initialize the console without a + * C Runtime to print debug information. This + * function will be accessed by console_init and + * crash reporting. + * In: x0 - console base address + * w1 - Uart clock in Hz + * w2 - Baud rate + * Out: return 1 on success else 0 on error + * Clobber list : x1, x2 + * ----------------------------------------------- + */ +func console_core_init + /* Check the input base address */ + cbz x0, core_init_fail + mov w0, #1 + ret +core_init_fail: + mov w0, wzr + ret +endfunc console_core_init + + /* -------------------------------------------------------- + * int console_core_putc(int c, uintptr_t base_addr) + * Function to output a character over the console. It + * returns the character printed on success or -1 on error. + * In : w0 - character to be printed + * x1 - console base address + * Out : return -1 on error else return character. + * Clobber list : x2 + * -------------------------------------------------------- + */ +func console_core_putc + /* Check the input parameter */ + cbz x1, putc_error + + /* wait until spe is ready */ +1: ldr w2, [x1] + and w2, w2, #CONSOLE_IS_BUSY + cbnz w2, 1b + + /* spe is ready */ + mov w2, w0 + and w2, w2, #0xFF + mov w3, #(CONSOLE_WRITE | (1 << CONSOLE_NUM_BYTES_SHIFT)) + orr w2, w2, w3 + str w2, [x1] + + ret +putc_error: + mov w0, #-1 + ret +endfunc console_core_putc + + /* --------------------------------------------- + * int console_core_getc(uintptr_t base_addr) + * Function to get a character from the console. + * It returns the character grabbed on success + * or -1 on error. + * In : x0 - console base address + * Clobber list : x0, x1 + * --------------------------------------------- + */ +func console_core_getc + mov w0, #-1 + ret +endfunc console_core_getc + + /* --------------------------------------------- + * int console_core_flush(uintptr_t base_addr) + * Function to force a write of all buffered + * data that hasn't been output. + * In : x0 - console base address + * Out : return -1 on error else return 0. + * Clobber list : x0, x1 + * --------------------------------------------- + */ +func console_core_flush + cbz x0, flush_error + + /* flush console */ + mov w1, #CONSOLE_WRITE + str w1, [x0] + mov w0, #0 + ret +flush_error: + mov w0, #-1 + ret +endfunc console_core_flush From 3e1923d9cf6416a0f69aa325a8cb1b2ef41a4408 Mon Sep 17 00:00:00 2001 From: Dilan Lee Date: Fri, 27 Oct 2017 09:51:09 +0800 Subject: [PATCH 25/27] Tegra: add 'late' platform setup handler This patch adds a platform setup handler that gets called after the MMU is enabled. Platforms wanting to make use of this handler should declare 'plat_late_platform_setup' handler in their platform files, to override the default weakly defined handler. Change-Id: Ibc97a2e5a24608ddea856d0bd543a9d5876f604c Signed-off-by: Dilan Lee --- plat/nvidia/tegra/common/tegra_bl31_setup.c | 13 +++++++++++++ plat/nvidia/tegra/include/tegra_private.h | 3 ++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/plat/nvidia/tegra/common/tegra_bl31_setup.c b/plat/nvidia/tegra/common/tegra_bl31_setup.c index 4712b8ab6..908e4f2dd 100644 --- a/plat/nvidia/tegra/common/tegra_bl31_setup.c +++ b/plat/nvidia/tegra/common/tegra_bl31_setup.c @@ -70,6 +70,7 @@ extern uint64_t ns_image_entrypoint; #pragma weak plat_early_platform_setup #pragma weak plat_get_bl31_params #pragma weak plat_get_bl31_plat_params +#pragma weak plat_late_platform_setup void plat_early_platform_setup(void) { @@ -86,6 +87,11 @@ plat_params_from_bl2_t *plat_get_bl31_plat_params(void) return NULL; } +void plat_late_platform_setup(void) +{ + ; /* do nothing */ +} + /******************************************************************************* * Return a pointer to the 'entry_point_info' structure of the next image for * security state specified. BL33 corresponds to the non-secure image type @@ -328,6 +334,13 @@ void bl31_platform_setup(void) */ tegra_memctrl_tzram_setup(TEGRA_TZRAM_BASE, TEGRA_TZRAM_SIZE); + /* + * Late setup handler to allow platforms to performs additional + * functionality. + * This handler gets called with MMU enabled. + */ + plat_late_platform_setup(); + /* * Add timestamp for platform setup exit. */ diff --git a/plat/nvidia/tegra/include/tegra_private.h b/plat/nvidia/tegra/include/tegra_private.h index f55f5df60..68b462425 100644 --- a/plat/nvidia/tegra/include/tegra_private.h +++ b/plat/nvidia/tegra/include/tegra_private.h @@ -75,6 +75,8 @@ uint32_t plat_get_console_from_id(int32_t id); void plat_gic_setup(void); struct tegra_bl31_params *plat_get_bl31_params(void); plat_params_from_bl2_t *plat_get_bl31_plat_params(void); +void plat_early_platform_setup(void); +void plat_late_platform_setup(void); /* Declarations for plat_secondary.c */ void plat_secondary_setup(void); @@ -126,7 +128,6 @@ int tegra_prepare_cpu_on_finish(unsigned long mpidr); /* Declarations for tegra_bl31_setup.c */ plat_params_from_bl2_t *bl31_get_plat_params(void); int32_t bl31_check_ns_address(uint64_t base, uint64_t size_in_bytes); -void plat_early_platform_setup(void); /* Declarations for tegra_delay_timer.c */ void tegra_delay_timer_init(void); From fc5adf7d1b48c9cdb47229bfed680aec7be6999b Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Wed, 29 Nov 2017 17:14:24 -0800 Subject: [PATCH 26/27] Tegra: memctrl_v2: remove usage of ENABLE_SMMU_DEVICE config This patch removes the usage of this platform config, as it is always enabled by all the supported platforms. Change-Id: Ie7adb641adeb3604b177b6960b797722d60addfa Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c | 3 +-- plat/nvidia/tegra/soc/t186/platform_t186.mk | 3 --- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c index 15314e722..a3ef5e131 100644 --- a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c +++ b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c @@ -51,10 +51,9 @@ void tegra_memctrl_setup(void) INFO("Tegra Memory Controller (v2)\n"); -#if ENABLE_SMMU_DEVICE /* Program the SMMU pagesize */ tegra_smmu_init(); -#endif + /* Get the settings from the platform */ assert(plat_mc_settings != NULL); mc_streamid_override_regs = plat_mc_settings->streamid_override_cfg; diff --git a/plat/nvidia/tegra/soc/t186/platform_t186.mk b/plat/nvidia/tegra/soc/t186/platform_t186.mk index 643443529..d486af2d5 100644 --- a/plat/nvidia/tegra/soc/t186/platform_t186.mk +++ b/plat/nvidia/tegra/soc/t186/platform_t186.mk @@ -17,9 +17,6 @@ $(eval $(call add_define,RELOCATE_TO_BL31_BASE)) ENABLE_CHIP_VERIFICATION_HARNESS := 0 $(eval $(call add_define,ENABLE_CHIP_VERIFICATION_HARNESS)) -ENABLE_SMMU_DEVICE := 1 -$(eval $(call add_define,ENABLE_SMMU_DEVICE)) - RESET_TO_BL31 := 1 PROGRAMMABLE_RESET_ADDRESS := 1 From 8ec4562165103792ac12e9531c9c5b9a4c4f4d98 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Wed, 29 Nov 2017 17:16:48 -0800 Subject: [PATCH 27/27] Tegra186: remove RELOCATE_TO_BL31_BASE config This patch removes this unused config option from the Tegra186 platform makefiles. Change-Id: Idcdf6854332a26599323a247289c2d3ce19f475f Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/soc/t186/platform_t186.mk | 3 --- 1 file changed, 3 deletions(-) diff --git a/plat/nvidia/tegra/soc/t186/platform_t186.mk b/plat/nvidia/tegra/soc/t186/platform_t186.mk index d486af2d5..fdeb886cd 100644 --- a/plat/nvidia/tegra/soc/t186/platform_t186.mk +++ b/plat/nvidia/tegra/soc/t186/platform_t186.mk @@ -11,9 +11,6 @@ $(eval $(call add_define,ENABLE_AFI_DEVICE)) ENABLE_ROC_FOR_ORDERING_CLIENT_REQUESTS := 1 $(eval $(call add_define,ENABLE_ROC_FOR_ORDERING_CLIENT_REQUESTS)) -RELOCATE_TO_BL31_BASE := 1 -$(eval $(call add_define,RELOCATE_TO_BL31_BASE)) - ENABLE_CHIP_VERIFICATION_HARNESS := 0 $(eval $(call add_define,ENABLE_CHIP_VERIFICATION_HARNESS))