blob: ae091e6ad0e3e5d9e29afaa81623855970738772 [file] [log] [blame]
Kumar Galaef50d6c2008-08-12 11:14:19 -05001/*
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
55void 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}