• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Support for reading and writing Meta core internal registers.
3  *
4  *  Copyright (C) 2011 Imagination Technologies Ltd.
5  *
6  */
7 
8 #include <linux/delay.h>
9 #include <linux/export.h>
10 
11 #include <asm/core_reg.h>
12 #include <asm/global_lock.h>
13 #include <asm/hwthread.h>
14 #include <asm/io.h>
15 #include <asm/metag_mem.h>
16 #include <asm/metag_regs.h>
17 
18 #define UNIT_BIT_MASK		TXUXXRXRQ_UXX_BITS
19 #define REG_BIT_MASK		TXUXXRXRQ_RX_BITS
20 #define THREAD_BIT_MASK		TXUXXRXRQ_TX_BITS
21 
22 #define UNIT_SHIFTS		TXUXXRXRQ_UXX_S
23 #define REG_SHIFTS		TXUXXRXRQ_RX_S
24 #define THREAD_SHIFTS		TXUXXRXRQ_TX_S
25 
26 #define UNIT_VAL(x)		(((x) << UNIT_SHIFTS) & UNIT_BIT_MASK)
27 #define REG_VAL(x)		(((x) << REG_SHIFTS) & REG_BIT_MASK)
28 #define THREAD_VAL(x)		(((x) << THREAD_SHIFTS) & THREAD_BIT_MASK)
29 
30 /*
31  * core_reg_write() - modify the content of a register in a core unit.
32  * @unit:	The unit to be modified.
33  * @reg:	Register number within the unit.
34  * @thread:	The thread we want to access.
35  * @val:	The new value to write.
36  *
37  * Check asm/metag_regs.h for a list/defines of supported units (ie: TXUPC_ID,
38  * TXUTR_ID, etc), and regnums within the units (ie: TXMASKI_REGNUM,
39  * TXPOLLI_REGNUM, etc).
40  */
core_reg_write(int unit,int reg,int thread,unsigned int val)41 void core_reg_write(int unit, int reg, int thread, unsigned int val)
42 {
43 	unsigned long flags;
44 
45 	/* TXUCT_ID has its own memory mapped registers */
46 	if (unit == TXUCT_ID) {
47 		void __iomem *cu_reg = __CU_addr(thread, reg);
48 		metag_out32(val, cu_reg);
49 		return;
50 	}
51 
52 	__global_lock2(flags);
53 
54 	/* wait for ready */
55 	while (!(metag_in32(TXUXXRXRQ) & TXUXXRXRQ_DREADY_BIT))
56 		udelay(10);
57 
58 	/* set the value to write */
59 	metag_out32(val, TXUXXRXDT);
60 
61 	/* set the register to write */
62 	val = UNIT_VAL(unit) | REG_VAL(reg) | THREAD_VAL(thread);
63 	metag_out32(val, TXUXXRXRQ);
64 
65 	/* wait for finish */
66 	while (!(metag_in32(TXUXXRXRQ) & TXUXXRXRQ_DREADY_BIT))
67 		udelay(10);
68 
69 	__global_unlock2(flags);
70 }
71 EXPORT_SYMBOL(core_reg_write);
72 
73 /*
74  * core_reg_read() - read the content of a register in a core unit.
75  * @unit:	The unit to be modified.
76  * @reg:	Register number within the unit.
77  * @thread:	The thread we want to access.
78  *
79  * Check asm/metag_regs.h for a list/defines of supported units (ie: TXUPC_ID,
80  * TXUTR_ID, etc), and regnums within the units (ie: TXMASKI_REGNUM,
81  * TXPOLLI_REGNUM, etc).
82  */
core_reg_read(int unit,int reg,int thread)83 unsigned int core_reg_read(int unit, int reg, int thread)
84 {
85 	unsigned long flags;
86 	unsigned int val;
87 
88 	/* TXUCT_ID has its own memory mapped registers */
89 	if (unit == TXUCT_ID) {
90 		void __iomem *cu_reg = __CU_addr(thread, reg);
91 		val = metag_in32(cu_reg);
92 		return val;
93 	}
94 
95 	__global_lock2(flags);
96 
97 	/* wait for ready */
98 	while (!(metag_in32(TXUXXRXRQ) & TXUXXRXRQ_DREADY_BIT))
99 		udelay(10);
100 
101 	/* set the register to read */
102 	val = (UNIT_VAL(unit) | REG_VAL(reg) | THREAD_VAL(thread) |
103 							TXUXXRXRQ_RDnWR_BIT);
104 	metag_out32(val, TXUXXRXRQ);
105 
106 	/* wait for finish */
107 	while (!(metag_in32(TXUXXRXRQ) & TXUXXRXRQ_DREADY_BIT))
108 		udelay(10);
109 
110 	/* read the register value */
111 	val = metag_in32(TXUXXRXDT);
112 
113 	__global_unlock2(flags);
114 
115 	return val;
116 }
117 EXPORT_SYMBOL(core_reg_read);
118