Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/powerpc/platforms/embedded6xx/prpmc2800.c
10819 views
1
/*
2
* Board setup routines for the Motorola PrPMC2800
3
*
4
* Author: Dale Farnsworth <[email protected]>
5
*
6
* 2007 (c) MontaVista, Software, Inc. This file is licensed under
7
* the terms of the GNU General Public License version 2. This program
8
* is licensed "as is" without any warranty of any kind, whether express
9
* or implied.
10
*/
11
12
#include <linux/stddef.h>
13
#include <linux/kernel.h>
14
#include <linux/delay.h>
15
#include <linux/interrupt.h>
16
#include <linux/seq_file.h>
17
18
#include <asm/machdep.h>
19
#include <asm/prom.h>
20
#include <asm/system.h>
21
#include <asm/time.h>
22
23
#include <mm/mmu_decl.h>
24
25
#include <sysdev/mv64x60.h>
26
27
#define MV64x60_MPP_CNTL_0 0x0000
28
#define MV64x60_MPP_CNTL_2 0x0008
29
30
#define MV64x60_GPP_IO_CNTL 0x0000
31
#define MV64x60_GPP_LEVEL_CNTL 0x0010
32
#define MV64x60_GPP_VALUE_SET 0x0018
33
34
#define PLATFORM_NAME_MAX 32
35
36
static char prpmc2800_platform_name[PLATFORM_NAME_MAX];
37
38
static void __iomem *mv64x60_mpp_reg_base;
39
static void __iomem *mv64x60_gpp_reg_base;
40
41
static void __init prpmc2800_setup_arch(void)
42
{
43
struct device_node *np;
44
phys_addr_t paddr;
45
const unsigned int *reg;
46
47
/*
48
* ioremap mpp and gpp registers in case they are later
49
* needed by prpmc2800_reset_board().
50
*/
51
np = of_find_compatible_node(NULL, NULL, "marvell,mv64360-mpp");
52
reg = of_get_property(np, "reg", NULL);
53
paddr = of_translate_address(np, reg);
54
of_node_put(np);
55
mv64x60_mpp_reg_base = ioremap(paddr, reg[1]);
56
57
np = of_find_compatible_node(NULL, NULL, "marvell,mv64360-gpp");
58
reg = of_get_property(np, "reg", NULL);
59
paddr = of_translate_address(np, reg);
60
of_node_put(np);
61
mv64x60_gpp_reg_base = ioremap(paddr, reg[1]);
62
63
#ifdef CONFIG_PCI
64
mv64x60_pci_init();
65
#endif
66
67
printk("Motorola %s\n", prpmc2800_platform_name);
68
}
69
70
static void prpmc2800_reset_board(void)
71
{
72
u32 temp;
73
74
local_irq_disable();
75
76
temp = in_le32(mv64x60_mpp_reg_base + MV64x60_MPP_CNTL_0);
77
temp &= 0xFFFF0FFF;
78
out_le32(mv64x60_mpp_reg_base + MV64x60_MPP_CNTL_0, temp);
79
80
temp = in_le32(mv64x60_gpp_reg_base + MV64x60_GPP_LEVEL_CNTL);
81
temp |= 0x00000004;
82
out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_LEVEL_CNTL, temp);
83
84
temp = in_le32(mv64x60_gpp_reg_base + MV64x60_GPP_IO_CNTL);
85
temp |= 0x00000004;
86
out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_IO_CNTL, temp);
87
88
temp = in_le32(mv64x60_mpp_reg_base + MV64x60_MPP_CNTL_2);
89
temp &= 0xFFFF0FFF;
90
out_le32(mv64x60_mpp_reg_base + MV64x60_MPP_CNTL_2, temp);
91
92
temp = in_le32(mv64x60_gpp_reg_base + MV64x60_GPP_LEVEL_CNTL);
93
temp |= 0x00080000;
94
out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_LEVEL_CNTL, temp);
95
96
temp = in_le32(mv64x60_gpp_reg_base + MV64x60_GPP_IO_CNTL);
97
temp |= 0x00080000;
98
out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_IO_CNTL, temp);
99
100
out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_VALUE_SET, 0x00080004);
101
}
102
103
static void prpmc2800_restart(char *cmd)
104
{
105
volatile ulong i = 10000000;
106
107
prpmc2800_reset_board();
108
109
while (i-- > 0);
110
panic("restart failed\n");
111
}
112
113
#ifdef CONFIG_NOT_COHERENT_CACHE
114
#define PPRPM2800_COHERENCY_SETTING "off"
115
#else
116
#define PPRPM2800_COHERENCY_SETTING "on"
117
#endif
118
119
void prpmc2800_show_cpuinfo(struct seq_file *m)
120
{
121
seq_printf(m, "Vendor\t\t: Motorola\n");
122
seq_printf(m, "coherency\t: %s\n", PPRPM2800_COHERENCY_SETTING);
123
}
124
125
/*
126
* Called very early, device-tree isn't unflattened
127
*/
128
static int __init prpmc2800_probe(void)
129
{
130
unsigned long root = of_get_flat_dt_root();
131
unsigned long len = PLATFORM_NAME_MAX;
132
void *m;
133
134
if (!of_flat_dt_is_compatible(root, "motorola,PrPMC2800"))
135
return 0;
136
137
/* Update ppc_md.name with name from dt */
138
m = of_get_flat_dt_prop(root, "model", &len);
139
if (m)
140
strncpy(prpmc2800_platform_name, m,
141
min((int)len, PLATFORM_NAME_MAX - 1));
142
143
_set_L2CR(_get_L2CR() | L2CR_L2E);
144
return 1;
145
}
146
147
define_machine(prpmc2800){
148
.name = prpmc2800_platform_name,
149
.probe = prpmc2800_probe,
150
.setup_arch = prpmc2800_setup_arch,
151
.init_early = mv64x60_init_early,
152
.show_cpuinfo = prpmc2800_show_cpuinfo,
153
.init_IRQ = mv64x60_init_irq,
154
.get_irq = mv64x60_get_irq,
155
.restart = prpmc2800_restart,
156
.calibrate_decr = generic_calibrate_decr,
157
};
158
159