xref: /rk3399_rockchip-uboot/arch/nds32/include/asm/macro.h (revision 45fe3809b9923b92f221d70eb45ae071059fd5e0)
100f892fcSMacpaul Lin /*
200f892fcSMacpaul Lin  * include/asm-nds32/macro.h
300f892fcSMacpaul Lin  *
400f892fcSMacpaul Lin  * Copyright (C) 2009 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
500f892fcSMacpaul Lin  * Copyright (C) 2011 Andes Technology Corporation
600f892fcSMacpaul Lin  * Macpaul Lin, Andes Technology Corporation <macpaul@andestech.com>
700f892fcSMacpaul Lin  *
81a459660SWolfgang Denk  * SPDX-License-Identifier:	GPL-2.0+
900f892fcSMacpaul Lin  */
1000f892fcSMacpaul Lin 
1100f892fcSMacpaul Lin #ifndef __ASM_NDS_MACRO_H
1200f892fcSMacpaul Lin #define __ASM_NDS_MACRO_H
1300f892fcSMacpaul Lin #ifdef __ASSEMBLY__
1400f892fcSMacpaul Lin 
1500f892fcSMacpaul Lin /*
1600f892fcSMacpaul Lin  * These macros provide a convenient way to write 8, 16 and 32 bit data
1700f892fcSMacpaul Lin  * to an "immediate address (address used by periphal)" only.
1800f892fcSMacpaul Lin  * Registers r4 and r5 are used, any data in these registers are
1900f892fcSMacpaul Lin  * overwritten by the macros.
2000f892fcSMacpaul Lin  * The macros are valid for any NDS32 architecture, they do not implement
2100f892fcSMacpaul Lin  * any memory barriers so caution is recommended when using these when the
2200f892fcSMacpaul Lin  * caches are enabled or on a multi-core system.
2300f892fcSMacpaul Lin  */
2400f892fcSMacpaul Lin 
2500f892fcSMacpaul Lin .macro	write32, addr, data
26*b19cc6bfSrick 	li	$r4, \addr
27*b19cc6bfSrick 	li	$r5, \data
2800f892fcSMacpaul Lin 	swi	$r5, [$r4]
2900f892fcSMacpaul Lin .endm
3000f892fcSMacpaul Lin 
3100f892fcSMacpaul Lin .macro	write16, addr, data
32*b19cc6bfSrick 	li	$r4, \addr
33*b19cc6bfSrick 	li	$r5, \data
3400f892fcSMacpaul Lin 	shi	$r5, [$r4]
3500f892fcSMacpaul Lin .endm
3600f892fcSMacpaul Lin 
3700f892fcSMacpaul Lin .macro	write8, addr, data
38*b19cc6bfSrick 	li	$r4, \addr
39*b19cc6bfSrick 	li	$r5, \data
4000f892fcSMacpaul Lin 	sbi	$r5, [$r4]
4100f892fcSMacpaul Lin .endm
4200f892fcSMacpaul Lin 
4300f892fcSMacpaul Lin /*
4400f892fcSMacpaul Lin  * This macro read a value from a register, then do OR operation
4500f892fcSMacpaul Lin  * (set bit fields) to the value, and then store it back to the register.
4600f892fcSMacpaul Lin  * Note: Instruction 'ori' supports immediate value up to 15 bits.
4700f892fcSMacpaul Lin  */
4800f892fcSMacpaul Lin .macro	setbf32, addr, data
49*b19cc6bfSrick 	li	$r4, \addr
5000f892fcSMacpaul Lin 	lwi	$r5, [$r4]
51*b19cc6bfSrick 	li	$r6, \data
5200f892fcSMacpaul Lin 	or	$r5, $r5, $r6
5300f892fcSMacpaul Lin 	swi	$r5, [$r4]
5400f892fcSMacpaul Lin .endm
5500f892fcSMacpaul Lin 
5600f892fcSMacpaul Lin .macro	setbf15, addr, data
57*b19cc6bfSrick 	li	$r4, \addr
5800f892fcSMacpaul Lin 	lwi	$r5, [$r4]
59*b19cc6bfSrick 	ori	$r5, $r5, \data
6000f892fcSMacpaul Lin 	swi	$r5, [$r4]
6100f892fcSMacpaul Lin .endm
6200f892fcSMacpaul Lin 
6300f892fcSMacpaul Lin /*
6400f892fcSMacpaul Lin  * This macro generates a loop that can be used for delays in the code.
6500f892fcSMacpaul Lin  * Register r4 is used, any data in this register is overwritten by the
6600f892fcSMacpaul Lin  * macro.
6700f892fcSMacpaul Lin  * The macro is valid for any NDS32 architeture. The actual time spent in the
6800f892fcSMacpaul Lin  * loop will vary from CPU to CPU though.
6900f892fcSMacpaul Lin  */
7000f892fcSMacpaul Lin 
7100f892fcSMacpaul Lin .macro	wait_timer, time
72*b19cc6bfSrick 	li	$r4, \time
7300f892fcSMacpaul Lin 1:
7400f892fcSMacpaul Lin 	nop
7500f892fcSMacpaul Lin 	addi	$r4, $r4, -1
7600f892fcSMacpaul Lin 	bnez    $r4, 1b
7700f892fcSMacpaul Lin .endm
7800f892fcSMacpaul Lin 
7900f892fcSMacpaul Lin #endif /* __ASSEMBLY__ */
8000f892fcSMacpaul Lin #endif /* __ASM_ARM_MACRO_H */
81