Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 344305
b: refs/heads/master
c: e60304f
h: refs/heads/master
i:
  344303: d8d079d
v: v3
  • Loading branch information
Gregory CLEMENT committed Nov 21, 2012
1 parent 432b697 commit 497d3d7
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 4 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: 722202e10b488c14e93c428743a0e476093949e3
refs/heads/master: e60304f8cb7bb545e79fe62d9b9762460c254ec2
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,17 @@ Available on Marvell SOCs: Armada 370 and Armada XP
Required properties:

- compatible: "marvell,coherency-fabric"
- reg: Should contain,coherency fabric registers location and length.

- 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>;
reg = <0xd0020200 0xb0>,
<0xd0021810 0x1c>;

};

3 changes: 2 additions & 1 deletion trunk/arch/arm/boot/dts/armada-370-xp.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@

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

soc {
Expand Down
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
73 changes: 73 additions & 0 deletions trunk/arch/arm/mach-mvebu/coherency.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
#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"

Expand All @@ -33,10 +35,13 @@
* 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 */ },
Expand Down Expand Up @@ -68,6 +73,70 @@ int set_cpu_coherent(unsigned int hw_cpu_id, int smp_group_id)
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;
Expand All @@ -76,6 +145,10 @@ int __init coherency_init(void)
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;
Expand Down

0 comments on commit 497d3d7

Please sign in to comment.