diff --git a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c new file mode 100644 index 000000000..e11b8adac --- /dev/null +++ b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c @@ -0,0 +1,450 @@ +/* + * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define TEGRA_GPU_RESET_REG_OFFSET 0x30 +#define GPU_RESET_BIT (1 << 0) + +/* Video Memory base and size (live values) */ +static uint64_t video_mem_base; +static uint64_t video_mem_size; + +/* array to hold stream_id override config register offsets */ +const static uint32_t streamid_overrides[] = { + MC_STREAMID_OVERRIDE_CFG_PTCR, + MC_STREAMID_OVERRIDE_CFG_AFIR, + MC_STREAMID_OVERRIDE_CFG_HDAR, + MC_STREAMID_OVERRIDE_CFG_HOST1XDMAR, + MC_STREAMID_OVERRIDE_CFG_NVENCSRD, + MC_STREAMID_OVERRIDE_CFG_SATAR, + MC_STREAMID_OVERRIDE_CFG_MPCORER, + MC_STREAMID_OVERRIDE_CFG_NVENCSWR, + MC_STREAMID_OVERRIDE_CFG_AFIW, + MC_STREAMID_OVERRIDE_CFG_SATAW, + MC_STREAMID_OVERRIDE_CFG_MPCOREW, + MC_STREAMID_OVERRIDE_CFG_SATAW, + MC_STREAMID_OVERRIDE_CFG_HDAW, + MC_STREAMID_OVERRIDE_CFG_ISPRA, + MC_STREAMID_OVERRIDE_CFG_ISPWA, + MC_STREAMID_OVERRIDE_CFG_ISPWB, + MC_STREAMID_OVERRIDE_CFG_XUSB_HOSTR, + MC_STREAMID_OVERRIDE_CFG_XUSB_HOSTW, + MC_STREAMID_OVERRIDE_CFG_XUSB_DEVR, + MC_STREAMID_OVERRIDE_CFG_XUSB_DEVW, + MC_STREAMID_OVERRIDE_CFG_TSECSRD, + MC_STREAMID_OVERRIDE_CFG_TSECSWR, + MC_STREAMID_OVERRIDE_CFG_GPUSRD, + MC_STREAMID_OVERRIDE_CFG_GPUSWR, + MC_STREAMID_OVERRIDE_CFG_SDMMCRA, + MC_STREAMID_OVERRIDE_CFG_SDMMCRAA, + MC_STREAMID_OVERRIDE_CFG_SDMMCR, + MC_STREAMID_OVERRIDE_CFG_SDMMCRAB, + MC_STREAMID_OVERRIDE_CFG_SDMMCWA, + MC_STREAMID_OVERRIDE_CFG_SDMMCWAA, + MC_STREAMID_OVERRIDE_CFG_SDMMCW, + MC_STREAMID_OVERRIDE_CFG_SDMMCWAB, + MC_STREAMID_OVERRIDE_CFG_VICSRD, + MC_STREAMID_OVERRIDE_CFG_VICSWR, + MC_STREAMID_OVERRIDE_CFG_VIW, + MC_STREAMID_OVERRIDE_CFG_NVDECSRD, + MC_STREAMID_OVERRIDE_CFG_NVDECSWR, + MC_STREAMID_OVERRIDE_CFG_APER, + MC_STREAMID_OVERRIDE_CFG_APEW, + MC_STREAMID_OVERRIDE_CFG_NVJPGSRD, + MC_STREAMID_OVERRIDE_CFG_NVJPGSWR, + MC_STREAMID_OVERRIDE_CFG_SESRD, + MC_STREAMID_OVERRIDE_CFG_SESWR, + MC_STREAMID_OVERRIDE_CFG_ETRR, + MC_STREAMID_OVERRIDE_CFG_ETRW, + MC_STREAMID_OVERRIDE_CFG_TSECSRDB, + MC_STREAMID_OVERRIDE_CFG_TSECSWRB, + MC_STREAMID_OVERRIDE_CFG_GPUSRD2, + MC_STREAMID_OVERRIDE_CFG_GPUSWR2, + MC_STREAMID_OVERRIDE_CFG_AXISR, + MC_STREAMID_OVERRIDE_CFG_AXISW, + MC_STREAMID_OVERRIDE_CFG_EQOSR, + MC_STREAMID_OVERRIDE_CFG_EQOSW, + MC_STREAMID_OVERRIDE_CFG_UFSHCR, + MC_STREAMID_OVERRIDE_CFG_UFSHCW, + MC_STREAMID_OVERRIDE_CFG_NVDISPLAYR, + MC_STREAMID_OVERRIDE_CFG_BPMPR, + MC_STREAMID_OVERRIDE_CFG_BPMPW, + MC_STREAMID_OVERRIDE_CFG_BPMPDMAR, + MC_STREAMID_OVERRIDE_CFG_BPMPDMAW, + MC_STREAMID_OVERRIDE_CFG_AONR, + MC_STREAMID_OVERRIDE_CFG_AONW, + MC_STREAMID_OVERRIDE_CFG_AONDMAR, + MC_STREAMID_OVERRIDE_CFG_AONDMAW, + MC_STREAMID_OVERRIDE_CFG_SCER, + MC_STREAMID_OVERRIDE_CFG_SCEW, + MC_STREAMID_OVERRIDE_CFG_SCEDMAR, + MC_STREAMID_OVERRIDE_CFG_SCEDMAW, + MC_STREAMID_OVERRIDE_CFG_APEDMAR, + MC_STREAMID_OVERRIDE_CFG_APEDMAW, + MC_STREAMID_OVERRIDE_CFG_NVDISPLAYR1, + MC_STREAMID_OVERRIDE_CFG_VICSRD1, + MC_STREAMID_OVERRIDE_CFG_NVDECSRD1 +}; + +/* array to hold the security configs for stream IDs */ +const static mc_streamid_security_cfg_t sec_cfgs[] = { + mc_make_sec_cfg(SCEW, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(AFIR, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(NVDISPLAYR1, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(XUSB_DEVR, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(VICSRD1, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(NVENCSWR, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(TSECSRDB, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(AXISW, SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(SDMMCWAB, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(AONDMAW, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(GPUSWR2, SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(SATAW, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(UFSHCW, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(AFIW, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(SDMMCR, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(SCEDMAW, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(UFSHCR, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(SDMMCWAA, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(APEDMAW, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(SESWR, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(MPCORER, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(PTCR, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(BPMPW, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(ETRW, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(GPUSRD, SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(VICSWR, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(SCEDMAR, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(HDAW, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(ISPWA, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(EQOSW, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(XUSB_HOSTW, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(TSECSWR, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(SDMMCRAA, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(APER, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(VIW, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(APEW, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(AXISR, SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(SDMMCW, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(BPMPDMAW, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(ISPRA, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(NVDECSWR, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(XUSB_DEVW, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(NVDECSRD, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(MPCOREW, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(NVDISPLAYR, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(BPMPDMAR, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(NVJPGSWR, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(NVDECSRD1, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(TSECSRD, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(NVJPGSRD, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(SDMMCWA, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(SCER, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(XUSB_HOSTR, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(VICSRD, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(AONDMAR, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(AONW, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(SDMMCRA, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(HOST1XDMAR, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(EQOSR, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(SATAR, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(BPMPR, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(HDAR, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(SDMMCRAB, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(ETRR, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(AONR, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(APEDMAR, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(SESRD, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(NVENCSRD, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(GPUSWR, SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(TSECSWRB, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(ISPWB, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(GPUSRD2, SECURE, NO_OVERRIDE, DISABLE), +}; + +const static mc_txn_override_cfg_t mc_override_cfgs[] = { + mc_make_txn_override_cfg(BPMPW, CGID_TAG_ADR), + mc_make_txn_override_cfg(EQOSW, CGID_TAG_ADR), + mc_make_txn_override_cfg(NVJPGSWR, CGID_TAG_ADR), + mc_make_txn_override_cfg(SDMMCWAA, CGID_TAG_ADR), + mc_make_txn_override_cfg(MPCOREW, CGID_TAG_ADR), + mc_make_txn_override_cfg(SCEDMAW, CGID_TAG_ADR), + mc_make_txn_override_cfg(SDMMCW, CGID_TAG_ADR), + mc_make_txn_override_cfg(AXISW, CGID_TAG_ADR), + mc_make_txn_override_cfg(TSECSWR, CGID_TAG_ADR), + mc_make_txn_override_cfg(GPUSWR, CGID_TAG_ADR), + mc_make_txn_override_cfg(XUSB_HOSTW, CGID_TAG_ADR), + mc_make_txn_override_cfg(TSECSWRB, CGID_TAG_ADR), + mc_make_txn_override_cfg(GPUSWR2, CGID_TAG_ADR), + mc_make_txn_override_cfg(AONDMAW, CGID_TAG_ADR), + mc_make_txn_override_cfg(AONW, CGID_TAG_ADR), + mc_make_txn_override_cfg(SESWR, CGID_TAG_ADR), + mc_make_txn_override_cfg(BPMPDMAW, CGID_TAG_ADR), + mc_make_txn_override_cfg(SDMMCWA, CGID_TAG_ADR), + mc_make_txn_override_cfg(HDAW, CGID_TAG_ADR), + mc_make_txn_override_cfg(NVDECSWR, CGID_TAG_ADR), + mc_make_txn_override_cfg(UFSHCW, CGID_TAG_ADR), + mc_make_txn_override_cfg(SATAW, CGID_TAG_ADR), + mc_make_txn_override_cfg(ETRW, CGID_TAG_ADR), + mc_make_txn_override_cfg(VICSWR, CGID_TAG_ADR), + mc_make_txn_override_cfg(NVENCSWR, CGID_TAG_ADR), + mc_make_txn_override_cfg(SDMMCWAB, CGID_TAG_ADR), + mc_make_txn_override_cfg(ISPWB, CGID_TAG_ADR), + mc_make_txn_override_cfg(APEW, CGID_TAG_ADR), + mc_make_txn_override_cfg(XUSB_DEVW, CGID_TAG_ADR), + mc_make_txn_override_cfg(AFIW, CGID_TAG_ADR), + mc_make_txn_override_cfg(SCEW, CGID_TAG_ADR), +}; + +/* + * Init Memory controller during boot. + */ +void tegra_memctrl_setup(void) +{ + uint32_t val; + uint32_t num_overrides = sizeof(streamid_overrides) / sizeof(uint32_t); + uint32_t num_sec_cfgs = sizeof(sec_cfgs) / sizeof(mc_streamid_security_cfg_t); + uint32_t num_txn_overrides = sizeof(mc_override_cfgs) / sizeof(mc_txn_override_cfg_t); + uint32_t tegra_rev; + int i; + + INFO("Tegra Memory Controller (v2)\n"); + + /* Program the SMMU pagesize */ + tegra_smmu_init(); + + /* Program all the Stream ID overrides */ + for (i = 0; i < num_overrides; i++) + tegra_mc_streamid_write_32(streamid_overrides[i], + MC_STREAM_ID_MAX); + + /* Program the security config settings for all Stream IDs */ + for (i = 0; i < num_sec_cfgs; i++) { + val = sec_cfgs[i].override_enable << 16 | + sec_cfgs[i].override_client_inputs << 8 | + sec_cfgs[i].override_client_ns_flag << 0; + tegra_mc_streamid_write_32(sec_cfgs[i].offset, val); + } + + /* + * All requests at boot time, and certain requests during + * normal run time, are physically addressed and must bypass + * the SMMU. The client hub logic implements a hardware bypass + * path around the Translation Buffer Units (TBU). During + * boot-time, the SMMU_BYPASS_CTRL register (which defaults to + * TBU_BYPASS mode) will be used to steer all requests around + * the uninitialized TBUs. During normal operation, this register + * is locked into TBU_BYPASS_SID config, which routes requests + * with special StreamID 0x7f on the bypass path and all others + * through the selected TBU. This is done to disable SMMU Bypass + * mode, as it could be used to circumvent SMMU security checks. + */ + tegra_mc_write_32(MC_SMMU_BYPASS_CONFIG, + MC_SMMU_BYPASS_CONFIG_SETTINGS); + + /* + * Set the MC_TXN_OVERRIDE registers for write clients. + */ + tegra_rev = (mmio_read_32(TEGRA_MISC_BASE + HARDWARE_REVISION_OFFSET) & + HARDWARE_MINOR_REVISION_MASK) >> HARDWARE_MINOR_REVISION_SHIFT; + + if (tegra_rev == HARDWARE_REVISION_A01) { + + /* GPU and NVENC settings for rev. A01 */ + val = tegra_mc_read_32(MC_TXN_OVERRIDE_CONFIG_GPUSWR); + val &= ~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 &= ~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 &= ~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 rev. A02 */ + for (i = 0; i < num_txn_overrides; i++) { + val = tegra_mc_read_32(mc_override_cfgs[i].offset); + val &= ~MC_TXN_OVERRIDE_CGID_TAG_MASK; + tegra_mc_write_32(mc_override_cfgs[i].offset, + val | mc_override_cfgs[i].cgid_tag); + } + + } +} + +/* + * Restore Memory Controller settings after "System Suspend" + */ +void tegra_memctrl_restore_settings(void) +{ + /* video memory carveout region */ + if (video_mem_base) { + tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_LO, + (uint32_t)video_mem_base); + tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_HI, + (uint32_t)(video_mem_base >> 32)); + tegra_mc_write_32(MC_VIDEO_PROTECT_SIZE_MB, video_mem_size); + + /* + * MCE propogates the VideoMem configuration values across the + * CCPLEX. + */ + mce_update_gsc_videomem(); + } +} + +/* + * Secure the BL31 DRAM aperture. + * + * phys_base = physical base of TZDRAM aperture + * size_in_bytes = size of aperture in bytes + */ +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); + + /* + * MCE propogates the security configuration values across the + * CCPLEX. + */ + mce_update_gsc_tzdram(); +} + +/* + * Secure the BL31 TZRAM aperture. + * + * phys_base = physical base of TZRAM aperture + * size_in_bytes = size of aperture in bytes + */ +void tegra_memctrl_tzram_setup(uint64_t phys_base, uint32_t size_in_bytes) +{ + uint64_t tzram_end = phys_base + size_in_bytes - 1; + uint32_t val; + + /* + * Check if the TZRAM is locked already. + */ + if (tegra_mc_read_32(MC_TZRAM_REG_CTRL) == DISABLE_TZRAM_ACCESS) + return; + + /* + * Setup the Memory controller to allow only secure accesses to + * the TZRAM carveout + */ + INFO("Configuring TrustZone RAM (SysRAM) Memory Carveout\n"); + + /* Program the base and end values */ + tegra_mc_write_32(MC_TZRAM_BASE, (uint32_t)phys_base); + tegra_mc_write_32(MC_TZRAM_END, (uint32_t)tzram_end); + + /* Extract the high address bits from the base/end values */ + val = (uint32_t)(phys_base >> 32) & TZRAM_ADDR_HI_BITS_MASK; + val |= (((uint32_t)(tzram_end >> 32) << TZRAM_END_HI_BITS_SHIFT) & + TZRAM_ADDR_HI_BITS_MASK); + tegra_mc_write_32(MC_TZRAM_HI_ADDR_BITS, val); + + /* Disable further writes to the TZRAM setup registers */ + tegra_mc_write_32(MC_TZRAM_REG_CTRL, DISABLE_TZRAM_ACCESS); + + /* + * MCE propogates the security configuration values across the + * CCPLEX. + */ + mce_update_gsc_tzram(); +} + +/* + * Program the Video Memory carveout region + * + * phys_base = physical base of aperture + * size_in_bytes = size of aperture in bytes + */ +void tegra_memctrl_videomem_setup(uint64_t phys_base, uint32_t size_in_bytes) +{ + uint32_t regval; + + /* + * The GPU is the user of the Video Memory region. In order to + * transition to the new memory region smoothly, we program the + * new base/size ONLY if the GPU is in reset mode. + */ + regval = mmio_read_32(TEGRA_CAR_RESET_BASE + TEGRA_GPU_RESET_REG_OFFSET); + if ((regval & GPU_RESET_BIT) == 0) { + ERROR("GPU not in reset! Video Memory setup failed\n"); + return; + } + + /* + * Setup the Memory controller to restrict CPU accesses to the Video + * Memory region + */ + INFO("Configuring Video Memory Carveout\n"); + + tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_LO, (uint32_t)phys_base); + tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_HI, + (uint32_t)(phys_base >> 32)); + tegra_mc_write_32(MC_VIDEO_PROTECT_SIZE_MB, size_in_bytes); + + /* store new values */ + video_mem_base = phys_base; + video_mem_size = size_in_bytes >> 20; + + /* + * MCE propogates the VideoMem configuration values across the + * CCPLEX. + */ + mce_update_gsc_videomem(); +} diff --git a/plat/nvidia/tegra/common/tegra_platform.c b/plat/nvidia/tegra/common/tegra_platform.c index 5b96459cd..0724b18ee 100644 --- a/plat/nvidia/tegra/common/tegra_platform.c +++ b/plat/nvidia/tegra/common/tegra_platform.c @@ -82,7 +82,7 @@ static uint32_t tegra_get_chipid(void) /* * Read the chip's major version from chip ID value */ -static uint32_t tegra_get_chipid_major(void) +uint32_t tegra_get_chipid_major(void) { return (tegra_get_chipid() >> MAJOR_VERSION_SHIFT) & MAJOR_VERSION_MASK; } @@ -90,7 +90,7 @@ static uint32_t tegra_get_chipid_major(void) /* * Read the chip's minor version from the chip ID value */ -static uint32_t tegra_get_chipid_minor(void) +uint32_t tegra_get_chipid_minor(void) { return (tegra_get_chipid() >> MINOR_VERSION_SHIFT) & MINOR_VERSION_MASK; } diff --git a/plat/nvidia/tegra/include/drivers/memctrl_v2.h b/plat/nvidia/tegra/include/drivers/memctrl_v2.h new file mode 100644 index 000000000..9623e25f8 --- /dev/null +++ b/plat/nvidia/tegra/include/drivers/memctrl_v2.h @@ -0,0 +1,391 @@ +/* + * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __MEMCTRLV2_H__ +#define __MEMCTRLV2_H__ + +#include +#include + +/******************************************************************************* + * StreamID to indicate no SMMU translations (requests to be steered on the + * SMMU bypass path) + ******************************************************************************/ +#define MC_STREAM_ID_MAX 0x7F + +/******************************************************************************* + * Stream ID Override Config registers + ******************************************************************************/ +#define MC_STREAMID_OVERRIDE_CFG_PTCR 0x0 +#define MC_STREAMID_OVERRIDE_CFG_AFIR 0x70 +#define MC_STREAMID_OVERRIDE_CFG_HDAR 0xA8 +#define MC_STREAMID_OVERRIDE_CFG_HOST1XDMAR 0xB0 +#define MC_STREAMID_OVERRIDE_CFG_NVENCSRD 0xE0 +#define MC_STREAMID_OVERRIDE_CFG_SATAR 0xF8 +#define MC_STREAMID_OVERRIDE_CFG_MPCORER 0x138 +#define MC_STREAMID_OVERRIDE_CFG_NVENCSWR 0x158 +#define MC_STREAMID_OVERRIDE_CFG_AFIW 0x188 +#define MC_STREAMID_OVERRIDE_CFG_SATAW 0x1E8 +#define MC_STREAMID_OVERRIDE_CFG_MPCOREW 0x1C8 +#define MC_STREAMID_OVERRIDE_CFG_SATAW 0x1E8 +#define MC_STREAMID_OVERRIDE_CFG_HDAW 0x1A8 +#define MC_STREAMID_OVERRIDE_CFG_ISPRA 0x220 +#define MC_STREAMID_OVERRIDE_CFG_ISPWA 0x230 +#define MC_STREAMID_OVERRIDE_CFG_ISPWB 0x238 +#define MC_STREAMID_OVERRIDE_CFG_XUSB_HOSTR 0x250 +#define MC_STREAMID_OVERRIDE_CFG_XUSB_HOSTW 0x258 +#define MC_STREAMID_OVERRIDE_CFG_XUSB_DEVR 0x260 +#define MC_STREAMID_OVERRIDE_CFG_XUSB_DEVW 0x268 +#define MC_STREAMID_OVERRIDE_CFG_TSECSRD 0x2A0 +#define MC_STREAMID_OVERRIDE_CFG_TSECSWR 0x2A8 +#define MC_STREAMID_OVERRIDE_CFG_GPUSRD 0x2C0 +#define MC_STREAMID_OVERRIDE_CFG_GPUSWR 0x2C8 +#define MC_STREAMID_OVERRIDE_CFG_SDMMCRA 0x300 +#define MC_STREAMID_OVERRIDE_CFG_SDMMCRAA 0x308 +#define MC_STREAMID_OVERRIDE_CFG_SDMMCR 0x310 +#define MC_STREAMID_OVERRIDE_CFG_SDMMCRAB 0x318 +#define MC_STREAMID_OVERRIDE_CFG_SDMMCWA 0x320 +#define MC_STREAMID_OVERRIDE_CFG_SDMMCWAA 0x328 +#define MC_STREAMID_OVERRIDE_CFG_SDMMCW 0x330 +#define MC_STREAMID_OVERRIDE_CFG_SDMMCWAB 0x338 +#define MC_STREAMID_OVERRIDE_CFG_VICSRD 0x360 +#define MC_STREAMID_OVERRIDE_CFG_VICSWR 0x368 +#define MC_STREAMID_OVERRIDE_CFG_VIW 0x390 +#define MC_STREAMID_OVERRIDE_CFG_NVDECSRD 0x3C0 +#define MC_STREAMID_OVERRIDE_CFG_NVDECSWR 0x3C8 +#define MC_STREAMID_OVERRIDE_CFG_APER 0x3D0 +#define MC_STREAMID_OVERRIDE_CFG_APEW 0x3D8 +#define MC_STREAMID_OVERRIDE_CFG_NVJPGSRD 0x3F0 +#define MC_STREAMID_OVERRIDE_CFG_NVJPGSWR 0x3F8 +#define MC_STREAMID_OVERRIDE_CFG_SESRD 0x400 +#define MC_STREAMID_OVERRIDE_CFG_SESWR 0x408 +#define MC_STREAMID_OVERRIDE_CFG_ETRR 0x420 +#define MC_STREAMID_OVERRIDE_CFG_ETRW 0x428 +#define MC_STREAMID_OVERRIDE_CFG_TSECSRDB 0x430 +#define MC_STREAMID_OVERRIDE_CFG_TSECSWRB 0x438 +#define MC_STREAMID_OVERRIDE_CFG_GPUSRD2 0x440 +#define MC_STREAMID_OVERRIDE_CFG_GPUSWR2 0x448 +#define MC_STREAMID_OVERRIDE_CFG_AXISR 0x460 +#define MC_STREAMID_OVERRIDE_CFG_AXISW 0x468 +#define MC_STREAMID_OVERRIDE_CFG_EQOSR 0x470 +#define MC_STREAMID_OVERRIDE_CFG_EQOSW 0x478 +#define MC_STREAMID_OVERRIDE_CFG_UFSHCR 0x480 +#define MC_STREAMID_OVERRIDE_CFG_UFSHCW 0x488 +#define MC_STREAMID_OVERRIDE_CFG_NVDISPLAYR 0x490 +#define MC_STREAMID_OVERRIDE_CFG_BPMPR 0x498 +#define MC_STREAMID_OVERRIDE_CFG_BPMPW 0x4A0 +#define MC_STREAMID_OVERRIDE_CFG_BPMPDMAR 0x4A8 +#define MC_STREAMID_OVERRIDE_CFG_BPMPDMAW 0x4B0 +#define MC_STREAMID_OVERRIDE_CFG_AONR 0x4B8 +#define MC_STREAMID_OVERRIDE_CFG_AONW 0x4C0 +#define MC_STREAMID_OVERRIDE_CFG_AONDMAR 0x4C8 +#define MC_STREAMID_OVERRIDE_CFG_AONDMAW 0x4D0 +#define MC_STREAMID_OVERRIDE_CFG_SCER 0x4D8 +#define MC_STREAMID_OVERRIDE_CFG_SCEW 0x4E0 +#define MC_STREAMID_OVERRIDE_CFG_SCEDMAR 0x4E8 +#define MC_STREAMID_OVERRIDE_CFG_SCEDMAW 0x4F0 +#define MC_STREAMID_OVERRIDE_CFG_APEDMAR 0x4F8 +#define MC_STREAMID_OVERRIDE_CFG_APEDMAW 0x500 +#define MC_STREAMID_OVERRIDE_CFG_NVDISPLAYR1 0x508 +#define MC_STREAMID_OVERRIDE_CFG_VICSRD1 0x510 +#define MC_STREAMID_OVERRIDE_CFG_NVDECSRD1 0x518 + +/******************************************************************************* + * Stream ID Security Config registers + ******************************************************************************/ +#define MC_STREAMID_SECURITY_CFG_PTCR 0x4 +#define MC_STREAMID_SECURITY_CFG_AFIR 0x74 +#define MC_STREAMID_SECURITY_CFG_HDAR 0xAC +#define MC_STREAMID_SECURITY_CFG_HOST1XDMAR 0xB4 +#define MC_STREAMID_SECURITY_CFG_NVENCSRD 0xE4 +#define MC_STREAMID_SECURITY_CFG_SATAR 0xFC +#define MC_STREAMID_SECURITY_CFG_HDAW 0x1AC +#define MC_STREAMID_SECURITY_CFG_MPCORER 0x13C +#define MC_STREAMID_SECURITY_CFG_NVENCSWR 0x15C +#define MC_STREAMID_SECURITY_CFG_AFIW 0x18C +#define MC_STREAMID_SECURITY_CFG_MPCOREW 0x1CC +#define MC_STREAMID_SECURITY_CFG_SATAW 0x1EC +#define MC_STREAMID_SECURITY_CFG_ISPRA 0x224 +#define MC_STREAMID_SECURITY_CFG_ISPWA 0x234 +#define MC_STREAMID_SECURITY_CFG_ISPWB 0x23C +#define MC_STREAMID_SECURITY_CFG_XUSB_HOSTR 0x254 +#define MC_STREAMID_SECURITY_CFG_XUSB_HOSTW 0x25C +#define MC_STREAMID_SECURITY_CFG_XUSB_DEVR 0x264 +#define MC_STREAMID_SECURITY_CFG_XUSB_DEVW 0x26C +#define MC_STREAMID_SECURITY_CFG_TSECSRD 0x2A4 +#define MC_STREAMID_SECURITY_CFG_TSECSWR 0x2AC +#define MC_STREAMID_SECURITY_CFG_GPUSRD 0x2C4 +#define MC_STREAMID_SECURITY_CFG_GPUSWR 0x2CC +#define MC_STREAMID_SECURITY_CFG_SDMMCRA 0x304 +#define MC_STREAMID_SECURITY_CFG_SDMMCRAA 0x30C +#define MC_STREAMID_SECURITY_CFG_SDMMCR 0x314 +#define MC_STREAMID_SECURITY_CFG_SDMMCRAB 0x31C +#define MC_STREAMID_SECURITY_CFG_SDMMCWA 0x324 +#define MC_STREAMID_SECURITY_CFG_SDMMCWAA 0x32C +#define MC_STREAMID_SECURITY_CFG_SDMMCW 0x334 +#define MC_STREAMID_SECURITY_CFG_SDMMCWAB 0x33C +#define MC_STREAMID_SECURITY_CFG_VICSRD 0x364 +#define MC_STREAMID_SECURITY_CFG_VICSWR 0x36C +#define MC_STREAMID_SECURITY_CFG_VIW 0x394 +#define MC_STREAMID_SECURITY_CFG_NVDECSRD 0x3C4 +#define MC_STREAMID_SECURITY_CFG_NVDECSWR 0x3CC +#define MC_STREAMID_SECURITY_CFG_APER 0x3D4 +#define MC_STREAMID_SECURITY_CFG_APEW 0x3DC +#define MC_STREAMID_SECURITY_CFG_NVJPGSRD 0x3F4 +#define MC_STREAMID_SECURITY_CFG_NVJPGSWR 0x3FC +#define MC_STREAMID_SECURITY_CFG_SESRD 0x404 +#define MC_STREAMID_SECURITY_CFG_SESWR 0x40C +#define MC_STREAMID_SECURITY_CFG_ETRR 0x424 +#define MC_STREAMID_SECURITY_CFG_ETRW 0x42C +#define MC_STREAMID_SECURITY_CFG_TSECSRDB 0x434 +#define MC_STREAMID_SECURITY_CFG_TSECSWRB 0x43C +#define MC_STREAMID_SECURITY_CFG_GPUSRD2 0x444 +#define MC_STREAMID_SECURITY_CFG_GPUSWR2 0x44C +#define MC_STREAMID_SECURITY_CFG_AXISR 0x464 +#define MC_STREAMID_SECURITY_CFG_AXISW 0x46C +#define MC_STREAMID_SECURITY_CFG_EQOSR 0x474 +#define MC_STREAMID_SECURITY_CFG_EQOSW 0x47C +#define MC_STREAMID_SECURITY_CFG_UFSHCR 0x484 +#define MC_STREAMID_SECURITY_CFG_UFSHCW 0x48C +#define MC_STREAMID_SECURITY_CFG_NVDISPLAYR 0x494 +#define MC_STREAMID_SECURITY_CFG_BPMPR 0x49C +#define MC_STREAMID_SECURITY_CFG_BPMPW 0x4A4 +#define MC_STREAMID_SECURITY_CFG_BPMPDMAR 0x4AC +#define MC_STREAMID_SECURITY_CFG_BPMPDMAW 0x4B4 +#define MC_STREAMID_SECURITY_CFG_AONR 0x4BC +#define MC_STREAMID_SECURITY_CFG_AONW 0x4C4 +#define MC_STREAMID_SECURITY_CFG_AONDMAR 0x4CC +#define MC_STREAMID_SECURITY_CFG_AONDMAW 0x4D4 +#define MC_STREAMID_SECURITY_CFG_SCER 0x4DC +#define MC_STREAMID_SECURITY_CFG_SCEW 0x4E4 +#define MC_STREAMID_SECURITY_CFG_SCEDMAR 0x4EC +#define MC_STREAMID_SECURITY_CFG_SCEDMAW 0x4F4 +#define MC_STREAMID_SECURITY_CFG_APEDMAR 0x4FC +#define MC_STREAMID_SECURITY_CFG_APEDMAW 0x504 +#define MC_STREAMID_SECURITY_CFG_NVDISPLAYR1 0x50C +#define MC_STREAMID_SECURITY_CFG_VICSRD1 0x514 +#define MC_STREAMID_SECURITY_CFG_NVDECSRD1 0x51C + +/******************************************************************************* + * Memory Controller SMMU Bypass config register + ******************************************************************************/ +#define MC_SMMU_BYPASS_CONFIG 0x1820 +#define MC_SMMU_BYPASS_CTRL_MASK 0x3 +#define MC_SMMU_BYPASS_CTRL_SHIFT 0 +#define MC_SMMU_CTRL_TBU_BYPASS_ALL (0 << MC_SMMU_BYPASS_CTRL_SHIFT) +#define MC_SMMU_CTRL_TBU_RSVD (1 << MC_SMMU_BYPASS_CTRL_SHIFT) +#define MC_SMMU_CTRL_TBU_BYPASS_SPL_STREAMID (2 << MC_SMMU_BYPASS_CTRL_SHIFT) +#define MC_SMMU_CTRL_TBU_BYPASS_NONE (3 << MC_SMMU_BYPASS_CTRL_SHIFT) +#define MC_SMMU_BYPASS_CONFIG_WRITE_ACCESS_BIT (1 << 31) +#define MC_SMMU_BYPASS_CONFIG_SETTINGS (MC_SMMU_BYPASS_CONFIG_WRITE_ACCESS_BIT | \ + MC_SMMU_CTRL_TBU_BYPASS_SPL_STREAMID) + +/******************************************************************************* + * Memory Controller transaction override config registers + ******************************************************************************/ +#define MC_TXN_OVERRIDE_CONFIG_HDAR 0x10a8 +#define MC_TXN_OVERRIDE_CONFIG_BPMPW 0x14a0 +#define MC_TXN_OVERRIDE_CONFIG_PTCR 0x1000 +#define MC_TXN_OVERRIDE_CONFIG_NVDISPLAYR 0x1490 +#define MC_TXN_OVERRIDE_CONFIG_EQOSW 0x1478 +#define MC_TXN_OVERRIDE_CONFIG_NVJPGSWR 0x13f8 +#define MC_TXN_OVERRIDE_CONFIG_ISPRA 0x1220 +#define MC_TXN_OVERRIDE_CONFIG_SDMMCWAA 0x1328 +#define MC_TXN_OVERRIDE_CONFIG_VICSRD 0x1360 +#define MC_TXN_OVERRIDE_CONFIG_MPCOREW 0x11c8 +#define MC_TXN_OVERRIDE_CONFIG_GPUSRD 0x12c0 +#define MC_TXN_OVERRIDE_CONFIG_AXISR 0x1460 +#define MC_TXN_OVERRIDE_CONFIG_SCEDMAW 0x14f0 +#define MC_TXN_OVERRIDE_CONFIG_SDMMCW 0x1330 +#define MC_TXN_OVERRIDE_CONFIG_EQOSR 0x1470 +#define MC_TXN_OVERRIDE_CONFIG_APEDMAR 0x14f8 +#define MC_TXN_OVERRIDE_CONFIG_NVENCSRD 0x10e0 +#define MC_TXN_OVERRIDE_CONFIG_SDMMCRAB 0x1318 +#define MC_TXN_OVERRIDE_CONFIG_VICSRD1 0x1510 +#define MC_TXN_OVERRIDE_CONFIG_BPMPDMAR 0x14a8 +#define MC_TXN_OVERRIDE_CONFIG_VIW 0x1390 +#define MC_TXN_OVERRIDE_CONFIG_SDMMCRAA 0x1308 +#define MC_TXN_OVERRIDE_CONFIG_AXISW 0x1468 +#define MC_TXN_OVERRIDE_CONFIG_XUSB_DEVR 0x1260 +#define MC_TXN_OVERRIDE_CONFIG_UFSHCR 0x1480 +#define MC_TXN_OVERRIDE_CONFIG_TSECSWR 0x12a8 +#define MC_TXN_OVERRIDE_CONFIG_GPUSWR 0x12c8 +#define MC_TXN_OVERRIDE_CONFIG_SATAR 0x10f8 +#define MC_TXN_OVERRIDE_CONFIG_XUSB_HOSTW 0x1258 +#define MC_TXN_OVERRIDE_CONFIG_TSECSWRB 0x1438 +#define MC_TXN_OVERRIDE_CONFIG_GPUSRD2 0x1440 +#define MC_TXN_OVERRIDE_CONFIG_SCEDMAR 0x14e8 +#define MC_TXN_OVERRIDE_CONFIG_GPUSWR2 0x1448 +#define MC_TXN_OVERRIDE_CONFIG_AONDMAW 0x14d0 +#define MC_TXN_OVERRIDE_CONFIG_APEDMAW 0x1500 +#define MC_TXN_OVERRIDE_CONFIG_AONW 0x14c0 +#define MC_TXN_OVERRIDE_CONFIG_HOST1XDMAR 0x10b0 +#define MC_TXN_OVERRIDE_CONFIG_ETRR 0x1420 +#define MC_TXN_OVERRIDE_CONFIG_SESWR 0x1408 +#define MC_TXN_OVERRIDE_CONFIG_NVJPGSRD 0x13f0 +#define MC_TXN_OVERRIDE_CONFIG_NVDECSRD 0x13c0 +#define MC_TXN_OVERRIDE_CONFIG_TSECSRDB 0x1430 +#define MC_TXN_OVERRIDE_CONFIG_BPMPDMAW 0x14b0 +#define MC_TXN_OVERRIDE_CONFIG_APER 0x13d0 +#define MC_TXN_OVERRIDE_CONFIG_NVDECSRD1 0x1518 +#define MC_TXN_OVERRIDE_CONFIG_XUSB_HOSTR 0x1250 +#define MC_TXN_OVERRIDE_CONFIG_ISPWA 0x1230 +#define MC_TXN_OVERRIDE_CONFIG_SESRD 0x1400 +#define MC_TXN_OVERRIDE_CONFIG_SCER 0x14d8 +#define MC_TXN_OVERRIDE_CONFIG_AONR 0x14b8 +#define MC_TXN_OVERRIDE_CONFIG_MPCORER 0x1138 +#define MC_TXN_OVERRIDE_CONFIG_SDMMCWA 0x1320 +#define MC_TXN_OVERRIDE_CONFIG_HDAW 0x11a8 +#define MC_TXN_OVERRIDE_CONFIG_NVDECSWR 0x13c8 +#define MC_TXN_OVERRIDE_CONFIG_UFSHCW 0x1488 +#define MC_TXN_OVERRIDE_CONFIG_AONDMAR 0x14c8 +#define MC_TXN_OVERRIDE_CONFIG_SATAW 0x11e8 +#define MC_TXN_OVERRIDE_CONFIG_ETRW 0x1428 +#define MC_TXN_OVERRIDE_CONFIG_VICSWR 0x1368 +#define MC_TXN_OVERRIDE_CONFIG_NVENCSWR 0x1158 +#define MC_TXN_OVERRIDE_CONFIG_AFIR 0x1070 +#define MC_TXN_OVERRIDE_CONFIG_SDMMCWAB 0x1338 +#define MC_TXN_OVERRIDE_CONFIG_SDMMCRA 0x1300 +#define MC_TXN_OVERRIDE_CONFIG_NVDISPLAYR1 0x1508 +#define MC_TXN_OVERRIDE_CONFIG_ISPWB 0x1238 +#define MC_TXN_OVERRIDE_CONFIG_BPMPR 0x1498 +#define MC_TXN_OVERRIDE_CONFIG_APEW 0x13d8 +#define MC_TXN_OVERRIDE_CONFIG_SDMMCR 0x1310 +#define MC_TXN_OVERRIDE_CONFIG_XUSB_DEVW 0x1268 +#define MC_TXN_OVERRIDE_CONFIG_TSECSRD 0x12a0 +#define MC_TXN_OVERRIDE_CONFIG_AFIW 0x1188 +#define MC_TXN_OVERRIDE_CONFIG_SCEW 0x14e0 + +/******************************************************************************* + * 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 0 +#define MC_TXN_OVERRIDE_CGID_TAG_CLIENT_AXI_ID 1 +#define MC_TXN_OVERRIDE_CGID_TAG_ZERO 2 +#define MC_TXN_OVERRIDE_CGID_TAG_ADR 3 +#define MC_TXN_OVERRIDE_CGID_TAG_MASK 3 + +/******************************************************************************* + * Structure to hold the transaction override settings to use to override + * client inputs + ******************************************************************************/ +typedef struct mc_txn_override_cfg { + uint32_t offset; + uint8_t cgid_tag; +} mc_txn_override_cfg_t; + +#define mc_make_txn_override_cfg(off, val) \ + { \ + .offset = MC_TXN_OVERRIDE_CONFIG_ ## off, \ + .cgid_tag = MC_TXN_OVERRIDE_ ## val \ + } + +/******************************************************************************* + * Structure to hold the Stream ID to use to override client inputs + ******************************************************************************/ +typedef struct mc_streamid_override_cfg { + uint32_t offset; + uint8_t stream_id; +} mc_streamid_override_cfg_t; + +/******************************************************************************* + * Structure to hold the Stream ID Security Configuration settings + ******************************************************************************/ +typedef struct mc_streamid_security_cfg { + char *name; + uint32_t offset; + int override_enable; + int override_client_inputs; + int override_client_ns_flag; +} mc_streamid_security_cfg_t; + +#define OVERRIDE_DISABLE 1 +#define OVERRIDE_ENABLE 0 +#define CLIENT_FLAG_SECURE 0 +#define CLIENT_FLAG_NON_SECURE 1 +#define CLIENT_INPUTS_OVERRIDE 1 +#define CLIENT_INPUTS_NO_OVERRIDE 0 + +#define mc_make_sec_cfg(off, ns, ovrrd, access) \ + { \ + .name = # off, \ + .offset = MC_STREAMID_SECURITY_CFG_ ## off, \ + .override_client_ns_flag = CLIENT_FLAG_ ## ns, \ + .override_client_inputs = CLIENT_INPUTS_ ## ovrrd, \ + .override_enable = OVERRIDE_ ## access \ + } + +/******************************************************************************* + * TZDRAM carveout configuration registers + ******************************************************************************/ +#define MC_SECURITY_CFG0_0 0x70 +#define MC_SECURITY_CFG1_0 0x74 +#define MC_SECURITY_CFG3_0 0x9BC + +/******************************************************************************* + * Video Memory carveout configuration registers + ******************************************************************************/ +#define MC_VIDEO_PROTECT_BASE_HI 0x978 +#define MC_VIDEO_PROTECT_BASE_LO 0x648 +#define MC_VIDEO_PROTECT_SIZE_MB 0x64c + +/******************************************************************************* + * TZRAM carveout configuration registers + ******************************************************************************/ +#define MC_TZRAM_BASE 0x1850 +#define MC_TZRAM_END 0x1854 +#define MC_TZRAM_HI_ADDR_BITS 0x1588 + #define TZRAM_ADDR_HI_BITS_MASK 0x3 + #define TZRAM_END_HI_BITS_SHIFT 8 +#define MC_TZRAM_REG_CTRL 0x185c + #define DISABLE_TZRAM_ACCESS 1 + +static inline uint32_t tegra_mc_read_32(uint32_t off) +{ + return mmio_read_32(TEGRA_MC_BASE + off); +} + +static inline void tegra_mc_write_32(uint32_t off, uint32_t val) +{ + mmio_write_32(TEGRA_MC_BASE + off, val); +} + +static inline uint32_t tegra_mc_streamid_read_32(uint32_t off) +{ + return mmio_read_32(TEGRA_MC_STREAMID_BASE + off); +} + +static inline void tegra_mc_streamid_write_32(uint32_t off, uint32_t val) +{ + mmio_write_32(TEGRA_MC_STREAMID_BASE + off, val); +} + +#endif /* __MEMCTRLV2_H__ */ diff --git a/plat/nvidia/tegra/include/drivers/smmu.h b/plat/nvidia/tegra/include/drivers/smmu.h new file mode 100644 index 000000000..bb08a559f --- /dev/null +++ b/plat/nvidia/tegra/include/drivers/smmu.h @@ -0,0 +1,632 @@ +/* + * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __SMMU_H +#define __SMMU_H + +#include +#include + +/******************************************************************************* + * SMMU Register constants + ******************************************************************************/ +#define SMMU_CBn_SCTLR (0x0) +#define SMMU_CBn_SCTLR_STAGE2 (0x0) +#define SMMU_CBn_ACTLR (0x4) +#define SMMU_CBn_RESUME (0x8) +#define SMMU_CBn_TCR2 (0x10) +#define SMMU_CBn_TTBR0_LO (0x20) +#define SMMU_CBn_TTBR0_HI (0x24) +#define SMMU_CBn_TTBR1_LO (0x28) +#define SMMU_CBn_TTBR1_HI (0x2c) +#define SMMU_CBn_TCR_LPAE (0x30) +#define SMMU_CBn_TCR (0x30) +#define SMMU_CBn_TCR_EAE_1 (0x30) +#define SMMU_CBn_TCR (0x30) +#define SMMU_CBn_CONTEXTIDR (0x34) +#define SMMU_CBn_CONTEXTIDR_EAE_1 (0x34) +#define SMMU_CBn_PRRR_MAIR0 (0x38) +#define SMMU_CBn_NMRR_MAIR1 (0x3c) +#define SMMU_CBn_SMMU_CBn_PAR (0x50) +#define SMMU_CBn_SMMU_CBn_PAR0 (0x50) +#define SMMU_CBn_SMMU_CBn_PAR1 (0x54) +/* SMMU_CBn_SMMU_CBn_PAR0_Fault (0x50) */ +/* SMMU_CBn_SMMU_CBn_PAR0_Fault (0x54) */ +#define SMMU_CBn_FSR (0x58) +#define SMMU_CBn_FSRRESTORE (0x5c) +#define SMMU_CBn_FAR_LO (0x60) +#define SMMU_CBn_FAR_HI (0x64) +#define SMMU_CBn_FSYNR0 (0x68) +#define SMMU_CBn_IPAFAR_LO (0x70) +#define SMMU_CBn_IPAFAR_HI (0x74) +#define SMMU_CBn_TLBIVA_LO (0x600) +#define SMMU_CBn_TLBIVA_HI (0x604) +#define SMMU_CBn_TLBIVA_AARCH_32 (0x600) +#define SMMU_CBn_TLBIVAA_LO (0x608) +#define SMMU_CBn_TLBIVAA_HI (0x60c) +#define SMMU_CBn_TLBIVAA_AARCH_32 (0x608) +#define SMMU_CBn_TLBIASID (0x610) +#define SMMU_CBn_TLBIALL (0x618) +#define SMMU_CBn_TLBIVAL_LO (0x620) +#define SMMU_CBn_TLBIVAL_HI (0x624) +#define SMMU_CBn_TLBIVAL_AARCH_32 (0x618) +#define SMMU_CBn_TLBIVAAL_LO (0x628) +#define SMMU_CBn_TLBIVAAL_HI (0x62c) +#define SMMU_CBn_TLBIVAAL_AARCH_32 (0x628) +#define SMMU_CBn_TLBIIPAS2_LO (0x630) +#define SMMU_CBn_TLBIIPAS2_HI (0x634) +#define SMMU_CBn_TLBIIPAS2L_LO (0x638) +#define SMMU_CBn_TLBIIPAS2L_HI (0x63c) +#define SMMU_CBn_TLBSYNC (0x7f0) +#define SMMU_CBn_TLBSTATUS (0x7f4) +#define SMMU_CBn_ATSR (0x800) +#define SMMU_CBn_PMEVCNTR0 (0xe00) +#define SMMU_CBn_PMEVCNTR1 (0xe04) +#define SMMU_CBn_PMEVCNTR2 (0xe08) +#define SMMU_CBn_PMEVCNTR3 (0xe0c) +#define SMMU_CBn_PMEVTYPER0 (0xe80) +#define SMMU_CBn_PMEVTYPER1 (0xe84) +#define SMMU_CBn_PMEVTYPER2 (0xe88) +#define SMMU_CBn_PMEVTYPER3 (0xe8c) +#define SMMU_CBn_PMCFGR (0xf00) +#define SMMU_CBn_PMCR (0xf04) +#define SMMU_CBn_PMCEID (0xf20) +#define SMMU_CBn_PMCNTENSE (0xf40) +#define SMMU_CBn_PMCNTENCLR (0xf44) +#define SMMU_CBn_PMCNTENSET (0xf48) +#define SMMU_CBn_PMINTENCLR (0xf4c) +#define SMMU_CBn_PMOVSCLR (0xf50) +#define SMMU_CBn_PMOVSSET (0xf58) +#define SMMU_CBn_PMAUTHSTATUS (0xfb8) +#define SMMU_GNSR0_CR0 (0x0) +#define SMMU_GNSR0_CR2 (0x8) +#define SMMU_GNSR0_ACR (0x10) +#define SMMU_GNSR0_IDR0 (0x20) +#define SMMU_GNSR0_IDR1 (0x24) +#define SMMU_GNSR0_IDR2 (0x28) +#define SMMU_GNSR0_IDR7 (0x3c) +#define SMMU_GNSR0_GFAR_LO (0x40) +#define SMMU_GNSR0_GFAR_HI (0x44) +#define SMMU_GNSR0_GFSR (0x48) +#define SMMU_GNSR0_GFSRRESTORE (0x4c) +#define SMMU_GNSR0_GFSYNR0 (0x50) +#define SMMU_GNSR0_GFSYNR1 (0x54) +#define SMMU_GNSR0_GFSYNR1_v2 (0x54) +#define SMMU_GNSR0_TLBIVMID (0x64) +#define SMMU_GNSR0_TLBIALLNSNH (0x68) +#define SMMU_GNSR0_TLBIALLH (0x6c) +#define SMMU_GNSR0_TLBGSYNC (0x70) +#define SMMU_GNSR0_TLBGSTATUS (0x74) +#define SMMU_GNSR0_TLBIVAH_LO (0x78) +#define SMMU_GNSR0_TLBIVALH64_LO (0xb0) +#define SMMU_GNSR0_TLBIVALH64_HI (0xb4) +#define SMMU_GNSR0_TLBIVMIDS1 (0xb8) +#define SMMU_GNSR0_TLBIVAH64_LO (0xc0) +#define SMMU_GNSR0_TLBIVAH64_HI (0xc4) +#define SMMU_GNSR0_SMR0 (0x800) +#define SMMU_GNSR0_SMRn (0x800) +#define SMMU_GNSR0_SMR1 (0x804) +#define SMMU_GNSR0_SMR2 (0x808) +#define SMMU_GNSR0_SMR3 (0x80c) +#define SMMU_GNSR0_SMR4 (0x810) +#define SMMU_GNSR0_SMR5 (0x814) +#define SMMU_GNSR0_SMR6 (0x818) +#define SMMU_GNSR0_SMR7 (0x81c) +#define SMMU_GNSR0_SMR8 (0x820) +#define SMMU_GNSR0_SMR9 (0x824) +#define SMMU_GNSR0_SMR10 (0x828) +#define SMMU_GNSR0_SMR11 (0x82c) +#define SMMU_GNSR0_SMR12 (0x830) +#define SMMU_GNSR0_SMR13 (0x834) +#define SMMU_GNSR0_SMR14 (0x838) +#define SMMU_GNSR0_SMR15 (0x83c) +#define SMMU_GNSR0_SMR16 (0x840) +#define SMMU_GNSR0_SMR17 (0x844) +#define SMMU_GNSR0_SMR18 (0x848) +#define SMMU_GNSR0_SMR19 (0x84c) +#define SMMU_GNSR0_SMR20 (0x850) +#define SMMU_GNSR0_SMR21 (0x854) +#define SMMU_GNSR0_SMR22 (0x858) +#define SMMU_GNSR0_SMR23 (0x85c) +#define SMMU_GNSR0_SMR24 (0x860) +#define SMMU_GNSR0_SMR25 (0x864) +#define SMMU_GNSR0_SMR26 (0x868) +#define SMMU_GNSR0_SMR27 (0x86c) +#define SMMU_GNSR0_SMR28 (0x870) +#define SMMU_GNSR0_SMR29 (0x874) +#define SMMU_GNSR0_SMR30 (0x878) +#define SMMU_GNSR0_SMR31 (0x87c) +#define SMMU_GNSR0_SMR32 (0x880) +#define SMMU_GNSR0_SMR33 (0x884) +#define SMMU_GNSR0_SMR34 (0x888) +#define SMMU_GNSR0_SMR35 (0x88c) +#define SMMU_GNSR0_SMR36 (0x890) +#define SMMU_GNSR0_SMR37 (0x894) +#define SMMU_GNSR0_SMR38 (0x898) +#define SMMU_GNSR0_SMR39 (0x89c) +#define SMMU_GNSR0_SMR40 (0x8a0) +#define SMMU_GNSR0_SMR41 (0x8a4) +#define SMMU_GNSR0_SMR42 (0x8a8) +#define SMMU_GNSR0_SMR43 (0x8ac) +#define SMMU_GNSR0_SMR44 (0x8b0) +#define SMMU_GNSR0_SMR45 (0x8b4) +#define SMMU_GNSR0_SMR46 (0x8b8) +#define SMMU_GNSR0_SMR47 (0x8bc) +#define SMMU_GNSR0_SMR48 (0x8c0) +#define SMMU_GNSR0_SMR49 (0x8c4) +#define SMMU_GNSR0_SMR50 (0x8c8) +#define SMMU_GNSR0_SMR51 (0x8cc) +#define SMMU_GNSR0_SMR52 (0x8d0) +#define SMMU_GNSR0_SMR53 (0x8d4) +#define SMMU_GNSR0_SMR54 (0x8d8) +#define SMMU_GNSR0_SMR55 (0x8dc) +#define SMMU_GNSR0_SMR56 (0x8e0) +#define SMMU_GNSR0_SMR57 (0x8e4) +#define SMMU_GNSR0_SMR58 (0x8e8) +#define SMMU_GNSR0_SMR59 (0x8ec) +#define SMMU_GNSR0_SMR60 (0x8f0) +#define SMMU_GNSR0_SMR61 (0x8f4) +#define SMMU_GNSR0_SMR62 (0x8f8) +#define SMMU_GNSR0_SMR63 (0x8fc) +#define SMMU_GNSR0_SMR64 (0x900) +#define SMMU_GNSR0_SMR65 (0x904) +#define SMMU_GNSR0_SMR66 (0x908) +#define SMMU_GNSR0_SMR67 (0x90c) +#define SMMU_GNSR0_SMR68 (0x910) +#define SMMU_GNSR0_SMR69 (0x914) +#define SMMU_GNSR0_SMR70 (0x918) +#define SMMU_GNSR0_SMR71 (0x91c) +#define SMMU_GNSR0_SMR72 (0x920) +#define SMMU_GNSR0_SMR73 (0x924) +#define SMMU_GNSR0_SMR74 (0x928) +#define SMMU_GNSR0_SMR75 (0x92c) +#define SMMU_GNSR0_SMR76 (0x930) +#define SMMU_GNSR0_SMR77 (0x934) +#define SMMU_GNSR0_SMR78 (0x938) +#define SMMU_GNSR0_SMR79 (0x93c) +#define SMMU_GNSR0_SMR80 (0x940) +#define SMMU_GNSR0_SMR81 (0x944) +#define SMMU_GNSR0_SMR82 (0x948) +#define SMMU_GNSR0_SMR83 (0x94c) +#define SMMU_GNSR0_SMR84 (0x950) +#define SMMU_GNSR0_SMR85 (0x954) +#define SMMU_GNSR0_SMR86 (0x958) +#define SMMU_GNSR0_SMR87 (0x95c) +#define SMMU_GNSR0_SMR88 (0x960) +#define SMMU_GNSR0_SMR89 (0x964) +#define SMMU_GNSR0_SMR90 (0x968) +#define SMMU_GNSR0_SMR91 (0x96c) +#define SMMU_GNSR0_SMR92 (0x970) +#define SMMU_GNSR0_SMR93 (0x974) +#define SMMU_GNSR0_SMR94 (0x978) +#define SMMU_GNSR0_SMR95 (0x97c) +#define SMMU_GNSR0_SMR96 (0x980) +#define SMMU_GNSR0_SMR97 (0x984) +#define SMMU_GNSR0_SMR98 (0x988) +#define SMMU_GNSR0_SMR99 (0x98c) +#define SMMU_GNSR0_SMR100 (0x990) +#define SMMU_GNSR0_SMR101 (0x994) +#define SMMU_GNSR0_SMR102 (0x998) +#define SMMU_GNSR0_SMR103 (0x99c) +#define SMMU_GNSR0_SMR104 (0x9a0) +#define SMMU_GNSR0_SMR105 (0x9a4) +#define SMMU_GNSR0_SMR106 (0x9a8) +#define SMMU_GNSR0_SMR107 (0x9ac) +#define SMMU_GNSR0_SMR108 (0x9b0) +#define SMMU_GNSR0_SMR109 (0x9b4) +#define SMMU_GNSR0_SMR110 (0x9b8) +#define SMMU_GNSR0_SMR111 (0x9bc) +#define SMMU_GNSR0_SMR112 (0x9c0) +#define SMMU_GNSR0_SMR113 (0x9c4) +#define SMMU_GNSR0_SMR114 (0x9c8) +#define SMMU_GNSR0_SMR115 (0x9cc) +#define SMMU_GNSR0_SMR116 (0x9d0) +#define SMMU_GNSR0_SMR117 (0x9d4) +#define SMMU_GNSR0_SMR118 (0x9d8) +#define SMMU_GNSR0_SMR119 (0x9dc) +#define SMMU_GNSR0_SMR120 (0x9e0) +#define SMMU_GNSR0_SMR121 (0x9e4) +#define SMMU_GNSR0_SMR122 (0x9e8) +#define SMMU_GNSR0_SMR123 (0x9ec) +#define SMMU_GNSR0_SMR124 (0x9f0) +#define SMMU_GNSR0_SMR125 (0x9f4) +#define SMMU_GNSR0_SMR126 (0x9f8) +#define SMMU_GNSR0_SMR127 (0x9fc) +#define SMMU_GNSR0_S2CR0 (0xc00) +#define SMMU_GNSR0_S2CRn (0xc00) +#define SMMU_GNSR0_S2CRn (0xc00) +#define SMMU_GNSR0_S2CR1 (0xc04) +#define SMMU_GNSR0_S2CR2 (0xc08) +#define SMMU_GNSR0_S2CR3 (0xc0c) +#define SMMU_GNSR0_S2CR4 (0xc10) +#define SMMU_GNSR0_S2CR5 (0xc14) +#define SMMU_GNSR0_S2CR6 (0xc18) +#define SMMU_GNSR0_S2CR7 (0xc1c) +#define SMMU_GNSR0_S2CR8 (0xc20) +#define SMMU_GNSR0_S2CR9 (0xc24) +#define SMMU_GNSR0_S2CR10 (0xc28) +#define SMMU_GNSR0_S2CR11 (0xc2c) +#define SMMU_GNSR0_S2CR12 (0xc30) +#define SMMU_GNSR0_S2CR13 (0xc34) +#define SMMU_GNSR0_S2CR14 (0xc38) +#define SMMU_GNSR0_S2CR15 (0xc3c) +#define SMMU_GNSR0_S2CR16 (0xc40) +#define SMMU_GNSR0_S2CR17 (0xc44) +#define SMMU_GNSR0_S2CR18 (0xc48) +#define SMMU_GNSR0_S2CR19 (0xc4c) +#define SMMU_GNSR0_S2CR20 (0xc50) +#define SMMU_GNSR0_S2CR21 (0xc54) +#define SMMU_GNSR0_S2CR22 (0xc58) +#define SMMU_GNSR0_S2CR23 (0xc5c) +#define SMMU_GNSR0_S2CR24 (0xc60) +#define SMMU_GNSR0_S2CR25 (0xc64) +#define SMMU_GNSR0_S2CR26 (0xc68) +#define SMMU_GNSR0_S2CR27 (0xc6c) +#define SMMU_GNSR0_S2CR28 (0xc70) +#define SMMU_GNSR0_S2CR29 (0xc74) +#define SMMU_GNSR0_S2CR30 (0xc78) +#define SMMU_GNSR0_S2CR31 (0xc7c) +#define SMMU_GNSR0_S2CR32 (0xc80) +#define SMMU_GNSR0_S2CR33 (0xc84) +#define SMMU_GNSR0_S2CR34 (0xc88) +#define SMMU_GNSR0_S2CR35 (0xc8c) +#define SMMU_GNSR0_S2CR36 (0xc90) +#define SMMU_GNSR0_S2CR37 (0xc94) +#define SMMU_GNSR0_S2CR38 (0xc98) +#define SMMU_GNSR0_S2CR39 (0xc9c) +#define SMMU_GNSR0_S2CR40 (0xca0) +#define SMMU_GNSR0_S2CR41 (0xca4) +#define SMMU_GNSR0_S2CR42 (0xca8) +#define SMMU_GNSR0_S2CR43 (0xcac) +#define SMMU_GNSR0_S2CR44 (0xcb0) +#define SMMU_GNSR0_S2CR45 (0xcb4) +#define SMMU_GNSR0_S2CR46 (0xcb8) +#define SMMU_GNSR0_S2CR47 (0xcbc) +#define SMMU_GNSR0_S2CR48 (0xcc0) +#define SMMU_GNSR0_S2CR49 (0xcc4) +#define SMMU_GNSR0_S2CR50 (0xcc8) +#define SMMU_GNSR0_S2CR51 (0xccc) +#define SMMU_GNSR0_S2CR52 (0xcd0) +#define SMMU_GNSR0_S2CR53 (0xcd4) +#define SMMU_GNSR0_S2CR54 (0xcd8) +#define SMMU_GNSR0_S2CR55 (0xcdc) +#define SMMU_GNSR0_S2CR56 (0xce0) +#define SMMU_GNSR0_S2CR57 (0xce4) +#define SMMU_GNSR0_S2CR58 (0xce8) +#define SMMU_GNSR0_S2CR59 (0xcec) +#define SMMU_GNSR0_S2CR60 (0xcf0) +#define SMMU_GNSR0_S2CR61 (0xcf4) +#define SMMU_GNSR0_S2CR62 (0xcf8) +#define SMMU_GNSR0_S2CR63 (0xcfc) +#define SMMU_GNSR0_S2CR64 (0xd00) +#define SMMU_GNSR0_S2CR65 (0xd04) +#define SMMU_GNSR0_S2CR66 (0xd08) +#define SMMU_GNSR0_S2CR67 (0xd0c) +#define SMMU_GNSR0_S2CR68 (0xd10) +#define SMMU_GNSR0_S2CR69 (0xd14) +#define SMMU_GNSR0_S2CR70 (0xd18) +#define SMMU_GNSR0_S2CR71 (0xd1c) +#define SMMU_GNSR0_S2CR72 (0xd20) +#define SMMU_GNSR0_S2CR73 (0xd24) +#define SMMU_GNSR0_S2CR74 (0xd28) +#define SMMU_GNSR0_S2CR75 (0xd2c) +#define SMMU_GNSR0_S2CR76 (0xd30) +#define SMMU_GNSR0_S2CR77 (0xd34) +#define SMMU_GNSR0_S2CR78 (0xd38) +#define SMMU_GNSR0_S2CR79 (0xd3c) +#define SMMU_GNSR0_S2CR80 (0xd40) +#define SMMU_GNSR0_S2CR81 (0xd44) +#define SMMU_GNSR0_S2CR82 (0xd48) +#define SMMU_GNSR0_S2CR83 (0xd4c) +#define SMMU_GNSR0_S2CR84 (0xd50) +#define SMMU_GNSR0_S2CR85 (0xd54) +#define SMMU_GNSR0_S2CR86 (0xd58) +#define SMMU_GNSR0_S2CR87 (0xd5c) +#define SMMU_GNSR0_S2CR88 (0xd60) +#define SMMU_GNSR0_S2CR89 (0xd64) +#define SMMU_GNSR0_S2CR90 (0xd68) +#define SMMU_GNSR0_S2CR91 (0xd6c) +#define SMMU_GNSR0_S2CR92 (0xd70) +#define SMMU_GNSR0_S2CR93 (0xd74) +#define SMMU_GNSR0_S2CR94 (0xd78) +#define SMMU_GNSR0_S2CR95 (0xd7c) +#define SMMU_GNSR0_S2CR96 (0xd80) +#define SMMU_GNSR0_S2CR97 (0xd84) +#define SMMU_GNSR0_S2CR98 (0xd88) +#define SMMU_GNSR0_S2CR99 (0xd8c) +#define SMMU_GNSR0_S2CR100 (0xd90) +#define SMMU_GNSR0_S2CR101 (0xd94) +#define SMMU_GNSR0_S2CR102 (0xd98) +#define SMMU_GNSR0_S2CR103 (0xd9c) +#define SMMU_GNSR0_S2CR104 (0xda0) +#define SMMU_GNSR0_S2CR105 (0xda4) +#define SMMU_GNSR0_S2CR106 (0xda8) +#define SMMU_GNSR0_S2CR107 (0xdac) +#define SMMU_GNSR0_S2CR108 (0xdb0) +#define SMMU_GNSR0_S2CR109 (0xdb4) +#define SMMU_GNSR0_S2CR110 (0xdb8) +#define SMMU_GNSR0_S2CR111 (0xdbc) +#define SMMU_GNSR0_S2CR112 (0xdc0) +#define SMMU_GNSR0_S2CR113 (0xdc4) +#define SMMU_GNSR0_S2CR114 (0xdc8) +#define SMMU_GNSR0_S2CR115 (0xdcc) +#define SMMU_GNSR0_S2CR116 (0xdd0) +#define SMMU_GNSR0_S2CR117 (0xdd4) +#define SMMU_GNSR0_S2CR118 (0xdd8) +#define SMMU_GNSR0_S2CR119 (0xddc) +#define SMMU_GNSR0_S2CR120 (0xde0) +#define SMMU_GNSR0_S2CR121 (0xde4) +#define SMMU_GNSR0_S2CR122 (0xde8) +#define SMMU_GNSR0_S2CR123 (0xdec) +#define SMMU_GNSR0_S2CR124 (0xdf0) +#define SMMU_GNSR0_S2CR125 (0xdf4) +#define SMMU_GNSR0_S2CR126 (0xdf8) +#define SMMU_GNSR0_S2CR127 (0xdfc) +#define SMMU_GNSR0_PIDR0 (0xfe0) +#define SMMU_GNSR0_PIDR1 (0xfe4) +#define SMMU_GNSR0_PIDR2 (0xfe8) +#define SMMU_GNSR0_PIDR3 (0xfec) +#define SMMU_GNSR0_PIDR4 (0xfd0) +#define SMMU_GNSR0_PIDR5 (0xfd4) +#define SMMU_GNSR0_PIDR6 (0xfd8) +#define SMMU_GNSR0_PIDR7 (0xfdc) +#define SMMU_GNSR0_CIDR0 (0xff0) +#define SMMU_GNSR0_CIDR1 (0xff4) +#define SMMU_GNSR0_CIDR2 (0xff8) +#define SMMU_GNSR0_CIDR3 (0xffc) +#define SMMU_GNSR1_CBAR0 (0x0) +#define SMMU_GNSR1_CBARn (0x0) +#define SMMU_GNSR1_CBFRSYNRA0 (0x400) +#define SMMU_GNSR1_CBA2R0 (0x800) +#define SMMU_GNSR1_CBAR1 (0x4) +#define SMMU_GNSR1_CBFRSYNRA1 (0x404) +#define SMMU_GNSR1_CBA2R1 (0x804) +#define SMMU_GNSR1_CBAR2 (0x8) +#define SMMU_GNSR1_CBFRSYNRA2 (0x408) +#define SMMU_GNSR1_CBA2R2 (0x808) +#define SMMU_GNSR1_CBAR3 (0xc) +#define SMMU_GNSR1_CBFRSYNRA3 (0x40c) +#define SMMU_GNSR1_CBA2R3 (0x80c) +#define SMMU_GNSR1_CBAR4 (0x10) +#define SMMU_GNSR1_CBFRSYNRA4 (0x410) +#define SMMU_GNSR1_CBA2R4 (0x810) +#define SMMU_GNSR1_CBAR5 (0x14) +#define SMMU_GNSR1_CBFRSYNRA5 (0x414) +#define SMMU_GNSR1_CBA2R5 (0x814) +#define SMMU_GNSR1_CBAR6 (0x18) +#define SMMU_GNSR1_CBFRSYNRA6 (0x418) +#define SMMU_GNSR1_CBA2R6 (0x818) +#define SMMU_GNSR1_CBAR7 (0x1c) +#define SMMU_GNSR1_CBFRSYNRA7 (0x41c) +#define SMMU_GNSR1_CBA2R7 (0x81c) +#define SMMU_GNSR1_CBAR8 (0x20) +#define SMMU_GNSR1_CBFRSYNRA8 (0x420) +#define SMMU_GNSR1_CBA2R8 (0x820) +#define SMMU_GNSR1_CBAR9 (0x24) +#define SMMU_GNSR1_CBFRSYNRA9 (0x424) +#define SMMU_GNSR1_CBA2R9 (0x824) +#define SMMU_GNSR1_CBAR10 (0x28) +#define SMMU_GNSR1_CBFRSYNRA10 (0x428) +#define SMMU_GNSR1_CBA2R10 (0x828) +#define SMMU_GNSR1_CBAR11 (0x2c) +#define SMMU_GNSR1_CBFRSYNRA11 (0x42c) +#define SMMU_GNSR1_CBA2R11 (0x82c) +#define SMMU_GNSR1_CBAR12 (0x30) +#define SMMU_GNSR1_CBFRSYNRA12 (0x430) +#define SMMU_GNSR1_CBA2R12 (0x830) +#define SMMU_GNSR1_CBAR13 (0x34) +#define SMMU_GNSR1_CBFRSYNRA13 (0x434) +#define SMMU_GNSR1_CBA2R13 (0x834) +#define SMMU_GNSR1_CBAR14 (0x38) +#define SMMU_GNSR1_CBFRSYNRA14 (0x438) +#define SMMU_GNSR1_CBA2R14 (0x838) +#define SMMU_GNSR1_CBAR15 (0x3c) +#define SMMU_GNSR1_CBFRSYNRA15 (0x43c) +#define SMMU_GNSR1_CBA2R15 (0x83c) +#define SMMU_GNSR1_CBAR16 (0x40) +#define SMMU_GNSR1_CBFRSYNRA16 (0x440) +#define SMMU_GNSR1_CBA2R16 (0x840) +#define SMMU_GNSR1_CBAR17 (0x44) +#define SMMU_GNSR1_CBFRSYNRA17 (0x444) +#define SMMU_GNSR1_CBA2R17 (0x844) +#define SMMU_GNSR1_CBAR18 (0x48) +#define SMMU_GNSR1_CBFRSYNRA18 (0x448) +#define SMMU_GNSR1_CBA2R18 (0x848) +#define SMMU_GNSR1_CBAR19 (0x4c) +#define SMMU_GNSR1_CBFRSYNRA19 (0x44c) +#define SMMU_GNSR1_CBA2R19 (0x84c) +#define SMMU_GNSR1_CBAR20 (0x50) +#define SMMU_GNSR1_CBFRSYNRA20 (0x450) +#define SMMU_GNSR1_CBA2R20 (0x850) +#define SMMU_GNSR1_CBAR21 (0x54) +#define SMMU_GNSR1_CBFRSYNRA21 (0x454) +#define SMMU_GNSR1_CBA2R21 (0x854) +#define SMMU_GNSR1_CBAR22 (0x58) +#define SMMU_GNSR1_CBFRSYNRA22 (0x458) +#define SMMU_GNSR1_CBA2R22 (0x858) +#define SMMU_GNSR1_CBAR23 (0x5c) +#define SMMU_GNSR1_CBFRSYNRA23 (0x45c) +#define SMMU_GNSR1_CBA2R23 (0x85c) +#define SMMU_GNSR1_CBAR24 (0x60) +#define SMMU_GNSR1_CBFRSYNRA24 (0x460) +#define SMMU_GNSR1_CBA2R24 (0x860) +#define SMMU_GNSR1_CBAR25 (0x64) +#define SMMU_GNSR1_CBFRSYNRA25 (0x464) +#define SMMU_GNSR1_CBA2R25 (0x864) +#define SMMU_GNSR1_CBAR26 (0x68) +#define SMMU_GNSR1_CBFRSYNRA26 (0x468) +#define SMMU_GNSR1_CBA2R26 (0x868) +#define SMMU_GNSR1_CBAR27 (0x6c) +#define SMMU_GNSR1_CBFRSYNRA27 (0x46c) +#define SMMU_GNSR1_CBA2R27 (0x86c) +#define SMMU_GNSR1_CBAR28 (0x70) +#define SMMU_GNSR1_CBFRSYNRA28 (0x470) +#define SMMU_GNSR1_CBA2R28 (0x870) +#define SMMU_GNSR1_CBAR29 (0x74) +#define SMMU_GNSR1_CBFRSYNRA29 (0x474) +#define SMMU_GNSR1_CBA2R29 (0x874) +#define SMMU_GNSR1_CBAR30 (0x78) +#define SMMU_GNSR1_CBFRSYNRA30 (0x478) +#define SMMU_GNSR1_CBA2R30 (0x878) +#define SMMU_GNSR1_CBAR31 (0x7c) +#define SMMU_GNSR1_CBFRSYNRA31 (0x47c) +#define SMMU_GNSR1_CBA2R31 (0x87c) +#define SMMU_GNSR1_CBAR32 (0x80) +#define SMMU_GNSR1_CBFRSYNRA32 (0x480) +#define SMMU_GNSR1_CBA2R32 (0x880) +#define SMMU_GNSR1_CBAR33 (0x84) +#define SMMU_GNSR1_CBFRSYNRA33 (0x484) +#define SMMU_GNSR1_CBA2R33 (0x884) +#define SMMU_GNSR1_CBAR34 (0x88) +#define SMMU_GNSR1_CBFRSYNRA34 (0x488) +#define SMMU_GNSR1_CBA2R34 (0x888) +#define SMMU_GNSR1_CBAR35 (0x8c) +#define SMMU_GNSR1_CBFRSYNRA35 (0x48c) +#define SMMU_GNSR1_CBA2R35 (0x88c) +#define SMMU_GNSR1_CBAR36 (0x90) +#define SMMU_GNSR1_CBFRSYNRA36 (0x490) +#define SMMU_GNSR1_CBA2R36 (0x890) +#define SMMU_GNSR1_CBAR37 (0x94) +#define SMMU_GNSR1_CBFRSYNRA37 (0x494) +#define SMMU_GNSR1_CBA2R37 (0x894) +#define SMMU_GNSR1_CBAR38 (0x98) +#define SMMU_GNSR1_CBFRSYNRA38 (0x498) +#define SMMU_GNSR1_CBA2R38 (0x898) +#define SMMU_GNSR1_CBAR39 (0x9c) +#define SMMU_GNSR1_CBFRSYNRA39 (0x49c) +#define SMMU_GNSR1_CBA2R39 (0x89c) +#define SMMU_GNSR1_CBAR40 (0xa0) +#define SMMU_GNSR1_CBFRSYNRA40 (0x4a0) +#define SMMU_GNSR1_CBA2R40 (0x8a0) +#define SMMU_GNSR1_CBAR41 (0xa4) +#define SMMU_GNSR1_CBFRSYNRA41 (0x4a4) +#define SMMU_GNSR1_CBA2R41 (0x8a4) +#define SMMU_GNSR1_CBAR42 (0xa8) +#define SMMU_GNSR1_CBFRSYNRA42 (0x4a8) +#define SMMU_GNSR1_CBA2R42 (0x8a8) +#define SMMU_GNSR1_CBAR43 (0xac) +#define SMMU_GNSR1_CBFRSYNRA43 (0x4ac) +#define SMMU_GNSR1_CBA2R43 (0x8ac) +#define SMMU_GNSR1_CBAR44 (0xb0) +#define SMMU_GNSR1_CBFRSYNRA44 (0x4b0) +#define SMMU_GNSR1_CBA2R44 (0x8b0) +#define SMMU_GNSR1_CBAR45 (0xb4) +#define SMMU_GNSR1_CBFRSYNRA45 (0x4b4) +#define SMMU_GNSR1_CBA2R45 (0x8b4) +#define SMMU_GNSR1_CBAR46 (0xb8) +#define SMMU_GNSR1_CBFRSYNRA46 (0x4b8) +#define SMMU_GNSR1_CBA2R46 (0x8b8) +#define SMMU_GNSR1_CBAR47 (0xbc) +#define SMMU_GNSR1_CBFRSYNRA47 (0x4bc) +#define SMMU_GNSR1_CBA2R47 (0x8bc) +#define SMMU_GNSR1_CBAR48 (0xc0) +#define SMMU_GNSR1_CBFRSYNRA48 (0x4c0) +#define SMMU_GNSR1_CBA2R48 (0x8c0) +#define SMMU_GNSR1_CBAR49 (0xc4) +#define SMMU_GNSR1_CBFRSYNRA49 (0x4c4) +#define SMMU_GNSR1_CBA2R49 (0x8c4) +#define SMMU_GNSR1_CBAR50 (0xc8) +#define SMMU_GNSR1_CBFRSYNRA50 (0x4c8) +#define SMMU_GNSR1_CBA2R50 (0x8c8) +#define SMMU_GNSR1_CBAR51 (0xcc) +#define SMMU_GNSR1_CBFRSYNRA51 (0x4cc) +#define SMMU_GNSR1_CBA2R51 (0x8cc) +#define SMMU_GNSR1_CBAR52 (0xd0) +#define SMMU_GNSR1_CBFRSYNRA52 (0x4d0) +#define SMMU_GNSR1_CBA2R52 (0x8d0) +#define SMMU_GNSR1_CBAR53 (0xd4) +#define SMMU_GNSR1_CBFRSYNRA53 (0x4d4) +#define SMMU_GNSR1_CBA2R53 (0x8d4) +#define SMMU_GNSR1_CBAR54 (0xd8) +#define SMMU_GNSR1_CBFRSYNRA54 (0x4d8) +#define SMMU_GNSR1_CBA2R54 (0x8d8) +#define SMMU_GNSR1_CBAR55 (0xdc) +#define SMMU_GNSR1_CBFRSYNRA55 (0x4dc) +#define SMMU_GNSR1_CBA2R55 (0x8dc) +#define SMMU_GNSR1_CBAR56 (0xe0) +#define SMMU_GNSR1_CBFRSYNRA56 (0x4e0) +#define SMMU_GNSR1_CBA2R56 (0x8e0) +#define SMMU_GNSR1_CBAR57 (0xe4) +#define SMMU_GNSR1_CBFRSYNRA57 (0x4e4) +#define SMMU_GNSR1_CBA2R57 (0x8e4) +#define SMMU_GNSR1_CBAR58 (0xe8) +#define SMMU_GNSR1_CBFRSYNRA58 (0x4e8) +#define SMMU_GNSR1_CBA2R58 (0x8e8) +#define SMMU_GNSR1_CBAR59 (0xec) +#define SMMU_GNSR1_CBFRSYNRA59 (0x4ec) +#define SMMU_GNSR1_CBA2R59 (0x8ec) +#define SMMU_GNSR1_CBAR60 (0xf0) +#define SMMU_GNSR1_CBFRSYNRA60 (0x4f0) +#define SMMU_GNSR1_CBA2R60 (0x8f0) +#define SMMU_GNSR1_CBAR61 (0xf4) +#define SMMU_GNSR1_CBFRSYNRA61 (0x4f4) +#define SMMU_GNSR1_CBA2R61 (0x8f4) +#define SMMU_GNSR1_CBAR62 (0xf8) +#define SMMU_GNSR1_CBFRSYNRA62 (0x4f8) +#define SMMU_GNSR1_CBA2R62 (0x8f8) +#define SMMU_GNSR1_CBAR63 (0xfc) +#define SMMU_GNSR1_CBFRSYNRA63 (0x4fc) +#define SMMU_GNSR1_CBA2R63 (0x8fc) + +/******************************************************************************* + * SMMU Global Secure Aux. Configuration Register + ******************************************************************************/ +#define SMMU_GSR0_SECURE_ACR 0x10 +#define SMMU_GSR0_PGSIZE_SHIFT 16 +#define SMMU_GSR0_PGSIZE_4K (0 << SMMU_GSR0_PGSIZE_SHIFT) +#define SMMU_GSR0_PGSIZE_64K (1 << SMMU_GSR0_PGSIZE_SHIFT) + +/******************************************************************************* + * SMMU configuration constants + ******************************************************************************/ +#define ID1_PAGESIZE (1 << 31) +#define ID1_NUMPAGENDXB_SHIFT 28 +#define ID1_NUMPAGENDXB_MASK 7 +#define ID1_NUMS2CB_SHIFT 16 +#define ID1_NUMS2CB_MASK 0xff +#define ID1_NUMCB_SHIFT 0 +#define ID1_NUMCB_MASK 0xff +#define PGSHIFT 16 +#define CB_SIZE 0x800000 + +static inline uint32_t tegra_smmu_read_32(uint32_t off) +{ + return mmio_read_32(TEGRA_SMMU_BASE + off); +} + +static inline void tegra_smmu_write_32(uint32_t off, uint32_t val) +{ + mmio_write_32(TEGRA_SMMU_BASE + off, val); +} + +void tegra_smmu_init(void); +void tegra_smmu_save_context(void); + +#endif /*__SMMU_H */ diff --git a/plat/nvidia/tegra/include/t186/tegra_def.h b/plat/nvidia/tegra/include/t186/tegra_def.h new file mode 100644 index 000000000..f3fbb891e --- /dev/null +++ b/plat/nvidia/tegra/include/t186/tegra_def.h @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __TEGRA_DEF_H__ +#define __TEGRA_DEF_H__ + +#include + +/******************************************************************************* + * These values are used by the PSCI implementation during the `CPU_SUSPEND` + * and `SYSTEM_SUSPEND` calls as the `state-id` field in the 'power state' + * parameter. + ******************************************************************************/ +#define PSTATE_ID_CORE_IDLE 6 +#define PSTATE_ID_CORE_POWERDN 7 +#define PSTATE_ID_SOC_POWERDN 2 + +/******************************************************************************* + * Platform power states (used by PSCI framework) + * + * - PLAT_MAX_RET_STATE should be less than lowest PSTATE_ID + * - PLAT_MAX_OFF_STATE should be greater than the highest PSTATE_ID + ******************************************************************************/ +#define PLAT_MAX_RET_STATE 1 +#define PLAT_MAX_OFF_STATE 8 + +/******************************************************************************* + * Implementation defined ACTLR_EL3 bit definitions + ******************************************************************************/ +#define ACTLR_EL3_L2ACTLR_BIT (1 << 6) +#define ACTLR_EL3_L2ECTLR_BIT (1 << 5) +#define ACTLR_EL3_L2CTLR_BIT (1 << 4) +#define ACTLR_EL3_CPUECTLR_BIT (1 << 1) +#define ACTLR_EL3_CPUACTLR_BIT (1 << 0) +#define ACTLR_EL3_ENABLE_ALL_ACCESS (ACTLR_EL3_L2ACTLR_BIT | \ + ACTLR_EL3_L2ECTLR_BIT | \ + ACTLR_EL3_L2CTLR_BIT | \ + ACTLR_EL3_CPUECTLR_BIT | \ + ACTLR_EL3_CPUACTLR_BIT) + +/******************************************************************************* + * Secure IRQ definitions + ******************************************************************************/ +#define TEGRA186_TOP_WDT_IRQ 49 +#define TEGRA186_AON_WDT_IRQ 50 + +#define TEGRA186_SEC_IRQ_TARGET_MASK 0xF3 /* 4 A57 - 2 Denver */ + +/******************************************************************************* + * Tegra Miscellanous register constants + ******************************************************************************/ +#define TEGRA_MISC_BASE 0x00100000 +#define HARDWARE_REVISION_OFFSET 0x4 +#define HARDWARE_MINOR_REVISION_MASK 0xf0000 +#define HARDWARE_MINOR_REVISION_SHIFT 0x10 +#define HARDWARE_REVISION_A01 1 +#define MISCREG_PFCFG 0x200C + +/******************************************************************************* + * Tegra Memory Controller constants + ******************************************************************************/ +#define TEGRA_MC_STREAMID_BASE 0x02C00000 +#define TEGRA_MC_BASE 0x02C10000 + +/******************************************************************************* + * Tegra UART Controller constants + ******************************************************************************/ +#define TEGRA_UARTA_BASE 0x03100000 +#define TEGRA_UARTB_BASE 0x03110000 +#define TEGRA_UARTC_BASE 0x0C280000 +#define TEGRA_UARTD_BASE 0x03130000 +#define TEGRA_UARTE_BASE 0x03140000 +#define TEGRA_UARTF_BASE 0x03150000 +#define TEGRA_UARTG_BASE 0x0C290000 + +/******************************************************************************* + * GICv2 & interrupt handling related constants + ******************************************************************************/ +#define TEGRA_GICD_BASE 0x03881000 +#define TEGRA_GICC_BASE 0x03882000 + +/******************************************************************************* + * Security Engine related constants + ******************************************************************************/ +#define TEGRA_SE0_BASE 0x03AC0000 +#define SE_MUTEX_WATCHDOG_NS_LIMIT 0x6C +#define TEGRA_PKA1_BASE 0x03AD0000 +#define PKA_MUTEX_WATCHDOG_NS_LIMIT 0x8144 +#define TEGRA_RNG1_BASE 0x03AE0000 +#define RNG_MUTEX_WATCHDOG_NS_LIMIT 0xFE0 + +/******************************************************************************* + * Tegra Clock and Reset Controller constants + ******************************************************************************/ +#define TEGRA_CAR_RESET_BASE 0x05000000 + +/******************************************************************************* + * Tegra micro-seconds timer constants + ******************************************************************************/ +#define TEGRA_TMRUS_BASE 0x0C2E0000 + +/******************************************************************************* + * Tegra Power Mgmt Controller constants + ******************************************************************************/ +#define TEGRA_PMC_BASE 0x0C360000 + +/******************************************************************************* + * Tegra scratch registers constants + ******************************************************************************/ +#define TEGRA_SCRATCH_BASE 0x0C390000 +#define SECURE_SCRATCH_RSV6 0x680 +#define SECURE_SCRATCH_RSV11_LO 0x6A8 +#define SECURE_SCRATCH_RSV11_HI 0x6AC + +/******************************************************************************* + * Tegra Memory Mapped Control Register Access Bus constants + ******************************************************************************/ +#define TEGRA_MMCRAB_BASE 0x0E000000 + +/******************************************************************************* + * Tegra SMMU Controller constants + ******************************************************************************/ +#define TEGRA_SMMU_BASE 0x12000000 + +/******************************************************************************* + * Tegra TZRAM constants + ******************************************************************************/ +#define TEGRA_TZRAM_BASE 0x30000000 +#define TEGRA_TZRAM_SIZE 0x50000 + +#endif /* __TEGRA_DEF_H__ */ diff --git a/plat/nvidia/tegra/include/tegra_platform.h b/plat/nvidia/tegra/include/tegra_platform.h index f9d7b60c9..a2813a832 100644 --- a/plat/nvidia/tegra/include/tegra_platform.h +++ b/plat/nvidia/tegra/include/tegra_platform.h @@ -33,6 +33,12 @@ #include +/* + * Tegra chip major/minor version + */ +uint32_t tegra_get_chipid_major(void); +uint32_t tegra_get_chipid_minor(void); + /* * Tegra chip identifiers */ diff --git a/plat/nvidia/tegra/soc/t186/drivers/include/mce.h b/plat/nvidia/tegra/soc/t186/drivers/include/mce.h new file mode 100644 index 000000000..7078b8bb2 --- /dev/null +++ b/plat/nvidia/tegra/soc/t186/drivers/include/mce.h @@ -0,0 +1,358 @@ +/* + * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __MCE_H__ +#define __MCE_H__ + +#include +#include + +/******************************************************************************* + * MCE apertures used by the ARI interface + * + * Aperture 0 - Cpu0 (ARM Cortex A-57) + * Aperture 1 - Cpu1 (ARM Cortex A-57) + * Aperture 2 - Cpu2 (ARM Cortex A-57) + * Aperture 3 - Cpu3 (ARM Cortex A-57) + * Aperture 4 - Cpu4 (Denver15) + * Aperture 5 - Cpu5 (Denver15) + ******************************************************************************/ +#define MCE_ARI_APERTURE_0_OFFSET 0x0 +#define MCE_ARI_APERTURE_1_OFFSET 0x10000 +#define MCE_ARI_APERTURE_2_OFFSET 0x20000 +#define MCE_ARI_APERTURE_3_OFFSET 0x30000 +#define MCE_ARI_APERTURE_4_OFFSET 0x40000 +#define MCE_ARI_APERTURE_5_OFFSET 0x50000 +#define MCE_ARI_APERTURE_OFFSET_MAX MCE_APERTURE_5_OFFSET + +/* number of apertures */ +#define MCE_ARI_APERTURES_MAX 6 + +/* each ARI aperture is 64KB */ +#define MCE_ARI_APERTURE_SIZE 0x10000 + +/******************************************************************************* + * CPU core ids - used by the MCE_ONLINE_CORE ARI + ******************************************************************************/ +typedef enum mce_core_id { + MCE_CORE_ID_DENVER_15_0, + MCE_CORE_ID_DENVER_15_1, + /* 2 and 3 are reserved */ + MCE_CORE_ID_A57_0 = 4, + MCE_CORE_ID_A57_1, + MCE_CORE_ID_A57_2, + MCE_CORE_ID_A57_3, + MCE_CORE_ID_MAX +} mce_core_id_t; + +#define MCE_CORE_ID_MASK 0x7 + +/******************************************************************************* + * MCE commands + ******************************************************************************/ +typedef enum mce_cmd { + MCE_CMD_ENTER_CSTATE = 0, + MCE_CMD_UPDATE_CSTATE_INFO, + MCE_CMD_UPDATE_CROSSOVER_TIME, + MCE_CMD_READ_CSTATE_STATS, + MCE_CMD_WRITE_CSTATE_STATS, + MCE_CMD_IS_SC7_ALLOWED, + MCE_CMD_ONLINE_CORE, + MCE_CMD_CC3_CTRL, + MCE_CMD_ECHO_DATA, + MCE_CMD_READ_VERSIONS, + MCE_CMD_ENUM_FEATURES, + MCE_CMD_ROC_FLUSH_CACHE_TRBITS, + MCE_CMD_ENUM_READ_MCA, + MCE_CMD_ENUM_WRITE_MCA, + MCE_CMD_ROC_FLUSH_CACHE, + MCE_CMD_ROC_CLEAN_CACHE, + MCE_CMD_IS_CCX_ALLOWED = 0xFE, + MCE_CMD_MAX = 0xFF, +} mce_cmd_t; + +#define MCE_CMD_MASK 0xFF + +/******************************************************************************* + * Macros to prepare CSTATE info request + ******************************************************************************/ +/* Description of the parameters for UPDATE_CSTATE_INFO request */ +#define CLUSTER_CSTATE_MASK 0x7 +#define CLUSTER_CSTATE_SHIFT 0 +#define CLUSTER_CSTATE_UPDATE_BIT (1 << 7) +#define CCPLEX_CSTATE_MASK 0x3 +#define CCPLEX_CSTATE_SHIFT 8 +#define CCPLEX_CSTATE_UPDATE_BIT (1 << 15) +#define SYSTEM_CSTATE_MASK 0xF +#define SYSTEM_CSTATE_SHIFT 16 +#define SYSTEM_CSTATE_FORCE_UPDATE_SHIFT 22 +#define SYSTEM_CSTATE_FORCE_UPDATE_BIT (1 << 22) +#define SYSTEM_CSTATE_UPDATE_BIT (1 << 23) +#define CSTATE_WAKE_MASK_UPDATE_BIT (1 << 31) +#define CSTATE_WAKE_MASK_SHIFT 32 +#define CSTATE_WAKE_MASK_CLEAR 0xFFFFFFFF + +/******************************************************************************* + * Auto-CC3 control macros + ******************************************************************************/ +#define MCE_AUTO_CC3_FREQ_MASK 0x1FF +#define MCE_AUTO_CC3_FREQ_SHIFT 0 +#define MCE_AUTO_CC3_VTG_MASK 0x7F +#define MCE_AUTO_CC3_VTG_SHIFT 16 +#define MCE_AUTO_CC3_ENABLE_BIT (1 << 31) + +/******************************************************************************* + * Macros for the 'IS_SC7_ALLOWED' command + ******************************************************************************/ +#define MCE_SC7_ALLOWED_MASK 0x7 +#define MCE_SC7_WAKE_TIME_SHIFT 32 + +/******************************************************************************* + * Macros for 'read/write ctats' commands + ******************************************************************************/ +#define MCE_CSTATE_STATS_TYPE_SHIFT 32 +#define MCE_CSTATE_WRITE_DATA_LO_MASK 0xF + +/******************************************************************************* + * Macros for 'update crossover threshold' command + ******************************************************************************/ +#define MCE_CROSSOVER_THRESHOLD_TIME_SHIFT 32 + +/******************************************************************************* + * Timeout value used to powerdown a core + ******************************************************************************/ +#define MCE_CORE_SLEEP_TIME_INFINITE 0xFFFFFFFF + +/******************************************************************************* + * MCA command struct + ******************************************************************************/ +typedef union mca_cmd { + struct command { + uint8_t cmd; + uint8_t idx; + uint8_t subidx; + } command; + struct input { + uint32_t low; + uint32_t high; + } input; + uint64_t data; +} mca_cmd_t; + +/******************************************************************************* + * MCA argument struct + ******************************************************************************/ +typedef union mca_arg { + struct err { + uint64_t error:8; + uint64_t unused:48; + uint64_t finish:8; + } err; + struct arg { + uint32_t low; + uint32_t high; + } arg; + uint64_t data; +} mca_arg_t; + +/******************************************************************************* + * Structure populated by arch specific code to export routines which perform + * common low level MCE functions + ******************************************************************************/ +typedef struct arch_mce_ops { + /* + * This ARI request sets up the MCE to start execution on assertion + * of STANDBYWFI, update the core power state and expected wake time, + * then determine the proper power state to enter. + */ + int (*enter_cstate)(uint32_t ari_base, uint32_t state, + uint32_t wake_time); + /* + * This ARI request allows updating of the CLUSTER_CSTATE, + * CCPLEX_CSTATE, and SYSTEM_CSTATE register values. + */ + int (*update_cstate_info)(uint32_t ari_base, + uint32_t cluster, + uint32_t ccplex, + uint32_t system, + uint8_t sys_state_force, + uint32_t wake_mask, + uint8_t update_wake_mask); + /* + * This ARI request allows updating of power state crossover + * threshold times. An index value specifies which crossover + * state is being updated. + */ + int (*update_crossover_time)(uint32_t ari_base, + uint32_t type, + uint32_t time); + /* + * This ARI request allows read access to statistical information + * related to power states. + */ + uint64_t (*read_cstate_stats)(uint32_t ari_base, + uint32_t state); + /* + * This ARI request allows write access to statistical information + * related to power states. + */ + int (*write_cstate_stats)(uint32_t ari_base, + uint32_t state, + uint32_t stats); + /* + * This ARI request allows the CPU to understand the features + * supported by the MCE firmware. + */ + uint64_t (*call_enum_misc)(uint32_t ari_base, uint32_t cmd, + uint32_t data); + /* + * This ARI request allows querying the CCPLEX to determine if + * the CCx state is allowed given a target core C-state and wake + * time. If the CCx state is allowed, the response indicates CCx + * must be entered. If the CCx state is not allowed, the response + * indicates CC6/CC7 can't be entered + */ + int (*is_ccx_allowed)(uint32_t ari_base, uint32_t state, + uint32_t wake_time); + /* + * This ARI request allows querying the CCPLEX to determine if + * the SC7 state is allowed given a target core C-state and wake + * time. If the SC7 state is allowed, all cores but the associated + * core are offlined (WAKE_EVENTS are set to 0) and the response + * indicates SC7 must be entered. If the SC7 state is not allowed, + * the response indicates SC7 can't be entered + */ + int (*is_sc7_allowed)(uint32_t ari_base, uint32_t state, + uint32_t wake_time); + /* + * This ARI request allows a core to bring another offlined core + * back online to the C0 state. Note that a core is offlined by + * entering a C-state where the WAKE_MASK is all 0. + */ + int (*online_core)(uint32_t ari_base, uint32_t cpuid); + /* + * This ARI request allows the CPU to enable/disable Auto-CC3 idle + * state. + */ + int (*cc3_ctrl)(uint32_t ari_base, + uint32_t freq, + uint32_t volt, + uint8_t enable); + /* + * This ARI request allows updating the reset vector register for + * D15 and A57 CPUs. + */ + int (*update_reset_vector)(uint32_t ari_base, + uint32_t addr_low, + uint32_t addr_high); + /* + * This ARI request instructs the ROC to flush A57 data caches in + * order to maintain coherency with the Denver cluster. + */ + int (*roc_flush_cache)(uint32_t ari_base); + /* + * This ARI request instructs the ROC to flush A57 data caches along + * with the caches covering ARM code in order to maintain coherency + * with the Denver cluster. + */ + int (*roc_flush_cache_trbits)(uint32_t ari_base); + /* + * This ARI request instructs the ROC to clean A57 data caches along + * with the caches covering ARM code in order to maintain coherency + * with the Denver cluster. + */ + int (*roc_clean_cache)(uint32_t ari_base); + /* + * This ARI request reads/writes the Machine Check Arch. (MCA) + * registers. + */ + uint64_t (*read_write_mca)(uint32_t ari_base, + mca_cmd_t cmd, + uint64_t *data); + /* + * Some MC GSC (General Security Carveout) register values are + * expected to be changed by TrustZone secure ARM code after boot. + * Since there is no hardware mechanism for the CCPLEX to know + * that an MC GSC register has changed to allow it to update its + * own internal GSC register, there needs to be a mechanism that + * can be used by ARM code to cause the CCPLEX to update its GSC + * register value. This ARI request allows updating the GSC register + * value for a certain carveout in the CCPLEX. + */ + int (*update_ccplex_gsc)(uint32_t ari_base, uint32_t gsc_idx); + /* + * This ARI request instructs the CCPLEX to either shutdown or + * reset the entire system + */ + void (*enter_ccplex_state)(uint32_t ari_base, uint32_t state_idx); +} arch_mce_ops_t; + +int mce_command_handler(mce_cmd_t cmd, uint64_t arg0, uint64_t arg1, + uint64_t arg2); +int mce_update_reset_vector(uint32_t addr_lo, uint32_t addr_hi); +int mce_update_gsc_videomem(void); +int mce_update_gsc_tzdram(void); +int mce_update_gsc_tzram(void); +__dead2 void mce_enter_ccplex_state(uint32_t state_idx); + +/* declarations for ARI/NVG handler functions */ +int ari_enter_cstate(uint32_t ari_base, uint32_t state, uint32_t wake_time); +int ari_update_cstate_info(uint32_t ari_base, uint32_t cluster, uint32_t ccplex, + uint32_t system, uint8_t sys_state_force, uint32_t wake_mask, + uint8_t update_wake_mask); +int ari_update_crossover_time(uint32_t ari_base, uint32_t type, uint32_t time); +uint64_t ari_read_cstate_stats(uint32_t ari_base, uint32_t state); +int ari_write_cstate_stats(uint32_t ari_base, uint32_t state, uint32_t stats); +uint64_t ari_enumeration_misc(uint32_t ari_base, uint32_t cmd, uint32_t data); +int ari_is_ccx_allowed(uint32_t ari_base, uint32_t state, uint32_t wake_time); +int ari_is_sc7_allowed(uint32_t ari_base, uint32_t state, uint32_t wake_time); +int ari_online_core(uint32_t ari_base, uint32_t core); +int ari_cc3_ctrl(uint32_t ari_base, uint32_t freq, uint32_t volt, uint8_t enable); +int ari_reset_vector_update(uint32_t ari_base, uint32_t lo, uint32_t hi); +int ari_roc_flush_cache_trbits(uint32_t ari_base); +int ari_roc_flush_cache(uint32_t ari_base); +int ari_roc_clean_cache(uint32_t ari_base); +uint64_t ari_read_write_mca(uint32_t ari_base, mca_cmd_t cmd, uint64_t *data); +int ari_update_ccplex_gsc(uint32_t ari_base, uint32_t gsc_idx); +void ari_enter_ccplex_state(uint32_t ari_base, uint32_t state_idx); + +int nvg_enter_cstate(uint32_t ari_base, uint32_t state, uint32_t wake_time); +int nvg_update_cstate_info(uint32_t ari_base, uint32_t cluster, uint32_t ccplex, + uint32_t system, uint8_t sys_state_force, uint32_t wake_mask, + uint8_t update_wake_mask); +int nvg_update_crossover_time(uint32_t ari_base, uint32_t type, uint32_t time); +uint64_t nvg_read_cstate_stats(uint32_t ari_base, uint32_t state); +int nvg_write_cstate_stats(uint32_t ari_base, uint32_t state, uint32_t val); +int nvg_is_ccx_allowed(uint32_t ari_base, uint32_t state, uint32_t wake_time); +int nvg_is_sc7_allowed(uint32_t ari_base, uint32_t state, uint32_t wake_time); +int nvg_online_core(uint32_t ari_base, uint32_t core); +int nvg_cc3_ctrl(uint32_t ari_base, uint32_t freq, uint32_t volt, uint8_t enable); + +#endif /* __MCE_H__ */ diff --git a/plat/nvidia/tegra/soc/t186/drivers/include/t18x_ari.h b/plat/nvidia/tegra/soc/t186/drivers/include/t18x_ari.h new file mode 100644 index 000000000..3e6054bd0 --- /dev/null +++ b/plat/nvidia/tegra/soc/t186/drivers/include/t18x_ari.h @@ -0,0 +1,450 @@ +/* + * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef T18X_TEGRA_ARI_H +#define T18X_TEGRA_ARI_H + +/* + * ---------------------------------------------------------------------------- + * t18x_ari.h + * + * Global ARI definitions. + * ---------------------------------------------------------------------------- + */ + +enum { + TEGRA_ARI_VERSION_MAJOR = 2, + TEGRA_ARI_VERSION_MINOR = 19, +}; + +typedef enum { + /* indexes below get the core lock */ + TEGRA_ARI_MISC = 0, + /* index 1 is deprecated */ + /* index 2 is deprecated */ + /* index 3 is deprecated */ + TEGRA_ARI_ONLINE_CORE = 4, + + /* indexes below need cluster lock */ + TEGRA_ARI_MISC_CLUSTER = 41, + TEGRA_ARI_IS_CCX_ALLOWED = 42, + TEGRA_ARI_CC3_CTRL = 43, + + /* indexes below need ccplex lock */ + TEGRA_ARI_ENTER_CSTATE = 80, + TEGRA_ARI_UPDATE_CSTATE_INFO = 81, + TEGRA_ARI_IS_SC7_ALLOWED = 82, + /* index 83 is deprecated */ + TEGRA_ARI_PERFMON = 84, + TEGRA_ARI_UPDATE_CCPLEX_GSC = 85, + /* index 86 is depracated */ + /* index 87 is deprecated */ + TEGRA_ARI_ROC_FLUSH_CACHE_ONLY = 88, + TEGRA_ARI_ROC_FLUSH_CACHE_TRBITS = 89, + TEGRA_ARI_MISC_CCPLEX = 90, + TEGRA_ARI_MCA = 91, + TEGRA_ARI_UPDATE_CROSSOVER = 92, + TEGRA_ARI_CSTATE_STATS = 93, + TEGRA_ARI_WRITE_CSTATE_STATS = 94, + TEGRA_ARI_COPY_MISCREG_AA64_RST = 95, + TEGRA_ARI_ROC_CLEAN_CACHE_ONLY = 96, +} tegra_ari_req_id_t; + +typedef enum { + TEGRA_ARI_MISC_ECHO = 0, + TEGRA_ARI_MISC_VERSION = 1, + TEGRA_ARI_MISC_FEATURE_LEAF_0 = 2, +} tegra_ari_misc_index_t; + +typedef enum { + TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_POWER_OFF = 0, + TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_REBOOT = 1, + TEGRA_ARI_MISC_CCPLEX_CORESIGHT_CG_CTRL = 2, +} tegra_ari_misc_ccplex_index_t; + +typedef enum { + TEGRA_ARI_CORE_C0 = 0, + TEGRA_ARI_CORE_C1 = 1, + TEGRA_ARI_CORE_C6 = 6, + TEGRA_ARI_CORE_C7 = 7, + TEGRA_ARI_CORE_WARMRSTREQ = 8, +} tegra_ari_core_sleep_state_t; + +typedef enum { + TEGRA_ARI_CLUSTER_CC0 = 0, + TEGRA_ARI_CLUSTER_CC1 = 1, + TEGRA_ARI_CLUSTER_CC6 = 6, + TEGRA_ARI_CLUSTER_CC7 = 7, +} tegra_ari_cluster_sleep_state_t; + +typedef enum { + TEGRA_ARI_CCPLEX_CCP0 = 0, + TEGRA_ARI_CCPLEX_CCP1 = 1, + TEGRA_ARI_CCPLEX_CCP3 = 3, +} tegra_ari_ccplex_sleep_state_t; + +typedef enum { + TEGRA_ARI_SYSTEM_SC0 = 0, + TEGRA_ARI_SYSTEM_SC1 = 1, + TEGRA_ARI_SYSTEM_SC2 = 2, + TEGRA_ARI_SYSTEM_SC3 = 3, + TEGRA_ARI_SYSTEM_SC4 = 4, + TEGRA_ARI_SYSTEM_SC7 = 7, + TEGRA_ARI_SYSTEM_SC8 = 8, +} tegra_ari_system_sleep_state_t; + +typedef enum { + TEGRA_ARI_CROSSOVER_C1_C6 = 0, + TEGRA_ARI_CROSSOVER_CC1_CC6 = 1, + TEGRA_ARI_CROSSOVER_CC1_CC7 = 2, + TEGRA_ARI_CROSSOVER_CCP1_CCP3 = 3, + TEGRA_ARI_CROSSOVER_CCP3_SC2 = 4, + TEGRA_ARI_CROSSOVER_CCP3_SC3 = 5, + TEGRA_ARI_CROSSOVER_CCP3_SC4 = 6, + TEGRA_ARI_CROSSOVER_CCP3_SC7 = 7, + TEGRA_ARI_CROSSOVER_CCP3_SC1 = 8, +} tegra_ari_crossover_index_t; + +typedef enum { + TEGRA_ARI_CSTATE_STATS_CLEAR = 0, + TEGRA_ARI_CSTATE_STATS_SC7_ENTRIES = 1, + TEGRA_ARI_CSTATE_STATS_SC4_ENTRIES, + TEGRA_ARI_CSTATE_STATS_SC3_ENTRIES, + TEGRA_ARI_CSTATE_STATS_SC2_ENTRIES, + TEGRA_ARI_CSTATE_STATS_CCP3_ENTRIES, + TEGRA_ARI_CSTATE_STATS_A57_CC6_ENTRIES, + TEGRA_ARI_CSTATE_STATS_A57_CC7_ENTRIES, + TEGRA_ARI_CSTATE_STATS_D15_CC6_ENTRIES, + TEGRA_ARI_CSTATE_STATS_D15_CC7_ENTRIES, + TEGRA_ARI_CSTATE_STATS_D15_0_C6_ENTRIES, + TEGRA_ARI_CSTATE_STATS_D15_1_C6_ENTRIES, + TEGRA_ARI_CSTATE_STATS_D15_0_C7_ENTRIES = 14, + TEGRA_ARI_CSTATE_STATS_D15_1_C7_ENTRIES, + TEGRA_ARI_CSTATE_STATS_A57_0_C7_ENTRIES = 18, + TEGRA_ARI_CSTATE_STATS_A57_1_C7_ENTRIES, + TEGRA_ARI_CSTATE_STATS_A57_2_C7_ENTRIES, + TEGRA_ARI_CSTATE_STATS_A57_3_C7_ENTRIES, + TEGRA_ARI_CSTATE_STATS_LAST_CSTATE_ENTRY_D15_0, + TEGRA_ARI_CSTATE_STATS_LAST_CSTATE_ENTRY_D15_1, + TEGRA_ARI_CSTATE_STATS_LAST_CSTATE_ENTRY_A57_0 = 26, + TEGRA_ARI_CSTATE_STATS_LAST_CSTATE_ENTRY_A57_1, + TEGRA_ARI_CSTATE_STATS_LAST_CSTATE_ENTRY_A57_2, + TEGRA_ARI_CSTATE_STATS_LAST_CSTATE_ENTRY_A57_3, +} tegra_ari_cstate_stats_index_t; + +typedef enum { + TEGRA_ARI_GSC_ALL = 0, + + TEGRA_ARI_GSC_BPMP = 6, + TEGRA_ARI_GSC_APE = 7, + TEGRA_ARI_GSC_SPE = 8, + TEGRA_ARI_GSC_SCE = 9, + TEGRA_ARI_GSC_APR = 10, + TEGRA_ARI_GSC_TZRAM = 11, + TEGRA_ARI_GSC_SE = 12, + + TEGRA_ARI_GSC_BPMP_TO_SPE = 16, + TEGRA_ARI_GSC_SPE_TO_BPMP = 17, + TEGRA_ARI_GSC_CPU_TZ_TO_BPMP = 18, + TEGRA_ARI_GSC_BPMP_TO_CPU_TZ = 19, + TEGRA_ARI_GSC_CPU_NS_TO_BPMP = 20, + TEGRA_ARI_GSC_BPMP_TO_CPU_NS = 21, + TEGRA_ARI_GSC_IPC_SE_SPE_SCE_BPMP = 22, + TEGRA_ARI_GSC_SC7_RESUME_FW = 23, + + TEGRA_ARI_GSC_TZ_DRAM_IDX = 34, + TEGRA_ARI_GSC_VPR_IDX = 35, +} tegra_ari_gsc_index_t; + +/* This macro will produce enums for __name##_LSB, __name##_MSB and __name##_MSK */ +#define TEGRA_ARI_ENUM_MASK_LSB_MSB(__name, __lsb, __msb) __name##_LSB = __lsb, __name##_MSB = __msb + +typedef enum { + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_UPDATE_CSTATE_INFO__CLUSTER_CSTATE, 0, 2), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_UPDATE_CSTATE_INFO__CLUSTER_CSTATE_PRESENT, 7, 7), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_UPDATE_CSTATE_INFO__CCPLEX_CSTATE, 8, 9), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_UPDATE_CSTATE_INFO__CCPLEX_CSTATE_PRESENT, 15, 15), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_UPDATE_CSTATE_INFO__SYSTEM_CSTATE, 16, 19), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_UPDATE_CSTATE_INFO__IGNORE_CROSSOVERS, 22, 22), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_UPDATE_CSTATE_INFO__SYSTEM_CSTATE_PRESENT, 23, 23), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_UPDATE_CSTATE_INFO__WAKE_MASK_PRESENT, 31, 31), +} tegra_ari_update_cstate_info_bitmasks_t; + +typedef enum { + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MISC_CCPLEX_CORESIGHT_CG_CTRL__EN, 0, 0), +} tegra_ari_misc_ccplex_bitmasks_t; + +typedef enum { + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_CC3_CTRL__IDLE_FREQ, 0, 8), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_CC3_CTRL__IDLE_VOLT, 16, 23), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_CC3_CTRL__ENABLE, 31, 31), +} tegra_ari_cc3_ctrl_bitmasks_t; + +typedef enum { + TEGRA_ARI_MCA_NOP = 0, + TEGRA_ARI_MCA_READ_SERR = 1, + TEGRA_ARI_MCA_WRITE_SERR = 2, + TEGRA_ARI_MCA_CLEAR_SERR = 4, + TEGRA_ARI_MCA_REPORT_SERR = 5, + TEGRA_ARI_MCA_READ_INTSTS = 6, + TEGRA_ARI_MCA_WRITE_INTSTS = 7, + TEGRA_ARI_MCA_READ_PREBOOT_SERR = 8, +} tegra_ari_mca_commands_t; + +typedef enum { + TEGRA_ARI_MCA_RD_WR_DPMU = 0, + TEGRA_ARI_MCA_RD_WR_IOB = 1, + TEGRA_ARI_MCA_RD_WR_MCB = 2, + TEGRA_ARI_MCA_RD_WR_CCE = 3, + TEGRA_ARI_MCA_RD_WR_CQX = 4, + TEGRA_ARI_MCA_RD_WR_CTU = 5, + TEGRA_ARI_MCA_RD_BANK_INFO = 0x0f, + TEGRA_ARI_MCA_RD_BANK_TEMPLATE = 0x10, + TEGRA_ARI_MCA_RD_WR_SECURE_ACCESS_REGISTER = 0x11, + TEGRA_ARI_MCA_RD_WR_GLOBAL_CONFIG_REGISTER = 0x12, +} tegra_ari_mca_rd_wr_indexes_t; + +typedef enum { + TEGRA_ARI_MCA_RD_WR_ASERRX_CTRL = 0, + TEGRA_ARI_MCA_RD_WR_ASERRX_STATUS = 1, + TEGRA_ARI_MCA_RD_WR_ASERRX_ADDR = 2, + TEGRA_ARI_MCA_RD_WR_ASERRX_MISC1 = 3, + TEGRA_ARI_MCA_RD_WR_ASERRX_MISC2 = 4, +} tegra_ari_mca_read_asserx_subindexes_t; + +typedef enum { + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_SECURE_REGISTER_SETTING_ENABLES_NS_PERMITTED, 0, 0), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_SECURE_REGISTER_READING_STATUS_NS_PERMITTED, 1, 1), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_SECURE_REGISTER_PENDING_MCA_ERRORS_NS_PERMITTED, 2, 2), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_SECURE_REGISTER_CLEARING_MCA_INTERRUPTS_NS_PERMITTED, 3, 3), +} tegra_ari_mca_secure_register_bitmasks_t; + +typedef enum { + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR0_STAT_SERR_ERR_CODE, 0, 15), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR0_STAT_PWM_ERR, 16, 16), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR0_STAT_CRAB_ERR, 17, 17), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR0_STAT_RD_WR_N, 18, 18), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR0_STAT_UCODE_ERR, 19, 19), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR0_STAT_PWM, 20, 23), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR0_STAT_AV, 58, 58), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR0_STAT_MV, 59, 59), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR0_STAT_EN, 60, 60), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR0_STAT_UC, 61, 61), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR0_STAT_OVF, 62, 62), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR0_STAT_VAL, 63, 63), + + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR0_ADDR_ADDR, 0, 41), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR0_ADDR_UCODE_ERRCD, 42, 52), + + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR0_CTRL_EN_PWM_ERR, 0, 0), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR0_CTRL_EN_CRAB_ERR, 1, 1), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR0_CTRL_EN_UCODE_ERR, 3, 3), +} tegra_ari_mca_aserr0_bitmasks_t; + +typedef enum { + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR1_STAT_SERR_ERR_CODE, 0, 15), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR1_STAT_MSI_ERR, 16, 16), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR1_STAT_IHI_ERR, 17, 17), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR1_STAT_CRI_ERR, 18, 18), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR1_STAT_MMCRAB_ERR, 19, 19), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR1_STAT_CSI_ERR, 20, 20), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR1_STAT_RD_WR_N, 21, 21), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR1_STAT_REQ_ERRT, 22, 23), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR1_STAT_RESP_ERRT, 24, 25), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR1_STAT_AV, 58, 58), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR1_STAT_MV, 59, 59), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR1_STAT_EN, 60, 60), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR1_STAT_UC, 61, 61), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR1_STAT_OVF, 62, 62), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR1_STAT_VAL, 63, 63), + + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR1_STAT_AXI_ID, 0, 7), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR1_STAT_CQX_ID, 8, 27), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR1_STAT_CQX_CID, 28, 31), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR1_STAT_CQX_CMD, 32, 35), + + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR1_CTRL_EN_MSI_ERR, 0, 0), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR1_CTRL_EN_IHI_ERR, 1, 1), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR1_CTRL_EN_CRI_ERR, 2, 2), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR1_CTRL_EN_MMCRAB_ERR, 3, 3), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR1_CTRL_EN_CSI_ERR, 4, 4), + + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR1_MISC_ADDR, 0, 41), +} tegra_ari_mca_aserr1_bitmasks_t; + +typedef enum { + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR2_STAT_SERR_ERR_CODE, 0, 15), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR2_STAT_MC_ERR, 16, 16), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR2_STAT_SYSRAM_ERR, 17, 17), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR2_STAT_CLIENT_ID, 18, 19), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR2_STAT_AV, 58, 58), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR2_STAT_MV, 59, 59), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR2_STAT_EN, 60, 60), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR2_STAT_UC, 61, 61), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR2_STAT_OVF, 62, 62), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR2_STAT_VAL, 63, 63), + + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR2_ADDR_ID, 0, 17), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR2_ADDR_CMD, 18, 21), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR2_ADDR_ADDR, 22, 53), + + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR2_CTRL_EN_MC_ERR, 0, 0), +} tegra_ari_mca_aserr2_bitmasks_t; + +typedef enum { + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR3_STAT_SERR_ERR_CODE, 0, 15), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR3_STAT_TO_ERR, 16, 16), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR3_STAT_STAT_ERR, 17, 17), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR3_STAT_DST_ERR, 18, 18), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR3_STAT_UNC_ERR, 19, 19), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR3_STAT_MH_ERR, 20, 20), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR3_STAT_PERR, 21, 21), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR3_STAT_PSN_ERR, 22, 22), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR3_STAT_AV, 58, 58), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR3_STAT_MV, 59, 59), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR3_STAT_EN, 60, 60), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR3_STAT_UC, 61, 61), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR3_STAT_OVF, 62, 62), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR3_STAT_VAL, 63, 63), + + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR3_ADDR_CMD, 0, 5), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR3_ADDR_ADDR, 6, 47), + + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR3_MISC1_TO, 0, 0), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR3_MISC1_DIV4, 1, 1), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR3_MISC1_TLIMIT, 2, 11), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR3_MISC1_PSN_ERR_CORR_MSK, 12, 25), + + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR3_MISC2_MORE_INFO, 0, 17), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR3_MISC2_TO_INFO, 18, 43), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR3_MISC2_SRC, 44, 45), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR3_MISC2_TID, 46, 52), + + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR3_CTRL_EN_TO_ERR, 0, 0), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR3_CTRL_EN_STAT_ERR, 1, 1), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR3_CTRL_EN_DST_ERR, 2, 2), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR3_CTRL_EN_UNC_ERR, 3, 3), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR3_CTRL_EN_MH_ERR, 4, 4), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR3_CTRL_EN_PERR, 5, 5), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR3_CTRL_EN_PSN_ERR, 6, 19), +} tegra_ari_mca_aserr3_bitmasks_t; + +typedef enum { + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR4_STAT_SERR_ERR_CODE, 0, 15), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR4_STAT_SRC_ERR, 16, 16), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR4_STAT_DST_ERR, 17, 17), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR4_STAT_REQ_ERR, 18, 18), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR4_STAT_RSP_ERR, 19, 19), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR4_STAT_AV, 58, 58), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR4_STAT_MV, 59, 59), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR4_STAT_EN, 60, 60), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR4_STAT_UC, 61, 61), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR4_STAT_OVF, 62, 62), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR4_STAT_VAL, 63, 63), + + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR4_CTRL_EN_CPE_ERR, 0, 0), +} tegra_ari_mca_aserr4_bitmasks_t; + +typedef enum { + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR5_STAT_SERR_ERR_CODE, 0, 15), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR5_STAT_CTUPAR, 16, 16), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR5_STAT_MULTI, 17, 17), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR5_STAT_AV, 58, 58), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR5_STAT_MV, 59, 59), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR5_STAT_EN, 60, 60), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR5_STAT_UC, 61, 61), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR5_STAT_OVF, 62, 62), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR5_STAT_VAL, 63, 63), + + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR5_ADDR_SRC, 0, 7), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR5_ADDR_ID, 8, 15), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR5_ADDR_DATA, 16, 26), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR5_ADDR_CMD, 32, 35), + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR5_ADDR_ADDR, 36, 45), + + TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR5_CTRL_EN_CTUPAR, 0, 0), +} tegra_ari_mca_aserr5_bitmasks_t; + +#undef TEGRA_ARI_ENUM_MASK_LSB_MSB + +typedef enum { + TEGRA_NVG_CHANNEL_PMIC = 0, + TEGRA_NVG_CHANNEL_POWER_PERF = 1, + TEGRA_NVG_CHANNEL_POWER_MODES = 2, + TEGRA_NVG_CHANNEL_WAKE_TIME = 3, + TEGRA_NVG_CHANNEL_CSTATE_INFO = 4, + TEGRA_NVG_CHANNEL_CROSSOVER_C1_C6 = 5, + TEGRA_NVG_CHANNEL_CROSSOVER_CC1_CC6 = 6, + TEGRA_NVG_CHANNEL_CROSSOVER_CC1_CC7 = 7, + TEGRA_NVG_CHANNEL_CROSSOVER_CCP1_CCP3 = 8, + TEGRA_NVG_CHANNEL_CROSSOVER_CCP3_SC2 = 9, + TEGRA_NVG_CHANNEL_CROSSOVER_CCP3_SC3 = 10, + TEGRA_NVG_CHANNEL_CROSSOVER_CCP3_SC4 = 11, + TEGRA_NVG_CHANNEL_CROSSOVER_CCP3_SC7 = 12, + TEGRA_NVG_CHANNEL_CSTATE_STATS_CLEAR = 13, + TEGRA_NVG_CHANNEL_CSTATE_STATS_SC7_ENTRIES = 14, + TEGRA_NVG_CHANNEL_CSTATE_STATS_SC4_ENTRIES = 15, + TEGRA_NVG_CHANNEL_CSTATE_STATS_SC3_ENTRIES = 16, + TEGRA_NVG_CHANNEL_CSTATE_STATS_SC2_ENTRIES = 17, + TEGRA_NVG_CHANNEL_CSTATE_STATS_CCP3_ENTRIES = 18, + TEGRA_NVG_CHANNEL_CSTATE_STATS_A57_CC6_ENTRIES = 19, + TEGRA_NVG_CHANNEL_CSTATE_STATS_A57_CC7_ENTRIES = 20, + TEGRA_NVG_CHANNEL_CSTATE_STATS_D15_CC6_ENTRIES = 21, + TEGRA_NVG_CHANNEL_CSTATE_STATS_D15_CC7_ENTRIES = 22, + TEGRA_NVG_CHANNEL_CSTATE_STATS_D15_0_C6_ENTRIES = 23, + TEGRA_NVG_CHANNEL_CSTATE_STATS_D15_1_C6_ENTRIES = 24, + TEGRA_NVG_CHANNEL_CSTATE_STATS_D15_2_C6_ENTRIES = 25, /* Reserved (for Denver15 core 2) */ + TEGRA_NVG_CHANNEL_CSTATE_STATS_D15_3_C6_ENTRIES = 26, /* Reserved (for Denver15 core 3) */ + TEGRA_NVG_CHANNEL_CSTATE_STATS_D15_0_C7_ENTRIES = 27, + TEGRA_NVG_CHANNEL_CSTATE_STATS_D15_1_C7_ENTRIES = 28, + TEGRA_NVG_CHANNEL_CSTATE_STATS_D15_2_C7_ENTRIES = 29, /* Reserved (for Denver15 core 2) */ + TEGRA_NVG_CHANNEL_CSTATE_STATS_D15_3_C7_ENTRIES = 30, /* Reserved (for Denver15 core 3) */ + TEGRA_NVG_CHANNEL_CSTATE_STATS_A57_0_C7_ENTRIES = 31, + TEGRA_NVG_CHANNEL_CSTATE_STATS_A57_1_C7_ENTRIES = 32, + TEGRA_NVG_CHANNEL_CSTATE_STATS_A57_2_C7_ENTRIES = 33, + TEGRA_NVG_CHANNEL_CSTATE_STATS_A57_3_C7_ENTRIES = 34, + TEGRA_NVG_CHANNEL_CSTATE_STATS_LAST_CSTATE_ENTRY_D15_0 = 35, + TEGRA_NVG_CHANNEL_CSTATE_STATS_LAST_CSTATE_ENTRY_D15_1 = 36, + TEGRA_NVG_CHANNEL_CSTATE_STATS_LAST_CSTATE_ENTRY_D15_2 = 37, /* Reserved (for Denver15 core 2) */ + TEGRA_NVG_CHANNEL_CSTATE_STATS_LAST_CSTATE_ENTRY_D15_3 = 38, /* Reserved (for Denver15 core 3) */ + TEGRA_NVG_CHANNEL_CSTATE_STATS_LAST_CSTATE_ENTRY_A57_0 = 39, + TEGRA_NVG_CHANNEL_CSTATE_STATS_LAST_CSTATE_ENTRY_A57_1 = 40, + TEGRA_NVG_CHANNEL_CSTATE_STATS_LAST_CSTATE_ENTRY_A57_2 = 41, + TEGRA_NVG_CHANNEL_CSTATE_STATS_LAST_CSTATE_ENTRY_A57_3 = 42, + TEGRA_NVG_CHANNEL_IS_SC7_ALLOWED = 43, + TEGRA_NVG_CHANNEL_ONLINE_CORE = 44, + TEGRA_NVG_CHANNEL_CC3_CTRL = 45, + TEGRA_NVG_CHANNEL_CROSSOVER_CCP3_SC1 = 46, + TEGRA_NVG_CHANNEL_LAST_INDEX, +} tegra_nvg_channel_id_t; + +#endif /* T18X_TEGRA_ARI_H */ + + diff --git a/plat/nvidia/tegra/soc/t186/drivers/mce/aarch64/nvg_helpers.S b/plat/nvidia/tegra/soc/t186/drivers/mce/aarch64/nvg_helpers.S new file mode 100644 index 000000000..b6e4b31ab --- /dev/null +++ b/plat/nvidia/tegra/soc/t186/drivers/mce/aarch64/nvg_helpers.S @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include + + .globl nvg_set_request_data + .globl nvg_set_request + .globl nvg_get_result + +/* void nvg_set_request_data(uint64_t req, uint64_t data) */ +func nvg_set_request_data + msr s3_0_c15_c1_2, x0 + msr s3_0_c15_c1_3, x1 + ret +endfunc nvg_set_request_data + +/* void nvg_set_request(uint64_t req) */ +func nvg_set_request + msr s3_0_c15_c1_2, x0 + ret +endfunc nvg_set_request + +/* uint64_t nvg_get_result(void) */ +func nvg_get_result + mrs x0, s3_0_c15_c1_3 + ret +endfunc nvg_get_result diff --git a/plat/nvidia/tegra/soc/t186/drivers/mce/ari.c b/plat/nvidia/tegra/soc/t186/drivers/mce/ari.c new file mode 100644 index 000000000..147a358ae --- /dev/null +++ b/plat/nvidia/tegra/soc/t186/drivers/mce/ari.c @@ -0,0 +1,391 @@ +/* + * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/******************************************************************************* + * Register offsets for ARI request/results + ******************************************************************************/ +#define ARI_REQUEST 0x0 +#define ARI_REQUEST_EVENT_MASK 0x4 +#define ARI_STATUS 0x8 +#define ARI_REQUEST_DATA_LO 0xC +#define ARI_REQUEST_DATA_HI 0x10 +#define ARI_RESPONSE_DATA_LO 0x14 +#define ARI_RESPONSE_DATA_HI 0x18 + +/* Status values for the current request */ +#define ARI_REQ_PENDING 1 +#define ARI_REQ_ONGOING 3 +#define ARI_REQUEST_VALID_BIT (1 << 8) +#define ARI_EVT_MASK_STANDBYWFI_BIT (1 << 7) + +/******************************************************************************* + * ARI helper functions + ******************************************************************************/ +static inline uint32_t ari_read_32(uint32_t ari_base, uint32_t reg) +{ + return mmio_read_32(ari_base + reg); +} + +static inline void ari_write_32(uint32_t ari_base, uint32_t val, uint32_t reg) +{ + mmio_write_32(ari_base + reg, val); +} + +static inline uint32_t ari_get_request_low(uint32_t ari_base) +{ + return ari_read_32(ari_base, ARI_REQUEST_DATA_LO); +} + +static inline uint32_t ari_get_request_high(uint32_t ari_base) +{ + return ari_read_32(ari_base, ARI_REQUEST_DATA_HI); +} + +static inline uint32_t ari_get_response_low(uint32_t ari_base) +{ + return ari_read_32(ari_base, ARI_RESPONSE_DATA_LO); +} + +static inline uint32_t ari_get_response_high(uint32_t ari_base) +{ + return ari_read_32(ari_base, ARI_RESPONSE_DATA_HI); +} + +static inline void ari_clobber_response(uint32_t ari_base) +{ + ari_write_32(ari_base, 0, ARI_RESPONSE_DATA_LO); + ari_write_32(ari_base, 0, ARI_RESPONSE_DATA_HI); +} + +static int ari_request_wait(uint32_t ari_base, uint32_t evt_mask, uint32_t req, + uint32_t lo, uint32_t hi) +{ + int status; + + /* program the request, event_mask, hi and lo registers */ + ari_write_32(ari_base, lo, ARI_REQUEST_DATA_LO); + ari_write_32(ari_base, hi, ARI_REQUEST_DATA_HI); + ari_write_32(ari_base, evt_mask, ARI_REQUEST_EVENT_MASK); + ari_write_32(ari_base, req | ARI_REQUEST_VALID_BIT, ARI_REQUEST); + + /* + * For commands that have an event trigger, we should bypass + * ARI_STATUS polling, since MCE is waiting for SW to trigger + * the event. + */ + if (evt_mask) + return 0; + + /* NOTE: add timeout check if needed */ + status = ari_read_32(ari_base, ARI_STATUS); + while (status & (ARI_REQ_ONGOING | ARI_REQ_PENDING)) + status = ari_read_32(ari_base, ARI_STATUS); + + return 0; +} + +int ari_enter_cstate(uint32_t ari_base, uint32_t state, uint32_t wake_time) +{ + /* check for allowed power state */ + if (state != TEGRA_ARI_CORE_C0 && state != TEGRA_ARI_CORE_C1 && + state != TEGRA_ARI_CORE_C6 && state != TEGRA_ARI_CORE_C7) { + ERROR("%s: unknown cstate (%d)\n", __func__, state); + return EINVAL; + } + + /* Enter the cstate, to be woken up after wake_time (TSC ticks) */ + return ari_request_wait(ari_base, ARI_EVT_MASK_STANDBYWFI_BIT, + TEGRA_ARI_ENTER_CSTATE, state, wake_time); +} + +int ari_update_cstate_info(uint32_t ari_base, uint32_t cluster, uint32_t ccplex, + uint32_t system, uint8_t sys_state_force, uint32_t wake_mask, + uint8_t update_wake_mask) +{ + uint32_t val = 0; + + /* update CLUSTER_CSTATE? */ + if (cluster) + val |= (cluster & CLUSTER_CSTATE_MASK) | + CLUSTER_CSTATE_UPDATE_BIT; + + /* update CCPLEX_CSTATE? */ + if (ccplex) + val |= (ccplex & CCPLEX_CSTATE_MASK) << CCPLEX_CSTATE_SHIFT | + CCPLEX_CSTATE_UPDATE_BIT; + + /* update SYSTEM_CSTATE? */ + if (system) + val |= ((system & SYSTEM_CSTATE_MASK) << SYSTEM_CSTATE_SHIFT) | + ((sys_state_force << SYSTEM_CSTATE_FORCE_UPDATE_SHIFT) | + SYSTEM_CSTATE_UPDATE_BIT); + + /* update wake mask value? */ + if (update_wake_mask) + val |= CSTATE_WAKE_MASK_UPDATE_BIT; + + /* set the updated cstate info */ + return ari_request_wait(ari_base, 0, TEGRA_ARI_UPDATE_CSTATE_INFO, val, + wake_mask); +} + +int ari_update_crossover_time(uint32_t ari_base, uint32_t type, uint32_t time) +{ + /* sanity check crossover type */ + if ((type == TEGRA_ARI_CROSSOVER_C1_C6) || + (type > TEGRA_ARI_CROSSOVER_CCP3_SC1)) + return EINVAL; + + /* update crossover threshold time */ + return ari_request_wait(ari_base, 0, TEGRA_ARI_UPDATE_CROSSOVER, + type, time); +} + +uint64_t ari_read_cstate_stats(uint32_t ari_base, uint32_t state) +{ + int ret; + + /* sanity check crossover type */ + if (state == 0) + return EINVAL; + + ret = ari_request_wait(ari_base, 0, TEGRA_ARI_CSTATE_STATS, state, 0); + if (ret != 0) + return EINVAL; + + return (uint64_t)ari_get_response_low(ari_base); +} + +int ari_write_cstate_stats(uint32_t ari_base, uint32_t state, uint32_t stats) +{ + /* write the cstate stats */ + return ari_request_wait(ari_base, 0, TEGRA_ARI_WRITE_CSTATE_STATS, state, + stats); +} + +uint64_t ari_enumeration_misc(uint32_t ari_base, uint32_t cmd, uint32_t data) +{ + uint64_t resp; + int ret; + + /* clean the previous response state */ + ari_clobber_response(ari_base); + + /* ARI_REQUEST_DATA_HI is reserved for commands other than 'ECHO' */ + if (cmd != TEGRA_ARI_MISC_ECHO) + data = 0; + + ret = ari_request_wait(ari_base, 0, TEGRA_ARI_MISC, cmd, data); + if (ret) + return (uint64_t)ret; + + /* get the command response */ + resp = ari_get_response_low(ari_base); + resp |= ((uint64_t)ari_get_response_high(ari_base) << 32); + + return resp; +} + +int ari_is_ccx_allowed(uint32_t ari_base, uint32_t state, uint32_t wake_time) +{ + int ret; + + ret = ari_request_wait(ari_base, 0, TEGRA_ARI_IS_CCX_ALLOWED, state & 0x7, + wake_time); + if (ret) { + ERROR("%s: failed (%d)\n", __func__, ret); + return 0; + } + + /* 1 = CCx allowed, 0 = CCx not allowed */ + return (ari_get_response_low(ari_base) & 0x1); +} + +int ari_is_sc7_allowed(uint32_t ari_base, uint32_t state, uint32_t wake_time) +{ + int ret; + + /* check for allowed power state */ + if (state != TEGRA_ARI_CORE_C0 && state != TEGRA_ARI_CORE_C1 && + state != TEGRA_ARI_CORE_C6 && state != TEGRA_ARI_CORE_C7) { + ERROR("%s: unknown cstate (%d)\n", __func__, state); + return EINVAL; + } + + ret = ari_request_wait(ari_base, 0, TEGRA_ARI_IS_SC7_ALLOWED, state, + wake_time); + if (ret) { + ERROR("%s: failed (%d)\n", __func__, ret); + return 0; + } + + /* 1 = SC7 allowed, 0 = SC7 not allowed */ + return !!ari_get_response_low(ari_base); +} + +int ari_online_core(uint32_t ari_base, uint32_t core) +{ + int cpu = read_mpidr() & MPIDR_CPU_MASK; + int cluster = (read_mpidr() & MPIDR_CLUSTER_MASK) >> + MPIDR_AFFINITY_BITS; + int impl = (read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK; + + /* construct the current CPU # */ + cpu |= (cluster << 2); + + /* sanity check target core id */ + if ((core >= MCE_CORE_ID_MAX) || (cpu == core)) { + ERROR("%s: unsupported core id (%d)\n", __func__, core); + return EINVAL; + } + + /* + * The Denver cluster has 2 CPUs only - 0, 1. + */ + if (impl == DENVER_IMPL && ((core == 2) || (core == 3))) { + ERROR("%s: unknown core id (%d)\n", __func__, core); + return EINVAL; + } + + return ari_request_wait(ari_base, 0, TEGRA_ARI_ONLINE_CORE, core, 0); +} + +int ari_cc3_ctrl(uint32_t ari_base, uint32_t freq, uint32_t volt, uint8_t enable) +{ + int val; + + /* + * If the enable bit is cleared, Auto-CC3 will be disabled by setting + * the SW visible voltage/frequency request registers for all non + * floorswept cores valid independent of StandbyWFI and disabling + * the IDLE voltage/frequency request register. If set, Auto-CC3 + * will be enabled by setting the ARM SW visible voltage/frequency + * request registers for all non floorswept cores to be enabled by + * StandbyWFI or the equivalent signal, and always keeping the IDLE + * voltage/frequency request register enabled. + */ + val = (((freq & MCE_AUTO_CC3_FREQ_MASK) << MCE_AUTO_CC3_FREQ_SHIFT) |\ + ((volt & MCE_AUTO_CC3_VTG_MASK) << MCE_AUTO_CC3_VTG_SHIFT) |\ + (enable ? MCE_AUTO_CC3_ENABLE_BIT : 0)); + + return ari_request_wait(ari_base, 0, TEGRA_ARI_CC3_CTRL, val, 0); +} + +int ari_reset_vector_update(uint32_t ari_base, uint32_t lo, uint32_t hi) +{ + /* + * Need to program the CPU reset vector one time during cold boot + * and SC7 exit + */ + ari_request_wait(ari_base, 0, TEGRA_ARI_COPY_MISCREG_AA64_RST, lo, hi); + + return 0; +} + +int ari_roc_flush_cache_trbits(uint32_t ari_base) +{ + return ari_request_wait(ari_base, 0, TEGRA_ARI_ROC_FLUSH_CACHE_TRBITS, + 0, 0); +} + +int ari_roc_flush_cache(uint32_t ari_base) +{ + return ari_request_wait(ari_base, 0, TEGRA_ARI_ROC_FLUSH_CACHE_ONLY, + 0, 0); +} + +int ari_roc_clean_cache(uint32_t ari_base) +{ + return ari_request_wait(ari_base, 0, TEGRA_ARI_ROC_CLEAN_CACHE_ONLY, + 0, 0); +} + +uint64_t ari_read_write_mca(uint32_t ari_base, mca_cmd_t cmd, uint64_t *data) +{ + mca_arg_t mca_arg; + int ret; + + /* Set data (write) */ + mca_arg.data = data ? *data : 0ull; + + /* Set command */ + ari_write_32(ari_base, cmd.input.low, ARI_RESPONSE_DATA_LO); + ari_write_32(ari_base, cmd.input.high, ARI_RESPONSE_DATA_HI); + + ret = ari_request_wait(ari_base, 0, TEGRA_ARI_MCA, mca_arg.arg.low, + mca_arg.arg.high); + if (!ret) { + mca_arg.arg.low = ari_get_response_low(ari_base); + mca_arg.arg.high = ari_get_response_high(ari_base); + if (!mca_arg.err.finish) + return (uint64_t)mca_arg.err.error; + + if (data) { + mca_arg.arg.low = ari_get_request_low(ari_base); + mca_arg.arg.high = ari_get_request_high(ari_base); + *data = mca_arg.data; + } + } + + return 0; +} + +int ari_update_ccplex_gsc(uint32_t ari_base, uint32_t gsc_idx) +{ + /* sanity check GSC ID */ + if (gsc_idx > TEGRA_ARI_GSC_VPR_IDX) + return EINVAL; + + /* + * The MCE code will read the GSC carveout value, corrseponding to + * the ID, from the MC registers and update the internal GSC registers + * of the CCPLEX. + */ + ari_request_wait(ari_base, 0, TEGRA_ARI_UPDATE_CCPLEX_GSC, gsc_idx, 0); + + return 0; +} + +void ari_enter_ccplex_state(uint32_t ari_base, uint32_t state_idx) +{ + /* + * The MCE will shutdown or restart the entire system + */ + (void)ari_request_wait(ari_base, 0, TEGRA_ARI_MISC_CCPLEX, state_idx, 0); +} diff --git a/plat/nvidia/tegra/soc/t186/drivers/mce/mce.c b/plat/nvidia/tegra/soc/t186/drivers/mce/mce.c new file mode 100644 index 000000000..745b6f4e5 --- /dev/null +++ b/plat/nvidia/tegra/soc/t186/drivers/mce/mce.c @@ -0,0 +1,431 @@ +/* + * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* NVG functions handlers */ +static arch_mce_ops_t nvg_mce_ops = { + .enter_cstate = nvg_enter_cstate, + .update_cstate_info = nvg_update_cstate_info, + .update_crossover_time = nvg_update_crossover_time, + .read_cstate_stats = nvg_read_cstate_stats, + .write_cstate_stats = nvg_write_cstate_stats, + .call_enum_misc = ari_enumeration_misc, + .is_ccx_allowed = nvg_is_ccx_allowed, + .is_sc7_allowed = nvg_is_sc7_allowed, + .online_core = nvg_online_core, + .cc3_ctrl = nvg_cc3_ctrl, + .update_reset_vector = ari_reset_vector_update, + .roc_flush_cache = ari_roc_flush_cache, + .roc_flush_cache_trbits = ari_roc_flush_cache_trbits, + .roc_clean_cache = ari_roc_clean_cache, + .read_write_mca = ari_read_write_mca, + .update_ccplex_gsc = ari_update_ccplex_gsc, + .enter_ccplex_state = ari_enter_ccplex_state +}; + +/* ARI functions handlers */ +static arch_mce_ops_t ari_mce_ops = { + .enter_cstate = ari_enter_cstate, + .update_cstate_info = ari_update_cstate_info, + .update_crossover_time = ari_update_crossover_time, + .read_cstate_stats = ari_read_cstate_stats, + .write_cstate_stats = ari_write_cstate_stats, + .call_enum_misc = ari_enumeration_misc, + .is_ccx_allowed = ari_is_ccx_allowed, + .is_sc7_allowed = ari_is_sc7_allowed, + .online_core = ari_online_core, + .cc3_ctrl = ari_cc3_ctrl, + .update_reset_vector = ari_reset_vector_update, + .roc_flush_cache = ari_roc_flush_cache, + .roc_flush_cache_trbits = ari_roc_flush_cache_trbits, + .roc_clean_cache = ari_roc_clean_cache, + .read_write_mca = ari_read_write_mca, + .update_ccplex_gsc = ari_update_ccplex_gsc, + .enter_ccplex_state = ari_enter_ccplex_state +}; + +typedef struct mce_config { + uint32_t ari_base; + arch_mce_ops_t *ops; +} mce_config_t; + +/* Table to hold the per-CPU ARI base address and function handlers */ +static mce_config_t mce_cfg_table[MCE_ARI_APERTURES_MAX] = { + { + /* A57 Core 0 */ + .ari_base = TEGRA_MMCRAB_BASE + MCE_ARI_APERTURE_0_OFFSET, + .ops = &ari_mce_ops, + }, + { + /* A57 Core 1 */ + .ari_base = TEGRA_MMCRAB_BASE + MCE_ARI_APERTURE_1_OFFSET, + .ops = &ari_mce_ops, + }, + { + /* A57 Core 2 */ + .ari_base = TEGRA_MMCRAB_BASE + MCE_ARI_APERTURE_2_OFFSET, + .ops = &ari_mce_ops, + }, + { + /* A57 Core 3 */ + .ari_base = TEGRA_MMCRAB_BASE + MCE_ARI_APERTURE_3_OFFSET, + .ops = &ari_mce_ops, + }, + { + /* D15 Core 0 */ + .ari_base = TEGRA_MMCRAB_BASE + MCE_ARI_APERTURE_4_OFFSET, + .ops = &nvg_mce_ops, + }, + { + /* D15 Core 1 */ + .ari_base = TEGRA_MMCRAB_BASE + MCE_ARI_APERTURE_5_OFFSET, + .ops = &nvg_mce_ops, + } +}; + +static uint32_t mce_get_curr_cpu_ari_base(void) +{ + uint32_t mpidr = read_mpidr(); + int cpuid = mpidr & MPIDR_CPU_MASK; + int impl = (read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK; + + /* + * T186 has 2 CPU clusters, one with Denver CPUs and the other with + * ARM CortexA-57 CPUs. Each cluster consists of 4 CPUs and the CPU + * numbers start from 0. In order to get the proper arch_mce_ops_t + * struct, we have to convert the Denver CPU ids to the corresponding + * indices in the mce_ops_table array. + */ + if (impl == DENVER_IMPL) + cpuid |= 0x4; + + return mce_cfg_table[cpuid].ari_base; +} + +static arch_mce_ops_t *mce_get_curr_cpu_ops(void) +{ + uint32_t mpidr = read_mpidr(); + int cpuid = mpidr & MPIDR_CPU_MASK; + int impl = (read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK; + + /* + * T186 has 2 CPU clusters, one with Denver CPUs and the other with + * ARM CortexA-57 CPUs. Each cluster consists of 4 CPUs and the CPU + * numbers start from 0. In order to get the proper arch_mce_ops_t + * struct, we have to convert the Denver CPU ids to the corresponding + * indices in the mce_ops_table array. + */ + if (impl == DENVER_IMPL) + cpuid |= 0x4; + + return mce_cfg_table[cpuid].ops; +} + +/******************************************************************************* + * Common handler for all MCE commands + ******************************************************************************/ +int mce_command_handler(mce_cmd_t cmd, uint64_t arg0, uint64_t arg1, + uint64_t arg2) +{ + arch_mce_ops_t *ops; + uint32_t cpu_ari_base; + uint64_t ret64 = 0, arg3, arg4, arg5; + int ret = 0; + mca_cmd_t mca_cmd; + cpu_context_t *ctx = cm_get_context(NON_SECURE); + gp_regs_t *gp_regs = get_gpregs_ctx(ctx); + + assert(ctx); + assert(gp_regs); + + /* get a pointer to the CPU's arch_mce_ops_t struct */ + ops = mce_get_curr_cpu_ops(); + + /* get the CPU's ARI base address */ + cpu_ari_base = mce_get_curr_cpu_ari_base(); + + switch (cmd) { + case MCE_CMD_ENTER_CSTATE: + ret = ops->enter_cstate(cpu_ari_base, arg0, arg1); + if (ret < 0) + ERROR("%s: enter_cstate failed(%d)\n", __func__, ret); + + break; + + case MCE_CMD_UPDATE_CSTATE_INFO: + /* + * get the parameters required for the update cstate info + * command + */ + arg3 = read_ctx_reg(gp_regs, CTX_GPREG_X4); + arg4 = read_ctx_reg(gp_regs, CTX_GPREG_X5); + arg5 = read_ctx_reg(gp_regs, CTX_GPREG_X6); + + ret = ops->update_cstate_info(cpu_ari_base, (uint32_t)arg0, + (uint32_t)arg1, (uint32_t)arg2, (uint8_t)arg3, + (uint32_t)arg4, (uint8_t)arg5); + if (ret < 0) + ERROR("%s: update_cstate_info failed(%d)\n", + __func__, ret); + + write_ctx_reg(gp_regs, CTX_GPREG_X4, 0); + write_ctx_reg(gp_regs, CTX_GPREG_X5, 0); + write_ctx_reg(gp_regs, CTX_GPREG_X6, 0); + + break; + + case MCE_CMD_UPDATE_CROSSOVER_TIME: + ret = ops->update_crossover_time(cpu_ari_base, arg0, arg1); + if (ret < 0) + ERROR("%s: update_crossover_time failed(%d)\n", + __func__, ret); + + break; + + case MCE_CMD_READ_CSTATE_STATS: + ret64 = ops->read_cstate_stats(cpu_ari_base, arg0); + + /* update context to return cstate stats value */ + write_ctx_reg(gp_regs, CTX_GPREG_X1, ret64); + write_ctx_reg(gp_regs, CTX_GPREG_X2, ret64); + + break; + + case MCE_CMD_WRITE_CSTATE_STATS: + ret = ops->write_cstate_stats(cpu_ari_base, arg0, arg1); + if (ret < 0) + ERROR("%s: write_cstate_stats failed(%d)\n", + __func__, ret); + + break; + + case MCE_CMD_IS_CCX_ALLOWED: + ret = ops->is_ccx_allowed(cpu_ari_base, arg0, arg1); + if (ret < 0) { + ERROR("%s: is_ccx_allowed failed(%d)\n", __func__, ret); + break; + } + + /* update context to return CCx status value */ + write_ctx_reg(gp_regs, CTX_GPREG_X1, ret); + + break; + + case MCE_CMD_IS_SC7_ALLOWED: + ret = ops->is_sc7_allowed(cpu_ari_base, arg0, arg1); + if (ret < 0) { + ERROR("%s: is_sc7_allowed failed(%d)\n", __func__, ret); + break; + } + + /* update context to return SC7 status value */ + write_ctx_reg(gp_regs, CTX_GPREG_X1, ret); + write_ctx_reg(gp_regs, CTX_GPREG_X3, ret); + + break; + + case MCE_CMD_ONLINE_CORE: + ret = ops->online_core(cpu_ari_base, arg0); + if (ret < 0) + ERROR("%s: online_core failed(%d)\n", __func__, ret); + + break; + + case MCE_CMD_CC3_CTRL: + ret = ops->cc3_ctrl(cpu_ari_base, arg0, arg1, arg2); + if (ret < 0) + ERROR("%s: cc3_ctrl failed(%d)\n", __func__, ret); + + break; + + case MCE_CMD_ECHO_DATA: + ret64 = ops->call_enum_misc(cpu_ari_base, TEGRA_ARI_MISC_ECHO, + arg0); + + /* update context to return if echo'd data matched source */ + write_ctx_reg(gp_regs, CTX_GPREG_X1, ret64 == arg0); + write_ctx_reg(gp_regs, CTX_GPREG_X2, ret64 == arg0); + + break; + + case MCE_CMD_READ_VERSIONS: + ret64 = ops->call_enum_misc(cpu_ari_base, TEGRA_ARI_MISC_VERSION, + arg0); + + /* + * version = minor(63:32) | major(31:0). Update context + * to return major and minor version number. + */ + write_ctx_reg(gp_regs, CTX_GPREG_X1, (uint32_t)ret64); + write_ctx_reg(gp_regs, CTX_GPREG_X2, (uint32_t)(ret64 >> 32)); + + break; + + case MCE_CMD_ENUM_FEATURES: + ret = ops->call_enum_misc(cpu_ari_base, + TEGRA_ARI_MISC_FEATURE_LEAF_0, arg0); + + /* update context to return features value */ + write_ctx_reg(gp_regs, CTX_GPREG_X1, ret64); + + ret = 0; + + break; + + case MCE_CMD_ROC_FLUSH_CACHE_TRBITS: + ret = ops->roc_flush_cache_trbits(cpu_ari_base); + if (ret < 0) + ERROR("%s: flush cache_trbits failed(%d)\n", __func__, + ret); + + break; + + case MCE_CMD_ROC_FLUSH_CACHE: + ret = ops->roc_flush_cache(cpu_ari_base); + if (ret < 0) + ERROR("%s: flush cache failed(%d)\n", __func__, ret); + + break; + + case MCE_CMD_ROC_CLEAN_CACHE: + ret = ops->roc_clean_cache(cpu_ari_base); + if (ret < 0) + ERROR("%s: clean cache failed(%d)\n", __func__, ret); + + break; + + case MCE_CMD_ENUM_READ_MCA: + memcpy(&mca_cmd, &arg0, sizeof(arg0)); + ret64 = ops->read_write_mca(cpu_ari_base, mca_cmd, &arg1); + + /* update context to return MCA data/error */ + write_ctx_reg(gp_regs, CTX_GPREG_X1, ret64); + write_ctx_reg(gp_regs, CTX_GPREG_X2, arg1); + write_ctx_reg(gp_regs, CTX_GPREG_X3, ret64); + + break; + + case MCE_CMD_ENUM_WRITE_MCA: + memcpy(&mca_cmd, &arg0, sizeof(arg0)); + ret64 = ops->read_write_mca(cpu_ari_base, mca_cmd, &arg1); + + /* update context to return MCA error */ + write_ctx_reg(gp_regs, CTX_GPREG_X1, ret64); + write_ctx_reg(gp_regs, CTX_GPREG_X3, ret64); + + break; + + default: + ERROR("unknown MCE command (%d)\n", cmd); + return EINVAL; + } + + return ret; +} + +/******************************************************************************* + * Handler to update the reset vector for CPUs + ******************************************************************************/ +int mce_update_reset_vector(uint32_t addr_lo, uint32_t addr_hi) +{ + arch_mce_ops_t *ops = mce_get_curr_cpu_ops(); + + ops->update_reset_vector(mce_get_curr_cpu_ari_base(), addr_lo, addr_hi); + + return 0; +} + +static int mce_update_ccplex_gsc(tegra_ari_gsc_index_t gsc_idx) +{ + arch_mce_ops_t *ops = mce_get_curr_cpu_ops(); + + ops->update_ccplex_gsc(mce_get_curr_cpu_ari_base(), gsc_idx); + + return 0; +} + +/******************************************************************************* + * Handler to update carveout values for Video Memory Carveout region + ******************************************************************************/ +int mce_update_gsc_videomem(void) +{ + return mce_update_ccplex_gsc(TEGRA_ARI_GSC_VPR_IDX); +} + +/******************************************************************************* + * Handler to update carveout values for TZDRAM aperture + ******************************************************************************/ +int mce_update_gsc_tzdram(void) +{ + return mce_update_ccplex_gsc(TEGRA_ARI_GSC_TZ_DRAM_IDX); +} + +/******************************************************************************* + * Handler to update carveout values for TZ SysRAM aperture + ******************************************************************************/ +int mce_update_gsc_tzram(void) +{ + return mce_update_ccplex_gsc(TEGRA_ARI_GSC_TZRAM); +} + +/******************************************************************************* + * Handler to shutdown/reset the entire system + ******************************************************************************/ +__dead2 void mce_enter_ccplex_state(uint32_t state_idx) +{ + arch_mce_ops_t *ops = mce_get_curr_cpu_ops(); + + /* sanity check state value */ + if (state_idx != TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_POWER_OFF && + state_idx != TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_REBOOT) + panic(); + + ops->enter_ccplex_state(mce_get_curr_cpu_ari_base(), state_idx); + + /* wait till the CCPLEX powers down */ + for (;;) + ; + + panic(); +} diff --git a/plat/nvidia/tegra/soc/t186/drivers/mce/nvg.c b/plat/nvidia/tegra/soc/t186/drivers/mce/nvg.c new file mode 100644 index 000000000..25479a24b --- /dev/null +++ b/plat/nvidia/tegra/soc/t186/drivers/mce/nvg.c @@ -0,0 +1,239 @@ +/* + * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +extern void nvg_set_request_data(uint64_t req, uint64_t data); +extern void nvg_set_request(uint64_t req); +extern uint64_t nvg_get_result(void); + +int nvg_enter_cstate(uint32_t ari_base, uint32_t state, uint32_t wake_time) +{ + /* check for allowed power state */ + if (state != TEGRA_ARI_CORE_C0 && state != TEGRA_ARI_CORE_C1 && + state != TEGRA_ARI_CORE_C6 && state != TEGRA_ARI_CORE_C7) { + ERROR("%s: unknown cstate (%d)\n", __func__, state); + return EINVAL; + } + + /* time (TSC ticks) until the core is expected to get a wake event */ + nvg_set_request_data(TEGRA_NVG_CHANNEL_WAKE_TIME, wake_time); + + /* set the core cstate */ + write_actlr_el1(state); + + return 0; +} + +/* + * This request allows updating of CLUSTER_CSTATE, CCPLEX_CSTATE and + * SYSTEM_CSTATE values. + */ +int nvg_update_cstate_info(uint32_t ari_base, uint32_t cluster, uint32_t ccplex, + uint32_t system, uint8_t sys_state_force, uint32_t wake_mask, + uint8_t update_wake_mask) +{ + uint64_t val = 0; + + /* update CLUSTER_CSTATE? */ + if (cluster) + val |= (cluster & CLUSTER_CSTATE_MASK) | + CLUSTER_CSTATE_UPDATE_BIT; + + /* update CCPLEX_CSTATE? */ + if (ccplex) + val |= (ccplex & CCPLEX_CSTATE_MASK) << CCPLEX_CSTATE_SHIFT | + CCPLEX_CSTATE_UPDATE_BIT; + + /* update SYSTEM_CSTATE? */ + if (system) + val |= ((system & SYSTEM_CSTATE_MASK) << SYSTEM_CSTATE_SHIFT) | + ((sys_state_force << SYSTEM_CSTATE_FORCE_UPDATE_SHIFT) | + SYSTEM_CSTATE_UPDATE_BIT); + + /* update wake mask value? */ + if (update_wake_mask) + val |= CSTATE_WAKE_MASK_UPDATE_BIT; + + /* set the wake mask */ + val &= CSTATE_WAKE_MASK_CLEAR; + val |= ((uint64_t)wake_mask << CSTATE_WAKE_MASK_SHIFT); + + /* set the updated cstate info */ + nvg_set_request_data(TEGRA_NVG_CHANNEL_CSTATE_INFO, val); + + return 0; +} + +int nvg_update_crossover_time(uint32_t ari_base, uint32_t type, uint32_t time) +{ + /* sanity check crossover type */ + if (type > TEGRA_ARI_CROSSOVER_CCP3_SC1) + return EINVAL; + + /* + * The crossover threshold limit types start from + * TEGRA_CROSSOVER_TYPE_C1_C6 to TEGRA_CROSSOVER_TYPE_CCP3_SC7. The + * command indices for updating the threshold can be generated + * by adding the type to the NVG_SET_THRESHOLD_CROSSOVER_C1_C6 + * command index. + */ + nvg_set_request_data(TEGRA_NVG_CHANNEL_CROSSOVER_C1_C6 + type, + (uint64_t)time); + + return 0; +} + +uint64_t nvg_read_cstate_stats(uint32_t ari_base, uint32_t state) +{ + /* sanity check state */ + if (state == 0) + return EINVAL; + + /* + * The cstate types start from NVG_READ_CSTATE_STATS_SC7_ENTRIES + * to NVG_GET_LAST_CSTATE_ENTRY_A57_3. The command indices for + * reading the threshold can be generated by adding the type to + * the NVG_CLEAR_CSTATE_STATS command index. + */ + nvg_set_request(TEGRA_NVG_CHANNEL_CSTATE_STATS_CLEAR + state); + + return (int64_t)nvg_get_result(); +} + +int nvg_write_cstate_stats(uint32_t ari_base, uint32_t state, uint32_t stats) +{ + uint64_t val; + + /* + * The only difference between a CSTATE_STATS_WRITE and + * CSTATE_STATS_READ is the usage of the 63:32 in the request. + * 63:32 are set to '0' for a read, while a write contains the + * actual stats value to be written. + */ + val = ((uint64_t)stats << MCE_CSTATE_STATS_TYPE_SHIFT) | state; + + /* + * The cstate types start from NVG_READ_CSTATE_STATS_SC7_ENTRIES + * to NVG_GET_LAST_CSTATE_ENTRY_A57_3. The command indices for + * reading the threshold can be generated by adding the type to + * the NVG_CLEAR_CSTATE_STATS command index. + */ + nvg_set_request_data(TEGRA_NVG_CHANNEL_CSTATE_STATS_CLEAR + state, val); + + return 0; +} + +int nvg_is_ccx_allowed(uint32_t ari_base, uint32_t state, uint32_t wake_time) +{ + /* This does not apply to the Denver cluster */ + return 0; +} + +int nvg_is_sc7_allowed(uint32_t ari_base, uint32_t state, uint32_t wake_time) +{ + uint64_t val; + + /* check for allowed power state */ + if (state != TEGRA_ARI_CORE_C0 && state != TEGRA_ARI_CORE_C1 && + state != TEGRA_ARI_CORE_C6 && state != TEGRA_ARI_CORE_C7) { + ERROR("%s: unknown cstate (%d)\n", __func__, state); + return EINVAL; + } + + /* + * Request format - + * 63:32 = wake time + * 31:0 = C-state for this core + */ + val = ((uint64_t)wake_time << MCE_SC7_WAKE_TIME_SHIFT) | + (state & MCE_SC7_ALLOWED_MASK); + + /* issue command to check if SC7 is allowed */ + nvg_set_request_data(TEGRA_NVG_CHANNEL_IS_SC7_ALLOWED, val); + + /* 1 = SC7 allowed, 0 = SC7 not allowed */ + return !!nvg_get_result(); +} + +int nvg_online_core(uint32_t ari_base, uint32_t core) +{ + int cpu = read_mpidr() & MPIDR_CPU_MASK; + int impl = (read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK; + + /* sanity check code id */ + if ((core >= MCE_CORE_ID_MAX) || (cpu == core)) { + ERROR("%s: unsupported core id (%d)\n", __func__, core); + return EINVAL; + } + + /* + * The Denver cluster has 2 CPUs only - 0, 1. + */ + if (impl == DENVER_IMPL && ((core == 2) || (core == 3))) { + ERROR("%s: unknown core id (%d)\n", __func__, core); + return EINVAL; + } + + /* get a core online */ + nvg_set_request_data(TEGRA_NVG_CHANNEL_ONLINE_CORE, core & MCE_CORE_ID_MASK); + + return 0; +} + +int nvg_cc3_ctrl(uint32_t ari_base, uint32_t freq, uint32_t volt, uint8_t enable) +{ + int val; + + /* + * If the enable bit is cleared, Auto-CC3 will be disabled by setting + * the SW visible voltage/frequency request registers for all non + * floorswept cores valid independent of StandbyWFI and disabling + * the IDLE voltage/frequency request register. If set, Auto-CC3 + * will be enabled by setting the ARM SW visible voltage/frequency + * request registers for all non floorswept cores to be enabled by + * StandbyWFI or the equivalent signal, and always keeping the IDLE + * voltage/frequency request register enabled. + */ + val = (((freq & MCE_AUTO_CC3_FREQ_MASK) << MCE_AUTO_CC3_FREQ_SHIFT) |\ + ((volt & MCE_AUTO_CC3_VTG_MASK) << MCE_AUTO_CC3_VTG_SHIFT) |\ + (enable ? MCE_AUTO_CC3_ENABLE_BIT : 0)); + + nvg_set_request_data(TEGRA_NVG_CHANNEL_CC3_CTRL, val); + + return 0; +} diff --git a/plat/nvidia/tegra/soc/t186/drivers/smmu/smmu.c b/plat/nvidia/tegra/soc/t186/drivers/smmu/smmu.c new file mode 100644 index 000000000..2940f5837 --- /dev/null +++ b/plat/nvidia/tegra/soc/t186/drivers/smmu/smmu.c @@ -0,0 +1,466 @@ +/* + * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include + +typedef struct smmu_regs { + uint32_t reg; + uint32_t val; +} smmu_regs_t; + +#define mc_make_sid_override_cfg(name) \ + { \ + .reg = TEGRA_MC_STREAMID_BASE + MC_STREAMID_OVERRIDE_CFG_ ## name, \ + .val = 0x00000000, \ + } + +#define mc_make_sid_security_cfg(name) \ + { \ + .reg = TEGRA_MC_STREAMID_BASE + MC_STREAMID_SECURITY_CFG_ ## name, \ + .val = 0x00000000, \ + } + +#define smmu_make_gnsr0_sec_cfg(name) \ + { \ + .reg = TEGRA_SMMU_BASE + SMMU_GNSR0_ ## name, \ + .val = 0x00000000, \ + } + +/* + * On ARM-SMMU, conditional offset to access secure aliases of non-secure registers + * is 0x400. So, add it to register address + */ +#define smmu_make_gnsr0_nsec_cfg(name) \ + { \ + .reg = TEGRA_SMMU_BASE + 0x400 + SMMU_GNSR0_ ## name, \ + .val = 0x00000000, \ + } + +#define smmu_make_gnsr0_smr_cfg(n) \ + { \ + .reg = TEGRA_SMMU_BASE + SMMU_GNSR0_SMR ## n, \ + .val = 0x00000000, \ + } + +#define smmu_make_gnsr0_s2cr_cfg(n) \ + { \ + .reg = TEGRA_SMMU_BASE + SMMU_GNSR0_S2CR ## n, \ + .val = 0x00000000, \ + } + +#define smmu_make_gnsr1_cbar_cfg(n) \ + { \ + .reg = TEGRA_SMMU_BASE + (1 << PGSHIFT) + SMMU_GNSR1_CBAR ## n, \ + .val = 0x00000000, \ + } + +#define smmu_make_gnsr1_cba2r_cfg(n) \ + { \ + .reg = TEGRA_SMMU_BASE + (1 << PGSHIFT) + SMMU_GNSR1_CBA2R ## n, \ + .val = 0x00000000, \ + } + +#define make_smmu_cb_cfg(name, n) \ + { \ + .reg = TEGRA_SMMU_BASE + (CB_SIZE >> 1) + (n * (1 << PGSHIFT)) \ + + SMMU_CBn_ ## name, \ + .val = 0x00000000, \ + } + +#define smmu_make_smrg_group(n) \ + smmu_make_gnsr0_smr_cfg(n), \ + smmu_make_gnsr0_s2cr_cfg(n), \ + smmu_make_gnsr1_cbar_cfg(n), \ + smmu_make_gnsr1_cba2r_cfg(n) /* don't put "," here. */ + +#define smmu_make_cb_group(n) \ + make_smmu_cb_cfg(SCTLR, n), \ + make_smmu_cb_cfg(TCR2, n), \ + make_smmu_cb_cfg(TTBR0_LO, n), \ + make_smmu_cb_cfg(TTBR0_HI, n), \ + make_smmu_cb_cfg(TCR, n), \ + make_smmu_cb_cfg(PRRR_MAIR0, n),\ + make_smmu_cb_cfg(FSR, n), \ + make_smmu_cb_cfg(FAR_LO, n), \ + make_smmu_cb_cfg(FAR_HI, n), \ + make_smmu_cb_cfg(FSYNR0, n) /* don't put "," here. */ + +#define smmu_bypass_cfg \ + { \ + .reg = TEGRA_MC_BASE + MC_SMMU_BYPASS_CONFIG, \ + .val = 0x00000000, \ + } + +#define _START_OF_TABLE_ \ + { \ + .reg = 0xCAFE05C7, \ + .val = 0x00000000, \ + } + +#define _END_OF_TABLE_ \ + { \ + .reg = 0xFFFFFFFF, \ + .val = 0xFFFFFFFF, \ + } + +static smmu_regs_t smmu_ctx_regs[] = { + _START_OF_TABLE_, + mc_make_sid_security_cfg(SCEW), + mc_make_sid_security_cfg(AFIR), + mc_make_sid_security_cfg(NVDISPLAYR1), + mc_make_sid_security_cfg(XUSB_DEVR), + mc_make_sid_security_cfg(VICSRD1), + mc_make_sid_security_cfg(NVENCSWR), + mc_make_sid_security_cfg(TSECSRDB), + mc_make_sid_security_cfg(AXISW), + mc_make_sid_security_cfg(SDMMCWAB), + mc_make_sid_security_cfg(AONDMAW), + mc_make_sid_security_cfg(GPUSWR2), + mc_make_sid_security_cfg(SATAW), + mc_make_sid_security_cfg(UFSHCW), + mc_make_sid_security_cfg(AFIW), + mc_make_sid_security_cfg(SDMMCR), + mc_make_sid_security_cfg(SCEDMAW), + mc_make_sid_security_cfg(UFSHCR), + mc_make_sid_security_cfg(SDMMCWAA), + mc_make_sid_security_cfg(APEDMAW), + mc_make_sid_security_cfg(SESWR), + mc_make_sid_security_cfg(MPCORER), + mc_make_sid_security_cfg(PTCR), + mc_make_sid_security_cfg(BPMPW), + mc_make_sid_security_cfg(ETRW), + mc_make_sid_security_cfg(GPUSRD), + mc_make_sid_security_cfg(VICSWR), + mc_make_sid_security_cfg(SCEDMAR), + mc_make_sid_security_cfg(HDAW), + mc_make_sid_security_cfg(ISPWA), + mc_make_sid_security_cfg(EQOSW), + mc_make_sid_security_cfg(XUSB_HOSTW), + mc_make_sid_security_cfg(TSECSWR), + mc_make_sid_security_cfg(SDMMCRAA), + mc_make_sid_security_cfg(APER), + mc_make_sid_security_cfg(VIW), + mc_make_sid_security_cfg(APEW), + mc_make_sid_security_cfg(AXISR), + mc_make_sid_security_cfg(SDMMCW), + mc_make_sid_security_cfg(BPMPDMAW), + mc_make_sid_security_cfg(ISPRA), + mc_make_sid_security_cfg(NVDECSWR), + mc_make_sid_security_cfg(XUSB_DEVW), + mc_make_sid_security_cfg(NVDECSRD), + mc_make_sid_security_cfg(MPCOREW), + mc_make_sid_security_cfg(NVDISPLAYR), + mc_make_sid_security_cfg(BPMPDMAR), + mc_make_sid_security_cfg(NVJPGSWR), + mc_make_sid_security_cfg(NVDECSRD1), + mc_make_sid_security_cfg(TSECSRD), + mc_make_sid_security_cfg(NVJPGSRD), + mc_make_sid_security_cfg(SDMMCWA), + mc_make_sid_security_cfg(SCER), + mc_make_sid_security_cfg(XUSB_HOSTR), + mc_make_sid_security_cfg(VICSRD), + mc_make_sid_security_cfg(AONDMAR), + mc_make_sid_security_cfg(AONW), + mc_make_sid_security_cfg(SDMMCRA), + mc_make_sid_security_cfg(HOST1XDMAR), + mc_make_sid_security_cfg(EQOSR), + mc_make_sid_security_cfg(SATAR), + mc_make_sid_security_cfg(BPMPR), + mc_make_sid_security_cfg(HDAR), + mc_make_sid_security_cfg(SDMMCRAB), + mc_make_sid_security_cfg(ETRR), + mc_make_sid_security_cfg(AONR), + mc_make_sid_security_cfg(APEDMAR), + mc_make_sid_security_cfg(SESRD), + mc_make_sid_security_cfg(NVENCSRD), + mc_make_sid_security_cfg(GPUSWR), + mc_make_sid_security_cfg(TSECSWRB), + mc_make_sid_security_cfg(ISPWB), + mc_make_sid_security_cfg(GPUSRD2), + mc_make_sid_override_cfg(APER), + mc_make_sid_override_cfg(VICSRD), + mc_make_sid_override_cfg(NVENCSRD), + mc_make_sid_override_cfg(NVJPGSWR), + mc_make_sid_override_cfg(AONW), + mc_make_sid_override_cfg(BPMPR), + mc_make_sid_override_cfg(BPMPW), + mc_make_sid_override_cfg(HDAW), + mc_make_sid_override_cfg(NVDISPLAYR1), + mc_make_sid_override_cfg(APEDMAR), + mc_make_sid_override_cfg(AFIR), + mc_make_sid_override_cfg(AXISR), + mc_make_sid_override_cfg(VICSRD1), + mc_make_sid_override_cfg(TSECSRD), + mc_make_sid_override_cfg(BPMPDMAW), + mc_make_sid_override_cfg(MPCOREW), + mc_make_sid_override_cfg(XUSB_HOSTR), + mc_make_sid_override_cfg(GPUSWR), + mc_make_sid_override_cfg(XUSB_DEVR), + mc_make_sid_override_cfg(UFSHCW), + mc_make_sid_override_cfg(XUSB_HOSTW), + mc_make_sid_override_cfg(SDMMCWAB), + mc_make_sid_override_cfg(SATAW), + mc_make_sid_override_cfg(SCEDMAR), + mc_make_sid_override_cfg(HOST1XDMAR), + mc_make_sid_override_cfg(SDMMCWA), + mc_make_sid_override_cfg(APEDMAW), + mc_make_sid_override_cfg(SESWR), + mc_make_sid_override_cfg(AXISW), + mc_make_sid_override_cfg(AONDMAW), + mc_make_sid_override_cfg(TSECSWRB), + mc_make_sid_override_cfg(MPCORER), + mc_make_sid_override_cfg(ISPWB), + mc_make_sid_override_cfg(AONR), + mc_make_sid_override_cfg(BPMPDMAR), + mc_make_sid_override_cfg(HDAR), + mc_make_sid_override_cfg(SDMMCRA), + mc_make_sid_override_cfg(ETRW), + mc_make_sid_override_cfg(GPUSWR2), + mc_make_sid_override_cfg(EQOSR), + mc_make_sid_override_cfg(TSECSWR), + mc_make_sid_override_cfg(ETRR), + mc_make_sid_override_cfg(NVDECSRD), + mc_make_sid_override_cfg(TSECSRDB), + mc_make_sid_override_cfg(SDMMCRAA), + mc_make_sid_override_cfg(NVDECSRD1), + mc_make_sid_override_cfg(SDMMCR), + mc_make_sid_override_cfg(NVJPGSRD), + mc_make_sid_override_cfg(SCEDMAW), + mc_make_sid_override_cfg(SDMMCWAA), + mc_make_sid_override_cfg(APEW), + mc_make_sid_override_cfg(AONDMAR), + mc_make_sid_override_cfg(PTCR), + mc_make_sid_override_cfg(SCER), + mc_make_sid_override_cfg(ISPRA), + mc_make_sid_override_cfg(ISPWA), + mc_make_sid_override_cfg(VICSWR), + mc_make_sid_override_cfg(SESRD), + mc_make_sid_override_cfg(SDMMCW), + mc_make_sid_override_cfg(SDMMCRAB), + mc_make_sid_override_cfg(EQOSW), + mc_make_sid_override_cfg(GPUSRD2), + mc_make_sid_override_cfg(SCEW), + mc_make_sid_override_cfg(GPUSRD), + mc_make_sid_override_cfg(NVDECSWR), + mc_make_sid_override_cfg(XUSB_DEVW), + mc_make_sid_override_cfg(SATAR), + mc_make_sid_override_cfg(NVDISPLAYR), + mc_make_sid_override_cfg(VIW), + mc_make_sid_override_cfg(UFSHCR), + mc_make_sid_override_cfg(NVENCSWR), + mc_make_sid_override_cfg(AFIW), + smmu_make_gnsr0_nsec_cfg(CR0), + smmu_make_gnsr0_sec_cfg(IDR0), + smmu_make_gnsr0_sec_cfg(IDR1), + smmu_make_gnsr0_sec_cfg(IDR2), + smmu_make_gnsr0_nsec_cfg(GFSR), + smmu_make_gnsr0_nsec_cfg(GFSYNR0), + smmu_make_gnsr0_nsec_cfg(GFSYNR1), + smmu_make_gnsr0_nsec_cfg(TLBGSTATUS), + smmu_make_gnsr0_nsec_cfg(PIDR2), + smmu_make_smrg_group(0), + smmu_make_smrg_group(1), + smmu_make_smrg_group(2), + smmu_make_smrg_group(3), + smmu_make_smrg_group(4), + smmu_make_smrg_group(5), + smmu_make_smrg_group(6), + smmu_make_smrg_group(7), + smmu_make_smrg_group(8), + smmu_make_smrg_group(9), + smmu_make_smrg_group(10), + smmu_make_smrg_group(11), + smmu_make_smrg_group(12), + smmu_make_smrg_group(13), + smmu_make_smrg_group(14), + smmu_make_smrg_group(15), + smmu_make_smrg_group(16), + smmu_make_smrg_group(17), + smmu_make_smrg_group(18), + smmu_make_smrg_group(19), + smmu_make_smrg_group(20), + smmu_make_smrg_group(21), + smmu_make_smrg_group(22), + smmu_make_smrg_group(23), + smmu_make_smrg_group(24), + smmu_make_smrg_group(25), + smmu_make_smrg_group(26), + smmu_make_smrg_group(27), + smmu_make_smrg_group(28), + smmu_make_smrg_group(29), + smmu_make_smrg_group(30), + smmu_make_smrg_group(31), + smmu_make_smrg_group(32), + smmu_make_smrg_group(33), + smmu_make_smrg_group(34), + smmu_make_smrg_group(35), + smmu_make_smrg_group(36), + smmu_make_smrg_group(37), + smmu_make_smrg_group(38), + smmu_make_smrg_group(39), + smmu_make_smrg_group(40), + smmu_make_smrg_group(41), + smmu_make_smrg_group(42), + smmu_make_smrg_group(43), + smmu_make_smrg_group(44), + smmu_make_smrg_group(45), + smmu_make_smrg_group(46), + smmu_make_smrg_group(47), + smmu_make_smrg_group(48), + smmu_make_smrg_group(49), + smmu_make_smrg_group(50), + smmu_make_smrg_group(51), + smmu_make_smrg_group(52), + smmu_make_smrg_group(53), + smmu_make_smrg_group(54), + smmu_make_smrg_group(55), + smmu_make_smrg_group(56), + smmu_make_smrg_group(57), + smmu_make_smrg_group(58), + smmu_make_smrg_group(59), + smmu_make_smrg_group(60), + smmu_make_smrg_group(61), + smmu_make_smrg_group(62), + smmu_make_smrg_group(63), + smmu_make_cb_group(0), + smmu_make_cb_group(1), + smmu_make_cb_group(2), + smmu_make_cb_group(3), + smmu_make_cb_group(4), + smmu_make_cb_group(5), + smmu_make_cb_group(6), + smmu_make_cb_group(7), + smmu_make_cb_group(8), + smmu_make_cb_group(9), + smmu_make_cb_group(10), + smmu_make_cb_group(11), + smmu_make_cb_group(12), + smmu_make_cb_group(13), + smmu_make_cb_group(14), + smmu_make_cb_group(15), + smmu_make_cb_group(16), + smmu_make_cb_group(17), + smmu_make_cb_group(18), + smmu_make_cb_group(19), + smmu_make_cb_group(20), + smmu_make_cb_group(21), + smmu_make_cb_group(22), + smmu_make_cb_group(23), + smmu_make_cb_group(24), + smmu_make_cb_group(25), + smmu_make_cb_group(26), + smmu_make_cb_group(27), + smmu_make_cb_group(28), + smmu_make_cb_group(29), + smmu_make_cb_group(30), + smmu_make_cb_group(31), + smmu_make_cb_group(32), + smmu_make_cb_group(33), + smmu_make_cb_group(34), + smmu_make_cb_group(35), + smmu_make_cb_group(36), + smmu_make_cb_group(37), + smmu_make_cb_group(38), + smmu_make_cb_group(39), + smmu_make_cb_group(40), + smmu_make_cb_group(41), + smmu_make_cb_group(42), + smmu_make_cb_group(43), + smmu_make_cb_group(44), + smmu_make_cb_group(45), + smmu_make_cb_group(46), + smmu_make_cb_group(47), + smmu_make_cb_group(48), + smmu_make_cb_group(49), + smmu_make_cb_group(50), + smmu_make_cb_group(51), + smmu_make_cb_group(52), + smmu_make_cb_group(53), + smmu_make_cb_group(54), + smmu_make_cb_group(55), + smmu_make_cb_group(56), + smmu_make_cb_group(57), + smmu_make_cb_group(58), + smmu_make_cb_group(59), + smmu_make_cb_group(60), + smmu_make_cb_group(61), + smmu_make_cb_group(62), + smmu_make_cb_group(63), + smmu_bypass_cfg, /* TBU settings */ + _END_OF_TABLE_, +}; + +/* + * Save SMMU settings before "System Suspend" + */ +void tegra_smmu_save_context(void) +{ + uint32_t i; +#if DEBUG + uint32_t reg_id1, pgshift, cb_size; + + /* sanity check SMMU settings c*/ + reg_id1 = mmio_read_32((TEGRA_SMMU_BASE + SMMU_GNSR0_IDR1)); + pgshift = (reg_id1 & ID1_PAGESIZE) ? 16 : 12; + cb_size = (2 << pgshift) * \ + (1 << (((reg_id1 >> ID1_NUMPAGENDXB_SHIFT) & ID1_NUMPAGENDXB_MASK) + 1)); + + assert(!((pgshift != PGSHIFT) || (cb_size != CB_SIZE))); +#endif + + /* index of _END_OF_TABLE_ */ + smmu_ctx_regs[0].val = ARRAY_SIZE(smmu_ctx_regs) - 1; + + /* save SMMU register values */ + for (i = 1; i < ARRAY_SIZE(smmu_ctx_regs) - 1; i++) + smmu_ctx_regs[i].val = mmio_read_32(smmu_ctx_regs[i].reg); + + /* save the SMMU table address */ + mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV11_LO, + (uint32_t)(unsigned long)smmu_ctx_regs); + mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV11_HI, + (uint32_t)(((unsigned long)smmu_ctx_regs) >> 32)); +} + +/* + * Init SMMU during boot or "System Suspend" exit + */ +void tegra_smmu_init(void) +{ + uint32_t val; + + /* Program the SMMU pagesize */ + val = tegra_smmu_read_32(SMMU_GSR0_SECURE_ACR); + val |= SMMU_GSR0_PGSIZE_64K; + tegra_smmu_write_32(SMMU_GSR0_SECURE_ACR, val); +} diff --git a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c new file mode 100644 index 000000000..7e35cc6b2 --- /dev/null +++ b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c @@ -0,0 +1,295 @@ +/* + * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern void prepare_cpu_pwr_dwn(void); + +/* state id mask */ +#define TEGRA186_STATE_ID_MASK 0xF +/* constants to get power state's wake time */ +#define TEGRA186_WAKE_TIME_MASK 0xFFFFFF +#define TEGRA186_WAKE_TIME_SHIFT 4 +/* context size to save during system suspend */ +#define TEGRA186_SE_CONTEXT_SIZE 3 + +static uint32_t se_regs[TEGRA186_SE_CONTEXT_SIZE]; +static unsigned int wake_time[PLATFORM_CORE_COUNT]; + +/* System power down state */ +uint32_t tegra186_system_powerdn_state = TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_POWER_OFF; + +int32_t tegra_soc_validate_power_state(unsigned int power_state, + psci_power_state_t *req_state) +{ + int state_id = psci_get_pstate_id(power_state) & TEGRA186_STATE_ID_MASK; + int cpu = read_mpidr() & MPIDR_CPU_MASK; + int impl = (read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK; + + if (impl == DENVER_IMPL) + cpu |= 0x4; + + wake_time[cpu] = (power_state >> TEGRA186_WAKE_TIME_SHIFT) & + TEGRA186_WAKE_TIME_MASK; + + /* Sanity check the requested state id */ + switch (state_id) { + case PSTATE_ID_CORE_IDLE: + case PSTATE_ID_CORE_POWERDN: + /* + * Core powerdown request only for afflvl 0 + */ + req_state->pwr_domain_state[MPIDR_AFFLVL0] = state_id; + + break; + + default: + ERROR("%s: unsupported state id (%d)\n", __func__, state_id); + return PSCI_E_INVALID_PARAMS; + } + + return PSCI_E_SUCCESS; +} + +int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state) +{ + const plat_local_state_t *pwr_domain_state; + unsigned int stateid_afflvl0, stateid_afflvl2; + int cpu = read_mpidr() & MPIDR_CPU_MASK; + int impl = (read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK; + cpu_context_t *ctx = cm_get_context(NON_SECURE); + gp_regs_t *gp_regs = get_gpregs_ctx(ctx); + uint32_t val; + + assert(ctx); + assert(gp_regs); + + if (impl == DENVER_IMPL) + cpu |= 0x4; + + /* get the state ID */ + pwr_domain_state = target_state->pwr_domain_state; + stateid_afflvl0 = pwr_domain_state[MPIDR_AFFLVL0] & + TEGRA186_STATE_ID_MASK; + stateid_afflvl2 = pwr_domain_state[PLAT_MAX_PWR_LVL] & + TEGRA186_STATE_ID_MASK; + + if (stateid_afflvl0 == PSTATE_ID_CORE_IDLE) { + + /* Prepare for cpu idle */ + (void)mce_command_handler(MCE_CMD_ENTER_CSTATE, + TEGRA_ARI_CORE_C6, wake_time[cpu], 0); + + } else if (stateid_afflvl0 == PSTATE_ID_CORE_POWERDN) { + + /* Prepare for cpu powerdn */ + (void)mce_command_handler(MCE_CMD_ENTER_CSTATE, + TEGRA_ARI_CORE_C7, wake_time[cpu], 0); + + } else if (stateid_afflvl2 == PSTATE_ID_SOC_POWERDN) { + + /* loop until SC7 is allowed */ + do { + val = mce_command_handler(MCE_CMD_IS_SC7_ALLOWED, + TEGRA_ARI_CORE_C7, + MCE_CORE_SLEEP_TIME_INFINITE, + 0); + } while (val == 0); + + /* save SE registers */ + se_regs[0] = mmio_read_32(TEGRA_SE0_BASE + + SE_MUTEX_WATCHDOG_NS_LIMIT); + se_regs[1] = mmio_read_32(TEGRA_RNG1_BASE + + RNG_MUTEX_WATCHDOG_NS_LIMIT); + se_regs[2] = mmio_read_32(TEGRA_PKA1_BASE + + PKA_MUTEX_WATCHDOG_NS_LIMIT); + + /* 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); + + /* save SMMU context */ + tegra_smmu_save_context(); + + /* Prepare for system suspend */ + write_ctx_reg(gp_regs, CTX_GPREG_X4, 1); + write_ctx_reg(gp_regs, CTX_GPREG_X5, 0); + write_ctx_reg(gp_regs, CTX_GPREG_X6, 1); + (void)mce_command_handler(MCE_CMD_UPDATE_CSTATE_INFO, + TEGRA_ARI_CLUSTER_CC7, 0, TEGRA_ARI_SYSTEM_SC7); + + /* Enter system suspend state */ + (void)mce_command_handler(MCE_CMD_ENTER_CSTATE, + TEGRA_ARI_CORE_C7, MCE_CORE_SLEEP_TIME_INFINITE, 0); + + } else { + ERROR("%s: Unknown state id\n", __func__); + return PSCI_E_NOT_SUPPORTED; + } + + return PSCI_E_SUCCESS; +} + +int tegra_soc_pwr_domain_on(u_register_t mpidr) +{ + int target_cpu = mpidr & MPIDR_CPU_MASK; + int target_cluster = (mpidr & MPIDR_CLUSTER_MASK) >> + MPIDR_AFFINITY_BITS; + + if (target_cluster > MPIDR_AFFLVL1) { + ERROR("%s: unsupported CPU (0x%lx)\n", __func__, mpidr); + return PSCI_E_NOT_PRESENT; + } + + /* construct the target CPU # */ + target_cpu |= (target_cluster << 2); + + mce_command_handler(MCE_CMD_ONLINE_CORE, target_cpu, 0, 0); + + return PSCI_E_SUCCESS; +} + +int tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state) +{ + int state_id = target_state->pwr_domain_state[PLAT_MAX_PWR_LVL]; + + /* + * Check if we are exiting from deep sleep and restore SE + * context if we are. + */ + if (state_id == PSTATE_ID_SOC_POWERDN) { + mmio_write_32(TEGRA_SE0_BASE + SE_MUTEX_WATCHDOG_NS_LIMIT, + se_regs[0]); + mmio_write_32(TEGRA_RNG1_BASE + RNG_MUTEX_WATCHDOG_NS_LIMIT, + se_regs[1]); + mmio_write_32(TEGRA_PKA1_BASE + PKA_MUTEX_WATCHDOG_NS_LIMIT, + se_regs[2]); + + /* Init SMMU */ + tegra_smmu_init(); + } + + return PSCI_E_SUCCESS; +} + +int tegra_soc_pwr_domain_off(const psci_power_state_t *target_state) +{ + cpu_context_t *ctx = cm_get_context(NON_SECURE); + gp_regs_t *gp_regs = get_gpregs_ctx(ctx); + int impl = (read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK; + + assert(ctx); + assert(gp_regs); + + /* Turn off wake_mask */ + write_ctx_reg(gp_regs, CTX_GPREG_X4, 0); + write_ctx_reg(gp_regs, CTX_GPREG_X5, 0); + write_ctx_reg(gp_regs, CTX_GPREG_X6, 1); + mce_command_handler(MCE_CMD_UPDATE_CSTATE_INFO, TEGRA_ARI_CLUSTER_CC7, + 0, TEGRA_ARI_SYSTEM_SC7); + + /* Disable Denver's DCO operations */ + if (impl == DENVER_IMPL) + denver_disable_dco(); + + /* Turn off CPU */ + return mce_command_handler(MCE_CMD_ENTER_CSTATE, TEGRA_ARI_CORE_C7, + MCE_CORE_SLEEP_TIME_INFINITE, 0); +} + +__dead2 void tegra_soc_prepare_system_off(void) +{ + cpu_context_t *ctx = cm_get_context(NON_SECURE); + gp_regs_t *gp_regs = get_gpregs_ctx(ctx); + uint32_t val; + + if (tegra186_system_powerdn_state == TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_POWER_OFF) { + + /* power off the entire system */ + mce_enter_ccplex_state(tegra186_system_powerdn_state); + + } else if (tegra186_system_powerdn_state == TEGRA_ARI_SYSTEM_SC8) { + + /* loop until other CPUs power down */ + do { + val = mce_command_handler(MCE_CMD_IS_SC7_ALLOWED, + TEGRA_ARI_CORE_C7, + MCE_CORE_SLEEP_TIME_INFINITE, + 0); + } while (val == 0); + + /* Prepare for quasi power down */ + write_ctx_reg(gp_regs, CTX_GPREG_X4, 1); + write_ctx_reg(gp_regs, CTX_GPREG_X5, 0); + write_ctx_reg(gp_regs, CTX_GPREG_X6, 1); + (void)mce_command_handler(MCE_CMD_UPDATE_CSTATE_INFO, + TEGRA_ARI_CLUSTER_CC7, 0, TEGRA_ARI_SYSTEM_SC8); + + /* Enter quasi power down state */ + (void)mce_command_handler(MCE_CMD_ENTER_CSTATE, + TEGRA_ARI_CORE_C7, MCE_CORE_SLEEP_TIME_INFINITE, 0); + + /* disable GICC */ + tegra_gic_cpuif_deactivate(); + + /* power down core */ + prepare_cpu_pwr_dwn(); + + } else { + ERROR("%s: unsupported power down state (%d)\n", __func__, + tegra186_system_powerdn_state); + } + + wfi(); + + /* wait for the system to power down */ + for (;;) { + ; + } +} + +int tegra_soc_prepare_system_reset(void) +{ + mce_enter_ccplex_state(TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_REBOOT); + + return PSCI_E_SUCCESS; +} diff --git a/plat/nvidia/tegra/soc/t186/plat_secondary.c b/plat/nvidia/tegra/soc/t186/plat_secondary.c new file mode 100644 index 000000000..df802891a --- /dev/null +++ b/plat/nvidia/tegra/soc/t186/plat_secondary.c @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include + +#define MISCREG_CPU_RESET_VECTOR 0x2000 +#define MISCREG_AA64_RST_LOW 0x2004 +#define MISCREG_AA64_RST_HIGH 0x2008 + +#define SCRATCH_SECURE_RSV1_SCRATCH_0 0x658 +#define SCRATCH_SECURE_RSV1_SCRATCH_1 0x65C + +#define CPU_RESET_MODE_AA64 1 + +extern void tegra_secure_entrypoint(void); + +/******************************************************************************* + * Setup secondary CPU vectors + ******************************************************************************/ +void plat_secondary_setup(void) +{ + uint32_t addr_low, addr_high; + uint64_t reset_addr = (uint64_t)tegra_secure_entrypoint; + + INFO("Setting up secondary CPU boot\n"); + + addr_low = (uint32_t)reset_addr | CPU_RESET_MODE_AA64; + addr_high = (uint32_t)((reset_addr >> 32) & 0x7ff); + + /* write lower 32 bits first, then the upper 11 bits */ + mmio_write_32(TEGRA_MISC_BASE + MISCREG_AA64_RST_LOW, addr_low); + 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, + addr_low); + mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_SECURE_RSV1_SCRATCH_1, + addr_high); + + /* update reset vector address to the CCPLEX */ + mce_update_reset_vector(addr_low, addr_high); +} diff --git a/plat/nvidia/tegra/soc/t186/plat_setup.c b/plat/nvidia/tegra/soc/t186/plat_setup.c new file mode 100644 index 000000000..d6b8bc3f8 --- /dev/null +++ b/plat/nvidia/tegra/soc/t186/plat_setup.c @@ -0,0 +1,170 @@ +/* + * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/******************************************************************************* + * The Tegra power domain tree has a single system level power domain i.e. a + * single root node. The first entry in the power domain descriptor specifies + * the number of power domains at the highest power level. + ******************************************************************************* + */ +const unsigned char tegra_power_domain_tree_desc[] = { + /* No of root nodes */ + 1, + /* No of clusters */ + PLATFORM_CLUSTER_COUNT, + /* No of CPU cores - cluster0 */ + PLATFORM_MAX_CPUS_PER_CLUSTER, + /* No of CPU cores - cluster1 */ + PLATFORM_MAX_CPUS_PER_CLUSTER +}; + +/* + * Table of regions to map using the MMU. + */ +static const mmap_region_t tegra_mmap[] = { + MAP_REGION_FLAT(TEGRA_MISC_BASE, 0x10000, /* 64KB */ + MT_DEVICE | MT_RW | MT_SECURE), + MAP_REGION_FLAT(TEGRA_MC_STREAMID_BASE, 0x10000, /* 64KB */ + MT_DEVICE | MT_RW | MT_SECURE), + MAP_REGION_FLAT(TEGRA_MC_BASE, 0x10000, /* 64KB */ + MT_DEVICE | MT_RW | MT_SECURE), + MAP_REGION_FLAT(TEGRA_UARTA_BASE, 0x20000, /* 128KB */ + MT_DEVICE | MT_RW | MT_SECURE), + MAP_REGION_FLAT(TEGRA_GICD_BASE, 0x20000, /* 128KB */ + MT_DEVICE | MT_RW | MT_SECURE), + MAP_REGION_FLAT(TEGRA_SE0_BASE, 0x10000, /* 64KB */ + MT_DEVICE | MT_RW | MT_SECURE), + MAP_REGION_FLAT(TEGRA_PKA1_BASE, 0x10000, /* 64KB */ + MT_DEVICE | MT_RW | MT_SECURE), + MAP_REGION_FLAT(TEGRA_RNG1_BASE, 0x10000, /* 64KB */ + MT_DEVICE | MT_RW | MT_SECURE), + MAP_REGION_FLAT(TEGRA_CAR_RESET_BASE, 0x10000, /* 64KB */ + MT_DEVICE | MT_RW | MT_SECURE), + MAP_REGION_FLAT(TEGRA_PMC_BASE, 0x40000, /* 256KB */ + MT_DEVICE | MT_RW | MT_SECURE), + MAP_REGION_FLAT(TEGRA_SCRATCH_BASE, 0x10000, /* 64KB */ + MT_DEVICE | MT_RW | MT_SECURE), + MAP_REGION_FLAT(TEGRA_MMCRAB_BASE, 0x60000, /* 384KB */ + MT_DEVICE | MT_RW | MT_SECURE), + MAP_REGION_FLAT(TEGRA_SMMU_BASE, 0x1000000, /* 64KB */ + MT_DEVICE | MT_RW | MT_SECURE), + {0} +}; + +/******************************************************************************* + * Set up the pagetables as per the platform memory map & initialize the MMU + ******************************************************************************/ +const mmap_region_t *plat_get_mmio_map(void) +{ + /* MMIO space */ + return tegra_mmap; +} + +/******************************************************************************* + * Handler to get the System Counter Frequency + ******************************************************************************/ +unsigned int plat_get_syscnt_freq2(void) +{ + return 31250000; +} + +/******************************************************************************* + * Maximum supported UART controllers + ******************************************************************************/ +#define TEGRA186_MAX_UART_PORTS 7 + +/******************************************************************************* + * This variable holds the UART port base addresses + ******************************************************************************/ +static uint32_t tegra186_uart_addresses[TEGRA186_MAX_UART_PORTS + 1] = { + 0, /* undefined - treated as an error case */ + TEGRA_UARTA_BASE, + TEGRA_UARTB_BASE, + TEGRA_UARTC_BASE, + TEGRA_UARTD_BASE, + TEGRA_UARTE_BASE, + TEGRA_UARTF_BASE, + TEGRA_UARTG_BASE, +}; + +/******************************************************************************* + * Retrieve the UART controller base to be used as the console + ******************************************************************************/ +uint32_t plat_get_console_from_id(int id) +{ + if (id > TEGRA186_MAX_UART_PORTS) + return 0; + + return tegra186_uart_addresses[id]; +} + +/* Secure IRQs for Tegra186 */ +static const irq_sec_cfg_t tegra186_sec_irqs[] = { + { + TEGRA186_TOP_WDT_IRQ, + TEGRA186_SEC_IRQ_TARGET_MASK, + INTR_TYPE_EL3, + }, + { + TEGRA186_AON_WDT_IRQ, + TEGRA186_SEC_IRQ_TARGET_MASK, + INTR_TYPE_EL3, + }, +}; + +/******************************************************************************* + * Initialize the GIC and SGIs + ******************************************************************************/ +void plat_gic_setup(void) +{ + tegra_gic_setup(tegra186_sec_irqs, + sizeof(tegra186_sec_irqs) / sizeof(tegra186_sec_irqs[0])); + + /* + * Initialize the FIQ handler only if the platform supports any + * FIQ interrupt sources. + */ + if (sizeof(tegra186_sec_irqs) > 0) + tegra_fiq_handler_setup(); +} diff --git a/plat/nvidia/tegra/soc/t186/plat_sip_calls.c b/plat/nvidia/tegra/soc/t186/plat_sip_calls.c new file mode 100644 index 000000000..fabab0185 --- /dev/null +++ b/plat/nvidia/tegra/soc/t186/plat_sip_calls.c @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern uint32_t tegra186_system_powerdn_state; + +/******************************************************************************* + * Tegra186 SiP SMCs + ******************************************************************************/ +#define TEGRA_SIP_NEW_VIDEOMEM_REGION 0x82000003 +#define TEGRA_SIP_SYSTEM_SHUTDOWN_STATE 0x82FFFE01 +#define TEGRA_SIP_MCE_CMD_ENTER_CSTATE 0x82FFFF00 +#define TEGRA_SIP_MCE_CMD_UPDATE_CSTATE_INFO 0x82FFFF01 +#define TEGRA_SIP_MCE_CMD_UPDATE_CROSSOVER_TIME 0x82FFFF02 +#define TEGRA_SIP_MCE_CMD_READ_CSTATE_STATS 0x82FFFF03 +#define TEGRA_SIP_MCE_CMD_WRITE_CSTATE_STATS 0x82FFFF04 +#define TEGRA_SIP_MCE_CMD_IS_SC7_ALLOWED 0x82FFFF05 +#define TEGRA_SIP_MCE_CMD_ONLINE_CORE 0x82FFFF06 +#define TEGRA_SIP_MCE_CMD_CC3_CTRL 0x82FFFF07 +#define TEGRA_SIP_MCE_CMD_ECHO_DATA 0x82FFFF08 +#define TEGRA_SIP_MCE_CMD_READ_VERSIONS 0x82FFFF09 +#define TEGRA_SIP_MCE_CMD_ENUM_FEATURES 0x82FFFF0A +#define TEGRA_SIP_MCE_CMD_ROC_FLUSH_CACHE_TRBITS 0x82FFFF0B +#define TEGRA_SIP_MCE_CMD_ENUM_READ_MCA 0x82FFFF0C +#define TEGRA_SIP_MCE_CMD_ENUM_WRITE_MCA 0x82FFFF0D +#define TEGRA_SIP_MCE_CMD_ROC_FLUSH_CACHE 0x82FFFF0E +#define TEGRA_SIP_MCE_CMD_ROC_CLEAN_CACHE 0x82FFFF0F + +/******************************************************************************* + * This function is responsible for handling all T186 SiP calls + ******************************************************************************/ +int plat_sip_handler(uint32_t smc_fid, + uint64_t x1, + uint64_t x2, + uint64_t x3, + uint64_t x4, + void *cookie, + void *handle, + uint64_t flags) +{ + int mce_ret; + + switch (smc_fid) { + + /* + * Micro Coded Engine (MCE) commands reside in the 0x82FFFF00 - + * 0x82FFFFFF SiP SMC space + */ + case TEGRA_SIP_MCE_CMD_ENTER_CSTATE: + case TEGRA_SIP_MCE_CMD_UPDATE_CSTATE_INFO: + case TEGRA_SIP_MCE_CMD_UPDATE_CROSSOVER_TIME: + case TEGRA_SIP_MCE_CMD_READ_CSTATE_STATS: + case TEGRA_SIP_MCE_CMD_WRITE_CSTATE_STATS: + case TEGRA_SIP_MCE_CMD_IS_SC7_ALLOWED: + case TEGRA_SIP_MCE_CMD_CC3_CTRL: + case TEGRA_SIP_MCE_CMD_ECHO_DATA: + case TEGRA_SIP_MCE_CMD_READ_VERSIONS: + case TEGRA_SIP_MCE_CMD_ENUM_FEATURES: + case TEGRA_SIP_MCE_CMD_ROC_FLUSH_CACHE_TRBITS: + case TEGRA_SIP_MCE_CMD_ENUM_READ_MCA: + case TEGRA_SIP_MCE_CMD_ENUM_WRITE_MCA: + case TEGRA_SIP_MCE_CMD_ROC_FLUSH_CACHE: + case TEGRA_SIP_MCE_CMD_ROC_CLEAN_CACHE: + + /* clean up the high bits */ + smc_fid &= MCE_CMD_MASK; + + /* execute the command and store the result */ + mce_ret = mce_command_handler(smc_fid, x1, x2, x3); + write_ctx_reg(get_gpregs_ctx(handle), CTX_GPREG_X0, mce_ret); + + return 0; + + case TEGRA_SIP_NEW_VIDEOMEM_REGION: + /* clean up the high bits */ + x1 = (uint32_t)x1; + x2 = (uint32_t)x2; + + /* + * Check if Video Memory overlaps TZDRAM (contains bl31/bl32) + * or falls outside of the valid DRAM range + */ + mce_ret = bl31_check_ns_address(x1, x2); + if (mce_ret) + return -ENOTSUP; + + /* + * Check if Video Memory is aligned to 1MB. + */ + if ((x1 & 0xFFFFF) || (x2 & 0xFFFFF)) { + ERROR("Unaligned Video Memory base address!\n"); + return -ENOTSUP; + } + + /* new video memory carveout settings */ + tegra_memctrl_videomem_setup(x1, x2); + + return 0; + + case TEGRA_SIP_SYSTEM_SHUTDOWN_STATE: + + /* clean up the high bits */ + x1 = (uint32_t)x1; + + /* + * SC8 is a special Tegra186 system state where the CPUs and + * DRAM are powered down but the other subsystem is still + * alive. + */ + if ((x1 == TEGRA_ARI_SYSTEM_SC8) || + (x1 == TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_POWER_OFF)) { + + tegra186_system_powerdn_state = x1; + flush_dcache_range( + (uintptr_t)&tegra186_system_powerdn_state, + sizeof(tegra186_system_powerdn_state)); + + } else { + + ERROR("%s: unhandled powerdn state (%d)\n", __func__, + (uint32_t)x1); + return -ENOTSUP; + } + + return 0; + + default: + break; + } + + return -ENOTSUP; +} diff --git a/plat/nvidia/tegra/soc/t186/platform_t186.mk b/plat/nvidia/tegra/soc/t186/platform_t186.mk new file mode 100644 index 000000000..adc4a9ee9 --- /dev/null +++ b/plat/nvidia/tegra/soc/t186/platform_t186.mk @@ -0,0 +1,65 @@ +# +# Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# Neither the name of ARM nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific +# prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +# platform configs +ENABLE_NS_L2_CPUECTRL_RW_ACCESS := 1 +$(eval $(call add_define,ENABLE_NS_L2_CPUECTRL_RW_ACCESS)) + +# platform settings +TZDRAM_BASE := 0x30000000 +$(eval $(call add_define,TZDRAM_BASE)) + +PLATFORM_CLUSTER_COUNT := 2 +$(eval $(call add_define,PLATFORM_CLUSTER_COUNT)) + +PLATFORM_MAX_CPUS_PER_CLUSTER := 4 +$(eval $(call add_define,PLATFORM_MAX_CPUS_PER_CLUSTER)) + +MAX_XLAT_TABLES := 15 +$(eval $(call add_define,MAX_XLAT_TABLES)) + +MAX_MMAP_REGIONS := 15 +$(eval $(call add_define,MAX_MMAP_REGIONS)) + +# platform files +PLAT_INCLUDES += -I${SOC_DIR}/drivers/include + +BL31_SOURCES += lib/cpus/aarch64/denver.S \ + lib/cpus/aarch64/cortex_a57.S \ + ${COMMON_DIR}/drivers/memctrl/memctrl_v2.c \ + ${SOC_DIR}/drivers/mce/mce.c \ + ${SOC_DIR}/drivers/mce/ari.c \ + ${SOC_DIR}/drivers/mce/nvg.c \ + ${SOC_DIR}/drivers/mce/aarch64/nvg_helpers.S \ + ${SOC_DIR}/drivers/smmu/smmu.c \ + ${SOC_DIR}/plat_psci_handlers.c \ + ${SOC_DIR}/plat_setup.c \ + ${SOC_DIR}/plat_secondary.c \ + ${SOC_DIR}/plat_sip_calls.c