1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * (C) Copyright 2016 Beniamino Galvani <b.galvani@gmail.com> 4 * (C) Copyright 2018 Neil Armstrong <narmstrong@baylibre.com> 5 */ 6 7 #include <common.h> 8 #include <asm/arch/boot.h> 9 #include <asm/arch/eth.h> 10 #include <asm/arch/gx.h> 11 #include <asm/arch/mem.h> 12 #include <asm/arch/meson-vpu.h> 13 #include <asm/io.h> 14 #include <asm/armv8/mmu.h> 15 #include <linux/sizes.h> 16 #include <phy.h> 17 18 DECLARE_GLOBAL_DATA_PTR; 19 20 int meson_get_boot_device(void) 21 { 22 return readl(GX_AO_SEC_GP_CFG0) & GX_AO_BOOT_DEVICE; 23 } 24 25 /* Configure the reserved memory zones exported by the secure registers 26 * into EFI and DTB reserved memory entries. 27 */ 28 void meson_init_reserved_memory(void *fdt) 29 { 30 u64 bl31_size, bl31_start; 31 u64 bl32_size, bl32_start; 32 u32 reg; 33 34 /* 35 * Get ARM Trusted Firmware reserved memory zones in : 36 * - AO_SEC_GP_CFG3: bl32 & bl31 size in KiB, can be 0 37 * - AO_SEC_GP_CFG5: bl31 physical start address, can be NULL 38 * - AO_SEC_GP_CFG4: bl32 physical start address, can be NULL 39 */ 40 reg = readl(GX_AO_SEC_GP_CFG3); 41 42 bl31_size = ((reg & GX_AO_BL31_RSVMEM_SIZE_MASK) 43 >> GX_AO_BL31_RSVMEM_SIZE_SHIFT) * SZ_1K; 44 bl32_size = (reg & GX_AO_BL32_RSVMEM_SIZE_MASK) * SZ_1K; 45 46 bl31_start = readl(GX_AO_SEC_GP_CFG5); 47 bl32_start = readl(GX_AO_SEC_GP_CFG4); 48 49 /* 50 * Early Meson GX Firmware revisions did not provide the reserved 51 * memory zones in the registers, keep fixed memory zone handling. 52 */ 53 if (IS_ENABLED(CONFIG_MESON_GX) && 54 !reg && !bl31_start && !bl32_start) { 55 bl31_start = 0x10000000; 56 bl31_size = 0x200000; 57 } 58 59 /* Add first 16MiB reserved zone */ 60 meson_board_add_reserved_memory(fdt, 0, GX_FIRMWARE_MEM_SIZE); 61 62 /* Add BL31 reserved zone */ 63 if (bl31_start && bl31_size) 64 meson_board_add_reserved_memory(fdt, bl31_start, bl31_size); 65 66 /* Add BL32 reserved zone */ 67 if (bl32_start && bl32_size) 68 meson_board_add_reserved_memory(fdt, bl32_start, bl32_size); 69 70 #if defined(CONFIG_VIDEO_MESON) 71 meson_vpu_rsv_fb(fdt); 72 #endif 73 } 74 75 phys_size_t get_effective_memsize(void) 76 { 77 /* Size is reported in MiB, convert it in bytes */ 78 return ((readl(GX_AO_SEC_GP_CFG0) & GX_AO_MEM_SIZE_MASK) 79 >> GX_AO_MEM_SIZE_SHIFT) * SZ_1M; 80 } 81 82 static struct mm_region gx_mem_map[] = { 83 { 84 .virt = 0x0UL, 85 .phys = 0x0UL, 86 .size = 0xc0000000UL, 87 .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | 88 PTE_BLOCK_INNER_SHARE 89 }, { 90 .virt = 0xc0000000UL, 91 .phys = 0xc0000000UL, 92 .size = 0x30000000UL, 93 .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | 94 PTE_BLOCK_NON_SHARE | 95 PTE_BLOCK_PXN | PTE_BLOCK_UXN 96 }, { 97 /* List terminator */ 98 0, 99 } 100 }; 101 102 struct mm_region *mem_map = gx_mem_map; 103 104 /* Configure the Ethernet MAC with the requested interface mode 105 * with some optional flags. 106 */ 107 void meson_eth_init(phy_interface_t mode, unsigned int flags) 108 { 109 switch (mode) { 110 case PHY_INTERFACE_MODE_RGMII: 111 case PHY_INTERFACE_MODE_RGMII_ID: 112 case PHY_INTERFACE_MODE_RGMII_RXID: 113 case PHY_INTERFACE_MODE_RGMII_TXID: 114 /* Set RGMII mode */ 115 setbits_le32(GX_ETH_REG_0, GX_ETH_REG_0_PHY_INTF | 116 GX_ETH_REG_0_TX_PHASE(1) | 117 GX_ETH_REG_0_TX_RATIO(4) | 118 GX_ETH_REG_0_PHY_CLK_EN | 119 GX_ETH_REG_0_CLK_EN); 120 break; 121 122 case PHY_INTERFACE_MODE_RMII: 123 /* Set RMII mode */ 124 out_le32(GX_ETH_REG_0, GX_ETH_REG_0_INVERT_RMII_CLK | 125 GX_ETH_REG_0_CLK_EN); 126 127 /* Use GXL RMII Internal PHY */ 128 if (IS_ENABLED(CONFIG_MESON_GXL) && 129 (flags & MESON_USE_INTERNAL_RMII_PHY)) { 130 writel(0x10110181, GX_ETH_REG_2); 131 writel(0xe40908ff, GX_ETH_REG_3); 132 } 133 134 break; 135 136 default: 137 printf("Invalid Ethernet interface mode\n"); 138 return; 139 } 140 141 /* Enable power gate */ 142 clrbits_le32(GX_MEM_PD_REG_0, GX_MEM_PD_REG_0_ETH_MASK); 143 } 144