1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright 2018 NXP 4 */ 5 6 #include <common.h> 7 #include <errno.h> 8 #include <linux/libfdt.h> 9 #include <environment.h> 10 #include <fsl_esdhc.h> 11 #include <asm/io.h> 12 #include <asm/gpio.h> 13 #include <asm/arch/clock.h> 14 #include <asm/arch/sci/sci.h> 15 #include <asm/arch/imx8-pins.h> 16 #include <asm/arch/iomux.h> 17 #include <asm/arch/sys_proto.h> 18 19 DECLARE_GLOBAL_DATA_PTR; 20 21 #define GPIO_PAD_CTRL ((SC_PAD_CONFIG_NORMAL << PADRING_CONFIG_SHIFT) | \ 22 (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) | \ 23 (SC_PAD_28FDSOI_DSE_DV_HIGH << PADRING_DSE_SHIFT) | \ 24 (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) 25 26 #define UART_PAD_CTRL ((SC_PAD_CONFIG_OUT_IN << PADRING_CONFIG_SHIFT) | \ 27 (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) | \ 28 (SC_PAD_28FDSOI_DSE_DV_HIGH << PADRING_DSE_SHIFT) | \ 29 (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) 30 31 static iomux_cfg_t uart0_pads[] = { 32 SC_P_UART0_RX | MUX_PAD_CTRL(UART_PAD_CTRL), 33 SC_P_UART0_TX | MUX_PAD_CTRL(UART_PAD_CTRL), 34 }; 35 36 static void setup_iomux_uart(void) 37 { 38 imx8_iomux_setup_multiple_pads(uart0_pads, ARRAY_SIZE(uart0_pads)); 39 } 40 41 int board_early_init_f(void) 42 { 43 int ret; 44 /* Set UART0 clock root to 80 MHz */ 45 sc_pm_clock_rate_t rate = 80000000; 46 47 /* Power up UART0 */ 48 ret = sc_pm_set_resource_power_mode(-1, SC_R_UART_0, SC_PM_PW_MODE_ON); 49 if (ret) 50 return ret; 51 52 ret = sc_pm_set_clock_rate(-1, SC_R_UART_0, 2, &rate); 53 if (ret) 54 return ret; 55 56 /* Enable UART0 clock root */ 57 ret = sc_pm_clock_enable(-1, SC_R_UART_0, 2, true, false); 58 if (ret) 59 return ret; 60 61 setup_iomux_uart(); 62 63 return 0; 64 } 65 66 #if IS_ENABLED(CONFIG_DM_GPIO) 67 static void board_gpio_init(void) 68 { 69 struct gpio_desc desc; 70 int ret; 71 72 ret = dm_gpio_lookup_name("gpio@1a_3", &desc); 73 if (ret) 74 return; 75 76 ret = dm_gpio_request(&desc, "bb_per_rst_b"); 77 if (ret) 78 return; 79 80 dm_gpio_set_dir_flags(&desc, GPIOD_IS_OUT); 81 dm_gpio_set_value(&desc, 0); 82 udelay(50); 83 dm_gpio_set_value(&desc, 1); 84 } 85 #else 86 static inline void board_gpio_init(void) {} 87 #endif 88 89 #if IS_ENABLED(CONFIG_FEC_MXC) 90 #include <miiphy.h> 91 92 int board_phy_config(struct phy_device *phydev) 93 { 94 phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x1f); 95 phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x8); 96 97 phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x05); 98 phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x100); 99 100 if (phydev->drv->config) 101 phydev->drv->config(phydev); 102 103 return 0; 104 } 105 #endif 106 107 void build_info(void) 108 { 109 u32 sc_build = 0, sc_commit = 0; 110 111 /* Get SCFW build and commit id */ 112 sc_misc_build_info(-1, &sc_build, &sc_commit); 113 if (!sc_build) { 114 printf("SCFW does not support build info\n"); 115 sc_commit = 0; /* Display 0 when the build info is not supported*/ 116 } 117 printf("Build: SCFW %x\n", sc_commit); 118 } 119 120 int checkboard(void) 121 { 122 puts("Board: iMX8QXP MEK\n"); 123 124 build_info(); 125 print_bootinfo(); 126 127 return 0; 128 } 129 130 int board_init(void) 131 { 132 board_gpio_init(); 133 134 return 0; 135 } 136 137 void detail_board_ddr_info(void) 138 { 139 puts("\nDDR "); 140 } 141 142 /* 143 * Board specific reset that is system reset. 144 */ 145 void reset_cpu(ulong addr) 146 { 147 /* TODO */ 148 } 149 150 #ifdef CONFIG_OF_BOARD_SETUP 151 int ft_board_setup(void *blob, bd_t *bd) 152 { 153 return 0; 154 } 155 #endif 156 157 int board_mmc_get_env_dev(int devno) 158 { 159 return devno; 160 } 161 162 int board_late_init(void) 163 { 164 #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG 165 env_set("board_name", "MEK"); 166 env_set("board_rev", "iMX8QXP"); 167 #endif 168 169 return 0; 170 } 171