]> git.sur5r.net Git - u-boot/blob - arch/arm/mach-socfpga/scan_manager.c
arm: socfpga: scan: Zap redundant params in scan_mgr_io_scan_chain_prg()
[u-boot] / 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 <asm/io.h>
9 #include <asm/arch/freeze_controller.h>
10 #include <asm/arch/scan_manager.h>
11
12 DECLARE_GLOBAL_DATA_PTR;
13
14 static const struct socfpga_scan_manager *scan_manager_base =
15                 (void *)(SOCFPGA_SCANMGR_ADDRESS);
16 static const struct socfpga_freeze_controller *freeze_controller_base =
17                 (void *)(SOCFPGA_SYSMGR_ADDRESS + SYSMGR_FRZCTRL_ADDRESS);
18
19 /*
20  * Function to check IO scan chain engine status and wait if the engine is
21  * is active. Poll the IO scan chain engine till maximum iteration reached.
22  */
23 static inline uint32_t scan_chain_engine_is_idle(uint32_t max_iter)
24 {
25         uint32_t scanmgr_status;
26
27         scanmgr_status = readl(&scan_manager_base->stat);
28
29         /* Poll the engine until the scan engine is inactive */
30         while (SCANMGR_STAT_ACTIVE_GET(scanmgr_status) ||
31               (SCANMGR_STAT_WFIFOCNT_GET(scanmgr_status) > 0)) {
32                 max_iter--;
33                 if (max_iter > 0)
34                         scanmgr_status = readl(&scan_manager_base->stat);
35                 else
36                         return 0;
37         }
38         return 1;
39 }
40
41 /**
42  * scan_mgr_io_scan_chain_prg() - Program HPS IO Scan Chain
43  * @io_scan_chain_id:           IO scan chain ID
44  */
45 static int scan_mgr_io_scan_chain_prg(const unsigned int io_scan_chain_id)
46 {
47         uint16_t tdi_tdo_header;
48         uint32_t io_program_iter;
49         uint32_t io_scan_chain_data_residual;
50         uint32_t residual;
51         uint32_t i;
52         uint32_t index = 0;
53         uint32_t io_scan_chain_len_in_bits,
54         const uint32_t *iocsr_scan_chain;
55
56         switch (io_scan_chain_id) {
57         case 0:
58                 io_scan_chain_len_in_bits = CONFIG_HPS_IOCSR_SCANCHAIN0_LENGTH;
59                 iocsr_scan_chain = iocsr_scan_chain0_table;
60                 break;
61         case 1:
62                 io_scan_chain_len_in_bits = CONFIG_HPS_IOCSR_SCANCHAIN1_LENGTH;
63                 iocsr_scan_chain = iocsr_scan_chain1_table;
64                 break;
65         case 2:
66                 io_scan_chain_len_in_bits = CONFIG_HPS_IOCSR_SCANCHAIN2_LENGTH;
67                 iocsr_scan_chain = iocsr_scan_chain2_table;
68                 break;
69         case 3:
70                 io_scan_chain_len_in_bits = CONFIG_HPS_IOCSR_SCANCHAIN3_LENGTH;
71                 iocsr_scan_chain = iocsr_scan_chain3_table;
72                 break;
73         }
74
75         /*
76          * De-assert reinit if the IO scan chain is intended for HIO. In
77          * this, its the chain 3.
78          */
79         if (io_scan_chain_id == 3)
80                 clrbits_le32(&freeze_controller_base->hioctrl,
81                              SYSMGR_FRZCTRL_HIOCTRL_DLLRST_MASK);
82
83         /*
84          * Check if the scan chain engine is inactive and the
85          * WFIFO is empty before enabling the IO scan chain
86          */
87         if (!scan_chain_engine_is_idle(SCAN_MAX_DELAY))
88                 return 1;
89
90         /*
91          * Enable IO Scan chain based on scan chain id
92          * Note: only one chain can be enabled at a time
93          */
94         setbits_le32(&scan_manager_base->en, 1 << io_scan_chain_id);
95
96         /*
97          * Calculate number of iteration needed for full 128-bit (4 x32-bits)
98          * bits shifting. Each TDI_TDO packet can shift in maximum 128-bits
99          */
100         io_program_iter = io_scan_chain_len_in_bits >>
101                 IO_SCAN_CHAIN_128BIT_SHIFT;
102         io_scan_chain_data_residual = io_scan_chain_len_in_bits &
103                 IO_SCAN_CHAIN_128BIT_MASK;
104
105         /* Construct TDI_TDO packet for 128-bit IO scan chain (2 bytes) */
106         tdi_tdo_header = TDI_TDO_HEADER_FIRST_BYTE |
107                 (TDI_TDO_MAX_PAYLOAD << TDI_TDO_HEADER_SECOND_BYTE_SHIFT);
108
109         /* Program IO scan chain in 128-bit iteration */
110         for (i = 0; i < io_program_iter; i++) {
111                 /* write TDI_TDO packet header to scan manager */
112                 writel(tdi_tdo_header,  &scan_manager_base->fifo_double_byte);
113
114                 /* calculate array index. Multiply by 4 as write 4 x 32bits */
115                 index = i * 4;
116
117                 /* write 4 successive 32-bit IO scan chain data into WFIFO */
118                 writel(iocsr_scan_chain[index],
119                        &scan_manager_base->fifo_quad_byte);
120                 writel(iocsr_scan_chain[index + 1],
121                        &scan_manager_base->fifo_quad_byte);
122                 writel(iocsr_scan_chain[index + 2],
123                        &scan_manager_base->fifo_quad_byte);
124                 writel(iocsr_scan_chain[index + 3],
125                        &scan_manager_base->fifo_quad_byte);
126
127                 /*
128                  * Check if the scan chain engine has completed the
129                  * IO scan chain data shifting
130                  */
131                 if (!scan_chain_engine_is_idle(SCAN_MAX_DELAY))
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                 if (!scan_chain_engine_is_idle(SCAN_MAX_DELAY))
203                         goto error;
204         }
205
206         /* Disable IO Scan chain when configuration done*/
207         clrbits_le32(&scan_manager_base->en, 1 << io_scan_chain_id);
208         return 0;
209
210 error:
211         /* Disable IO Scan chain when error detected */
212         clrbits_le32(&scan_manager_base->en, 1 << io_scan_chain_id);
213         return 1;
214 }
215
216 int scan_mgr_configure_iocsr(void)
217 {
218         int status = 0;
219
220         /* configure the IOCSR through scan chain */
221         status |= scan_mgr_io_scan_chain_prg(0);
222         status |= scan_mgr_io_scan_chain_prg(1);
223         status |= scan_mgr_io_scan_chain_prg(2);
224         status |= scan_mgr_io_scan_chain_prg(3);
225         return status;
226 }