Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b6d92b4a authored by Steven J. Hill's avatar Steven J. Hill
Browse files

MIPS: Add option to disable software I/O coherency.



Some MIPS controllers have hardware I/O coherency. This patch
detects those and turns off software coherency. A new kernel
command line option also allows the user to manually turn
software coherency on or off.

Signed-off-by: default avatarSteven J. Hill <Steven.Hill@imgtec.com>
parent c34c09c8
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
/*
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 *
 * Copyright (C) 2006  Ralf Baechle <ralf@linux-mips.org>
 *
 */
#ifndef __ASM_DMA_COHERENCE_H
#define __ASM_DMA_COHERENCE_H

extern int coherentio;
extern int hw_coherentio;

#endif
+1 −0
Original line number Diff line number Diff line
@@ -2,6 +2,7 @@
#define _ASM_DMA_MAPPING_H

#include <asm/scatterlist.h>
#include <asm/dma-coherence.h>
#include <asm/cache.h>
#include <asm-generic/dma-coherent.h>

+2 −3
Original line number Diff line number Diff line
@@ -61,9 +61,8 @@ static inline int plat_device_is_coherent(struct device *dev)
{
#ifdef CONFIG_DMA_COHERENT
	return 1;
#endif
#ifdef CONFIG_DMA_NONCOHERENT
	return 0;
#else
	return coherentio;
#endif
}

+8 −16
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@
#include <asm/war.h>
#include <asm/cacheflush.h> /* for run_uncached() */
#include <asm/traps.h>
#include <asm/dma-coherence.h>

/*
 * Special Variant of smp_call_function for use by cache functions:
@@ -1377,20 +1378,6 @@ static void __cpuinit coherency_setup(void)
	}
}

#if defined(CONFIG_DMA_NONCOHERENT)

static int __cpuinitdata coherentio;

static int __init setcoherentio(char *str)
{
	coherentio = 1;

	return 0;
}

early_param("coherentio", setcoherentio);
#endif

static void __cpuinit r4k_cache_error_setup(void)
{
	extern char __weak except_vec2_generic;
@@ -1472,9 +1459,14 @@ void __cpuinit r4k_cache_init(void)

	build_clear_page();
	build_copy_page();
#if !defined(CONFIG_MIPS_CMP)

	/*
	 * We want to run CMP kernels on core with and without coherent
	 * caches. Therefore, do not use CONFIG_MIPS_CMP to decide whether
	 * or not to flush caches.
	 */
	local_r4k___flush_cache_all(NULL);
#endif

	coherency_setup();
	board_cache_error_setup = r4k_cache_error_setup;
}
+23 −2
Original line number Diff line number Diff line
@@ -22,6 +22,26 @@

#include <dma-coherence.h>

int coherentio = 0;	/* User defined DMA coherency from command line. */
EXPORT_SYMBOL_GPL(coherentio);
int hw_coherentio = 0;	/* Actual hardware supported DMA coherency setting. */

static int __init setcoherentio(char *str)
{
	coherentio = 1;
	pr_info("Hardware DMA cache coherency (command line)\n");
	return 0;
}
early_param("coherentio", setcoherentio);

static int __init setnocoherentio(char *str)
{
	coherentio = 0;
	pr_info("Software DMA cache coherency (command line)\n");
	return 0;
}
early_param("nocoherentio", setnocoherentio);

static inline struct page *dma_addr_to_page(struct device *dev,
	dma_addr_t dma_addr)
{
@@ -115,6 +135,7 @@ static void *mips_dma_alloc_coherent(struct device *dev, size_t size,

		if (!plat_device_is_coherent(dev)) {
			dma_cache_wback_inv((unsigned long) ret, size);
			if (!hw_coherentio)
				ret = UNCAC_ADDR(ret);
		}
	}
@@ -142,7 +163,7 @@ static void mips_dma_free_coherent(struct device *dev, size_t size, void *vaddr,

	plat_unmap_dma_mem(dev, dma_handle, size, DMA_BIDIRECTIONAL);

	if (!plat_device_is_coherent(dev))
	if (!plat_device_is_coherent(dev) && !hw_coherentio)
		addr = CAC_ADDR(addr);

	free_pages(addr, get_order(size));
Loading