1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Copyright 2018 congatec AG 4 * Copyright (C) 2019 Oliver Graute <oliver.graute@kococonnector.com> 5 */ 6#include <common.h> 7#include <errno.h> 8#include <linux/libfdt.h> 9#include <fsl_esdhc.h> 10#include <init.h> 11 12#include <asm/io.h> 13#include <asm/gpio.h> 14#include <asm/arch/clock.h> 15#include <firmware/imx/sci/sci.h> 16#include <asm/arch/imx8-pins.h> 17#include <usb.h> 18#include <asm/arch/iomux.h> 19#include <asm/arch/sys_proto.h> 20#include <linux/delay.h> 21#include <power-domain.h> 22 23DECLARE_GLOBAL_DATA_PTR; 24 25#define ESDHC_PAD_CTRL ((SC_PAD_CONFIG_NORMAL << PADRING_CONFIG_SHIFT) | \ 26 (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) | \ 27 (SC_PAD_28FDSOI_DSE_DV_HIGH << PADRING_DSE_SHIFT) | \ 28 (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) 29 30#define ESDHC_CLK_PAD_CTRL ((SC_PAD_CONFIG_OUT_IN << PADRING_CONFIG_SHIFT) | \ 31 (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) | \ 32 (SC_PAD_28FDSOI_DSE_DV_HIGH << PADRING_DSE_SHIFT) | \ 33 (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) 34 35#define ENET_INPUT_PAD_CTRL ((SC_PAD_CONFIG_OD_IN << PADRING_CONFIG_SHIFT) | \ 36 (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) | \ 37 (SC_PAD_28FDSOI_DSE_18V_10MA << PADRING_DSE_SHIFT) | \ 38 (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) 39 40#define ENET_NORMAL_PAD_CTRL ((SC_PAD_CONFIG_NORMAL << PADRING_CONFIG_SHIFT) | \ 41 (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) | \ 42 (SC_PAD_28FDSOI_DSE_18V_10MA << PADRING_DSE_SHIFT) | \ 43 (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) 44 45#define FSPI_PAD_CTRL ((SC_PAD_CONFIG_NORMAL << PADRING_CONFIG_SHIFT) | \ 46 (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) | \ 47 (SC_PAD_28FDSOI_DSE_DV_HIGH << PADRING_DSE_SHIFT) | \ 48 (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) 49 50#define GPIO_PAD_CTRL ((SC_PAD_CONFIG_NORMAL << PADRING_CONFIG_SHIFT) | \ 51 (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) | \ 52 (SC_PAD_28FDSOI_DSE_DV_HIGH << PADRING_DSE_SHIFT) | \ 53 (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) 54 55#define I2C_PAD_CTRL ((SC_PAD_CONFIG_OUT_IN << PADRING_CONFIG_SHIFT) | \ 56 (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) | \ 57 (SC_PAD_28FDSOI_DSE_DV_LOW << PADRING_DSE_SHIFT) | \ 58 (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) 59 60#define UART_PAD_CTRL ((SC_PAD_CONFIG_OUT_IN << PADRING_CONFIG_SHIFT) | \ 61 (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) | \ 62 (SC_PAD_28FDSOI_DSE_DV_HIGH << PADRING_DSE_SHIFT) | \ 63 (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) 64 65static iomux_cfg_t uart0_pads[] = { 66 SC_P_UART0_RX | MUX_PAD_CTRL(UART_PAD_CTRL), 67 SC_P_UART0_TX | MUX_PAD_CTRL(UART_PAD_CTRL), 68}; 69 70void board_late_mmc_env_init(void); 71void init_clk_usdhc(u32 index); 72int fsl_esdhc_initialize(struct bd_info *bis, struct fsl_esdhc_cfg *cfg); 73 74static void setup_iomux_uart(void) 75{ 76 imx8_iomux_setup_multiple_pads(uart0_pads, ARRAY_SIZE(uart0_pads)); 77} 78 79int board_early_init_f(void) 80{ 81 /* sc_ipc_t ipcHndl = 0; */ 82 int scierr; 83 84 /* When start u-boot in XEN VM, directly return */ 85 /* if (IS_ENABLED(CONFIG_XEN)) */ 86 /* return 0; */ 87 88 /* ipcHndl = gd->arch.ipc_channel_handle; */ 89 90 /* Power up UART0, this is very early while power domain is not working */ 91 scierr = sc_pm_set_resource_power_mode(-1, SC_R_UART_0, SC_PM_PW_MODE_ON); 92 if (scierr) 93 return 0; 94 95 /* Set UART0 clock root to 80 MHz */ 96 sc_pm_clock_rate_t rate = 80000000; 97 98 scierr = sc_pm_set_clock_rate(-1, SC_R_UART_0, 2, &rate); 99 if (scierr) 100 return 0; 101 102 /* Enable UART0 clock root */ 103 scierr = sc_pm_clock_enable(-1, SC_R_UART_0, 2, true, false); 104 if (scierr) 105 return 0; 106 107 setup_iomux_uart(); 108 109 return 0; 110} 111 112#if IS_ENABLED(CONFIG_FSL_ESDHC_IMX) 113 114#define USDHC1_CD_GPIO IMX_GPIO_NR(5, 22) 115#define USDHC2_CD_GPIO IMX_GPIO_NR(4, 12) 116 117static struct fsl_esdhc_cfg usdhc_cfg[CFG_SYS_FSL_USDHC_NUM] = { 118 {USDHC1_BASE_ADDR, 0, 8}, 119 {USDHC2_BASE_ADDR, 0, 4}, 120 {USDHC3_BASE_ADDR, 0, 4}, 121}; 122 123static iomux_cfg_t emmc0[] = { 124 SC_P_EMMC0_CLK | MUX_PAD_CTRL(ESDHC_CLK_PAD_CTRL), 125 SC_P_EMMC0_CMD | MUX_PAD_CTRL(ESDHC_PAD_CTRL), 126 SC_P_EMMC0_DATA0 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), 127 SC_P_EMMC0_DATA1 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), 128 SC_P_EMMC0_DATA2 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), 129 SC_P_EMMC0_DATA3 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), 130 SC_P_EMMC0_DATA4 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), 131 SC_P_EMMC0_DATA5 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), 132 SC_P_EMMC0_DATA6 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), 133 SC_P_EMMC0_DATA7 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), 134 SC_P_EMMC0_RESET_B | MUX_PAD_CTRL(ESDHC_PAD_CTRL), 135 SC_P_EMMC0_STROBE | MUX_PAD_CTRL(ESDHC_PAD_CTRL), 136}; 137 138static iomux_cfg_t usdhc1_sd[] = { 139 SC_P_USDHC1_CLK | MUX_PAD_CTRL(ESDHC_CLK_PAD_CTRL), 140 SC_P_USDHC1_CMD | MUX_PAD_CTRL(ESDHC_PAD_CTRL), 141 SC_P_USDHC1_DATA0 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), 142 SC_P_USDHC1_DATA1 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), 143 SC_P_USDHC1_DATA2 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), 144 SC_P_USDHC1_DATA3 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), 145 SC_P_USDHC1_DATA6 | MUX_MODE_ALT(2) | MUX_PAD_CTRL(ESDHC_PAD_CTRL), 146 SC_P_USDHC1_DATA7 | MUX_MODE_ALT(3) | MUX_PAD_CTRL(ESDHC_PAD_CTRL), 147 SC_P_USDHC1_RESET_B | MUX_PAD_CTRL(ESDHC_PAD_CTRL), 148 SC_P_USDHC1_VSELECT | MUX_PAD_CTRL(ESDHC_PAD_CTRL), 149}; 150 151static iomux_cfg_t usdhc2_sd[] = { 152 SC_P_USDHC2_CLK | MUX_PAD_CTRL(ESDHC_CLK_PAD_CTRL), 153 SC_P_USDHC2_CMD | MUX_PAD_CTRL(ESDHC_PAD_CTRL), 154 SC_P_USDHC2_DATA0 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), 155 SC_P_USDHC2_DATA1 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), 156 SC_P_USDHC2_DATA2 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), 157 SC_P_USDHC2_DATA3 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), 158 SC_P_USDHC2_RESET_B | MUX_PAD_CTRL(ESDHC_PAD_CTRL), 159 SC_P_USDHC2_VSELECT | MUX_PAD_CTRL(ESDHC_PAD_CTRL), 160 SC_P_USDHC2_WP | MUX_PAD_CTRL(ESDHC_PAD_CTRL), 161 SC_P_USDHC2_CD_B | MUX_MODE_ALT(3) | MUX_PAD_CTRL(ESDHC_PAD_CTRL), 162}; 163 164int board_mmc_init(struct bd_info *bis) 165{ 166 int i, ret; 167 struct power_domain pd; 168 169 /* 170 * According to the board_mmc_init() the following map is done: 171 * (U-Boot device node) (Physical Port) 172 * mmc0 (onboard eMMC) USDHC1 173 * mmc1 (external SD card) USDHC2 174 * mmc2 (onboard uSD) USDHC3 175 */ 176 for (i = 0; i < CFG_SYS_FSL_USDHC_NUM; i++) { 177 switch (i) { 178 case 0: 179 /* onboard eMMC */ 180 if (!imx8_power_domain_lookup_name("conn_sdhc0", &pd)) 181 power_domain_on(&pd); 182 183 imx8_iomux_setup_multiple_pads(emmc0, ARRAY_SIZE(emmc0)); 184 init_clk_usdhc(0); 185 usdhc_cfg[i].sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK); 186 break; 187 case 1: 188 /* external SD card */ 189 if (!imx8_power_domain_lookup_name("conn_sdhc1", &pd)) 190 power_domain_on(&pd); 191 192 imx8_iomux_setup_multiple_pads(usdhc1_sd, ARRAY_SIZE(usdhc1_sd)); 193 init_clk_usdhc(1); 194 usdhc_cfg[i].sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK); 195 gpio_request(USDHC1_CD_GPIO, "sd1_cd"); 196 gpio_direction_input(USDHC1_CD_GPIO); 197 break; 198 case 2: 199 /* onboard uSD */ 200 if (!imx8_power_domain_lookup_name("conn_sdhc2", &pd)) 201 power_domain_on(&pd); 202 203 imx8_iomux_setup_multiple_pads(usdhc2_sd, ARRAY_SIZE(usdhc2_sd)); 204 init_clk_usdhc(2); 205 usdhc_cfg[i].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK); 206 gpio_request(USDHC2_CD_GPIO, "sd2_cd"); 207 gpio_direction_input(USDHC2_CD_GPIO); 208 break; 209 default: 210 printf("Warning: you configured more USDHC controllers" 211 "(%d) than supported by the board\n", i + 1); 212 return 0; 213 } 214 ret = fsl_esdhc_initialize(bis, &usdhc_cfg[i]); 215 if (ret) { 216 printf("Warning: failed to initialize mmc dev %d\n", i); 217 return ret; 218 } 219 } 220 221 return 0; 222} 223 224int board_mmc_getcd(struct mmc *mmc) 225{ 226 struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv; 227 int ret = 0; 228 229 switch (cfg->esdhc_base) { 230 case USDHC1_BASE_ADDR: 231 ret = 1; 232 break; 233 case USDHC2_BASE_ADDR: 234 ret = !gpio_get_value(USDHC1_CD_GPIO); 235 break; 236 case USDHC3_BASE_ADDR: 237 ret = !gpio_get_value(USDHC2_CD_GPIO); 238 break; 239 } 240 241 return ret; 242} 243 244#endif /* CONFIG_FSL_ESDHC_IMX */ 245 246#if (IS_ENABLED(CONFIG_FEC_MXC)) 247 248#include <miiphy.h> 249 250static iomux_cfg_t pad_enet0[] = { 251 SC_P_ENET0_RGMII_RX_CTL | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), 252 SC_P_ENET0_RGMII_RXD0 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), 253 SC_P_ENET0_RGMII_RXD1 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), 254 SC_P_ENET0_RGMII_RXD2 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), 255 SC_P_ENET0_RGMII_RXD3 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), 256 SC_P_ENET0_RGMII_RXC | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), 257 SC_P_ENET0_RGMII_TX_CTL | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), 258 SC_P_ENET0_RGMII_TXD0 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), 259 SC_P_ENET0_RGMII_TXD1 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), 260 SC_P_ENET0_RGMII_TXD2 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), 261 SC_P_ENET0_RGMII_TXD3 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), 262 SC_P_ENET0_RGMII_TXC | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), 263 SC_P_ENET0_MDC | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), 264 SC_P_ENET0_MDIO | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), 265}; 266 267static void setup_iomux_fec(void) 268{ 269 imx8_iomux_setup_multiple_pads(pad_enet0, ARRAY_SIZE(pad_enet0)); 270} 271 272static void enet_device_phy_reset(void) 273{ 274 gpio_set_value(FEC0_RESET, 0); 275 udelay(50); 276 gpio_set_value(FEC0_RESET, 1); 277 278 /* The board has a long delay for this reset to become stable */ 279 mdelay(200); 280} 281 282int board_eth_init(struct bd_info *bis) 283{ 284 setup_iomux_fec(); 285 286 return 0; 287} 288 289int board_phy_config(struct phy_device *phydev) 290{ 291 phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x1f); 292 phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x8); 293 294 phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x00); 295 phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x82ee); 296 phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x05); 297 phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x100); 298 299 if (phydev->drv->config) 300 phydev->drv->config(phydev); 301 302 return 0; 303} 304 305static int setup_fec(void) 306{ 307 /* Reset ENET PHY */ 308 enet_device_phy_reset(); 309 310 return 0; 311} 312#endif 313 314#ifdef CONFIG_MXC_GPIO 315 316#define LVDS_ENABLE IMX_GPIO_NR(1, 6) 317#define BKL_ENABLE IMX_GPIO_NR(1, 7) 318 319static iomux_cfg_t board_gpios[] = { 320 SC_P_LVDS0_I2C0_SCL | MUX_MODE_ALT(3) | MUX_PAD_CTRL(GPIO_PAD_CTRL), 321 SC_P_LVDS0_I2C0_SDA | MUX_MODE_ALT(3) | MUX_PAD_CTRL(GPIO_PAD_CTRL), 322 SC_P_ESAI1_FST | MUX_MODE_ALT(3) | MUX_PAD_CTRL(GPIO_PAD_CTRL), 323}; 324 325static void board_gpio_init(void) 326{ 327 imx8_iomux_setup_multiple_pads(board_gpios, ARRAY_SIZE(board_gpios)); 328 329 /* enable LVDS */ 330 gpio_request(LVDS_ENABLE, "lvds_enable"); 331 gpio_direction_output(LVDS_ENABLE, 1); 332 333 /* enable backlight */ 334 gpio_request(BKL_ENABLE, "bkl_enable"); 335 gpio_direction_output(BKL_ENABLE, 1); 336 337 /* ethernet reset */ 338 gpio_request(FEC0_RESET, "enet0_reset"); 339 gpio_direction_output(FEC0_RESET, 1); 340} 341#endif 342 343int checkboard(void) 344{ 345 puts("Board: conga-QMX8\n"); 346 347 build_info(); 348 print_bootinfo(); 349 350 return 0; 351} 352 353int board_init(void) 354{ 355 if (IS_ENABLED(CONFIG_XEN)) 356 return 0; 357 358#ifdef CONFIG_MXC_GPIO 359 board_gpio_init(); 360#endif 361 362#if (IS_ENABLED(CONFIG_FEC_MXC)) 363 setup_fec(); 364#endif 365 366 return 0; 367} 368 369void detail_board_ddr_info(void) 370{ 371 puts("\nDDR "); 372} 373 374 375#ifdef CONFIG_OF_BOARD_SETUP 376int ft_board_setup(void *blob, struct bd_info *bd) 377{ 378 return 0; 379} 380#endif 381 382int board_mmc_get_env_dev(int devno) 383{ 384 /* Use EMMC */ 385 if (IS_ENABLED(CONFIG_XEN)) 386 return 0; 387 388 return devno; 389} 390 391int mmc_map_to_kernel_blk(int dev_no) 392{ 393 /* Use EMMC */ 394 if (IS_ENABLED(CONFIG_XEN)) 395 return 0; 396 397 return dev_no; 398} 399 400extern u32 _end_ofs; 401int board_late_init(void) 402{ 403#ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG 404 env_set("board_name", "QMX8"); 405 env_set("board_rev", "iMX8QM"); 406#endif 407 408 env_set("sec_boot", "no"); 409#ifdef CONFIG_AHAB_BOOT 410 env_set("sec_boot", "yes"); 411#endif 412 413#ifdef CONFIG_ENV_IS_IN_MMC 414 board_late_mmc_env_init(); 415#endif 416 417#ifdef IMX_LOAD_HDMI_FIMRWARE 418 char *end_of_uboot; 419 char command[256]; 420 421 end_of_uboot = (char *)(ulong)(CONFIG_TEXT_BASE + _end_ofs 422 + fdt_totalsize(gd->fdt_blob)); 423 end_of_uboot += 9; 424 425 /* load hdmitxfw.bin and hdmirxfw.bin*/ 426 memcpy(IMX_HDMI_FIRMWARE_LOAD_ADDR, end_of_uboot, 427 IMX_HDMITX_FIRMWARE_SIZE + IMX_HDMIRX_FIRMWARE_SIZE); 428 429 sprintf(command, "hdp load 0x%x", IMX_HDMI_FIRMWARE_LOAD_ADDR); 430 run_command(command, 0); 431 432 sprintf(command, "hdprx load 0x%x", 433 IMX_HDMI_FIRMWARE_LOAD_ADDR + IMX_HDMITX_FIRMWARE_SIZE); 434 run_command(command, 0); 435#endif 436 437 return 0; 438} 439 440#ifdef CONFIG_FSL_FASTBOOT 441#ifdef CONFIG_ANDROID_RECOVERY 442int is_recovery_key_pressing(void) 443{ 444 return 0; /*TODO*/ 445} 446#endif /*CONFIG_ANDROID_RECOVERY*/ 447#endif /*CONFIG_FSL_FASTBOOT*/ 448 449/* Only Enable USB3 resources currently */ 450int board_usb_init(int index, enum usb_init_type init) 451{ 452 return 0; 453} 454