uboot/board/siemens/capricorn/board.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright 2017-2019 NXP
   4 *
   5 * Copyright 2019 Siemens AG
   6 *
   7 */
   8#include <common.h>
   9#include <command.h>
  10#include <dm.h>
  11#include <env.h>
  12#include <errno.h>
  13#include <init.h>
  14#include <log.h>
  15#include <netdev.h>
  16#include <env_internal.h>
  17#include <fsl_esdhc_imx.h>
  18#include <i2c.h>
  19#include <led.h>
  20#include <pca953x.h>
  21#include <power-domain.h>
  22#include <asm/gpio.h>
  23#include <asm/arch/imx8-pins.h>
  24#include <asm/arch/iomux.h>
  25#include <asm/arch/sci/sci.h>
  26#include <asm/arch/sys_proto.h>
  27#ifndef CONFIG_SPL
  28#include <asm/arch-imx8/clock.h>
  29#endif
  30#include <linux/delay.h>
  31#include "../common/factoryset.h"
  32
  33#define GPIO_PAD_CTRL \
  34                ((SC_PAD_CONFIG_NORMAL << PADRING_CONFIG_SHIFT) | \
  35                 (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) | \
  36                 (SC_PAD_28FDSOI_DSE_DV_HIGH << PADRING_DSE_SHIFT) | \
  37                 (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT))
  38
  39#define ENET_NORMAL_PAD_CTRL \
  40                ((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 UART_PAD_CTRL \
  46                ((SC_PAD_CONFIG_OUT_IN << PADRING_CONFIG_SHIFT) | \
  47                 (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) | \
  48                 (SC_PAD_28FDSOI_DSE_DV_HIGH << PADRING_DSE_SHIFT) | \
  49                 (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT))
  50
  51static iomux_cfg_t uart2_pads[] = {
  52        SC_P_UART2_RX | MUX_PAD_CTRL(UART_PAD_CTRL),
  53        SC_P_UART2_TX | MUX_PAD_CTRL(UART_PAD_CTRL),
  54};
  55
  56static void setup_iomux_uart(void)
  57{
  58        imx8_iomux_setup_multiple_pads(uart2_pads, ARRAY_SIZE(uart2_pads));
  59}
  60
  61int board_early_init_f(void)
  62{
  63        /* Set UART clock root to 80 MHz */
  64        sc_pm_clock_rate_t rate = SC_80MHZ;
  65        int ret;
  66
  67        ret = sc_pm_setup_uart(SC_R_UART_0, rate);
  68        ret |= sc_pm_setup_uart(SC_R_UART_2, rate);
  69        if (ret)
  70                return ret;
  71
  72        setup_iomux_uart();
  73
  74        return 0;
  75}
  76
  77#define ENET_PHY_RESET  IMX_GPIO_NR(0, 3)
  78#define ENET_TEST_1     IMX_GPIO_NR(0, 8)
  79#define ENET_TEST_2     IMX_GPIO_NR(0, 9)
  80
  81/*#define ETH_IO_TEST*/
  82static iomux_cfg_t enet_reset[] = {
  83        SC_P_ESAI0_SCKT | MUX_MODE_ALT(4) | MUX_PAD_CTRL(GPIO_PAD_CTRL),
  84#ifdef ETH_IO_TEST
  85        /* GPIO0.IO08 MODE3: TXD0 */
  86        SC_P_ESAI0_TX4_RX1 | MUX_MODE_ALT(4) |
  87        MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL),
  88        /* GPIO0.IO09 MODE3: TXD1 */
  89        SC_P_ESAI0_TX5_RX0 | MUX_MODE_ALT(4) |
  90        MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL),
  91#endif
  92};
  93
  94static void enet_device_phy_reset(void)
  95{
  96        int ret = 0;
  97
  98        imx8_iomux_setup_multiple_pads(enet_reset, ARRAY_SIZE(enet_reset));
  99
 100        ret = gpio_request(ENET_PHY_RESET, "enet_phy_reset");
 101        if (!ret) {
 102                gpio_direction_output(ENET_PHY_RESET, 1);
 103                gpio_set_value(ENET_PHY_RESET, 0);
 104                /* SMSC9303 TRM chapter 14.5.2 */
 105                udelay(200);
 106                gpio_set_value(ENET_PHY_RESET, 1);
 107        } else {
 108                printf("ENET RESET failed!\n");
 109        }
 110
 111#ifdef ETH_IO_TEST
 112        ret =  gpio_request(ENET_TEST_1, "enet_test1");
 113        if (!ret) {
 114                int i;
 115
 116                printf("ENET TEST 1!\n");
 117                for (i = 0; i < 20; i++) {
 118                        gpio_direction_output(ENET_TEST_1, 1);
 119                        gpio_set_value(ENET_TEST_1, 0);
 120                        udelay(50);
 121                        gpio_set_value(ENET_TEST_1, 1);
 122                        udelay(50);
 123                }
 124                gpio_free(ENET_TEST_1);
 125        } else {
 126                printf("GPIO for ENET TEST 1 failed!\n");
 127        }
 128        ret =  gpio_request(ENET_TEST_2, "enet_test2");
 129        if (!ret) {
 130                int i;
 131
 132                printf("ENET TEST 2!\n");
 133                for (i = 0; i < 20; i++) {
 134                        gpio_direction_output(ENET_TEST_2, 1);
 135                        gpio_set_value(ENET_TEST_2, 0);
 136                        udelay(50);
 137                        gpio_set_value(ENET_TEST_2, 1);
 138                        udelay(50);
 139                }
 140                gpio_free(ENET_TEST_2);
 141        } else {
 142                printf("GPIO for ENET TEST 2 failed!\n");
 143        }
 144#endif
 145}
 146
 147int setup_gpr_fec(void)
 148{
 149        sc_ipc_t ipc_handle = -1;
 150        sc_err_t err = 0;
 151        unsigned int test;
 152
 153        /*
 154         * TX_CLK_SEL: it controls a mux between clock coming from the pad 50M
 155         * input pin and clock generated internally to connectivity subsystem
 156         *      0: internal clock
 157         *      1: external clock --->  your choice for RMII
 158         *
 159         * CLKDIV_SEL: it controls a div by 2 on the internal clock path à
 160         *      it should be don’t care when using external clock
 161         *      0: non-divided clock
 162         *      1: clock divided by 2
 163         * 50_DISABLE or 125_DISABLE:
 164         *      it’s used to disable the clock tree going outside the chip
 165         *      when reference clock is generated internally.
 166         *      It should be don’t care when reference clock is provided
 167         *      externally.
 168         *      0: clock is enabled
 169         *      1: clock is disabled
 170         *
 171         * SC_C_TXCLK           = 24,
 172         * SC_C_CLKDIV          = 25,
 173         * SC_C_DISABLE_50      = 26,
 174         * SC_C_DISABLE_125     = 27,
 175         */
 176
 177        err = sc_misc_set_control(ipc_handle, SC_R_ENET_1, SC_C_TXCLK, 1);
 178        if (err != SC_ERR_NONE)
 179                printf("Error in setting up SC_C %d\n\r", SC_C_TXCLK);
 180
 181        sc_misc_get_control(ipc_handle, SC_R_ENET_1, SC_C_TXCLK, &test);
 182        debug("TEST SC_C %d-->%d\n\r", SC_C_TXCLK, test);
 183
 184        err = sc_misc_set_control(ipc_handle, SC_R_ENET_1, SC_C_CLKDIV, 0);
 185        if (err != SC_ERR_NONE)
 186                printf("Error in setting up SC_C %d\n\r", SC_C_CLKDIV);
 187
 188        sc_misc_get_control(ipc_handle, SC_R_ENET_1, SC_C_CLKDIV, &test);
 189        debug("TEST SC_C %d-->%d\n\r", SC_C_CLKDIV, test);
 190
 191        err = sc_misc_set_control(ipc_handle, SC_R_ENET_1, SC_C_DISABLE_50, 0);
 192        if (err != SC_ERR_NONE)
 193                printf("Error in setting up SC_C %d\n\r", SC_C_DISABLE_50);
 194
 195        sc_misc_get_control(ipc_handle, SC_R_ENET_1, SC_C_TXCLK, &test);
 196        debug("TEST SC_C %d-->%d\n\r", SC_C_DISABLE_50, test);
 197
 198        err = sc_misc_set_control(ipc_handle, SC_R_ENET_1, SC_C_DISABLE_125, 1);
 199        if (err != SC_ERR_NONE)
 200                printf("Error in setting up SC_C %d\n\r", SC_C_DISABLE_125);
 201
 202        sc_misc_get_control(ipc_handle, SC_R_ENET_1, SC_C_TXCLK, &test);
 203        debug("TEST SC_C %d-->%d\n\r", SC_C_DISABLE_125, test);
 204
 205        err = sc_misc_set_control(ipc_handle, SC_R_ENET_1, SC_C_SEL_125, 1);
 206        if (err != SC_ERR_NONE)
 207                printf("Error in setting up SC_C %d\n\r", SC_C_SEL_125);
 208
 209        sc_misc_get_control(ipc_handle, SC_R_ENET_1, SC_C_SEL_125, &test);
 210        debug("TEST SC_C %d-->%d\n\r", SC_C_SEL_125, test);
 211
 212        return 0;
 213}
 214
 215#if IS_ENABLED(CONFIG_FEC_MXC)
 216#include <miiphy.h>
 217int board_phy_config(struct phy_device *phydev)
 218{
 219        if (phydev->drv->config)
 220                phydev->drv->config(phydev);
 221
 222        return 0;
 223}
 224
 225#endif
 226
 227static int setup_fec(void)
 228{
 229        setup_gpr_fec();
 230        /* Reset ENET PHY */
 231        enet_device_phy_reset();
 232        return 0;
 233}
 234
 235void reset_cpu(void)
 236{
 237}
 238
 239#ifndef CONFIG_SPL_BUILD
 240/* LED's */
 241static int board_led_init(void)
 242{
 243        struct udevice *bus, *dev;
 244        u8 pca_led[2] = { 0x00, 0x00 };
 245        int ret;
 246
 247        /* init all GPIO LED's */
 248        if (IS_ENABLED(CONFIG_LED))
 249                led_default_state();
 250
 251        /* enable all leds on PCA9552 */
 252        ret = uclass_get_device_by_seq(UCLASS_I2C, PCA9552_1_I2C_BUS, &bus);
 253        if (ret) {
 254                printf("ERROR: I2C get %d\n", ret);
 255                return ret;
 256        }
 257
 258        ret = dm_i2c_probe(bus, PCA9552_1_I2C_ADDR, 0, &dev);
 259        if (ret) {
 260                printf("ERROR: PCA9552 probe failed\n");
 261                return ret;
 262        }
 263
 264        ret = dm_i2c_write(dev, 0x16, pca_led, sizeof(pca_led));
 265        if (ret) {
 266                printf("ERROR: PCA9552 write failed\n");
 267                return ret;
 268        }
 269
 270        mdelay(1);
 271        return ret;
 272}
 273#endif /* !CONFIG_SPL_BUILD */
 274
 275int checkboard(void)
 276{
 277        puts("Board: Capricorn\n");
 278
 279        /*
 280         * Running build_info() doesn't work with current SCFW blob.
 281         * Uncomment below call when new blob is available.
 282         */
 283        /*build_info();*/
 284
 285        print_bootinfo();
 286        return 0;
 287}
 288
 289int board_init(void)
 290{
 291        setup_fec();
 292        return 0;
 293}
 294
 295#ifdef CONFIG_OF_BOARD_SETUP
 296int ft_board_setup(void *blob, struct bd_info *bd)
 297{
 298        return 0;
 299}
 300#endif
 301
 302int board_mmc_get_env_dev(int devno)
 303{
 304        return devno;
 305}
 306
 307static int check_mmc_autodetect(void)
 308{
 309        char *autodetect_str = env_get("mmcautodetect");
 310
 311        if (autodetect_str && (strcmp(autodetect_str, "yes") == 0))
 312                return 1;
 313
 314        return 0;
 315}
 316
 317/* This should be defined for each board */
 318__weak int mmc_map_to_kernel_blk(int dev_no)
 319{
 320        return dev_no;
 321}
 322
 323void board_late_mmc_env_init(void)
 324{
 325        char cmd[32];
 326        char mmcblk[32];
 327        u32 dev_no = mmc_get_env_dev();
 328
 329        if (!check_mmc_autodetect())
 330                return;
 331
 332        env_set_ulong("mmcdev", dev_no);
 333
 334        /* Set mmcblk env */
 335        sprintf(mmcblk, "/dev/mmcblk%dp2 rootwait rw",
 336                mmc_map_to_kernel_blk(dev_no));
 337        env_set("mmcroot", mmcblk);
 338
 339        sprintf(cmd, "mmc dev %d", dev_no);
 340        run_command(cmd, 0);
 341}
 342
 343#ifndef CONFIG_SPL_BUILD
 344int factoryset_read_eeprom(int i2c_addr);
 345
 346static int load_parameters_from_factoryset(void)
 347{
 348        int ret;
 349
 350        ret = factoryset_read_eeprom(EEPROM_I2C_ADDR);
 351        if (ret)
 352                return ret;
 353
 354        return factoryset_env_set();
 355}
 356
 357int board_late_init(void)
 358{
 359        env_set("sec_boot", "no");
 360#ifdef CONFIG_AHAB_BOOT
 361        env_set("sec_boot", "yes");
 362#endif
 363
 364#ifdef CONFIG_ENV_IS_IN_MMC
 365        board_late_mmc_env_init();
 366#endif
 367        /* Init LEDs */
 368        if (board_led_init())
 369                printf("I2C LED init failed\n");
 370
 371        /* Set environment from factoryset */
 372        if (load_parameters_from_factoryset())
 373                printf("Loading factoryset parameters failed!\n");
 374
 375        return 0;
 376}
 377
 378/* Service button */
 379#define MAX_PIN_NUMBER                  128
 380#define BOARD_DEFAULT_BUTTON_GPIO       IMX_GPIO_NR(1, 31)
 381
 382unsigned char get_button_state(char * const envname, unsigned char def)
 383{
 384        int button = 0;
 385        int gpio;
 386        char *ptr_env;
 387
 388        /* If button is not found we take default */
 389        ptr_env = env_get(envname);
 390        if (!ptr_env) {
 391                printf("Using default: %u\n", def);
 392                gpio = def;
 393        } else {
 394                gpio = (unsigned char)simple_strtoul(ptr_env, NULL, 0);
 395                if (gpio > MAX_PIN_NUMBER)
 396                        gpio = def;
 397        }
 398
 399        gpio_request(gpio, "");
 400        gpio_direction_input(gpio);
 401        if (gpio_get_value(gpio))
 402                button = 1;
 403        else
 404                button = 0;
 405
 406        gpio_free(gpio);
 407
 408        return button;
 409}
 410
 411/*
 412 * This command returns the status of the user button on
 413 * Input - none
 414 * Returns -    1 if button is held down
 415 *              0 if button is not held down
 416 */
 417static int
 418do_userbutton(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
 419{
 420        int button = 0;
 421
 422        button = get_button_state("button_usr1", BOARD_DEFAULT_BUTTON_GPIO);
 423
 424        if (argc > 1)
 425                printf("Button state: %u\n", button);
 426
 427        return button;
 428}
 429
 430U_BOOT_CMD(
 431        usrbutton, CONFIG_SYS_MAXARGS, 2, do_userbutton,
 432        "Return the status of user button",
 433        "[print]"
 434);
 435
 436#define ERST    IMX_GPIO_NR(0, 3)
 437
 438static int
 439do_eth_reset(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
 440{
 441        gpio_request(ERST, "ERST");
 442        gpio_direction_output(ERST, 0);
 443        udelay(200);
 444        gpio_set_value(ERST, 1);
 445        return 0;
 446}
 447
 448U_BOOT_CMD(
 449        switch_rst, CONFIG_SYS_MAXARGS, 2, do_eth_reset,
 450        "Reset eth phy",
 451        "[print]"
 452);
 453#endif /* ! CONFIG_SPL_BUILD */
 454