12d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo/*
22d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo * Cache management functions for Hexagon
32d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo *
42d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
52d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo *
62d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo * This program is free software; you can redistribute it and/or modify
72d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo * it under the terms of the GNU General Public License version 2 and
82d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo * only version 2 as published by the Free Software Foundation.
92d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo *
102d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo * This program is distributed in the hope that it will be useful,
112d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo * but WITHOUT ANY WARRANTY; without even the implied warranty of
122d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
132d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo * GNU General Public License for more details.
142d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo *
152d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo * You should have received a copy of the GNU General Public License
162d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo * along with this program; if not, write to the Free Software
172d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
182d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo * 02110-1301, USA.
192d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo */
202d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo
212d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo#include <linux/mm.h>
222d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo#include <asm/cacheflush.h>
232d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo#include <asm/hexagon_vm.h>
242d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo
252d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo#define spanlines(start, end) \
262d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo	(((end - (start & ~(LINESIZE - 1))) >> LINEBITS) + 1)
272d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo
282d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuovoid flush_dcache_range(unsigned long start, unsigned long end)
292d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo{
302d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo	unsigned long lines = spanlines(start, end-1);
312d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo	unsigned long i, flags;
322d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo
332d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo	start &= ~(LINESIZE - 1);
342d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo
352d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo	local_irq_save(flags);
362d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo
372d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo	for (i = 0; i < lines; i++) {
382d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo		__asm__ __volatile__ (
392d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo		"	dccleaninva(%0);	"
402d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo		:
412d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo		: "r" (start)
422d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo		);
432d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo		start += LINESIZE;
442d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo	}
452d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo	local_irq_restore(flags);
462d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo}
472d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo
482d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuovoid flush_icache_range(unsigned long start, unsigned long end)
492d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo{
502d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo	unsigned long lines = spanlines(start, end-1);
512d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo	unsigned long i, flags;
522d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo
532d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo	start &= ~(LINESIZE - 1);
542d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo
552d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo	local_irq_save(flags);
562d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo
572d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo	for (i = 0; i < lines; i++) {
582d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo		__asm__ __volatile__ (
592d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo			"	dccleana(%0); "
602d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo			"	icinva(%0);	"
612d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo			:
622d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo			: "r" (start)
632d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo		);
642d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo		start += LINESIZE;
652d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo	}
662d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo	__asm__ __volatile__ (
672d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo		"isync"
682d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo	);
692d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo	local_irq_restore(flags);
702d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo}
712d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo
722d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuovoid hexagon_clean_dcache_range(unsigned long start, unsigned long end)
732d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo{
742d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo	unsigned long lines = spanlines(start, end-1);
752d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo	unsigned long i, flags;
762d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo
772d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo	start &= ~(LINESIZE - 1);
782d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo
792d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo	local_irq_save(flags);
802d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo
812d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo	for (i = 0; i < lines; i++) {
822d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo		__asm__ __volatile__ (
832d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo		"	dccleana(%0);	"
842d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo		:
852d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo		: "r" (start)
862d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo		);
872d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo		start += LINESIZE;
882d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo	}
892d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo	local_irq_restore(flags);
902d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo}
912d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo
922d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuovoid hexagon_inv_dcache_range(unsigned long start, unsigned long end)
932d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo{
942d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo	unsigned long lines = spanlines(start, end-1);
952d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo	unsigned long i, flags;
962d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo
972d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo	start &= ~(LINESIZE - 1);
982d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo
992d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo	local_irq_save(flags);
1002d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo
1012d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo	for (i = 0; i < lines; i++) {
1022d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo		__asm__ __volatile__ (
1032d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo		"	dcinva(%0);	"
1042d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo		:
1052d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo		: "r" (start)
1062d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo		);
1072d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo		start += LINESIZE;
1082d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo	}
1092d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo	local_irq_restore(flags);
1102d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo}
1112d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo
1122d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo
1132d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo
1142d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo
1152d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo/*
1162d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo * This is just really brutal and shouldn't be used anyways,
1172d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo * especially on V2.  Left here just in case.
1182d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo */
1192d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuovoid flush_cache_all_hexagon(void)
1202d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo{
1212d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo	unsigned long flags;
1222d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo	local_irq_save(flags);
1232d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo	__vmcache_ickill();
1242d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo	__vmcache_dckill();
1252d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo	__vmcache_l2kill();
1262d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo	local_irq_restore(flags);
1272d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo	mb();
1282d3cbc780437ae4e81f09d0efdd6769852bce5f5Richard Kuo}
129