]>
Commit | Line | Data |
---|---|---|
83d290c5 | 1 | // SPDX-License-Identifier: GPL-2.0+ |
7ab16479 CJ |
2 | /* |
3 | * Copyright 2015-2016 Freescale Semiconductor, Inc. | |
4 | * Copyright 2017 NXP | |
7ab16479 CJ |
5 | */ |
6 | ||
d678a59d | 7 | #include <common.h> |
7ab16479 | 8 | #include <dm.h> |
5e6267af | 9 | #include <net.h> |
7ab16479 CJ |
10 | #include <asm/io.h> |
11 | #include <netdev.h> | |
12 | #include <fm_eth.h> | |
13 | #include <fsl_mdio.h> | |
14 | #include <malloc.h> | |
15 | #include <asm/types.h> | |
16 | #include <fsl_dtsec.h> | |
17 | #include <asm/arch/soc.h> | |
18 | #include <asm/arch-fsl-layerscape/config.h> | |
19 | #include <asm/arch-fsl-layerscape/immap_lsch2.h> | |
20 | #include <asm/arch/fsl_serdes.h> | |
c05ed00a | 21 | #include <linux/delay.h> |
7ab16479 CJ |
22 | #include <net/pfe_eth/pfe_eth.h> |
23 | #include <dm/platform_data/pfe_dm_eth.h> | |
24 | #include <i2c.h> | |
25 | ||
26 | #define DEFAULT_PFE_MDIO_NAME "PFE_MDIO" | |
27 | ||
28 | static inline void ls1012ardb_reset_phy(void) | |
29 | { | |
28e3c39e | 30 | #ifdef CONFIG_TARGET_LS1012ARDB |
7ab16479 | 31 | /* Through reset IO expander reset both RGMII and SGMII PHYs */ |
2147a169 | 32 | #if CONFIG_IS_ENABLED(DM_I2C) |
a0affb36 BL |
33 | struct udevice *dev; |
34 | int ret; | |
35 | ||
36 | /* | |
37 | * The I2C IO-expander PCAL9555A is mouted on I2C1 bus(bus number is 0). | |
38 | */ | |
39 | ret = i2c_get_chip_for_busnum(0, I2C_MUX_IO2_ADDR, | |
40 | 1, &dev); | |
41 | if (ret) { | |
42 | printf("%s: Cannot find udev for a bus %d\n", __func__, | |
43 | 0); | |
44 | return; | |
45 | } | |
46 | /* Config port 0 | |
47 | * - config pin IOXP_RST_ETH1_B and IOXP_RST_ETH2_B | |
48 | * are enabled as an output. | |
49 | */ | |
50 | dm_i2c_reg_write(dev, 6, __PHY_MASK); | |
51 | ||
52 | /* | |
53 | * Set port 0 output a value to reset ETH2 interface | |
54 | * - pin IOXP_RST_ETH2_B output 0b0 | |
55 | */ | |
56 | dm_i2c_reg_write(dev, 2, __PHY_ETH2_MASK); | |
57 | mdelay(10); | |
58 | dm_i2c_reg_write(dev, 2, __PHY_ETH1_MASK); | |
59 | /* | |
60 | * Set port 0 output a value to reset ETH1 interface | |
61 | * - pin IOXP_RST_ETH1_B output 0b0 | |
62 | */ | |
63 | mdelay(10); | |
64 | dm_i2c_reg_write(dev, 2, 0xFF); | |
65 | #else | |
7ab16479 CJ |
66 | i2c_reg_write(I2C_MUX_IO2_ADDR, 6, __PHY_MASK); |
67 | i2c_reg_write(I2C_MUX_IO2_ADDR, 2, __PHY_ETH2_MASK); | |
68 | mdelay(10); | |
69 | i2c_reg_write(I2C_MUX_IO2_ADDR, 2, __PHY_ETH1_MASK); | |
70 | mdelay(10); | |
71 | i2c_reg_write(I2C_MUX_IO2_ADDR, 2, 0xFF); | |
a0affb36 | 72 | #endif |
7ab16479 | 73 | mdelay(50); |
28e3c39e | 74 | #endif |
7ab16479 CJ |
75 | } |
76 | ||
77 | int pfe_eth_board_init(struct udevice *dev) | |
78 | { | |
79 | static int init_done; | |
80 | struct mii_dev *bus; | |
81 | struct pfe_mdio_info mac_mdio_info; | |
82 | struct pfe_eth_dev *priv = dev_get_priv(dev); | |
6cc04547 | 83 | struct ccsr_gur __iomem *gur = (void *)CFG_SYS_FSL_GUTS_ADDR; |
28e3c39e CJ |
84 | |
85 | int srds_s1 = in_be32(&gur->rcwsr[4]) & | |
86 | FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_MASK; | |
87 | srds_s1 >>= FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_SHIFT; | |
7ab16479 CJ |
88 | |
89 | if (!init_done) { | |
90 | ls1012ardb_reset_phy(); | |
91 | mac_mdio_info.reg_base = (void *)EMAC1_BASE_ADDR; | |
92 | mac_mdio_info.name = DEFAULT_PFE_MDIO_NAME; | |
93 | ||
94 | bus = pfe_mdio_init(&mac_mdio_info); | |
95 | if (!bus) { | |
96 | printf("Failed to register mdio\n"); | |
97 | return -1; | |
98 | } | |
99 | init_done = 1; | |
100 | } | |
101 | ||
102 | pfe_set_mdio(priv->gemac_port, | |
103 | miiphy_get_dev_by_name(DEFAULT_PFE_MDIO_NAME)); | |
104 | ||
28e3c39e CJ |
105 | switch (srds_s1) { |
106 | case 0x3508: | |
107 | if (!priv->gemac_port) { | |
108 | /* MAC1 */ | |
109 | pfe_set_phy_address_mode(priv->gemac_port, | |
110 | CONFIG_PFE_EMAC1_PHY_ADDR, | |
111 | PHY_INTERFACE_MODE_SGMII); | |
112 | } else { | |
113 | /* MAC2 */ | |
114 | pfe_set_phy_address_mode(priv->gemac_port, | |
115 | CONFIG_PFE_EMAC2_PHY_ADDR, | |
cb1de606 | 116 | PHY_INTERFACE_MODE_RGMII_ID); |
28e3c39e CJ |
117 | } |
118 | break; | |
119 | case 0x2208: | |
120 | if (!priv->gemac_port) { | |
121 | /* MAC1 */ | |
122 | pfe_set_phy_address_mode(priv->gemac_port, | |
123 | CONFIG_PFE_EMAC1_PHY_ADDR, | |
7c2d5d16 | 124 | PHY_INTERFACE_MODE_2500BASEX); |
28e3c39e CJ |
125 | } else { |
126 | /* MAC2 */ | |
127 | pfe_set_phy_address_mode(priv->gemac_port, | |
128 | CONFIG_PFE_EMAC2_PHY_ADDR, | |
7c2d5d16 | 129 | PHY_INTERFACE_MODE_2500BASEX); |
28e3c39e CJ |
130 | } |
131 | break; | |
132 | default: | |
133 | printf("unsupported SerDes PRCTL= %d\n", srds_s1); | |
134 | break; | |
7ab16479 CJ |
135 | } |
136 | return 0; | |
137 | } | |
138 | ||
139 | static struct pfe_eth_pdata pfe_pdata0 = { | |
140 | .pfe_eth_pdata_mac = { | |
141 | .iobase = (phys_addr_t)EMAC1_BASE_ADDR, | |
142 | .phy_interface = 0, | |
143 | }, | |
144 | ||
145 | .pfe_ddr_addr = { | |
146 | .ddr_pfe_baseaddr = (void *)CONFIG_DDR_PFE_BASEADDR, | |
147 | .ddr_pfe_phys_baseaddr = CONFIG_DDR_PFE_PHYS_BASEADDR, | |
148 | }, | |
149 | }; | |
150 | ||
151 | static struct pfe_eth_pdata pfe_pdata1 = { | |
152 | .pfe_eth_pdata_mac = { | |
153 | .iobase = (phys_addr_t)EMAC2_BASE_ADDR, | |
154 | .phy_interface = 1, | |
155 | }, | |
156 | ||
157 | .pfe_ddr_addr = { | |
158 | .ddr_pfe_baseaddr = (void *)CONFIG_DDR_PFE_BASEADDR, | |
159 | .ddr_pfe_phys_baseaddr = CONFIG_DDR_PFE_PHYS_BASEADDR, | |
160 | }, | |
161 | }; | |
162 | ||
20e442ab | 163 | U_BOOT_DRVINFO(ls1012a_pfe0) = { |
7ab16479 | 164 | .name = "pfe_eth", |
caa4daa2 | 165 | .plat = &pfe_pdata0, |
7ab16479 CJ |
166 | }; |
167 | ||
20e442ab | 168 | U_BOOT_DRVINFO(ls1012a_pfe1) = { |
7ab16479 | 169 | .name = "pfe_eth", |
caa4daa2 | 170 | .plat = &pfe_pdata1, |
7ab16479 | 171 | }; |