diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/include/asm/hardware/sp810.h | 6 | ||||
-rw-r--r-- | arch/arm/mach-vexpress/Kconfig | 4 | ||||
-rw-r--r-- | arch/arm/mach-vexpress/Makefile | 2 | ||||
-rw-r--r-- | arch/arm/mach-vexpress/ct-ca9x4.c | 41 | ||||
-rw-r--r-- | arch/arm/mach-vexpress/include/mach/motherboard.h | 81 | ||||
-rw-r--r-- | arch/arm/mach-vexpress/platsmp.c | 3 | ||||
-rw-r--r-- | arch/arm/mach-vexpress/v2m.c | 332 |
7 files changed, 99 insertions, 370 deletions
diff --git a/arch/arm/include/asm/hardware/sp810.h b/arch/arm/include/asm/hardware/sp810.h index afd7e916472f..6636430dd0e6 100644 --- a/arch/arm/include/asm/hardware/sp810.h +++ b/arch/arm/include/asm/hardware/sp810.h | |||
@@ -50,12 +50,6 @@ | |||
50 | #define SCPCELLID2 0xFF8 | 50 | #define SCPCELLID2 0xFF8 |
51 | #define SCPCELLID3 0xFFC | 51 | #define SCPCELLID3 0xFFC |
52 | 52 | ||
53 | #define SCCTRL_TIMEREN0SEL_REFCLK (0 << 15) | ||
54 | #define SCCTRL_TIMEREN0SEL_TIMCLK (1 << 15) | ||
55 | |||
56 | #define SCCTRL_TIMEREN1SEL_REFCLK (0 << 17) | ||
57 | #define SCCTRL_TIMEREN1SEL_TIMCLK (1 << 17) | ||
58 | |||
59 | #define SCCTRL_TIMERENnSEL_SHIFT(n) (15 + ((n) * 2)) | 53 | #define SCCTRL_TIMERENnSEL_SHIFT(n) (15 + ((n) * 2)) |
60 | 54 | ||
61 | static inline void sysctl_soft_reset(void __iomem *base) | 55 | static inline void sysctl_soft_reset(void __iomem *base) |
diff --git a/arch/arm/mach-vexpress/Kconfig b/arch/arm/mach-vexpress/Kconfig index c95296066203..99e63f5f99d1 100644 --- a/arch/arm/mach-vexpress/Kconfig +++ b/arch/arm/mach-vexpress/Kconfig | |||
@@ -1,11 +1,12 @@ | |||
1 | config ARCH_VEXPRESS | 1 | config ARCH_VEXPRESS |
2 | bool "ARM Ltd. Versatile Express family" if ARCH_MULTI_V7 | 2 | bool "ARM Ltd. Versatile Express family" if ARCH_MULTI_V7 |
3 | select ARCH_WANT_OPTIONAL_GPIOLIB | 3 | select ARCH_REQUIRE_GPIOLIB |
4 | select ARM_AMBA | 4 | select ARM_AMBA |
5 | select ARM_GIC | 5 | select ARM_GIC |
6 | select ARM_TIMER_SP804 | 6 | select ARM_TIMER_SP804 |
7 | select CLKDEV_LOOKUP | 7 | select CLKDEV_LOOKUP |
8 | select COMMON_CLK | 8 | select COMMON_CLK |
9 | select COMMON_CLK_VERSATILE | ||
9 | select CPU_V7 | 10 | select CPU_V7 |
10 | select GENERIC_CLOCKEVENTS | 11 | select GENERIC_CLOCKEVENTS |
11 | select HAVE_CLK | 12 | select HAVE_CLK |
@@ -17,6 +18,7 @@ config ARCH_VEXPRESS | |||
17 | select PLAT_VERSATILE | 18 | select PLAT_VERSATILE |
18 | select PLAT_VERSATILE_CLCD | 19 | select PLAT_VERSATILE_CLCD |
19 | select REGULATOR_FIXED_VOLTAGE if REGULATOR | 20 | select REGULATOR_FIXED_VOLTAGE if REGULATOR |
21 | select VEXPRESS_CONFIG | ||
20 | help | 22 | help |
21 | This option enables support for systems using Cortex processor based | 23 | This option enables support for systems using Cortex processor based |
22 | ARM core and logic (FPGA) tiles on the Versatile Express motherboard, | 24 | ARM core and logic (FPGA) tiles on the Versatile Express motherboard, |
diff --git a/arch/arm/mach-vexpress/Makefile b/arch/arm/mach-vexpress/Makefile index 42703e8b4d3b..80b64971fbdd 100644 --- a/arch/arm/mach-vexpress/Makefile +++ b/arch/arm/mach-vexpress/Makefile | |||
@@ -4,7 +4,7 @@ | |||
4 | ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include \ | 4 | ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include \ |
5 | -I$(srctree)/arch/arm/plat-versatile/include | 5 | -I$(srctree)/arch/arm/plat-versatile/include |
6 | 6 | ||
7 | obj-y := v2m.o | 7 | obj-y := v2m.o reset.o |
8 | obj-$(CONFIG_ARCH_VEXPRESS_CA9X4) += ct-ca9x4.o | 8 | obj-$(CONFIG_ARCH_VEXPRESS_CA9X4) += ct-ca9x4.o |
9 | obj-$(CONFIG_SMP) += platsmp.o | 9 | obj-$(CONFIG_SMP) += platsmp.o |
10 | obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o | 10 | obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o |
diff --git a/arch/arm/mach-vexpress/ct-ca9x4.c b/arch/arm/mach-vexpress/ct-ca9x4.c index 4f471fa3e3c5..60838ddb8564 100644 --- a/arch/arm/mach-vexpress/ct-ca9x4.c +++ b/arch/arm/mach-vexpress/ct-ca9x4.c | |||
@@ -9,6 +9,7 @@ | |||
9 | #include <linux/amba/bus.h> | 9 | #include <linux/amba/bus.h> |
10 | #include <linux/amba/clcd.h> | 10 | #include <linux/amba/clcd.h> |
11 | #include <linux/clkdev.h> | 11 | #include <linux/clkdev.h> |
12 | #include <linux/vexpress.h> | ||
12 | 13 | ||
13 | #include <asm/hardware/arm_timer.h> | 14 | #include <asm/hardware/arm_timer.h> |
14 | #include <asm/hardware/cache-l2x0.h> | 15 | #include <asm/hardware/cache-l2x0.h> |
@@ -64,19 +65,6 @@ static void __init ct_ca9x4_init_irq(void) | |||
64 | ca9x4_twd_init(); | 65 | ca9x4_twd_init(); |
65 | } | 66 | } |
66 | 67 | ||
67 | static void ct_ca9x4_clcd_enable(struct clcd_fb *fb) | ||
68 | { | ||
69 | u32 site = v2m_get_master_site(); | ||
70 | |||
71 | /* | ||
72 | * Old firmware was using the "site" component of the command | ||
73 | * to control the DVI muxer (while it should be always 0 ie. MB). | ||
74 | * Newer firmware uses the data register. Keep both for compatibility. | ||
75 | */ | ||
76 | v2m_cfg_write(SYS_CFG_MUXFPGA | SYS_CFG_SITE(site), site); | ||
77 | v2m_cfg_write(SYS_CFG_DVIMODE | SYS_CFG_SITE(SYS_CFG_SITE_MB), 2); | ||
78 | } | ||
79 | |||
80 | static int ct_ca9x4_clcd_setup(struct clcd_fb *fb) | 68 | static int ct_ca9x4_clcd_setup(struct clcd_fb *fb) |
81 | { | 69 | { |
82 | unsigned long framesize = 1024 * 768 * 2; | 70 | unsigned long framesize = 1024 * 768 * 2; |
@@ -93,7 +81,6 @@ static struct clcd_board ct_ca9x4_clcd_data = { | |||
93 | .caps = CLCD_CAP_5551 | CLCD_CAP_565, | 81 | .caps = CLCD_CAP_5551 | CLCD_CAP_565, |
94 | .check = clcdfb_check, | 82 | .check = clcdfb_check, |
95 | .decode = clcdfb_decode, | 83 | .decode = clcdfb_decode, |
96 | .enable = ct_ca9x4_clcd_enable, | ||
97 | .setup = ct_ca9x4_clcd_setup, | 84 | .setup = ct_ca9x4_clcd_setup, |
98 | .mmap = versatile_clcd_mmap_dma, | 85 | .mmap = versatile_clcd_mmap_dma, |
99 | .remove = versatile_clcd_remove_dma, | 86 | .remove = versatile_clcd_remove_dma, |
@@ -111,14 +98,6 @@ static struct amba_device *ct_ca9x4_amba_devs[] __initdata = { | |||
111 | &gpio_device, | 98 | &gpio_device, |
112 | }; | 99 | }; |
113 | 100 | ||
114 | |||
115 | static struct v2m_osc ct_osc1 = { | ||
116 | .osc = 1, | ||
117 | .rate_min = 10000000, | ||
118 | .rate_max = 80000000, | ||
119 | .rate_default = 23750000, | ||
120 | }; | ||
121 | |||
122 | static struct resource pmu_resources[] = { | 101 | static struct resource pmu_resources[] = { |
123 | [0] = { | 102 | [0] = { |
124 | .start = IRQ_CT_CA9X4_PMU_CPU0, | 103 | .start = IRQ_CT_CA9X4_PMU_CPU0, |
@@ -149,10 +128,18 @@ static struct platform_device pmu_device = { | |||
149 | .resource = pmu_resources, | 128 | .resource = pmu_resources, |
150 | }; | 129 | }; |
151 | 130 | ||
131 | static struct platform_device osc1_device = { | ||
132 | .name = "vexpress-osc", | ||
133 | .id = 1, | ||
134 | .num_resources = 1, | ||
135 | .resource = (struct resource []) { | ||
136 | VEXPRESS_RES_FUNC(0xf, 1), | ||
137 | }, | ||
138 | }; | ||
139 | |||
152 | static void __init ct_ca9x4_init(void) | 140 | static void __init ct_ca9x4_init(void) |
153 | { | 141 | { |
154 | int i; | 142 | int i; |
155 | struct clk *clk; | ||
156 | 143 | ||
157 | #ifdef CONFIG_CACHE_L2X0 | 144 | #ifdef CONFIG_CACHE_L2X0 |
158 | void __iomem *l2x0_base = ioremap(CT_CA9X4_L2CC, SZ_4K); | 145 | void __iomem *l2x0_base = ioremap(CT_CA9X4_L2CC, SZ_4K); |
@@ -164,14 +151,14 @@ static void __init ct_ca9x4_init(void) | |||
164 | l2x0_init(l2x0_base, 0x00400000, 0xfe0fffff); | 151 | l2x0_init(l2x0_base, 0x00400000, 0xfe0fffff); |
165 | #endif | 152 | #endif |
166 | 153 | ||
167 | ct_osc1.site = v2m_get_master_site(); | ||
168 | clk = v2m_osc_register("ct:osc1", &ct_osc1); | ||
169 | clk_register_clkdev(clk, NULL, "ct:clcd"); | ||
170 | |||
171 | for (i = 0; i < ARRAY_SIZE(ct_ca9x4_amba_devs); i++) | 154 | for (i = 0; i < ARRAY_SIZE(ct_ca9x4_amba_devs); i++) |
172 | amba_device_register(ct_ca9x4_amba_devs[i], &iomem_resource); | 155 | amba_device_register(ct_ca9x4_amba_devs[i], &iomem_resource); |
173 | 156 | ||
174 | platform_device_register(&pmu_device); | 157 | platform_device_register(&pmu_device); |
158 | platform_device_register(&osc1_device); | ||
159 | |||
160 | WARN_ON(clk_register_clkdev(vexpress_osc_setup(&osc1_device.dev), | ||
161 | NULL, "ct:clcd")); | ||
175 | } | 162 | } |
176 | 163 | ||
177 | #ifdef CONFIG_SMP | 164 | #ifdef CONFIG_SMP |
diff --git a/arch/arm/mach-vexpress/include/mach/motherboard.h b/arch/arm/mach-vexpress/include/mach/motherboard.h index 1e388c7bf4d7..68abc8b72781 100644 --- a/arch/arm/mach-vexpress/include/mach/motherboard.h +++ b/arch/arm/mach-vexpress/include/mach/motherboard.h | |||
@@ -1,8 +1,6 @@ | |||
1 | #ifndef __MACH_MOTHERBOARD_H | 1 | #ifndef __MACH_MOTHERBOARD_H |
2 | #define __MACH_MOTHERBOARD_H | 2 | #define __MACH_MOTHERBOARD_H |
3 | 3 | ||
4 | #include <linux/clk-provider.h> | ||
5 | |||
6 | /* | 4 | /* |
7 | * Physical addresses, offset from V2M_PA_CS0-3 | 5 | * Physical addresses, offset from V2M_PA_CS0-3 |
8 | */ | 6 | */ |
@@ -41,31 +39,6 @@ | |||
41 | #define V2M_CF (V2M_PA_CS7 + 0x0001a000) | 39 | #define V2M_CF (V2M_PA_CS7 + 0x0001a000) |
42 | #define V2M_CLCD (V2M_PA_CS7 + 0x0001f000) | 40 | #define V2M_CLCD (V2M_PA_CS7 + 0x0001f000) |
43 | 41 | ||
44 | /* | ||
45 | * Offsets from SYSREGS base | ||
46 | */ | ||
47 | #define V2M_SYS_ID 0x000 | ||
48 | #define V2M_SYS_SW 0x004 | ||
49 | #define V2M_SYS_LED 0x008 | ||
50 | #define V2M_SYS_100HZ 0x024 | ||
51 | #define V2M_SYS_FLAGS 0x030 | ||
52 | #define V2M_SYS_FLAGSSET 0x030 | ||
53 | #define V2M_SYS_FLAGSCLR 0x034 | ||
54 | #define V2M_SYS_NVFLAGS 0x038 | ||
55 | #define V2M_SYS_NVFLAGSSET 0x038 | ||
56 | #define V2M_SYS_NVFLAGSCLR 0x03c | ||
57 | #define V2M_SYS_MCI 0x048 | ||
58 | #define V2M_SYS_FLASH 0x03c | ||
59 | #define V2M_SYS_CFGSW 0x058 | ||
60 | #define V2M_SYS_24MHZ 0x05c | ||
61 | #define V2M_SYS_MISC 0x060 | ||
62 | #define V2M_SYS_DMA 0x064 | ||
63 | #define V2M_SYS_PROCID0 0x084 | ||
64 | #define V2M_SYS_PROCID1 0x088 | ||
65 | #define V2M_SYS_CFGDATA 0x0a0 | ||
66 | #define V2M_SYS_CFGCTRL 0x0a4 | ||
67 | #define V2M_SYS_CFGSTAT 0x0a8 | ||
68 | |||
69 | 42 | ||
70 | /* | 43 | /* |
71 | * Interrupts. Those in {} are for AMBA devices | 44 | * Interrupts. Those in {} are for AMBA devices |
@@ -91,43 +64,6 @@ | |||
91 | 64 | ||
92 | 65 | ||
93 | /* | 66 | /* |
94 | * Configuration | ||
95 | */ | ||
96 | #define SYS_CFG_START (1 << 31) | ||
97 | #define SYS_CFG_WRITE (1 << 30) | ||
98 | #define SYS_CFG_OSC (1 << 20) | ||
99 | #define SYS_CFG_VOLT (2 << 20) | ||
100 | #define SYS_CFG_AMP (3 << 20) | ||
101 | #define SYS_CFG_TEMP (4 << 20) | ||
102 | #define SYS_CFG_RESET (5 << 20) | ||
103 | #define SYS_CFG_SCC (6 << 20) | ||
104 | #define SYS_CFG_MUXFPGA (7 << 20) | ||
105 | #define SYS_CFG_SHUTDOWN (8 << 20) | ||
106 | #define SYS_CFG_REBOOT (9 << 20) | ||
107 | #define SYS_CFG_DVIMODE (11 << 20) | ||
108 | #define SYS_CFG_POWER (12 << 20) | ||
109 | #define SYS_CFG_SITE(n) ((n) << 16) | ||
110 | #define SYS_CFG_SITE_MB 0 | ||
111 | #define SYS_CFG_SITE_DB1 1 | ||
112 | #define SYS_CFG_SITE_DB2 2 | ||
113 | #define SYS_CFG_STACK(n) ((n) << 12) | ||
114 | |||
115 | #define SYS_CFG_ERR (1 << 1) | ||
116 | #define SYS_CFG_COMPLETE (1 << 0) | ||
117 | |||
118 | int v2m_cfg_write(u32 devfn, u32 data); | ||
119 | int v2m_cfg_read(u32 devfn, u32 *data); | ||
120 | void v2m_flags_set(u32 data); | ||
121 | |||
122 | /* | ||
123 | * Miscellaneous | ||
124 | */ | ||
125 | #define SYS_MISC_MASTERSITE (1 << 14) | ||
126 | #define SYS_PROCIDx_HBI_MASK 0xfff | ||
127 | |||
128 | int v2m_get_master_site(void); | ||
129 | |||
130 | /* | ||
131 | * Core tile IDs | 67 | * Core tile IDs |
132 | */ | 68 | */ |
133 | #define V2M_CT_ID_CA9 0x0c000191 | 69 | #define V2M_CT_ID_CA9 0x0c000191 |
@@ -149,21 +85,4 @@ struct ct_desc { | |||
149 | 85 | ||
150 | extern struct ct_desc *ct_desc; | 86 | extern struct ct_desc *ct_desc; |
151 | 87 | ||
152 | /* | ||
153 | * OSC clock provider | ||
154 | */ | ||
155 | struct v2m_osc { | ||
156 | struct clk_hw hw; | ||
157 | u8 site; /* 0 = motherboard, 1 = site 1, 2 = site 2 */ | ||
158 | u8 stack; /* board stack position */ | ||
159 | u16 osc; | ||
160 | unsigned long rate_min; | ||
161 | unsigned long rate_max; | ||
162 | unsigned long rate_default; | ||
163 | }; | ||
164 | |||
165 | #define to_v2m_osc(osc) container_of(osc, struct v2m_osc, hw) | ||
166 | |||
167 | struct clk *v2m_osc_register(const char *name, struct v2m_osc *osc); | ||
168 | |||
169 | #endif | 88 | #endif |
diff --git a/arch/arm/mach-vexpress/platsmp.c b/arch/arm/mach-vexpress/platsmp.c index 7db27c8c05cc..c5d70de9bb4e 100644 --- a/arch/arm/mach-vexpress/platsmp.c +++ b/arch/arm/mach-vexpress/platsmp.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/smp.h> | 13 | #include <linux/smp.h> |
14 | #include <linux/io.h> | 14 | #include <linux/io.h> |
15 | #include <linux/of_fdt.h> | 15 | #include <linux/of_fdt.h> |
16 | #include <linux/vexpress.h> | ||
16 | 17 | ||
17 | #include <asm/smp_scu.h> | 18 | #include <asm/smp_scu.h> |
18 | #include <asm/hardware/gic.h> | 19 | #include <asm/hardware/gic.h> |
@@ -193,7 +194,7 @@ static void __init vexpress_smp_prepare_cpus(unsigned int max_cpus) | |||
193 | * until it receives a soft interrupt, and then the | 194 | * until it receives a soft interrupt, and then the |
194 | * secondary CPU branches to this address. | 195 | * secondary CPU branches to this address. |
195 | */ | 196 | */ |
196 | v2m_flags_set(virt_to_phys(versatile_secondary_startup)); | 197 | vexpress_flags_set(virt_to_phys(versatile_secondary_startup)); |
197 | } | 198 | } |
198 | 199 | ||
199 | struct smp_operations __initdata vexpress_smp_ops = { | 200 | struct smp_operations __initdata vexpress_smp_ops = { |
diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c index 560e0df728f8..99d4172816be 100644 --- a/arch/arm/mach-vexpress/v2m.c +++ b/arch/arm/mach-vexpress/v2m.c | |||
@@ -16,11 +16,10 @@ | |||
16 | #include <linux/smsc911x.h> | 16 | #include <linux/smsc911x.h> |
17 | #include <linux/spinlock.h> | 17 | #include <linux/spinlock.h> |
18 | #include <linux/usb/isp1760.h> | 18 | #include <linux/usb/isp1760.h> |
19 | #include <linux/clkdev.h> | ||
20 | #include <linux/clk-provider.h> | ||
21 | #include <linux/mtd/physmap.h> | 19 | #include <linux/mtd/physmap.h> |
22 | #include <linux/regulator/fixed.h> | 20 | #include <linux/regulator/fixed.h> |
23 | #include <linux/regulator/machine.h> | 21 | #include <linux/regulator/machine.h> |
22 | #include <linux/vexpress.h> | ||
24 | 23 | ||
25 | #include <asm/arch_timer.h> | 24 | #include <asm/arch_timer.h> |
26 | #include <asm/mach-types.h> | 25 | #include <asm/mach-types.h> |
@@ -33,7 +32,6 @@ | |||
33 | #include <asm/hardware/cache-l2x0.h> | 32 | #include <asm/hardware/cache-l2x0.h> |
34 | #include <asm/hardware/gic.h> | 33 | #include <asm/hardware/gic.h> |
35 | #include <asm/hardware/timer-sp.h> | 34 | #include <asm/hardware/timer-sp.h> |
36 | #include <asm/hardware/sp810.h> | ||
37 | 35 | ||
38 | #include <mach/ct-ca9x4.h> | 36 | #include <mach/ct-ca9x4.h> |
39 | #include <mach/motherboard.h> | 37 | #include <mach/motherboard.h> |
@@ -58,22 +56,6 @@ static struct map_desc v2m_io_desc[] __initdata = { | |||
58 | }, | 56 | }, |
59 | }; | 57 | }; |
60 | 58 | ||
61 | static void __iomem *v2m_sysreg_base; | ||
62 | |||
63 | static void __init v2m_sysctl_init(void __iomem *base) | ||
64 | { | ||
65 | u32 scctrl; | ||
66 | |||
67 | if (WARN_ON(!base)) | ||
68 | return; | ||
69 | |||
70 | /* Select 1MHz TIMCLK as the reference clock for SP804 timers */ | ||
71 | scctrl = readl(base + SCCTRL); | ||
72 | scctrl |= SCCTRL_TIMEREN0SEL_TIMCLK; | ||
73 | scctrl |= SCCTRL_TIMEREN1SEL_TIMCLK; | ||
74 | writel(scctrl, base + SCCTRL); | ||
75 | } | ||
76 | |||
77 | static void __init v2m_sp804_init(void __iomem *base, unsigned int irq) | 59 | static void __init v2m_sp804_init(void __iomem *base, unsigned int irq) |
78 | { | 60 | { |
79 | if (WARN_ON(!base || irq == NO_IRQ)) | 61 | if (WARN_ON(!base || irq == NO_IRQ)) |
@@ -87,69 +69,6 @@ static void __init v2m_sp804_init(void __iomem *base, unsigned int irq) | |||
87 | } | 69 | } |
88 | 70 | ||
89 | 71 | ||
90 | static DEFINE_SPINLOCK(v2m_cfg_lock); | ||
91 | |||
92 | int v2m_cfg_write(u32 devfn, u32 data) | ||
93 | { | ||
94 | /* Configuration interface broken? */ | ||
95 | u32 val; | ||
96 | |||
97 | printk("%s: writing %08x to %08x\n", __func__, data, devfn); | ||
98 | |||
99 | devfn |= SYS_CFG_START | SYS_CFG_WRITE; | ||
100 | |||
101 | spin_lock(&v2m_cfg_lock); | ||
102 | val = readl(v2m_sysreg_base + V2M_SYS_CFGSTAT); | ||
103 | writel(val & ~SYS_CFG_COMPLETE, v2m_sysreg_base + V2M_SYS_CFGSTAT); | ||
104 | |||
105 | writel(data, v2m_sysreg_base + V2M_SYS_CFGDATA); | ||
106 | writel(devfn, v2m_sysreg_base + V2M_SYS_CFGCTRL); | ||
107 | |||
108 | do { | ||
109 | val = readl(v2m_sysreg_base + V2M_SYS_CFGSTAT); | ||
110 | } while (val == 0); | ||
111 | spin_unlock(&v2m_cfg_lock); | ||
112 | |||
113 | return !!(val & SYS_CFG_ERR); | ||
114 | } | ||
115 | |||
116 | int v2m_cfg_read(u32 devfn, u32 *data) | ||
117 | { | ||
118 | u32 val; | ||
119 | |||
120 | devfn |= SYS_CFG_START; | ||
121 | |||
122 | spin_lock(&v2m_cfg_lock); | ||
123 | writel(0, v2m_sysreg_base + V2M_SYS_CFGSTAT); | ||
124 | writel(devfn, v2m_sysreg_base + V2M_SYS_CFGCTRL); | ||
125 | |||
126 | mb(); | ||
127 | |||
128 | do { | ||
129 | cpu_relax(); | ||
130 | val = readl(v2m_sysreg_base + V2M_SYS_CFGSTAT); | ||
131 | } while (val == 0); | ||
132 | |||
133 | *data = readl(v2m_sysreg_base + V2M_SYS_CFGDATA); | ||
134 | spin_unlock(&v2m_cfg_lock); | ||
135 | |||
136 | return !!(val & SYS_CFG_ERR); | ||
137 | } | ||
138 | |||
139 | void __init v2m_flags_set(u32 data) | ||
140 | { | ||
141 | writel(~0, v2m_sysreg_base + V2M_SYS_FLAGSCLR); | ||
142 | writel(data, v2m_sysreg_base + V2M_SYS_FLAGSSET); | ||
143 | } | ||
144 | |||
145 | int v2m_get_master_site(void) | ||
146 | { | ||
147 | u32 misc = readl(v2m_sysreg_base + V2M_SYS_MISC); | ||
148 | |||
149 | return misc & SYS_MISC_MASTERSITE ? SYS_CFG_SITE_DB2 : SYS_CFG_SITE_DB1; | ||
150 | } | ||
151 | |||
152 | |||
153 | static struct resource v2m_pcie_i2c_resource = { | 72 | static struct resource v2m_pcie_i2c_resource = { |
154 | .start = V2M_SERIAL_BUS_PCI, | 73 | .start = V2M_SERIAL_BUS_PCI, |
155 | .end = V2M_SERIAL_BUS_PCI + SZ_4K - 1, | 74 | .end = V2M_SERIAL_BUS_PCI + SZ_4K - 1, |
@@ -237,14 +156,8 @@ static struct platform_device v2m_usb_device = { | |||
237 | .dev.platform_data = &v2m_usb_config, | 156 | .dev.platform_data = &v2m_usb_config, |
238 | }; | 157 | }; |
239 | 158 | ||
240 | static void v2m_flash_set_vpp(struct platform_device *pdev, int on) | ||
241 | { | ||
242 | writel(on != 0, v2m_sysreg_base + V2M_SYS_FLASH); | ||
243 | } | ||
244 | |||
245 | static struct physmap_flash_data v2m_flash_data = { | 159 | static struct physmap_flash_data v2m_flash_data = { |
246 | .width = 4, | 160 | .width = 4, |
247 | .set_vpp = v2m_flash_set_vpp, | ||
248 | }; | 161 | }; |
249 | 162 | ||
250 | static struct resource v2m_flash_resources[] = { | 163 | static struct resource v2m_flash_resources[] = { |
@@ -291,14 +204,61 @@ static struct platform_device v2m_cf_device = { | |||
291 | .dev.platform_data = &v2m_pata_data, | 204 | .dev.platform_data = &v2m_pata_data, |
292 | }; | 205 | }; |
293 | 206 | ||
294 | static unsigned int v2m_mmci_status(struct device *dev) | ||
295 | { | ||
296 | return readl(v2m_sysreg_base + V2M_SYS_MCI) & (1 << 0); | ||
297 | } | ||
298 | |||
299 | static struct mmci_platform_data v2m_mmci_data = { | 207 | static struct mmci_platform_data v2m_mmci_data = { |
300 | .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, | 208 | .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, |
301 | .status = v2m_mmci_status, | 209 | .gpio_wp = VEXPRESS_GPIO_MMC_WPROT, |
210 | .gpio_cd = VEXPRESS_GPIO_MMC_CARDIN, | ||
211 | }; | ||
212 | |||
213 | static struct resource v2m_sysreg_resources[] = { | ||
214 | { | ||
215 | .start = V2M_SYSREGS, | ||
216 | .end = V2M_SYSREGS + 0xfff, | ||
217 | .flags = IORESOURCE_MEM, | ||
218 | }, | ||
219 | }; | ||
220 | |||
221 | static struct platform_device v2m_sysreg_device = { | ||
222 | .name = "vexpress-sysreg", | ||
223 | .id = -1, | ||
224 | .resource = v2m_sysreg_resources, | ||
225 | .num_resources = ARRAY_SIZE(v2m_sysreg_resources), | ||
226 | }; | ||
227 | |||
228 | static struct platform_device v2m_muxfpga_device = { | ||
229 | .name = "vexpress-muxfpga", | ||
230 | .id = 0, | ||
231 | .num_resources = 1, | ||
232 | .resource = (struct resource []) { | ||
233 | VEXPRESS_RES_FUNC(0, 7), | ||
234 | } | ||
235 | }; | ||
236 | |||
237 | static struct platform_device v2m_shutdown_device = { | ||
238 | .name = "vexpress-shutdown", | ||
239 | .id = 0, | ||
240 | .num_resources = 1, | ||
241 | .resource = (struct resource []) { | ||
242 | VEXPRESS_RES_FUNC(0, 8), | ||
243 | } | ||
244 | }; | ||
245 | |||
246 | static struct platform_device v2m_reboot_device = { | ||
247 | .name = "vexpress-reboot", | ||
248 | .id = 0, | ||
249 | .num_resources = 1, | ||
250 | .resource = (struct resource []) { | ||
251 | VEXPRESS_RES_FUNC(0, 9), | ||
252 | } | ||
253 | }; | ||
254 | |||
255 | static struct platform_device v2m_dvimode_device = { | ||
256 | .name = "vexpress-dvimode", | ||
257 | .id = 0, | ||
258 | .num_resources = 1, | ||
259 | .resource = (struct resource []) { | ||
260 | VEXPRESS_RES_FUNC(0, 11), | ||
261 | } | ||
302 | }; | 262 | }; |
303 | 263 | ||
304 | static AMBA_APB_DEVICE(aaci, "mb:aaci", 0, V2M_AACI, IRQ_V2M_AACI, NULL); | 264 | static AMBA_APB_DEVICE(aaci, "mb:aaci", 0, V2M_AACI, IRQ_V2M_AACI, NULL); |
@@ -325,123 +285,9 @@ static struct amba_device *v2m_amba_devs[] __initdata = { | |||
325 | &rtc_device, | 285 | &rtc_device, |
326 | }; | 286 | }; |
327 | 287 | ||
328 | |||
329 | static unsigned long v2m_osc_recalc_rate(struct clk_hw *hw, | ||
330 | unsigned long parent_rate) | ||
331 | { | ||
332 | struct v2m_osc *osc = to_v2m_osc(hw); | ||
333 | |||
334 | return !parent_rate ? osc->rate_default : parent_rate; | ||
335 | } | ||
336 | |||
337 | static long v2m_osc_round_rate(struct clk_hw *hw, unsigned long rate, | ||
338 | unsigned long *parent_rate) | ||
339 | { | ||
340 | struct v2m_osc *osc = to_v2m_osc(hw); | ||
341 | |||
342 | if (WARN_ON(rate < osc->rate_min)) | ||
343 | rate = osc->rate_min; | ||
344 | |||
345 | if (WARN_ON(rate > osc->rate_max)) | ||
346 | rate = osc->rate_max; | ||
347 | |||
348 | return rate; | ||
349 | } | ||
350 | |||
351 | static int v2m_osc_set_rate(struct clk_hw *hw, unsigned long rate, | ||
352 | unsigned long parent_rate) | ||
353 | { | ||
354 | struct v2m_osc *osc = to_v2m_osc(hw); | ||
355 | |||
356 | v2m_cfg_write(SYS_CFG_OSC | SYS_CFG_SITE(osc->site) | | ||
357 | SYS_CFG_STACK(osc->stack) | osc->osc, rate); | ||
358 | |||
359 | return 0; | ||
360 | } | ||
361 | |||
362 | static struct clk_ops v2m_osc_ops = { | ||
363 | .recalc_rate = v2m_osc_recalc_rate, | ||
364 | .round_rate = v2m_osc_round_rate, | ||
365 | .set_rate = v2m_osc_set_rate, | ||
366 | }; | ||
367 | |||
368 | struct clk * __init v2m_osc_register(const char *name, struct v2m_osc *osc) | ||
369 | { | ||
370 | struct clk_init_data init; | ||
371 | |||
372 | WARN_ON(osc->site > 2); | ||
373 | WARN_ON(osc->stack > 15); | ||
374 | WARN_ON(osc->osc > 4095); | ||
375 | |||
376 | init.name = name; | ||
377 | init.ops = &v2m_osc_ops; | ||
378 | init.flags = CLK_IS_ROOT; | ||
379 | init.num_parents = 0; | ||
380 | |||
381 | osc->hw.init = &init; | ||
382 | |||
383 | return clk_register(NULL, &osc->hw); | ||
384 | } | ||
385 | |||
386 | static struct v2m_osc v2m_mb_osc1 = { | ||
387 | .site = SYS_CFG_SITE_MB, | ||
388 | .osc = 1, | ||
389 | .rate_min = 23750000, | ||
390 | .rate_max = 63500000, | ||
391 | .rate_default = 23750000, | ||
392 | }; | ||
393 | |||
394 | static const char *v2m_ref_clk_periphs[] __initconst = { | ||
395 | "mb:wdt", "1000f000.wdt", "1c0f0000.wdt", /* SP805 WDT */ | ||
396 | }; | ||
397 | |||
398 | static const char *v2m_osc1_periphs[] __initconst = { | ||
399 | "mb:clcd", "1001f000.clcd", "1c1f0000.clcd", /* PL111 CLCD */ | ||
400 | }; | ||
401 | |||
402 | static const char *v2m_osc2_periphs[] __initconst = { | ||
403 | "mb:mmci", "10005000.mmci", "1c050000.mmci", /* PL180 MMCI */ | ||
404 | "mb:kmi0", "10006000.kmi", "1c060000.kmi", /* PL050 KMI0 */ | ||
405 | "mb:kmi1", "10007000.kmi", "1c070000.kmi", /* PL050 KMI1 */ | ||
406 | "mb:uart0", "10009000.uart", "1c090000.uart", /* PL011 UART0 */ | ||
407 | "mb:uart1", "1000a000.uart", "1c0a0000.uart", /* PL011 UART1 */ | ||
408 | "mb:uart2", "1000b000.uart", "1c0b0000.uart", /* PL011 UART2 */ | ||
409 | "mb:uart3", "1000c000.uart", "1c0c0000.uart", /* PL011 UART3 */ | ||
410 | }; | ||
411 | |||
412 | static void __init v2m_clk_init(void) | ||
413 | { | ||
414 | struct clk *clk; | ||
415 | int i; | ||
416 | |||
417 | clk = clk_register_fixed_rate(NULL, "dummy_apb_pclk", NULL, | ||
418 | CLK_IS_ROOT, 0); | ||
419 | WARN_ON(clk_register_clkdev(clk, "apb_pclk", NULL)); | ||
420 | |||
421 | clk = clk_register_fixed_rate(NULL, "mb:ref_clk", NULL, | ||
422 | CLK_IS_ROOT, 32768); | ||
423 | for (i = 0; i < ARRAY_SIZE(v2m_ref_clk_periphs); i++) | ||
424 | WARN_ON(clk_register_clkdev(clk, NULL, v2m_ref_clk_periphs[i])); | ||
425 | |||
426 | clk = clk_register_fixed_rate(NULL, "mb:sp804_clk", NULL, | ||
427 | CLK_IS_ROOT, 1000000); | ||
428 | WARN_ON(clk_register_clkdev(clk, "v2m-timer0", "sp804")); | ||
429 | WARN_ON(clk_register_clkdev(clk, "v2m-timer1", "sp804")); | ||
430 | |||
431 | clk = v2m_osc_register("mb:osc1", &v2m_mb_osc1); | ||
432 | for (i = 0; i < ARRAY_SIZE(v2m_osc1_periphs); i++) | ||
433 | WARN_ON(clk_register_clkdev(clk, NULL, v2m_osc1_periphs[i])); | ||
434 | |||
435 | clk = clk_register_fixed_rate(NULL, "mb:osc2", NULL, | ||
436 | CLK_IS_ROOT, 24000000); | ||
437 | for (i = 0; i < ARRAY_SIZE(v2m_osc2_periphs); i++) | ||
438 | WARN_ON(clk_register_clkdev(clk, NULL, v2m_osc2_periphs[i])); | ||
439 | } | ||
440 | |||
441 | static void __init v2m_timer_init(void) | 288 | static void __init v2m_timer_init(void) |
442 | { | 289 | { |
443 | v2m_sysctl_init(ioremap(V2M_SYSCTL, SZ_4K)); | 290 | vexpress_clk_init(ioremap(V2M_SYSCTL, SZ_4K)); |
444 | v2m_clk_init(); | ||
445 | v2m_sp804_init(ioremap(V2M_TIMER01, SZ_4K), IRQ_V2M_TIMER0); | 291 | v2m_sp804_init(ioremap(V2M_TIMER01, SZ_4K), IRQ_V2M_TIMER0); |
446 | } | 292 | } |
447 | 293 | ||
@@ -453,19 +299,7 @@ static void __init v2m_init_early(void) | |||
453 | { | 299 | { |
454 | if (ct_desc->init_early) | 300 | if (ct_desc->init_early) |
455 | ct_desc->init_early(); | 301 | ct_desc->init_early(); |
456 | versatile_sched_clock_init(v2m_sysreg_base + V2M_SYS_24MHZ, 24000000); | 302 | versatile_sched_clock_init(vexpress_get_24mhz_clock_base(), 24000000); |
457 | } | ||
458 | |||
459 | static void v2m_power_off(void) | ||
460 | { | ||
461 | if (v2m_cfg_write(SYS_CFG_SHUTDOWN | SYS_CFG_SITE(SYS_CFG_SITE_MB), 0)) | ||
462 | printk(KERN_EMERG "Unable to shutdown\n"); | ||
463 | } | ||
464 | |||
465 | static void v2m_restart(char str, const char *cmd) | ||
466 | { | ||
467 | if (v2m_cfg_write(SYS_CFG_REBOOT | SYS_CFG_SITE(SYS_CFG_SITE_MB), 0)) | ||
468 | printk(KERN_EMERG "Unable to reboot\n"); | ||
469 | } | 303 | } |
470 | 304 | ||
471 | struct ct_desc *ct_desc; | 305 | struct ct_desc *ct_desc; |
@@ -482,7 +316,7 @@ static void __init v2m_populate_ct_desc(void) | |||
482 | u32 current_tile_id; | 316 | u32 current_tile_id; |
483 | 317 | ||
484 | ct_desc = NULL; | 318 | ct_desc = NULL; |
485 | current_tile_id = readl(v2m_sysreg_base + V2M_SYS_PROCID0) | 319 | current_tile_id = vexpress_get_procid(VEXPRESS_SITE_MASTER) |
486 | & V2M_CT_ID_MASK; | 320 | & V2M_CT_ID_MASK; |
487 | 321 | ||
488 | for (i = 0; i < ARRAY_SIZE(ct_descs) && !ct_desc; ++i) | 322 | for (i = 0; i < ARRAY_SIZE(ct_descs) && !ct_desc; ++i) |
@@ -498,7 +332,7 @@ static void __init v2m_populate_ct_desc(void) | |||
498 | static void __init v2m_map_io(void) | 332 | static void __init v2m_map_io(void) |
499 | { | 333 | { |
500 | iotable_init(v2m_io_desc, ARRAY_SIZE(v2m_io_desc)); | 334 | iotable_init(v2m_io_desc, ARRAY_SIZE(v2m_io_desc)); |
501 | v2m_sysreg_base = ioremap(V2M_SYSREGS, SZ_4K); | 335 | vexpress_sysreg_early_init(ioremap(V2M_SYSREGS, SZ_4K)); |
502 | v2m_populate_ct_desc(); | 336 | v2m_populate_ct_desc(); |
503 | ct_desc->map_io(); | 337 | ct_desc->map_io(); |
504 | } | 338 | } |
@@ -515,6 +349,12 @@ static void __init v2m_init(void) | |||
515 | regulator_register_fixed(0, v2m_eth_supplies, | 349 | regulator_register_fixed(0, v2m_eth_supplies, |
516 | ARRAY_SIZE(v2m_eth_supplies)); | 350 | ARRAY_SIZE(v2m_eth_supplies)); |
517 | 351 | ||
352 | platform_device_register(&v2m_muxfpga_device); | ||
353 | platform_device_register(&v2m_shutdown_device); | ||
354 | platform_device_register(&v2m_reboot_device); | ||
355 | platform_device_register(&v2m_dvimode_device); | ||
356 | |||
357 | platform_device_register(&v2m_sysreg_device); | ||
518 | platform_device_register(&v2m_pcie_i2c_device); | 358 | platform_device_register(&v2m_pcie_i2c_device); |
519 | platform_device_register(&v2m_ddc_i2c_device); | 359 | platform_device_register(&v2m_ddc_i2c_device); |
520 | platform_device_register(&v2m_flash_device); | 360 | platform_device_register(&v2m_flash_device); |
@@ -525,7 +365,7 @@ static void __init v2m_init(void) | |||
525 | for (i = 0; i < ARRAY_SIZE(v2m_amba_devs); i++) | 365 | for (i = 0; i < ARRAY_SIZE(v2m_amba_devs); i++) |
526 | amba_device_register(v2m_amba_devs[i], &iomem_resource); | 366 | amba_device_register(v2m_amba_devs[i], &iomem_resource); |
527 | 367 | ||
528 | pm_power_off = v2m_power_off; | 368 | pm_power_off = vexpress_power_off; |
529 | 369 | ||
530 | ct_desc->init_tile(); | 370 | ct_desc->init_tile(); |
531 | } | 371 | } |
@@ -539,7 +379,7 @@ MACHINE_START(VEXPRESS, "ARM-Versatile Express") | |||
539 | .timer = &v2m_timer, | 379 | .timer = &v2m_timer, |
540 | .handle_irq = gic_handle_irq, | 380 | .handle_irq = gic_handle_irq, |
541 | .init_machine = v2m_init, | 381 | .init_machine = v2m_init, |
542 | .restart = v2m_restart, | 382 | .restart = vexpress_restart, |
543 | MACHINE_END | 383 | MACHINE_END |
544 | 384 | ||
545 | static struct map_desc v2m_rs1_io_desc __initdata = { | 385 | static struct map_desc v2m_rs1_io_desc __initdata = { |
@@ -580,20 +420,13 @@ void __init v2m_dt_map_io(void) | |||
580 | 420 | ||
581 | void __init v2m_dt_init_early(void) | 421 | void __init v2m_dt_init_early(void) |
582 | { | 422 | { |
583 | struct device_node *node; | ||
584 | u32 dt_hbi; | 423 | u32 dt_hbi; |
585 | 424 | ||
586 | node = of_find_compatible_node(NULL, NULL, "arm,vexpress-sysreg"); | 425 | vexpress_sysreg_of_early_init(); |
587 | v2m_sysreg_base = of_iomap(node, 0); | ||
588 | if (WARN_ON(!v2m_sysreg_base)) | ||
589 | return; | ||
590 | 426 | ||
591 | /* Confirm board type against DT property, if available */ | 427 | /* Confirm board type against DT property, if available */ |
592 | if (of_property_read_u32(allnodes, "arm,hbi", &dt_hbi) == 0) { | 428 | if (of_property_read_u32(allnodes, "arm,hbi", &dt_hbi) == 0) { |
593 | int site = v2m_get_master_site(); | 429 | u32 hbi = vexpress_get_hbi(VEXPRESS_SITE_MASTER); |
594 | u32 id = readl(v2m_sysreg_base + (site == SYS_CFG_SITE_DB2 ? | ||
595 | V2M_SYS_PROCID1 : V2M_SYS_PROCID0)); | ||
596 | u32 hbi = id & SYS_PROCIDx_HBI_MASK; | ||
597 | 430 | ||
598 | if (WARN_ON(dt_hbi != hbi)) | 431 | if (WARN_ON(dt_hbi != hbi)) |
599 | pr_warning("vexpress: DT HBI (%x) is not matching " | 432 | pr_warning("vexpress: DT HBI (%x) is not matching " |
@@ -617,10 +450,7 @@ static void __init v2m_dt_timer_init(void) | |||
617 | const char *path; | 450 | const char *path; |
618 | int err; | 451 | int err; |
619 | 452 | ||
620 | node = of_find_compatible_node(NULL, NULL, "arm,sp810"); | 453 | vexpress_clk_of_init(); |
621 | v2m_sysctl_init(of_iomap(node, 0)); | ||
622 | |||
623 | v2m_clk_init(); | ||
624 | 454 | ||
625 | err = of_property_read_string(of_aliases, "arm,v2m_timer", &path); | 455 | err = of_property_read_string(of_aliases, "arm,v2m_timer", &path); |
626 | if (WARN_ON(err)) | 456 | if (WARN_ON(err)) |
@@ -631,33 +461,29 @@ static void __init v2m_dt_timer_init(void) | |||
631 | twd_local_timer_of_register(); | 461 | twd_local_timer_of_register(); |
632 | 462 | ||
633 | if (arch_timer_sched_clock_init() != 0) | 463 | if (arch_timer_sched_clock_init() != 0) |
634 | versatile_sched_clock_init(v2m_sysreg_base + V2M_SYS_24MHZ, 24000000); | 464 | versatile_sched_clock_init(vexpress_get_24mhz_clock_base(), |
465 | 24000000); | ||
635 | } | 466 | } |
636 | 467 | ||
637 | static struct sys_timer v2m_dt_timer = { | 468 | static struct sys_timer v2m_dt_timer = { |
638 | .init = v2m_dt_timer_init, | 469 | .init = v2m_dt_timer_init, |
639 | }; | 470 | }; |
640 | 471 | ||
641 | static struct of_dev_auxdata v2m_dt_auxdata_lookup[] __initdata = { | 472 | static const struct of_device_id v2m_dt_bus_match[] __initconst = { |
642 | OF_DEV_AUXDATA("arm,vexpress-flash", V2M_NOR0, "physmap-flash", | 473 | { .compatible = "simple-bus", }, |
643 | &v2m_flash_data), | 474 | { .compatible = "arm,amba-bus", }, |
644 | OF_DEV_AUXDATA("arm,primecell", V2M_MMCI, "mb:mmci", &v2m_mmci_data), | 475 | { .compatible = "arm,vexpress,config-bus", }, |
645 | /* RS1 memory map */ | ||
646 | OF_DEV_AUXDATA("arm,vexpress-flash", 0x08000000, "physmap-flash", | ||
647 | &v2m_flash_data), | ||
648 | OF_DEV_AUXDATA("arm,primecell", 0x1c050000, "mb:mmci", &v2m_mmci_data), | ||
649 | {} | 476 | {} |
650 | }; | 477 | }; |
651 | 478 | ||
652 | static void __init v2m_dt_init(void) | 479 | static void __init v2m_dt_init(void) |
653 | { | 480 | { |
654 | l2x0_of_init(0x00400000, 0xfe0fffff); | 481 | l2x0_of_init(0x00400000, 0xfe0fffff); |
655 | of_platform_populate(NULL, of_default_bus_match_table, | 482 | of_platform_populate(NULL, v2m_dt_bus_match, NULL, NULL); |
656 | v2m_dt_auxdata_lookup, NULL); | 483 | pm_power_off = vexpress_power_off; |
657 | pm_power_off = v2m_power_off; | ||
658 | } | 484 | } |
659 | 485 | ||
660 | const static char *v2m_dt_match[] __initconst = { | 486 | static const char * const v2m_dt_match[] __initconst = { |
661 | "arm,vexpress", | 487 | "arm,vexpress", |
662 | "xen,xenvm", | 488 | "xen,xenvm", |
663 | NULL, | 489 | NULL, |
@@ -672,5 +498,5 @@ DT_MACHINE_START(VEXPRESS_DT, "ARM-Versatile Express") | |||
672 | .timer = &v2m_dt_timer, | 498 | .timer = &v2m_dt_timer, |
673 | .init_machine = v2m_dt_init, | 499 | .init_machine = v2m_dt_init, |
674 | .handle_irq = gic_handle_irq, | 500 | .handle_irq = gic_handle_irq, |
675 | .restart = v2m_restart, | 501 | .restart = vexpress_restart, |
676 | MACHINE_END | 502 | MACHINE_END |