]>
Commit | Line | Data |
---|---|---|
193030e5 ÁFR |
1 | /* |
2 | * Copyright (C) 2017 Álvaro Fernández Rojas <noltari@gmail.com> | |
3 | * | |
4 | * Derived from linux/arch/mips/bcm63xx/cpu.c: | |
5 | * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr> | |
6 | * Copyright (C) 2009 Florian Fainelli <florian@openwrt.org> | |
7 | * | |
8 | * SPDX-License-Identifier: GPL-2.0+ | |
9 | */ | |
10 | ||
11 | #include <common.h> | |
9d922450 | 12 | #include <dm.h> |
193030e5 ÁFR |
13 | #include <errno.h> |
14 | #include <ram.h> | |
15 | #include <asm/io.h> | |
193030e5 | 16 | |
5a0efcf7 ÁFR |
17 | #define SDRAM_CFG_REG 0x0 |
18 | #define SDRAM_CFG_COL_SHIFT 4 | |
19 | #define SDRAM_CFG_COL_MASK (0x3 << SDRAM_CFG_COL_SHIFT) | |
20 | #define SDRAM_CFG_ROW_SHIFT 6 | |
21 | #define SDRAM_CFG_ROW_MASK (0x3 << SDRAM_CFG_ROW_SHIFT) | |
22 | #define SDRAM_CFG_32B_SHIFT 10 | |
23 | #define SDRAM_CFG_32B_MASK (1 << SDRAM_CFG_32B_SHIFT) | |
24 | #define SDRAM_CFG_BANK_SHIFT 13 | |
25 | #define SDRAM_CFG_BANK_MASK (1 << SDRAM_CFG_BANK_SHIFT) | |
a80bf5e4 ÁFR |
26 | #define SDRAM_6318_SPACE_SHIFT 4 |
27 | #define SDRAM_6318_SPACE_MASK (0xf << SDRAM_6318_SPACE_SHIFT) | |
5a0efcf7 | 28 | |
193030e5 ÁFR |
29 | #define MEMC_CFG_REG 0x4 |
30 | #define MEMC_CFG_32B_SHIFT 1 | |
31 | #define MEMC_CFG_32B_MASK (1 << MEMC_CFG_32B_SHIFT) | |
32 | #define MEMC_CFG_COL_SHIFT 3 | |
33 | #define MEMC_CFG_COL_MASK (0x3 << MEMC_CFG_COL_SHIFT) | |
34 | #define MEMC_CFG_ROW_SHIFT 6 | |
35 | #define MEMC_CFG_ROW_MASK (0x3 << MEMC_CFG_ROW_SHIFT) | |
36 | ||
37 | #define DDR_CSEND_REG 0x8 | |
38 | ||
39 | struct bmips_ram_priv; | |
40 | ||
41 | struct bmips_ram_hw { | |
42 | ulong (*get_ram_size)(struct bmips_ram_priv *); | |
43 | }; | |
44 | ||
45 | struct bmips_ram_priv { | |
46 | void __iomem *regs; | |
47 | const struct bmips_ram_hw *hw; | |
48 | }; | |
49 | ||
a80bf5e4 ÁFR |
50 | static ulong bcm6318_get_ram_size(struct bmips_ram_priv *priv) |
51 | { | |
52 | u32 val; | |
53 | ||
54 | val = readl_be(priv->regs + SDRAM_CFG_REG); | |
55 | val = (val & SDRAM_6318_SPACE_MASK) >> SDRAM_6318_SPACE_SHIFT; | |
56 | ||
57 | return (1 << (val + 20)); | |
58 | } | |
59 | ||
193030e5 ÁFR |
60 | static ulong bcm6328_get_ram_size(struct bmips_ram_priv *priv) |
61 | { | |
62 | return readl_be(priv->regs + DDR_CSEND_REG) << 24; | |
63 | } | |
64 | ||
2165961c ÁFR |
65 | static ulong bmips_dram_size(unsigned int cols, unsigned int rows, |
66 | unsigned int is_32b, unsigned int banks) | |
67 | { | |
68 | rows += 11; /* 0 => 11 address bits ... 2 => 13 address bits */ | |
69 | cols += 8; /* 0 => 8 address bits ... 2 => 10 address bits */ | |
70 | is_32b += 1; | |
71 | ||
72 | return 1 << (cols + rows + is_32b + banks); | |
73 | } | |
74 | ||
5a0efcf7 ÁFR |
75 | static ulong bcm6338_get_ram_size(struct bmips_ram_priv *priv) |
76 | { | |
77 | unsigned int cols = 0, rows = 0, is_32b = 0, banks = 0; | |
78 | u32 val; | |
79 | ||
80 | val = readl_be(priv->regs + SDRAM_CFG_REG); | |
81 | rows = (val & SDRAM_CFG_ROW_MASK) >> SDRAM_CFG_ROW_SHIFT; | |
82 | cols = (val & SDRAM_CFG_COL_MASK) >> SDRAM_CFG_COL_SHIFT; | |
83 | is_32b = (val & SDRAM_CFG_32B_MASK) ? 1 : 0; | |
84 | banks = (val & SDRAM_CFG_BANK_MASK) ? 2 : 1; | |
85 | ||
86 | return bmips_dram_size(cols, rows, is_32b, banks); | |
87 | } | |
88 | ||
193030e5 ÁFR |
89 | static ulong bcm6358_get_ram_size(struct bmips_ram_priv *priv) |
90 | { | |
2165961c | 91 | unsigned int cols = 0, rows = 0, is_32b = 0; |
193030e5 ÁFR |
92 | u32 val; |
93 | ||
94 | val = readl_be(priv->regs + MEMC_CFG_REG); | |
95 | rows = (val & MEMC_CFG_ROW_MASK) >> MEMC_CFG_ROW_SHIFT; | |
96 | cols = (val & MEMC_CFG_COL_MASK) >> MEMC_CFG_COL_SHIFT; | |
2165961c | 97 | is_32b = (val & MEMC_CFG_32B_MASK) ? 0 : 1; |
193030e5 | 98 | |
2165961c | 99 | return bmips_dram_size(cols, rows, is_32b, 2); |
193030e5 ÁFR |
100 | } |
101 | ||
102 | static int bmips_ram_get_info(struct udevice *dev, struct ram_info *info) | |
103 | { | |
104 | struct bmips_ram_priv *priv = dev_get_priv(dev); | |
105 | const struct bmips_ram_hw *hw = priv->hw; | |
106 | ||
107 | info->base = 0x80000000; | |
108 | info->size = hw->get_ram_size(priv); | |
109 | ||
110 | return 0; | |
111 | } | |
112 | ||
113 | static const struct ram_ops bmips_ram_ops = { | |
114 | .get_info = bmips_ram_get_info, | |
115 | }; | |
116 | ||
a80bf5e4 ÁFR |
117 | static const struct bmips_ram_hw bmips_ram_bcm6318 = { |
118 | .get_ram_size = bcm6318_get_ram_size, | |
119 | }; | |
120 | ||
193030e5 ÁFR |
121 | static const struct bmips_ram_hw bmips_ram_bcm6328 = { |
122 | .get_ram_size = bcm6328_get_ram_size, | |
123 | }; | |
124 | ||
5a0efcf7 ÁFR |
125 | static const struct bmips_ram_hw bmips_ram_bcm6338 = { |
126 | .get_ram_size = bcm6338_get_ram_size, | |
127 | }; | |
128 | ||
193030e5 ÁFR |
129 | static const struct bmips_ram_hw bmips_ram_bcm6358 = { |
130 | .get_ram_size = bcm6358_get_ram_size, | |
131 | }; | |
132 | ||
133 | static const struct udevice_id bmips_ram_ids[] = { | |
134 | { | |
a80bf5e4 ÁFR |
135 | .compatible = "brcm,bcm6318-mc", |
136 | .data = (ulong)&bmips_ram_bcm6318, | |
137 | }, { | |
193030e5 ÁFR |
138 | .compatible = "brcm,bcm6328-mc", |
139 | .data = (ulong)&bmips_ram_bcm6328, | |
5a0efcf7 ÁFR |
140 | }, { |
141 | .compatible = "brcm,bcm6338-mc", | |
142 | .data = (ulong)&bmips_ram_bcm6338, | |
193030e5 ÁFR |
143 | }, { |
144 | .compatible = "brcm,bcm6358-mc", | |
145 | .data = (ulong)&bmips_ram_bcm6358, | |
b493a356 | 146 | }, { /* sentinel */ } |
193030e5 ÁFR |
147 | }; |
148 | ||
149 | static int bmips_ram_probe(struct udevice *dev) | |
150 | { | |
151 | struct bmips_ram_priv *priv = dev_get_priv(dev); | |
152 | const struct bmips_ram_hw *hw = | |
153 | (const struct bmips_ram_hw *)dev_get_driver_data(dev); | |
154 | fdt_addr_t addr; | |
155 | fdt_size_t size; | |
156 | ||
a821c4af | 157 | addr = devfdt_get_addr_size_index(dev, 0, &size); |
193030e5 ÁFR |
158 | if (addr == FDT_ADDR_T_NONE) |
159 | return -EINVAL; | |
160 | ||
161 | priv->regs = ioremap(addr, size); | |
162 | priv->hw = hw; | |
163 | ||
164 | return 0; | |
165 | } | |
166 | ||
167 | U_BOOT_DRIVER(bmips_ram) = { | |
168 | .name = "bmips-mc", | |
169 | .id = UCLASS_RAM, | |
170 | .of_match = bmips_ram_ids, | |
171 | .probe = bmips_ram_probe, | |
172 | .priv_auto_alloc_size = sizeof(struct bmips_ram_priv), | |
173 | .ops = &bmips_ram_ops, | |
174 | .flags = DM_FLAG_PRE_RELOC, | |
175 | }; |