1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (C) 2017 Logic PD, Inc. 4 * 5 * Author: Adam Ford <aford173@gmail.com> 6 * 7 * Based on SabreSD by Fabio Estevam <fabio.estevam@nxp.com> 8 * and updates by Jagan Teki <jagan@amarulasolutions.com> 9 */ 10 11 #include <common.h> 12 #include <miiphy.h> 13 #include <input.h> 14 #include <mmc.h> 15 #include <fsl_esdhc.h> 16 #include <asm/io.h> 17 #include <asm/gpio.h> 18 #include <linux/sizes.h> 19 #include <asm/arch/clock.h> 20 #include <asm/arch/crm_regs.h> 21 #include <asm/arch/iomux.h> 22 #include <asm/arch/mxc_hdmi.h> 23 #include <asm/arch/mx6-pins.h> 24 #include <asm/arch/sys_proto.h> 25 #include <asm/mach-imx/boot_mode.h> 26 #include <asm/mach-imx/iomux-v3.h> 27 28 DECLARE_GLOBAL_DATA_PTR; 29 30 #define UART_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \ 31 PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \ 32 PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS) 33 34 #define NAND_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \ 35 PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \ 36 PAD_CTL_DSE_40ohm | PAD_CTL_HYS) 37 38 int dram_init(void) 39 { 40 gd->ram_size = imx_ddr_size(); 41 return 0; 42 } 43 44 static iomux_v3_cfg_t const uart1_pads[] = { 45 MX6_PAD_SD3_DAT7__UART1_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL), 46 MX6_PAD_SD3_DAT6__UART1_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL), 47 }; 48 49 static iomux_v3_cfg_t const uart2_pads[] = { 50 MX6_PAD_SD4_DAT4__UART2_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL), 51 MX6_PAD_SD4_DAT5__UART2_RTS_B | MUX_PAD_CTRL(UART_PAD_CTRL), 52 MX6_PAD_SD4_DAT6__UART2_CTS_B | MUX_PAD_CTRL(UART_PAD_CTRL), 53 MX6_PAD_SD4_DAT7__UART2_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL), 54 }; 55 56 static iomux_v3_cfg_t const uart3_pads[] = { 57 MX6_PAD_EIM_D23__UART3_CTS_B | MUX_PAD_CTRL(UART_PAD_CTRL), 58 MX6_PAD_EIM_D24__UART3_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL), 59 MX6_PAD_EIM_D25__UART3_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL), 60 MX6_PAD_EIM_EB3__UART3_RTS_B | MUX_PAD_CTRL(UART_PAD_CTRL), 61 }; 62 63 static void fixup_enet_clock(void) 64 { 65 struct iomuxc *iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR; 66 struct gpio_desc nint; 67 struct gpio_desc reset; 68 int ret; 69 70 /* Set Ref Clock to 50 MHz */ 71 enable_fec_anatop_clock(0, ENET_50MHZ); 72 73 /* Set GPIO_16 as ENET_REF_CLK_OUT */ 74 setbits_le32(&iomuxc_regs->gpr[1], IOMUXC_GPR1_ENET_CLK_SEL_MASK); 75 76 /* Request GPIO Pins to reset Ethernet with new clock */ 77 ret = dm_gpio_lookup_name("GPIO4_7", &nint); 78 if (ret) { 79 printf("Unable to lookup GPIO4_7\n"); 80 return; 81 } 82 83 ret = dm_gpio_request(&nint, "eth0_nInt"); 84 if (ret) { 85 printf("Unable to request eth0_nInt\n"); 86 return; 87 } 88 89 /* Ensure nINT is input or PHY won't startup */ 90 dm_gpio_set_dir_flags(&nint, GPIOD_IS_IN); 91 92 ret = dm_gpio_lookup_name("GPIO4_9", &reset); 93 if (ret) { 94 printf("Unable to lookup GPIO4_9\n"); 95 return; 96 } 97 98 ret = dm_gpio_request(&reset, "eth0_reset"); 99 if (ret) { 100 printf("Unable to request eth0_reset\n"); 101 return; 102 } 103 104 /* Reset LAN8710A PHY */ 105 dm_gpio_set_dir_flags(&reset, GPIOD_IS_OUT); 106 dm_gpio_set_value(&reset, 0); 107 udelay(150); 108 dm_gpio_set_value(&reset, 1); 109 mdelay(50); 110 } 111 112 static void setup_iomux_uart(void) 113 { 114 imx_iomux_v3_setup_multiple_pads(uart1_pads, ARRAY_SIZE(uart1_pads)); 115 imx_iomux_v3_setup_multiple_pads(uart2_pads, ARRAY_SIZE(uart2_pads)); 116 imx_iomux_v3_setup_multiple_pads(uart3_pads, ARRAY_SIZE(uart3_pads)); 117 } 118 119 static iomux_v3_cfg_t const nand_pads[] = { 120 MX6_PAD_NANDF_CS0__NAND_CE0_B | MUX_PAD_CTRL(NAND_PAD_CTRL), 121 MX6_PAD_NANDF_ALE__NAND_ALE | MUX_PAD_CTRL(NAND_PAD_CTRL), 122 MX6_PAD_NANDF_CLE__NAND_CLE | MUX_PAD_CTRL(NAND_PAD_CTRL), 123 MX6_PAD_NANDF_WP_B__NAND_WP_B | MUX_PAD_CTRL(NAND_PAD_CTRL), 124 MX6_PAD_NANDF_RB0__NAND_READY_B | MUX_PAD_CTRL(NAND_PAD_CTRL), 125 MX6_PAD_NANDF_D0__NAND_DATA00 | MUX_PAD_CTRL(NAND_PAD_CTRL), 126 MX6_PAD_NANDF_D1__NAND_DATA01 | MUX_PAD_CTRL(NAND_PAD_CTRL), 127 MX6_PAD_NANDF_D2__NAND_DATA02 | MUX_PAD_CTRL(NAND_PAD_CTRL), 128 MX6_PAD_NANDF_D3__NAND_DATA03 | MUX_PAD_CTRL(NAND_PAD_CTRL), 129 MX6_PAD_NANDF_D4__NAND_DATA04 | MUX_PAD_CTRL(NAND_PAD_CTRL), 130 MX6_PAD_NANDF_D5__NAND_DATA05 | MUX_PAD_CTRL(NAND_PAD_CTRL), 131 MX6_PAD_NANDF_D6__NAND_DATA06 | MUX_PAD_CTRL(NAND_PAD_CTRL), 132 MX6_PAD_NANDF_D7__NAND_DATA07 | MUX_PAD_CTRL(NAND_PAD_CTRL), 133 MX6_PAD_SD4_CLK__NAND_WE_B | MUX_PAD_CTRL(NAND_PAD_CTRL), 134 MX6_PAD_SD4_CMD__NAND_RE_B | MUX_PAD_CTRL(NAND_PAD_CTRL), 135 }; 136 137 static void setup_nand_pins(void) 138 { 139 imx_iomux_v3_setup_multiple_pads(nand_pads, ARRAY_SIZE(nand_pads)); 140 } 141 142 int board_phy_config(struct phy_device *phydev) 143 { 144 if (phydev->drv->config) 145 phydev->drv->config(phydev); 146 147 return 0; 148 } 149 150 /* 151 * Do not overwrite the console 152 * Use always serial for U-Boot console 153 */ 154 int overwrite_console(void) 155 { 156 return 1; 157 } 158 159 int board_early_init_f(void) 160 { 161 fixup_enet_clock(); 162 setup_iomux_uart(); 163 setup_nand_pins(); 164 return 0; 165 } 166 167 int board_init(void) 168 { 169 /* address of boot parameters */ 170 gd->bd->bi_boot_params = PHYS_SDRAM + 0x100; 171 return 0; 172 } 173 174 int board_late_init(void) 175 { 176 env_set("board_name", "imx6logic"); 177 178 if (is_mx6dq()) { 179 env_set("board_rev", "MX6DQ"); 180 env_set("fdt_file", "imx6q-logicpd.dtb"); 181 } 182 183 return 0; 184 } 185 186 #ifdef CONFIG_SPL_BUILD 187 #include <asm/arch/mx6-ddr.h> 188 #include <asm/arch/mx6q-ddr.h> 189 #include <spl.h> 190 #include <linux/libfdt.h> 191 192 #ifdef CONFIG_SPL_OS_BOOT 193 int spl_start_uboot(void) 194 { 195 /* break into full u-boot on 'c' */ 196 if (serial_tstc() && serial_getc() == 'c') 197 return 1; 198 199 return 0; 200 } 201 #endif 202 203 static void ccgr_init(void) 204 { 205 struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; 206 207 writel(0x00C03F3F, &ccm->CCGR0); 208 writel(0x0030FC03, &ccm->CCGR1); 209 writel(0x0FFFC000, &ccm->CCGR2); 210 writel(0x3FF00000, &ccm->CCGR3); 211 writel(0xFFFFF300, &ccm->CCGR4); 212 writel(0x0F0000F3, &ccm->CCGR5); 213 writel(0x00000FFF, &ccm->CCGR6); 214 } 215 216 static int mx6q_dcd_table[] = { 217 MX6_IOM_GRP_DDR_TYPE, 0x000C0000, 218 MX6_IOM_GRP_DDRPKE, 0x00000000, 219 MX6_IOM_DRAM_SDCLK_0, 0x00000030, 220 MX6_IOM_DRAM_SDCLK_1, 0x00000030, 221 MX6_IOM_DRAM_CAS, 0x00000030, 222 MX6_IOM_DRAM_RAS, 0x00000030, 223 MX6_IOM_GRP_ADDDS, 0x00000030, 224 MX6_IOM_DRAM_RESET, 0x00000030, 225 MX6_IOM_DRAM_SDBA2, 0x00000000, 226 MX6_IOM_DRAM_SDODT0, 0x00000030, 227 MX6_IOM_DRAM_SDODT1, 0x00000030, 228 MX6_IOM_GRP_CTLDS, 0x00000030, 229 MX6_IOM_DDRMODE_CTL, 0x00020000, 230 MX6_IOM_DRAM_SDQS0, 0x00000030, 231 MX6_IOM_DRAM_SDQS1, 0x00000030, 232 MX6_IOM_DRAM_SDQS2, 0x00000030, 233 MX6_IOM_DRAM_SDQS3, 0x00000030, 234 MX6_IOM_GRP_DDRMODE, 0x00020000, 235 MX6_IOM_GRP_B0DS, 0x00000030, 236 MX6_IOM_GRP_B1DS, 0x00000030, 237 MX6_IOM_GRP_B2DS, 0x00000030, 238 MX6_IOM_GRP_B3DS, 0x00000030, 239 MX6_IOM_DRAM_DQM0, 0x00000030, 240 MX6_IOM_DRAM_DQM1, 0x00000030, 241 MX6_IOM_DRAM_DQM2, 0x00000030, 242 MX6_IOM_DRAM_DQM3, 0x00000030, 243 MX6_MMDC_P0_MDSCR, 0x00008000, 244 MX6_MMDC_P0_MPZQHWCTRL, 0xA1390003, 245 MX6_MMDC_P0_MPWLDECTRL0, 0x002D003A, 246 MX6_MMDC_P0_MPWLDECTRL1, 0x0038002B, 247 MX6_MMDC_P0_MPDGCTRL0, 0x03340338, 248 MX6_MMDC_P0_MPDGCTRL1, 0x0334032C, 249 MX6_MMDC_P0_MPRDDLCTL, 0x4036383C, 250 MX6_MMDC_P0_MPWRDLCTL, 0x2E384038, 251 MX6_MMDC_P0_MPRDDQBY0DL, 0x33333333, 252 MX6_MMDC_P0_MPRDDQBY1DL, 0x33333333, 253 MX6_MMDC_P0_MPRDDQBY2DL, 0x33333333, 254 MX6_MMDC_P0_MPRDDQBY3DL, 0x33333333, 255 MX6_MMDC_P0_MPMUR0, 0x00000800, 256 MX6_MMDC_P0_MDPDC, 0x00020036, 257 MX6_MMDC_P0_MDOTC, 0x09444040, 258 MX6_MMDC_P0_MDCFG0, 0xB8BE7955, 259 MX6_MMDC_P0_MDCFG1, 0xFF328F64, 260 MX6_MMDC_P0_MDCFG2, 0x01FF00DB, 261 MX6_MMDC_P0_MDMISC, 0x00011740, 262 MX6_MMDC_P0_MDSCR, 0x00008000, 263 MX6_MMDC_P0_MDRWD, 0x000026D2, 264 MX6_MMDC_P0_MDOR, 0x00BE1023, 265 MX6_MMDC_P0_MDASP, 0x00000047, 266 MX6_MMDC_P0_MDCTL, 0x85190000, 267 MX6_MMDC_P0_MDSCR, 0x00888032, 268 MX6_MMDC_P0_MDSCR, 0x00008033, 269 MX6_MMDC_P0_MDSCR, 0x00008031, 270 MX6_MMDC_P0_MDSCR, 0x19408030, 271 MX6_MMDC_P0_MDSCR, 0x04008040, 272 MX6_MMDC_P0_MDREF, 0x00007800, 273 MX6_MMDC_P0_MPODTCTRL, 0x00000007, 274 MX6_MMDC_P0_MDPDC, 0x00025576, 275 MX6_MMDC_P0_MAPSR, 0x00011006, 276 MX6_MMDC_P0_MDSCR, 0x00000000, 277 /* enable AXI cache for VDOA/VPU/IPU */ 278 279 MX6_IOMUXC_GPR4, 0xF00000CF, 280 /* set IPU AXI-id0 Qos=0xf(bypass) AXI-id1 Qos=0x7 */ 281 MX6_IOMUXC_GPR6, 0x007F007F, 282 MX6_IOMUXC_GPR7, 0x007F007F, 283 }; 284 285 static void ddr_init(int *table, int size) 286 { 287 int i; 288 289 for (i = 0; i < size / 2 ; i++) 290 writel(table[2 * i + 1], table[2 * i]); 291 } 292 293 static void spl_dram_init(void) 294 { 295 if (is_mx6dq()) 296 ddr_init(mx6q_dcd_table, ARRAY_SIZE(mx6q_dcd_table)); 297 } 298 299 void board_init_f(ulong dummy) 300 { 301 /* DDR initialization */ 302 spl_dram_init(); 303 304 /* setup AIPS and disable watchdog */ 305 arch_cpu_init(); 306 307 ccgr_init(); 308 gpr_init(); 309 310 /* iomux and setup of uart and NAND pins */ 311 board_early_init_f(); 312 313 /* setup GP timer */ 314 timer_init(); 315 316 /* UART clocks enabled and gd valid - init serial console */ 317 preloader_console_init(); 318 319 /* Clear the BSS. */ 320 memset(__bss_start, 0, __bss_end - __bss_start); 321 322 /* load/boot image from boot device */ 323 board_init_r(NULL, 0); 324 } 325 #endif 326