2 * Copyright (C) 2008 Freescale Semicondutor, Inc. All rights reserved.
3 * Dave Liu <daveliu@freescale.com>
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
14 #include <asm/immap_85xx.h>
16 /* PORDEVSR register */
17 #define GUTS_PORDEVSR_OFFS 0xc
18 #define GUTS_PORDEVSR_SERDES2_IO_SEL 0x38000000
19 #define GUTS_PORDEVSR_SERDES2_IO_SEL_SHIFT 27
21 /* SerDes CR0 register */
22 #define FSL_SRDSCR0_OFFS 0x0
23 #define FSL_SRDSCR0_TXEQA_MASK 0x00007000
24 #define FSL_SRDSCR0_TXEQA_SGMII 0x00004000
25 #define FSL_SRDSCR0_TXEQA_SATA 0x00001000
26 #define FSL_SRDSCR0_TXEQE_MASK 0x00000700
27 #define FSL_SRDSCR0_TXEQE_SGMII 0x00000400
28 #define FSL_SRDSCR0_TXEQE_SATA 0x00000100
30 /* SerDes CR1 register */
31 #define FSL_SRDSCR1_OFFS 0x4
32 #define FSL_SRDSCR1_LANEA_MASK 0x80200000
33 #define FSL_SRDSCR1_LANEA_OFF 0x80200000
34 #define FSL_SRDSCR1_LANEE_MASK 0x08020000
35 #define FSL_SRDSCR1_LANEE_OFF 0x08020000
37 /* SerDes CR2 register */
38 #define FSL_SRDSCR2_OFFS 0x8
39 #define FSL_SRDSCR2_EICA_MASK 0x00001f00
40 #define FSL_SRDSCR2_EICA_SGMII 0x00000400
41 #define FSL_SRDSCR2_EICA_SATA 0x00001400
42 #define FSL_SRDSCR2_EICE_MASK 0x0000001f
43 #define FSL_SRDSCR2_EICE_SGMII 0x00000004
44 #define FSL_SRDSCR2_EICE_SATA 0x00000014
46 /* SerDes CR3 register */
47 #define FSL_SRDSCR3_OFFS 0xc
48 #define FSL_SRDSCR3_LANEA_MASK 0x3f000700
49 #define FSL_SRDSCR3_LANEA_SGMII 0x00000000
50 #define FSL_SRDSCR3_LANEA_SATA 0x15000500
51 #define FSL_SRDSCR3_LANEE_MASK 0x003f0007
52 #define FSL_SRDSCR3_LANEE_SGMII 0x00000000
53 #define FSL_SRDSCR3_LANEE_SATA 0x00150005
55 void fsl_serdes_init(void)
57 void *guts = (void *)(CFG_MPC85xx_GUTS_ADDR);
58 void *sd = (void *)CFG_MPC85xx_SERDES2_ADDR;
59 u32 pordevsr = in_be32(guts + GUTS_PORDEVSR_OFFS);
63 /* parse the SRDS2_IO_SEL of PORDEVSR */
64 srds2_io_sel = (pordevsr & GUTS_PORDEVSR_SERDES2_IO_SEL)
65 >> GUTS_PORDEVSR_SERDES2_IO_SEL_SHIFT;
67 switch (srds2_io_sel) {
68 case 1: /* Lane A - SATA1, Lane E - SATA2 */
70 tmp = in_be32(sd + FSL_SRDSCR0_OFFS);
71 tmp &= ~FSL_SRDSCR0_TXEQA_MASK;
72 tmp |= FSL_SRDSCR0_TXEQA_SATA;
73 tmp &= ~FSL_SRDSCR0_TXEQE_MASK;
74 tmp |= FSL_SRDSCR0_TXEQE_SATA;
75 out_be32(sd + FSL_SRDSCR0_OFFS, tmp);
77 tmp = in_be32(sd + FSL_SRDSCR1_OFFS);
78 tmp &= ~FSL_SRDSCR1_LANEA_MASK;
79 tmp &= ~FSL_SRDSCR1_LANEE_MASK;
80 out_be32(sd + FSL_SRDSCR1_OFFS, tmp);
82 tmp = in_be32(sd + FSL_SRDSCR2_OFFS);
83 tmp &= ~FSL_SRDSCR2_EICA_MASK;
84 tmp |= FSL_SRDSCR2_EICA_SATA;
85 tmp &= ~FSL_SRDSCR2_EICE_MASK;
86 tmp |= FSL_SRDSCR2_EICE_SATA;
87 out_be32(sd + FSL_SRDSCR2_OFFS, tmp);
89 tmp = in_be32(sd + FSL_SRDSCR3_OFFS);
90 tmp &= ~FSL_SRDSCR3_LANEA_MASK;
91 tmp |= FSL_SRDSCR3_LANEA_SATA;
92 tmp &= ~FSL_SRDSCR3_LANEE_MASK;
93 tmp |= FSL_SRDSCR3_LANEE_SATA;
94 out_be32(sd + FSL_SRDSCR3_OFFS, tmp);
96 case 3: /* Lane A - SATA1, Lane E - disabled */
98 tmp = in_be32(sd + FSL_SRDSCR0_OFFS);
99 tmp &= ~FSL_SRDSCR0_TXEQA_MASK;
100 tmp |= FSL_SRDSCR0_TXEQA_SATA;
101 out_be32(sd + FSL_SRDSCR0_OFFS, tmp);
103 tmp = in_be32(sd + FSL_SRDSCR1_OFFS);
104 tmp &= ~FSL_SRDSCR1_LANEE_MASK;
105 tmp |= FSL_SRDSCR1_LANEE_OFF;
106 out_be32(sd + FSL_SRDSCR1_OFFS, tmp);
108 tmp = in_be32(sd + FSL_SRDSCR2_OFFS);
109 tmp &= ~FSL_SRDSCR2_EICA_MASK;
110 tmp |= FSL_SRDSCR2_EICA_SATA;
111 out_be32(sd + FSL_SRDSCR2_OFFS, tmp);
113 tmp = in_be32(sd + FSL_SRDSCR3_OFFS);
114 tmp &= ~FSL_SRDSCR3_LANEA_MASK;
115 tmp |= FSL_SRDSCR3_LANEA_SATA;
116 out_be32(sd + FSL_SRDSCR3_OFFS, tmp);
118 case 4: /* Lane A - eTSEC1 SGMII, Lane E - eTSEC3 SGMII */
120 tmp = in_be32(sd + FSL_SRDSCR0_OFFS);
121 tmp &= ~FSL_SRDSCR0_TXEQA_MASK;
122 tmp |= FSL_SRDSCR0_TXEQA_SGMII;
123 tmp &= ~FSL_SRDSCR0_TXEQE_MASK;
124 tmp |= FSL_SRDSCR0_TXEQE_SGMII;
125 out_be32(sd + FSL_SRDSCR0_OFFS, tmp);
127 tmp = in_be32(sd + FSL_SRDSCR1_OFFS);
128 tmp &= ~FSL_SRDSCR1_LANEA_MASK;
129 tmp &= ~FSL_SRDSCR1_LANEE_MASK;
130 out_be32(sd + FSL_SRDSCR1_OFFS, tmp);
132 tmp = in_be32(sd + FSL_SRDSCR2_OFFS);
133 tmp &= ~FSL_SRDSCR2_EICA_MASK;
134 tmp |= FSL_SRDSCR2_EICA_SGMII;
135 tmp &= ~FSL_SRDSCR2_EICE_MASK;
136 tmp |= FSL_SRDSCR2_EICE_SGMII;
137 out_be32(sd + FSL_SRDSCR2_OFFS, tmp);
139 tmp = in_be32(sd + FSL_SRDSCR3_OFFS);
140 tmp &= ~FSL_SRDSCR3_LANEA_MASK;
141 tmp |= FSL_SRDSCR3_LANEA_SGMII;
142 tmp &= ~FSL_SRDSCR3_LANEE_MASK;
143 tmp |= FSL_SRDSCR3_LANEE_SGMII;
144 out_be32(sd + FSL_SRDSCR3_OFFS, tmp);
146 case 6: /* Lane A - eTSEC1 SGMII, Lane E - disabled */
148 tmp = in_be32(sd + FSL_SRDSCR0_OFFS);
149 tmp &= ~FSL_SRDSCR0_TXEQA_MASK;
150 tmp |= FSL_SRDSCR0_TXEQA_SGMII;
151 out_be32(sd + FSL_SRDSCR0_OFFS, tmp);
153 tmp = in_be32(sd + FSL_SRDSCR1_OFFS);
154 tmp &= ~FSL_SRDSCR1_LANEE_MASK;
155 tmp |= FSL_SRDSCR1_LANEE_OFF;
156 out_be32(sd + FSL_SRDSCR1_OFFS, tmp);
158 tmp = in_be32(sd + FSL_SRDSCR2_OFFS);
159 tmp &= ~FSL_SRDSCR2_EICA_MASK;
160 tmp |= FSL_SRDSCR2_EICA_SGMII;
161 out_be32(sd + FSL_SRDSCR2_OFFS, tmp);
163 tmp = in_be32(sd + FSL_SRDSCR3_OFFS);
164 tmp &= ~FSL_SRDSCR3_LANEA_MASK;
165 tmp |= FSL_SRDSCR3_LANEA_SGMII;
166 out_be32(sd + FSL_SRDSCR3_OFFS, tmp);
168 case 7: /* Lane A - disabled, Lane E - disabled */
170 tmp = in_be32(sd + FSL_SRDSCR1_OFFS);
171 tmp &= ~FSL_SRDSCR1_LANEA_MASK;
172 tmp |= FSL_SRDSCR1_LANEA_OFF;
173 tmp &= ~FSL_SRDSCR1_LANEE_MASK;
174 tmp |= FSL_SRDSCR1_LANEE_OFF;
175 out_be32(sd + FSL_SRDSCR1_OFFS, tmp);