Merge branch 'vexpress-v3.5-rc6' of git://git.linaro.org/people/pawelmoll/linux into next/soc

From Pawel Moll <pawel.moll@arm.com>:

Versatile Express updates for v3.6

* 'vexpress-v3.5-rc6' of git://git.linaro.org/people/pawelmoll/linux:
  ARM: vexpress: Config option for early printk console
  ARM: vexpress: Add Device Tree for V2P-CA15_CA7 core tile
  ARM: vexpress: Convert V2P-CA15 Device Tree to 64 bit addresses
  ARM: vexpress: Add fixed regulator for SMSC
  ARM: vexpress: Add missing SP804 interrupt in motherboard's DTS files
  ARM: vexpress: Initial common clock support
  ARM: versatile: Make plat-versatile clock optional
  ARM: vexpress: Check master site in daughterboard's sysctl operations
  ARM: vexpress: remove automatic errata workaround selection

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
This commit is contained in:
Arnd Bergmann 2012-07-13 18:46:58 +02:00
commit ff60914362
16 changed files with 495 additions and 232 deletions

View File

@ -260,6 +260,7 @@ config ARCH_INTEGRATOR
select ICST
select GENERIC_CLOCKEVENTS
select PLAT_VERSATILE
select PLAT_VERSATILE_CLOCK
select PLAT_VERSATILE_FPGA_IRQ
select NEED_MACH_IO_H
select NEED_MACH_MEMORY_H
@ -277,6 +278,7 @@ config ARCH_REALVIEW
select GENERIC_CLOCKEVENTS
select ARCH_WANT_OPTIONAL_GPIOLIB
select PLAT_VERSATILE
select PLAT_VERSATILE_CLOCK
select PLAT_VERSATILE_CLCD
select ARM_TIMER_SP804
select GPIO_PL061 if GPIOLIB
@ -295,6 +297,7 @@ config ARCH_VERSATILE
select ARCH_WANT_OPTIONAL_GPIOLIB
select NEED_MACH_IO_H if PCI
select PLAT_VERSATILE
select PLAT_VERSATILE_CLOCK
select PLAT_VERSATILE_CLCD
select PLAT_VERSATILE_FPGA_IRQ
select ARM_TIMER_SP804
@ -307,7 +310,7 @@ config ARCH_VEXPRESS
select ARM_AMBA
select ARM_TIMER_SP804
select CLKDEV_LOOKUP
select HAVE_MACH_CLKDEV
select COMMON_CLK
select GENERIC_CLOCKEVENTS
select HAVE_CLK
select HAVE_PATA_PLATFORM
@ -315,6 +318,7 @@ config ARCH_VEXPRESS
select NO_IOPORT
select PLAT_VERSATILE
select PLAT_VERSATILE_CLCD
select REGULATOR_FIXED_VOLTAGE if REGULATOR
help
This enables support for the ARM Ltd Versatile Express boards.

View File

@ -310,6 +310,32 @@ choice
The uncompressor code port configuration is now handled
by CONFIG_S3C_LOWLEVEL_UART_PORT.
config DEBUG_VEXPRESS_UART0_DETECT
bool "Autodetect UART0 on Versatile Express Cortex-A core tiles"
depends on ARCH_VEXPRESS && CPU_CP15_MMU
help
This option enables a simple heuristic which tries to determine
the motherboard's memory map variant (original or RS1) and then
choose the relevant UART0 base address.
Note that this will only work with standard A-class core tiles,
and may fail with non-standard SMM or custom software models.
config DEBUG_VEXPRESS_UART0_CA9
bool "Use PL011 UART0 at 0x10009000 (V2P-CA9 core tile)"
depends on ARCH_VEXPRESS
help
This option selects UART0 at 0x10009000. Except for custom models,
this applies only to the V2P-CA9 tile.
config DEBUG_VEXPRESS_UART0_RS1
bool "Use PL011 UART0 at 0x1c090000 (RS1 complaint tiles)"
depends on ARCH_VEXPRESS
help
This option selects UART0 at 0x1c090000. This applies to most
of the tiles using the RS1 memory map, including all new A-class
core tiles, FPGA-based SMMs and software models.
config DEBUG_LL_UART_NONE
bool "No low-level debugging UART"
help

View File

@ -55,6 +55,8 @@
reg-io-width = <4>;
smsc,irq-active-high;
smsc,irq-push-pull;
vdd33a-supply = <&v2m_fixed_3v3>;
vddvario-supply = <&v2m_fixed_3v3>;
};
usb@2,03000000 {
@ -157,6 +159,7 @@
v2m_timer23: timer@120000 {
compatible = "arm,sp804", "arm,primecell";
reg = <0x120000 0x1000>;
interrupts = <3>;
};
/* DVI I2C bus */
@ -197,5 +200,13 @@
interrupts = <14>;
};
};
v2m_fixed_3v3: fixedregulator@0 {
compatible = "regulator-fixed";
regulator-name = "3V3";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-always-on;
};
};
};

View File

@ -54,6 +54,8 @@
reg-io-width = <4>;
smsc,irq-active-high;
smsc,irq-push-pull;
vdd33a-supply = <&v2m_fixed_3v3>;
vddvario-supply = <&v2m_fixed_3v3>;
};
usb@3,03000000 {
@ -156,6 +158,7 @@
v2m_timer23: timer@12000 {
compatible = "arm,sp804", "arm,primecell";
reg = <0x12000 0x1000>;
interrupts = <3>;
};
/* DVI I2C bus */
@ -196,5 +199,13 @@
interrupts = <14>;
};
};
v2m_fixed_3v3: fixedregulator@0 {
compatible = "regulator-fixed";
regulator-name = "3V3";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-always-on;
};
};
};

View File

@ -14,8 +14,8 @@
arm,hbi = <0x237>;
compatible = "arm,vexpress,v2p-ca15,tc1", "arm,vexpress,v2p-ca15", "arm,vexpress";
interrupt-parent = <&gic>;
#address-cells = <1>;
#size-cells = <1>;
#address-cells = <2>;
#size-cells = <2>;
chosen { };
@ -47,23 +47,23 @@
memory@80000000 {
device_type = "memory";
reg = <0x80000000 0x40000000>;
reg = <0 0x80000000 0 0x40000000>;
};
hdlcd@2b000000 {
compatible = "arm,hdlcd";
reg = <0x2b000000 0x1000>;
reg = <0 0x2b000000 0 0x1000>;
interrupts = <0 85 4>;
};
memory-controller@2b0a0000 {
compatible = "arm,pl341", "arm,primecell";
reg = <0x2b0a0000 0x1000>;
reg = <0 0x2b0a0000 0 0x1000>;
};
wdt@2b060000 {
compatible = "arm,sp805", "arm,primecell";
reg = <0x2b060000 0x1000>;
reg = <0 0x2b060000 0 0x1000>;
interrupts = <98>;
};
@ -72,23 +72,23 @@
#interrupt-cells = <3>;
#address-cells = <0>;
interrupt-controller;
reg = <0x2c001000 0x1000>,
<0x2c002000 0x1000>,
<0x2c004000 0x2000>,
<0x2c006000 0x2000>;
reg = <0 0x2c001000 0 0x1000>,
<0 0x2c002000 0 0x1000>,
<0 0x2c004000 0 0x2000>,
<0 0x2c006000 0 0x2000>;
interrupts = <1 9 0xf04>;
};
memory-controller@7ffd0000 {
compatible = "arm,pl354", "arm,primecell";
reg = <0x7ffd0000 0x1000>;
reg = <0 0x7ffd0000 0 0x1000>;
interrupts = <0 86 4>,
<0 87 4>;
};
dma@7ffb0000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x7ffb0000 0x1000>;
reg = <0 0x7ffb0000 0 0x1000>;
interrupts = <0 92 4>,
<0 88 4>,
<0 89 4>,
@ -111,12 +111,12 @@
};
motherboard {
ranges = <0 0 0x08000000 0x04000000>,
<1 0 0x14000000 0x04000000>,
<2 0 0x18000000 0x04000000>,
<3 0 0x1c000000 0x04000000>,
<4 0 0x0c000000 0x04000000>,
<5 0 0x10000000 0x04000000>;
ranges = <0 0 0 0x08000000 0x04000000>,
<1 0 0 0x14000000 0x04000000>,
<2 0 0 0x18000000 0x04000000>,
<3 0 0 0x1c000000 0x04000000>,
<4 0 0 0x0c000000 0x04000000>,
<5 0 0 0x10000000 0x04000000>;
interrupt-map-mask = <0 0 63>;
interrupt-map = <0 0 0 &gic 0 0 4>,

View File

@ -0,0 +1,188 @@
/*
* ARM Ltd. Versatile Express
*
* CoreTile Express A15x2 A7x3
* Cortex-A15_A7 MPCore (V2P-CA15_A7)
*
* HBI-0249A
*/
/dts-v1/;
/ {
model = "V2P-CA15_CA7";
arm,hbi = <0x249>;
compatible = "arm,vexpress,v2p-ca15_a7", "arm,vexpress";
interrupt-parent = <&gic>;
#address-cells = <2>;
#size-cells = <2>;
chosen { };
aliases {
serial0 = &v2m_serial0;
serial1 = &v2m_serial1;
serial2 = &v2m_serial2;
serial3 = &v2m_serial3;
i2c0 = &v2m_i2c_dvi;
i2c1 = &v2m_i2c_pcie;
};
cpus {
#address-cells = <1>;
#size-cells = <0>;
cpu0: cpu@0 {
device_type = "cpu";
compatible = "arm,cortex-a15";
reg = <0>;
};
cpu1: cpu@1 {
device_type = "cpu";
compatible = "arm,cortex-a15";
reg = <1>;
};
/* A7s disabled till big.LITTLE patches are available...
cpu2: cpu@2 {
device_type = "cpu";
compatible = "arm,cortex-a7";
reg = <0x100>;
};
cpu3: cpu@3 {
device_type = "cpu";
compatible = "arm,cortex-a7";
reg = <0x101>;
};
cpu4: cpu@4 {
device_type = "cpu";
compatible = "arm,cortex-a7";
reg = <0x102>;
};
*/
};
memory@80000000 {
device_type = "memory";
reg = <0 0x80000000 0 0x40000000>;
};
wdt@2a490000 {
compatible = "arm,sp805", "arm,primecell";
reg = <0 0x2a490000 0 0x1000>;
interrupts = <98>;
};
hdlcd@2b000000 {
compatible = "arm,hdlcd";
reg = <0 0x2b000000 0 0x1000>;
interrupts = <0 85 4>;
};
memory-controller@2b0a0000 {
compatible = "arm,pl341", "arm,primecell";
reg = <0 0x2b0a0000 0 0x1000>;
};
gic: interrupt-controller@2c001000 {
compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic";
#interrupt-cells = <3>;
#address-cells = <0>;
interrupt-controller;
reg = <0 0x2c001000 0 0x1000>,
<0 0x2c002000 0 0x1000>,
<0 0x2c004000 0 0x2000>,
<0 0x2c006000 0 0x2000>;
interrupts = <1 9 0xf04>;
};
memory-controller@7ffd0000 {
compatible = "arm,pl354", "arm,primecell";
reg = <0 0x7ffd0000 0 0x1000>;
interrupts = <0 86 4>,
<0 87 4>;
};
dma@7ff00000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0 0x7ff00000 0 0x1000>;
interrupts = <0 92 4>,
<0 88 4>,
<0 89 4>,
<0 90 4>,
<0 91 4>;
};
timer {
compatible = "arm,armv7-timer";
interrupts = <1 13 0xf08>,
<1 14 0xf08>,
<1 11 0xf08>,
<1 10 0xf08>;
};
pmu {
compatible = "arm,cortex-a15-pmu", "arm,cortex-a9-pmu";
interrupts = <0 68 4>,
<0 69 4>;
};
motherboard {
ranges = <0 0 0 0x08000000 0x04000000>,
<1 0 0 0x14000000 0x04000000>,
<2 0 0 0x18000000 0x04000000>,
<3 0 0 0x1c000000 0x04000000>,
<4 0 0 0x0c000000 0x04000000>,
<5 0 0 0x10000000 0x04000000>;
interrupt-map-mask = <0 0 63>;
interrupt-map = <0 0 0 &gic 0 0 4>,
<0 0 1 &gic 0 1 4>,
<0 0 2 &gic 0 2 4>,
<0 0 3 &gic 0 3 4>,
<0 0 4 &gic 0 4 4>,
<0 0 5 &gic 0 5 4>,
<0 0 6 &gic 0 6 4>,
<0 0 7 &gic 0 7 4>,
<0 0 8 &gic 0 8 4>,
<0 0 9 &gic 0 9 4>,
<0 0 10 &gic 0 10 4>,
<0 0 11 &gic 0 11 4>,
<0 0 12 &gic 0 12 4>,
<0 0 13 &gic 0 13 4>,
<0 0 14 &gic 0 14 4>,
<0 0 15 &gic 0 15 4>,
<0 0 16 &gic 0 16 4>,
<0 0 17 &gic 0 17 4>,
<0 0 18 &gic 0 18 4>,
<0 0 19 &gic 0 19 4>,
<0 0 20 &gic 0 20 4>,
<0 0 21 &gic 0 21 4>,
<0 0 22 &gic 0 22 4>,
<0 0 23 &gic 0 23 4>,
<0 0 24 &gic 0 24 4>,
<0 0 25 &gic 0 25 4>,
<0 0 26 &gic 0 26 4>,
<0 0 27 &gic 0 27 4>,
<0 0 28 &gic 0 28 4>,
<0 0 29 &gic 0 29 4>,
<0 0 30 &gic 0 30 4>,
<0 0 31 &gic 0 31 4>,
<0 0 32 &gic 0 32 4>,
<0 0 33 &gic 0 33 4>,
<0 0 34 &gic 0 34 4>,
<0 0 35 &gic 0 35 4>,
<0 0 36 &gic 0 36 4>,
<0 0 37 &gic 0 37 4>,
<0 0 38 &gic 0 38 4>,
<0 0 39 &gic 0 39 4>,
<0 0 40 &gic 0 40 4>,
<0 0 41 &gic 0 41 4>,
<0 0 42 &gic 0 42 4>;
};
};
/include/ "vexpress-v2m-rs1.dtsi"

View File

@ -2,7 +2,8 @@ menu "Versatile Express platform type"
depends on ARCH_VEXPRESS
config ARCH_VEXPRESS_CORTEX_A5_A9_ERRATA
bool
bool "Enable A5 and A9 only errata work-arounds"
default y
select ARM_ERRATA_720789
select ARM_ERRATA_751472
select PL310_ERRATA_753970 if CACHE_PL310
@ -14,7 +15,6 @@ config ARCH_VEXPRESS_CORTEX_A5_A9_ERRATA
config ARCH_VEXPRESS_CA9X4
bool "Versatile Express Cortex-A9x4 tile"
select ARCH_VEXPRESS_CORTEX_A5_A9_ERRATA
select ARM_GIC
select CPU_V7
select HAVE_SMP
@ -22,7 +22,6 @@ config ARCH_VEXPRESS_CA9X4
config ARCH_VEXPRESS_DT
bool "Device Tree support for Versatile Express platforms"
select ARCH_VEXPRESS_CORTEX_A5_A9_ERRATA
select ARM_GIC
select ARM_PATCH_PHYS_VIRT
select AUTO_ZRELADDR

View File

@ -6,4 +6,5 @@ initrd_phys-y := 0x60800000
dtb-$(CONFIG_ARCH_VEXPRESS_DT) += vexpress-v2p-ca5s.dtb \
vexpress-v2p-ca9.dtb \
vexpress-v2p-ca15-tc1.dtb
vexpress-v2p-ca15-tc1.dtb \
vexpress-v2p-ca15_a7.dtb

View File

@ -66,8 +66,15 @@ static void __init ct_ca9x4_init_irq(void)
static void ct_ca9x4_clcd_enable(struct clcd_fb *fb)
{
v2m_cfg_write(SYS_CFG_MUXFPGA | SYS_CFG_SITE_DB1, 0);
v2m_cfg_write(SYS_CFG_DVIMODE | SYS_CFG_SITE_DB1, 2);
u32 site = v2m_get_master_site();
/*
* Old firmware was using the "site" component of the command
* to control the DVI muxer (while it should be always 0 ie. MB).
* Newer firmware uses the data register. Keep both for compatibility.
*/
v2m_cfg_write(SYS_CFG_MUXFPGA | SYS_CFG_SITE(site), site);
v2m_cfg_write(SYS_CFG_DVIMODE | SYS_CFG_SITE(SYS_CFG_SITE_MB), 2);
}
static int ct_ca9x4_clcd_setup(struct clcd_fb *fb)
@ -105,43 +112,11 @@ static struct amba_device *ct_ca9x4_amba_devs[] __initdata = {
};
static long ct_round(struct clk *clk, unsigned long rate)
{
return rate;
}
static int ct_set(struct clk *clk, unsigned long rate)
{
return v2m_cfg_write(SYS_CFG_OSC | SYS_CFG_SITE_DB1 | 1, rate);
}
static const struct clk_ops osc1_clk_ops = {
.round = ct_round,
.set = ct_set,
};
static struct clk osc1_clk = {
.ops = &osc1_clk_ops,
.rate = 24000000,
};
static struct clk ct_sp804_clk = {
.rate = 1000000,
};
static struct clk_lookup lookups[] = {
{ /* CLCD */
.dev_id = "ct:clcd",
.clk = &osc1_clk,
}, { /* SP804 timers */
.dev_id = "sp804",
.con_id = "ct-timer0",
.clk = &ct_sp804_clk,
}, { /* SP804 timers */
.dev_id = "sp804",
.con_id = "ct-timer1",
.clk = &ct_sp804_clk,
},
static struct v2m_osc ct_osc1 = {
.osc = 1,
.rate_min = 10000000,
.rate_max = 80000000,
.rate_default = 23750000,
};
static struct resource pmu_resources[] = {
@ -174,14 +149,10 @@ static struct platform_device pmu_device = {
.resource = pmu_resources,
};
static void __init ct_ca9x4_init_early(void)
{
clkdev_add_table(lookups, ARRAY_SIZE(lookups));
}
static void __init ct_ca9x4_init(void)
{
int i;
struct clk *clk;
#ifdef CONFIG_CACHE_L2X0
void __iomem *l2x0_base = ioremap(CT_CA9X4_L2CC, SZ_4K);
@ -193,6 +164,10 @@ static void __init ct_ca9x4_init(void)
l2x0_init(l2x0_base, 0x00400000, 0xfe0fffff);
#endif
ct_osc1.site = v2m_get_master_site();
clk = v2m_osc_register("ct:osc1", &ct_osc1);
clk_register_clkdev(clk, NULL, "ct:clcd");
for (i = 0; i < ARRAY_SIZE(ct_ca9x4_amba_devs); i++)
amba_device_register(ct_ca9x4_amba_devs[i], &iomem_resource);
@ -234,7 +209,6 @@ struct ct_desc ct_ca9x4_desc __initdata = {
.id = V2M_CT_ID_CA9,
.name = "CA9x4",
.map_io = ct_ca9x4_map_io,
.init_early = ct_ca9x4_init_early,
.init_irq = ct_ca9x4_init_irq,
.init_tile = ct_ca9x4_init,
#ifdef CONFIG_SMP

View File

@ -1,15 +0,0 @@
#ifndef __ASM_MACH_CLKDEV_H
#define __ASM_MACH_CLKDEV_H
#include <plat/clock.h>
struct clk {
const struct clk_ops *ops;
unsigned long rate;
const struct icst_params *params;
};
#define __clk_get(clk) ({ 1; })
#define __clk_put(clk) do { } while (0)
#endif

View File

@ -18,6 +18,8 @@
#define DEBUG_LL_VIRT_BASE 0xf8000000
#if defined(CONFIG_DEBUG_VEXPRESS_UART0_DETECT)
.macro addruart,rp,rv,tmp
@ Make an educated guess regarding the memory map:
@ -41,3 +43,42 @@
.endm
#include <asm/hardware/debug-pl01x.S>
#elif defined(CONFIG_DEBUG_VEXPRESS_UART0_CA9)
.macro addruart,rp,rv,tmp
mov \rp, #DEBUG_LL_UART_OFFSET
orr \rv, \rp, #DEBUG_LL_VIRT_BASE
orr \rp, \rp, #DEBUG_LL_PHYS_BASE
.endm
#include <asm/hardware/debug-pl01x.S>
#elif defined(CONFIG_DEBUG_VEXPRESS_UART0_RS1)
.macro addruart,rp,rv,tmp
mov \rp, #DEBUG_LL_UART_OFFSET_RS1
orr \rv, \rp, #DEBUG_LL_VIRT_BASE
orr \rp, \rp, #DEBUG_LL_PHYS_BASE_RS1
.endm
#include <asm/hardware/debug-pl01x.S>
#else /* CONFIG_DEBUG_LL_UART_NONE */
.macro addruart, rp, rv, tmp
/* Safe dummy values */
mov \rp, #0
mov \rv, #DEBUG_LL_VIRT_BASE
.endm
.macro senduart,rd,rx
.endm
.macro waituart,rd,rx
.endm
.macro busyuart,rd,rx
.endm
#endif

View File

@ -1,6 +1,8 @@
#ifndef __MACH_MOTHERBOARD_H
#define __MACH_MOTHERBOARD_H
#include <linux/clk-provider.h>
/*
* Physical addresses, offset from V2M_PA_CS0-3
*/
@ -104,9 +106,10 @@
#define SYS_CFG_REBOOT (9 << 20)
#define SYS_CFG_DVIMODE (11 << 20)
#define SYS_CFG_POWER (12 << 20)
#define SYS_CFG_SITE_MB (0 << 16)
#define SYS_CFG_SITE_DB1 (1 << 16)
#define SYS_CFG_SITE_DB2 (2 << 16)
#define SYS_CFG_SITE(n) ((n) << 16)
#define SYS_CFG_SITE_MB 0
#define SYS_CFG_SITE_DB1 1
#define SYS_CFG_SITE_DB2 2
#define SYS_CFG_STACK(n) ((n) << 12)
#define SYS_CFG_ERR (1 << 1)
@ -122,6 +125,8 @@ void v2m_flags_set(u32 data);
#define SYS_MISC_MASTERSITE (1 << 14)
#define SYS_PROCIDx_HBI_MASK 0xfff
int v2m_get_master_site(void);
/*
* Core tile IDs
*/
@ -144,4 +149,21 @@ struct ct_desc {
extern struct ct_desc *ct_desc;
/*
* OSC clock provider
*/
struct v2m_osc {
struct clk_hw hw;
u8 site; /* 0 = motherboard, 1 = site 1, 2 = site 2 */
u8 stack; /* board stack position */
u16 osc;
unsigned long rate_min;
unsigned long rate_max;
unsigned long rate_default;
};
#define to_v2m_osc(osc) container_of(osc, struct v2m_osc, hw)
struct clk *v2m_osc_register(const char *name, struct v2m_osc *osc);
#endif

View File

@ -27,6 +27,7 @@
static unsigned long get_uart_base(void)
{
#if defined(CONFIG_DEBUG_VEXPRESS_UART0_DETECT)
unsigned long mpcore_periph;
/*
@ -42,6 +43,13 @@ static unsigned long get_uart_base(void)
return UART_BASE;
else
return UART_BASE_RS1;
#elif defined(CONFIG_DEBUG_VEXPRESS_UART0_CA9)
return UART_BASE;
#elif defined(CONFIG_DEBUG_VEXPRESS_UART0_RS1)
return UART_BASE_RS1;
#else
return 0;
#endif
}
/*
@ -51,6 +59,9 @@ static inline void putc(int c)
{
unsigned long base = get_uart_base();
if (!base)
return;
while (AMBA_UART_FR(base) & (1 << 5))
barrier();
@ -61,6 +72,9 @@ static inline void flush(void)
{
unsigned long base = get_uart_base();
if (!base)
return;
while (AMBA_UART_FR(base) & (1 << 3))
barrier();
}

View File

@ -16,7 +16,10 @@
#include <linux/spinlock.h>
#include <linux/usb/isp1760.h>
#include <linux/clkdev.h>
#include <linux/clk-provider.h>
#include <linux/mtd/physmap.h>
#include <linux/regulator/fixed.h>
#include <linux/regulator/machine.h>
#include <asm/arch_timer.h>
#include <asm/mach-types.h>
@ -81,16 +84,6 @@ static void __init v2m_sp804_init(void __iomem *base, unsigned int irq)
sp804_clockevents_init(base + TIMER_1_BASE, irq, "v2m-timer0");
}
static void __init v2m_timer_init(void)
{
v2m_sysctl_init(ioremap(V2M_SYSCTL, SZ_4K));
v2m_sp804_init(ioremap(V2M_TIMER01, SZ_4K), IRQ_V2M_TIMER0);
}
static struct sys_timer v2m_timer = {
.init = v2m_timer_init,
};
static DEFINE_SPINLOCK(v2m_cfg_lock);
@ -147,6 +140,13 @@ void __init v2m_flags_set(u32 data)
writel(data, v2m_sysreg_base + V2M_SYS_FLAGSSET);
}
int v2m_get_master_site(void)
{
u32 misc = readl(v2m_sysreg_base + V2M_SYS_MISC);
return misc & SYS_MISC_MASTERSITE ? SYS_CFG_SITE_DB2 : SYS_CFG_SITE_DB1;
}
static struct resource v2m_pcie_i2c_resource = {
.start = V2M_SERIAL_BUS_PCI,
@ -201,6 +201,11 @@ static struct platform_device v2m_eth_device = {
.dev.platform_data = &v2m_eth_config,
};
static struct regulator_consumer_supply v2m_eth_supplies[] = {
REGULATOR_SUPPLY("vddvario", "smsc911x"),
REGULATOR_SUPPLY("vdd33a", "smsc911x"),
};
static struct resource v2m_usb_resources[] = {
{
.start = V2M_ISP1761,
@ -319,98 +324,145 @@ static struct amba_device *v2m_amba_devs[] __initdata = {
};
static long v2m_osc_round(struct clk *clk, unsigned long rate)
static unsigned long v2m_osc_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
struct v2m_osc *osc = to_v2m_osc(hw);
return !parent_rate ? osc->rate_default : parent_rate;
}
static long v2m_osc_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *parent_rate)
{
struct v2m_osc *osc = to_v2m_osc(hw);
if (WARN_ON(rate < osc->rate_min))
rate = osc->rate_min;
if (WARN_ON(rate > osc->rate_max))
rate = osc->rate_max;
return rate;
}
static int v2m_osc1_set(struct clk *clk, unsigned long rate)
static int v2m_osc_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
return v2m_cfg_write(SYS_CFG_OSC | SYS_CFG_SITE_MB | 1, rate);
struct v2m_osc *osc = to_v2m_osc(hw);
v2m_cfg_write(SYS_CFG_OSC | SYS_CFG_SITE(osc->site) |
SYS_CFG_STACK(osc->stack) | osc->osc, rate);
return 0;
}
static const struct clk_ops osc1_clk_ops = {
.round = v2m_osc_round,
.set = v2m_osc1_set,
static struct clk_ops v2m_osc_ops = {
.recalc_rate = v2m_osc_recalc_rate,
.round_rate = v2m_osc_round_rate,
.set_rate = v2m_osc_set_rate,
};
static struct clk osc1_clk = {
.ops = &osc1_clk_ops,
.rate = 24000000,
struct clk * __init v2m_osc_register(const char *name, struct v2m_osc *osc)
{
struct clk_init_data init;
WARN_ON(osc->site > 2);
WARN_ON(osc->stack > 15);
WARN_ON(osc->osc > 4095);
init.name = name;
init.ops = &v2m_osc_ops;
init.flags = CLK_IS_ROOT;
init.num_parents = 0;
osc->hw.init = &init;
return clk_register(NULL, &osc->hw);
}
static struct v2m_osc v2m_mb_osc1 = {
.site = SYS_CFG_SITE_MB,
.osc = 1,
.rate_min = 23750000,
.rate_max = 63500000,
.rate_default = 23750000,
};
static struct clk osc2_clk = {
.rate = 24000000,
static const char *v2m_ref_clk_periphs[] __initconst = {
"mb:wdt", "1000f000.wdt", "1c0f0000.wdt", /* SP805 WDT */
};
static struct clk v2m_sp804_clk = {
.rate = 1000000,
static const char *v2m_osc1_periphs[] __initconst = {
"mb:clcd", "1001f000.clcd", "1c1f0000.clcd", /* PL111 CLCD */
};
static struct clk v2m_ref_clk = {
.rate = 32768,
static const char *v2m_osc2_periphs[] __initconst = {
"mb:mmci", "10005000.mmci", "1c050000.mmci", /* PL180 MMCI */
"mb:kmi0", "10006000.kmi", "1c060000.kmi", /* PL050 KMI0 */
"mb:kmi1", "10007000.kmi", "1c070000.kmi", /* PL050 KMI1 */
"mb:uart0", "10009000.uart", "1c090000.uart", /* PL011 UART0 */
"mb:uart1", "1000a000.uart", "1c0a0000.uart", /* PL011 UART1 */
"mb:uart2", "1000b000.uart", "1c0b0000.uart", /* PL011 UART2 */
"mb:uart3", "1000c000.uart", "1c0c0000.uart", /* PL011 UART3 */
};
static struct clk dummy_apb_pclk;
static void __init v2m_clk_init(void)
{
struct clk *clk;
int i;
static struct clk_lookup v2m_lookups[] = {
{ /* AMBA bus clock */
.con_id = "apb_pclk",
.clk = &dummy_apb_pclk,
}, { /* UART0 */
.dev_id = "mb:uart0",
.clk = &osc2_clk,
}, { /* UART1 */
.dev_id = "mb:uart1",
.clk = &osc2_clk,
}, { /* UART2 */
.dev_id = "mb:uart2",
.clk = &osc2_clk,
}, { /* UART3 */
.dev_id = "mb:uart3",
.clk = &osc2_clk,
}, { /* KMI0 */
.dev_id = "mb:kmi0",
.clk = &osc2_clk,
}, { /* KMI1 */
.dev_id = "mb:kmi1",
.clk = &osc2_clk,
}, { /* MMC0 */
.dev_id = "mb:mmci",
.clk = &osc2_clk,
}, { /* CLCD */
.dev_id = "mb:clcd",
.clk = &osc1_clk,
}, { /* SP805 WDT */
.dev_id = "mb:wdt",
.clk = &v2m_ref_clk,
}, { /* SP804 timers */
.dev_id = "sp804",
.con_id = "v2m-timer0",
.clk = &v2m_sp804_clk,
}, { /* SP804 timers */
.dev_id = "sp804",
.con_id = "v2m-timer1",
.clk = &v2m_sp804_clk,
},
clk = clk_register_fixed_rate(NULL, "dummy_apb_pclk", NULL,
CLK_IS_ROOT, 0);
WARN_ON(clk_register_clkdev(clk, "apb_pclk", NULL));
clk = clk_register_fixed_rate(NULL, "mb:ref_clk", NULL,
CLK_IS_ROOT, 32768);
for (i = 0; i < ARRAY_SIZE(v2m_ref_clk_periphs); i++)
WARN_ON(clk_register_clkdev(clk, NULL, v2m_ref_clk_periphs[i]));
clk = clk_register_fixed_rate(NULL, "mb:sp804_clk", NULL,
CLK_IS_ROOT, 1000000);
WARN_ON(clk_register_clkdev(clk, "v2m-timer0", "sp804"));
WARN_ON(clk_register_clkdev(clk, "v2m-timer1", "sp804"));
clk = v2m_osc_register("mb:osc1", &v2m_mb_osc1);
for (i = 0; i < ARRAY_SIZE(v2m_osc1_periphs); i++)
WARN_ON(clk_register_clkdev(clk, NULL, v2m_osc1_periphs[i]));
clk = clk_register_fixed_rate(NULL, "mb:osc2", NULL,
CLK_IS_ROOT, 24000000);
for (i = 0; i < ARRAY_SIZE(v2m_osc2_periphs); i++)
WARN_ON(clk_register_clkdev(clk, NULL, v2m_osc2_periphs[i]));
}
static void __init v2m_timer_init(void)
{
v2m_sysctl_init(ioremap(V2M_SYSCTL, SZ_4K));
v2m_clk_init();
v2m_sp804_init(ioremap(V2M_TIMER01, SZ_4K), IRQ_V2M_TIMER0);
}
static struct sys_timer v2m_timer = {
.init = v2m_timer_init,
};
static void __init v2m_init_early(void)
{
ct_desc->init_early();
clkdev_add_table(v2m_lookups, ARRAY_SIZE(v2m_lookups));
if (ct_desc->init_early)
ct_desc->init_early();
versatile_sched_clock_init(v2m_sysreg_base + V2M_SYS_24MHZ, 24000000);
}
static void v2m_power_off(void)
{
if (v2m_cfg_write(SYS_CFG_SHUTDOWN | SYS_CFG_SITE_MB, 0))
if (v2m_cfg_write(SYS_CFG_SHUTDOWN | SYS_CFG_SITE(SYS_CFG_SITE_MB), 0))
printk(KERN_EMERG "Unable to shutdown\n");
}
static void v2m_restart(char str, const char *cmd)
{
if (v2m_cfg_write(SYS_CFG_REBOOT | SYS_CFG_SITE_MB, 0))
if (v2m_cfg_write(SYS_CFG_REBOOT | SYS_CFG_SITE(SYS_CFG_SITE_MB), 0))
printk(KERN_EMERG "Unable to reboot\n");
}
@ -458,6 +510,9 @@ static void __init v2m_init(void)
{
int i;
regulator_register_fixed(0, v2m_eth_supplies,
ARRAY_SIZE(v2m_eth_supplies));
platform_device_register(&v2m_pcie_i2c_device);
platform_device_register(&v2m_ddc_i2c_device);
platform_device_register(&v2m_flash_device);
@ -522,77 +577,6 @@ void __init v2m_dt_map_io(void)
#endif
}
static struct clk_lookup v2m_dt_lookups[] = {
{ /* AMBA bus clock */
.con_id = "apb_pclk",
.clk = &dummy_apb_pclk,
}, { /* SP804 timers */
.dev_id = "sp804",
.con_id = "v2m-timer0",
.clk = &v2m_sp804_clk,
}, { /* SP804 timers */
.dev_id = "sp804",
.con_id = "v2m-timer1",
.clk = &v2m_sp804_clk,
}, { /* PL180 MMCI */
.dev_id = "mb:mmci", /* 10005000.mmci */
.clk = &osc2_clk,
}, { /* PL050 KMI0 */
.dev_id = "10006000.kmi",
.clk = &osc2_clk,
}, { /* PL050 KMI1 */
.dev_id = "10007000.kmi",
.clk = &osc2_clk,
}, { /* PL011 UART0 */
.dev_id = "10009000.uart",
.clk = &osc2_clk,
}, { /* PL011 UART1 */
.dev_id = "1000a000.uart",
.clk = &osc2_clk,
}, { /* PL011 UART2 */
.dev_id = "1000b000.uart",
.clk = &osc2_clk,
}, { /* PL011 UART3 */
.dev_id = "1000c000.uart",
.clk = &osc2_clk,
}, { /* SP805 WDT */
.dev_id = "1000f000.wdt",
.clk = &v2m_ref_clk,
}, { /* PL111 CLCD */
.dev_id = "1001f000.clcd",
.clk = &osc1_clk,
},
/* RS1 memory map */
{ /* PL180 MMCI */
.dev_id = "mb:mmci", /* 1c050000.mmci */
.clk = &osc2_clk,
}, { /* PL050 KMI0 */
.dev_id = "1c060000.kmi",
.clk = &osc2_clk,
}, { /* PL050 KMI1 */
.dev_id = "1c070000.kmi",
.clk = &osc2_clk,
}, { /* PL011 UART0 */
.dev_id = "1c090000.uart",
.clk = &osc2_clk,
}, { /* PL011 UART1 */
.dev_id = "1c0a0000.uart",
.clk = &osc2_clk,
}, { /* PL011 UART2 */
.dev_id = "1c0b0000.uart",
.clk = &osc2_clk,
}, { /* PL011 UART3 */
.dev_id = "1c0c0000.uart",
.clk = &osc2_clk,
}, { /* SP805 WDT */
.dev_id = "1c0f0000.wdt",
.clk = &v2m_ref_clk,
}, { /* PL111 CLCD */
.dev_id = "1c1f0000.clcd",
.clk = &osc1_clk,
},
};
void __init v2m_dt_init_early(void)
{
struct device_node *node;
@ -605,8 +589,8 @@ void __init v2m_dt_init_early(void)
/* Confirm board type against DT property, if available */
if (of_property_read_u32(allnodes, "arm,hbi", &dt_hbi) == 0) {
u32 misc = readl(v2m_sysreg_base + V2M_SYS_MISC);
u32 id = readl(v2m_sysreg_base + (misc & SYS_MISC_MASTERSITE ?
int site = v2m_get_master_site();
u32 id = readl(v2m_sysreg_base + (site == SYS_CFG_SITE_DB2 ?
V2M_SYS_PROCID1 : V2M_SYS_PROCID0));
u32 hbi = id & SYS_PROCIDx_HBI_MASK;
@ -614,8 +598,6 @@ void __init v2m_dt_init_early(void)
pr_warning("vexpress: DT HBI (%x) is not matching "
"hardware (%x)!\n", dt_hbi, hbi);
}
clkdev_add_table(v2m_dt_lookups, ARRAY_SIZE(v2m_dt_lookups));
}
static struct of_device_id vexpress_irq_match[] __initdata = {
@ -637,6 +619,8 @@ static void __init v2m_dt_timer_init(void)
node = of_find_compatible_node(NULL, NULL, "arm,sp810");
v2m_sysctl_init(of_iomap(node, 0));
v2m_clk_init();
err = of_property_read_string(of_aliases, "arm,v2m_timer", &path);
if (WARN_ON(err))
return;

View File

@ -1,5 +1,8 @@
if PLAT_VERSATILE
config PLAT_VERSATILE_CLOCK
bool
config PLAT_VERSATILE_CLCD
bool

View File

@ -1,4 +1,4 @@
obj-y := clock.o
obj-$(CONFIG_PLAT_VERSATILE_CLOCK) += clock.o
obj-$(CONFIG_PLAT_VERSATILE_CLCD) += clcd.o
obj-$(CONFIG_PLAT_VERSATILE_FPGA_IRQ) += fpga-irq.o
obj-$(CONFIG_PLAT_VERSATILE_LEDS) += leds.o