uboot/board/kontron/pitx_imx8m/spl.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2
   3#include <common.h>
   4#include <errno.h>
   5#include <fsl_esdhc_imx.h>
   6#include <hang.h>
   7#include <init.h>
   8#include <log.h>
   9#include <spl.h>
  10#include <asm/arch/ddr.h>
  11#include <asm/arch/imx8mq_pins.h>
  12#include <asm/arch/sys_proto.h>
  13#include <asm/arch/clock.h>
  14#include <asm/global_data.h>
  15#include <asm/io.h>
  16#include <asm/mach-imx/iomux-v3.h>
  17#include <asm/mach-imx/gpio.h>
  18#include <asm/mach-imx/mxc_i2c.h>
  19#include <linux/delay.h>
  20#include <power/pmic.h>
  21#include <power/pfuze100_pmic.h>
  22
  23#include "pitx_misc.h"
  24
  25extern struct dram_timing_info dram_timing_2gb;
  26extern struct dram_timing_info dram_timing_4gb;
  27
  28DECLARE_GLOBAL_DATA_PTR;
  29
  30
  31static void spl_dram_init(void)
  32{
  33        struct dram_timing_info *dram_timing;
  34        int variant = 0, size;
  35
  36        variant = get_pitx_board_variant();
  37
  38        switch(variant) {
  39        case 2:
  40                dram_timing = &dram_timing_2gb;
  41                size = 2;
  42                break;
  43        case 3:
  44                dram_timing = &dram_timing_4gb;
  45                size = 4;
  46                break;
  47        default:
  48                printf("Unknown DDR type (%d)\n", variant);
  49                return;
  50        };
  51
  52        /* ddr init */
  53        ddr_init(dram_timing);
  54}
  55
  56#define I2C_PAD_CTRL    (PAD_CTL_DSE6 | PAD_CTL_HYS | PAD_CTL_PUE)
  57#define PC MUX_PAD_CTRL(I2C_PAD_CTRL)
  58static struct i2c_pads_info i2c_pad_info1 = {
  59        .scl = {
  60                .i2c_mode = IMX8MQ_PAD_I2C1_SCL__I2C1_SCL | PC,
  61                .gpio_mode = IMX8MQ_PAD_I2C1_SCL__GPIO5_IO14 | PC,
  62                .gp = IMX_GPIO_NR(5, 14),
  63        },
  64        .sda = {
  65                .i2c_mode = IMX8MQ_PAD_I2C1_SDA__I2C1_SDA | PC,
  66                .gpio_mode = IMX8MQ_PAD_I2C1_SDA__GPIO5_IO15 | PC,
  67                .gp = IMX_GPIO_NR(5, 15),
  68        },
  69};
  70
  71#if CONFIG_IS_ENABLED(MMC)
  72#define USDHC2_CD_GPIO  IMX_GPIO_NR(2, 12)
  73#define USDHC1_PWR_GPIO IMX_GPIO_NR(2, 10)
  74#define USDHC2_PWR_GPIO IMX_GPIO_NR(2, 19)
  75
  76int board_mmc_getcd(struct mmc *mmc)
  77{
  78        struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
  79
  80        switch (cfg->esdhc_base) {
  81        case USDHC1_BASE_ADDR:
  82                /* the eMMC does not have a CD pin */
  83                return 1;
  84        case USDHC2_BASE_ADDR:
  85                return !gpio_get_value(USDHC2_CD_GPIO);
  86        }
  87
  88        return 0;
  89}
  90
  91
  92#define USDHC_PAD_CTRL  (PAD_CTL_DSE6 | PAD_CTL_HYS | PAD_CTL_PUE | \
  93                         PAD_CTL_FSEL2)
  94#define USDHC_GPIO_PAD_CTRL (PAD_CTL_PUE | PAD_CTL_DSE1)
  95
  96static iomux_v3_cfg_t const usdhc1_pads[] = {
  97        IMX8MQ_PAD_SD1_CLK__USDHC1_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  98        IMX8MQ_PAD_SD1_CMD__USDHC1_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  99        IMX8MQ_PAD_SD1_DATA0__USDHC1_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 100        IMX8MQ_PAD_SD1_DATA1__USDHC1_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 101        IMX8MQ_PAD_SD1_DATA2__USDHC1_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 102        IMX8MQ_PAD_SD1_DATA3__USDHC1_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 103        IMX8MQ_PAD_SD1_DATA4__USDHC1_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 104        IMX8MQ_PAD_SD1_DATA5__USDHC1_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 105        IMX8MQ_PAD_SD1_DATA6__USDHC1_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 106        IMX8MQ_PAD_SD1_DATA7__USDHC1_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 107        IMX8MQ_PAD_SD1_RESET_B__GPIO2_IO10 | MUX_PAD_CTRL(NO_PAD_CTRL),
 108};
 109
 110static iomux_v3_cfg_t const usdhc2_pads[] = {
 111        IMX8MQ_PAD_SD2_CLK__USDHC2_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL), /* 0xd6 */
 112        IMX8MQ_PAD_SD2_CMD__USDHC2_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL), /* 0xd6 */
 113        IMX8MQ_PAD_SD2_DATA0__USDHC2_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL), /* 0xd6 */
 114        IMX8MQ_PAD_SD2_DATA1__USDHC2_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL), /* 0xd6 */
 115        IMX8MQ_PAD_SD2_DATA2__USDHC2_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL), /* 0x16 */
 116        IMX8MQ_PAD_SD2_DATA3__USDHC2_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL), /* 0xd6 */
 117        IMX8MQ_PAD_SD2_CD_B__GPIO2_IO12 | MUX_PAD_CTRL(USDHC_GPIO_PAD_CTRL),
 118        IMX8MQ_PAD_SD2_RESET_B__GPIO2_IO19 | MUX_PAD_CTRL(USDHC_GPIO_PAD_CTRL),
 119};
 120
 121static struct fsl_esdhc_cfg usdhc_cfg[2] = {
 122        {USDHC1_BASE_ADDR, 0, 8},
 123        {USDHC2_BASE_ADDR, 0, 4},
 124};
 125
 126int board_mmc_init(struct bd_info *bis)
 127{
 128        int i, ret;
 129        /*
 130         * According to the board_mmc_init() the following map is done:
 131         * (U-Boot device node)    (Physical Port)
 132         * mmc0                    USDHC1
 133         * mmc1                    USDHC2
 134         */
 135        for (i = 0; i < CONFIG_SYS_FSL_USDHC_NUM; i++) {
 136                switch (i) {
 137                case 0:
 138                        init_clk_usdhc(0);
 139                        usdhc_cfg[0].sdhc_clk = mxc_get_clock(USDHC1_CLK_ROOT);
 140                        imx_iomux_v3_setup_multiple_pads(usdhc1_pads,
 141                                                         ARRAY_SIZE(usdhc1_pads));
 142                        gpio_request(USDHC1_PWR_GPIO, "usdhc1_reset");
 143                        gpio_direction_output(USDHC1_PWR_GPIO, 0);
 144                        udelay(500);
 145                        gpio_direction_output(USDHC1_PWR_GPIO, 1);
 146                        break;
 147                case 1:
 148                        init_clk_usdhc(1);
 149                        usdhc_cfg[1].sdhc_clk = mxc_get_clock(USDHC2_CLK_ROOT);
 150                        imx_iomux_v3_setup_multiple_pads(usdhc2_pads,
 151                                                         ARRAY_SIZE(usdhc2_pads));
 152                        gpio_request(USDHC2_PWR_GPIO, "usdhc2_reset");
 153                        gpio_direction_output(USDHC2_PWR_GPIO, 0);
 154                        udelay(500);
 155                        gpio_direction_output(USDHC2_PWR_GPIO, 1);
 156                        break;
 157                default:
 158                        printf("Warning: you configured more USDHC controllers "
 159                                "(%d) than supported by the board\n", i + 1);
 160                        return -EINVAL;
 161                }
 162
 163                ret = fsl_esdhc_initialize(bis, &usdhc_cfg[i]);
 164                if (ret)
 165                        return ret;
 166        }
 167
 168        return 0;
 169}
 170
 171const char *spl_board_loader_name(u32 boot_device)
 172{
 173        switch (boot_device) {
 174        case BOOT_DEVICE_MMC1:
 175                return "eMMC";
 176        case BOOT_DEVICE_MMC2:
 177                return "SD card";
 178        default:
 179                return NULL;
 180        }
 181}
 182#endif
 183
 184#if CONFIG_IS_ENABLED(POWER_LEGACY)
 185#define I2C_PMIC        0
 186
 187static int pfuze_mode_init(struct pmic *p, u32 mode)
 188{
 189        unsigned char offset, i, switch_num;
 190        u32 id;
 191        int ret;
 192
 193        pmic_reg_read(p, PFUZE100_DEVICEID, &id);
 194        id = id & 0xf;
 195
 196        if (id == 0) {
 197                switch_num = 6;
 198                offset = PFUZE100_SW1CMODE;
 199        } else if (id == 1) {
 200                switch_num = 4;
 201                offset = PFUZE100_SW2MODE;
 202        } else {
 203                printf("Not supported, id=%d\n", id);
 204                return -EINVAL;
 205        }
 206
 207        ret = pmic_reg_write(p, PFUZE100_SW1ABMODE, mode);
 208        if (ret < 0) {
 209                printf("Set SW1AB mode error!\n");
 210                return ret;
 211        }
 212
 213        for (i = 0; i < switch_num - 1; i++) {
 214                ret = pmic_reg_write(p, offset + i * SWITCH_SIZE, mode);
 215                if (ret < 0) {
 216                        printf("Set switch 0x%x mode error!\n",
 217                               offset + i * SWITCH_SIZE);
 218                        return ret;
 219                }
 220        }
 221
 222        return ret;
 223}
 224
 225int power_init_board(void)
 226{
 227        struct pmic *p;
 228        int ret;
 229        unsigned int reg;
 230
 231        ret = power_pfuze100_init(I2C_PMIC);
 232        if (ret)
 233                return -ENODEV;
 234
 235        p = pmic_get("PFUZE100");
 236        ret = pmic_probe(p);
 237        if (ret)
 238                return -ENODEV;
 239
 240        pmic_reg_read(p, PFUZE100_SW3AVOL, &reg);
 241        if ((reg & 0x3f) != 0x18) {
 242                reg &= ~0x3f;
 243                reg |= 0x18;
 244                pmic_reg_write(p, PFUZE100_SW3AVOL, reg);
 245        }
 246
 247        ret = pfuze_mode_init(p, APS_PFM);
 248        if (ret < 0)
 249                return ret;
 250
 251        /* set SW3A standby mode to off */
 252        pmic_reg_read(p, PFUZE100_SW3AMODE, &reg);
 253        reg &= ~0xf;
 254        reg |= APS_OFF;
 255        pmic_reg_write(p, PFUZE100_SW3AMODE, reg);
 256
 257        return 0;
 258}
 259#endif
 260
 261void board_init_f(ulong dummy)
 262{
 263        int ret;
 264
 265        /* Clear global data */
 266        memset((void *)gd, 0, sizeof(gd_t));
 267
 268        arch_cpu_init();
 269
 270        init_uart_clk(2);
 271
 272        board_early_init_f();
 273
 274        timer_init();
 275
 276        preloader_console_init();
 277
 278        /* Clear the BSS. */
 279        memset(__bss_start, 0, __bss_end - __bss_start);
 280
 281        ret = spl_init();
 282        if (ret) {
 283                debug("spl_init() failed: %d\n", ret);
 284                hang();
 285        }
 286
 287        enable_tzc380();
 288
 289        setup_i2c(0, 100000, 0x7f, &i2c_pad_info1);
 290
 291#if CONFIG_IS_ENABLED(POWER_LEGACY)
 292        power_init_board();
 293#endif
 294
 295        spl_dram_init();
 296
 297        board_init_r(NULL, 0);
 298}
 299