Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 344322
b: refs/heads/master
c: 4e76b1b
h: refs/heads/master
v: v3
  • Loading branch information
Jason Cooper committed Nov 22, 2012
1 parent 37920ce commit f3110c0
Show file tree
Hide file tree
Showing 28 changed files with 775 additions and 16 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 9bfd143ed247fc7a9e0573dc1fbaf6d124b5cac9
refs/heads/master: 4e76b1b2329b4a19adfacd187bc2920f68126a95
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,15 @@ Required properties:
- interrupt-controller: Identifies the node as an interrupt controller.
- #interrupt-cells: The number of cells to define the interrupts. Should be 1.
The cell is the IRQ number

- reg: Should contain PMIC registers location and length. First pair
for the main interrupt registers, second pair for the per-CPU
interrupt registers
interrupt registers. For this last pair, to be compliant with SMP
support, the "virtual" must be use (For the record, these registers
automatically map to the interrupt controller registers of the
current CPU)



Example:

Expand All @@ -18,6 +24,6 @@ Example:
#address-cells = <1>;
#size-cells = <1>;
interrupt-controller;
reg = <0xd0020000 0x1000>,
<0xd0021000 0x1000>;
reg = <0xd0020a00 0x1d0>,
<0xd0021070 0x58>;
};
20 changes: 20 additions & 0 deletions trunk/Documentation/devicetree/bindings/arm/armada-370-xp-pmsu.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
Power Management Service Unit(PMSU)
-----------------------------------
Available on Marvell SOCs: Armada 370 and Armada XP

Required properties:

- compatible: "marvell,armada-370-xp-pmsu"

- reg: Should contain PMSU registers location and length. First pair
for the per-CPU SW Reset Control registers, second pair for the
Power Management Service Unit.

Example:

armada-370-xp-pmsu@d0022000 {
compatible = "marvell,armada-370-xp-pmsu";
reg = <0xd0022100 0x430>,
<0xd0020800 0x20>;
};

21 changes: 21 additions & 0 deletions trunk/Documentation/devicetree/bindings/arm/coherency-fabric.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
Coherency fabric
----------------
Available on Marvell SOCs: Armada 370 and Armada XP

Required properties:

- compatible: "marvell,coherency-fabric"

- reg: Should contain coherency fabric registers location and
length. First pair for the coherency fabric registers, second pair
for the per-CPU fabric registers registers.

Example:

coherency-fabric@d0020200 {
compatible = "marvell,coherency-fabric";
reg = <0xd0020200 0xb0>,
<0xd0021810 0x1c>;

};

6 changes: 6 additions & 0 deletions trunk/arch/arm/boot/dts/armada-370-xp.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@
interrupt-controller;
};

coherency-fabric@d0020200 {
compatible = "marvell,coherency-fabric";
reg = <0xd0020200 0xb0>,
<0xd0021810 0x1c>;
};

soc {
#address-cells = <1>;
#size-cells = <1>;
Expand Down
8 changes: 7 additions & 1 deletion trunk/arch/arm/boot/dts/armada-xp.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,13 @@

mpic: interrupt-controller@d0020000 {
reg = <0xd0020a00 0x1d0>,
<0xd0021870 0x58>;
<0xd0021070 0x58>;
};

armada-370-xp-pmsu@d0022000 {
compatible = "marvell,armada-370-xp-pmsu";
reg = <0xd0022100 0x430>,
<0xd0020800 0x20>;
};

soc {
Expand Down
3 changes: 3 additions & 0 deletions trunk/arch/arm/configs/mvebu_defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ CONFIG_ARCH_MVEBU=y
CONFIG_MACH_ARMADA_370=y
CONFIG_MACH_ARMADA_XP=y
# CONFIG_CACHE_L2X0 is not set
# CONFIG_SWP_EMULATE is not set
CONFIG_SMP=y
# CONFIG_LOCAL_TIMERS is not set
CONFIG_AEABI=y
CONFIG_HIGHMEM=y
# CONFIG_COMPACTION is not set
Expand Down
2 changes: 2 additions & 0 deletions trunk/arch/arm/include/asm/dma-mapping.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@ static inline void dma_free_noncoherent(struct device *dev, size_t size,

extern int dma_supported(struct device *dev, u64 mask);

extern int arm_dma_set_mask(struct device *dev, u64 dma_mask);

/**
* arm_dma_alloc - allocate consistent memory for DMA
* @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
Expand Down
3 changes: 2 additions & 1 deletion trunk/arch/arm/mach-mvebu/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ menu "Marvell SOC with device tree"
config MACH_ARMADA_370_XP
bool
select ARMADA_370_XP_TIMER
select CPU_V7
select HAVE_SMP
select CPU_PJ4B

config MACH_ARMADA_370
bool "Marvell Armada 370 boards"
Expand Down
4 changes: 3 additions & 1 deletion trunk/arch/arm/mach-mvebu/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,6 @@ ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include \
-I$(srctree)/arch/arm/plat-orion/include

obj-y += system-controller.o
obj-$(CONFIG_MACH_ARMADA_370_XP) += armada-370-xp.o irq-armada-370-xp.o addr-map.o
obj-$(CONFIG_MACH_ARMADA_370_XP) += armada-370-xp.o irq-armada-370-xp.o addr-map.o coherency.o coherency_ll.o pmsu.o
obj-$(CONFIG_SMP) += platsmp.o headsmp.o
obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
3 changes: 3 additions & 0 deletions trunk/arch/arm/mach-mvebu/addr-map.c
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,9 @@ static int __init armada_setup_cpu_mbus(void)

addr_map_cfg.bridge_virt_base = mbus_unit_addr_decoding_base;

if (of_find_compatible_node(NULL, NULL, "marvell,coherency-fabric"))
addr_map_cfg.hw_io_coherency = 1;

/*
* Disable, clear and configure windows.
*/
Expand Down
3 changes: 3 additions & 0 deletions trunk/arch/arm/mach-mvebu/armada-370-xp.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include <asm/mach/time.h>
#include "armada-370-xp.h"
#include "common.h"
#include "coherency.h"

static struct map_desc armada_370_xp_io_desc[] __initdata = {
{
Expand Down Expand Up @@ -62,6 +63,7 @@ struct sys_timer armada_370_xp_timer = {
static void __init armada_370_xp_dt_init(void)
{
of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
coherency_init();
}

static const char * const armada_370_xp_dt_board_dt_compat[] = {
Expand All @@ -71,6 +73,7 @@ static const char * const armada_370_xp_dt_board_dt_compat[] = {
};

DT_MACHINE_START(ARMADA_XP_DT, "Marvell Aramada 370/XP (Device Tree)")
.smp = smp_ops(armada_xp_smp_ops),
.init_machine = armada_370_xp_dt_init,
.map_io = armada_370_xp_map_io,
.init_early = armada_370_xp_init_early,
Expand Down
7 changes: 7 additions & 0 deletions trunk/arch/arm/mach-mvebu/armada-370-xp.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,11 @@
#define ARMADA_370_XP_REGS_VIRT_BASE IOMEM(0xfeb00000)
#define ARMADA_370_XP_REGS_SIZE SZ_1M

#ifdef CONFIG_SMP
#include <linux/cpumask.h>

void armada_mpic_send_doorbell(const struct cpumask *mask, unsigned int irq);
void armada_xp_mpic_smp_cpu_init(void);
#endif

#endif /* __MACH_ARMADA_370_XP_H */
155 changes: 155 additions & 0 deletions trunk/arch/arm/mach-mvebu/coherency.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
/*
* Coherency fabric (Aurora) support for Armada 370 and XP platforms.
*
* Copyright (C) 2012 Marvell
*
* Yehuda Yitschak <yehuday@marvell.com>
* Gregory Clement <gregory.clement@free-electrons.com>
* Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*
* The Armada 370 and Armada XP SOCs have a coherency fabric which is
* responsible for ensuring hardware coherency between all CPUs and between
* CPUs and I/O masters. This file initializes the coherency fabric and
* supplies basic routines for configuring and controlling hardware coherency
*/

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/of_address.h>
#include <linux/io.h>
#include <linux/smp.h>
#include <linux/dma-mapping.h>
#include <linux/platform_device.h>
#include <asm/smp_plat.h>
#include "armada-370-xp.h"

/*
* Some functions in this file are called very early during SMP
* initialization. At that time the device tree framework is not yet
* ready, and it is not possible to get the register address to
* ioremap it. That's why the pointer below is given with an initial
* value matching its virtual mapping
*/
static void __iomem *coherency_base = ARMADA_370_XP_REGS_VIRT_BASE + 0x20200;
static void __iomem *coherency_cpu_base;

/* Coherency fabric registers */
#define COHERENCY_FABRIC_CFG_OFFSET 0x4

#define IO_SYNC_BARRIER_CTL_OFFSET 0x0

static struct of_device_id of_coherency_table[] = {
{.compatible = "marvell,coherency-fabric"},
{ /* end of list */ },
};

#ifdef CONFIG_SMP
int coherency_get_cpu_count(void)
{
int reg, cnt;

reg = readl(coherency_base + COHERENCY_FABRIC_CFG_OFFSET);
cnt = (reg & 0xF) + 1;

return cnt;
}
#endif

/* Function defined in coherency_ll.S */
int ll_set_cpu_coherent(void __iomem *base_addr, unsigned int hw_cpu_id);

int set_cpu_coherent(unsigned int hw_cpu_id, int smp_group_id)
{
if (!coherency_base) {
pr_warn("Can't make CPU %d cache coherent.\n", hw_cpu_id);
pr_warn("Coherency fabric is not initialized\n");
return 1;
}

return ll_set_cpu_coherent(coherency_base, hw_cpu_id);
}

static inline void mvebu_hwcc_sync_io_barrier(void)
{
writel(0x1, coherency_cpu_base + IO_SYNC_BARRIER_CTL_OFFSET);
while (readl(coherency_cpu_base + IO_SYNC_BARRIER_CTL_OFFSET) & 0x1);
}

static dma_addr_t mvebu_hwcc_dma_map_page(struct device *dev, struct page *page,
unsigned long offset, size_t size,
enum dma_data_direction dir,
struct dma_attrs *attrs)
{
if (dir != DMA_TO_DEVICE)
mvebu_hwcc_sync_io_barrier();
return pfn_to_dma(dev, page_to_pfn(page)) + offset;
}


static void mvebu_hwcc_dma_unmap_page(struct device *dev, dma_addr_t dma_handle,
size_t size, enum dma_data_direction dir,
struct dma_attrs *attrs)
{
if (dir != DMA_TO_DEVICE)
mvebu_hwcc_sync_io_barrier();
}

static void mvebu_hwcc_dma_sync(struct device *dev, dma_addr_t dma_handle,
size_t size, enum dma_data_direction dir)
{
if (dir != DMA_TO_DEVICE)
mvebu_hwcc_sync_io_barrier();
}

static struct dma_map_ops mvebu_hwcc_dma_ops = {
.alloc = arm_dma_alloc,
.free = arm_dma_free,
.mmap = arm_dma_mmap,
.map_page = mvebu_hwcc_dma_map_page,
.unmap_page = mvebu_hwcc_dma_unmap_page,
.get_sgtable = arm_dma_get_sgtable,
.map_sg = arm_dma_map_sg,
.unmap_sg = arm_dma_unmap_sg,
.sync_single_for_cpu = mvebu_hwcc_dma_sync,
.sync_single_for_device = mvebu_hwcc_dma_sync,
.sync_sg_for_cpu = arm_dma_sync_sg_for_cpu,
.sync_sg_for_device = arm_dma_sync_sg_for_device,
.set_dma_mask = arm_dma_set_mask,
};

static int mvebu_hwcc_platform_notifier(struct notifier_block *nb,
unsigned long event, void *__dev)
{
struct device *dev = __dev;

if (event != BUS_NOTIFY_ADD_DEVICE)
return NOTIFY_DONE;
set_dma_ops(dev, &mvebu_hwcc_dma_ops);

return NOTIFY_OK;
}

static struct notifier_block mvebu_hwcc_platform_nb = {
.notifier_call = mvebu_hwcc_platform_notifier,
};

int __init coherency_init(void)
{
struct device_node *np;

np = of_find_matching_node(NULL, of_coherency_table);
if (np) {
pr_info("Initializing Coherency fabric\n");
coherency_base = of_iomap(np, 0);
coherency_cpu_base = of_iomap(np, 1);
set_cpu_coherent(cpu_logical_map(smp_processor_id()), 0);
bus_register_notifier(&platform_bus_type,
&mvebu_hwcc_platform_nb);
}

return 0;
}
24 changes: 24 additions & 0 deletions trunk/arch/arm/mach-mvebu/coherency.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* arch/arm/mach-mvebu/include/mach/coherency.h
*
*
* Coherency fabric (Aurora) support for Armada 370 and XP platforms.
*
* Copyright (C) 2012 Marvell
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/

#ifndef __MACH_370_XP_COHERENCY_H
#define __MACH_370_XP_COHERENCY_H

#ifdef CONFIG_SMP
int coherency_get_cpu_count(void);
#endif

int set_cpu_coherent(int cpu_id, int smp_group_id);
int coherency_init(void);

#endif /* __MACH_370_XP_COHERENCY_H */
Loading

0 comments on commit f3110c0

Please sign in to comment.