1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
|
diff --git a/arch/arm/include/asm/mach/arch.h b/arch/arm/include/asm/mach/arch.h
index 441efc4..d91b168 100644
--- a/arch/arm/include/asm/mach/arch.h
+++ b/arch/arm/include/asm/mach/arch.h
@@ -35,7 +35,7 @@ struct machine_desc {
unsigned int nr_irqs; /* number of IRQs */
#ifdef CONFIG_ZONE_DMA
- unsigned long dma_zone_size; /* size of DMA-able area */
+ phys_addr_t dma_zone_size; /* size of DMA-able area */
#endif
unsigned int video_start; /* start of video RAM */
diff --git a/arch/arm/include/asm/outercache.h b/arch/arm/include/asm/outercache.h
index 12f71a1..f94784f 100644
--- a/arch/arm/include/asm/outercache.h
+++ b/arch/arm/include/asm/outercache.h
@@ -37,10 +37,10 @@ struct outer_cache_fns {
void (*resume)(void);
};
-#ifdef CONFIG_OUTER_CACHE
-
extern struct outer_cache_fns outer_cache;
+#ifdef CONFIG_OUTER_CACHE
+
static inline void outer_inv_range(phys_addr_t start, phys_addr_t end)
{
if (outer_cache.inv_range)
diff --git a/arch/arm/mach-highbank/Kconfig b/arch/arm/mach-highbank/Kconfig
index cd9fcb1..b9dd13a 100644
--- a/arch/arm/mach-highbank/Kconfig
+++ b/arch/arm/mach-highbank/Kconfig
@@ -1,9 +1,14 @@
config ARCH_HIGHBANK
bool "Calxeda ECX-1000/2000 (Highbank/Midway)" if ARCH_MULTI_V7
+ select ARCH_DMA_ADDR_T_64BIT if ARM_LPAE
select ARCH_HAS_CPUFREQ
+ select ARCH_HAS_HOLES_MEMORYMODEL
select ARCH_HAS_OPP
select ARCH_WANT_OPTIONAL_GPIOLIB
select ARM_AMBA
+ select ARM_ERRATA_764369
+ select ARM_ERRATA_775420
+ select ARM_ERRATA_798181
select ARM_GIC
select ARM_TIMER_SP804
select CACHE_L2X0
@@ -18,3 +23,4 @@ config ARCH_HIGHBANK
select PL320_MBOX
select SPARSE_IRQ
select USE_OF
+ select ZONE_DMA if ARM_LPAE
diff --git a/arch/arm/mach-highbank/highbank.c b/arch/arm/mach-highbank/highbank.c
index 8881579..8e63ccd 100644
--- a/arch/arm/mach-highbank/highbank.c
+++ b/arch/arm/mach-highbank/highbank.c
@@ -18,14 +18,11 @@
#include <linux/clocksource.h>
#include <linux/dma-mapping.h>
#include <linux/io.h>
-#include <linux/irq.h>
#include <linux/irqchip.h>
-#include <linux/irqdomain.h>
#include <linux/of.h>
#include <linux/of_irq.h>
#include <linux/of_platform.h>
#include <linux/of_address.h>
-#include <linux/smp.h>
#include <linux/amba/bus.h>
#include <linux/clk-provider.h>
@@ -35,7 +32,6 @@
#include <asm/hardware/cache-l2x0.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
-#include <asm/mach/time.h>
#include "core.h"
#include "sysregs.h"
@@ -65,13 +61,11 @@ void highbank_set_cpu_jump(int cpu, void *jump_addr)
HB_JUMP_TABLE_PHYS(cpu) + 15);
}
-#ifdef CONFIG_CACHE_L2X0
static void highbank_l2x0_disable(void)
{
/* Disable PL310 L2 Cache controller */
highbank_smc1(0x102, 0x0);
}
-#endif
static void __init highbank_init_irq(void)
{
@@ -80,12 +74,13 @@ static void __init highbank_init_irq(void)
if (of_find_compatible_node(NULL, NULL, "arm,cortex-a9"))
highbank_scu_map_io();
-#ifdef CONFIG_CACHE_L2X0
/* Enable PL310 L2 Cache controller */
- highbank_smc1(0x102, 0x1);
- l2x0_of_init(0, ~0UL);
- outer_cache.disable = highbank_l2x0_disable;
-#endif
+ if (IS_ENABLED(CONFIG_CACHE_L2X0) &&
+ of_find_compatible_node(NULL, NULL, "arm,pl310-cache")) {
+ highbank_smc1(0x102, 0x1);
+ l2x0_of_init(0, ~0UL);
+ outer_cache.disable = highbank_l2x0_disable;
+ }
}
static void __init highbank_timer_init(void)
@@ -176,6 +171,9 @@ static const char *highbank_match[] __initconst = {
};
DT_MACHINE_START(HIGHBANK, "Highbank")
+#if defined(CONFIG_ZONE_DMA) && defined(CONFIG_ARM_LPAE)
+ .dma_zone_size = (4ULL * SZ_1G),
+#endif
.smp = smp_ops(highbank_smp_ops),
.init_irq = highbank_init_irq,
.init_time = highbank_timer_init,
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 15225d8..c0bb66e 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -207,7 +207,7 @@ static void __init arm_bootmem_init(unsigned long start_pfn,
#ifdef CONFIG_ZONE_DMA
-unsigned long arm_dma_zone_size __read_mostly;
+phys_addr_t arm_dma_zone_size __read_mostly;
EXPORT_SYMBOL(arm_dma_zone_size);
/*
diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c
index 06fe45c..bff41d4 100644
--- a/drivers/dma/amba-pl08x.c
+++ b/drivers/dma/amba-pl08x.c
@@ -133,6 +133,8 @@ struct pl08x_bus_data {
u8 buswidth;
};
+#define IS_BUS_ALIGNED(bus) IS_ALIGNED((bus)->addr, (bus)->buswidth)
+
/**
* struct pl08x_phy_chan - holder for the physical channels
* @id: physical index to this channel
@@ -845,10 +847,13 @@ static int pl08x_fill_llis_for_desc(struct pl08x_driver_data *pl08x,
pl08x_choose_master_bus(&bd, &mbus, &sbus, cctl);
- dev_vdbg(&pl08x->adev->dev, "src=0x%08x%s/%u dst=0x%08x%s/%u len=%zu\n",
- bd.srcbus.addr, cctl & PL080_CONTROL_SRC_INCR ? "+" : "",
+ dev_vdbg(&pl08x->adev->dev,
+ "src=0x%08llx%s/%u dst=0x%08llx%s/%u len=%zu\n",
+ (u64)bd.srcbus.addr,
+ cctl & PL080_CONTROL_SRC_INCR ? "+" : "",
bd.srcbus.buswidth,
- bd.dstbus.addr, cctl & PL080_CONTROL_DST_INCR ? "+" : "",
+ (u64)bd.dstbus.addr,
+ cctl & PL080_CONTROL_DST_INCR ? "+" : "",
bd.dstbus.buswidth,
bd.remainder);
dev_vdbg(&pl08x->adev->dev, "mbus=%s sbus=%s\n",
@@ -886,8 +891,8 @@ static int pl08x_fill_llis_for_desc(struct pl08x_driver_data *pl08x,
return 0;
}
- if ((bd.srcbus.addr % bd.srcbus.buswidth) ||
- (bd.dstbus.addr % bd.dstbus.buswidth)) {
+ if (!IS_BUS_ALIGNED(&bd.srcbus) ||
+ !IS_BUS_ALIGNED(&bd.dstbus)) {
dev_err(&pl08x->adev->dev,
"%s src & dst address must be aligned to src"
" & dst width if peripheral is flow controller",
@@ -908,9 +913,9 @@ static int pl08x_fill_llis_for_desc(struct pl08x_driver_data *pl08x,
*/
if (bd.remainder < mbus->buswidth)
early_bytes = bd.remainder;
- else if ((mbus->addr) % (mbus->buswidth)) {
- early_bytes = mbus->buswidth - (mbus->addr) %
- (mbus->buswidth);
+ else if (!IS_BUS_ALIGNED(mbus)) {
+ early_bytes = mbus->buswidth -
+ (mbus->addr & (mbus->buswidth - 1));
if ((bd.remainder - early_bytes) < mbus->buswidth)
early_bytes = bd.remainder;
}
@@ -928,7 +933,7 @@ static int pl08x_fill_llis_for_desc(struct pl08x_driver_data *pl08x,
* Master now aligned
* - if slave is not then we must set its width down
*/
- if (sbus->addr % sbus->buswidth) {
+ if (!IS_BUS_ALIGNED(sbus)) {
dev_dbg(&pl08x->adev->dev,
"%s set down bus width to one byte\n",
__func__);
|