1 /* 2 * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <errno.h> 8 9 #include <common/debug.h> 10 #include <lib/mmio.h> 11 #include <lib/smccc.h> 12 #include <lib/xlat_tables/xlat_tables_v2.h> 13 #include <services/arm_arch_svc.h> 14 15 #include <sunxi_def.h> 16 #include <sunxi_mmap.h> 17 #include <sunxi_private.h> 18 19 static const mmap_region_t sunxi_mmap[MAX_STATIC_MMAP_REGIONS + 1] = { 20 MAP_REGION_FLAT(SUNXI_SRAM_BASE, SUNXI_SRAM_SIZE, 21 MT_DEVICE | MT_RW | MT_SECURE | MT_EXECUTE_NEVER), 22 MAP_REGION_FLAT(SUNXI_DEV_BASE, SUNXI_DEV_SIZE, 23 MT_DEVICE | MT_RW | MT_SECURE | MT_EXECUTE_NEVER), 24 MAP_REGION(PRELOADED_BL33_BASE, SUNXI_BL33_VIRT_BASE, 25 SUNXI_DRAM_MAP_SIZE, MT_RW_DATA | MT_NS), 26 {}, 27 }; 28 29 unsigned int plat_get_syscnt_freq2(void) 30 { 31 return SUNXI_OSC24M_CLK_IN_HZ; 32 } 33 34 void sunxi_configure_mmu_el3(int flags) 35 { 36 mmap_add_region(BL_CODE_BASE, BL_CODE_BASE, 37 BL_CODE_END - BL_CODE_BASE, 38 MT_CODE | MT_SECURE); 39 mmap_add_region(BL_CODE_END, BL_CODE_END, 40 BL_END - BL_CODE_END, 41 MT_RW_DATA | MT_SECURE); 42 #if SEPARATE_CODE_AND_RODATA 43 mmap_add_region(BL_RO_DATA_BASE, BL_RO_DATA_BASE, 44 BL_RO_DATA_END - BL_RO_DATA_BASE, 45 MT_RO_DATA | MT_SECURE); 46 #endif 47 #if SEPARATE_NOBITS_REGION 48 mmap_add_region(BL_NOBITS_BASE, BL_NOBITS_BASE, 49 BL_NOBITS_END - BL_NOBITS_BASE, 50 MT_RW_DATA | MT_SECURE); 51 #endif 52 #if USE_COHERENT_MEM 53 mmap_add_region(BL_COHERENT_RAM_BASE, BL_COHERENT_RAM_BASE, 54 BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE, 55 MT_DEVICE | MT_RW | MT_SECURE | MT_EXECUTE_NEVER); 56 #endif 57 58 mmap_add(sunxi_mmap); 59 init_xlat_tables(); 60 61 enable_mmu_el3(0); 62 } 63 64 #define SRAM_VER_REG (SUNXI_SYSCON_BASE + 0x24) 65 uint16_t sunxi_read_soc_id(void) 66 { 67 uint32_t reg = mmio_read_32(SRAM_VER_REG); 68 69 /* Set bit 15 to prepare for the SOCID read. */ 70 mmio_write_32(SRAM_VER_REG, reg | BIT(15)); 71 72 reg = mmio_read_32(SRAM_VER_REG); 73 74 /* deactivate the SOCID access again */ 75 mmio_write_32(SRAM_VER_REG, reg & ~BIT(15)); 76 77 return reg >> 16; 78 } 79 80 /* 81 * Configure a given pin to the GPIO-OUT function and sets its level. 82 * The port is given as a capital letter, the pin is the number within 83 * this port group. 84 * So to set pin PC7 to high, use: sunxi_set_gpio_out('C', 7, true); 85 */ 86 void sunxi_set_gpio_out(char port, int pin, bool level_high) 87 { 88 uintptr_t port_base; 89 90 if (port < 'A' || port > 'L') 91 return; 92 if (port == 'L') 93 port_base = SUNXI_R_PIO_BASE; 94 else 95 port_base = SUNXI_PIO_BASE + (port - 'A') * 0x24; 96 97 /* Set the new level first before configuring the pin. */ 98 if (level_high) 99 mmio_setbits_32(port_base + 0x10, BIT(pin)); 100 else 101 mmio_clrbits_32(port_base + 0x10, BIT(pin)); 102 103 /* configure pin as GPIO out (4(3) bits per pin, 1: GPIO out */ 104 mmio_clrsetbits_32(port_base + (pin / 8) * 4, 105 0x7 << ((pin % 8) * 4), 106 0x1 << ((pin % 8) * 4)); 107 } 108 109 int sunxi_init_platform_r_twi(uint16_t socid, bool use_rsb) 110 { 111 uint32_t pin_func = 0x77; 112 uint32_t device_bit; 113 unsigned int reset_offset = 0xb0; 114 115 switch (socid) { 116 case SUNXI_SOC_H5: 117 if (use_rsb) 118 return -ENODEV; 119 pin_func = 0x22; 120 device_bit = BIT(6); 121 break; 122 case SUNXI_SOC_H6: 123 case SUNXI_SOC_H616: 124 pin_func = use_rsb ? 0x22 : 0x33; 125 device_bit = BIT(16); 126 reset_offset = use_rsb ? 0x1bc : 0x19c; 127 break; 128 case SUNXI_SOC_A64: 129 pin_func = use_rsb ? 0x22 : 0x33; 130 device_bit = use_rsb ? BIT(3) : BIT(6); 131 break; 132 default: 133 INFO("R_I2C/RSB on Allwinner 0x%x SoC not supported\n", socid); 134 return -ENODEV; 135 } 136 137 /* un-gate R_PIO clock */ 138 if (socid != SUNXI_SOC_H6 && socid != SUNXI_SOC_H616) 139 mmio_setbits_32(SUNXI_R_PRCM_BASE + 0x28, BIT(0)); 140 141 /* switch pins PL0 and PL1 to the desired function */ 142 mmio_clrsetbits_32(SUNXI_R_PIO_BASE + 0x00, 0xffU, pin_func); 143 144 /* level 2 drive strength */ 145 mmio_clrsetbits_32(SUNXI_R_PIO_BASE + 0x14, 0x0fU, 0xaU); 146 147 /* set both pins to pull-up */ 148 mmio_clrsetbits_32(SUNXI_R_PIO_BASE + 0x1c, 0x0fU, 0x5U); 149 150 /* un-gate clock */ 151 if (socid != SUNXI_SOC_H6 && socid != SUNXI_SOC_H616) 152 mmio_setbits_32(SUNXI_R_PRCM_BASE + 0x28, device_bit); 153 else 154 mmio_setbits_32(SUNXI_R_PRCM_BASE + reset_offset, BIT(0)); 155 156 /* assert, then de-assert reset of I2C/RSB controller */ 157 mmio_clrbits_32(SUNXI_R_PRCM_BASE + reset_offset, device_bit); 158 mmio_setbits_32(SUNXI_R_PRCM_BASE + reset_offset, device_bit); 159 160 return 0; 161 } 162 163 int32_t plat_is_smccc_feature_available(u_register_t fid) 164 { 165 switch (fid) { 166 case SMCCC_ARCH_SOC_ID: 167 return SMC_ARCH_CALL_SUCCESS; 168 default: 169 return SMC_ARCH_CALL_NOT_SUPPORTED; 170 } 171 } 172 173 int32_t plat_get_soc_version(void) 174 { 175 int32_t ret; 176 177 ret = SOC_ID_SET_JEP_106(JEDEC_ALLWINNER_BKID, JEDEC_ALLWINNER_MFID); 178 179 return ret | (sunxi_read_soc_id() & SOC_ID_IMPL_DEF_MASK); 180 } 181 182 int32_t plat_get_soc_revision(void) 183 { 184 uint32_t reg = mmio_read_32(SRAM_VER_REG); 185 186 return reg & SUNXI_VER_BITS_MASK; 187 } 188