1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun * ti816x_emif4.c
3*4882a593Smuzhiyun *
4*4882a593Smuzhiyun * TI816x emif4 configuration file
5*4882a593Smuzhiyun *
6*4882a593Smuzhiyun * Copyright (C) 2017, Konsulko Group
7*4882a593Smuzhiyun *
8*4882a593Smuzhiyun * SPDX-License-Identifier: GPL-2.0+
9*4882a593Smuzhiyun */
10*4882a593Smuzhiyun
11*4882a593Smuzhiyun #include <common.h>
12*4882a593Smuzhiyun #include <asm/arch/cpu.h>
13*4882a593Smuzhiyun #include <asm/arch/ddr_defs.h>
14*4882a593Smuzhiyun #include <asm/arch/hardware.h>
15*4882a593Smuzhiyun #include <asm/arch/clock.h>
16*4882a593Smuzhiyun #include <asm/arch/sys_proto.h>
17*4882a593Smuzhiyun #include <asm/io.h>
18*4882a593Smuzhiyun #include <asm/emif.h>
19*4882a593Smuzhiyun
20*4882a593Smuzhiyun /*********************************************************************
21*4882a593Smuzhiyun * Init DDR3 on TI816X EVM
22*4882a593Smuzhiyun *********************************************************************/
ddr_init_settings(const struct cmd_control * ctrl,int emif)23*4882a593Smuzhiyun static void ddr_init_settings(const struct cmd_control *ctrl, int emif)
24*4882a593Smuzhiyun {
25*4882a593Smuzhiyun /*
26*4882a593Smuzhiyun * setup use_rank_delays to 1. This is only necessary when
27*4882a593Smuzhiyun * multiple ranks are in use. Though the EVM does not have
28*4882a593Smuzhiyun * multiple ranks, this is a good value to set.
29*4882a593Smuzhiyun */
30*4882a593Smuzhiyun writel(1, DDRPHY_CONFIG_BASE + 0x134); // DATA0_REG_PHY_USE_RANK0_DELAYS
31*4882a593Smuzhiyun writel(1, DDRPHY_CONFIG_BASE + 0x1d8); // DATA1_REG_PHY_USE_RANK0_DELAYS
32*4882a593Smuzhiyun writel(1, DDRPHY_CONFIG_BASE + 0x27c); // DATA2_REG_PHY_USE_RANK0_DELAYS
33*4882a593Smuzhiyun writel(1, DDRPHY_CONFIG_BASE + 0x320); // DATA3_REG_PHY_USE_RANK0_DELAYS
34*4882a593Smuzhiyun
35*4882a593Smuzhiyun config_cmd_ctrl(ctrl, emif);
36*4882a593Smuzhiyun
37*4882a593Smuzhiyun /* for ddr3 this needs to be set to 1 */
38*4882a593Smuzhiyun writel(0x1, DDRPHY_CONFIG_BASE + 0x0F8); /* init mode */
39*4882a593Smuzhiyun writel(0x1, DDRPHY_CONFIG_BASE + 0x104);
40*4882a593Smuzhiyun writel(0x1, DDRPHY_CONFIG_BASE + 0x19C);
41*4882a593Smuzhiyun writel(0x1, DDRPHY_CONFIG_BASE + 0x1A8);
42*4882a593Smuzhiyun writel(0x1, DDRPHY_CONFIG_BASE + 0x240);
43*4882a593Smuzhiyun writel(0x1, DDRPHY_CONFIG_BASE + 0x24C);
44*4882a593Smuzhiyun writel(0x1, DDRPHY_CONFIG_BASE + 0x2E4);
45*4882a593Smuzhiyun writel(0x1, DDRPHY_CONFIG_BASE + 0x2F0);
46*4882a593Smuzhiyun
47*4882a593Smuzhiyun /*
48*4882a593Smuzhiyun * This represents the initial value for the leveling process. The
49*4882a593Smuzhiyun * value is a ratio - so 0x100 represents one cycle. The real delay
50*4882a593Smuzhiyun * is determined through the leveling process.
51*4882a593Smuzhiyun *
52*4882a593Smuzhiyun * During the leveling process, 0x20 is subtracted from the value, so
53*4882a593Smuzhiyun * we have added that to the value we want to set. We also set the
54*4882a593Smuzhiyun * values such that byte3 completes leveling after byte2 and byte1
55*4882a593Smuzhiyun * after byte0.
56*4882a593Smuzhiyun */
57*4882a593Smuzhiyun writel((0x20 << 10) | 0x20, DDRPHY_CONFIG_BASE + 0x0F0); /* data0 writelvl init ratio */
58*4882a593Smuzhiyun writel(0x0, DDRPHY_CONFIG_BASE + 0x0F4); /* */
59*4882a593Smuzhiyun writel((0x20 << 10) | 0x20, DDRPHY_CONFIG_BASE + 0x194); /* data1 writelvl init ratio */
60*4882a593Smuzhiyun writel(0x0, DDRPHY_CONFIG_BASE + 0x198); /* */
61*4882a593Smuzhiyun writel((0x20 << 10) | 0x20, DDRPHY_CONFIG_BASE + 0x238); /* data2 writelvl init ratio */
62*4882a593Smuzhiyun writel(0x0, DDRPHY_CONFIG_BASE + 0x23c); /* */
63*4882a593Smuzhiyun writel((0x20 << 10) | 0x20, DDRPHY_CONFIG_BASE + 0x2dc); /* data3 writelvl init ratio */
64*4882a593Smuzhiyun writel(0x0, DDRPHY_CONFIG_BASE + 0x2e0); /* */
65*4882a593Smuzhiyun
66*4882a593Smuzhiyun
67*4882a593Smuzhiyun writel((0x20 << 10) | 0x20, DDRPHY_CONFIG_BASE + 0x0FC); /* data0 gatelvl init ratio */
68*4882a593Smuzhiyun writel(0x0, DDRPHY_CONFIG_BASE + 0x100);
69*4882a593Smuzhiyun writel((0x20 << 10) | 0x20, DDRPHY_CONFIG_BASE + 0x1A0); /* data1 gatelvl init ratio */
70*4882a593Smuzhiyun writel(0x0, DDRPHY_CONFIG_BASE + 0x1A4);
71*4882a593Smuzhiyun writel((0x20 << 10) | 0x20, DDRPHY_CONFIG_BASE + 0x244); /* data2 gatelvl init ratio */
72*4882a593Smuzhiyun writel(0x0, DDRPHY_CONFIG_BASE + 0x248);
73*4882a593Smuzhiyun writel((0x20 << 10) | 0x20, DDRPHY_CONFIG_BASE + 0x2E8); /* data3 gatelvl init ratio */
74*4882a593Smuzhiyun writel(0x0, DDRPHY_CONFIG_BASE + 0x2EC);
75*4882a593Smuzhiyun
76*4882a593Smuzhiyun writel(0x5, DDRPHY_CONFIG_BASE + 0x00C); /* cmd0 io config - output impedance of pad */
77*4882a593Smuzhiyun writel(0x5, DDRPHY_CONFIG_BASE + 0x010); /* cmd0 io clk config - output impedance of pad */
78*4882a593Smuzhiyun writel(0x5, DDRPHY_CONFIG_BASE + 0x040); /* cmd1 io config - output impedance of pad */
79*4882a593Smuzhiyun writel(0x5, DDRPHY_CONFIG_BASE + 0x044); /* cmd1 io clk config - output impedance of pad */
80*4882a593Smuzhiyun writel(0x5, DDRPHY_CONFIG_BASE + 0x074); /* cmd2 io config - output impedance of pad */
81*4882a593Smuzhiyun writel(0x5, DDRPHY_CONFIG_BASE + 0x078); /* cmd2 io clk config - output impedance of pad */
82*4882a593Smuzhiyun writel(0x4, DDRPHY_CONFIG_BASE + 0x0A8); /* data0 io config - output impedance of pad */
83*4882a593Smuzhiyun writel(0x4, DDRPHY_CONFIG_BASE + 0x0AC); /* data0 io clk config - output impedance of pad */
84*4882a593Smuzhiyun writel(0x4, DDRPHY_CONFIG_BASE + 0x14C); /* data1 io config - output impedance of pa */
85*4882a593Smuzhiyun writel(0x4, DDRPHY_CONFIG_BASE + 0x150); /* data1 io clk config - output impedance of pad */
86*4882a593Smuzhiyun writel(0x4, DDRPHY_CONFIG_BASE + 0x1F0); /* data2 io config - output impedance of pa */
87*4882a593Smuzhiyun writel(0x4, DDRPHY_CONFIG_BASE + 0x1F4); /* data2 io clk config - output impedance of pad */
88*4882a593Smuzhiyun writel(0x4, DDRPHY_CONFIG_BASE + 0x294); /* data3 io config - output impedance of pa */
89*4882a593Smuzhiyun writel(0x4, DDRPHY_CONFIG_BASE + 0x298); /* data3 io clk config - output impedance of pad */
90*4882a593Smuzhiyun }
91*4882a593Smuzhiyun
ddr3_sw_levelling(const struct ddr_data * data,int emif)92*4882a593Smuzhiyun static void ddr3_sw_levelling(const struct ddr_data *data, int emif)
93*4882a593Smuzhiyun {
94*4882a593Smuzhiyun /* Set the correct value to DDR_VTP_CTRL_0 */
95*4882a593Smuzhiyun writel(0x6, (DDRPHY_CONFIG_BASE + 0x358));
96*4882a593Smuzhiyun
97*4882a593Smuzhiyun writel(data->datafwsratio0, (DDRPHY_CONFIG_BASE + 0x108));
98*4882a593Smuzhiyun writel(data->datafwsratio0, (DDRPHY_CONFIG_BASE + 0x1AC));
99*4882a593Smuzhiyun writel(data->datafwsratio0, (DDRPHY_CONFIG_BASE + 0x250));
100*4882a593Smuzhiyun writel(data->datafwsratio0, (DDRPHY_CONFIG_BASE + 0x2F4));
101*4882a593Smuzhiyun
102*4882a593Smuzhiyun writel(data->datawdsratio0, (DDRPHY_CONFIG_BASE + 0x0DC));
103*4882a593Smuzhiyun writel(data->datawdsratio0, (DDRPHY_CONFIG_BASE + 0x180));
104*4882a593Smuzhiyun writel(data->datawdsratio0, (DDRPHY_CONFIG_BASE + 0x224));
105*4882a593Smuzhiyun writel(data->datawdsratio0, (DDRPHY_CONFIG_BASE + 0x2C8));
106*4882a593Smuzhiyun
107*4882a593Smuzhiyun writel(data->datawrsratio0, (DDRPHY_CONFIG_BASE + 0x120));
108*4882a593Smuzhiyun writel(data->datawrsratio0, (DDRPHY_CONFIG_BASE + 0x1C4));
109*4882a593Smuzhiyun writel(data->datawrsratio0, (DDRPHY_CONFIG_BASE + 0x268));
110*4882a593Smuzhiyun writel(data->datawrsratio0, (DDRPHY_CONFIG_BASE + 0x30C));
111*4882a593Smuzhiyun
112*4882a593Smuzhiyun writel(data->datardsratio0, (DDRPHY_CONFIG_BASE + 0x0C8));
113*4882a593Smuzhiyun writel(data->datardsratio0, (DDRPHY_CONFIG_BASE + 0x16C));
114*4882a593Smuzhiyun writel(data->datardsratio0, (DDRPHY_CONFIG_BASE + 0x210));
115*4882a593Smuzhiyun writel(data->datardsratio0, (DDRPHY_CONFIG_BASE + 0x2B4));
116*4882a593Smuzhiyun }
117*4882a593Smuzhiyun
118*4882a593Smuzhiyun static struct dmm_lisa_map_regs *hw_lisa_map_regs =
119*4882a593Smuzhiyun (struct dmm_lisa_map_regs *)DMM_BASE;
120*4882a593Smuzhiyun
121*4882a593Smuzhiyun #define DMM_PAT_BASE_ADDR (DMM_BASE + 0x420)
config_dmm(const struct dmm_lisa_map_regs * regs)122*4882a593Smuzhiyun void config_dmm(const struct dmm_lisa_map_regs *regs)
123*4882a593Smuzhiyun {
124*4882a593Smuzhiyun writel(0, &hw_lisa_map_regs->dmm_lisa_map_3);
125*4882a593Smuzhiyun writel(0, &hw_lisa_map_regs->dmm_lisa_map_2);
126*4882a593Smuzhiyun writel(0, &hw_lisa_map_regs->dmm_lisa_map_1);
127*4882a593Smuzhiyun writel(0, &hw_lisa_map_regs->dmm_lisa_map_0);
128*4882a593Smuzhiyun
129*4882a593Smuzhiyun writel(regs->dmm_lisa_map_3, &hw_lisa_map_regs->dmm_lisa_map_3);
130*4882a593Smuzhiyun writel(regs->dmm_lisa_map_2, &hw_lisa_map_regs->dmm_lisa_map_2);
131*4882a593Smuzhiyun writel(regs->dmm_lisa_map_1, &hw_lisa_map_regs->dmm_lisa_map_1);
132*4882a593Smuzhiyun writel(regs->dmm_lisa_map_0, &hw_lisa_map_regs->dmm_lisa_map_0);
133*4882a593Smuzhiyun
134*4882a593Smuzhiyun /* Enable Tiled Access */
135*4882a593Smuzhiyun writel(0x80000000, DMM_PAT_BASE_ADDR);
136*4882a593Smuzhiyun }
137*4882a593Smuzhiyun
config_ddr(const struct ddr_data * data,const struct cmd_control * ctrl,const struct emif_regs * regs,const struct dmm_lisa_map_regs * lisa_regs,int nrs)138*4882a593Smuzhiyun void config_ddr(const struct ddr_data *data, const struct cmd_control *ctrl,
139*4882a593Smuzhiyun const struct emif_regs *regs,
140*4882a593Smuzhiyun const struct dmm_lisa_map_regs *lisa_regs, int nrs)
141*4882a593Smuzhiyun {
142*4882a593Smuzhiyun int i;
143*4882a593Smuzhiyun
144*4882a593Smuzhiyun enable_emif_clocks();
145*4882a593Smuzhiyun
146*4882a593Smuzhiyun for (i = 0; i < nrs; i++)
147*4882a593Smuzhiyun ddr_init_settings(ctrl, i);
148*4882a593Smuzhiyun
149*4882a593Smuzhiyun enable_dmm_clocks();
150*4882a593Smuzhiyun
151*4882a593Smuzhiyun /* Program the DMM to for non-interleaved configuration */
152*4882a593Smuzhiyun config_dmm(lisa_regs);
153*4882a593Smuzhiyun
154*4882a593Smuzhiyun /* Program EMIF CFG Registers */
155*4882a593Smuzhiyun for (i = 0; i < nrs; i++) {
156*4882a593Smuzhiyun set_sdram_timings(regs, i);
157*4882a593Smuzhiyun config_sdram(regs, i);
158*4882a593Smuzhiyun }
159*4882a593Smuzhiyun
160*4882a593Smuzhiyun udelay(1000);
161*4882a593Smuzhiyun for (i = 0; i < nrs; i++)
162*4882a593Smuzhiyun ddr3_sw_levelling(data, i);
163*4882a593Smuzhiyun
164*4882a593Smuzhiyun udelay(50000); /* Some delay needed */
165*4882a593Smuzhiyun }
166