1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Copyright 2022 Marek Vasut <marex@denx.de> 4 */ 5 6#include <common.h> 7#include <asm/arch/clock.h> 8#include <asm/arch/imx8mp_pins.h> 9#include <asm/io.h> 10#include <dm.h> 11#include <dm/device-internal.h> 12#include <env.h> 13#include <env_internal.h> 14#include <linux/bitfield.h> 15#include <malloc.h> 16#include <net.h> 17#include <spl.h> 18 19#include "../common/common.h" 20 21DECLARE_GLOBAL_DATA_PTR; 22 23static void dmo_setup_second_mac_address(void) 24{ 25 u8 enetaddr[6]; 26 int ret; 27 28 /* In case 'eth1addr' is already set in environment, do nothing. */ 29 ret = eth_env_get_enetaddr_by_index("eth", 1, enetaddr); 30 if (ret) /* valid 'eth1addr' is already set */ 31 return; 32 33 /* Read 'ethaddr' from environment and validate. */ 34 ret = eth_env_get_enetaddr_by_index("eth", 0, enetaddr); 35 if (!ret) /* 'ethaddr' in environment is not valid, stop */ 36 return; 37 38 /* Set 'eth1addr' as 'ethaddr' + 1 */ 39 enetaddr[5]++; 40 41 eth_env_set_enetaddr_by_index("eth", 1, enetaddr); 42} 43 44enum env_location env_get_location(enum env_operation op, int prio) 45{ 46 /* Environment is always in eMMC boot partitions */ 47 return prio ? ENVL_UNKNOWN : ENVL_MMC; 48} 49 50int board_init(void) 51{ 52 return 0; 53} 54 55int board_late_init(void) 56{ 57 struct udevice *dev; 58 int ret; 59 60 dmo_setup_boot_device(); 61 dmo_setup_mac_address(); 62 dmo_setup_second_mac_address(); 63 64 ret = uclass_get_device_by_name(UCLASS_MISC, "usb-hub@2c", &dev); 65 if (ret) 66 printf("Error bringing up USB hub (%d)\n", ret); 67 68 return 0; 69} 70 71int fdtdec_board_setup(const void *fdt_blob) 72{ 73 const void __iomem *mux = (void __iomem *)IOMUXC_BASE_ADDR + 74 FIELD_GET(MUX_CTRL_OFS_MASK, MX8MP_PAD_ENET_MDC__ENET_QOS_MDC); 75 const char *phy_compat = "ethernet-phy-ieee802.3-c22"; 76 bool is_bcmphy; 77 int phy_node; 78 int ret; 79 80 /* Do nothing if not i.MX8MP eDM SBC */ 81 ret = fdt_node_check_compatible(fdt_blob, 0, "dmo,imx8mp-data-modul-edm-sbc"); 82 if (ret) 83 return 0; 84 85 /* 86 * If GPIO1_16 RGMII_MDC is HIGH, then R390 is populated. 87 * R390 is populated only on boards with AR8031 PHY. 88 * 89 * If GPIO1_16 RGMII_MDC is LOW, then the in-SoM pull down 90 * is the dominant pull resistor. This is the case on boards 91 * with BCM54213PE PHY. 92 */ 93 setbits_le32(mux, IOMUX_CONFIG_SION); 94 is_bcmphy = !(readl(GPIO1_BASE_ADDR) & BIT(16)); 95 clrbits_le32(mux, IOMUX_CONFIG_SION); 96 97 phy_node = fdt_node_offset_by_compatible(fdt_blob, -1, phy_compat); 98 if (phy_node < 0) 99 return 0; 100 101 /* 102 * Update PHY MDC address in control DT based on the populated 103 * PHY type. AR8031 is at address 0, BCM54213PE is at address 1. 104 */ 105 fdt_setprop_inplace_u32((void *)fdt_blob, phy_node, 106 "reg", is_bcmphy ? 1 : 0); 107 108 /* Apply the same modification to EQoS PHY */ 109 phy_node = fdt_node_offset_by_compatible(fdt_blob, phy_node, phy_compat); 110 if (phy_node < 0) 111 return 0; 112 113 fdt_setprop_inplace_u32((void *)fdt_blob, phy_node, 114 "reg", is_bcmphy ? 1 : 0); 115 116 return 0; 117} 118