5de73770a8c0bc48abbc9388e0a4bdecc389a88e
[oweals/u-boot.git] / drivers / ram / rockchip / sdram_phy_px30.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * (C) Copyright 2018 Rockchip Electronics Co., Ltd.
4  */
5
6 #include <common.h>
7 #include <ram.h>
8 #include <asm/io.h>
9 #include <asm/arch-rockchip/sdram.h>
10 #include <asm/arch-rockchip/sdram_common.h>
11 #include <asm/arch-rockchip/sdram_phy_px30.h>
12
13 static void sdram_phy_dll_bypass_set(void __iomem *phy_base, u32 freq)
14 {
15         u32 tmp;
16         u32 i, j;
17         u32 dqs_dll_freq;
18
19         setbits_le32(PHY_REG(phy_base, 0x13), 1 << 4);
20         clrbits_le32(PHY_REG(phy_base, 0x14), 1 << 3);
21         for (i = 0; i < 4; i++) {
22                 j = 0x26 + i * 0x10;
23                 setbits_le32(PHY_REG(phy_base, j), 1 << 4);
24                 clrbits_le32(PHY_REG(phy_base, j + 0x1), 1 << 3);
25         }
26
27         if (freq <= 400)
28                 /* DLL bypass */
29                 setbits_le32(PHY_REG(phy_base, 0xa4), 0x1f);
30         else
31                 clrbits_le32(PHY_REG(phy_base, 0xa4), 0x1f);
32
33         #ifdef CONFIG_ROCKCHIP_RK3328
34         dqs_dll_freq = 680;
35         #else
36         dqs_dll_freq = 801;
37         #endif
38
39         if (freq <= dqs_dll_freq)
40                 tmp = 2;
41         else
42                 tmp = 1;
43
44         for (i = 0; i < 4; i++) {
45                 j = 0x28 + i * 0x10;
46                 writel(tmp, PHY_REG(phy_base, j));
47         }
48 }
49
50 static void sdram_phy_set_ds_odt(void __iomem *phy_base,
51                                  u32 dram_type)
52 {
53         u32 cmd_drv, clk_drv, dqs_drv, dqs_odt;
54         u32 i, j;
55
56         if (dram_type == DDR3) {
57                 cmd_drv = PHY_DDR3_RON_RTT_34ohm;
58                 clk_drv = PHY_DDR3_RON_RTT_45ohm;
59                 dqs_drv = PHY_DDR3_RON_RTT_34ohm;
60                 dqs_odt = PHY_DDR3_RON_RTT_225ohm;
61         } else {
62                 cmd_drv = PHY_DDR4_LPDDR3_RON_RTT_34ohm;
63                 clk_drv = PHY_DDR4_LPDDR3_RON_RTT_43ohm;
64                 dqs_drv = PHY_DDR4_LPDDR3_RON_RTT_34ohm;
65                 if (dram_type == LPDDR2)
66                         dqs_odt = PHY_DDR4_LPDDR3_RON_RTT_DISABLE;
67                 else
68                         dqs_odt = PHY_DDR4_LPDDR3_RON_RTT_240ohm;
69         }
70         /* DS */
71         writel(cmd_drv, PHY_REG(phy_base, 0x11));
72         clrsetbits_le32(PHY_REG(phy_base, 0x12), 0x1f << 3, cmd_drv << 3);
73         writel(clk_drv, PHY_REG(phy_base, 0x16));
74         writel(clk_drv, PHY_REG(phy_base, 0x18));
75
76         for (i = 0; i < 4; i++) {
77                 j = 0x20 + i * 0x10;
78                 writel(dqs_drv, PHY_REG(phy_base, j));
79                 writel(dqs_drv, PHY_REG(phy_base, j + 0xf));
80                 /* ODT */
81                 writel(dqs_odt, PHY_REG(phy_base, j + 0x1));
82                 writel(dqs_odt, PHY_REG(phy_base, j + 0xe));
83         }
84 }
85
86 void phy_soft_reset(void __iomem *phy_base)
87 {
88         clrbits_le32(PHY_REG(phy_base, 0), 0x3 << 2);
89         udelay(1);
90         setbits_le32(PHY_REG(phy_base, 0), ANALOG_DERESET);
91         udelay(5);
92         setbits_le32(PHY_REG(phy_base, 0), DIGITAL_DERESET);
93         udelay(1);
94 }
95
96 void phy_dram_set_bw(void __iomem *phy_base, u32 bw)
97 {
98         if (bw == 2) {
99                 clrsetbits_le32(PHY_REG(phy_base, 0), 0xf << 4, 0xf << 4);
100                 setbits_le32(PHY_REG(phy_base, 0x46), 1 << 3);
101                 setbits_le32(PHY_REG(phy_base, 0x56), 1 << 3);
102         } else if (bw == 1) {
103                 clrsetbits_le32(PHY_REG(phy_base, 0), 0xf << 4, 3 << 4);
104                 clrbits_le32(PHY_REG(phy_base, 0x46), 1 << 3);
105                 clrbits_le32(PHY_REG(phy_base, 0x56), 1 << 3);
106         } else if (bw == 0) {
107                 clrsetbits_le32(PHY_REG(phy_base, 0), 0xf << 4, 1 << 4);
108                 clrbits_le32(PHY_REG(phy_base, 0x36), 1 << 3);
109                 clrbits_le32(PHY_REG(phy_base, 0x46), 1 << 3);
110                 clrbits_le32(PHY_REG(phy_base, 0x56), 1 << 3);
111         }
112
113         phy_soft_reset(phy_base);
114 }
115
116 int phy_data_training(void __iomem *phy_base, u32 cs, u32 dramtype)
117 {
118         u32 ret;
119         u32 odt_val;
120         u32 i, j;
121
122         odt_val = readl(PHY_REG(phy_base, 0x2e));
123
124         for (i = 0; i < 4; i++) {
125                 j = 0x20 + i * 0x10;
126                 writel(PHY_DDR3_RON_RTT_225ohm, PHY_REG(phy_base, j + 0x1));
127                 writel(0, PHY_REG(phy_base, j + 0xe));
128         }
129
130         if (dramtype == DDR4) {
131                 clrsetbits_le32(PHY_REG(phy_base, 0x29), 0x3, 0);
132                 clrsetbits_le32(PHY_REG(phy_base, 0x39), 0x3, 0);
133                 clrsetbits_le32(PHY_REG(phy_base, 0x49), 0x3, 0);
134                 clrsetbits_le32(PHY_REG(phy_base, 0x59), 0x3, 0);
135         }
136         /* choose training cs */
137         clrsetbits_le32(PHY_REG(phy_base, 2), 0x33, (0x20 >> cs));
138         /* enable gate training */
139         clrsetbits_le32(PHY_REG(phy_base, 2), 0x33, (0x20 >> cs) | 1);
140         udelay(50);
141         ret = readl(PHY_REG(phy_base, 0xff));
142         /* disable gate training */
143         clrsetbits_le32(PHY_REG(phy_base, 2), 0x33, (0x20 >> cs) | 0);
144         #ifndef CONFIG_ROCKCHIP_RK3328
145         clrbits_le32(PHY_REG(phy_base, 2), 0x30);
146         #endif
147
148         if (dramtype == DDR4) {
149                 clrsetbits_le32(PHY_REG(phy_base, 0x29), 0x3, 0x2);
150                 clrsetbits_le32(PHY_REG(phy_base, 0x39), 0x3, 0x2);
151                 clrsetbits_le32(PHY_REG(phy_base, 0x49), 0x3, 0x2);
152                 clrsetbits_le32(PHY_REG(phy_base, 0x59), 0x3, 0x2);
153         }
154
155         if (ret & 0x10) {
156                 ret = -1;
157         } else {
158                 ret = (ret & 0xf) ^ (readl(PHY_REG(phy_base, 0)) >> 4);
159                 ret = (ret == 0) ? 0 : -1;
160         }
161
162         for (i = 0; i < 4; i++) {
163                 j = 0x20 + i * 0x10;
164                 writel(odt_val, PHY_REG(phy_base, j + 0x1));
165                 writel(odt_val, PHY_REG(phy_base, j + 0xe));
166         }
167         return ret;
168 }
169
170 void phy_cfg(void __iomem *phy_base,
171              struct ddr_phy_regs *phy_regs, struct ddr_phy_skew *skew,
172              struct sdram_base_params *base, u32 bw)
173 {
174         u32 i;
175
176         sdram_phy_dll_bypass_set(phy_base, base->ddr_freq);
177         for (i = 0; phy_regs->phy[i][0] != 0xFFFFFFFF; i++) {
178                 writel(phy_regs->phy[i][1],
179                        phy_base + phy_regs->phy[i][0]);
180         }
181         if (bw == 2) {
182                 clrsetbits_le32(PHY_REG(phy_base, 0), 0xf << 4, 0xf << 4);
183         } else if (bw == 1) {
184                 clrsetbits_le32(PHY_REG(phy_base, 0), 0xf << 4, 3 << 4);
185                 /* disable DQS2,DQS3 tx dll  for saving power */
186                 clrbits_le32(PHY_REG(phy_base, 0x46), 1 << 3);
187                 clrbits_le32(PHY_REG(phy_base, 0x56), 1 << 3);
188         } else {
189                 clrsetbits_le32(PHY_REG(phy_base, 0), 0xf << 4, 1 << 4);
190                 /* disable DQS2,DQS3 tx dll  for saving power */
191                 clrbits_le32(PHY_REG(phy_base, 0x36), 1 << 3);
192                 clrbits_le32(PHY_REG(phy_base, 0x46), 1 << 3);
193                 clrbits_le32(PHY_REG(phy_base, 0x56), 1 << 3);
194         }
195         sdram_phy_set_ds_odt(phy_base, base->dramtype);
196
197         /* deskew */
198         setbits_le32(PHY_REG(phy_base, 2), 8);
199         sdram_copy_to_reg(PHY_REG(phy_base, 0xb0),
200                           &skew->a0_a1_skew[0], 15 * 4);
201         sdram_copy_to_reg(PHY_REG(phy_base, 0x70),
202                           &skew->cs0_dm0_skew[0], 44 * 4);
203         sdram_copy_to_reg(PHY_REG(phy_base, 0xc0),
204                           &skew->cs1_dm0_skew[0], 44 * 4);
205 }