xen: Port Xen grant table driver from mini-os
[platform/kernel/u-boot.git] / drivers / bus / uniphier-system-bus.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2
3 #include <linux/bitops.h>
4 #include <linux/errno.h>
5 #include <linux/io.h>
6 #include <linux/sizes.h>
7 #include <linux/types.h>
8 #include <dm.h>
9
10 /* System Bus Controller registers */
11 #define UNIPHIER_SBC_BASE       0x100   /* base address of bank0 space */
12 #define    UNIPHIER_SBC_BASE_BE         BIT(0)  /* bank_enable */
13 #define UNIPHIER_SBC_CTRL0      0x200   /* timing parameter 0 of bank0 */
14 #define UNIPHIER_SBC_CTRL1      0x204   /* timing parameter 1 of bank0 */
15 #define UNIPHIER_SBC_CTRL2      0x208   /* timing parameter 2 of bank0 */
16 #define UNIPHIER_SBC_CTRL3      0x20c   /* timing parameter 3 of bank0 */
17 #define UNIPHIER_SBC_CTRL4      0x300   /* timing parameter 4 of bank0 */
18
19 #define UNIPHIER_SBC_STRIDE     0x10    /* register stride to next bank */
20
21 #if 1
22 /* slower but LED works */
23 #define SBCTRL0_VALUE   0x55450000
24 #define SBCTRL1_VALUE   0x07168d00
25 #define SBCTRL2_VALUE   0x34000009
26 #define SBCTRL4_VALUE   0x02110110
27
28 #else
29 /* faster but LED does not work */
30 #define SBCTRL0_VALUE   0x55450000
31 #define SBCTRL1_VALUE   0x06057700
32 /* NOR flash needs more wait counts than SRAM */
33 #define SBCTRL2_VALUE   0x34000009
34 #define SBCTRL4_VALUE   0x02110210
35 #endif
36
37 void uniphier_system_bus_set_reg(void __iomem *membase)
38 {
39         void __iomem *bank0_base = membase;
40         void __iomem *bank1_base = membase + UNIPHIER_SBC_STRIDE;
41
42         /*
43          * Only CS1 is connected to support card.
44          * BKSZ[1:0] should be set to "01".
45          */
46         writel(SBCTRL0_VALUE, bank1_base + UNIPHIER_SBC_CTRL0);
47         writel(SBCTRL1_VALUE, bank1_base + UNIPHIER_SBC_CTRL1);
48         writel(SBCTRL2_VALUE, bank1_base + UNIPHIER_SBC_CTRL2);
49         writel(SBCTRL4_VALUE, bank1_base + UNIPHIER_SBC_CTRL4);
50
51         if (readl(bank1_base + UNIPHIER_SBC_BASE) & UNIPHIER_SBC_BASE_BE) {
52                 /*
53                  * Boot Swap On: boot from external NOR/SRAM
54                  * 0x42000000-0x43ffffff is a mirror of 0x40000000-0x41ffffff.
55                  *
56                  * 0x40000000-0x41efffff, 0x42000000-0x43efffff: memory bank
57                  * 0x41f00000-0x41ffffff, 0x43f00000-0x43ffffff: peripherals
58                  */
59                 writel(0x0000bc01, bank0_base + UNIPHIER_SBC_BASE);
60         } else {
61                 /*
62                  * Boot Swap Off: boot from mask ROM
63                  * 0x40000000-0x41ffffff: mask ROM
64                  * 0x42000000-0x43efffff: memory bank (31MB)
65                  * 0x43f00000-0x43ffffff: peripherals (1MB)
66                  */
67                 writel(0x0000be01, bank0_base + UNIPHIER_SBC_BASE); /* dummy */
68                 writel(0x0200be01, bank0_base + UNIPHIER_SBC_BASE);
69         }
70 }
71
72 static int uniphier_system_bus_probe(struct udevice *dev)
73 {
74         fdt_addr_t base;
75         void __iomem *membase;
76
77         base = dev_read_addr(dev);
78         if (base == FDT_ADDR_T_NONE)
79                 return -EINVAL;
80
81         membase = devm_ioremap(dev, base, SZ_1K);
82         if (!membase)
83                 return -ENOMEM;
84
85         uniphier_system_bus_set_reg(membase);
86
87         return 0;
88 }
89
90 static const struct udevice_id uniphier_system_bus_match[] = {
91         { .compatible = "socionext,uniphier-system-bus" },
92         { /* sentinel */ }
93 };
94
95 U_BOOT_DRIVER(uniphier_system_bus_driver) = {
96         .name   = "uniphier-system-bus",
97         .id     = UCLASS_SIMPLE_BUS,
98         .of_match = uniphier_system_bus_match,
99         .probe = uniphier_system_bus_probe,
100 };