2 * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
16 #include <linux/log2.h>
17 #include <linux/module.h>
19 #include <linux/of_address.h>
20 #include <linux/of_platform.h>
21 #include <linux/platform_device.h>
23 /* System Bus Controller registers */
24 #define UNIPHIER_SBC_BASE 0x100 /* base address of bank0 space */
25 #define UNIPHIER_SBC_BASE_BE BIT(0) /* bank_enable */
26 #define UNIPHIER_SBC_CTRL0 0x200 /* timing parameter 0 of bank0 */
27 #define UNIPHIER_SBC_CTRL1 0x204 /* timing parameter 1 of bank0 */
28 #define UNIPHIER_SBC_CTRL2 0x208 /* timing parameter 2 of bank0 */
29 #define UNIPHIER_SBC_CTRL3 0x20c /* timing parameter 3 of bank0 */
30 #define UNIPHIER_SBC_CTRL4 0x300 /* timing parameter 4 of bank0 */
32 #define UNIPHIER_SBC_STRIDE 0x10 /* register stride to next bank */
33 #define UNIPHIER_SBC_NR_BANKS 8 /* number of banks (chip select) */
34 #define UNIPHIER_SBC_BASE_DUMMY 0xffffffff /* data to squash bank 0, 1 */
36 struct uniphier_system_bus_bank
{
41 struct uniphier_system_bus_priv
{
43 void __iomem
*membase
;
44 struct uniphier_system_bus_bank bank
[UNIPHIER_SBC_NR_BANKS
];
47 static int uniphier_system_bus_add_bank(struct uniphier_system_bus_priv
*priv
,
48 int bank
, u32 addr
, u64 paddr
, u32 size
)
53 "range found: bank = %d, addr = %08x, paddr = %08llx, size = %08x\n",
54 bank
, addr
, paddr
, size
);
56 if (bank
>= ARRAY_SIZE(priv
->bank
)) {
57 dev_err(priv
->dev
, "unsupported bank number %d\n", bank
);
61 if (priv
->bank
[bank
].base
|| priv
->bank
[bank
].end
) {
63 "range for bank %d has already been specified\n", bank
);
67 if (paddr
> U32_MAX
) {
68 dev_err(priv
->dev
, "base address %llx is too high\n", paddr
);
76 "base %08x cannot be mapped to %08llx of parent\n",
82 paddr
= round_down(paddr
, 0x00020000);
83 end
= round_up(end
, 0x00020000);
86 dev_err(priv
->dev
, "end address %08llx is too high\n", end
);
89 mask
= paddr
^ (end
- 1);
90 mask
= roundup_pow_of_two(mask
);
92 paddr
= round_down(paddr
, mask
);
93 end
= round_up(end
, mask
);
95 priv
->bank
[bank
].base
= paddr
;
96 priv
->bank
[bank
].end
= end
;
98 dev_dbg(priv
->dev
, "range added: bank = %d, addr = %08x, end = %08x\n",
99 bank
, priv
->bank
[bank
].base
, priv
->bank
[bank
].end
);
104 static int uniphier_system_bus_check_overlap(
105 const struct uniphier_system_bus_priv
*priv
)
109 for (i
= 0; i
< ARRAY_SIZE(priv
->bank
); i
++) {
110 for (j
= i
+ 1; j
< ARRAY_SIZE(priv
->bank
); j
++) {
111 if (priv
->bank
[i
].end
> priv
->bank
[j
].base
&&
112 priv
->bank
[i
].base
< priv
->bank
[j
].end
) {
114 "region overlap between bank%d and bank%d\n",
124 static void uniphier_system_bus_check_boot_swap(
125 struct uniphier_system_bus_priv
*priv
)
127 void __iomem
*base_reg
= priv
->membase
+ UNIPHIER_SBC_BASE
;
130 is_swapped
= !(readl(base_reg
) & UNIPHIER_SBC_BASE_BE
);
132 dev_dbg(priv
->dev
, "Boot Swap: %s\n", is_swapped
? "on" : "off");
135 * If BOOT_SWAP was asserted on power-on-reset, the CS0 and CS1 are
136 * swapped. In this case, bank0 and bank1 should be swapped as well.
139 swap(priv
->bank
[0], priv
->bank
[1]);
142 static void uniphier_system_bus_set_reg(
143 const struct uniphier_system_bus_priv
*priv
)
145 void __iomem
*base_reg
= priv
->membase
+ UNIPHIER_SBC_BASE
;
146 u32 base
, end
, mask
, val
;
149 for (i
= 0; i
< ARRAY_SIZE(priv
->bank
); i
++) {
150 base
= priv
->bank
[i
].base
;
151 end
= priv
->bank
[i
].end
;
155 * If SBC_BASE0 or SBC_BASE1 is set to zero, the access
156 * to anywhere in the system bus space is routed to
157 * bank 0 (if boot swap if off) or bank 1 (if boot swap
158 * if on). It means that CPUs cannot get access to
159 * bank 2 or later. In other words, bank 0/1 cannot
160 * be disabled even if its bank_enable bits is cleared.
161 * This seems odd, but it is how this hardware goes.
162 * As a workaround, dummy data (0xffffffff) should be
163 * set when the bank 0/1 is unused. As for bank 2 and
164 * later, they can be simply disable by clearing the
168 val
= UNIPHIER_SBC_BASE_DUMMY
;
172 mask
= base
^ (end
- 1);
174 val
= base
& 0xfffe0000;
175 val
|= (~mask
>> 16) & 0xfffe;
176 val
|= UNIPHIER_SBC_BASE_BE
;
178 dev_dbg(priv
->dev
, "SBC_BASE[%d] = 0x%08x\n", i
, val
);
180 writel(val
, base_reg
+ UNIPHIER_SBC_STRIDE
* i
);
184 static int uniphier_system_bus_probe(struct platform_device
*pdev
)
186 struct device
*dev
= &pdev
->dev
;
187 struct uniphier_system_bus_priv
*priv
;
188 struct resource
*regs
;
189 const __be32
*ranges
;
190 u32 cells
, addr
, size
;
192 int pna
, bank
, rlen
, rone
, ret
;
194 priv
= devm_kzalloc(dev
, sizeof(*priv
), GFP_KERNEL
);
198 regs
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
199 priv
->membase
= devm_ioremap_resource(dev
, regs
);
200 if (IS_ERR(priv
->membase
))
201 return PTR_ERR(priv
->membase
);
205 pna
= of_n_addr_cells(dev
->of_node
);
207 ret
= of_property_read_u32(dev
->of_node
, "#address-cells", &cells
);
209 dev_err(dev
, "failed to get #address-cells\n");
213 dev_err(dev
, "#address-cells must be 2\n");
217 ret
= of_property_read_u32(dev
->of_node
, "#size-cells", &cells
);
219 dev_err(dev
, "failed to get #size-cells\n");
223 dev_err(dev
, "#size-cells must be 1\n");
227 ranges
= of_get_property(dev
->of_node
, "ranges", &rlen
);
229 dev_err(dev
, "failed to get ranges property\n");
233 rlen
/= sizeof(*ranges
);
236 for (; rlen
>= rone
; rlen
-= rone
) {
237 bank
= be32_to_cpup(ranges
++);
238 addr
= be32_to_cpup(ranges
++);
239 paddr
= of_translate_address(dev
->of_node
, ranges
);
240 if (paddr
== OF_BAD_ADDR
)
243 size
= be32_to_cpup(ranges
++);
245 ret
= uniphier_system_bus_add_bank(priv
, bank
, addr
,
251 ret
= uniphier_system_bus_check_overlap(priv
);
255 uniphier_system_bus_check_boot_swap(priv
);
257 uniphier_system_bus_set_reg(priv
);
259 /* Now, the bus is configured. Populate platform_devices below it */
260 return of_platform_default_populate(dev
->of_node
, NULL
, dev
);
263 static const struct of_device_id uniphier_system_bus_match
[] = {
264 { .compatible
= "socionext,uniphier-system-bus" },
267 MODULE_DEVICE_TABLE(of
, uniphier_system_bus_match
);
269 static struct platform_driver uniphier_system_bus_driver
= {
270 .probe
= uniphier_system_bus_probe
,
272 .name
= "uniphier-system-bus",
273 .of_match_table
= uniphier_system_bus_match
,
276 module_platform_driver(uniphier_system_bus_driver
);
278 MODULE_AUTHOR("Masahiro Yamada <yamada.masahiro@socionext.com>");
279 MODULE_DESCRIPTION("UniPhier System Bus driver");
280 MODULE_LICENSE("GPL");