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