162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci#ifndef _M68KNOMMU_CACHEFLUSH_H
362306a36Sopenharmony_ci#define _M68KNOMMU_CACHEFLUSH_H
462306a36Sopenharmony_ci
562306a36Sopenharmony_ci/*
662306a36Sopenharmony_ci * (C) Copyright 2000-2010, Greg Ungerer <gerg@snapgear.com>
762306a36Sopenharmony_ci */
862306a36Sopenharmony_ci#include <linux/mm.h>
962306a36Sopenharmony_ci#include <asm/mcfsim.h>
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci#define flush_cache_all()			__flush_cache_all()
1262306a36Sopenharmony_ci#define flush_dcache_range(start, len)		__flush_dcache_all()
1362306a36Sopenharmony_ci#define flush_icache_range(start, len)		__flush_icache_all()
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_civoid mcf_cache_push(void);
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_cistatic inline void __clear_cache_all(void)
1862306a36Sopenharmony_ci{
1962306a36Sopenharmony_ci#ifdef CACHE_INVALIDATE
2062306a36Sopenharmony_ci	__asm__ __volatile__ (
2162306a36Sopenharmony_ci		"movec	%0, %%CACR\n\t"
2262306a36Sopenharmony_ci		"nop\n\t"
2362306a36Sopenharmony_ci		: : "r" (CACHE_INVALIDATE) );
2462306a36Sopenharmony_ci#endif
2562306a36Sopenharmony_ci}
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_cistatic inline void __flush_cache_all(void)
2862306a36Sopenharmony_ci{
2962306a36Sopenharmony_ci#ifdef CACHE_PUSH
3062306a36Sopenharmony_ci	mcf_cache_push();
3162306a36Sopenharmony_ci#endif
3262306a36Sopenharmony_ci	__clear_cache_all();
3362306a36Sopenharmony_ci}
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_ci/*
3662306a36Sopenharmony_ci * Some ColdFire parts implement separate instruction and data caches,
3762306a36Sopenharmony_ci * on those we should just flush the appropriate cache. If we don't need
3862306a36Sopenharmony_ci * to do any specific flushing then this will be optimized away.
3962306a36Sopenharmony_ci */
4062306a36Sopenharmony_cistatic inline void __flush_icache_all(void)
4162306a36Sopenharmony_ci{
4262306a36Sopenharmony_ci#ifdef CACHE_INVALIDATEI
4362306a36Sopenharmony_ci	__asm__ __volatile__ (
4462306a36Sopenharmony_ci		"movec	%0, %%CACR\n\t"
4562306a36Sopenharmony_ci		"nop\n\t"
4662306a36Sopenharmony_ci		: : "r" (CACHE_INVALIDATEI) );
4762306a36Sopenharmony_ci#endif
4862306a36Sopenharmony_ci}
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_cistatic inline void __flush_dcache_all(void)
5162306a36Sopenharmony_ci{
5262306a36Sopenharmony_ci#ifdef CACHE_PUSH
5362306a36Sopenharmony_ci	mcf_cache_push();
5462306a36Sopenharmony_ci#endif
5562306a36Sopenharmony_ci#ifdef CACHE_INVALIDATED
5662306a36Sopenharmony_ci	__asm__ __volatile__ (
5762306a36Sopenharmony_ci		"movec	%0, %%CACR\n\t"
5862306a36Sopenharmony_ci		"nop\n\t"
5962306a36Sopenharmony_ci		: : "r" (CACHE_INVALIDATED) );
6062306a36Sopenharmony_ci#else
6162306a36Sopenharmony_ci	/* Flush the write buffer */
6262306a36Sopenharmony_ci	__asm__ __volatile__ ( "nop" );
6362306a36Sopenharmony_ci#endif
6462306a36Sopenharmony_ci}
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_ci/*
6762306a36Sopenharmony_ci * Push cache entries at supplied address. We want to write back any dirty
6862306a36Sopenharmony_ci * data and then invalidate the cache lines associated with this address.
6962306a36Sopenharmony_ci */
7062306a36Sopenharmony_cistatic inline void cache_push(unsigned long paddr, int len)
7162306a36Sopenharmony_ci{
7262306a36Sopenharmony_ci	__flush_cache_all();
7362306a36Sopenharmony_ci}
7462306a36Sopenharmony_ci
7562306a36Sopenharmony_ci/*
7662306a36Sopenharmony_ci * Clear cache entries at supplied address (that is don't write back any
7762306a36Sopenharmony_ci * dirty data).
7862306a36Sopenharmony_ci */
7962306a36Sopenharmony_cistatic inline void cache_clear(unsigned long paddr, int len)
8062306a36Sopenharmony_ci{
8162306a36Sopenharmony_ci	__clear_cache_all();
8262306a36Sopenharmony_ci}
8362306a36Sopenharmony_ci
8462306a36Sopenharmony_ci#include <asm-generic/cacheflush.h>
8562306a36Sopenharmony_ci
8662306a36Sopenharmony_ci#endif /* _M68KNOMMU_CACHEFLUSH_H */
87