Home | History | Annotate | Download | only in zynqmp
      1 // SPDX-License-Identifier: GPL-2.0+
      2 /*
      3  * (C) Copyright 2014 - 2015 Xilinx, Inc.
      4  * Michal Simek <michal.simek (at) xilinx.com>
      5  */
      6 
      7 #include <common.h>
      8 #include <asm/arch/hardware.h>
      9 #include <asm/arch/sys_proto.h>
     10 #include <asm/armv8/mmu.h>
     11 #include <asm/io.h>
     12 
     13 #define ZYNQ_SILICON_VER_MASK	0xF000
     14 #define ZYNQ_SILICON_VER_SHIFT	12
     15 
     16 DECLARE_GLOBAL_DATA_PTR;
     17 
     18 /*
     19  * Number of filled static entries and also the first empty
     20  * slot in zynqmp_mem_map.
     21  */
     22 #define ZYNQMP_MEM_MAP_USED	4
     23 
     24 #if !defined(CONFIG_ZYNQMP_NO_DDR)
     25 #define DRAM_BANKS CONFIG_NR_DRAM_BANKS
     26 #else
     27 #define DRAM_BANKS 0
     28 #endif
     29 
     30 #if defined(CONFIG_DEFINE_TCM_OCM_MMAP)
     31 #define TCM_MAP 1
     32 #else
     33 #define TCM_MAP 0
     34 #endif
     35 
     36 /* +1 is end of list which needs to be empty */
     37 #define ZYNQMP_MEM_MAP_MAX (ZYNQMP_MEM_MAP_USED + DRAM_BANKS + TCM_MAP + 1)
     38 
     39 static struct mm_region zynqmp_mem_map[ZYNQMP_MEM_MAP_MAX] = {
     40 	{
     41 		.virt = 0x80000000UL,
     42 		.phys = 0x80000000UL,
     43 		.size = 0x70000000UL,
     44 		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
     45 			 PTE_BLOCK_NON_SHARE |
     46 			 PTE_BLOCK_PXN | PTE_BLOCK_UXN
     47 	}, {
     48 		.virt = 0xf8000000UL,
     49 		.phys = 0xf8000000UL,
     50 		.size = 0x07e00000UL,
     51 		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
     52 			 PTE_BLOCK_NON_SHARE |
     53 			 PTE_BLOCK_PXN | PTE_BLOCK_UXN
     54 	}, {
     55 		.virt = 0x400000000UL,
     56 		.phys = 0x400000000UL,
     57 		.size = 0x400000000UL,
     58 		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
     59 			 PTE_BLOCK_NON_SHARE |
     60 			 PTE_BLOCK_PXN | PTE_BLOCK_UXN
     61 	}, {
     62 		.virt = 0x1000000000UL,
     63 		.phys = 0x1000000000UL,
     64 		.size = 0xf000000000UL,
     65 		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
     66 			 PTE_BLOCK_NON_SHARE |
     67 			 PTE_BLOCK_PXN | PTE_BLOCK_UXN
     68 	}
     69 };
     70 
     71 void mem_map_fill(void)
     72 {
     73 	int banks = ZYNQMP_MEM_MAP_USED;
     74 
     75 #if defined(CONFIG_DEFINE_TCM_OCM_MMAP)
     76 	zynqmp_mem_map[banks].virt = 0xffe00000UL;
     77 	zynqmp_mem_map[banks].phys = 0xffe00000UL;
     78 	zynqmp_mem_map[banks].size = 0x00200000UL;
     79 	zynqmp_mem_map[banks].attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
     80 				      PTE_BLOCK_INNER_SHARE;
     81 	banks = banks + 1;
     82 #endif
     83 
     84 #if !defined(CONFIG_ZYNQMP_NO_DDR)
     85 	for (int i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
     86 		/* Zero size means no more DDR that's this is end */
     87 		if (!gd->bd->bi_dram[i].size)
     88 			break;
     89 
     90 		zynqmp_mem_map[banks].virt = gd->bd->bi_dram[i].start;
     91 		zynqmp_mem_map[banks].phys = gd->bd->bi_dram[i].start;
     92 		zynqmp_mem_map[banks].size = gd->bd->bi_dram[i].size;
     93 		zynqmp_mem_map[banks].attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
     94 					      PTE_BLOCK_INNER_SHARE;
     95 		banks = banks + 1;
     96 	}
     97 #endif
     98 }
     99 
    100 struct mm_region *mem_map = zynqmp_mem_map;
    101 
    102 u64 get_page_table_size(void)
    103 {
    104 	return 0x14000;
    105 }
    106 
    107 #ifdef CONFIG_SYS_MEM_RSVD_FOR_MMU
    108 int reserve_mmu(void)
    109 {
    110 	initialize_tcm(TCM_LOCK);
    111 	memset((void *)ZYNQMP_TCM_BASE_ADDR, 0, ZYNQMP_TCM_SIZE);
    112 	gd->arch.tlb_size = PGTABLE_SIZE;
    113 	gd->arch.tlb_addr = ZYNQMP_TCM_BASE_ADDR;
    114 
    115 	return 0;
    116 }
    117 #endif
    118 
    119 static unsigned int zynqmp_get_silicon_version_secure(void)
    120 {
    121 	u32 ver;
    122 
    123 	ver = readl(&csu_base->version);
    124 	ver &= ZYNQMP_SILICON_VER_MASK;
    125 	ver >>= ZYNQMP_SILICON_VER_SHIFT;
    126 
    127 	return ver;
    128 }
    129 
    130 unsigned int zynqmp_get_silicon_version(void)
    131 {
    132 	if (current_el() == 3)
    133 		return zynqmp_get_silicon_version_secure();
    134 
    135 	gd->cpu_clk = get_tbclk();
    136 
    137 	switch (gd->cpu_clk) {
    138 	case 50000000:
    139 		return ZYNQMP_CSU_VERSION_QEMU;
    140 	}
    141 
    142 	return ZYNQMP_CSU_VERSION_SILICON;
    143 }
    144 
    145 #define ZYNQMP_MMIO_READ	0xC2000014
    146 #define ZYNQMP_MMIO_WRITE	0xC2000013
    147 
    148 int __maybe_unused invoke_smc(u32 pm_api_id, u32 arg0, u32 arg1, u32 arg2,
    149 			      u32 arg3, u32 *ret_payload)
    150 {
    151 	/*
    152 	 * Added SIP service call Function Identifier
    153 	 * Make sure to stay in x0 register
    154 	 */
    155 	struct pt_regs regs;
    156 
    157 	regs.regs[0] = pm_api_id;
    158 	regs.regs[1] = ((u64)arg1 << 32) | arg0;
    159 	regs.regs[2] = ((u64)arg3 << 32) | arg2;
    160 
    161 	smc_call(&regs);
    162 
    163 	if (ret_payload != NULL) {
    164 		ret_payload[0] = (u32)regs.regs[0];
    165 		ret_payload[1] = upper_32_bits(regs.regs[0]);
    166 		ret_payload[2] = (u32)regs.regs[1];
    167 		ret_payload[3] = upper_32_bits(regs.regs[1]);
    168 		ret_payload[4] = (u32)regs.regs[2];
    169 	}
    170 
    171 	return regs.regs[0];
    172 }
    173 
    174 #define ZYNQMP_SIP_SVC_GET_API_VERSION		0xC2000001
    175 
    176 #define ZYNQMP_PM_VERSION_MAJOR		1
    177 #define ZYNQMP_PM_VERSION_MINOR		0
    178 #define ZYNQMP_PM_VERSION_MAJOR_SHIFT	16
    179 #define ZYNQMP_PM_VERSION_MINOR_MASK	0xFFFF
    180 
    181 #define ZYNQMP_PM_VERSION	\
    182 	((ZYNQMP_PM_VERSION_MAJOR << ZYNQMP_PM_VERSION_MAJOR_SHIFT) | \
    183 				 ZYNQMP_PM_VERSION_MINOR)
    184 
    185 #if defined(CONFIG_CLK_ZYNQMP)
    186 void zynqmp_pmufw_version(void)
    187 {
    188 	int ret;
    189 	u32 ret_payload[PAYLOAD_ARG_CNT];
    190 	u32 pm_api_version;
    191 
    192 	ret = invoke_smc(ZYNQMP_SIP_SVC_GET_API_VERSION, 0, 0, 0, 0,
    193 			 ret_payload);
    194 	pm_api_version = ret_payload[1];
    195 
    196 	if (ret)
    197 		panic("PMUFW is not found - Please load it!\n");
    198 
    199 	printf("PMUFW:\tv%d.%d\n",
    200 	       pm_api_version >> ZYNQMP_PM_VERSION_MAJOR_SHIFT,
    201 	       pm_api_version & ZYNQMP_PM_VERSION_MINOR_MASK);
    202 
    203 	if (pm_api_version < ZYNQMP_PM_VERSION)
    204 		panic("PMUFW version error. Expected: v%d.%d\n",
    205 		      ZYNQMP_PM_VERSION_MAJOR, ZYNQMP_PM_VERSION_MINOR);
    206 }
    207 #endif
    208 
    209 static int zynqmp_mmio_rawwrite(const u32 address,
    210 		      const u32 mask,
    211 		      const u32 value)
    212 {
    213 	u32 data;
    214 	u32 value_local = value;
    215 	int ret;
    216 
    217 	ret = zynqmp_mmio_read(address, &data);
    218 	if (ret)
    219 		return ret;
    220 
    221 	data &= ~mask;
    222 	value_local &= mask;
    223 	value_local |= data;
    224 	writel(value_local, (ulong)address);
    225 	return 0;
    226 }
    227 
    228 static int zynqmp_mmio_rawread(const u32 address, u32 *value)
    229 {
    230 	*value = readl((ulong)address);
    231 	return 0;
    232 }
    233 
    234 int zynqmp_mmio_write(const u32 address,
    235 		      const u32 mask,
    236 		      const u32 value)
    237 {
    238 	if (IS_ENABLED(CONFIG_SPL_BUILD) || current_el() == 3)
    239 		return zynqmp_mmio_rawwrite(address, mask, value);
    240 	else
    241 		return invoke_smc(ZYNQMP_MMIO_WRITE, address, mask,
    242 				  value, 0, NULL);
    243 
    244 	return -EINVAL;
    245 }
    246 
    247 int zynqmp_mmio_read(const u32 address, u32 *value)
    248 {
    249 	u32 ret_payload[PAYLOAD_ARG_CNT];
    250 	u32 ret;
    251 
    252 	if (!value)
    253 		return -EINVAL;
    254 
    255 	if (IS_ENABLED(CONFIG_SPL_BUILD) || current_el() == 3) {
    256 		ret = zynqmp_mmio_rawread(address, value);
    257 	} else {
    258 		ret = invoke_smc(ZYNQMP_MMIO_READ, address, 0, 0,
    259 				 0, ret_payload);
    260 		*value = ret_payload[1];
    261 	}
    262 
    263 	return ret;
    264 }
    265