bmips: switch to linux 5.15
[openwrt/staging/dedeckeh.git] / target / linux / bmips / patches-5.10 / 201-mips-bmips-automatically-detect-RAM-size.patch
1 From f9ee3f28ecb979c77423be965ef9dd313bdb9e9b Mon Sep 17 00:00:00 2001
2 From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com>
3 Date: Mon, 8 Mar 2021 16:58:34 +0100
4 Subject: [PATCH 2/2] mips: bmips: automatically detect RAM size
5 MIME-Version: 1.0
6 Content-Type: text/plain; charset=UTF-8
7 Content-Transfer-Encoding: 8bit
8
9 Some devices have different amounts of RAM installed depending on HW revision.
10
11 Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
12 ---
13 arch/mips/bmips/setup.c | 118 ++++++++++++++++++++++++++++++++++++++++
14 1 file changed, 118 insertions(+)
15
16 --- a/arch/mips/bmips/setup.c
17 +++ b/arch/mips/bmips/setup.c
18 @@ -19,6 +19,7 @@
19 #include <linux/of_platform.h>
20 #include <linux/libfdt.h>
21 #include <linux/smp.h>
22 +#include <linux/types.h>
23 #include <asm/addrspace.h>
24 #include <asm/bmips.h>
25 #include <asm/bootinfo.h>
26 @@ -34,13 +35,16 @@
27 #define REG_BCM6318_SOB ((void __iomem *)CKSEG1ADDR(0x10000900))
28 #define BCM6318_FREQ_SHIFT 23
29 #define BCM6318_FREQ_MASK (0x3 << BCM6318_FREQ_SHIFT)
30 +#define BCM6318_SDRAM_ADDR ((void __iomem *)CKSEG1ADDR(0x10004000))
31
32 #define REG_BCM6328_OTP ((void __iomem *)CKSEG1ADDR(0x1000062c))
33 #define BCM6328_TP1_DISABLED BIT(9)
34 #define REG_BCM6328_MISC_SB ((void __iomem *)CKSEG1ADDR(0x10001a40))
35 #define BCM6328_FCVO_SHIFT 7
36 #define BCM6328_FCVO_MASK (0x1f << BCM6328_FCVO_SHIFT)
37 +#define BCM6328_MEMC_ADDR ((void __iomem *)CKSEG1ADDR(0x10003000))
38
39 +#define BCM6358_MEMC_ADDR ((void __iomem *)0xfffe1200)
40 #define REG_BCM6358_DDR_PLLC ((void __iomem *)0xfffe12b8)
41 #define BCM6358_PLLC_M1_SHIFT 0
42 #define BCM6358_PLLC_M1_MASK (0xff << BCM6358_PLLC_M1_SHIFT)
43 @@ -52,7 +56,9 @@
44 #define REG_BCM6362_MISC_SB ((void __iomem *)CKSEG1ADDR(0x10001814))
45 #define BCM6362_FCVO_SHIFT 1
46 #define BCM6362_FCVO_MASK (0x1f << BCM6362_FCVO_SHIFT)
47 +#define BCM6362_MEMC_ADDR ((void __iomem *)CKSEG1ADDR(0x10003000))
48
49 +#define BCM6368_MEMC_ADDR ((void __iomem *)CKSEG1ADDR(0x10001200))
50 #define REG_BCM6368_DDR_PLLC ((void __iomem *)CKSEG1ADDR(0x100012a0))
51 #define BCM6368_PLLC_P1_SHIFT 0
52 #define BCM6368_PLLC_P1_MASK (0xf << BCM6368_PLLC_P1_SHIFT)
53 @@ -67,7 +73,21 @@
54 #define REG_BCM63268_MISC_SB ((void __iomem *)CKSEG1ADDR(0x10001814))
55 #define BCM63268_FCVO_SHIFT 21
56 #define BCM63268_FCVO_MASK (0xf << BCM63268_FCVO_SHIFT)
57 +#define BCM63268_MEMC_ADDR ((void __iomem *)CKSEG1ADDR(0x10003000))
58
59 +#define SDRAM_CFG_REG 0x0
60 +#define SDRAM_SPACE_SHIFT 4
61 +#define SDRAM_SPACE_MASK (0xf << SDRAM_SPACE_SHIFT)
62 +
63 +#define MEMC_CFG_REG 0x4
64 +#define MEMC_CFG_32B_SHIFT 1
65 +#define MEMC_CFG_32B_MASK (1 << MEMC_CFG_32B_SHIFT)
66 +#define MEMC_CFG_COL_SHIFT 3
67 +#define MEMC_CFG_COL_MASK (0x3 << MEMC_CFG_COL_SHIFT)
68 +#define MEMC_CFG_ROW_SHIFT 6
69 +#define MEMC_CFG_ROW_MASK (0x3 << MEMC_CFG_ROW_SHIFT)
70 +
71 +#define DDR_CSEND_REG 0x8
72
73 static const unsigned long kbase = VMLINUX_LOAD_ADDRESS & 0xfff00000;
74
75 @@ -76,6 +96,11 @@ struct bmips_cpufreq {
76 u32 (*cpu_freq)(void);
77 };
78
79 +struct bmips_memsize {
80 + const char *compatible;
81 + phys_addr_t (*mem_size)(void);
82 +};
83 +
84 struct bmips_quirk {
85 const char *compatible;
86 void (*quirk_fn)(void);
87 @@ -337,9 +362,90 @@ void __init plat_time_init(void)
88 mips_hpt_frequency = freq;
89 }
90
91 +static inline phys_addr_t bmips_dram_size(unsigned int cols,
92 + unsigned int rows,
93 + unsigned int is_32b,
94 + unsigned int banks)
95 +{
96 + rows += 11; /* 0 => 11 address bits ... 2 => 13 address bits */
97 + cols += 8; /* 0 => 8 address bits ... 2 => 10 address bits */
98 + is_32b += 1;
99 +
100 + return 1 << (cols + rows + is_32b + banks);
101 +}
102 +
103 +static phys_addr_t _bcm6318_memsize(void __iomem *addr)
104 +{
105 + u32 val;
106 +
107 + val = __raw_readl(addr + SDRAM_CFG_REG);
108 + val = (val & SDRAM_SPACE_MASK) >> SDRAM_SPACE_SHIFT;
109 +
110 + return (1 << (val + 20));
111 +}
112 +
113 +static phys_addr_t _bcm6328_memsize(void __iomem *addr)
114 +{
115 + return __raw_readl(addr + DDR_CSEND_REG) << 24;
116 +}
117 +
118 +static phys_addr_t _bcm6358_memsize(void __iomem *addr)
119 +{
120 + unsigned int cols, rows, is_32b;
121 + u32 val;
122 +
123 + val = __raw_readl(addr + MEMC_CFG_REG);
124 + rows = (val & MEMC_CFG_ROW_MASK) >> MEMC_CFG_ROW_SHIFT;
125 + cols = (val & MEMC_CFG_COL_MASK) >> MEMC_CFG_COL_SHIFT;
126 + is_32b = (val & MEMC_CFG_32B_MASK) ? 0 : 1;
127 +
128 + return bmips_dram_size(cols, rows, is_32b, 2);
129 +}
130 +
131 +static phys_addr_t bcm6318_memsize(void)
132 +{
133 + return _bcm6318_memsize(BCM6318_SDRAM_ADDR);
134 +}
135 +
136 +static phys_addr_t bcm6328_memsize(void)
137 +{
138 + return _bcm6328_memsize(BCM6328_MEMC_ADDR);
139 +}
140 +
141 +static phys_addr_t bcm6358_memsize(void)
142 +{
143 + return _bcm6358_memsize(BCM6358_MEMC_ADDR);
144 +}
145 +
146 +static phys_addr_t bcm6362_memsize(void)
147 +{
148 + return _bcm6328_memsize(BCM6362_MEMC_ADDR);
149 +}
150 +
151 +static phys_addr_t bcm6368_memsize(void)
152 +{
153 + return _bcm6358_memsize(BCM6368_MEMC_ADDR);
154 +}
155 +
156 +static phys_addr_t bcm63268_memsize(void)
157 +{
158 + return _bcm6328_memsize(BCM63268_MEMC_ADDR);
159 +}
160 +
161 +static const struct bmips_memsize bmips_memsize_list[] = {
162 + { "brcm,bcm6318", &bcm6318_memsize },
163 + { "brcm,bcm6328", &bcm6328_memsize },
164 + { "brcm,bcm6358", &bcm6358_memsize },
165 + { "brcm,bcm6362", &bcm6362_memsize },
166 + { "brcm,bcm6368", &bcm6368_memsize },
167 + { "brcm,bcm63268", &bcm63268_memsize },
168 + { /* sentinel */ }
169 +};
170 +
171 void __init plat_mem_setup(void)
172 {
173 void *dtb;
174 + const struct bmips_memsize *ms;
175 const struct bmips_quirk *q;
176
177 set_io_port_base(0);
178 @@ -358,6 +464,18 @@ void __init plat_mem_setup(void)
179
180 __dt_setup_arch(dtb);
181
182 + for (ms = bmips_memsize_list; ms->mem_size; ms++) {
183 + if (of_flat_dt_is_compatible(of_get_flat_dt_root(),
184 + ms->compatible)) {
185 + phys_addr_t mem = ms->mem_size();
186 + if (mem) {
187 + memblock_add(0, mem);
188 + printk("%uMB of RAM installed\n", mem >> 20);
189 + break;
190 + }
191 + }
192 + }
193 +
194 for (q = bmips_quirk_list; q->quirk_fn; q++) {
195 if (of_flat_dt_is_compatible(of_get_flat_dt_root(),
196 q->compatible)) {