1/* 2 * Copyright (C) 2000, 2001 Broadcom Corporation 3 * Copyright (C) 2002 Ralf Baechle 4 * 5 * This program is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU General Public License 7 * as published by the Free Software Foundation; either version 2 8 * of the License, or (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18 */ 19 20#ifndef __ASM_SIBYTE_64BIT_H 21#define __ASM_SIBYTE_64BIT_H 22 23#include <linux/config.h> 24#include <linux/types.h> 25 26#ifdef CONFIG_MIPS32 27 28#include <asm/system.h> 29 30/* 31 * This is annoying...we can't actually write the 64-bit IO register properly 32 * without having access to 64-bit registers... which doesn't work by default 33 * in o32 format...grrr... 34 */ 35static inline void __out64(u64 val, unsigned long addr) 36{ 37 u64 tmp; 38 39 __asm__ __volatile__ ( 40 " .set mips3 \n" 41 " dsll32 %L0, %L0, 0 # __out64 \n" 42 " dsrl32 %L0, %L0, 0 \n" 43 " dsll32 %M0, %M0, 0 \n" 44 " or %L0, %L0, %M0 \n" 45 " sd %L0, (%2) \n" 46 " .set mips0 \n" 47 : "=r" (tmp) 48 : "0" (val), "r" (addr)); 49} 50 51static inline void out64(u64 val, unsigned long addr) 52{ 53 unsigned long flags; 54 55 local_irq_save(flags); 56 __out64(val, addr); 57 local_irq_restore(flags); 58} 59 60static inline u64 __in64(unsigned long addr) 61{ 62 u64 res; 63 64 __asm__ __volatile__ ( 65 " .set mips3 # __in64 \n" 66 " ld %L0, (%1) \n" 67 " dsra32 %M0, %L0, 0 \n" 68 " sll %L0, %L0, 0 \n" 69 " .set mips0 \n" 70 : "=r" (res) 71 : "r" (addr)); 72 73 return res; 74} 75 76static inline u64 in64(unsigned long addr) 77{ 78 unsigned long flags; 79 u64 res; 80 81 local_irq_save(flags); 82 res = __in64(addr); 83 local_irq_restore(flags); 84 85 return res; 86} 87 88#endif /* CONFIG_MIPS32 */ 89 90#ifdef CONFIG_MIPS64 91 92/* 93 * These are provided so as to be able to use common 94 * driver code for the 32-bit and 64-bit trees 95 */ 96extern inline void out64(u64 val, unsigned long addr) 97{ 98 *(volatile unsigned long *)addr = val; 99} 100 101extern inline u64 in64(unsigned long addr) 102{ 103 return *(volatile unsigned long *)addr; 104} 105 106#define __in64(a) in64(a) 107#define __out64(v,a) out64(v,a) 108 109#endif /* CONFIG_MIPS64 */ 110 111/* 112 * Avoid interrupt mucking, just adjust the address for 4-byte access. 113 * Assume the addresses are 8-byte aligned. 114 */ 115 116#ifdef __MIPSEB__ 117#define __CSR_32_ADJUST 4 118#else 119#define __CSR_32_ADJUST 0 120#endif 121 122#define csr_out32(v,a) (*(u32 *)((unsigned long)(a) + __CSR_32_ADJUST) = (v)) 123#define csr_in32(a) (*(u32 *)((unsigned long)(a) + __CSR_32_ADJUST)) 124 125#endif /* __ASM_SIBYTE_64BIT_H */ 126