1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun * (C) Copyright 2009
3*4882a593Smuzhiyun * Vipin Kumar, ST Micoelectronics, vipin.kumar@st.com.
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Copyright (C) 2012 Stefan Roese <sr@denx.de>
6*4882a593Smuzhiyun *
7*4882a593Smuzhiyun * SPDX-License-Identifier: GPL-2.0+
8*4882a593Smuzhiyun */
9*4882a593Smuzhiyun
10*4882a593Smuzhiyun #include <common.h>
11*4882a593Smuzhiyun #include <micrel.h>
12*4882a593Smuzhiyun #include <nand.h>
13*4882a593Smuzhiyun #include <netdev.h>
14*4882a593Smuzhiyun #include <phy.h>
15*4882a593Smuzhiyun #include <rtc.h>
16*4882a593Smuzhiyun #include <asm/io.h>
17*4882a593Smuzhiyun #include <asm/mach-types.h>
18*4882a593Smuzhiyun #include <asm/arch/hardware.h>
19*4882a593Smuzhiyun #include <asm/arch/spr_defs.h>
20*4882a593Smuzhiyun #include <asm/arch/spr_misc.h>
21*4882a593Smuzhiyun #include <linux/mtd/fsmc_nand.h>
22*4882a593Smuzhiyun #include "fpga.h"
23*4882a593Smuzhiyun
24*4882a593Smuzhiyun static struct nand_chip nand_chip[CONFIG_SYS_MAX_NAND_DEVICE];
25*4882a593Smuzhiyun
board_init(void)26*4882a593Smuzhiyun int board_init(void)
27*4882a593Smuzhiyun {
28*4882a593Smuzhiyun /*
29*4882a593Smuzhiyun * X600 is equipped with an M41T82 RTC. This RTC has the
30*4882a593Smuzhiyun * HT bit (Halt Update), which needs to be cleared upon
31*4882a593Smuzhiyun * power-up. Otherwise the RTC is halted.
32*4882a593Smuzhiyun */
33*4882a593Smuzhiyun rtc_reset();
34*4882a593Smuzhiyun
35*4882a593Smuzhiyun return spear_board_init(MACH_TYPE_SPEAR600);
36*4882a593Smuzhiyun }
37*4882a593Smuzhiyun
board_late_init(void)38*4882a593Smuzhiyun int board_late_init(void)
39*4882a593Smuzhiyun {
40*4882a593Smuzhiyun /*
41*4882a593Smuzhiyun * Monitor and env protection on by default
42*4882a593Smuzhiyun */
43*4882a593Smuzhiyun flash_protect(FLAG_PROTECT_SET,
44*4882a593Smuzhiyun CONFIG_SYS_FLASH_BASE, CONFIG_SYS_FLASH_BASE +
45*4882a593Smuzhiyun CONFIG_SYS_SPL_LEN + CONFIG_SYS_MONITOR_LEN +
46*4882a593Smuzhiyun 2 * CONFIG_ENV_SECT_SIZE - 1,
47*4882a593Smuzhiyun &flash_info[0]);
48*4882a593Smuzhiyun
49*4882a593Smuzhiyun /* Init FPGA subsystem */
50*4882a593Smuzhiyun x600_init_fpga();
51*4882a593Smuzhiyun
52*4882a593Smuzhiyun return 0;
53*4882a593Smuzhiyun }
54*4882a593Smuzhiyun
55*4882a593Smuzhiyun /*
56*4882a593Smuzhiyun * board_nand_init - Board specific NAND initialization
57*4882a593Smuzhiyun * @nand: mtd private chip structure
58*4882a593Smuzhiyun *
59*4882a593Smuzhiyun * Called by nand_init_chip to initialize the board specific functions
60*4882a593Smuzhiyun */
61*4882a593Smuzhiyun
board_nand_init(void)62*4882a593Smuzhiyun void board_nand_init(void)
63*4882a593Smuzhiyun {
64*4882a593Smuzhiyun struct misc_regs *const misc_regs_p =
65*4882a593Smuzhiyun (struct misc_regs *)CONFIG_SPEAR_MISCBASE;
66*4882a593Smuzhiyun struct nand_chip *nand = &nand_chip[0];
67*4882a593Smuzhiyun
68*4882a593Smuzhiyun if (!(readl(&misc_regs_p->auto_cfg_reg) & MISC_NANDDIS))
69*4882a593Smuzhiyun fsmc_nand_init(nand);
70*4882a593Smuzhiyun }
71*4882a593Smuzhiyun
board_phy_config(struct phy_device * phydev)72*4882a593Smuzhiyun int board_phy_config(struct phy_device *phydev)
73*4882a593Smuzhiyun {
74*4882a593Smuzhiyun unsigned short id1, id2;
75*4882a593Smuzhiyun
76*4882a593Smuzhiyun /* check whether KSZ9031 or AR8035 has to be configured */
77*4882a593Smuzhiyun id1 = phy_read(phydev, MDIO_DEVAD_NONE, 2);
78*4882a593Smuzhiyun id2 = phy_read(phydev, MDIO_DEVAD_NONE, 3);
79*4882a593Smuzhiyun
80*4882a593Smuzhiyun if ((id1 == 0x22) && ((id2 & 0xFFF0) == 0x1620)) {
81*4882a593Smuzhiyun /* PHY configuration for Micrel KSZ9031 */
82*4882a593Smuzhiyun printf("PHY KSZ9031 detected - ");
83*4882a593Smuzhiyun
84*4882a593Smuzhiyun phy_write(phydev, MDIO_DEVAD_NONE, MII_CTRL1000, 0x1c00);
85*4882a593Smuzhiyun
86*4882a593Smuzhiyun /* control data pad skew - devaddr = 0x02, register = 0x04 */
87*4882a593Smuzhiyun ksz9031_phy_extended_write(phydev, 0x02,
88*4882a593Smuzhiyun MII_KSZ9031_EXT_RGMII_CTRL_SIG_SKEW,
89*4882a593Smuzhiyun MII_KSZ9031_MOD_DATA_NO_POST_INC,
90*4882a593Smuzhiyun 0x0000);
91*4882a593Smuzhiyun /* rx data pad skew - devaddr = 0x02, register = 0x05 */
92*4882a593Smuzhiyun ksz9031_phy_extended_write(phydev, 0x02,
93*4882a593Smuzhiyun MII_KSZ9031_EXT_RGMII_RX_DATA_SKEW,
94*4882a593Smuzhiyun MII_KSZ9031_MOD_DATA_NO_POST_INC,
95*4882a593Smuzhiyun 0x0000);
96*4882a593Smuzhiyun /* tx data pad skew - devaddr = 0x02, register = 0x05 */
97*4882a593Smuzhiyun ksz9031_phy_extended_write(phydev, 0x02,
98*4882a593Smuzhiyun MII_KSZ9031_EXT_RGMII_TX_DATA_SKEW,
99*4882a593Smuzhiyun MII_KSZ9031_MOD_DATA_NO_POST_INC,
100*4882a593Smuzhiyun 0x0000);
101*4882a593Smuzhiyun /* gtx and rx clock pad skew - devaddr = 0x02, reg = 0x08 */
102*4882a593Smuzhiyun ksz9031_phy_extended_write(phydev, 0x02,
103*4882a593Smuzhiyun MII_KSZ9031_EXT_RGMII_CLOCK_SKEW,
104*4882a593Smuzhiyun MII_KSZ9031_MOD_DATA_NO_POST_INC,
105*4882a593Smuzhiyun 0x03FF);
106*4882a593Smuzhiyun } else {
107*4882a593Smuzhiyun /* PHY configuration for Vitesse VSC8641 */
108*4882a593Smuzhiyun printf("PHY VSC8641 detected - ");
109*4882a593Smuzhiyun
110*4882a593Smuzhiyun /* Extended PHY control 1, select GMII */
111*4882a593Smuzhiyun phy_write(phydev, MDIO_DEVAD_NONE, 23, 0x0020);
112*4882a593Smuzhiyun
113*4882a593Smuzhiyun /* Software reset necessary after GMII mode selction */
114*4882a593Smuzhiyun phy_reset(phydev);
115*4882a593Smuzhiyun
116*4882a593Smuzhiyun /* Enable extended page register access */
117*4882a593Smuzhiyun phy_write(phydev, MDIO_DEVAD_NONE, 31, 0x0001);
118*4882a593Smuzhiyun
119*4882a593Smuzhiyun /* 17e: Enhanced LED behavior, needs to be written twice */
120*4882a593Smuzhiyun phy_write(phydev, MDIO_DEVAD_NONE, 17, 0x09ff);
121*4882a593Smuzhiyun phy_write(phydev, MDIO_DEVAD_NONE, 17, 0x09ff);
122*4882a593Smuzhiyun
123*4882a593Smuzhiyun /* 16e: Enhanced LED method select */
124*4882a593Smuzhiyun phy_write(phydev, MDIO_DEVAD_NONE, 16, 0xe0ea);
125*4882a593Smuzhiyun
126*4882a593Smuzhiyun /* Disable extended page register access */
127*4882a593Smuzhiyun phy_write(phydev, MDIO_DEVAD_NONE, 31, 0x0000);
128*4882a593Smuzhiyun
129*4882a593Smuzhiyun /* Enable clock output pin */
130*4882a593Smuzhiyun phy_write(phydev, MDIO_DEVAD_NONE, 18, 0x0049);
131*4882a593Smuzhiyun }
132*4882a593Smuzhiyun
133*4882a593Smuzhiyun if (phydev->drv->config)
134*4882a593Smuzhiyun phydev->drv->config(phydev);
135*4882a593Smuzhiyun
136*4882a593Smuzhiyun return 0;
137*4882a593Smuzhiyun }
138*4882a593Smuzhiyun
board_eth_init(bd_t * bis)139*4882a593Smuzhiyun int board_eth_init(bd_t *bis)
140*4882a593Smuzhiyun {
141*4882a593Smuzhiyun int ret = 0;
142*4882a593Smuzhiyun
143*4882a593Smuzhiyun if (designware_initialize(CONFIG_SPEAR_ETHBASE,
144*4882a593Smuzhiyun PHY_INTERFACE_MODE_GMII) >= 0)
145*4882a593Smuzhiyun ret++;
146*4882a593Smuzhiyun
147*4882a593Smuzhiyun return ret;
148*4882a593Smuzhiyun }
149