]>
Commit | Line | Data |
---|---|---|
453316a2 AV |
1 | /* |
2 | * Freescale SerDes initialization routine | |
3 | * | |
4c2e3da8 | 4 | * Copyright (C) 2007 Freescale Semicondutor, Inc. |
453316a2 AV |
5 | * Copyright (C) 2008 MontaVista Software, Inc. All rights reserved. |
6 | * | |
7 | * Author: Li Yang <leoli@freescale.com> | |
8 | * | |
9 | * This program is free software; you can redistribute it and/or modify it | |
10 | * under the terms of the GNU General Public License as published by the | |
11 | * Free Software Foundation; either version 2 of the License, or (at your | |
12 | * option) any later version. | |
13 | */ | |
14 | ||
15 | #include <config.h> | |
16 | #include <common.h> | |
17 | #include <asm/io.h> | |
18 | #include <asm/fsl_serdes.h> | |
19 | ||
20 | /* SerDes registers */ | |
21 | #define FSL_SRDSCR0_OFFS 0x0 | |
22 | #define FSL_SRDSCR0_DPP_1V2 0x00008800 | |
23 | #define FSL_SRDSCR1_OFFS 0x4 | |
24 | #define FSL_SRDSCR1_PLLBW 0x00000040 | |
25 | #define FSL_SRDSCR2_OFFS 0x8 | |
26 | #define FSL_SRDSCR2_VDD_1V2 0x00800000 | |
27 | #define FSL_SRDSCR2_SEIC_MASK 0x00001c1c | |
28 | #define FSL_SRDSCR2_SEIC_SATA 0x00001414 | |
29 | #define FSL_SRDSCR2_SEIC_PEX 0x00001010 | |
30 | #define FSL_SRDSCR2_SEIC_SGMII 0x00000101 | |
31 | #define FSL_SRDSCR3_OFFS 0xc | |
32 | #define FSL_SRDSCR3_KFR_SATA 0x10100000 | |
33 | #define FSL_SRDSCR3_KPH_SATA 0x04040000 | |
34 | #define FSL_SRDSCR3_SDFM_SATA_PEX 0x01010000 | |
35 | #define FSL_SRDSCR3_SDTXL_SATA 0x00000505 | |
36 | #define FSL_SRDSCR4_OFFS 0x10 | |
37 | #define FSL_SRDSCR4_PROT_SATA 0x00000808 | |
38 | #define FSL_SRDSCR4_PROT_PEX 0x00000101 | |
39 | #define FSL_SRDSCR4_PROT_SGMII 0x00000505 | |
40 | #define FSL_SRDSCR4_PLANE_X2 0x01000000 | |
41 | #define FSL_SRDSRSTCTL_OFFS 0x20 | |
42 | #define FSL_SRDSRSTCTL_RST 0x80000000 | |
43 | #define FSL_SRDSRSTCTL_SATA_RESET 0xf | |
44 | ||
6f9cc660 | 45 | void fsl_setup_serdes(u32 offset, char proto, u32 rfcks, char vdd) |
453316a2 | 46 | { |
6d0f6bcf | 47 | void *regs = (void *)CONFIG_SYS_IMMR + offset; |
453316a2 AV |
48 | u32 tmp; |
49 | ||
50 | /* 1.0V corevdd */ | |
51 | if (vdd) { | |
52 | /* DPPE/DPPA = 0 */ | |
53 | tmp = in_be32(regs + FSL_SRDSCR0_OFFS); | |
54 | tmp &= ~FSL_SRDSCR0_DPP_1V2; | |
55 | out_be32(regs + FSL_SRDSCR0_OFFS, tmp); | |
56 | ||
57 | /* VDD = 0 */ | |
58 | tmp = in_be32(regs + FSL_SRDSCR2_OFFS); | |
59 | tmp &= ~FSL_SRDSCR2_VDD_1V2; | |
60 | out_be32(regs + FSL_SRDSCR2_OFFS, tmp); | |
61 | } | |
62 | ||
63 | /* protocol specific configuration */ | |
64 | switch (proto) { | |
65 | case FSL_SERDES_PROTO_SATA: | |
66 | /* Set and clear reset bits */ | |
67 | tmp = in_be32(regs + FSL_SRDSRSTCTL_OFFS); | |
68 | tmp |= FSL_SRDSRSTCTL_SATA_RESET; | |
69 | out_be32(regs + FSL_SRDSRSTCTL_OFFS, tmp); | |
70 | udelay(1000); | |
71 | tmp &= ~FSL_SRDSRSTCTL_SATA_RESET; | |
72 | out_be32(regs + FSL_SRDSRSTCTL_OFFS, tmp); | |
73 | ||
74 | /* Configure SRDSCR1 */ | |
75 | tmp = in_be32(regs + FSL_SRDSCR1_OFFS); | |
76 | tmp &= ~FSL_SRDSCR1_PLLBW; | |
77 | out_be32(regs + FSL_SRDSCR1_OFFS, tmp); | |
78 | ||
79 | /* Configure SRDSCR2 */ | |
80 | tmp = in_be32(regs + FSL_SRDSCR2_OFFS); | |
81 | tmp &= ~FSL_SRDSCR2_SEIC_MASK; | |
82 | tmp |= FSL_SRDSCR2_SEIC_SATA; | |
83 | out_be32(regs + FSL_SRDSCR2_OFFS, tmp); | |
84 | ||
85 | /* Configure SRDSCR3 */ | |
86 | tmp = FSL_SRDSCR3_KFR_SATA | FSL_SRDSCR3_KPH_SATA | | |
87 | FSL_SRDSCR3_SDFM_SATA_PEX | | |
88 | FSL_SRDSCR3_SDTXL_SATA; | |
89 | out_be32(regs + FSL_SRDSCR3_OFFS, tmp); | |
90 | ||
91 | /* Configure SRDSCR4 */ | |
92 | tmp = rfcks | FSL_SRDSCR4_PROT_SATA; | |
93 | out_be32(regs + FSL_SRDSCR4_OFFS, tmp); | |
94 | break; | |
95 | case FSL_SERDES_PROTO_PEX: | |
96 | case FSL_SERDES_PROTO_PEX_X2: | |
97 | /* Configure SRDSCR1 */ | |
98 | tmp = in_be32(regs + FSL_SRDSCR1_OFFS); | |
99 | tmp |= FSL_SRDSCR1_PLLBW; | |
100 | out_be32(regs + FSL_SRDSCR1_OFFS, tmp); | |
101 | ||
102 | /* Configure SRDSCR2 */ | |
103 | tmp = in_be32(regs + FSL_SRDSCR2_OFFS); | |
104 | tmp &= ~FSL_SRDSCR2_SEIC_MASK; | |
105 | tmp |= FSL_SRDSCR2_SEIC_PEX; | |
106 | out_be32(regs + FSL_SRDSCR2_OFFS, tmp); | |
107 | ||
108 | /* Configure SRDSCR3 */ | |
109 | tmp = FSL_SRDSCR3_SDFM_SATA_PEX; | |
110 | out_be32(regs + FSL_SRDSCR3_OFFS, tmp); | |
111 | ||
112 | /* Configure SRDSCR4 */ | |
113 | tmp = rfcks | FSL_SRDSCR4_PROT_PEX; | |
114 | if (proto == FSL_SERDES_PROTO_PEX_X2) | |
115 | tmp |= FSL_SRDSCR4_PLANE_X2; | |
116 | out_be32(regs + FSL_SRDSCR4_OFFS, tmp); | |
117 | break; | |
118 | case FSL_SERDES_PROTO_SGMII: | |
119 | /* Configure SRDSCR1 */ | |
120 | tmp = in_be32(regs + FSL_SRDSCR1_OFFS); | |
121 | tmp &= ~FSL_SRDSCR1_PLLBW; | |
122 | out_be32(regs + FSL_SRDSCR1_OFFS, tmp); | |
123 | ||
124 | /* Configure SRDSCR2 */ | |
125 | tmp = in_be32(regs + FSL_SRDSCR2_OFFS); | |
126 | tmp &= ~FSL_SRDSCR2_SEIC_MASK; | |
127 | tmp |= FSL_SRDSCR2_SEIC_SGMII; | |
128 | out_be32(regs + FSL_SRDSCR2_OFFS, tmp); | |
129 | ||
130 | /* Configure SRDSCR3 */ | |
131 | out_be32(regs + FSL_SRDSCR3_OFFS, 0); | |
132 | ||
133 | /* Configure SRDSCR4 */ | |
134 | tmp = rfcks | FSL_SRDSCR4_PROT_SGMII; | |
135 | out_be32(regs + FSL_SRDSCR4_OFFS, tmp); | |
136 | break; | |
137 | default: | |
138 | return; | |
139 | } | |
140 | ||
141 | /* Do a software reset */ | |
142 | tmp = in_be32(regs + FSL_SRDSRSTCTL_OFFS); | |
143 | tmp |= FSL_SRDSRSTCTL_RST; | |
144 | out_be32(regs + FSL_SRDSRSTCTL_OFFS, tmp); | |
145 | } |