xref: /rk3399_ARM-atf/plat/allwinner/common/sunxi_common.c (revision 103f19f055bebf5ffa5ef73bba51d736123c7c33)
1 /*
2  * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <mmio.h>
8 #include <platform.h>
9 #include <platform_def.h>
10 #include <sunxi_def.h>
11 #include <sunxi_private.h>
12 #include <xlat_tables_v2.h>
13 
14 static mmap_region_t sunxi_mmap[PLATFORM_MMAP_REGIONS + 1] = {
15 	MAP_REGION_FLAT(SUNXI_SRAM_BASE, SUNXI_SRAM_SIZE,
16 			MT_MEMORY | MT_RW | MT_SECURE),
17 	MAP_REGION_FLAT(SUNXI_DEV_BASE, SUNXI_DEV_SIZE,
18 			MT_DEVICE | MT_RW | MT_SECURE),
19 	MAP_REGION(SUNXI_DRAM_BASE, SUNXI_DRAM_VIRT_BASE, SUNXI_DRAM_SEC_SIZE,
20 			MT_MEMORY | MT_RW | MT_SECURE),
21 	MAP_REGION(PLAT_SUNXI_NS_IMAGE_OFFSET,
22 		   SUNXI_DRAM_VIRT_BASE + SUNXI_DRAM_SEC_SIZE,
23 		   SUNXI_DRAM_MAP_SIZE,
24 		   MT_MEMORY | MT_RO | MT_NS),
25 	{},
26 };
27 
28 unsigned int plat_get_syscnt_freq2(void)
29 {
30 	return SUNXI_OSC24M_CLK_IN_HZ;
31 }
32 
33 uintptr_t plat_get_ns_image_entrypoint(void)
34 {
35 #ifdef PRELOADED_BL33_BASE
36 	return PRELOADED_BL33_BASE;
37 #else
38 	return PLAT_SUNXI_NS_IMAGE_OFFSET;
39 #endif
40 }
41 
42 void sunxi_configure_mmu_el3(int flags)
43 {
44 	mmap_add_region(BL31_BASE, BL31_BASE,
45 			BL31_LIMIT - BL31_BASE,
46 			MT_MEMORY | MT_RW | MT_SECURE);
47 	mmap_add_region(BL_CODE_BASE, BL_CODE_BASE,
48 			BL_CODE_END - BL_CODE_BASE,
49 			MT_CODE | MT_SECURE);
50 	mmap_add_region(BL_RO_DATA_BASE, BL_RO_DATA_BASE,
51 			BL_RO_DATA_END - BL_RO_DATA_BASE,
52 			MT_RO_DATA | MT_SECURE);
53 	mmap_add(sunxi_mmap);
54 	init_xlat_tables();
55 
56 	enable_mmu_el3(0);
57 }
58 
59 #define SRAM_VER_REG (SUNXI_SYSCON_BASE + 0x24)
60 uint16_t sunxi_read_soc_id(void)
61 {
62 	uint32_t reg = mmio_read_32(SRAM_VER_REG);
63 
64 	/* Set bit 15 to prepare for the SOCID read. */
65 	mmio_write_32(SRAM_VER_REG, reg | BIT(15));
66 
67 	reg = mmio_read_32(SRAM_VER_REG);
68 
69 	/* deactivate the SOCID access again */
70 	mmio_write_32(SRAM_VER_REG, reg & ~BIT(15));
71 
72 	return reg >> 16;
73 }
74 
75 /*
76  * Configure a given pin to the GPIO-OUT function and sets its level.
77  * The port is given as a capital letter, the pin is the number within
78  * this port group.
79  * So to set pin PC7 to high, use: sunxi_set_gpio_out('C', 7, true);
80  */
81 void sunxi_set_gpio_out(char port, int pin, bool level_high)
82 {
83 	uintptr_t port_base;
84 
85 	if (port < 'A' || port > 'L')
86 		return;
87 	if (port == 'L')
88 		port_base = SUNXI_R_PIO_BASE;
89 	else
90 		port_base = SUNXI_PIO_BASE + (port - 'A') * 0x24;
91 
92 	/* Set the new level first before configuring the pin. */
93 	if (level_high)
94 		mmio_setbits_32(port_base + 0x10, BIT(pin));
95 	else
96 		mmio_clrbits_32(port_base + 0x10, BIT(pin));
97 
98 	/* configure pin as GPIO out (4(3) bits per pin, 1: GPIO out */
99 	mmio_clrsetbits_32(port_base + (pin / 8) * 4,
100 			   0x7 << ((pin % 8) * 4),
101 			   0x1 << ((pin % 8) * 4));
102 }
103