Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/arm/mv/mv_common.c
39507 views
1
/*-
2
* SPDX-License-Identifier: BSD-3-Clause
3
*
4
* Copyright (C) 2008-2011 MARVELL INTERNATIONAL LTD.
5
* All rights reserved.
6
*
7
* Developed by Semihalf.
8
*
9
* Redistribution and use in source and binary forms, with or without
10
* modification, are permitted provided that the following conditions
11
* are met:
12
* 1. Redistributions of source code must retain the above copyright
13
* notice, this list of conditions and the following disclaimer.
14
* 2. Redistributions in binary form must reproduce the above copyright
15
* notice, this list of conditions and the following disclaimer in the
16
* documentation and/or other materials provided with the distribution.
17
* 3. Neither the name of MARVELL nor the names of contributors
18
* may be used to endorse or promote products derived from this software
19
* without specific prior written permission.
20
*
21
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
22
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
25
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31
* SUCH DAMAGE.
32
*/
33
34
#include <sys/param.h>
35
#include <sys/systm.h>
36
#include <sys/bus.h>
37
#include <sys/kernel.h>
38
#include <sys/malloc.h>
39
#include <sys/kdb.h>
40
#include <sys/reboot.h>
41
42
#include <dev/fdt/fdt_common.h>
43
#include <dev/ofw/openfirm.h>
44
#include <dev/ofw/ofw_bus_subr.h>
45
46
#include <machine/bus.h>
47
#include <machine/fdt.h>
48
#include <machine/vmparam.h>
49
#include <machine/intr.h>
50
51
#include <arm/mv/mvreg.h>
52
#include <arm/mv/mvvar.h>
53
#include <arm/mv/mvwin.h>
54
55
MALLOC_DEFINE(M_IDMA, "idma", "idma dma test memory");
56
57
#define IDMA_DEBUG
58
#undef IDMA_DEBUG
59
60
#define MAX_CPU_WIN 5
61
62
#ifdef DEBUG
63
#define debugf(fmt, args...) do { printf("%s(): ", __func__); \
64
printf(fmt,##args); } while (0)
65
#else
66
#define debugf(fmt, args...)
67
#endif
68
69
#ifdef DEBUG
70
#define MV_DUMP_WIN 1
71
#else
72
#define MV_DUMP_WIN 0
73
#endif
74
75
struct soc_node_spec;
76
77
static enum soc_family soc_family;
78
79
static int mv_win_cesa_attr_armada38x(int eng_sel);
80
static int mv_win_cesa_attr_armadaxp(int eng_sel);
81
82
uint32_t read_cpu_ctrl_armv7(uint32_t reg);
83
84
void write_cpu_ctrl_armv7(uint32_t reg, uint32_t val);
85
86
static int win_eth_can_remap(int i);
87
88
static int decode_win_cesa_valid(void);
89
static int decode_win_usb_valid(void);
90
static int decode_win_usb3_valid(void);
91
static int decode_win_eth_valid(void);
92
static int decode_win_pcie_valid(void);
93
static int decode_win_sata_valid(void);
94
static int decode_win_sdhci_valid(void);
95
96
static void decode_win_cpu_setup(void);
97
static int decode_win_sdram_fixup(void);
98
static void decode_win_cesa_setup(u_long);
99
static void decode_win_a38x_cesa_setup(u_long);
100
static void decode_win_usb_setup(u_long);
101
static void decode_win_usb3_setup(u_long);
102
static void decode_win_eth_setup(u_long);
103
static void decode_win_neta_setup(u_long);
104
static void decode_win_sata_setup(u_long);
105
static void decode_win_ahci_setup(u_long);
106
static void decode_win_sdhci_setup(u_long);
107
108
static void decode_win_cesa_dump(u_long);
109
static void decode_win_a38x_cesa_dump(u_long);
110
static void decode_win_usb_dump(u_long);
111
static void decode_win_usb3_dump(u_long);
112
static void decode_win_eth_dump(u_long base);
113
static void decode_win_neta_dump(u_long base);
114
static void decode_win_ahci_dump(u_long base);
115
static void decode_win_sdhci_dump(u_long);
116
static void decode_win_pcie_dump(u_long);
117
118
static uint32_t win_cpu_cr_read(int);
119
static uint32_t win_cpu_armv7_cr_read(int);
120
static uint32_t win_cpu_br_read(int);
121
static uint32_t win_cpu_armv7_br_read(int);
122
static uint32_t win_cpu_remap_l_read(int);
123
static uint32_t win_cpu_armv7_remap_l_read(int);
124
static uint32_t win_cpu_remap_h_read(int);
125
static uint32_t win_cpu_armv7_remap_h_read(int);
126
127
static void win_cpu_cr_write(int, uint32_t);
128
static void win_cpu_armv7_cr_write(int, uint32_t);
129
static void win_cpu_br_write(int, uint32_t);
130
static void win_cpu_armv7_br_write(int, uint32_t);
131
static void win_cpu_remap_l_write(int, uint32_t);
132
static void win_cpu_armv7_remap_l_write(int, uint32_t);
133
static void win_cpu_remap_h_write(int, uint32_t);
134
static void win_cpu_armv7_remap_h_write(int, uint32_t);
135
136
static uint32_t ddr_br_read(int);
137
static uint32_t ddr_sz_read(int);
138
static uint32_t ddr_armv7_br_read(int);
139
static uint32_t ddr_armv7_sz_read(int);
140
static void ddr_br_write(int, uint32_t);
141
static void ddr_sz_write(int, uint32_t);
142
static void ddr_armv7_br_write(int, uint32_t);
143
static void ddr_armv7_sz_write(int, uint32_t);
144
145
static int fdt_get_ranges(const char *, void *, int, int *, int *);
146
int gic_decode_fdt(phandle_t iparent, pcell_t *intr, int *interrupt,
147
int *trig, int *pol);
148
149
static int win_cpu_from_dt(void);
150
static int fdt_win_setup(void);
151
152
static int fdt_win_process_child(phandle_t, struct soc_node_spec *, const char*);
153
154
static void soc_identify(uint32_t, uint32_t);
155
156
static uint32_t dev_mask = 0;
157
static int cpu_wins_no = 0;
158
static int eth_port = 0;
159
static int usb_port = 0;
160
static boolean_t platform_io_coherent = false;
161
162
static struct decode_win cpu_win_tbl[MAX_CPU_WIN];
163
164
const struct decode_win *cpu_wins = cpu_win_tbl;
165
166
typedef void (*decode_win_setup_t)(u_long);
167
typedef void (*dump_win_t)(u_long);
168
typedef int (*valid_t)(void);
169
170
struct soc_node_spec {
171
const char *compat;
172
decode_win_setup_t decode_handler;
173
dump_win_t dump_handler;
174
valid_t valid_handler;
175
};
176
177
static struct soc_node_spec soc_nodes[] = {
178
{ "mrvl,ge", &decode_win_eth_setup, &decode_win_eth_dump, &decode_win_eth_valid},
179
{ "marvell,armada-370-neta", &decode_win_neta_setup,
180
&decode_win_neta_dump, NULL },
181
{ "mrvl,usb-ehci", &decode_win_usb_setup, &decode_win_usb_dump, &decode_win_usb_valid},
182
{ "marvell,orion-ehci", &decode_win_usb_setup, &decode_win_usb_dump, &decode_win_usb_valid },
183
{ "marvell,armada-380-xhci", &decode_win_usb3_setup,
184
&decode_win_usb3_dump, &decode_win_usb3_valid },
185
{ "marvell,armada-380-ahci", &decode_win_ahci_setup,
186
&decode_win_ahci_dump, NULL },
187
{ "marvell,armada-380-sdhci", &decode_win_sdhci_setup,
188
&decode_win_sdhci_dump, &decode_win_sdhci_valid},
189
{ "mrvl,sata", &decode_win_sata_setup, NULL, &decode_win_sata_valid},
190
{ "mrvl,pcie", &decode_win_pcie_setup, &decode_win_pcie_dump, &decode_win_pcie_valid},
191
{ "marvell,armada-38x-crypto", &decode_win_a38x_cesa_setup,
192
&decode_win_a38x_cesa_dump, &decode_win_cesa_valid},
193
{ NULL, NULL, NULL, NULL },
194
};
195
196
#define SOC_NODE_PCIE_ENTRY_IDX 11
197
198
typedef uint32_t(*read_cpu_ctrl_t)(uint32_t);
199
typedef void(*write_cpu_ctrl_t)(uint32_t, uint32_t);
200
typedef uint32_t (*win_read_t)(int);
201
typedef void (*win_write_t)(int, uint32_t);
202
typedef int (*win_cesa_attr_t)(int);
203
typedef uint32_t (*get_t)(void);
204
205
struct decode_win_spec {
206
read_cpu_ctrl_t read_cpu_ctrl;
207
write_cpu_ctrl_t write_cpu_ctrl;
208
win_read_t cr_read;
209
win_read_t br_read;
210
win_read_t remap_l_read;
211
win_read_t remap_h_read;
212
win_write_t cr_write;
213
win_write_t br_write;
214
win_write_t remap_l_write;
215
win_write_t remap_h_write;
216
uint32_t mv_win_cpu_max;
217
win_cesa_attr_t win_cesa_attr;
218
int win_cesa_target;
219
win_read_t ddr_br_read;
220
win_read_t ddr_sz_read;
221
win_write_t ddr_br_write;
222
win_write_t ddr_sz_write;
223
get_t get_tclk;
224
get_t get_cpu_freq;
225
};
226
227
struct decode_win_spec *soc_decode_win_spec;
228
229
static struct decode_win_spec decode_win_specs[] =
230
{
231
{
232
&read_cpu_ctrl_armv7,
233
&write_cpu_ctrl_armv7,
234
&win_cpu_armv7_cr_read,
235
&win_cpu_armv7_br_read,
236
&win_cpu_armv7_remap_l_read,
237
&win_cpu_armv7_remap_h_read,
238
&win_cpu_armv7_cr_write,
239
&win_cpu_armv7_br_write,
240
&win_cpu_armv7_remap_l_write,
241
&win_cpu_armv7_remap_h_write,
242
MV_WIN_CPU_MAX_ARMV7,
243
&mv_win_cesa_attr_armada38x,
244
MV_WIN_CESA_TARGET_ARMADA38X,
245
&ddr_armv7_br_read,
246
&ddr_armv7_sz_read,
247
&ddr_armv7_br_write,
248
&ddr_armv7_sz_write,
249
&get_tclk_armada38x,
250
&get_cpu_freq_armada38x,
251
},
252
{
253
&read_cpu_ctrl_armv7,
254
&write_cpu_ctrl_armv7,
255
&win_cpu_armv7_cr_read,
256
&win_cpu_armv7_br_read,
257
&win_cpu_armv7_remap_l_read,
258
&win_cpu_armv7_remap_h_read,
259
&win_cpu_armv7_cr_write,
260
&win_cpu_armv7_br_write,
261
&win_cpu_armv7_remap_l_write,
262
&win_cpu_armv7_remap_h_write,
263
MV_WIN_CPU_MAX_ARMV7,
264
&mv_win_cesa_attr_armadaxp,
265
MV_WIN_CESA_TARGET_ARMADAXP,
266
&ddr_armv7_br_read,
267
&ddr_armv7_sz_read,
268
&ddr_armv7_br_write,
269
&ddr_armv7_sz_write,
270
&get_tclk_armadaxp,
271
&get_cpu_freq_armadaxp,
272
},
273
};
274
275
struct fdt_pm_mask_entry {
276
char *compat;
277
uint32_t mask;
278
};
279
280
static struct fdt_pm_mask_entry fdt_pm_mask_table[] = {
281
{ "mrvl,ge", CPU_PM_CTRL_GE(0) },
282
{ "mrvl,ge", CPU_PM_CTRL_GE(1) },
283
{ "mrvl,usb-ehci", CPU_PM_CTRL_USB(0) },
284
{ "mrvl,usb-ehci", CPU_PM_CTRL_USB(1) },
285
{ "mrvl,usb-ehci", CPU_PM_CTRL_USB(2) },
286
{ "mrvl,xor", CPU_PM_CTRL_XOR },
287
{ "mrvl,sata", CPU_PM_CTRL_SATA },
288
{ NULL, 0 }
289
};
290
291
/*
292
* Disable device using power management register.
293
* 1 - Device Power On
294
* 0 - Device Power Off
295
* Mask can be set in loader.
296
* EXAMPLE:
297
* loader> set hw.pm-disable-mask=0x2
298
*
299
* Common mask:
300
* |-------------------------------|
301
* | Device | Kirkwood | Discovery |
302
* |-------------------------------|
303
* | USB0 | 0x00008 | 0x020000 |
304
* |-------------------------------|
305
* | USB1 | - | 0x040000 |
306
* |-------------------------------|
307
* | USB2 | - | 0x080000 |
308
* |-------------------------------|
309
* | GE0 | 0x00001 | 0x000002 |
310
* |-------------------------------|
311
* | GE1 | - | 0x000004 |
312
* |-------------------------------|
313
* | IDMA | - | 0x100000 |
314
* |-------------------------------|
315
* | XOR | 0x10000 | 0x200000 |
316
* |-------------------------------|
317
* | CESA | 0x20000 | 0x400000 |
318
* |-------------------------------|
319
* | SATA | 0x04000 | 0x004000 |
320
* --------------------------------|
321
* This feature can be used only on Kirkwood and Discovery
322
* machines.
323
*/
324
325
static int mv_win_cesa_attr_armada38x(int eng_sel)
326
{
327
328
return MV_WIN_CESA_ATTR_ARMADA38X(eng_sel);
329
}
330
331
static int mv_win_cesa_attr_armadaxp(int eng_sel)
332
{
333
334
return MV_WIN_CESA_ATTR_ARMADAXP(eng_sel);
335
}
336
337
enum soc_family
338
mv_check_soc_family(void)
339
{
340
uint32_t dev, rev;
341
342
soc_id(&dev, &rev);
343
switch (dev) {
344
case MV_DEV_MV78230:
345
case MV_DEV_MV78260:
346
case MV_DEV_MV78460:
347
soc_decode_win_spec = &decode_win_specs[MV_SOC_ARMADA_XP];
348
soc_family = MV_SOC_ARMADA_XP;
349
break;
350
case MV_DEV_88F6828:
351
case MV_DEV_88F6820:
352
case MV_DEV_88F6810:
353
soc_decode_win_spec = &decode_win_specs[MV_SOC_ARMADA_38X];
354
soc_family = MV_SOC_ARMADA_38X;
355
break;
356
default:
357
soc_family = MV_SOC_UNSUPPORTED;
358
return (MV_SOC_UNSUPPORTED);
359
}
360
361
soc_identify(dev, rev);
362
363
return (soc_family);
364
}
365
366
static __inline void
367
pm_disable_device(int mask)
368
{
369
#ifdef DIAGNOSTIC
370
uint32_t reg;
371
372
reg = CPU_PM_CTRL_ALL;
373
reg &= ~mask;
374
soc_power_ctrl_set(reg);
375
printf("Device %x is disabled\n", mask);
376
#endif
377
}
378
379
int
380
mv_fdt_is_type(phandle_t node, const char *typestr)
381
{
382
#define FDT_TYPE_LEN 64
383
char type[FDT_TYPE_LEN];
384
385
if (OF_getproplen(node, "device_type") <= 0)
386
return (0);
387
388
if (OF_getprop(node, "device_type", type, FDT_TYPE_LEN) < 0)
389
return (0);
390
391
if (strncasecmp(type, typestr, FDT_TYPE_LEN) == 0)
392
/* This fits. */
393
return (1);
394
395
return (0);
396
#undef FDT_TYPE_LEN
397
}
398
399
int
400
mv_fdt_pm(phandle_t node)
401
{
402
uint32_t cpu_pm_ctrl;
403
int i, ena, compat;
404
405
ena = 1;
406
cpu_pm_ctrl = read_cpu_ctrl(CPU_PM_CTRL);
407
for (i = 0; fdt_pm_mask_table[i].compat != NULL; i++) {
408
if (dev_mask & (1 << i))
409
continue;
410
411
compat = ofw_bus_node_is_compatible(node,
412
fdt_pm_mask_table[i].compat);
413
if (compat && (~cpu_pm_ctrl & fdt_pm_mask_table[i].mask)) {
414
dev_mask |= (1 << i);
415
ena = 0;
416
break;
417
} else if (compat) {
418
dev_mask |= (1 << i);
419
break;
420
}
421
}
422
423
return (ena);
424
}
425
426
uint32_t
427
read_cpu_ctrl(uint32_t reg)
428
{
429
430
if (soc_decode_win_spec->read_cpu_ctrl != NULL)
431
return (soc_decode_win_spec->read_cpu_ctrl(reg));
432
return (-1);
433
}
434
435
uint32_t
436
read_cpu_ctrl_armv7(uint32_t reg)
437
{
438
439
return (bus_space_read_4(fdtbus_bs_tag, MV_CPU_CONTROL_BASE_ARMV7, reg));
440
}
441
442
void
443
write_cpu_ctrl(uint32_t reg, uint32_t val)
444
{
445
446
if (soc_decode_win_spec->write_cpu_ctrl != NULL)
447
soc_decode_win_spec->write_cpu_ctrl(reg, val);
448
}
449
450
void
451
write_cpu_ctrl_armv7(uint32_t reg, uint32_t val)
452
{
453
454
bus_space_write_4(fdtbus_bs_tag, MV_CPU_CONTROL_BASE_ARMV7, reg, val);
455
}
456
457
uint32_t
458
read_cpu_mp_clocks(uint32_t reg)
459
{
460
461
return (bus_space_read_4(fdtbus_bs_tag, MV_MP_CLOCKS_BASE, reg));
462
}
463
464
void
465
write_cpu_mp_clocks(uint32_t reg, uint32_t val)
466
{
467
468
bus_space_write_4(fdtbus_bs_tag, MV_MP_CLOCKS_BASE, reg, val);
469
}
470
471
uint32_t
472
read_cpu_misc(uint32_t reg)
473
{
474
475
return (bus_space_read_4(fdtbus_bs_tag, MV_MISC_BASE, reg));
476
}
477
478
void
479
write_cpu_misc(uint32_t reg, uint32_t val)
480
{
481
482
bus_space_write_4(fdtbus_bs_tag, MV_MISC_BASE, reg, val);
483
}
484
485
/*
486
* Set the power status of device. This feature was only supported on
487
* Kirkwood and Discovery SoCs.
488
*/
489
void
490
soc_power_ctrl_set(uint32_t mask)
491
{
492
493
if (mask != CPU_PM_CTRL_NONE)
494
write_cpu_ctrl(CPU_PM_CTRL, mask);
495
}
496
497
void
498
soc_id(uint32_t *dev, uint32_t *rev)
499
{
500
uint64_t mv_pcie_base = MV_PCIE_BASE;
501
phandle_t node;
502
503
/*
504
* Notice: system identifiers are available in the registers range of
505
* PCIE controller, so using this function is only allowed (and
506
* possible) after the internal registers range has been mapped in via
507
* devmap_bootstrap().
508
*/
509
*dev = 0;
510
*rev = 0;
511
if ((node = OF_finddevice("/")) == -1)
512
return;
513
if (ofw_bus_node_is_compatible(node, "marvell,armada380"))
514
mv_pcie_base = MV_PCIE_BASE_ARMADA38X;
515
516
*dev = bus_space_read_4(fdtbus_bs_tag, mv_pcie_base, 0) >> 16;
517
*rev = bus_space_read_4(fdtbus_bs_tag, mv_pcie_base, 8) & 0xff;
518
}
519
520
static void
521
soc_identify(uint32_t d, uint32_t r)
522
{
523
uint32_t mode, freq;
524
const char *dev;
525
const char *rev;
526
527
printf("SOC: ");
528
if (bootverbose)
529
printf("(0x%4x:0x%02x) ", d, r);
530
531
rev = "";
532
switch (d) {
533
case MV_DEV_88F6828:
534
dev = "Marvell 88F6828";
535
break;
536
case MV_DEV_88F6820:
537
dev = "Marvell 88F6820";
538
break;
539
case MV_DEV_88F6810:
540
dev = "Marvell 88F6810";
541
break;
542
case MV_DEV_MV78260:
543
dev = "Marvell MV78260";
544
break;
545
case MV_DEV_MV78460:
546
dev = "Marvell MV78460";
547
break;
548
default:
549
dev = "UNKNOWN";
550
break;
551
}
552
553
printf("%s", dev);
554
if (*rev != '\0')
555
printf(" rev %s", rev);
556
printf(", TClock %dMHz", get_tclk() / 1000 / 1000);
557
freq = get_cpu_freq();
558
if (freq != 0)
559
printf(", Frequency %dMHz", freq / 1000 / 1000);
560
printf("\n");
561
562
mode = read_cpu_ctrl(CPU_CONFIG);
563
printf(" Instruction cache prefetch %s, data cache prefetch %s\n",
564
(mode & CPU_CONFIG_IC_PREF) ? "enabled" : "disabled",
565
(mode & CPU_CONFIG_DC_PREF) ? "enabled" : "disabled");
566
}
567
568
#ifdef KDB
569
static void
570
mv_enter_debugger(void *dummy)
571
{
572
573
if (boothowto & RB_KDB)
574
kdb_enter(KDB_WHY_BOOTFLAGS, "Boot flags requested debugger");
575
}
576
SYSINIT(mv_enter_debugger, SI_SUB_CPU, SI_ORDER_ANY, mv_enter_debugger, NULL);
577
#endif
578
579
int
580
soc_decode_win(void)
581
{
582
int mask, err;
583
584
mask = 0;
585
TUNABLE_INT_FETCH("hw.pm-disable-mask", &mask);
586
587
if (mask != 0)
588
pm_disable_device(mask);
589
590
/* Retrieve data about physical addresses from device tree. */
591
if ((err = win_cpu_from_dt()) != 0)
592
return (err);
593
594
if (soc_family == MV_SOC_ARMADA_XP)
595
if ((err = decode_win_sdram_fixup()) != 0)
596
return(err);
597
598
decode_win_cpu_setup();
599
if (MV_DUMP_WIN)
600
soc_dump_decode_win();
601
602
eth_port = 0;
603
usb_port = 0;
604
if ((err = fdt_win_setup()) != 0)
605
return (err);
606
607
return (0);
608
}
609
610
/**************************************************************************
611
* Decode windows registers accessors
612
**************************************************************************/
613
614
WIN_REG_IDX_RD(win_cpu_armv7, cr, MV_WIN_CPU_CTRL_ARMV7, MV_MBUS_BRIDGE_BASE)
615
WIN_REG_IDX_RD(win_cpu_armv7, br, MV_WIN_CPU_BASE_ARMV7, MV_MBUS_BRIDGE_BASE)
616
WIN_REG_IDX_RD(win_cpu_armv7, remap_l, MV_WIN_CPU_REMAP_LO_ARMV7, MV_MBUS_BRIDGE_BASE)
617
WIN_REG_IDX_RD(win_cpu_armv7, remap_h, MV_WIN_CPU_REMAP_HI_ARMV7, MV_MBUS_BRIDGE_BASE)
618
WIN_REG_IDX_WR(win_cpu_armv7, cr, MV_WIN_CPU_CTRL_ARMV7, MV_MBUS_BRIDGE_BASE)
619
WIN_REG_IDX_WR(win_cpu_armv7, br, MV_WIN_CPU_BASE_ARMV7, MV_MBUS_BRIDGE_BASE)
620
WIN_REG_IDX_WR(win_cpu_armv7, remap_l, MV_WIN_CPU_REMAP_LO_ARMV7, MV_MBUS_BRIDGE_BASE)
621
WIN_REG_IDX_WR(win_cpu_armv7, remap_h, MV_WIN_CPU_REMAP_HI_ARMV7, MV_MBUS_BRIDGE_BASE)
622
623
static uint32_t
624
win_cpu_cr_read(int i)
625
{
626
627
if (soc_decode_win_spec->cr_read != NULL)
628
return (soc_decode_win_spec->cr_read(i));
629
return (-1);
630
}
631
632
static uint32_t
633
win_cpu_br_read(int i)
634
{
635
636
if (soc_decode_win_spec->br_read != NULL)
637
return (soc_decode_win_spec->br_read(i));
638
return (-1);
639
}
640
641
static uint32_t
642
win_cpu_remap_l_read(int i)
643
{
644
645
if (soc_decode_win_spec->remap_l_read != NULL)
646
return (soc_decode_win_spec->remap_l_read(i));
647
return (-1);
648
}
649
650
static uint32_t
651
win_cpu_remap_h_read(int i)
652
{
653
654
if (soc_decode_win_spec->remap_h_read != NULL)
655
return soc_decode_win_spec->remap_h_read(i);
656
return (-1);
657
}
658
659
static void
660
win_cpu_cr_write(int i, uint32_t val)
661
{
662
663
if (soc_decode_win_spec->cr_write != NULL)
664
soc_decode_win_spec->cr_write(i, val);
665
}
666
667
static void
668
win_cpu_br_write(int i, uint32_t val)
669
{
670
671
if (soc_decode_win_spec->br_write != NULL)
672
soc_decode_win_spec->br_write(i, val);
673
}
674
675
static void
676
win_cpu_remap_l_write(int i, uint32_t val)
677
{
678
679
if (soc_decode_win_spec->remap_l_write != NULL)
680
soc_decode_win_spec->remap_l_write(i, val);
681
}
682
683
static void
684
win_cpu_remap_h_write(int i, uint32_t val)
685
{
686
687
if (soc_decode_win_spec->remap_h_write != NULL)
688
soc_decode_win_spec->remap_h_write(i, val);
689
}
690
691
WIN_REG_BASE_IDX_RD(win_cesa, cr, MV_WIN_CESA_CTRL)
692
WIN_REG_BASE_IDX_RD(win_cesa, br, MV_WIN_CESA_BASE)
693
WIN_REG_BASE_IDX_WR(win_cesa, cr, MV_WIN_CESA_CTRL)
694
WIN_REG_BASE_IDX_WR(win_cesa, br, MV_WIN_CESA_BASE)
695
696
WIN_REG_BASE_IDX_RD(win_usb, cr, MV_WIN_USB_CTRL)
697
WIN_REG_BASE_IDX_RD(win_usb, br, MV_WIN_USB_BASE)
698
WIN_REG_BASE_IDX_WR(win_usb, cr, MV_WIN_USB_CTRL)
699
WIN_REG_BASE_IDX_WR(win_usb, br, MV_WIN_USB_BASE)
700
701
WIN_REG_BASE_IDX_RD(win_usb3, cr, MV_WIN_USB3_CTRL)
702
WIN_REG_BASE_IDX_RD(win_usb3, br, MV_WIN_USB3_BASE)
703
WIN_REG_BASE_IDX_WR(win_usb3, cr, MV_WIN_USB3_CTRL)
704
WIN_REG_BASE_IDX_WR(win_usb3, br, MV_WIN_USB3_BASE)
705
706
WIN_REG_BASE_IDX_RD(win_eth, br, MV_WIN_ETH_BASE)
707
WIN_REG_BASE_IDX_RD(win_eth, sz, MV_WIN_ETH_SIZE)
708
WIN_REG_BASE_IDX_RD(win_eth, har, MV_WIN_ETH_REMAP)
709
WIN_REG_BASE_IDX_WR(win_eth, br, MV_WIN_ETH_BASE)
710
WIN_REG_BASE_IDX_WR(win_eth, sz, MV_WIN_ETH_SIZE)
711
WIN_REG_BASE_IDX_WR(win_eth, har, MV_WIN_ETH_REMAP)
712
713
WIN_REG_BASE_RD(win_eth, bare, 0x290)
714
WIN_REG_BASE_RD(win_eth, epap, 0x294)
715
WIN_REG_BASE_WR(win_eth, bare, 0x290)
716
WIN_REG_BASE_WR(win_eth, epap, 0x294)
717
718
WIN_REG_BASE_IDX_RD(win_pcie, cr, MV_WIN_PCIE_CTRL);
719
WIN_REG_BASE_IDX_RD(win_pcie, br, MV_WIN_PCIE_BASE);
720
WIN_REG_BASE_IDX_RD(win_pcie, remap, MV_WIN_PCIE_REMAP);
721
WIN_REG_BASE_IDX_WR(win_pcie, cr, MV_WIN_PCIE_CTRL);
722
WIN_REG_BASE_IDX_WR(win_pcie, br, MV_WIN_PCIE_BASE);
723
WIN_REG_BASE_IDX_WR(win_pcie, remap, MV_WIN_PCIE_REMAP);
724
WIN_REG_BASE_IDX_RD(pcie_bar, br, MV_PCIE_BAR_BASE);
725
WIN_REG_BASE_IDX_RD(pcie_bar, brh, MV_PCIE_BAR_BASE_H);
726
WIN_REG_BASE_IDX_RD(pcie_bar, cr, MV_PCIE_BAR_CTRL);
727
WIN_REG_BASE_IDX_WR(pcie_bar, br, MV_PCIE_BAR_BASE);
728
WIN_REG_BASE_IDX_WR(pcie_bar, brh, MV_PCIE_BAR_BASE_H);
729
WIN_REG_BASE_IDX_WR(pcie_bar, cr, MV_PCIE_BAR_CTRL);
730
731
WIN_REG_BASE_IDX_RD(win_sata, cr, MV_WIN_SATA_CTRL);
732
WIN_REG_BASE_IDX_RD(win_sata, br, MV_WIN_SATA_BASE);
733
WIN_REG_BASE_IDX_WR(win_sata, cr, MV_WIN_SATA_CTRL);
734
WIN_REG_BASE_IDX_WR(win_sata, br, MV_WIN_SATA_BASE);
735
736
WIN_REG_BASE_IDX_RD(win_sata_armada38x, sz, MV_WIN_SATA_SIZE_ARMADA38X);
737
WIN_REG_BASE_IDX_WR(win_sata_armada38x, sz, MV_WIN_SATA_SIZE_ARMADA38X);
738
WIN_REG_BASE_IDX_RD(win_sata_armada38x, cr, MV_WIN_SATA_CTRL_ARMADA38X);
739
WIN_REG_BASE_IDX_WR(win_sata_armada38x, cr, MV_WIN_SATA_CTRL_ARMADA38X);
740
WIN_REG_BASE_IDX_WR(win_sata_armada38x, br, MV_WIN_SATA_BASE_ARMADA38X);
741
742
WIN_REG_BASE_IDX_RD(win_sdhci, cr, MV_WIN_SDHCI_CTRL);
743
WIN_REG_BASE_IDX_RD(win_sdhci, br, MV_WIN_SDHCI_BASE);
744
WIN_REG_BASE_IDX_WR(win_sdhci, cr, MV_WIN_SDHCI_CTRL);
745
WIN_REG_BASE_IDX_WR(win_sdhci, br, MV_WIN_SDHCI_BASE);
746
747
#ifndef SOC_MV_DOVE
748
WIN_REG_IDX_RD(ddr_armv7, br, MV_WIN_DDR_BASE, MV_DDR_CADR_BASE_ARMV7)
749
WIN_REG_IDX_RD(ddr_armv7, sz, MV_WIN_DDR_SIZE, MV_DDR_CADR_BASE_ARMV7)
750
WIN_REG_IDX_WR(ddr_armv7, br, MV_WIN_DDR_BASE, MV_DDR_CADR_BASE_ARMV7)
751
WIN_REG_IDX_WR(ddr_armv7, sz, MV_WIN_DDR_SIZE, MV_DDR_CADR_BASE_ARMV7)
752
753
static inline uint32_t
754
ddr_br_read(int i)
755
{
756
757
if (soc_decode_win_spec->ddr_br_read != NULL)
758
return (soc_decode_win_spec->ddr_br_read(i));
759
return (-1);
760
}
761
762
static inline uint32_t
763
ddr_sz_read(int i)
764
{
765
766
if (soc_decode_win_spec->ddr_sz_read != NULL)
767
return (soc_decode_win_spec->ddr_sz_read(i));
768
return (-1);
769
}
770
771
static inline void
772
ddr_br_write(int i, uint32_t val)
773
{
774
775
if (soc_decode_win_spec->ddr_br_write != NULL)
776
soc_decode_win_spec->ddr_br_write(i, val);
777
}
778
779
static inline void
780
ddr_sz_write(int i, uint32_t val)
781
{
782
783
if (soc_decode_win_spec->ddr_sz_write != NULL)
784
soc_decode_win_spec->ddr_sz_write(i, val);
785
}
786
#else
787
/*
788
* On 88F6781 (Dove) SoC DDR Controller is accessed through
789
* single MBUS <-> AXI bridge. In this case we provide emulated
790
* ddr_br_read() and ddr_sz_read() functions to keep compatibility
791
* with common decoding windows setup code.
792
*/
793
794
static inline uint32_t ddr_br_read(int i)
795
{
796
uint32_t mmap;
797
798
/* Read Memory Address Map Register for CS i */
799
mmap = bus_space_read_4(fdtbus_bs_tag, MV_DDR_CADR_BASE + (i * 0x10), 0);
800
801
/* Return CS i base address */
802
return (mmap & 0xFF000000);
803
}
804
805
static inline uint32_t ddr_sz_read(int i)
806
{
807
uint32_t mmap, size;
808
809
/* Read Memory Address Map Register for CS i */
810
mmap = bus_space_read_4(fdtbus_bs_tag, MV_DDR_CADR_BASE + (i * 0x10), 0);
811
812
/* Extract size of CS space in 64kB units */
813
size = (1 << ((mmap >> 16) & 0x0F));
814
815
/* Return CS size and enable/disable status */
816
return (((size - 1) << 16) | (mmap & 0x01));
817
}
818
#endif
819
820
/**************************************************************************
821
* Decode windows helper routines
822
**************************************************************************/
823
void
824
soc_dump_decode_win(void)
825
{
826
int i;
827
828
for (i = 0; i < soc_decode_win_spec->mv_win_cpu_max; i++) {
829
printf("CPU window#%d: c 0x%08x, b 0x%08x", i,
830
win_cpu_cr_read(i),
831
win_cpu_br_read(i));
832
833
if (win_cpu_can_remap(i))
834
printf(", rl 0x%08x, rh 0x%08x",
835
win_cpu_remap_l_read(i),
836
win_cpu_remap_h_read(i));
837
838
printf("\n");
839
}
840
printf("Internal regs base: 0x%08x\n",
841
bus_space_read_4(fdtbus_bs_tag, MV_INTREGS_BASE, 0));
842
843
for (i = 0; i < MV_WIN_DDR_MAX; i++)
844
printf("DDR CS#%d: b 0x%08x, s 0x%08x\n", i,
845
ddr_br_read(i), ddr_sz_read(i));
846
}
847
848
/**************************************************************************
849
* CPU windows routines
850
**************************************************************************/
851
int
852
win_cpu_can_remap(int i)
853
{
854
uint32_t dev, rev;
855
856
soc_id(&dev, &rev);
857
858
/* Depending on the SoC certain windows have remap capability */
859
if ((dev == MV_DEV_88F6828 && i < 20) ||
860
(dev == MV_DEV_88F6820 && i < 20) ||
861
(dev == MV_DEV_88F6810 && i < 20))
862
return (1);
863
864
return (0);
865
}
866
867
/* XXX This should check for overlapping remap fields too.. */
868
int
869
decode_win_overlap(int win, int win_no, const struct decode_win *wintab)
870
{
871
const struct decode_win *tab;
872
int i;
873
874
tab = wintab;
875
876
for (i = 0; i < win_no; i++, tab++) {
877
if (i == win)
878
/* Skip self */
879
continue;
880
881
if ((tab->base + tab->size - 1) < (wintab + win)->base)
882
continue;
883
884
else if (((wintab + win)->base + (wintab + win)->size - 1) <
885
tab->base)
886
continue;
887
else
888
return (i);
889
}
890
891
return (-1);
892
}
893
894
int
895
decode_win_cpu_set(int target, int attr, vm_paddr_t base, uint32_t size,
896
vm_paddr_t remap)
897
{
898
uint32_t br, cr;
899
int win, i;
900
901
if (remap == ~0) {
902
win = soc_decode_win_spec->mv_win_cpu_max - 1;
903
i = -1;
904
} else {
905
win = 0;
906
i = 1;
907
}
908
909
while ((win >= 0) && (win < soc_decode_win_spec->mv_win_cpu_max)) {
910
cr = win_cpu_cr_read(win);
911
if ((cr & MV_WIN_CPU_ENABLE_BIT) == 0)
912
break;
913
if ((cr & ((0xff << MV_WIN_CPU_ATTR_SHIFT) |
914
(0x1f << MV_WIN_CPU_TARGET_SHIFT))) ==
915
((attr << MV_WIN_CPU_ATTR_SHIFT) |
916
(target << MV_WIN_CPU_TARGET_SHIFT)))
917
break;
918
win += i;
919
}
920
if ((win < 0) || (win >= soc_decode_win_spec->mv_win_cpu_max) ||
921
((remap != ~0) && (win_cpu_can_remap(win) == 0)))
922
return (-1);
923
924
br = base & 0xffff0000;
925
win_cpu_br_write(win, br);
926
927
if (win_cpu_can_remap(win)) {
928
if (remap != ~0) {
929
win_cpu_remap_l_write(win, remap & 0xffff0000);
930
win_cpu_remap_h_write(win, 0);
931
} else {
932
/*
933
* Remap function is not used for a given window
934
* (capable of remapping) - set remap field with the
935
* same value as base.
936
*/
937
win_cpu_remap_l_write(win, base & 0xffff0000);
938
win_cpu_remap_h_write(win, 0);
939
}
940
}
941
942
cr = ((size - 1) & 0xffff0000) | (attr << MV_WIN_CPU_ATTR_SHIFT) |
943
(target << MV_WIN_CPU_TARGET_SHIFT) | MV_WIN_CPU_ENABLE_BIT;
944
win_cpu_cr_write(win, cr);
945
946
return (0);
947
}
948
949
static void
950
decode_win_cpu_setup(void)
951
{
952
int i;
953
954
/* Disable all CPU windows */
955
for (i = 0; i < soc_decode_win_spec->mv_win_cpu_max; i++) {
956
win_cpu_cr_write(i, 0);
957
win_cpu_br_write(i, 0);
958
if (win_cpu_can_remap(i)) {
959
win_cpu_remap_l_write(i, 0);
960
win_cpu_remap_h_write(i, 0);
961
}
962
}
963
964
for (i = 0; i < cpu_wins_no; i++)
965
if (cpu_wins[i].target > 0)
966
decode_win_cpu_set(cpu_wins[i].target,
967
cpu_wins[i].attr, cpu_wins[i].base,
968
cpu_wins[i].size, cpu_wins[i].remap);
969
970
}
971
972
struct ddr_data {
973
uint8_t window_valid[MV_WIN_DDR_MAX];
974
uint32_t mr_count;
975
uint32_t valid_win_num;
976
};
977
978
static void
979
ddr_valid_cb(const struct mem_region *mr, void *arg)
980
{
981
struct ddr_data *data = arg;
982
int j;
983
984
for (j = 0; j < MV_WIN_DDR_MAX; j++) {
985
if (ddr_is_active(j) &&
986
(ddr_base(j) == mr->mr_start) &&
987
(ddr_size(j) == mr->mr_size)) {
988
data->window_valid[j] = 1;
989
data->valid_win_num++;
990
}
991
}
992
data->mr_count++;
993
}
994
995
static int
996
decode_win_sdram_fixup(void)
997
{
998
struct ddr_data window_data;
999
int err, j;
1000
1001
memset(&window_data, 0, sizeof(window_data));
1002
err = fdt_foreach_mem_region(ddr_valid_cb, &window_data);
1003
if (err != 0)
1004
return (err);
1005
1006
if (window_data.mr_count != window_data.valid_win_num)
1007
return (EINVAL);
1008
1009
/* Destroy windows without corresponding device tree entry */
1010
for (j = 0; j < MV_WIN_DDR_MAX; j++) {
1011
if (ddr_is_active(j) && (window_data.window_valid[j] != 1)) {
1012
printf("Disabling SDRAM decoding window: %d\n", j);
1013
ddr_disable(j);
1014
}
1015
}
1016
1017
return (0);
1018
}
1019
/*
1020
* Check if we're able to cover all active DDR banks.
1021
*/
1022
static int
1023
decode_win_can_cover_ddr(int max)
1024
{
1025
int i, c;
1026
1027
c = 0;
1028
for (i = 0; i < MV_WIN_DDR_MAX; i++)
1029
if (ddr_is_active(i))
1030
c++;
1031
1032
if (c > max) {
1033
printf("Unable to cover all active DDR banks: "
1034
"%d, available windows: %d\n", c, max);
1035
return (0);
1036
}
1037
1038
return (1);
1039
}
1040
1041
/**************************************************************************
1042
* DDR windows routines
1043
**************************************************************************/
1044
int
1045
ddr_is_active(int i)
1046
{
1047
1048
if (ddr_sz_read(i) & 0x1)
1049
return (1);
1050
1051
return (0);
1052
}
1053
1054
void
1055
ddr_disable(int i)
1056
{
1057
1058
ddr_sz_write(i, 0);
1059
ddr_br_write(i, 0);
1060
}
1061
1062
uint32_t
1063
ddr_base(int i)
1064
{
1065
1066
return (ddr_br_read(i) & 0xff000000);
1067
}
1068
1069
uint32_t
1070
ddr_size(int i)
1071
{
1072
1073
return ((ddr_sz_read(i) | 0x00ffffff) + 1);
1074
}
1075
1076
uint32_t
1077
ddr_attr(int i)
1078
{
1079
uint32_t attr;
1080
1081
attr = (i == 0 ? 0xe :
1082
(i == 1 ? 0xd :
1083
(i == 2 ? 0xb :
1084
(i == 3 ? 0x7 : 0xff))));
1085
if (platform_io_coherent)
1086
attr |= 0x10;
1087
1088
return (attr);
1089
}
1090
1091
/**************************************************************************
1092
* CESA windows routines
1093
**************************************************************************/
1094
static int
1095
decode_win_cesa_valid(void)
1096
{
1097
1098
return (decode_win_can_cover_ddr(MV_WIN_CESA_MAX));
1099
}
1100
1101
static void
1102
decode_win_cesa_dump(u_long base)
1103
{
1104
int i;
1105
1106
for (i = 0; i < MV_WIN_CESA_MAX; i++)
1107
printf("CESA window#%d: c 0x%08x, b 0x%08x\n", i,
1108
win_cesa_cr_read(base, i), win_cesa_br_read(base, i));
1109
}
1110
1111
/*
1112
* Set CESA decode windows.
1113
*/
1114
static void
1115
decode_win_cesa_setup(u_long base)
1116
{
1117
uint32_t br, cr;
1118
uint64_t size;
1119
int i, j;
1120
1121
for (i = 0; i < MV_WIN_CESA_MAX; i++) {
1122
win_cesa_cr_write(base, i, 0);
1123
win_cesa_br_write(base, i, 0);
1124
}
1125
1126
/* Only access to active DRAM banks is required */
1127
for (i = 0; i < MV_WIN_DDR_MAX; i++) {
1128
if (ddr_is_active(i)) {
1129
br = ddr_base(i);
1130
1131
size = ddr_size(i);
1132
/*
1133
* Armada 38x SoC's equipped with 4GB DRAM
1134
* suffer freeze during CESA operation, if
1135
* MBUS window opened at given DRAM CS reaches
1136
* end of the address space. Apply a workaround
1137
* by setting the window size to the closest possible
1138
* value, i.e. divide it by 2.
1139
*/
1140
if ((soc_family == MV_SOC_ARMADA_38X) &&
1141
(size + ddr_base(i) == 0x100000000ULL))
1142
size /= 2;
1143
1144
cr = (((size - 1) & 0xffff0000) |
1145
(ddr_attr(i) << IO_WIN_ATTR_SHIFT) |
1146
IO_WIN_ENA_MASK);
1147
1148
/* Set the first free CESA window */
1149
for (j = 0; j < MV_WIN_CESA_MAX; j++) {
1150
if (win_cesa_cr_read(base, j) & 0x1)
1151
continue;
1152
1153
win_cesa_br_write(base, j, br);
1154
win_cesa_cr_write(base, j, cr);
1155
break;
1156
}
1157
}
1158
}
1159
}
1160
1161
static void
1162
decode_win_a38x_cesa_setup(u_long base)
1163
{
1164
decode_win_cesa_setup(base);
1165
decode_win_cesa_setup(base + MV_WIN_CESA_OFFSET);
1166
}
1167
1168
static void
1169
decode_win_a38x_cesa_dump(u_long base)
1170
{
1171
decode_win_cesa_dump(base);
1172
decode_win_cesa_dump(base + MV_WIN_CESA_OFFSET);
1173
}
1174
1175
/**************************************************************************
1176
* USB windows routines
1177
**************************************************************************/
1178
static int
1179
decode_win_usb_valid(void)
1180
{
1181
1182
return (decode_win_can_cover_ddr(MV_WIN_USB_MAX));
1183
}
1184
1185
static void
1186
decode_win_usb_dump(u_long base)
1187
{
1188
int i;
1189
1190
for (i = 0; i < MV_WIN_USB_MAX; i++)
1191
printf("USB window#%d: c 0x%08x, b 0x%08x\n", i,
1192
win_usb_cr_read(base, i), win_usb_br_read(base, i));
1193
}
1194
1195
/*
1196
* Set USB decode windows.
1197
*/
1198
static void
1199
decode_win_usb_setup(u_long base)
1200
{
1201
uint32_t br, cr;
1202
int i, j;
1203
1204
usb_port++;
1205
1206
for (i = 0; i < MV_WIN_USB_MAX; i++) {
1207
win_usb_cr_write(base, i, 0);
1208
win_usb_br_write(base, i, 0);
1209
}
1210
1211
/* Only access to active DRAM banks is required */
1212
for (i = 0; i < MV_WIN_DDR_MAX; i++) {
1213
if (ddr_is_active(i)) {
1214
br = ddr_base(i);
1215
/*
1216
* XXX for 6281 we should handle Mbus write
1217
* burst limit field in the ctrl reg
1218
*/
1219
cr = (((ddr_size(i) - 1) & 0xffff0000) |
1220
(ddr_attr(i) << 8) | 1);
1221
1222
/* Set the first free USB window */
1223
for (j = 0; j < MV_WIN_USB_MAX; j++) {
1224
if (win_usb_cr_read(base, j) & 0x1)
1225
continue;
1226
1227
win_usb_br_write(base, j, br);
1228
win_usb_cr_write(base, j, cr);
1229
break;
1230
}
1231
}
1232
}
1233
}
1234
1235
/**************************************************************************
1236
* USB3 windows routines
1237
**************************************************************************/
1238
static int
1239
decode_win_usb3_valid(void)
1240
{
1241
1242
return (decode_win_can_cover_ddr(MV_WIN_USB3_MAX));
1243
}
1244
1245
static void
1246
decode_win_usb3_dump(u_long base)
1247
{
1248
int i;
1249
1250
for (i = 0; i < MV_WIN_USB3_MAX; i++)
1251
printf("USB3.0 window#%d: c 0x%08x, b 0x%08x\n", i,
1252
win_usb3_cr_read(base, i), win_usb3_br_read(base, i));
1253
}
1254
1255
/*
1256
* Set USB3 decode windows
1257
*/
1258
static void
1259
decode_win_usb3_setup(u_long base)
1260
{
1261
uint32_t br, cr;
1262
int i, j;
1263
1264
for (i = 0; i < MV_WIN_USB3_MAX; i++) {
1265
win_usb3_cr_write(base, i, 0);
1266
win_usb3_br_write(base, i, 0);
1267
}
1268
1269
/* Only access to active DRAM banks is required */
1270
for (i = 0; i < MV_WIN_DDR_MAX; i++) {
1271
if (ddr_is_active(i)) {
1272
br = ddr_base(i);
1273
cr = (((ddr_size(i) - 1) &
1274
(IO_WIN_SIZE_MASK << IO_WIN_SIZE_SHIFT)) |
1275
(ddr_attr(i) << IO_WIN_ATTR_SHIFT) |
1276
IO_WIN_ENA_MASK);
1277
1278
/* Set the first free USB3.0 window */
1279
for (j = 0; j < MV_WIN_USB3_MAX; j++) {
1280
if (win_usb3_cr_read(base, j) & IO_WIN_ENA_MASK)
1281
continue;
1282
1283
win_usb3_br_write(base, j, br);
1284
win_usb3_cr_write(base, j, cr);
1285
break;
1286
}
1287
}
1288
}
1289
}
1290
1291
/**************************************************************************
1292
* ETH windows routines
1293
**************************************************************************/
1294
1295
static int
1296
win_eth_can_remap(int i)
1297
{
1298
1299
/* ETH encode windows 0-3 have remap capability */
1300
if (i < 4)
1301
return (1);
1302
1303
return (0);
1304
}
1305
1306
static int
1307
eth_bare_read(uint32_t base, int i)
1308
{
1309
uint32_t v;
1310
1311
v = win_eth_bare_read(base);
1312
v &= (1 << i);
1313
1314
return (v >> i);
1315
}
1316
1317
static void
1318
eth_bare_write(uint32_t base, int i, int val)
1319
{
1320
uint32_t v;
1321
1322
v = win_eth_bare_read(base);
1323
v &= ~(1 << i);
1324
v |= (val << i);
1325
win_eth_bare_write(base, v);
1326
}
1327
1328
static void
1329
eth_epap_write(uint32_t base, int i, int val)
1330
{
1331
uint32_t v;
1332
1333
v = win_eth_epap_read(base);
1334
v &= ~(0x3 << (i * 2));
1335
v |= (val << (i * 2));
1336
win_eth_epap_write(base, v);
1337
}
1338
1339
static void
1340
decode_win_eth_dump(u_long base)
1341
{
1342
int i;
1343
1344
for (i = 0; i < MV_WIN_ETH_MAX; i++) {
1345
printf("ETH window#%d: b 0x%08x, s 0x%08x", i,
1346
win_eth_br_read(base, i),
1347
win_eth_sz_read(base, i));
1348
1349
if (win_eth_can_remap(i))
1350
printf(", ha 0x%08x",
1351
win_eth_har_read(base, i));
1352
1353
printf("\n");
1354
}
1355
printf("ETH windows: bare 0x%08x, epap 0x%08x\n",
1356
win_eth_bare_read(base),
1357
win_eth_epap_read(base));
1358
}
1359
1360
static void
1361
decode_win_eth_setup(u_long base)
1362
{
1363
uint32_t br, sz;
1364
int i, j;
1365
1366
eth_port++;
1367
1368
/* Disable, clear and revoke protection for all ETH windows */
1369
for (i = 0; i < MV_WIN_ETH_MAX; i++) {
1370
eth_bare_write(base, i, 1);
1371
eth_epap_write(base, i, 0);
1372
win_eth_br_write(base, i, 0);
1373
win_eth_sz_write(base, i, 0);
1374
if (win_eth_can_remap(i))
1375
win_eth_har_write(base, i, 0);
1376
}
1377
1378
/* Only access to active DRAM banks is required */
1379
for (i = 0; i < MV_WIN_DDR_MAX; i++)
1380
if (ddr_is_active(i)) {
1381
br = ddr_base(i) | (ddr_attr(i) << 8);
1382
sz = ((ddr_size(i) - 1) & 0xffff0000);
1383
1384
/* Set the first free ETH window */
1385
for (j = 0; j < MV_WIN_ETH_MAX; j++) {
1386
if (eth_bare_read(base, j) == 0)
1387
continue;
1388
1389
win_eth_br_write(base, j, br);
1390
win_eth_sz_write(base, j, sz);
1391
1392
/* XXX remapping ETH windows not supported */
1393
1394
/* Set protection RW */
1395
eth_epap_write(base, j, 0x3);
1396
1397
/* Enable window */
1398
eth_bare_write(base, j, 0);
1399
break;
1400
}
1401
}
1402
}
1403
1404
static void
1405
decode_win_neta_dump(u_long base)
1406
{
1407
1408
decode_win_eth_dump(base + MV_WIN_NETA_OFFSET);
1409
}
1410
1411
static void
1412
decode_win_neta_setup(u_long base)
1413
{
1414
1415
decode_win_eth_setup(base + MV_WIN_NETA_OFFSET);
1416
}
1417
1418
static int
1419
decode_win_eth_valid(void)
1420
{
1421
1422
return (decode_win_can_cover_ddr(MV_WIN_ETH_MAX));
1423
}
1424
1425
/**************************************************************************
1426
* PCIE windows routines
1427
**************************************************************************/
1428
static void
1429
decode_win_pcie_dump(u_long base)
1430
{
1431
int i;
1432
1433
printf("PCIE windows base 0x%08lx\n", base);
1434
for (i = 0; i < MV_WIN_PCIE_MAX; i++)
1435
printf("PCIE window#%d: cr 0x%08x br 0x%08x remap 0x%08x\n",
1436
i, win_pcie_cr_read(base, i),
1437
win_pcie_br_read(base, i), win_pcie_remap_read(base, i));
1438
1439
for (i = 0; i < MV_PCIE_BAR_MAX; i++)
1440
printf("PCIE bar#%d: cr 0x%08x br 0x%08x brh 0x%08x\n",
1441
i, pcie_bar_cr_read(base, i),
1442
pcie_bar_br_read(base, i), pcie_bar_brh_read(base, i));
1443
}
1444
1445
void
1446
decode_win_pcie_setup(u_long base)
1447
{
1448
uint32_t size = 0, ddrbase = ~0;
1449
uint32_t cr, br;
1450
int i, j;
1451
1452
for (i = 0; i < MV_PCIE_BAR_MAX; i++) {
1453
pcie_bar_br_write(base, i,
1454
MV_PCIE_BAR_64BIT | MV_PCIE_BAR_PREFETCH_EN);
1455
if (i < 3)
1456
pcie_bar_brh_write(base, i, 0);
1457
if (i > 0)
1458
pcie_bar_cr_write(base, i, 0);
1459
}
1460
1461
for (i = 0; i < MV_WIN_PCIE_MAX; i++) {
1462
win_pcie_cr_write(base, i, 0);
1463
win_pcie_br_write(base, i, 0);
1464
win_pcie_remap_write(base, i, 0);
1465
}
1466
1467
/* On End-Point only set BAR size to 1MB regardless of DDR size */
1468
if ((bus_space_read_4(fdtbus_bs_tag, base, MV_PCIE_CONTROL)
1469
& MV_PCIE_ROOT_CMPLX) == 0) {
1470
pcie_bar_cr_write(base, 1, 0xf0000 | 1);
1471
return;
1472
}
1473
1474
for (i = 0; i < MV_WIN_DDR_MAX; i++) {
1475
if (ddr_is_active(i)) {
1476
/* Map DDR to BAR 1 */
1477
cr = (ddr_size(i) - 1) & 0xffff0000;
1478
size += ddr_size(i) & 0xffff0000;
1479
cr |= (ddr_attr(i) << 8) | 1;
1480
br = ddr_base(i);
1481
if (br < ddrbase)
1482
ddrbase = br;
1483
1484
/* Use the first available PCIE window */
1485
for (j = 0; j < MV_WIN_PCIE_MAX; j++) {
1486
if (win_pcie_cr_read(base, j) != 0)
1487
continue;
1488
1489
win_pcie_br_write(base, j, br);
1490
win_pcie_cr_write(base, j, cr);
1491
break;
1492
}
1493
}
1494
}
1495
1496
/*
1497
* Upper 16 bits in BAR register is interpreted as BAR size
1498
* (in 64 kB units) plus 64kB, so subtract 0x10000
1499
* form value passed to register to get correct value.
1500
*/
1501
size -= 0x10000;
1502
pcie_bar_cr_write(base, 1, size | 1);
1503
pcie_bar_br_write(base, 1, ddrbase |
1504
MV_PCIE_BAR_64BIT | MV_PCIE_BAR_PREFETCH_EN);
1505
pcie_bar_br_write(base, 0, fdt_immr_pa |
1506
MV_PCIE_BAR_64BIT | MV_PCIE_BAR_PREFETCH_EN);
1507
}
1508
1509
static int
1510
decode_win_pcie_valid(void)
1511
{
1512
1513
return (decode_win_can_cover_ddr(MV_WIN_PCIE_MAX));
1514
}
1515
1516
/**************************************************************************
1517
* SATA windows routines
1518
**************************************************************************/
1519
static void
1520
decode_win_sata_setup(u_long base)
1521
{
1522
uint32_t cr, br;
1523
int i, j;
1524
1525
for (i = 0; i < MV_WIN_SATA_MAX; i++) {
1526
win_sata_cr_write(base, i, 0);
1527
win_sata_br_write(base, i, 0);
1528
}
1529
1530
for (i = 0; i < MV_WIN_DDR_MAX; i++)
1531
if (ddr_is_active(i)) {
1532
cr = ((ddr_size(i) - 1) & 0xffff0000) |
1533
(ddr_attr(i) << 8) | 1;
1534
br = ddr_base(i);
1535
1536
/* Use the first available SATA window */
1537
for (j = 0; j < MV_WIN_SATA_MAX; j++) {
1538
if ((win_sata_cr_read(base, j) & 1) != 0)
1539
continue;
1540
1541
win_sata_br_write(base, j, br);
1542
win_sata_cr_write(base, j, cr);
1543
break;
1544
}
1545
}
1546
}
1547
1548
/*
1549
* Configure AHCI decoding windows
1550
*/
1551
static void
1552
decode_win_ahci_setup(u_long base)
1553
{
1554
uint32_t br, cr, sz;
1555
int i, j;
1556
1557
for (i = 0; i < MV_WIN_SATA_MAX_ARMADA38X; i++) {
1558
win_sata_armada38x_cr_write(base, i, 0);
1559
win_sata_armada38x_br_write(base, i, 0);
1560
win_sata_armada38x_sz_write(base, i, 0);
1561
}
1562
1563
for (i = 0; i < MV_WIN_DDR_MAX; i++) {
1564
if (ddr_is_active(i)) {
1565
cr = (ddr_attr(i) << IO_WIN_ATTR_SHIFT) |
1566
IO_WIN_ENA_MASK;
1567
br = ddr_base(i);
1568
sz = (ddr_size(i) - 1) &
1569
(IO_WIN_SIZE_MASK << IO_WIN_SIZE_SHIFT);
1570
1571
/* Use first available SATA window */
1572
for (j = 0; j < MV_WIN_SATA_MAX_ARMADA38X; j++) {
1573
if (win_sata_armada38x_cr_read(base, j) & IO_WIN_ENA_MASK)
1574
continue;
1575
1576
/* BASE is set to DRAM base (0x00000000) */
1577
win_sata_armada38x_br_write(base, j, br);
1578
/* CTRL targets DRAM ctrl with 0x0E or 0x0D */
1579
win_sata_armada38x_cr_write(base, j, cr);
1580
/* SIZE is set to 16MB - max value */
1581
win_sata_armada38x_sz_write(base, j, sz);
1582
break;
1583
}
1584
}
1585
}
1586
}
1587
1588
static void
1589
decode_win_ahci_dump(u_long base)
1590
{
1591
int i;
1592
1593
for (i = 0; i < MV_WIN_SATA_MAX_ARMADA38X; i++)
1594
printf("SATA window#%d: cr 0x%08x, br 0x%08x, sz 0x%08x\n", i,
1595
win_sata_armada38x_cr_read(base, i), win_sata_br_read(base, i),
1596
win_sata_armada38x_sz_read(base,i));
1597
}
1598
1599
static int
1600
decode_win_sata_valid(void)
1601
{
1602
return (decode_win_can_cover_ddr(MV_WIN_SATA_MAX));
1603
}
1604
1605
static void
1606
decode_win_sdhci_setup(u_long base)
1607
{
1608
uint32_t cr, br;
1609
int i, j;
1610
1611
for (i = 0; i < MV_WIN_SDHCI_MAX; i++) {
1612
win_sdhci_cr_write(base, i, 0);
1613
win_sdhci_br_write(base, i, 0);
1614
}
1615
1616
for (i = 0; i < MV_WIN_DDR_MAX; i++)
1617
if (ddr_is_active(i)) {
1618
br = ddr_base(i);
1619
cr = (((ddr_size(i) - 1) &
1620
(IO_WIN_SIZE_MASK << IO_WIN_SIZE_SHIFT)) |
1621
(ddr_attr(i) << IO_WIN_ATTR_SHIFT) |
1622
IO_WIN_ENA_MASK);
1623
1624
/* Use the first available SDHCI window */
1625
for (j = 0; j < MV_WIN_SDHCI_MAX; j++) {
1626
if (win_sdhci_cr_read(base, j) & IO_WIN_ENA_MASK)
1627
continue;
1628
1629
win_sdhci_cr_write(base, j, cr);
1630
win_sdhci_br_write(base, j, br);
1631
break;
1632
}
1633
}
1634
}
1635
1636
static void
1637
decode_win_sdhci_dump(u_long base)
1638
{
1639
int i;
1640
1641
for (i = 0; i < MV_WIN_SDHCI_MAX; i++)
1642
printf("SDHCI window#%d: c 0x%08x, b 0x%08x\n", i,
1643
win_sdhci_cr_read(base, i), win_sdhci_br_read(base, i));
1644
}
1645
1646
static int
1647
decode_win_sdhci_valid(void)
1648
{
1649
1650
return (decode_win_can_cover_ddr(MV_WIN_SDHCI_MAX));
1651
}
1652
1653
/**************************************************************************
1654
* FDT parsing routines.
1655
**************************************************************************/
1656
1657
static int
1658
fdt_get_ranges(const char *nodename, void *buf, int size, int *tuples,
1659
int *tuplesize)
1660
{
1661
phandle_t node;
1662
pcell_t addr_cells, par_addr_cells, size_cells;
1663
int len, tuple_size, tuples_count;
1664
1665
node = OF_finddevice(nodename);
1666
if (node == -1)
1667
return (EINVAL);
1668
1669
if ((fdt_addrsize_cells(node, &addr_cells, &size_cells)) != 0)
1670
return (ENXIO);
1671
1672
par_addr_cells = fdt_parent_addr_cells(node);
1673
if (par_addr_cells > 2)
1674
return (ERANGE);
1675
1676
tuple_size = sizeof(pcell_t) * (addr_cells + par_addr_cells +
1677
size_cells);
1678
1679
/* Note the OF_getprop_alloc() cannot be used at this early stage. */
1680
len = OF_getprop(node, "ranges", buf, size);
1681
1682
/*
1683
* XXX this does not handle the empty 'ranges;' case, which is
1684
* legitimate and should be allowed.
1685
*/
1686
tuples_count = len / tuple_size;
1687
if (tuples_count <= 0)
1688
return (ERANGE);
1689
1690
if (par_addr_cells > 2 || addr_cells > 2 || size_cells > 2)
1691
return (ERANGE);
1692
1693
*tuples = tuples_count;
1694
*tuplesize = tuple_size;
1695
return (0);
1696
}
1697
1698
static int
1699
win_cpu_from_dt(void)
1700
{
1701
pcell_t ranges[48];
1702
phandle_t node;
1703
int i, entry_size, err, t, tuple_size, tuples;
1704
u_long sram_base, sram_size;
1705
1706
t = 0;
1707
/* Retrieve 'ranges' property of '/localbus' node. */
1708
if ((err = fdt_get_ranges("/localbus", ranges, sizeof(ranges),
1709
&tuples, &tuple_size)) == 0) {
1710
/*
1711
* Fill CPU decode windows table.
1712
*/
1713
bzero((void *)&cpu_win_tbl, sizeof(cpu_win_tbl));
1714
1715
entry_size = tuple_size / sizeof(pcell_t);
1716
cpu_wins_no = tuples;
1717
1718
/* Check range */
1719
if (tuples > nitems(cpu_win_tbl)) {
1720
debugf("too many tuples to fit into cpu_win_tbl\n");
1721
return (ENOMEM);
1722
}
1723
1724
for (i = 0, t = 0; t < tuples; i += entry_size, t++) {
1725
cpu_win_tbl[t].target = 1;
1726
cpu_win_tbl[t].attr = fdt32_to_cpu(ranges[i + 1]);
1727
cpu_win_tbl[t].base = fdt32_to_cpu(ranges[i + 2]);
1728
cpu_win_tbl[t].size = fdt32_to_cpu(ranges[i + 3]);
1729
cpu_win_tbl[t].remap = ~0;
1730
debugf("target = 0x%0x attr = 0x%0x base = 0x%0x "
1731
"size = 0x%0x remap = 0x%0x\n",
1732
cpu_win_tbl[t].target,
1733
cpu_win_tbl[t].attr, cpu_win_tbl[t].base,
1734
cpu_win_tbl[t].size, cpu_win_tbl[t].remap);
1735
}
1736
}
1737
1738
/*
1739
* Retrieve CESA SRAM data.
1740
*/
1741
if ((node = OF_finddevice("sram")) != -1)
1742
if (ofw_bus_node_is_compatible(node, "mrvl,cesa-sram"))
1743
goto moveon;
1744
1745
if ((node = OF_finddevice("/")) == -1)
1746
return (ENXIO);
1747
1748
if ((node = fdt_find_compatible(node, "mrvl,cesa-sram", 0)) == 0)
1749
/* SRAM block is not always present. */
1750
return (0);
1751
moveon:
1752
sram_base = sram_size = 0;
1753
if (fdt_regsize(node, &sram_base, &sram_size) != 0)
1754
return (EINVAL);
1755
1756
/* Check range */
1757
if (t >= nitems(cpu_win_tbl)) {
1758
debugf("cannot fit CESA tuple into cpu_win_tbl\n");
1759
return (ENOMEM);
1760
}
1761
1762
cpu_win_tbl[t].target = soc_decode_win_spec->win_cesa_target;
1763
if (soc_family == MV_SOC_ARMADA_38X)
1764
cpu_win_tbl[t].attr = soc_decode_win_spec->win_cesa_attr(0);
1765
else
1766
cpu_win_tbl[t].attr = soc_decode_win_spec->win_cesa_attr(1);
1767
cpu_win_tbl[t].base = sram_base;
1768
cpu_win_tbl[t].size = sram_size;
1769
cpu_win_tbl[t].remap = ~0;
1770
cpu_wins_no++;
1771
debugf("sram: base = 0x%0lx size = 0x%0lx\n", sram_base, sram_size);
1772
1773
/* Check if there is a second CESA node */
1774
while ((node = OF_peer(node)) != 0) {
1775
if (ofw_bus_node_is_compatible(node, "mrvl,cesa-sram")) {
1776
if (fdt_regsize(node, &sram_base, &sram_size) != 0)
1777
return (EINVAL);
1778
break;
1779
}
1780
}
1781
1782
if (node == 0)
1783
return (0);
1784
1785
t++;
1786
if (t >= nitems(cpu_win_tbl)) {
1787
debugf("cannot fit CESA tuple into cpu_win_tbl\n");
1788
return (ENOMEM);
1789
}
1790
1791
/* Configure window for CESA1 */
1792
cpu_win_tbl[t].target = soc_decode_win_spec->win_cesa_target;
1793
cpu_win_tbl[t].attr = soc_decode_win_spec->win_cesa_attr(1);
1794
cpu_win_tbl[t].base = sram_base;
1795
cpu_win_tbl[t].size = sram_size;
1796
cpu_win_tbl[t].remap = ~0;
1797
cpu_wins_no++;
1798
debugf("sram: base = 0x%0lx size = 0x%0lx\n", sram_base, sram_size);
1799
1800
return (0);
1801
}
1802
1803
static int
1804
fdt_win_process(phandle_t child)
1805
{
1806
int i, ret;
1807
1808
for (i = 0; soc_nodes[i].compat != NULL; i++) {
1809
/* Setup only for enabled devices */
1810
if (ofw_bus_node_status_okay(child) == 0)
1811
continue;
1812
1813
if (!ofw_bus_node_is_compatible(child, soc_nodes[i].compat))
1814
continue;
1815
1816
ret = fdt_win_process_child(child, &soc_nodes[i], "reg");
1817
if (ret != 0)
1818
return (ret);
1819
}
1820
1821
return (0);
1822
}
1823
1824
static int
1825
fdt_win_process_child(phandle_t child, struct soc_node_spec *soc_node,
1826
const char* mimo_reg_source)
1827
{
1828
int addr_cells, size_cells;
1829
pcell_t reg[8];
1830
u_long base;
1831
1832
if (fdt_addrsize_cells(OF_parent(child), &addr_cells,
1833
&size_cells))
1834
return (ENXIO);
1835
1836
if ((sizeof(pcell_t) * (addr_cells + size_cells)) > sizeof(reg))
1837
return (ENOMEM);
1838
if (OF_getprop(child, mimo_reg_source, &reg, sizeof(reg)) <= 0)
1839
return (EINVAL);
1840
1841
if (addr_cells <= 2)
1842
base = fdt_data_get(&reg[0], addr_cells);
1843
else
1844
base = fdt_data_get(&reg[addr_cells - 2], 2);
1845
fdt_data_get(&reg[addr_cells], size_cells);
1846
1847
if (soc_node->valid_handler != NULL)
1848
if (!soc_node->valid_handler())
1849
return (EINVAL);
1850
1851
base = (base & 0x000fffff) | fdt_immr_va;
1852
if (soc_node->decode_handler != NULL)
1853
soc_node->decode_handler(base);
1854
else
1855
return (ENXIO);
1856
1857
if (MV_DUMP_WIN && (soc_node->dump_handler != NULL))
1858
soc_node->dump_handler(base);
1859
1860
return (0);
1861
}
1862
1863
static int
1864
fdt_win_setup(void)
1865
{
1866
phandle_t node, child, sb;
1867
phandle_t child_pci;
1868
int err;
1869
1870
sb = 0;
1871
node = OF_finddevice("/");
1872
if (node == -1)
1873
panic("fdt_win_setup: no root node");
1874
1875
/* Allow for coherent transactions on the A38x MBUS */
1876
if (ofw_bus_node_is_compatible(node, "marvell,armada380"))
1877
platform_io_coherent = true;
1878
1879
/*
1880
* Traverse through all children of root and simple-bus nodes.
1881
* For each found device retrieve decode windows data (if applicable).
1882
*/
1883
child = OF_child(node);
1884
while (child != 0) {
1885
/* Lookup for callback and run */
1886
err = fdt_win_process(child);
1887
if (err != 0)
1888
return (err);
1889
1890
/* Process Marvell Armada-XP/38x PCIe controllers */
1891
if (ofw_bus_node_is_compatible(child, "marvell,armada-370-pcie")) {
1892
child_pci = OF_child(child);
1893
while (child_pci != 0) {
1894
err = fdt_win_process_child(child_pci,
1895
&soc_nodes[SOC_NODE_PCIE_ENTRY_IDX],
1896
"assigned-addresses");
1897
if (err != 0)
1898
return (err);
1899
1900
child_pci = OF_peer(child_pci);
1901
}
1902
}
1903
1904
/*
1905
* Once done with root-level children let's move down to
1906
* simple-bus and its children.
1907
*/
1908
child = OF_peer(child);
1909
if ((child == 0) && (node == OF_finddevice("/"))) {
1910
sb = node = fdt_find_compatible(node, "simple-bus", 0);
1911
if (node == 0)
1912
return (ENXIO);
1913
child = OF_child(node);
1914
}
1915
/*
1916
* Next, move one more level down to internal-regs node (if
1917
* it is present) and its children. This node also have
1918
* "simple-bus" compatible.
1919
*/
1920
if ((child == 0) && (node == sb)) {
1921
node = fdt_find_compatible(node, "simple-bus", 0);
1922
if (node == 0)
1923
return (0);
1924
child = OF_child(node);
1925
}
1926
}
1927
1928
return (0);
1929
}
1930
1931
static void
1932
fdt_fixup_busfreq(phandle_t root)
1933
{
1934
phandle_t sb;
1935
pcell_t freq;
1936
1937
freq = cpu_to_fdt32(get_tclk());
1938
1939
/*
1940
* Fix bus speed in cpu node
1941
*/
1942
if ((sb = OF_finddevice("cpu")) != -1)
1943
if (fdt_is_compatible_strict(sb, "ARM,88VS584"))
1944
OF_setprop(sb, "bus-frequency", (void *)&freq,
1945
sizeof(freq));
1946
1947
/*
1948
* This fixup sets the simple-bus bus-frequency property.
1949
*/
1950
if ((sb = fdt_find_compatible(root, "simple-bus", 1)) != 0)
1951
OF_setprop(sb, "bus-frequency", (void *)&freq, sizeof(freq));
1952
}
1953
1954
static void
1955
fdt_fixup_ranges(phandle_t root)
1956
{
1957
phandle_t node;
1958
pcell_t par_addr_cells, addr_cells, size_cells;
1959
pcell_t ranges[3], reg[2], *rangesptr;
1960
int len, tuple_size, tuples_count;
1961
uint32_t base;
1962
1963
/* Fix-up SoC ranges according to real fdt_immr_pa */
1964
if ((node = fdt_find_compatible(root, "simple-bus", 1)) != 0) {
1965
if (fdt_addrsize_cells(node, &addr_cells, &size_cells) == 0 &&
1966
((par_addr_cells = fdt_parent_addr_cells(node)) <= 2)) {
1967
tuple_size = sizeof(pcell_t) * (par_addr_cells +
1968
addr_cells + size_cells);
1969
len = OF_getprop(node, "ranges", ranges,
1970
sizeof(ranges));
1971
tuples_count = len / tuple_size;
1972
/* Unexpected settings are not supported */
1973
if (tuples_count != 1)
1974
goto fixup_failed;
1975
1976
rangesptr = &ranges[0];
1977
rangesptr += par_addr_cells;
1978
base = fdt_data_get((void *)rangesptr, addr_cells);
1979
*rangesptr = cpu_to_fdt32(fdt_immr_pa);
1980
if (OF_setprop(node, "ranges", (void *)&ranges[0],
1981
sizeof(ranges)) < 0)
1982
goto fixup_failed;
1983
}
1984
}
1985
1986
/* Fix-up PCIe reg according to real PCIe registers' PA */
1987
if ((node = fdt_find_compatible(root, "mrvl,pcie", 1)) != 0) {
1988
if (fdt_addrsize_cells(OF_parent(node), &par_addr_cells,
1989
&size_cells) == 0) {
1990
tuple_size = sizeof(pcell_t) * (par_addr_cells +
1991
size_cells);
1992
len = OF_getprop(node, "reg", reg, sizeof(reg));
1993
tuples_count = len / tuple_size;
1994
/* Unexpected settings are not supported */
1995
if (tuples_count != 1)
1996
goto fixup_failed;
1997
1998
base = fdt_data_get((void *)&reg[0], par_addr_cells);
1999
base &= ~0xFF000000;
2000
base |= fdt_immr_pa;
2001
reg[0] = cpu_to_fdt32(base);
2002
if (OF_setprop(node, "reg", (void *)&reg[0],
2003
sizeof(reg)) < 0)
2004
goto fixup_failed;
2005
}
2006
}
2007
/* Fix-up succeeded. May return and continue */
2008
return;
2009
2010
fixup_failed:
2011
while (1) {
2012
/*
2013
* In case of any error while fixing ranges just hang.
2014
* 1. No message can be displayed yet since console
2015
* is not initialized.
2016
* 2. Going further will cause failure on bus_space_map()
2017
* relying on the wrong ranges or data abort when
2018
* accessing PCIe registers.
2019
*/
2020
}
2021
}
2022
2023
struct fdt_fixup_entry fdt_fixup_table[] = {
2024
{ "mrvl,DB-88F6281", &fdt_fixup_busfreq },
2025
{ "mrvl,DB-78460", &fdt_fixup_busfreq },
2026
{ "mrvl,DB-78460", &fdt_fixup_ranges },
2027
{ NULL, NULL }
2028
};
2029
2030
uint32_t
2031
get_tclk(void)
2032
{
2033
2034
if (soc_decode_win_spec->get_tclk != NULL)
2035
return soc_decode_win_spec->get_tclk();
2036
else
2037
return -1;
2038
}
2039
2040
uint32_t
2041
get_cpu_freq(void)
2042
{
2043
2044
if (soc_decode_win_spec->get_cpu_freq != NULL)
2045
return soc_decode_win_spec->get_cpu_freq();
2046
else
2047
return -1;
2048
}
2049
2050