uboot/board/dhelectronics/dh_imx6/dh_imx6.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * DHCOM DH-iMX6 PDK board support
   4 *
   5 * Copyright (C) 2017 Marek Vasut <marex@denx.de>
   6 */
   7
   8#include <common.h>
   9#include <dm.h>
  10#include <eeprom.h>
  11#include <image.h>
  12#include <init.h>
  13#include <net.h>
  14#include <dm/device-internal.h>
  15#include <asm/arch/clock.h>
  16#include <asm/arch/crm_regs.h>
  17#include <asm/arch/imx-regs.h>
  18#include <asm/arch/iomux.h>
  19#include <asm/arch/mx6-pins.h>
  20#include <asm/arch/sys_proto.h>
  21#include <asm/gpio.h>
  22#include <asm/io.h>
  23#include <asm/mach-imx/boot_mode.h>
  24#include <asm/mach-imx/iomux-v3.h>
  25#include <asm/mach-imx/sata.h>
  26#include <ahci.h>
  27#include <dwc_ahsata.h>
  28#include <env.h>
  29#include <errno.h>
  30#include <fsl_esdhc_imx.h>
  31#include <fuse.h>
  32#include <i2c_eeprom.h>
  33#include <mmc.h>
  34#include <usb.h>
  35#include <linux/delay.h>
  36#include <usb/ehci-ci.h>
  37
  38DECLARE_GLOBAL_DATA_PTR;
  39
  40int dram_init(void)
  41{
  42        gd->ram_size = imx_ddr_size();
  43        return 0;
  44}
  45
  46/*
  47 * Do not overwrite the console
  48 * Use always serial for U-Boot console
  49 */
  50int overwrite_console(void)
  51{
  52        return 1;
  53}
  54
  55static int setup_fec_clock(void)
  56{
  57        struct iomuxc *iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR;
  58
  59        /* set gpr1[21] to select anatop clock */
  60        clrsetbits_le32(&iomuxc_regs->gpr[1], 0x1 << 21, 0x1 << 21);
  61
  62        return enable_fec_anatop_clock(0, ENET_50MHZ);
  63}
  64
  65#ifdef CONFIG_USB_EHCI_MX6
  66static void setup_usb(void)
  67{
  68        /*
  69         * Set daisy chain for otg_pin_id on MX6Q.
  70         * For MX6DL, this bit is reserved.
  71         */
  72        imx_iomux_set_gpr_register(1, 13, 1, 0);
  73}
  74
  75int board_usb_phy_mode(int port)
  76{
  77        if (port == 1)
  78                return USB_INIT_HOST;
  79        else
  80                return USB_INIT_DEVICE;
  81}
  82#endif
  83
  84static int setup_dhcom_mac_from_fuse(void)
  85{
  86        struct udevice *dev;
  87        ofnode eeprom;
  88        unsigned char enetaddr[6];
  89        int ret;
  90
  91        ret = eth_env_get_enetaddr("ethaddr", enetaddr);
  92        if (ret)        /* ethaddr is already set */
  93                return 0;
  94
  95        imx_get_mac_from_fuse(0, enetaddr);
  96
  97        if (is_valid_ethaddr(enetaddr)) {
  98                eth_env_set_enetaddr("ethaddr", enetaddr);
  99                return 0;
 100        }
 101
 102        eeprom = ofnode_path("/soc/aips-bus@2100000/i2c@21a8000/eeprom@50");
 103        if (!ofnode_valid(eeprom)) {
 104                printf("Invalid hardware path to EEPROM!\n");
 105                return -ENODEV;
 106        }
 107
 108        ret = uclass_get_device_by_ofnode(UCLASS_I2C_EEPROM, eeprom, &dev);
 109        if (ret) {
 110                printf("Cannot find EEPROM!\n");
 111                return ret;
 112        }
 113
 114        ret = i2c_eeprom_read(dev, 0xfa, enetaddr, 0x6);
 115        if (ret) {
 116                printf("Error reading configuration EEPROM!\n");
 117                return ret;
 118        }
 119
 120        if (is_valid_ethaddr(enetaddr))
 121                eth_env_set_enetaddr("ethaddr", enetaddr);
 122
 123        return 0;
 124}
 125
 126int board_early_init_f(void)
 127{
 128#ifdef CONFIG_USB_EHCI_MX6
 129        setup_usb();
 130#endif
 131
 132        return 0;
 133}
 134
 135int board_init(void)
 136{
 137        struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
 138
 139        /* address of boot parameters */
 140        gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
 141
 142        /* Enable eim_slow clocks */
 143        setbits_le32(&mxc_ccm->CCGR6, 0x1 << MXC_CCM_CCGR6_EMI_SLOW_OFFSET);
 144
 145        setup_fec_clock();
 146
 147        return 0;
 148}
 149
 150#ifdef CONFIG_CMD_BMODE
 151static const struct boot_mode board_boot_modes[] = {
 152        /* 4 bit bus width */
 153        {"sd2",  MAKE_CFGVAL(0x40, 0x28, 0x00, 0x00)},
 154        {"sd3",  MAKE_CFGVAL(0x40, 0x30, 0x00, 0x00)},
 155        /* 8 bit bus width */
 156        {"emmc", MAKE_CFGVAL(0x60, 0x58, 0x00, 0x00)},
 157        {NULL,   0},
 158};
 159#endif
 160
 161#define HW_CODE_BIT_0   IMX_GPIO_NR(2, 19)
 162#define HW_CODE_BIT_1   IMX_GPIO_NR(6, 6)
 163#define HW_CODE_BIT_2   IMX_GPIO_NR(2, 16)
 164
 165static int board_get_hwcode(void)
 166{
 167        int hw_code;
 168
 169        gpio_request(HW_CODE_BIT_0, "HW-code-bit-0");
 170        gpio_request(HW_CODE_BIT_1, "HW-code-bit-1");
 171        gpio_request(HW_CODE_BIT_2, "HW-code-bit-2");
 172
 173        gpio_direction_input(HW_CODE_BIT_0);
 174        gpio_direction_input(HW_CODE_BIT_1);
 175        gpio_direction_input(HW_CODE_BIT_2);
 176
 177        /* HW 100 + HW 200 = 00b; HW 300 = 01b */
 178        hw_code = ((gpio_get_value(HW_CODE_BIT_2) << 2) |
 179                   (gpio_get_value(HW_CODE_BIT_1) << 1) |
 180                    gpio_get_value(HW_CODE_BIT_0)) + 2;
 181
 182        return hw_code;
 183}
 184
 185int board_late_init(void)
 186{
 187        u32 hw_code;
 188        char buf[16];
 189
 190        setup_dhcom_mac_from_fuse();
 191
 192        hw_code = board_get_hwcode();
 193
 194        switch (get_cpu_type()) {
 195        case MXC_CPU_MX6SOLO:
 196                snprintf(buf, sizeof(buf), "imx6s-dhcom%1d", hw_code);
 197                break;
 198        case MXC_CPU_MX6DL:
 199                snprintf(buf, sizeof(buf), "imx6dl-dhcom%1d", hw_code);
 200                break;
 201        case MXC_CPU_MX6D:
 202                snprintf(buf, sizeof(buf), "imx6d-dhcom%1d", hw_code);
 203                break;
 204        case MXC_CPU_MX6Q:
 205                snprintf(buf, sizeof(buf), "imx6q-dhcom%1d", hw_code);
 206                break;
 207        default:
 208                snprintf(buf, sizeof(buf), "UNKNOWN%1d", hw_code);
 209                break;
 210        }
 211
 212        env_set("dhcom", buf);
 213
 214#ifdef CONFIG_CMD_BMODE
 215        add_board_boot_modes(board_boot_modes);
 216#endif
 217        return 0;
 218}
 219
 220int checkboard(void)
 221{
 222        puts("Board: DHCOM i.MX6\n");
 223        return 0;
 224}
 225
 226#ifdef CONFIG_MULTI_DTB_FIT
 227int board_fit_config_name_match(const char *name)
 228{
 229        if (is_mx6dq()) {
 230                if (!strcmp(name, "imx6q-dhcom-pdk2"))
 231                        return 0;
 232        } else if (is_mx6sdl()) {
 233                if (!strcmp(name, "imx6dl-dhcom-pdk2"))
 234                        return 0;
 235        }
 236
 237        return -1;
 238}
 239#endif
 240