common: Drop init.h from common header
[platform/kernel/u-boot.git] / drivers / ddr / altera / sdram_soc64.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (C) 2016-2019 Intel Corporation <www.intel.com>
4  *
5  */
6
7 #include <common.h>
8 #include <cpu_func.h>
9 #include <dm.h>
10 #include <errno.h>
11 #include <div64.h>
12 #include <fdtdec.h>
13 #include <hang.h>
14 #include <init.h>
15 #include <ram.h>
16 #include <reset.h>
17 #include "sdram_soc64.h"
18 #include <wait_bit.h>
19 #include <asm/arch/firewall.h>
20 #include <asm/arch/system_manager.h>
21 #include <asm/arch/reset_manager.h>
22 #include <asm/cache.h>
23 #include <asm/io.h>
24 #include <dm/device_compat.h>
25 #include <linux/sizes.h>
26
27 #define PGTABLE_OFF     0x4000
28
29 u32 hmc_readl(struct altera_sdram_platdata *plat, u32 reg)
30 {
31         return readl(plat->iomhc + reg);
32 }
33
34 u32 hmc_ecc_readl(struct altera_sdram_platdata *plat, u32 reg)
35 {
36         return readl(plat->hmc + reg);
37 }
38
39 u32 hmc_ecc_writel(struct altera_sdram_platdata *plat,
40                    u32 data, u32 reg)
41 {
42         return writel(data, plat->hmc + reg);
43 }
44
45 u32 ddr_sch_writel(struct altera_sdram_platdata *plat, u32 data,
46                    u32 reg)
47 {
48         return writel(data, plat->ddr_sch + reg);
49 }
50
51 int emif_clear(struct altera_sdram_platdata *plat)
52 {
53         hmc_ecc_writel(plat, 0, RSTHANDSHAKECTRL);
54
55         return wait_for_bit_le32((const void *)(plat->hmc +
56                                  RSTHANDSHAKESTAT),
57                                  DDR_HMC_RSTHANDSHAKE_MASK,
58                                  false, 1000, false);
59 }
60
61 int emif_reset(struct altera_sdram_platdata *plat)
62 {
63         u32 c2s, s2c, ret;
64
65         c2s = hmc_ecc_readl(plat, RSTHANDSHAKECTRL) & DDR_HMC_RSTHANDSHAKE_MASK;
66         s2c = hmc_ecc_readl(plat, RSTHANDSHAKESTAT) & DDR_HMC_RSTHANDSHAKE_MASK;
67
68         debug("DDR: c2s=%08x s2c=%08x nr0=%08x nr1=%08x nr2=%08x dst=%08x\n",
69               c2s, s2c, hmc_readl(plat, NIOSRESERVED0),
70               hmc_readl(plat, NIOSRESERVED1), hmc_readl(plat, NIOSRESERVED2),
71               hmc_readl(plat, DRAMSTS));
72
73         if (s2c && emif_clear(plat)) {
74                 printf("DDR: emif_clear() failed\n");
75                 return -1;
76         }
77
78         debug("DDR: Triggerring emif reset\n");
79         hmc_ecc_writel(plat, DDR_HMC_CORE2SEQ_INT_REQ, RSTHANDSHAKECTRL);
80
81         /* if seq2core[3] = 0, we are good */
82         ret = wait_for_bit_le32((const void *)(plat->hmc +
83                                  RSTHANDSHAKESTAT),
84                                  DDR_HMC_SEQ2CORE_INT_RESP_MASK,
85                                  false, 1000, false);
86         if (ret) {
87                 printf("DDR: failed to get ack from EMIF\n");
88                 return ret;
89         }
90
91         ret = emif_clear(plat);
92         if (ret) {
93                 printf("DDR: emif_clear() failed\n");
94                 return ret;
95         }
96
97         debug("DDR: %s triggered successly\n", __func__);
98         return 0;
99 }
100
101 int poll_hmc_clock_status(void)
102 {
103         return wait_for_bit_le32((const void *)(socfpga_get_sysmgr_addr() +
104                                  SYSMGR_SOC64_HMC_CLK),
105                                  SYSMGR_HMC_CLK_STATUS_MSK, true, 1000, false);
106 }
107
108 void sdram_clear_mem(phys_addr_t addr, phys_size_t size)
109 {
110         phys_size_t i;
111
112         if (addr % CONFIG_SYS_CACHELINE_SIZE) {
113                 printf("DDR: address 0x%llx is not cacheline size aligned.\n",
114                        addr);
115                 hang();
116         }
117
118         if (size % CONFIG_SYS_CACHELINE_SIZE) {
119                 printf("DDR: size 0x%llx is not multiple of cacheline size\n",
120                        size);
121                 hang();
122         }
123
124         /* Use DC ZVA instruction to clear memory to zeros by a cache line */
125         for (i = 0; i < size; i = i + CONFIG_SYS_CACHELINE_SIZE) {
126                 asm volatile("dc zva, %0"
127                      :
128                      : "r"(addr)
129                      : "memory");
130                 addr += CONFIG_SYS_CACHELINE_SIZE;
131         }
132 }
133
134 void sdram_init_ecc_bits(bd_t *bd)
135 {
136         phys_size_t size, size_init;
137         phys_addr_t start_addr;
138         int bank = 0;
139         unsigned int start = get_timer(0);
140
141         icache_enable();
142
143         start_addr = bd->bi_dram[0].start;
144         size = bd->bi_dram[0].size;
145
146         /* Initialize small block for page table */
147         memset((void *)start_addr, 0, PGTABLE_SIZE + PGTABLE_OFF);
148         gd->arch.tlb_addr = start_addr + PGTABLE_OFF;
149         gd->arch.tlb_size = PGTABLE_SIZE;
150         start_addr += PGTABLE_SIZE + PGTABLE_OFF;
151         size -= (PGTABLE_OFF + PGTABLE_SIZE);
152         dcache_enable();
153
154         while (1) {
155                 while (size) {
156                         size_init = min((phys_addr_t)SZ_1G, (phys_addr_t)size);
157                         sdram_clear_mem(start_addr, size_init);
158                         size -= size_init;
159                         start_addr += size_init;
160                         WATCHDOG_RESET();
161                 }
162
163                 bank++;
164                 if (bank >= CONFIG_NR_DRAM_BANKS)
165                         break;
166
167                 start_addr = bd->bi_dram[bank].start;
168                 size = bd->bi_dram[bank].size;
169         }
170
171         dcache_disable();
172         icache_disable();
173
174         printf("SDRAM-ECC: Initialized success with %d ms\n",
175                (unsigned int)get_timer(start));
176 }
177
178 void sdram_size_check(bd_t *bd)
179 {
180         phys_size_t total_ram_check = 0;
181         phys_size_t ram_check = 0;
182         phys_addr_t start = 0;
183         int bank;
184
185         /* Sanity check ensure correct SDRAM size specified */
186         debug("DDR: Running SDRAM size sanity check\n");
187
188         for (bank = 0; bank < CONFIG_NR_DRAM_BANKS; bank++) {
189                 start = bd->bi_dram[bank].start;
190                 while (ram_check < bd->bi_dram[bank].size) {
191                         ram_check += get_ram_size((void *)(start + ram_check),
192                                                  (phys_size_t)SZ_1G);
193                 }
194                 total_ram_check += ram_check;
195                 ram_check = 0;
196         }
197
198         /* If the ram_size is 2GB smaller, we can assume the IO space is
199          * not mapped in.  gd->ram_size is the actual size of the dram
200          * not the accessible size.
201          */
202         if (total_ram_check != gd->ram_size) {
203                 puts("DDR: SDRAM size check failed!\n");
204                 hang();
205         }
206
207         debug("DDR: SDRAM size check passed!\n");
208 }
209
210 /**
211  * sdram_calculate_size() - Calculate SDRAM size
212  *
213  * Calculate SDRAM device size based on SDRAM controller parameters.
214  * Size is specified in bytes.
215  */
216 phys_size_t sdram_calculate_size(struct altera_sdram_platdata *plat)
217 {
218         u32 dramaddrw = hmc_readl(plat, DRAMADDRW);
219
220         phys_size_t size = 1 << (DRAMADDRW_CFG_CS_ADDR_WIDTH(dramaddrw) +
221                          DRAMADDRW_CFG_BANK_GRP_ADDR_WIDTH(dramaddrw) +
222                          DRAMADDRW_CFG_BANK_ADDR_WIDTH(dramaddrw) +
223                          DRAMADDRW_CFG_ROW_ADDR_WIDTH(dramaddrw) +
224                          DRAMADDRW_CFG_COL_ADDR_WIDTH(dramaddrw));
225
226         size *= (2 << (hmc_ecc_readl(plat, DDRIOCTRL) &
227                         DDR_HMC_DDRIOCTRL_IOSIZE_MSK));
228
229         return size;
230 }
231
232 static int altera_sdram_ofdata_to_platdata(struct udevice *dev)
233 {
234         struct altera_sdram_platdata *plat = dev->platdata;
235         fdt_addr_t addr;
236
237         addr = dev_read_addr_index(dev, 0);
238         if (addr == FDT_ADDR_T_NONE)
239                 return -EINVAL;
240         plat->ddr_sch = (void __iomem *)addr;
241
242         addr = dev_read_addr_index(dev, 1);
243         if (addr == FDT_ADDR_T_NONE)
244                 return -EINVAL;
245         plat->iomhc = (void __iomem *)addr;
246
247         addr = dev_read_addr_index(dev, 2);
248         if (addr == FDT_ADDR_T_NONE)
249                 return -EINVAL;
250         plat->hmc = (void __iomem *)addr;
251
252         return 0;
253 }
254
255 static int altera_sdram_probe(struct udevice *dev)
256 {
257         int ret;
258         struct altera_sdram_priv *priv = dev_get_priv(dev);
259
260         ret = reset_get_bulk(dev, &priv->resets);
261         if (ret) {
262                 dev_err(dev, "Can't get reset: %d\n", ret);
263                 return -ENODEV;
264         }
265         reset_deassert_bulk(&priv->resets);
266
267         if (sdram_mmr_init_full(dev) != 0) {
268                 puts("SDRAM init failed.\n");
269                 goto failed;
270         }
271
272         return 0;
273
274 failed:
275         reset_release_bulk(&priv->resets);
276         return -ENODEV;
277 }
278
279 static int altera_sdram_get_info(struct udevice *dev,
280                                  struct ram_info *info)
281 {
282         struct altera_sdram_priv *priv = dev_get_priv(dev);
283
284         info->base = priv->info.base;
285         info->size = priv->info.size;
286
287         return 0;
288 }
289
290 static struct ram_ops altera_sdram_ops = {
291         .get_info = altera_sdram_get_info,
292 };
293
294 static const struct udevice_id altera_sdram_ids[] = {
295         { .compatible = "altr,sdr-ctl-s10" },
296         { .compatible = "intel,sdr-ctl-agilex" },
297         { /* sentinel */ }
298 };
299
300 U_BOOT_DRIVER(altera_sdram) = {
301         .name = "altr_sdr_ctl",
302         .id = UCLASS_RAM,
303         .of_match = altera_sdram_ids,
304         .ops = &altera_sdram_ops,
305         .ofdata_to_platdata = altera_sdram_ofdata_to_platdata,
306         .platdata_auto_alloc_size = sizeof(struct altera_sdram_platdata),
307         .probe = altera_sdram_probe,
308         .priv_auto_alloc_size = sizeof(struct altera_sdram_priv),
309 };