1 /* 2 * Freescale SerDes initialization routine 3 * 4 * Copyright (C) 2007,2011 Freescale Semicondutor, Inc. 5 * Copyright (C) 2008 MontaVista Software, Inc. 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_mpc83xx_serdes.h> 19 20 /* SerDes registers */ 21 #define FSL_SRDSCR0_OFFS 0x0 22 #define FSL_SRDSCR0_DPP_1V2 0x00008800 23 #define FSL_SRDSCR0_TXEQA_MASK 0x00007000 24 #define FSL_SRDSCR0_TXEQA_SATA 0x00001000 25 #define FSL_SRDSCR0_TXEQE_MASK 0x00000700 26 #define FSL_SRDSCR0_TXEQE_SATA 0x00000100 27 #define FSL_SRDSCR1_OFFS 0x4 28 #define FSL_SRDSCR1_PLLBW 0x00000040 29 #define FSL_SRDSCR2_OFFS 0x8 30 #define FSL_SRDSCR2_VDD_1V2 0x00800000 31 #define FSL_SRDSCR2_SEIC_MASK 0x00001c1c 32 #define FSL_SRDSCR2_SEIC_SATA 0x00001414 33 #define FSL_SRDSCR2_SEIC_PEX 0x00001010 34 #define FSL_SRDSCR2_SEIC_SGMII 0x00000101 35 #define FSL_SRDSCR3_OFFS 0xc 36 #define FSL_SRDSCR3_KFR_SATA 0x10100000 37 #define FSL_SRDSCR3_KPH_SATA 0x04040000 38 #define FSL_SRDSCR3_SDFM_SATA_PEX 0x01010000 39 #define FSL_SRDSCR3_SDTXL_SATA 0x00000505 40 #define FSL_SRDSCR4_OFFS 0x10 41 #define FSL_SRDSCR4_PROT_SATA 0x00000808 42 #define FSL_SRDSCR4_PROT_PEX 0x00000101 43 #define FSL_SRDSCR4_PROT_SGMII 0x00000505 44 #define FSL_SRDSCR4_PLANE_X2 0x01000000 45 #define FSL_SRDSRSTCTL_OFFS 0x20 46 #define FSL_SRDSRSTCTL_RST 0x80000000 47 #define FSL_SRDSRSTCTL_SATA_RESET 0xf 48 49 void fsl_setup_serdes(u32 offset, char proto, u32 rfcks, char vdd) 50 { 51 void *regs = (void *)CONFIG_SYS_IMMR + offset; 52 u32 tmp; 53 54 /* 1.0V corevdd */ 55 if (vdd) { 56 /* DPPE/DPPA = 0 */ 57 tmp = in_be32(regs + FSL_SRDSCR0_OFFS); 58 tmp &= ~FSL_SRDSCR0_DPP_1V2; 59 out_be32(regs + FSL_SRDSCR0_OFFS, tmp); 60 61 /* VDD = 0 */ 62 tmp = in_be32(regs + FSL_SRDSCR2_OFFS); 63 tmp &= ~FSL_SRDSCR2_VDD_1V2; 64 out_be32(regs + FSL_SRDSCR2_OFFS, tmp); 65 } 66 67 /* protocol specific configuration */ 68 switch (proto) { 69 case FSL_SERDES_PROTO_SATA: 70 /* Set and clear reset bits */ 71 tmp = in_be32(regs + FSL_SRDSRSTCTL_OFFS); 72 tmp |= FSL_SRDSRSTCTL_SATA_RESET; 73 out_be32(regs + FSL_SRDSRSTCTL_OFFS, tmp); 74 udelay(1000); 75 tmp &= ~FSL_SRDSRSTCTL_SATA_RESET; 76 out_be32(regs + FSL_SRDSRSTCTL_OFFS, tmp); 77 78 /* Configure SRDSCR0 */ 79 clrsetbits_be32(regs + FSL_SRDSCR0_OFFS, 80 FSL_SRDSCR0_TXEQA_MASK | FSL_SRDSCR0_TXEQE_MASK, 81 FSL_SRDSCR0_TXEQA_SATA | FSL_SRDSCR0_TXEQE_SATA); 82 83 /* Configure SRDSCR1 */ 84 tmp = in_be32(regs + FSL_SRDSCR1_OFFS); 85 tmp &= ~FSL_SRDSCR1_PLLBW; 86 out_be32(regs + FSL_SRDSCR1_OFFS, tmp); 87 88 /* Configure SRDSCR2 */ 89 tmp = in_be32(regs + FSL_SRDSCR2_OFFS); 90 tmp &= ~FSL_SRDSCR2_SEIC_MASK; 91 tmp |= FSL_SRDSCR2_SEIC_SATA; 92 out_be32(regs + FSL_SRDSCR2_OFFS, tmp); 93 94 /* Configure SRDSCR3 */ 95 tmp = FSL_SRDSCR3_KFR_SATA | FSL_SRDSCR3_KPH_SATA | 96 FSL_SRDSCR3_SDFM_SATA_PEX | 97 FSL_SRDSCR3_SDTXL_SATA; 98 out_be32(regs + FSL_SRDSCR3_OFFS, tmp); 99 100 /* Configure SRDSCR4 */ 101 tmp = rfcks | FSL_SRDSCR4_PROT_SATA; 102 out_be32(regs + FSL_SRDSCR4_OFFS, tmp); 103 break; 104 case FSL_SERDES_PROTO_PEX: 105 case FSL_SERDES_PROTO_PEX_X2: 106 /* Configure SRDSCR1 */ 107 tmp = in_be32(regs + FSL_SRDSCR1_OFFS); 108 tmp |= FSL_SRDSCR1_PLLBW; 109 out_be32(regs + FSL_SRDSCR1_OFFS, tmp); 110 111 /* Configure SRDSCR2 */ 112 tmp = in_be32(regs + FSL_SRDSCR2_OFFS); 113 tmp &= ~FSL_SRDSCR2_SEIC_MASK; 114 tmp |= FSL_SRDSCR2_SEIC_PEX; 115 out_be32(regs + FSL_SRDSCR2_OFFS, tmp); 116 117 /* Configure SRDSCR3 */ 118 tmp = FSL_SRDSCR3_SDFM_SATA_PEX; 119 out_be32(regs + FSL_SRDSCR3_OFFS, tmp); 120 121 /* Configure SRDSCR4 */ 122 tmp = rfcks | FSL_SRDSCR4_PROT_PEX; 123 if (proto == FSL_SERDES_PROTO_PEX_X2) 124 tmp |= FSL_SRDSCR4_PLANE_X2; 125 out_be32(regs + FSL_SRDSCR4_OFFS, tmp); 126 break; 127 case FSL_SERDES_PROTO_SGMII: 128 /* Configure SRDSCR1 */ 129 tmp = in_be32(regs + FSL_SRDSCR1_OFFS); 130 tmp &= ~FSL_SRDSCR1_PLLBW; 131 out_be32(regs + FSL_SRDSCR1_OFFS, tmp); 132 133 /* Configure SRDSCR2 */ 134 tmp = in_be32(regs + FSL_SRDSCR2_OFFS); 135 tmp &= ~FSL_SRDSCR2_SEIC_MASK; 136 tmp |= FSL_SRDSCR2_SEIC_SGMII; 137 out_be32(regs + FSL_SRDSCR2_OFFS, tmp); 138 139 /* Configure SRDSCR3 */ 140 out_be32(regs + FSL_SRDSCR3_OFFS, 0); 141 142 /* Configure SRDSCR4 */ 143 tmp = rfcks | FSL_SRDSCR4_PROT_SGMII; 144 out_be32(regs + FSL_SRDSCR4_OFFS, tmp); 145 break; 146 default: 147 return; 148 } 149 150 /* Do a software reset */ 151 tmp = in_be32(regs + FSL_SRDSRSTCTL_OFFS); 152 tmp |= FSL_SRDSRSTCTL_RST; 153 out_be32(regs + FSL_SRDSRSTCTL_OFFS, tmp); 154 } 155