xref: /rk3399_ARM-atf/plat/qti/common/src/qti_common.c (revision 7a0f795ee716c5d26bcfd994288e35e2b193b5df)
15bd9c17dSSaurabh Gorecha /*
25bd9c17dSSaurabh Gorecha  * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
35bd9c17dSSaurabh Gorecha  * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
45bd9c17dSSaurabh Gorecha  *
55bd9c17dSSaurabh Gorecha  * SPDX-License-Identifier: BSD-3-Clause
65bd9c17dSSaurabh Gorecha  */
75bd9c17dSSaurabh Gorecha 
85bd9c17dSSaurabh Gorecha #include <assert.h>
95bd9c17dSSaurabh Gorecha #include <errno.h>
105bd9c17dSSaurabh Gorecha #include <stdbool.h>
115bd9c17dSSaurabh Gorecha #include <stdint.h>
125bd9c17dSSaurabh Gorecha 
135bd9c17dSSaurabh Gorecha #include <common/debug.h>
144b918452SSaurabh Gorecha #include <lib/mmio.h>
154b918452SSaurabh Gorecha #include <lib/smccc.h>
165bd9c17dSSaurabh Gorecha #include <lib/xlat_tables/xlat_tables_v2.h>
174b918452SSaurabh Gorecha #include <services/arm_arch_svc.h>
185bd9c17dSSaurabh Gorecha 
195bd9c17dSSaurabh Gorecha #include <platform_def.h>
205bd9c17dSSaurabh Gorecha #include <qti_plat.h>
215bd9c17dSSaurabh Gorecha #include <qtiseclib_interface.h>
225bd9c17dSSaurabh Gorecha 
235bd9c17dSSaurabh Gorecha /*
245bd9c17dSSaurabh Gorecha  * Table of regions for various BL stages to map using the MMU.
255bd9c17dSSaurabh Gorecha  * This doesn't include TZRAM as the 'mem_layout' argument passed to
265bd9c17dSSaurabh Gorecha  * qti_configure_mmu_elx() will give the available subset of that,
275bd9c17dSSaurabh Gorecha  */
285bd9c17dSSaurabh Gorecha 
295bd9c17dSSaurabh Gorecha const mmap_region_t plat_qti_mmap[] = {
305bd9c17dSSaurabh Gorecha 	MAP_REGION_FLAT(QTI_DEVICE_BASE, QTI_DEVICE_SIZE,
315bd9c17dSSaurabh Gorecha 			MT_DEVICE | MT_RW | MT_SECURE),
325bd9c17dSSaurabh Gorecha 	MAP_REGION_FLAT(QTI_AOP_CMD_DB_BASE, QTI_AOP_CMD_DB_SIZE,
335bd9c17dSSaurabh Gorecha 			MT_NS | MT_RO | MT_EXECUTE_NEVER),
345bd9c17dSSaurabh Gorecha 	{0}
355bd9c17dSSaurabh Gorecha };
365bd9c17dSSaurabh Gorecha 
375bd9c17dSSaurabh Gorecha CASSERT(ARRAY_SIZE(plat_qti_mmap) <= MAX_MMAP_REGIONS, assert_max_mmap_regions);
385bd9c17dSSaurabh Gorecha 
395bd9c17dSSaurabh Gorecha 
405bd9c17dSSaurabh Gorecha bool qti_is_overlap_atf_rg(unsigned long long addr, size_t size)
415bd9c17dSSaurabh Gorecha {
425bd9c17dSSaurabh Gorecha 	if (addr > addr + size
435bd9c17dSSaurabh Gorecha 			|| (BL31_BASE < addr + size && BL31_LIMIT > addr)) {
445bd9c17dSSaurabh Gorecha 		return true;
455bd9c17dSSaurabh Gorecha 	}
465bd9c17dSSaurabh Gorecha 	return false;
475bd9c17dSSaurabh Gorecha }
485bd9c17dSSaurabh Gorecha 
495bd9c17dSSaurabh Gorecha /*
505bd9c17dSSaurabh Gorecha  *  unsigned int plat_qti_my_cluster_pos(void)
515bd9c17dSSaurabh Gorecha  *  definition to get the cluster index of the calling CPU.
525bd9c17dSSaurabh Gorecha  *  - In ARM v8   (MPIDR_EL1[24]=0)
535bd9c17dSSaurabh Gorecha  *    ClusterId = MPIDR_EL1[15:8]
545bd9c17dSSaurabh Gorecha  *  - In ARM v8.1 & Later version (MPIDR_EL1[24]=1)
555bd9c17dSSaurabh Gorecha  *    ClusterId = MPIDR_EL1[23:15]
565bd9c17dSSaurabh Gorecha  */
575bd9c17dSSaurabh Gorecha unsigned int plat_qti_my_cluster_pos(void)
585bd9c17dSSaurabh Gorecha {
595bd9c17dSSaurabh Gorecha 	unsigned int mpidr, cluster_id;
605bd9c17dSSaurabh Gorecha 
615bd9c17dSSaurabh Gorecha 	mpidr = read_mpidr_el1();
625bd9c17dSSaurabh Gorecha 	if ((mpidr & MPIDR_MT_MASK) == 0) {	/* MT not supported */
635bd9c17dSSaurabh Gorecha 		cluster_id = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK;
645bd9c17dSSaurabh Gorecha 	} else {		/* MT supported */
655bd9c17dSSaurabh Gorecha 		cluster_id = (mpidr >> MPIDR_AFF2_SHIFT) & MPIDR_AFFLVL_MASK;
665bd9c17dSSaurabh Gorecha 	}
675bd9c17dSSaurabh Gorecha 	assert(cluster_id < PLAT_CLUSTER_COUNT);
685bd9c17dSSaurabh Gorecha 	return cluster_id;
695bd9c17dSSaurabh Gorecha }
705bd9c17dSSaurabh Gorecha 
715bd9c17dSSaurabh Gorecha /*
725bd9c17dSSaurabh Gorecha  * Set up the page tables for the generic and platform-specific memory regions.
735bd9c17dSSaurabh Gorecha  * The extents of the generic memory regions are specified by the function
745bd9c17dSSaurabh Gorecha  * arguments and consist of:
755bd9c17dSSaurabh Gorecha  * - Trusted SRAM seen by the BL image;
765bd9c17dSSaurabh Gorecha  * - Code section;
775bd9c17dSSaurabh Gorecha  * - Read-only data section;
785bd9c17dSSaurabh Gorecha  * - Coherent memory region, if applicable.
795bd9c17dSSaurabh Gorecha  */
805bd9c17dSSaurabh Gorecha void qti_setup_page_tables(uintptr_t total_base,
815bd9c17dSSaurabh Gorecha 			   size_t total_size,
825bd9c17dSSaurabh Gorecha 			   uintptr_t code_start,
835bd9c17dSSaurabh Gorecha 			   uintptr_t code_limit,
845bd9c17dSSaurabh Gorecha 			   uintptr_t rodata_start,
855bd9c17dSSaurabh Gorecha 			   uintptr_t rodata_limit,
865bd9c17dSSaurabh Gorecha 			   uintptr_t coh_start, uintptr_t coh_limit)
875bd9c17dSSaurabh Gorecha {
885bd9c17dSSaurabh Gorecha 	/*
895bd9c17dSSaurabh Gorecha 	 * Map the Trusted SRAM with appropriate memory attributes.
905bd9c17dSSaurabh Gorecha 	 * Subsequent mappings will adjust the attributes for specific regions.
915bd9c17dSSaurabh Gorecha 	 */
925bd9c17dSSaurabh Gorecha 	VERBOSE("Trusted SRAM seen by this BL image: %p - %p\n",
935bd9c17dSSaurabh Gorecha 		(void *)total_base, (void *)(total_base + total_size));
945bd9c17dSSaurabh Gorecha 	mmap_add_region(total_base, total_base,
955bd9c17dSSaurabh Gorecha 			total_size, MT_MEMORY | MT_RW | MT_SECURE);
965bd9c17dSSaurabh Gorecha 
975bd9c17dSSaurabh Gorecha 	/* Re-map the code section */
985bd9c17dSSaurabh Gorecha 	VERBOSE("Code region: %p - %p\n",
995bd9c17dSSaurabh Gorecha 		(void *)code_start, (void *)code_limit);
1005bd9c17dSSaurabh Gorecha 	mmap_add_region(code_start, code_start,
1015bd9c17dSSaurabh Gorecha 			code_limit - code_start, MT_CODE | MT_SECURE);
1025bd9c17dSSaurabh Gorecha 
1035bd9c17dSSaurabh Gorecha 	/* Re-map the read-only data section */
1045bd9c17dSSaurabh Gorecha 	VERBOSE("Read-only data region: %p - %p\n",
1055bd9c17dSSaurabh Gorecha 		(void *)rodata_start, (void *)rodata_limit);
1065bd9c17dSSaurabh Gorecha 	mmap_add_region(rodata_start, rodata_start,
1075bd9c17dSSaurabh Gorecha 			rodata_limit - rodata_start, MT_RO_DATA | MT_SECURE);
1085bd9c17dSSaurabh Gorecha 
1095bd9c17dSSaurabh Gorecha 	/* Re-map the coherent memory region */
1105bd9c17dSSaurabh Gorecha 	VERBOSE("Coherent region: %p - %p\n",
1115bd9c17dSSaurabh Gorecha 		(void *)coh_start, (void *)coh_limit);
1125bd9c17dSSaurabh Gorecha 	mmap_add_region(coh_start, coh_start,
1135bd9c17dSSaurabh Gorecha 			coh_limit - coh_start, MT_DEVICE | MT_RW | MT_SECURE);
1145bd9c17dSSaurabh Gorecha 
1155bd9c17dSSaurabh Gorecha 	/* Now (re-)map the platform-specific memory regions */
1165bd9c17dSSaurabh Gorecha 	mmap_add(plat_qti_mmap);
1175bd9c17dSSaurabh Gorecha 
1185bd9c17dSSaurabh Gorecha 	/* Create the page tables to reflect the above mappings */
1195bd9c17dSSaurabh Gorecha 	init_xlat_tables();
1205bd9c17dSSaurabh Gorecha }
1215bd9c17dSSaurabh Gorecha 
1225bd9c17dSSaurabh Gorecha static inline void qti_align_mem_region(uintptr_t addr, size_t size,
1235bd9c17dSSaurabh Gorecha 					uintptr_t *aligned_addr,
1245bd9c17dSSaurabh Gorecha 					size_t *aligned_size)
1255bd9c17dSSaurabh Gorecha {
1265bd9c17dSSaurabh Gorecha 	*aligned_addr = round_down(addr, PAGE_SIZE);
1275bd9c17dSSaurabh Gorecha 	*aligned_size = round_up(addr - *aligned_addr + size, PAGE_SIZE);
1285bd9c17dSSaurabh Gorecha }
1295bd9c17dSSaurabh Gorecha 
1305bd9c17dSSaurabh Gorecha int qti_mmap_add_dynamic_region(uintptr_t base_pa, size_t size,
1315bd9c17dSSaurabh Gorecha 				unsigned int attr)
1325bd9c17dSSaurabh Gorecha {
1335bd9c17dSSaurabh Gorecha 	uintptr_t aligned_pa;
1345bd9c17dSSaurabh Gorecha 	size_t aligned_size;
1355bd9c17dSSaurabh Gorecha 
1365bd9c17dSSaurabh Gorecha 	qti_align_mem_region(base_pa, size, &aligned_pa, &aligned_size);
1375bd9c17dSSaurabh Gorecha 
1385bd9c17dSSaurabh Gorecha 	if (qti_is_overlap_atf_rg(base_pa, size)) {
1395bd9c17dSSaurabh Gorecha 		/* Memory shouldn't overlap with TF-A range. */
1405bd9c17dSSaurabh Gorecha 		return -EPERM;
1415bd9c17dSSaurabh Gorecha 	}
1425bd9c17dSSaurabh Gorecha 
1435bd9c17dSSaurabh Gorecha 	return mmap_add_dynamic_region(aligned_pa, aligned_pa, aligned_size,
1445bd9c17dSSaurabh Gorecha 				       attr);
1455bd9c17dSSaurabh Gorecha }
1465bd9c17dSSaurabh Gorecha 
1475bd9c17dSSaurabh Gorecha int qti_mmap_remove_dynamic_region(uintptr_t base_va, size_t size)
1485bd9c17dSSaurabh Gorecha {
1495bd9c17dSSaurabh Gorecha 	qti_align_mem_region(base_va, size, &base_va, &size);
1505bd9c17dSSaurabh Gorecha 	return mmap_remove_dynamic_region(base_va, size);
1515bd9c17dSSaurabh Gorecha }
1524b918452SSaurabh Gorecha 
1534b918452SSaurabh Gorecha /*
1544b918452SSaurabh Gorecha  * This function returns soc version which mainly consist of below fields
1554b918452SSaurabh Gorecha  *
1564b918452SSaurabh Gorecha  * soc_version[30:24] = JEP-106 continuation code for the SiP
1574b918452SSaurabh Gorecha  * soc_version[23:16] = JEP-106 identification code with parity bit for the SiP
1584b918452SSaurabh Gorecha  * soc_version[0:15]  = Implementation defined SoC ID
1594b918452SSaurabh Gorecha  */
1604b918452SSaurabh Gorecha int32_t plat_get_soc_version(void)
1614b918452SSaurabh Gorecha {
1624b918452SSaurabh Gorecha 	uint32_t soc_version = (QTI_SOC_VERSION & QTI_SOC_VERSION_MASK);
1634b918452SSaurabh Gorecha 	uint32_t jep106az_code = (JEDEC_QTI_BKID << QTI_SOC_CONTINUATION_SHIFT)
1644b918452SSaurabh Gorecha 			 | (JEDEC_QTI_MFID << QTI_SOC_IDENTIFICATION_SHIFT);
1654b918452SSaurabh Gorecha 	return (int32_t)(jep106az_code | (soc_version));
1664b918452SSaurabh Gorecha }
1674b918452SSaurabh Gorecha 
1684b918452SSaurabh Gorecha /*
1694b918452SSaurabh Gorecha  * This function returns soc revision in below format
1704b918452SSaurabh Gorecha  *
1714b918452SSaurabh Gorecha  *   soc_revision[0:30] = SOC revision of specific SOC
1724b918452SSaurabh Gorecha  */
1734b918452SSaurabh Gorecha int32_t plat_get_soc_revision(void)
1744b918452SSaurabh Gorecha {
1754b918452SSaurabh Gorecha 	return mmio_read_32(QTI_SOC_REVISION_REG) & QTI_SOC_REVISION_MASK;
1764b918452SSaurabh Gorecha }
1774b918452SSaurabh Gorecha 
1784b918452SSaurabh Gorecha /*****************************************************************************
179*7a0f795eSSaurabh Gorecha  * plat_is_smccc_feature_available() - This function checks whether SMCCC feature
1804b918452SSaurabh Gorecha  *                                  is availabile for the platform or not.
1814b918452SSaurabh Gorecha  * @fid: SMCCC function id
1824b918452SSaurabh Gorecha  *
1834b918452SSaurabh Gorecha  * Return SMC_ARCH_CALL_SUCCESS if SMCCC feature is available and
1844b918452SSaurabh Gorecha  * SMC_ARCH_CALL_NOT_SUPPORTED otherwise.
1854b918452SSaurabh Gorecha  *****************************************************************************/
186*7a0f795eSSaurabh Gorecha int32_t plat_is_smccc_feature_available(u_register_t fid)
1874b918452SSaurabh Gorecha {
1884b918452SSaurabh Gorecha 	switch (fid) {
1894b918452SSaurabh Gorecha 	case SMCCC_ARCH_SOC_ID:
1904b918452SSaurabh Gorecha 		return SMC_ARCH_CALL_SUCCESS;
1914b918452SSaurabh Gorecha 	default:
1924b918452SSaurabh Gorecha 		return SMC_ARCH_CALL_NOT_SUPPORTED;
1934b918452SSaurabh Gorecha 	}
1944b918452SSaurabh Gorecha }
195