/*
 * SMP/VPE-safe functions to access "registers" (see note).
 *
 * NOTES:
* - These macros use ll/sc instructions, so it is your responsibility to
 * ensure these are available on your platform before including this file.
 * - The MIPS32 spec states that ll/sc results are undefined for uncached
 * accesses. This means they can't be used on HW registers accessed
 * through kseg1. Code which requires these macros for this purpose must
 * front-end the registers with cached memory "registers" and have a single
 * thread update the actual HW registers.
 * - A maximum of 2k of code can be inserted between ll and sc. Every
 * memory accesses between the instructions will increase the chance of
 * sc failing and having to loop.
 * - When using custom_read_reg32/custom_write_reg32 only perform the
 * necessary logical operations on the register value in between these
 * two calls. All other logic should be performed before the first call.
  * - There is a bug on the R10000 chips which has a workaround. If you
 * are affected by this bug, make sure to define the symbol 'R10000_LLSC_WAR'
 * to be non-zero.  If you are using this header from within linux, you may
 * include <asm/war.h> before including this file to have this defined
 * appropriately for you.
 *
 * Copyright 2005-2007 PMC-Sierra, Inc.
 *
 *  This program is free software; you can redistribute  it and/or modify it
 *  under  the terms of  the GNU General  Public License as published by the
 *  Free Software Foundation;  either version 2 of the  License, or (at your
 *  option) any later version.
 *
 *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
 *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
 *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO
 *  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 *  LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF USE,
 *  DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 *  THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *  You should have received a copy of the  GNU General Public License along
 *  with this program; if not, write  to the Free Software Foundation, Inc., 675
 *  Mass Ave, Cambridge, MA 02139, USA.
 */

#ifndef __ASM_REGOPS_H__
#define __ASM_REGOPS_H__

#include <linux/types.h>

#include <asm/compiler.h>
#include <asm/war.h>

#ifndef R10000_LLSC_WAR
#define R10000_LLSC_WAR 0
#endif

#if R10000_LLSC_WAR == 1
#define __beqz	"beqzl	"
#else
#define __beqz	"beqz	"
#endif

#ifndef _LINUX_TYPES_H
typedef unsigned int u32;
#endif

/*
 * Sets all the masked bits to the corresponding value bits
 */
static inline void set_value_reg32(volatile u32 *const addr,
					u32 const mask,
					u32 const value)
{
	u32 temp;

	__asm__ __volatile__(
	"	.set	push				\n"
	"	.set	arch=r4000			\n"
	"1:	ll	%0, %1	# set_value_reg32	\n"
	"	and	%0, %2				\n"
	"	or	%0, %3				\n"
	"	sc	%0, %1				\n"
	"	"__beqz"%0, 1b				\n"
	"	nop					\n"
	"	.set	pop				\n"
	: "=&r" (temp), "=" GCC_OFF_SMALL_ASM() (*addr)
	: "ir" (~mask), "ir" (value), GCC_OFF_SMALL_ASM() (*addr));
}

/*
 * Sets all the masked bits to '1'
 */
static inline void set_reg32(volatile u32 *const addr,
				u32 const mask)
{
	u32 temp;

	__asm__ __volatile__(
	"	.set	push				\n"
	"	.set	arch=r4000			\n"
	"1:	ll	%0, %1		# set_reg32	\n"
	"	or	%0, %2				\n"
	"	sc	%0, %1				\n"
	"	"__beqz"%0, 1b				\n"
	"	nop					\n"
	"	.set	pop				\n"
	: "=&r" (temp), "=" GCC_OFF_SMALL_ASM() (*addr)
	: "ir" (mask), GCC_OFF_SMALL_ASM() (*addr));
}

/*
 * Sets all the masked bits to '0'
 */
static inline void clear_reg32(volatile u32 *const addr,
				u32 const mask)
{
	u32 temp;

	__asm__ __volatile__(
	"	.set	push				\n"
	"	.set	arch=r4000			\n"
	"1:	ll	%0, %1		# clear_reg32	\n"
	"	and	%0, %2				\n"
	"	sc	%0, %1				\n"
	"	"__beqz"%0, 1b				\n"
	"	nop					\n"
	"	.set	pop				\n"
	: "=&r" (temp), "=" GCC_OFF_SMALL_ASM() (*addr)
	: "ir" (~mask), GCC_OFF_SMALL_ASM() (*addr));
}

/*
 * Toggles all masked bits from '0' to '1' and '1' to '0'
 */
static inline void toggle_reg32(volatile u32 *const addr,
				u32 const mask)
{
	u32 temp;

	__asm__ __volatile__(
	"	.set	push				\n"
	"	.set	arch=r4000			\n"
	"1:	ll	%0, %1		# toggle_reg32	\n"
	"	xor	%0, %2				\n"
	"	sc	%0, %1				\n"
	"	"__beqz"%0, 1b				\n"
	"	nop					\n"
	"	.set	pop				\n"
	: "=&r" (temp), "=" GCC_OFF_SMALL_ASM() (*addr)
	: "ir" (mask), GCC_OFF_SMALL_ASM() (*addr));
}

/*
 * Read all masked bits others are returned as '0'
 */
static inline u32 read_reg32(volatile u32 *const addr,
				u32 const mask)
{
	u32 temp;

	__asm__ __volatile__(
	"	.set	push				\n"
	"	.set	noreorder			\n"
	"	lw	%0, %1		# read		\n"
	"	and	%0, %2		# mask		\n"
	"	.set	pop				\n"
	: "=&r" (temp)
	: "m" (*addr), "ir" (mask));

	return temp;
}

/*
 * blocking_read_reg32 - Read address with blocking load
 *
 * Uncached writes need to be read back to ensure they reach RAM.
 * The returned value must be 'used' to prevent from becoming a
 * non-blocking load.
 */
static inline u32 blocking_read_reg32(volatile u32 *const addr)
{
	u32 temp;

	__asm__ __volatile__(
	"	.set	push				\n"
	"	.set	noreorder			\n"
	"	lw	%0, %1		# read		\n"
	"	move	%0, %0		# block		\n"
	"	.set	pop				\n"
	: "=&r" (temp)
	: "m" (*addr));

	return temp;
}

/*
 * For special strange cases only:
 *
 * If you need custom processing within a ll/sc loop, use the following macros
 * VERY CAREFULLY:
 *
 *   u32 tmp;				<-- Define a variable to hold the data
 *
 *   custom_read_reg32(address, tmp);	<-- Reads the address and put the value
 *						in the 'tmp' variable given
 *
 *	From here on out, you are (basically) atomic, so don't do anything too
 *	fancy!
 *	Also, this code may loop if the end of this block fails to write
 *	everything back safely due do the other CPU, so do NOT do anything
 *	with side-effects!
 *
 *   custom_write_reg32(address, tmp);	<-- Writes back 'tmp' safely.
 */
#define custom_read_reg32(address, tmp)				\
	__asm__ __volatile__(					\
	"	.set	push				\n"	\
	"	.set	arch=r4000			\n"	\
	"1:	ll	%0, %1	#custom_read_reg32	\n"	\
	"	.set	pop				\n"	\
	: "=r" (tmp), "=" GCC_OFF_SMALL_ASM() (*address)		\
	: GCC_OFF_SMALL_ASM() (*address))

#define custom_write_reg32(address, tmp)			\
	__asm__ __volatile__(					\
	"	.set	push				\n"	\
	"	.set	arch=r4000			\n"	\
	"	sc	%0, %1	#custom_write_reg32	\n"	\
	"	"__beqz"%0, 1b				\n"	\
	"	nop					\n"	\
	"	.set	pop				\n"	\
	: "=&r" (tmp), "=" GCC_OFF_SMALL_ASM() (*address)		\
	: "0" (tmp), GCC_OFF_SMALL_ASM() (*address))

#endif	/* __ASM_REGOPS_H__ */
