]> git.sur5r.net Git - u-boot/blob - cpu/mpc85xx/mpc8536_serdes.c
powerpc: Fix bootm to boot up again with a Ramdisk
[u-boot] / cpu / mpc85xx / mpc8536_serdes.c
1 /*
2  * Copyright (C) 2008 Freescale Semicondutor, Inc. All rights reserved.
3  *      Dave Liu <daveliu@freescale.com>
4  *
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.
9  */
10
11 #include <config.h>
12 #include <common.h>
13 #include <asm/io.h>
14 #include <asm/immap_85xx.h>
15
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
20
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
29
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
36
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
45
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
54
55 void fsl_serdes_init(void)
56 {
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);
60         u32 srds2_io_sel;
61         u32 tmp;
62
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;
66
67         switch (srds2_io_sel) {
68         case 1: /* Lane A - SATA1, Lane E - SATA2 */
69                 /* CR 0 */
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);
76                 /* CR 1 */
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);
81                 /* CR 2 */
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);
88                 /* CR 3 */
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);
95                 break;
96         case 3: /* Lane A - SATA1, Lane E - disabled */
97                 /* CR 0 */
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);
102                 /* CR 1 */
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);
107                 /* CR 2 */
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);
112                 /* CR 3 */
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);
117                 break;
118         case 4: /* Lane A - eTSEC1 SGMII, Lane E - eTSEC3 SGMII */
119                 /* CR 0 */
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);
126                 /* CR 1 */
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);
131                 /* CR 2 */
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);
138                 /* CR 3 */
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);
145                 break;
146         case 6: /* Lane A - eTSEC1 SGMII, Lane E - disabled */
147                 /* CR 0 */
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);
152                 /* CR 1 */
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);
157                 /* CR 2 */
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);
162                 /* CR 3 */
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);
167                 break;
168         case 7: /* Lane A - disabled, Lane E - disabled */
169                 /* CR 1 */
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);
176                 break;
177         default:
178                 break;
179         }
180 }