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