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