blob: 902de2b6c479c4ac6b807686be1d9116e4326a55 [file] [log] [blame]
Vikas Manochabf1ae442017-04-10 15:02:51 -07001/*
2 * (C) Copyright 2017
3 * Vikas Manocha, <vikas.manocha@st.com>
4 *
5 * SPDX-License-Identifier: GPL-2.0+
6 */
7
8#include <common.h>
Vikas Manochad0b24c12017-04-10 15:02:55 -07009#include <clk.h>
Vikas Manocha910a52e2017-04-10 15:02:52 -070010#include <dm.h>
11#include <ram.h>
Vikas Manochabf1ae442017-04-10 15:02:51 -070012#include <asm/io.h>
13#include <asm/arch/fmc.h>
14#include <asm/arch/stm32.h>
15
Vikas Manocha6c9a1002017-04-10 15:02:56 -070016DECLARE_GLOBAL_DATA_PTR;
17
18struct stm32_sdram_control {
19 u8 no_columns;
20 u8 no_rows;
21 u8 memory_width;
22 u8 no_banks;
23 u8 cas_latency;
Vikas Manochabfea69a2017-04-10 15:03:03 -070024 u8 sdclk;
Vikas Manocha6c9a1002017-04-10 15:02:56 -070025 u8 rd_burst;
26 u8 rd_pipe_delay;
27};
28
29struct stm32_sdram_timing {
30 u8 tmrd;
31 u8 txsr;
32 u8 tras;
33 u8 trc;
34 u8 trp;
Vikas Manochabfea69a2017-04-10 15:03:03 -070035 u8 twr;
Vikas Manocha6c9a1002017-04-10 15:02:56 -070036 u8 trcd;
37};
38struct stm32_sdram_params {
39 u8 no_sdram_banks;
40 struct stm32_sdram_control sdram_control;
41 struct stm32_sdram_timing sdram_timing;
Vikas Manochabfea69a2017-04-10 15:03:03 -070042 u32 sdram_ref_count;
Vikas Manocha6c9a1002017-04-10 15:02:56 -070043};
Vikas Manochabf1ae442017-04-10 15:02:51 -070044
45#define SDRAM_MODE_BL_SHIFT 0
46#define SDRAM_MODE_CAS_SHIFT 4
47#define SDRAM_MODE_BL 0
Vikas Manocha6c9a1002017-04-10 15:02:56 -070048
49int stm32_sdram_init(struct udevice *dev)
Vikas Manochabf1ae442017-04-10 15:02:51 -070050{
Vikas Manocha6c9a1002017-04-10 15:02:56 -070051 struct stm32_sdram_params *params = dev_get_platdata(dev);
Vikas Manochabf1ae442017-04-10 15:02:51 -070052
Vikas Manochabfea69a2017-04-10 15:03:03 -070053 writel(params->sdram_control.sdclk << FMC_SDCR_SDCLK_SHIFT
Vikas Manocha6c9a1002017-04-10 15:02:56 -070054 | params->sdram_control.cas_latency << FMC_SDCR_CAS_SHIFT
55 | params->sdram_control.no_banks << FMC_SDCR_NB_SHIFT
56 | params->sdram_control.memory_width << FMC_SDCR_MWID_SHIFT
57 | params->sdram_control.no_rows << FMC_SDCR_NR_SHIFT
58 | params->sdram_control.no_columns << FMC_SDCR_NC_SHIFT
59 | params->sdram_control.rd_pipe_delay << FMC_SDCR_RPIPE_SHIFT
60 | params->sdram_control.rd_burst << FMC_SDCR_RBURST_SHIFT,
61 &STM32_SDRAM_FMC->sdcr1);
Vikas Manochabf1ae442017-04-10 15:02:51 -070062
Vikas Manochabfea69a2017-04-10 15:03:03 -070063 writel(params->sdram_timing.trcd << FMC_SDTR_TRCD_SHIFT
64 | params->sdram_timing.trp << FMC_SDTR_TRP_SHIFT
65 | params->sdram_timing.twr << FMC_SDTR_TWR_SHIFT
66 | params->sdram_timing.trc << FMC_SDTR_TRC_SHIFT
67 | params->sdram_timing.tras << FMC_SDTR_TRAS_SHIFT
68 | params->sdram_timing.txsr << FMC_SDTR_TXSR_SHIFT
69 | params->sdram_timing.tmrd << FMC_SDTR_TMRD_SHIFT,
Vikas Manocha6c9a1002017-04-10 15:02:56 -070070 &STM32_SDRAM_FMC->sdtr1);
Vikas Manochabf1ae442017-04-10 15:02:51 -070071
72 writel(FMC_SDCMR_BANK_1 | FMC_SDCMR_MODE_START_CLOCK,
73 &STM32_SDRAM_FMC->sdcmr);
74 udelay(200); /* 200 us delay, page 10, "Power-Up" */
75 FMC_BUSY_WAIT();
76
77 writel(FMC_SDCMR_BANK_1 | FMC_SDCMR_MODE_PRECHARGE,
78 &STM32_SDRAM_FMC->sdcmr);
79 udelay(100);
80 FMC_BUSY_WAIT();
81
82 writel((FMC_SDCMR_BANK_1 | FMC_SDCMR_MODE_AUTOREFRESH
83 | 7 << FMC_SDCMR_NRFS_SHIFT), &STM32_SDRAM_FMC->sdcmr);
84 udelay(100);
85 FMC_BUSY_WAIT();
86
87 writel(FMC_SDCMR_BANK_1 | (SDRAM_MODE_BL << SDRAM_MODE_BL_SHIFT
Vikas Manochabfea69a2017-04-10 15:03:03 -070088 | params->sdram_control.cas_latency << SDRAM_MODE_CAS_SHIFT)
Vikas Manochabf1ae442017-04-10 15:02:51 -070089 << FMC_SDCMR_MODE_REGISTER_SHIFT | FMC_SDCMR_MODE_WRITE_MODE,
90 &STM32_SDRAM_FMC->sdcmr);
91 udelay(100);
92 FMC_BUSY_WAIT();
93
94 writel(FMC_SDCMR_BANK_1 | FMC_SDCMR_MODE_NORMAL,
95 &STM32_SDRAM_FMC->sdcmr);
96 FMC_BUSY_WAIT();
97
98 /* Refresh timer */
Vikas Manochabfea69a2017-04-10 15:03:03 -070099 writel((params->sdram_ref_count) << 1, &STM32_SDRAM_FMC->sdrtr);
Vikas Manochabf1ae442017-04-10 15:02:51 -0700100
101 return 0;
102}
Vikas Manocha910a52e2017-04-10 15:02:52 -0700103
Vikas Manocha6c9a1002017-04-10 15:02:56 -0700104static int stm32_fmc_ofdata_to_platdata(struct udevice *dev)
105{
106 int ret;
Simon Glassda409cc2017-05-17 17:18:09 -0600107 int node = dev_of_offset(dev);
Vikas Manocha6c9a1002017-04-10 15:02:56 -0700108 const void *blob = gd->fdt_blob;
109 struct stm32_sdram_params *params = dev_get_platdata(dev);
110
111 params->no_sdram_banks = fdtdec_get_uint(blob, node, "mr-nbanks", 1);
112 debug("%s, no of banks = %d\n", __func__, params->no_sdram_banks);
113
114 fdt_for_each_subnode(node, blob, node) {
115 ret = fdtdec_get_byte_array(blob, node, "st,sdram-control",
116 (u8 *)&params->sdram_control,
117 sizeof(params->sdram_control));
118 if (ret)
119 return ret;
Vikas Manocha6c9a1002017-04-10 15:02:56 -0700120 ret = fdtdec_get_byte_array(blob, node, "st,sdram-timing",
121 (u8 *)&params->sdram_timing,
122 sizeof(params->sdram_timing));
123 if (ret)
124 return ret;
Vikas Manochabfea69a2017-04-10 15:03:03 -0700125
126 params->sdram_ref_count = fdtdec_get_int(blob, node,
127 "st,sdram-refcount", 8196);
Vikas Manocha6c9a1002017-04-10 15:02:56 -0700128 }
129
130 return 0;
131}
132
Vikas Manocha910a52e2017-04-10 15:02:52 -0700133static int stm32_fmc_probe(struct udevice *dev)
134{
Vikas Manochad0b24c12017-04-10 15:02:55 -0700135 int ret;
Patrice Chotard14a50e32017-05-30 15:06:31 +0200136#ifdef CONFIG_CLK
Vikas Manochad0b24c12017-04-10 15:02:55 -0700137 struct clk clk;
Vikas Manocha6c9a1002017-04-10 15:02:56 -0700138
Vikas Manochad0b24c12017-04-10 15:02:55 -0700139 ret = clk_get_by_index(dev, 0, &clk);
140 if (ret < 0)
141 return ret;
142
143 ret = clk_enable(&clk);
144
145 if (ret) {
146 dev_err(dev, "failed to enable clock\n");
147 return ret;
148 }
149#endif
Vikas Manocha6c9a1002017-04-10 15:02:56 -0700150 ret = stm32_sdram_init(dev);
151 if (ret)
152 return ret;
153
Vikas Manocha910a52e2017-04-10 15:02:52 -0700154 return 0;
155}
156
157static int stm32_fmc_get_info(struct udevice *dev, struct ram_info *info)
158{
Vikas Manocha910a52e2017-04-10 15:02:52 -0700159 return 0;
160}
161
162static struct ram_ops stm32_fmc_ops = {
163 .get_info = stm32_fmc_get_info,
164};
165
166static const struct udevice_id stm32_fmc_ids[] = {
167 { .compatible = "st,stm32-fmc" },
168 { }
169};
170
171U_BOOT_DRIVER(stm32_fmc) = {
172 .name = "stm32_fmc",
173 .id = UCLASS_RAM,
174 .of_match = stm32_fmc_ids,
175 .ops = &stm32_fmc_ops,
Vikas Manocha6c9a1002017-04-10 15:02:56 -0700176 .ofdata_to_platdata = stm32_fmc_ofdata_to_platdata,
Vikas Manocha910a52e2017-04-10 15:02:52 -0700177 .probe = stm32_fmc_probe,
Vikas Manocha6c9a1002017-04-10 15:02:56 -0700178 .platdata_auto_alloc_size = sizeof(struct stm32_sdram_params),
Vikas Manocha910a52e2017-04-10 15:02:52 -0700179};