]> git.karo-electronics.de Git - karo-tx-uboot.git/blob - arch/arm/mach-socfpga/scan_manager.c
arm: socfpga: scan: Clean up scan_chain_engine_is_idle()
[karo-tx-uboot.git] / arch / arm / mach-socfpga / scan_manager.c
1 /*
2  *  Copyright (C) 2013 Altera Corporation <www.altera.com>
3  *
4  * SPDX-License-Identifier:     GPL-2.0+
5  */
6
7 #include <common.h>
8 #include <errno.h>
9 #include <asm/io.h>
10 #include <asm/arch/freeze_controller.h>
11 #include <asm/arch/scan_manager.h>
12
13 /*
14  * Maximum polling loop to wait for IO scan chain engine becomes idle
15  * to prevent infinite loop. It is important that this is NOT changed
16  * to delay using timer functions, since at the time this function is
17  * called, timer might not yet be inited.
18  */
19 #define SCANMGR_MAX_DELAY               100
20
21 #define SCANMGR_STAT_ACTIVE             (1 << 31)
22 #define SCANMGR_STAT_WFIFOCNT_MASK      0x70000000
23
24 DECLARE_GLOBAL_DATA_PTR;
25
26 static const struct socfpga_scan_manager *scan_manager_base =
27                 (void *)(SOCFPGA_SCANMGR_ADDRESS);
28 static const struct socfpga_freeze_controller *freeze_controller_base =
29                 (void *)(SOCFPGA_SYSMGR_ADDRESS + SYSMGR_FRZCTRL_ADDRESS);
30
31 /**
32  * scan_chain_engine_is_idle() - Check if the JTAG scan chain is idle
33  * @max_iter:   Maximum number of iterations to wait for idle
34  *
35  * Function to check IO scan chain engine status and wait if the engine is
36  * is active. Poll the IO scan chain engine till maximum iteration reached.
37  */
38 static u32 scan_chain_engine_is_idle(u32 max_iter)
39 {
40         const u32 mask = SCANMGR_STAT_ACTIVE | SCANMGR_STAT_WFIFOCNT_MASK;
41         u32 status;
42
43         /* Poll the engine until the scan engine is inactive. */
44         do {
45                 status = readl(&scan_manager_base->stat);
46                 if (!(status & mask))
47                         return 0;
48         } while (max_iter--);
49
50         return -ETIMEDOUT;
51 }
52
53 /**
54  * scan_mgr_io_scan_chain_prg() - Program HPS IO Scan Chain
55  * @io_scan_chain_id:           IO scan chain ID
56  */
57 static int scan_mgr_io_scan_chain_prg(const unsigned int io_scan_chain_id)
58 {
59         uint16_t tdi_tdo_header;
60         uint32_t io_program_iter;
61         uint32_t io_scan_chain_data_residual;
62         uint32_t residual;
63         uint32_t i, ret;
64         uint32_t index = 0;
65         uint32_t io_scan_chain_len_in_bits;
66         const unsigned long *iocsr_scan_chain;
67
68         ret = iocsr_get_config_table(io_scan_chain_id, &iocsr_scan_chain,
69                                      &io_scan_chain_len_in_bits);
70         if (ret)
71                 return 1;
72
73         /*
74          * De-assert reinit if the IO scan chain is intended for HIO. In
75          * this, its the chain 3.
76          */
77         if (io_scan_chain_id == 3)
78                 clrbits_le32(&freeze_controller_base->hioctrl,
79                              SYSMGR_FRZCTRL_HIOCTRL_DLLRST_MASK);
80
81         /*
82          * Check if the scan chain engine is inactive and the
83          * WFIFO is empty before enabling the IO scan chain
84          */
85         ret = scan_chain_engine_is_idle(SCANMGR_MAX_DELAY);
86         if (ret)
87                 return ret;
88
89         /*
90          * Enable IO Scan chain based on scan chain id
91          * Note: only one chain can be enabled at a time
92          */
93         setbits_le32(&scan_manager_base->en, 1 << io_scan_chain_id);
94
95         /*
96          * Calculate number of iteration needed for full 128-bit (4 x32-bits)
97          * bits shifting. Each TDI_TDO packet can shift in maximum 128-bits
98          */
99         io_program_iter = io_scan_chain_len_in_bits >>
100                 IO_SCAN_CHAIN_128BIT_SHIFT;
101         io_scan_chain_data_residual = io_scan_chain_len_in_bits &
102                 IO_SCAN_CHAIN_128BIT_MASK;
103
104         /* Construct TDI_TDO packet for 128-bit IO scan chain (2 bytes) */
105         tdi_tdo_header = TDI_TDO_HEADER_FIRST_BYTE |
106                 (TDI_TDO_MAX_PAYLOAD << TDI_TDO_HEADER_SECOND_BYTE_SHIFT);
107
108         /* Program IO scan chain in 128-bit iteration */
109         for (i = 0; i < io_program_iter; i++) {
110                 /* write TDI_TDO packet header to scan manager */
111                 writel(tdi_tdo_header,  &scan_manager_base->fifo_double_byte);
112
113                 /* calculate array index. Multiply by 4 as write 4 x 32bits */
114                 index = i * 4;
115
116                 /* write 4 successive 32-bit IO scan chain data into WFIFO */
117                 writel(iocsr_scan_chain[index],
118                        &scan_manager_base->fifo_quad_byte);
119                 writel(iocsr_scan_chain[index + 1],
120                        &scan_manager_base->fifo_quad_byte);
121                 writel(iocsr_scan_chain[index + 2],
122                        &scan_manager_base->fifo_quad_byte);
123                 writel(iocsr_scan_chain[index + 3],
124                        &scan_manager_base->fifo_quad_byte);
125
126                 /*
127                  * Check if the scan chain engine has completed the
128                  * IO scan chain data shifting
129                  */
130                 ret = scan_chain_engine_is_idle(SCANMGR_MAX_DELAY);
131                 if (ret)
132                         goto error;
133         }
134
135         /* Calculate array index for final TDI_TDO packet */
136         index = io_program_iter * 4;
137
138         /* Final TDI_TDO packet if any */
139         if (io_scan_chain_data_residual) {
140                 /*
141                  * Calculate number of quad bytes FIFO write
142                  * needed for the final TDI_TDO packet
143                  */
144                 io_program_iter = io_scan_chain_data_residual >>
145                         IO_SCAN_CHAIN_32BIT_SHIFT;
146
147                 /*
148                  * Construct TDI_TDO packet for remaining IO
149                  * scan chain (2 bytes)
150                  */
151                 tdi_tdo_header  = TDI_TDO_HEADER_FIRST_BYTE |
152                         ((io_scan_chain_data_residual - 1) <<
153                         TDI_TDO_HEADER_SECOND_BYTE_SHIFT);
154
155                 /*
156                  * Program the last part of IO scan chain write TDI_TDO packet
157                  * header (2 bytes) to scan manager
158                  */
159                 writel(tdi_tdo_header, &scan_manager_base->fifo_double_byte);
160
161                 for (i = 0; i < io_program_iter; i++) {
162                         /*
163                          * write remaining scan chain data into scan
164                          * manager WFIFO with 4 bytes write
165                         */
166                         writel(iocsr_scan_chain[index + i],
167                                &scan_manager_base->fifo_quad_byte);
168                 }
169
170                 index += io_program_iter;
171                 residual = io_scan_chain_data_residual &
172                         IO_SCAN_CHAIN_32BIT_MASK;
173
174                 if (IO_SCAN_CHAIN_PAYLOAD_24BIT < residual) {
175                         /*
176                          * write the last 4B scan chain data
177                          * into scan manager WFIFO
178                          */
179                         writel(iocsr_scan_chain[index],
180                                &scan_manager_base->fifo_quad_byte);
181                 } else {
182                         /*
183                          * write the remaining 1 - 3 bytes scan chain
184                          * data into scan manager WFIFO byte by byte
185                          * to prevent JTAG engine shifting unused data
186                          * from the FIFO and mistaken the data as a
187                          * valid command (even though unused bits are
188                          * set to 0, but just to prevent hardware
189                          * glitch)
190                          */
191                         for (i = 0; i < residual; i += 8) {
192                                 writel(((iocsr_scan_chain[index] >> i)
193                                         & IO_SCAN_CHAIN_BYTE_MASK),
194                                         &scan_manager_base->fifo_single_byte);
195                         }
196                 }
197
198                 /*
199                  * Check if the scan chain engine has completed the
200                  * IO scan chain data shifting
201                  */
202                 ret = scan_chain_engine_is_idle(SCANMGR_MAX_DELAY);
203                 if (ret)
204                         goto error;
205         }
206
207         /* Disable IO Scan chain when configuration done*/
208         clrbits_le32(&scan_manager_base->en, 1 << io_scan_chain_id);
209         return 0;
210
211 error:
212         /* Disable IO Scan chain when error detected */
213         clrbits_le32(&scan_manager_base->en, 1 << io_scan_chain_id);
214         return ret;
215 }
216
217 int scan_mgr_configure_iocsr(void)
218 {
219         int status = 0;
220
221         /* configure the IOCSR through scan chain */
222         status |= scan_mgr_io_scan_chain_prg(0);
223         status |= scan_mgr_io_scan_chain_prg(1);
224         status |= scan_mgr_io_scan_chain_prg(2);
225         status |= scan_mgr_io_scan_chain_prg(3);
226         return status;
227 }