1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * K+P iMX6Q KP_IMX6Q_TPC board configuration 4 * 5 * Copyright (C) 2018 Lukasz Majewski <lukma@denx.de> 6 */ 7 8#include <common.h> 9#include <init.h> 10#include <asm/arch/clock.h> 11#include <asm/arch/crm_regs.h> 12#include <asm/arch/imx-regs.h> 13#include <asm/arch/mx6-pins.h> 14#include <asm/arch/sys_proto.h> 15#include <asm/global_data.h> 16#include <asm/mach-imx/boot_mode.h> 17#include <env.h> 18#include <errno.h> 19#include <miiphy.h> 20#include <usb.h> 21#include <usb/ehci-ci.h> 22#include <led.h> 23 24DECLARE_GLOBAL_DATA_PTR; 25 26int dram_init(void) 27{ 28 gd->ram_size = imx_ddr_size(); 29 return 0; 30} 31 32/* 33 * Do not overwrite the console 34 * Use always serial for U-Boot console 35 */ 36int overwrite_console(void) 37{ 38 return 1; 39} 40 41#ifdef CONFIG_FEC_MXC 42static int setup_fec_clock(void) 43{ 44 struct iomuxc *iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR; 45 46 /* set gpr1[21] to select anatop clock */ 47 clrsetbits_le32(&iomuxc_regs->gpr[1], IOMUXC_GPR1_ENET_CLK_SEL_MASK, 48 IOMUXC_GPR1_ENET_CLK_SEL_MASK); 49 50 return enable_fec_anatop_clock(0, ENET_50MHZ); 51} 52 53static int ar8031_phy_fixup(struct phy_device *phydev) 54{ 55 unsigned short val; 56 57 /* To enable AR8031 output a 125MHz clk from CLK_25M */ 58 phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x7); 59 phy_write(phydev, MDIO_DEVAD_NONE, 0xe, 0x8016); 60 phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x4007); 61 62 val = phy_read(phydev, MDIO_DEVAD_NONE, 0xe); 63 val &= 0xffe3; 64 val |= 0x18; 65 phy_write(phydev, MDIO_DEVAD_NONE, 0xe, val); 66 67 /* introduce tx clock delay */ 68 phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x5); 69 val = phy_read(phydev, MDIO_DEVAD_NONE, 0x1e); 70 val |= 0x0100; 71 phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, val); 72 73 return 0; 74} 75 76int board_phy_config(struct phy_device *phydev) 77{ 78 ar8031_phy_fixup(phydev); 79 80 if (phydev->drv->config) 81 phydev->drv->config(phydev); 82 83 return 0; 84} 85#endif 86 87#ifdef CONFIG_USB_EHCI_MX6 88static void setup_usb(void) 89{ 90 /* 91 * Set daisy chain for otg_pin_id on MX6Q. 92 * For MX6DL, this bit is reserved. 93 */ 94 imx_iomux_set_gpr_register(1, 13, 1, 0); 95} 96#endif 97 98int board_early_init_f(void) 99{ 100#ifdef CONFIG_USB_EHCI_MX6 101 setup_usb(); 102#endif 103 104#ifdef CONFIG_FEC_MXC 105 setup_fec_clock(); 106#endif 107 108 return 0; 109} 110 111int board_init(void) 112{ 113 struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; 114 115 /* address of boot parameters */ 116 gd->bd->bi_boot_params = PHYS_SDRAM + 0x100; 117 118 /* Enable eim_slow clocks */ 119 setbits_le32(&mxc_ccm->CCGR6, 0x1 << MXC_CCM_CCGR6_EMI_SLOW_OFFSET); 120 121 return 0; 122} 123 124#ifdef CONFIG_CMD_BMODE 125static const struct boot_mode board_boot_modes[] = { 126 /* 4 bit bus width */ 127 {"sd2", MAKE_CFGVAL(0x40, 0x28, 0x00, 0x00)}, 128 /* 8 bit bus width */ 129 {"emmc", MAKE_CFGVAL(0x60, 0x58, 0x00, 0x00)}, 130 {NULL, 0}, 131}; 132#endif 133 134int board_late_init(void) 135{ 136#ifdef CONFIG_CMD_BMODE 137 add_board_boot_modes(board_boot_modes); 138#endif 139 140 env_set("boardname", "kp-tpc"); 141 env_set("boardsoc", "imx6q"); 142 return 0; 143} 144 145int checkboard(void) 146{ 147 puts("Board: K+P KP_IMX6Q_TPC i.MX6Q\n"); 148 return 0; 149} 150