Home | History | Annotate | Download | only in mpc83xx
      1 // SPDX-License-Identifier: GPL-2.0+
      2 /*
      3  * Freescale SerDes initialization routine
      4  *
      5  * Copyright 2007,2011 Freescale Semiconductor, Inc.
      6  * Copyright (C) 2008 MontaVista Software, Inc.
      7  *
      8  * Author: Li Yang <leoli (at) freescale.com>
      9  */
     10 
     11 #include <config.h>
     12 #include <common.h>
     13 #include <asm/io.h>
     14 #include <asm/fsl_mpc83xx_serdes.h>
     15 
     16 /* SerDes registers */
     17 #define FSL_SRDSCR0_OFFS		0x0
     18 #define FSL_SRDSCR0_DPP_1V2		0x00008800
     19 #define FSL_SRDSCR0_TXEQA_MASK		0x00007000
     20 #define FSL_SRDSCR0_TXEQA_SATA		0x00001000
     21 #define FSL_SRDSCR0_TXEQE_MASK		0x00000700
     22 #define FSL_SRDSCR0_TXEQE_SATA		0x00000100
     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 
     45 void fsl_setup_serdes(u32 offset, char proto, u32 rfcks, char vdd)
     46 {
     47 	void *regs = (void *)CONFIG_SYS_IMMR + offset;
     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 SRDSCR0 */
     75 		clrsetbits_be32(regs + FSL_SRDSCR0_OFFS,
     76 			FSL_SRDSCR0_TXEQA_MASK | FSL_SRDSCR0_TXEQE_MASK,
     77 			FSL_SRDSCR0_TXEQA_SATA | FSL_SRDSCR0_TXEQE_SATA);
     78 
     79 		/* Configure SRDSCR1 */
     80 		tmp = in_be32(regs + FSL_SRDSCR1_OFFS);
     81 		tmp &= ~FSL_SRDSCR1_PLLBW;
     82 		out_be32(regs + FSL_SRDSCR1_OFFS, tmp);
     83 
     84 		/* Configure SRDSCR2 */
     85 		tmp = in_be32(regs + FSL_SRDSCR2_OFFS);
     86 		tmp &= ~FSL_SRDSCR2_SEIC_MASK;
     87 		tmp |= FSL_SRDSCR2_SEIC_SATA;
     88 		out_be32(regs + FSL_SRDSCR2_OFFS, tmp);
     89 
     90 		/* Configure SRDSCR3 */
     91 		tmp = FSL_SRDSCR3_KFR_SATA | FSL_SRDSCR3_KPH_SATA |
     92 			FSL_SRDSCR3_SDFM_SATA_PEX |
     93 			FSL_SRDSCR3_SDTXL_SATA;
     94 		out_be32(regs + FSL_SRDSCR3_OFFS, tmp);
     95 
     96 		/* Configure SRDSCR4 */
     97 		tmp = rfcks | FSL_SRDSCR4_PROT_SATA;
     98 		out_be32(regs + FSL_SRDSCR4_OFFS, tmp);
     99 		break;
    100 	case FSL_SERDES_PROTO_PEX:
    101 	case FSL_SERDES_PROTO_PEX_X2:
    102 		/* Configure SRDSCR1 */
    103 		tmp = in_be32(regs + FSL_SRDSCR1_OFFS);
    104 		tmp |= FSL_SRDSCR1_PLLBW;
    105 		out_be32(regs + FSL_SRDSCR1_OFFS, tmp);
    106 
    107 		/* Configure SRDSCR2 */
    108 		tmp = in_be32(regs + FSL_SRDSCR2_OFFS);
    109 		tmp &= ~FSL_SRDSCR2_SEIC_MASK;
    110 		tmp |= FSL_SRDSCR2_SEIC_PEX;
    111 		out_be32(regs + FSL_SRDSCR2_OFFS, tmp);
    112 
    113 		/* Configure SRDSCR3 */
    114 		tmp = FSL_SRDSCR3_SDFM_SATA_PEX;
    115 		out_be32(regs + FSL_SRDSCR3_OFFS, tmp);
    116 
    117 		/* Configure SRDSCR4 */
    118 		tmp = rfcks | FSL_SRDSCR4_PROT_PEX;
    119 		if (proto == FSL_SERDES_PROTO_PEX_X2)
    120 			tmp |= FSL_SRDSCR4_PLANE_X2;
    121 		out_be32(regs + FSL_SRDSCR4_OFFS, tmp);
    122 		break;
    123 	case FSL_SERDES_PROTO_SGMII:
    124 		/* Configure SRDSCR1 */
    125 		tmp = in_be32(regs + FSL_SRDSCR1_OFFS);
    126 		tmp &= ~FSL_SRDSCR1_PLLBW;
    127 		out_be32(regs + FSL_SRDSCR1_OFFS, tmp);
    128 
    129 		/* Configure SRDSCR2 */
    130 		tmp = in_be32(regs + FSL_SRDSCR2_OFFS);
    131 		tmp &= ~FSL_SRDSCR2_SEIC_MASK;
    132 		tmp |= FSL_SRDSCR2_SEIC_SGMII;
    133 		out_be32(regs + FSL_SRDSCR2_OFFS, tmp);
    134 
    135 		/* Configure SRDSCR3 */
    136 		out_be32(regs + FSL_SRDSCR3_OFFS, 0);
    137 
    138 		/* Configure SRDSCR4 */
    139 		tmp = rfcks | FSL_SRDSCR4_PROT_SGMII;
    140 		out_be32(regs + FSL_SRDSCR4_OFFS, tmp);
    141 		break;
    142 	default:
    143 		return;
    144 	}
    145 
    146 	/* Do a software reset */
    147 	tmp = in_be32(regs + FSL_SRDSRSTCTL_OFFS);
    148 	tmp |= FSL_SRDSRSTCTL_RST;
    149 	out_be32(regs + FSL_SRDSRSTCTL_OFFS, tmp);
    150 }
    151