2 * Copyright (C) 2008 Freescale Semicondutor, Inc.
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 *)(CONFIG_SYS_MPC85xx_GUTS_ADDR
);
58 void *sd
= (void *)CONFIG_SYS_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
);