]>
Commit | Line | Data |
---|---|---|
83d290c5 | 1 | // SPDX-License-Identifier: GPL-2.0+ |
193030e5 ÁFR |
2 | /* |
3 | * Copyright (C) 2017 Álvaro Fernández Rojas <[email protected]> | |
4 | * | |
5 | * Derived from linux/arch/mips/bcm63xx/cpu.c: | |
6 | * Copyright (C) 2008 Maxime Bizon <[email protected]> | |
7 | * Copyright (C) 2009 Florian Fainelli <[email protected]> | |
193030e5 ÁFR |
8 | */ |
9 | ||
10 | #include <common.h> | |
9d922450 | 11 | #include <dm.h> |
193030e5 | 12 | #include <errno.h> |
9b4a205f | 13 | #include <init.h> |
193030e5 ÁFR |
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; | |
3e4a68d3 | 47 | u32 force_size; |
193030e5 ÁFR |
48 | const struct bmips_ram_hw *hw; |
49 | }; | |
50 | ||
a80bf5e4 ÁFR |
51 | static ulong bcm6318_get_ram_size(struct bmips_ram_priv *priv) |
52 | { | |
53 | u32 val; | |
54 | ||
55 | val = readl_be(priv->regs + SDRAM_CFG_REG); | |
56 | val = (val & SDRAM_6318_SPACE_MASK) >> SDRAM_6318_SPACE_SHIFT; | |
57 | ||
58 | return (1 << (val + 20)); | |
59 | } | |
60 | ||
193030e5 ÁFR |
61 | static ulong bcm6328_get_ram_size(struct bmips_ram_priv *priv) |
62 | { | |
63 | return readl_be(priv->regs + DDR_CSEND_REG) << 24; | |
64 | } | |
65 | ||
2165961c ÁFR |
66 | static ulong bmips_dram_size(unsigned int cols, unsigned int rows, |
67 | unsigned int is_32b, unsigned int banks) | |
68 | { | |
69 | rows += 11; /* 0 => 11 address bits ... 2 => 13 address bits */ | |
70 | cols += 8; /* 0 => 8 address bits ... 2 => 10 address bits */ | |
71 | is_32b += 1; | |
72 | ||
73 | return 1 << (cols + rows + is_32b + banks); | |
74 | } | |
75 | ||
5a0efcf7 ÁFR |
76 | static ulong bcm6338_get_ram_size(struct bmips_ram_priv *priv) |
77 | { | |
78 | unsigned int cols = 0, rows = 0, is_32b = 0, banks = 0; | |
79 | u32 val; | |
80 | ||
81 | val = readl_be(priv->regs + SDRAM_CFG_REG); | |
82 | rows = (val & SDRAM_CFG_ROW_MASK) >> SDRAM_CFG_ROW_SHIFT; | |
83 | cols = (val & SDRAM_CFG_COL_MASK) >> SDRAM_CFG_COL_SHIFT; | |
84 | is_32b = (val & SDRAM_CFG_32B_MASK) ? 1 : 0; | |
85 | banks = (val & SDRAM_CFG_BANK_MASK) ? 2 : 1; | |
86 | ||
87 | return bmips_dram_size(cols, rows, is_32b, banks); | |
88 | } | |
89 | ||
193030e5 ÁFR |
90 | static ulong bcm6358_get_ram_size(struct bmips_ram_priv *priv) |
91 | { | |
2165961c | 92 | unsigned int cols = 0, rows = 0, is_32b = 0; |
193030e5 ÁFR |
93 | u32 val; |
94 | ||
95 | val = readl_be(priv->regs + MEMC_CFG_REG); | |
96 | rows = (val & MEMC_CFG_ROW_MASK) >> MEMC_CFG_ROW_SHIFT; | |
97 | cols = (val & MEMC_CFG_COL_MASK) >> MEMC_CFG_COL_SHIFT; | |
2165961c | 98 | is_32b = (val & MEMC_CFG_32B_MASK) ? 0 : 1; |
193030e5 | 99 | |
2165961c | 100 | return bmips_dram_size(cols, rows, is_32b, 2); |
193030e5 ÁFR |
101 | } |
102 | ||
103 | static int bmips_ram_get_info(struct udevice *dev, struct ram_info *info) | |
104 | { | |
105 | struct bmips_ram_priv *priv = dev_get_priv(dev); | |
106 | const struct bmips_ram_hw *hw = priv->hw; | |
107 | ||
108 | info->base = 0x80000000; | |
3e4a68d3 PR |
109 | if (priv->force_size) |
110 | info->size = priv->force_size; | |
111 | else | |
112 | info->size = hw->get_ram_size(priv); | |
193030e5 ÁFR |
113 | |
114 | return 0; | |
115 | } | |
116 | ||
117 | static const struct ram_ops bmips_ram_ops = { | |
118 | .get_info = bmips_ram_get_info, | |
119 | }; | |
120 | ||
a80bf5e4 ÁFR |
121 | static const struct bmips_ram_hw bmips_ram_bcm6318 = { |
122 | .get_ram_size = bcm6318_get_ram_size, | |
123 | }; | |
124 | ||
193030e5 ÁFR |
125 | static const struct bmips_ram_hw bmips_ram_bcm6328 = { |
126 | .get_ram_size = bcm6328_get_ram_size, | |
127 | }; | |
128 | ||
5a0efcf7 ÁFR |
129 | static const struct bmips_ram_hw bmips_ram_bcm6338 = { |
130 | .get_ram_size = bcm6338_get_ram_size, | |
131 | }; | |
132 | ||
193030e5 ÁFR |
133 | static const struct bmips_ram_hw bmips_ram_bcm6358 = { |
134 | .get_ram_size = bcm6358_get_ram_size, | |
135 | }; | |
136 | ||
137 | static const struct udevice_id bmips_ram_ids[] = { | |
138 | { | |
a80bf5e4 ÁFR |
139 | .compatible = "brcm,bcm6318-mc", |
140 | .data = (ulong)&bmips_ram_bcm6318, | |
141 | }, { | |
193030e5 ÁFR |
142 | .compatible = "brcm,bcm6328-mc", |
143 | .data = (ulong)&bmips_ram_bcm6328, | |
5a0efcf7 ÁFR |
144 | }, { |
145 | .compatible = "brcm,bcm6338-mc", | |
146 | .data = (ulong)&bmips_ram_bcm6338, | |
193030e5 ÁFR |
147 | }, { |
148 | .compatible = "brcm,bcm6358-mc", | |
149 | .data = (ulong)&bmips_ram_bcm6358, | |
b493a356 | 150 | }, { /* sentinel */ } |
193030e5 ÁFR |
151 | }; |
152 | ||
153 | static int bmips_ram_probe(struct udevice *dev) | |
154 | { | |
155 | struct bmips_ram_priv *priv = dev_get_priv(dev); | |
156 | const struct bmips_ram_hw *hw = | |
157 | (const struct bmips_ram_hw *)dev_get_driver_data(dev); | |
193030e5 | 158 | |
13a7bfe4 ÁFR |
159 | priv->regs = dev_remap_addr(dev); |
160 | if (!priv->regs) | |
193030e5 ÁFR |
161 | return -EINVAL; |
162 | ||
3e4a68d3 PR |
163 | dev_read_u32(dev, "force-size", &priv->force_size); |
164 | ||
193030e5 ÁFR |
165 | priv->hw = hw; |
166 | ||
167 | return 0; | |
168 | } | |
169 | ||
170 | U_BOOT_DRIVER(bmips_ram) = { | |
171 | .name = "bmips-mc", | |
172 | .id = UCLASS_RAM, | |
173 | .of_match = bmips_ram_ids, | |
174 | .probe = bmips_ram_probe, | |
41575d8e | 175 | .priv_auto = sizeof(struct bmips_ram_priv), |
193030e5 | 176 | .ops = &bmips_ram_ops, |
193030e5 | 177 | }; |