uboot/board/dhelectronics/dh_stm32mp1/board.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
   2/*
   3 * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
   4 */
   5
   6#include <common.h>
   7#include <adc.h>
   8#include <log.h>
   9#include <net.h>
  10#include <asm/arch/stm32.h>
  11#include <asm/arch/sys_proto.h>
  12#include <asm/global_data.h>
  13#include <asm/gpio.h>
  14#include <asm/io.h>
  15#include <bootm.h>
  16#include <clk.h>
  17#include <config.h>
  18#include <dm.h>
  19#include <dm/device.h>
  20#include <dm/uclass.h>
  21#include <env.h>
  22#include <env_internal.h>
  23#include <g_dnl.h>
  24#include <generic-phy.h>
  25#include <hang.h>
  26#include <i2c.h>
  27#include <i2c_eeprom.h>
  28#include <init.h>
  29#include <led.h>
  30#include <memalign.h>
  31#include <misc.h>
  32#include <mtd.h>
  33#include <mtd_node.h>
  34#include <netdev.h>
  35#include <phy.h>
  36#include <linux/bitops.h>
  37#include <linux/delay.h>
  38#include <power/regulator.h>
  39#include <remoteproc.h>
  40#include <reset.h>
  41#include <syscon.h>
  42#include <usb.h>
  43#include <usb/dwc2_udc.h>
  44#include <watchdog.h>
  45#include <dm/ofnode.h>
  46#include "../../st/common/stpmic1.h"
  47
  48/* SYSCFG registers */
  49#define SYSCFG_BOOTR            0x00
  50#define SYSCFG_PMCSETR          0x04
  51#define SYSCFG_IOCTRLSETR       0x18
  52#define SYSCFG_ICNR             0x1C
  53#define SYSCFG_CMPCR            0x20
  54#define SYSCFG_CMPENSETR        0x24
  55#define SYSCFG_PMCCLRR          0x44
  56
  57#define SYSCFG_BOOTR_BOOT_MASK          GENMASK(2, 0)
  58#define SYSCFG_BOOTR_BOOTPD_SHIFT       4
  59
  60#define SYSCFG_IOCTRLSETR_HSLVEN_TRACE          BIT(0)
  61#define SYSCFG_IOCTRLSETR_HSLVEN_QUADSPI        BIT(1)
  62#define SYSCFG_IOCTRLSETR_HSLVEN_ETH            BIT(2)
  63#define SYSCFG_IOCTRLSETR_HSLVEN_SDMMC          BIT(3)
  64#define SYSCFG_IOCTRLSETR_HSLVEN_SPI            BIT(4)
  65
  66#define SYSCFG_CMPCR_SW_CTRL            BIT(1)
  67#define SYSCFG_CMPCR_READY              BIT(8)
  68
  69#define SYSCFG_CMPENSETR_MPU_EN         BIT(0)
  70
  71#define SYSCFG_PMCSETR_ETH_CLK_SEL      BIT(16)
  72#define SYSCFG_PMCSETR_ETH_REF_CLK_SEL  BIT(17)
  73
  74#define SYSCFG_PMCSETR_ETH_SELMII       BIT(20)
  75
  76#define SYSCFG_PMCSETR_ETH_SEL_MASK     GENMASK(23, 21)
  77#define SYSCFG_PMCSETR_ETH_SEL_GMII_MII 0
  78#define SYSCFG_PMCSETR_ETH_SEL_RGMII    BIT(21)
  79#define SYSCFG_PMCSETR_ETH_SEL_RMII     BIT(23)
  80
  81/*
  82 * Get a global data pointer
  83 */
  84DECLARE_GLOBAL_DATA_PTR;
  85
  86#define KS_CCR          0x08
  87#define KS_CCR_EEPROM   BIT(9)
  88#define KS_BE0          BIT(12)
  89#define KS_BE1          BIT(13)
  90#define KS_CIDER        0xC0
  91#define CIDER_ID        0x8870
  92
  93int setup_mac_address(void)
  94{
  95        unsigned char enetaddr[6];
  96        bool skip_eth0 = false;
  97        bool skip_eth1 = false;
  98        struct udevice *dev;
  99        int off, ret;
 100
 101        ret = eth_env_get_enetaddr("ethaddr", enetaddr);
 102        if (ret)        /* ethaddr is already set */
 103                skip_eth0 = true;
 104
 105        off = fdt_path_offset(gd->fdt_blob, "ethernet1");
 106        if (off < 0) {
 107                /* ethernet1 is not present in the system */
 108                skip_eth1 = true;
 109                goto out_set_ethaddr;
 110        }
 111
 112        ret = eth_env_get_enetaddr("eth1addr", enetaddr);
 113        if (ret) {
 114                /* eth1addr is already set */
 115                skip_eth1 = true;
 116                goto out_set_ethaddr;
 117        }
 118
 119        ret = fdt_node_check_compatible(gd->fdt_blob, off, "micrel,ks8851-mll");
 120        if (ret)
 121                goto out_set_ethaddr;
 122
 123        /*
 124         * KS8851 with EEPROM may use custom MAC from EEPROM, read
 125         * out the KS8851 CCR register to determine whether EEPROM
 126         * is present. If EEPROM is present, it must contain valid
 127         * MAC address.
 128         */
 129        u32 reg, cider, ccr;
 130        reg = fdt_get_base_address(gd->fdt_blob, off);
 131        if (!reg)
 132                goto out_set_ethaddr;
 133
 134        writew(KS_BE0 | KS_BE1 | KS_CIDER, reg + 2);
 135        cider = readw(reg);
 136        if ((cider & 0xfff0) != CIDER_ID) {
 137                skip_eth1 = true;
 138                goto out_set_ethaddr;
 139        }
 140
 141        writew(KS_BE0 | KS_BE1 | KS_CCR, reg + 2);
 142        ccr = readw(reg);
 143        if (ccr & KS_CCR_EEPROM) {
 144                skip_eth1 = true;
 145                goto out_set_ethaddr;
 146        }
 147
 148out_set_ethaddr:
 149        if (skip_eth0 && skip_eth1)
 150                return 0;
 151
 152        off = fdt_path_offset(gd->fdt_blob, "eeprom0");
 153        if (off < 0) {
 154                printf("%s: No eeprom0 path offset\n", __func__);
 155                return off;
 156        }
 157
 158        ret = uclass_get_device_by_of_offset(UCLASS_I2C_EEPROM, off, &dev);
 159        if (ret) {
 160                printf("Cannot find EEPROM!\n");
 161                return ret;
 162        }
 163
 164        ret = i2c_eeprom_read(dev, 0xfa, enetaddr, 0x6);
 165        if (ret) {
 166                printf("Error reading configuration EEPROM!\n");
 167                return ret;
 168        }
 169
 170        if (is_valid_ethaddr(enetaddr)) {
 171                if (!skip_eth0)
 172                        eth_env_set_enetaddr("ethaddr", enetaddr);
 173
 174                enetaddr[5]++;
 175                if (!skip_eth1)
 176                        eth_env_set_enetaddr("eth1addr", enetaddr);
 177        }
 178
 179        return 0;
 180}
 181
 182int checkboard(void)
 183{
 184        char *mode;
 185        const char *fdt_compat;
 186        int fdt_compat_len;
 187
 188        if (IS_ENABLED(CONFIG_TFABOOT))
 189                mode = "trusted";
 190        else
 191                mode = "basic";
 192
 193        printf("Board: stm32mp1 in %s mode", mode);
 194        fdt_compat = fdt_getprop(gd->fdt_blob, 0, "compatible",
 195                                 &fdt_compat_len);
 196        if (fdt_compat && fdt_compat_len)
 197                printf(" (%s)", fdt_compat);
 198        puts("\n");
 199
 200        return 0;
 201}
 202
 203#ifdef CONFIG_BOARD_EARLY_INIT_F
 204static u8 brdcode __section("data");
 205static u8 ddr3code __section("data");
 206static u8 somcode __section("data");
 207static u32 opp_voltage_mv __section(".data");
 208
 209static void board_get_coding_straps(void)
 210{
 211        struct gpio_desc gpio[4];
 212        ofnode node;
 213        int i, ret;
 214
 215        brdcode = 0;
 216        ddr3code = 0;
 217        somcode = 0;
 218
 219        node = ofnode_path("/config");
 220        if (!ofnode_valid(node)) {
 221                printf("%s: no /config node?\n", __func__);
 222                return;
 223        }
 224
 225        ret = gpio_request_list_by_name_nodev(node, "dh,som-coding-gpios",
 226                                              gpio, ARRAY_SIZE(gpio),
 227                                              GPIOD_IS_IN);
 228        for (i = 0; i < ret; i++)
 229                somcode |= !!dm_gpio_get_value(&(gpio[i])) << i;
 230
 231        gpio_free_list_nodev(gpio, ret);
 232
 233        ret = gpio_request_list_by_name_nodev(node, "dh,ddr3-coding-gpios",
 234                                              gpio, ARRAY_SIZE(gpio),
 235                                              GPIOD_IS_IN);
 236        for (i = 0; i < ret; i++)
 237                ddr3code |= !!dm_gpio_get_value(&(gpio[i])) << i;
 238
 239        gpio_free_list_nodev(gpio, ret);
 240
 241        ret = gpio_request_list_by_name_nodev(node, "dh,board-coding-gpios",
 242                                              gpio, ARRAY_SIZE(gpio),
 243                                              GPIOD_IS_IN);
 244        for (i = 0; i < ret; i++)
 245                brdcode |= !!dm_gpio_get_value(&(gpio[i])) << i;
 246
 247        gpio_free_list_nodev(gpio, ret);
 248
 249        printf("Code:  SoM:rev=%d,ddr3=%d Board:rev=%d\n",
 250                somcode, ddr3code, brdcode);
 251}
 252
 253int board_stm32mp1_ddr_config_name_match(struct udevice *dev,
 254                                         const char *name)
 255{
 256        if (ddr3code == 1 &&
 257            !strcmp(name, "st,ddr3l-dhsom-1066-888-bin-g-2x1gb-533mhz"))
 258                return 0;
 259
 260        if (ddr3code == 2 &&
 261            !strcmp(name, "st,ddr3l-dhsom-1066-888-bin-g-2x2gb-533mhz"))
 262                return 0;
 263
 264        if (ddr3code == 3 &&
 265            !strcmp(name, "st,ddr3l-dhsom-1066-888-bin-g-2x4gb-533mhz"))
 266                return 0;
 267
 268        return -EINVAL;
 269}
 270
 271void board_vddcore_init(u32 voltage_mv)
 272{
 273        if (IS_ENABLED(CONFIG_SPL_BUILD))
 274                opp_voltage_mv = voltage_mv;
 275}
 276
 277int board_early_init_f(void)
 278{
 279        if (IS_ENABLED(CONFIG_SPL_BUILD))
 280                stpmic1_init(opp_voltage_mv);
 281        board_get_coding_straps();
 282
 283        return 0;
 284}
 285
 286#ifdef CONFIG_SPL_LOAD_FIT
 287int board_fit_config_name_match(const char *name)
 288{
 289        const char *compat;
 290        char test[128];
 291
 292        compat = fdt_getprop(gd->fdt_blob, 0, "compatible", NULL);
 293
 294        snprintf(test, sizeof(test), "%s_somrev%d_boardrev%d",
 295                compat, somcode, brdcode);
 296
 297        if (!strcmp(name, test))
 298                return 0;
 299
 300        return -EINVAL;
 301}
 302#endif
 303#endif
 304
 305static void board_key_check(void)
 306{
 307#if defined(CONFIG_FASTBOOT) || defined(CONFIG_CMD_STM32PROG)
 308        ofnode node;
 309        struct gpio_desc gpio;
 310        enum forced_boot_mode boot_mode = BOOT_NORMAL;
 311
 312        node = ofnode_path("/config");
 313        if (!ofnode_valid(node)) {
 314                debug("%s: no /config node?\n", __func__);
 315                return;
 316        }
 317#ifdef CONFIG_FASTBOOT
 318        if (gpio_request_by_name_nodev(node, "st,fastboot-gpios", 0,
 319                                       &gpio, GPIOD_IS_IN)) {
 320                debug("%s: could not find a /config/st,fastboot-gpios\n",
 321                      __func__);
 322        } else {
 323                if (dm_gpio_get_value(&gpio)) {
 324                        puts("Fastboot key pressed, ");
 325                        boot_mode = BOOT_FASTBOOT;
 326                }
 327
 328                dm_gpio_free(NULL, &gpio);
 329        }
 330#endif
 331#ifdef CONFIG_CMD_STM32PROG
 332        if (gpio_request_by_name_nodev(node, "st,stm32prog-gpios", 0,
 333                                       &gpio, GPIOD_IS_IN)) {
 334                debug("%s: could not find a /config/st,stm32prog-gpios\n",
 335                      __func__);
 336        } else {
 337                if (dm_gpio_get_value(&gpio)) {
 338                        puts("STM32Programmer key pressed, ");
 339                        boot_mode = BOOT_STM32PROG;
 340                }
 341                dm_gpio_free(NULL, &gpio);
 342        }
 343#endif
 344
 345        if (boot_mode != BOOT_NORMAL) {
 346                puts("entering download mode...\n");
 347                clrsetbits_le32(TAMP_BOOT_CONTEXT,
 348                                TAMP_BOOT_FORCED_MASK,
 349                                boot_mode);
 350        }
 351#endif
 352}
 353
 354#if defined(CONFIG_USB_GADGET) && defined(CONFIG_USB_GADGET_DWC2_OTG)
 355
 356#include <usb/dwc2_udc.h>
 357int g_dnl_board_usb_cable_connected(void)
 358{
 359        struct udevice *dwc2_udc_otg;
 360        int ret;
 361
 362        ret = uclass_get_device_by_driver(UCLASS_USB_GADGET_GENERIC,
 363                                          DM_DRIVER_GET(dwc2_udc_otg),
 364                                          &dwc2_udc_otg);
 365        if (!ret)
 366                debug("dwc2_udc_otg init failed\n");
 367
 368        return dwc2_udc_B_session_valid(dwc2_udc_otg);
 369}
 370
 371#define STM32MP1_G_DNL_DFU_PRODUCT_NUM 0xdf11
 372#define STM32MP1_G_DNL_FASTBOOT_PRODUCT_NUM 0x0afb
 373
 374int g_dnl_bind_fixup(struct usb_device_descriptor *dev, const char *name)
 375{
 376        if (!strcmp(name, "usb_dnl_dfu"))
 377                put_unaligned(STM32MP1_G_DNL_DFU_PRODUCT_NUM, &dev->idProduct);
 378        else if (!strcmp(name, "usb_dnl_fastboot"))
 379                put_unaligned(STM32MP1_G_DNL_FASTBOOT_PRODUCT_NUM,
 380                              &dev->idProduct);
 381        else
 382                put_unaligned(CONFIG_USB_GADGET_PRODUCT_NUM, &dev->idProduct);
 383
 384        return 0;
 385}
 386
 387#endif /* CONFIG_USB_GADGET */
 388
 389#ifdef CONFIG_LED
 390static int get_led(struct udevice **dev, char *led_string)
 391{
 392        const char *led_name;
 393        int ret;
 394
 395        led_name = ofnode_conf_read_str(led_string);
 396        if (!led_name) {
 397                pr_debug("%s: could not find %s config string\n",
 398                         __func__, led_string);
 399                return -ENOENT;
 400        }
 401        ret = led_get_by_label(led_name, dev);
 402        if (ret) {
 403                debug("%s: get=%d\n", __func__, ret);
 404                return ret;
 405        }
 406
 407        return 0;
 408}
 409
 410static int setup_led(enum led_state_t cmd)
 411{
 412        struct udevice *dev;
 413        int ret;
 414
 415        ret = get_led(&dev, "u-boot,boot-led");
 416        if (ret)
 417                return ret;
 418
 419        ret = led_set_state(dev, cmd);
 420        return ret;
 421}
 422#endif
 423
 424static void __maybe_unused led_error_blink(u32 nb_blink)
 425{
 426#ifdef CONFIG_LED
 427        int ret;
 428        struct udevice *led;
 429        u32 i;
 430#endif
 431
 432        if (!nb_blink)
 433                return;
 434
 435#ifdef CONFIG_LED
 436        ret = get_led(&led, "u-boot,error-led");
 437        if (!ret) {
 438                /* make u-boot,error-led blinking */
 439                /* if U32_MAX and 125ms interval, for 17.02 years */
 440                for (i = 0; i < 2 * nb_blink; i++) {
 441                        led_set_state(led, LEDST_TOGGLE);
 442                        mdelay(125);
 443                        WATCHDOG_RESET();
 444                }
 445        }
 446#endif
 447
 448        /* infinite: the boot process must be stopped */
 449        if (nb_blink == U32_MAX)
 450                hang();
 451}
 452
 453static void sysconf_init(void)
 454{
 455#ifndef CONFIG_TFABOOT
 456        u8 *syscfg;
 457#ifdef CONFIG_DM_REGULATOR
 458        struct udevice *pwr_dev;
 459        struct udevice *pwr_reg;
 460        struct udevice *dev;
 461        int ret;
 462        u32 otp = 0;
 463#endif
 464        u32 bootr;
 465
 466        syscfg = (u8 *)syscon_get_first_range(STM32MP_SYSCON_SYSCFG);
 467
 468        /* interconnect update : select master using the port 1 */
 469        /* LTDC = AXI_M9 */
 470        /* GPU  = AXI_M8 */
 471        /* today information is hardcoded in U-Boot */
 472        writel(BIT(9), syscfg + SYSCFG_ICNR);
 473
 474        /* disable Pull-Down for boot pin connected to VDD */
 475        bootr = readl(syscfg + SYSCFG_BOOTR);
 476        bootr &= ~(SYSCFG_BOOTR_BOOT_MASK << SYSCFG_BOOTR_BOOTPD_SHIFT);
 477        bootr |= (bootr & SYSCFG_BOOTR_BOOT_MASK) << SYSCFG_BOOTR_BOOTPD_SHIFT;
 478        writel(bootr, syscfg + SYSCFG_BOOTR);
 479
 480#ifdef CONFIG_DM_REGULATOR
 481        /* High Speed Low Voltage Pad mode Enable for SPI, SDMMC, ETH, QSPI
 482         * and TRACE. Needed above ~50MHz and conditioned by AFMUX selection.
 483         * The customer will have to disable this for low frequencies
 484         * or if AFMUX is selected but the function not used, typically for
 485         * TRACE. Otherwise, impact on power consumption.
 486         *
 487         * WARNING:
 488         *   enabling High Speed mode while VDD>2.7V
 489         *   with the OTP product_below_2v5 (OTP 18, BIT 13)
 490         *   erroneously set to 1 can damage the IC!
 491         *   => U-Boot set the register only if VDD < 2.7V (in DT)
 492         *      but this value need to be consistent with board design
 493         */
 494        ret = uclass_get_device_by_driver(UCLASS_PMIC,
 495                                          DM_DRIVER_GET(stm32mp_pwr_pmic),
 496                                          &pwr_dev);
 497        if (!ret) {
 498                ret = uclass_get_device_by_driver(UCLASS_MISC,
 499                                                  DM_DRIVER_GET(stm32mp_bsec),
 500                                                  &dev);
 501                if (ret) {
 502                        pr_err("Can't find stm32mp_bsec driver\n");
 503                        return;
 504                }
 505
 506                ret = misc_read(dev, STM32_BSEC_SHADOW(18), &otp, 4);
 507                if (ret > 0)
 508                        otp = otp & BIT(13);
 509
 510                /* get VDD = vdd-supply */
 511                ret = device_get_supply_regulator(pwr_dev, "vdd-supply",
 512                                                  &pwr_reg);
 513
 514                /* check if VDD is Low Voltage */
 515                if (!ret) {
 516                        if (regulator_get_value(pwr_reg) < 2700000) {
 517                                writel(SYSCFG_IOCTRLSETR_HSLVEN_TRACE |
 518                                       SYSCFG_IOCTRLSETR_HSLVEN_QUADSPI |
 519                                       SYSCFG_IOCTRLSETR_HSLVEN_ETH |
 520                                       SYSCFG_IOCTRLSETR_HSLVEN_SDMMC |
 521                                       SYSCFG_IOCTRLSETR_HSLVEN_SPI,
 522                                       syscfg + SYSCFG_IOCTRLSETR);
 523
 524                                if (!otp)
 525                                        pr_err("product_below_2v5=0: HSLVEN protected by HW\n");
 526                        } else {
 527                                if (otp)
 528                                        pr_err("product_below_2v5=1: HSLVEN update is destructive, no update as VDD>2.7V\n");
 529                        }
 530                } else {
 531                        debug("VDD unknown");
 532                }
 533        }
 534#endif
 535
 536        /* activate automatic I/O compensation
 537         * warning: need to ensure CSI enabled and ready in clock driver
 538         */
 539        writel(SYSCFG_CMPENSETR_MPU_EN, syscfg + SYSCFG_CMPENSETR);
 540
 541        while (!(readl(syscfg + SYSCFG_CMPCR) & SYSCFG_CMPCR_READY))
 542                ;
 543        clrbits_le32(syscfg + SYSCFG_CMPCR, SYSCFG_CMPCR_SW_CTRL);
 544#endif
 545}
 546
 547static void board_init_fmc2(void)
 548{
 549#define STM32_FMC2_BCR1                 0x0
 550#define STM32_FMC2_BTR1                 0x4
 551#define STM32_FMC2_BWTR1                0x104
 552#define STM32_FMC2_BCR(x)               ((x) * 0x8 + STM32_FMC2_BCR1)
 553#define STM32_FMC2_BCRx_FMCEN           BIT(31)
 554#define STM32_FMC2_BCRx_WREN            BIT(12)
 555#define STM32_FMC2_BCRx_RSVD            BIT(7)
 556#define STM32_FMC2_BCRx_FACCEN          BIT(6)
 557#define STM32_FMC2_BCRx_MWID(n)         ((n) << 4)
 558#define STM32_FMC2_BCRx_MTYP(n)         ((n) << 2)
 559#define STM32_FMC2_BCRx_MUXEN           BIT(1)
 560#define STM32_FMC2_BCRx_MBKEN           BIT(0)
 561#define STM32_FMC2_BTR(x)               ((x) * 0x8 + STM32_FMC2_BTR1)
 562#define STM32_FMC2_BTRx_DATAHLD(n)      ((n) << 30)
 563#define STM32_FMC2_BTRx_BUSTURN(n)      ((n) << 16)
 564#define STM32_FMC2_BTRx_DATAST(n)       ((n) << 8)
 565#define STM32_FMC2_BTRx_ADDHLD(n)       ((n) << 4)
 566#define STM32_FMC2_BTRx_ADDSET(n)       ((n) << 0)
 567
 568#define RCC_MP_AHB6RSTCLRR              0x218
 569#define RCC_MP_AHB6RSTCLRR_FMCRST       BIT(12)
 570#define RCC_MP_AHB6ENSETR               0x19c
 571#define RCC_MP_AHB6ENSETR_FMCEN         BIT(12)
 572
 573        const u32 bcr = STM32_FMC2_BCRx_WREN |STM32_FMC2_BCRx_RSVD |
 574                        STM32_FMC2_BCRx_FACCEN | STM32_FMC2_BCRx_MWID(1) |
 575                        STM32_FMC2_BCRx_MTYP(2) | STM32_FMC2_BCRx_MUXEN |
 576                        STM32_FMC2_BCRx_MBKEN;
 577        const u32 btr = STM32_FMC2_BTRx_DATAHLD(3) |
 578                        STM32_FMC2_BTRx_BUSTURN(2) |
 579                        STM32_FMC2_BTRx_DATAST(0x22) |
 580                        STM32_FMC2_BTRx_ADDHLD(2) |
 581                        STM32_FMC2_BTRx_ADDSET(2);
 582
 583        /* Set up FMC2 bus for KS8851-16MLL and X11 SRAM */
 584        writel(RCC_MP_AHB6RSTCLRR_FMCRST, STM32_RCC_BASE + RCC_MP_AHB6RSTCLRR);
 585        writel(RCC_MP_AHB6ENSETR_FMCEN, STM32_RCC_BASE + RCC_MP_AHB6ENSETR);
 586
 587        /* KS8851-16MLL -- Muxed mode */
 588        writel(bcr, STM32_FMC2_BASE + STM32_FMC2_BCR(1));
 589        writel(btr, STM32_FMC2_BASE + STM32_FMC2_BTR(1));
 590        /* AS7C34098 SRAM on X11 -- Muxed mode */
 591        writel(bcr, STM32_FMC2_BASE + STM32_FMC2_BCR(3));
 592        writel(btr, STM32_FMC2_BASE + STM32_FMC2_BTR(3));
 593
 594        setbits_le32(STM32_FMC2_BASE + STM32_FMC2_BCR1, STM32_FMC2_BCRx_FMCEN);
 595}
 596
 597/* board dependent setup after realloc */
 598int board_init(void)
 599{
 600        board_key_check();
 601
 602#ifdef CONFIG_DM_REGULATOR
 603        regulators_enable_boot_on(_DEBUG);
 604#endif
 605
 606        sysconf_init();
 607
 608        board_init_fmc2();
 609
 610        if (CONFIG_IS_ENABLED(LED))
 611                led_default_state();
 612
 613        return 0;
 614}
 615
 616int board_late_init(void)
 617{
 618        char *boot_device;
 619#ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
 620        const void *fdt_compat;
 621        int fdt_compat_len;
 622
 623        fdt_compat = fdt_getprop(gd->fdt_blob, 0, "compatible",
 624                                 &fdt_compat_len);
 625        if (fdt_compat && fdt_compat_len) {
 626                if (strncmp(fdt_compat, "st,", 3) != 0)
 627                        env_set("board_name", fdt_compat);
 628                else
 629                        env_set("board_name", fdt_compat + 3);
 630        }
 631#endif
 632
 633        /* Check the boot-source to disable bootdelay */
 634        boot_device = env_get("boot_device");
 635        if (!strcmp(boot_device, "serial") || !strcmp(boot_device, "usb"))
 636                env_set("bootdelay", "0");
 637
 638#ifdef CONFIG_BOARD_EARLY_INIT_F
 639        env_set_ulong("dh_som_rev", somcode);
 640        env_set_ulong("dh_board_rev", brdcode);
 641        env_set_ulong("dh_ddr3_code", ddr3code);
 642#endif
 643
 644        return 0;
 645}
 646
 647void board_quiesce_devices(void)
 648{
 649#ifdef CONFIG_LED
 650        setup_led(LEDST_OFF);
 651#endif
 652}
 653
 654/* eth init function : weak called in eqos driver */
 655int board_interface_eth_init(struct udevice *dev,
 656                             phy_interface_t interface_type)
 657{
 658        u8 *syscfg;
 659        u32 value;
 660        bool eth_clk_sel_reg = false;
 661        bool eth_ref_clk_sel_reg = false;
 662
 663        /* Gigabit Ethernet 125MHz clock selection. */
 664        eth_clk_sel_reg = dev_read_bool(dev, "st,eth-clk-sel");
 665
 666        /* Ethernet 50Mhz RMII clock selection */
 667        eth_ref_clk_sel_reg =
 668                dev_read_bool(dev, "st,eth-ref-clk-sel");
 669
 670        syscfg = (u8 *)syscon_get_first_range(STM32MP_SYSCON_SYSCFG);
 671
 672        if (!syscfg)
 673                return -ENODEV;
 674
 675        switch (interface_type) {
 676        case PHY_INTERFACE_MODE_MII:
 677                value = SYSCFG_PMCSETR_ETH_SEL_GMII_MII |
 678                        SYSCFG_PMCSETR_ETH_REF_CLK_SEL;
 679                debug("%s: PHY_INTERFACE_MODE_MII\n", __func__);
 680                break;
 681        case PHY_INTERFACE_MODE_GMII:
 682                if (eth_clk_sel_reg)
 683                        value = SYSCFG_PMCSETR_ETH_SEL_GMII_MII |
 684                                SYSCFG_PMCSETR_ETH_CLK_SEL;
 685                else
 686                        value = SYSCFG_PMCSETR_ETH_SEL_GMII_MII;
 687                debug("%s: PHY_INTERFACE_MODE_GMII\n", __func__);
 688                break;
 689        case PHY_INTERFACE_MODE_RMII:
 690                if (eth_ref_clk_sel_reg)
 691                        value = SYSCFG_PMCSETR_ETH_SEL_RMII |
 692                                SYSCFG_PMCSETR_ETH_REF_CLK_SEL;
 693                else
 694                        value = SYSCFG_PMCSETR_ETH_SEL_RMII;
 695                debug("%s: PHY_INTERFACE_MODE_RMII\n", __func__);
 696                break;
 697        case PHY_INTERFACE_MODE_RGMII:
 698        case PHY_INTERFACE_MODE_RGMII_ID:
 699        case PHY_INTERFACE_MODE_RGMII_RXID:
 700        case PHY_INTERFACE_MODE_RGMII_TXID:
 701                if (eth_clk_sel_reg)
 702                        value = SYSCFG_PMCSETR_ETH_SEL_RGMII |
 703                                SYSCFG_PMCSETR_ETH_CLK_SEL;
 704                else
 705                        value = SYSCFG_PMCSETR_ETH_SEL_RGMII;
 706                debug("%s: PHY_INTERFACE_MODE_RGMII\n", __func__);
 707                break;
 708        default:
 709                debug("%s: Do not manage %d interface\n",
 710                      __func__, interface_type);
 711                /* Do not manage others interfaces */
 712                return -EINVAL;
 713        }
 714
 715        /* clear and set ETH configuration bits */
 716        writel(SYSCFG_PMCSETR_ETH_SEL_MASK | SYSCFG_PMCSETR_ETH_SELMII |
 717               SYSCFG_PMCSETR_ETH_REF_CLK_SEL | SYSCFG_PMCSETR_ETH_CLK_SEL,
 718               syscfg + SYSCFG_PMCCLRR);
 719        writel(value, syscfg + SYSCFG_PMCSETR);
 720
 721        return 0;
 722}
 723
 724#if defined(CONFIG_OF_BOARD_SETUP)
 725int ft_board_setup(void *blob, struct bd_info *bd)
 726{
 727        return 0;
 728}
 729#endif
 730
 731static void board_copro_image_process(ulong fw_image, size_t fw_size)
 732{
 733        int ret, id = 0; /* Copro id fixed to 0 as only one coproc on mp1 */
 734
 735        if (!rproc_is_initialized())
 736                if (rproc_init()) {
 737                        printf("Remote Processor %d initialization failed\n",
 738                               id);
 739                        return;
 740                }
 741
 742        ret = rproc_load(id, fw_image, fw_size);
 743        printf("Load Remote Processor %d with data@addr=0x%08lx %u bytes:%s\n",
 744               id, fw_image, fw_size, ret ? " Failed!" : " Success!");
 745
 746        if (!ret) {
 747                rproc_start(id);
 748                env_set("copro_state", "booted");
 749        }
 750}
 751
 752U_BOOT_FIT_LOADABLE_HANDLER(IH_TYPE_COPRO, board_copro_image_process);
 753