blob: 3632c22be29adaf9fbf76067902c1618805d4d2c [file] [log] [blame]
Khoronzhuk, Ivana43febd2014-10-22 17:18:21 +03001/*
2 * TI serdes driver for keystone2.
3 *
4 * (C) Copyright 2014
5 * Texas Instruments Incorporated, <www.ti.com>
6 *
7 * SPDX-License-Identifier: GPL-2.0+
8 */
9
10#include <common.h>
11
Hao Zhang95f74da2014-10-22 17:18:22 +030012#define SERDES_LANE_REGS(x) (0x0200 + (0x200 * (x)))
13
14struct serdes_cfg {
15 u32 ofs;
16 u32 val;
17 u32 mask;
18};
19
20static struct serdes_cfg cfg_cmu_156p25m_5g[] = {
21 {0x0000, 0x00800000, 0xffff0000},
22 {0x0014, 0x00008282, 0x0000ffff},
23 {0x0060, 0x00142438, 0x00ffffff},
24 {0x0064, 0x00c3c700, 0x00ffff00},
25 {0x0078, 0x0000c000, 0x0000ff00}
26};
27
28static struct serdes_cfg cfg_comlane_156p25m_5g[] = {
29 {0x0a00, 0x00000800, 0x0000ff00},
30 {0x0a08, 0x38a20000, 0xffff0000},
31 {0x0a30, 0x008a8a00, 0x00ffff00},
32 {0x0a84, 0x00000600, 0x0000ff00},
33 {0x0a94, 0x10000000, 0xff000000},
34 {0x0aa0, 0x81000000, 0xff000000},
35 {0x0abc, 0xff000000, 0xff000000},
36 {0x0ac0, 0x0000008b, 0x000000ff},
37 {0x0b08, 0x583f0000, 0xffff0000},
38 {0x0b0c, 0x0000004e, 0x000000ff}
39};
40
41static struct serdes_cfg cfg_lane_156p25mhz_5g[] = {
42 {0x0004, 0x38000080, 0xff0000ff},
43 {0x0008, 0x00000000, 0x000000ff},
44 {0x000c, 0x02000000, 0xff000000},
45 {0x0010, 0x1b000000, 0xff000000},
46 {0x0014, 0x00006fb8, 0x0000ffff},
47 {0x0018, 0x758000e4, 0xffff00ff},
48 {0x00ac, 0x00004400, 0x0000ff00},
49 {0x002c, 0x00100800, 0x00ffff00},
50 {0x0080, 0x00820082, 0x00ff00ff},
51 {0x0084, 0x1d0f0385, 0xffffffff}
52
53};
54
55static inline void ks2_serdes_rmw(u32 addr, u32 value, u32 mask)
56{
57 writel(((readl(addr) & (~mask)) | (value & mask)), addr);
58}
59
60static void ks2_serdes_cfg_setup(u32 base, struct serdes_cfg *cfg, u32 size)
61{
62 u32 i;
63
64 for (i = 0; i < size; i++)
65 ks2_serdes_rmw(base + cfg[i].ofs, cfg[i].val, cfg[i].mask);
66}
67
68static void ks2_serdes_lane_config(u32 base, struct serdes_cfg *cfg_lane,
69 u32 size, u32 lane)
70{
71 u32 i;
72
73 for (i = 0; i < size; i++)
74 ks2_serdes_rmw(base + cfg_lane[i].ofs + SERDES_LANE_REGS(lane),
75 cfg_lane[i].val, cfg_lane[i].mask);
76}
77
78static int ks2_serdes_init_156p25m_5g(u32 base, u32 num_lanes)
79{
80 u32 i;
81
82 ks2_serdes_cfg_setup(base, cfg_cmu_156p25m_5g,
83 ARRAY_SIZE(cfg_cmu_156p25m_5g));
84 ks2_serdes_cfg_setup(base, cfg_comlane_156p25m_5g,
85 ARRAY_SIZE(cfg_comlane_156p25m_5g));
86
87 for (i = 0; i < num_lanes; i++)
88 ks2_serdes_lane_config(base, cfg_lane_156p25mhz_5g,
89 ARRAY_SIZE(cfg_lane_156p25mhz_5g), i);
90
91 return 0;
92}
93
Khoronzhuk, Ivana43febd2014-10-22 17:18:21 +030094void ks2_serdes_sgmii_156p25mhz_setup(void)
95{
96 unsigned int cnt;
97
Hao Zhang95f74da2014-10-22 17:18:22 +030098 ks2_serdes_init_156p25m_5g(CONFIG_KS2_SERDES_SGMII_BASE,
99 CONFIG_KS2_SERDES_LANES_PER_SGMII);
Khoronzhuk, Ivana43febd2014-10-22 17:18:21 +0300100
101 /*Bring SerDes out of Reset if SerDes is Shutdown & is in Reset Mode*/
102 clrbits_le32(0x0232a010, 1 << 28);
103
104 /* Enable TX and RX via the LANExCTL_STS 0x0000 + x*4 */
105 clrbits_le32(0x0232a228, 1 << 29);
106 writel(0xF800F8C0, 0x0232bfe0);
107 clrbits_le32(0x0232a428, 1 << 29);
108 writel(0xF800F8C0, 0x0232bfe4);
109 clrbits_le32(0x0232a628, 1 << 29);
110 writel(0xF800F8C0, 0x0232bfe8);
111 clrbits_le32(0x0232a828, 1 << 29);
112 writel(0xF800F8C0, 0x0232bfec);
113
114 /*Enable pll via the pll_ctrl 0x0014*/
115 writel(0xe0000000, 0x0232bff4)
116 ;
117
118 /*Waiting for SGMII Serdes PLL lock.*/
119 for (cnt = 10000; cnt > 0 && ((readl(0x02090114) & 0x10) == 0); cnt--)
120 ;
121 for (cnt = 10000; cnt > 0 && ((readl(0x02090214) & 0x10) == 0); cnt--)
122 ;
123 for (cnt = 10000; cnt > 0 && ((readl(0x02090414) & 0x10) == 0); cnt--)
124 ;
125 for (cnt = 10000; cnt > 0 && ((readl(0x02090514) & 0x10) == 0); cnt--)
126 ;
127
128 udelay(45000);
129}