cvmx-helper-jtag.c revision 215976
1 2/***********************license start*************** 3 * Copyright (c) 2003-2010 Cavium Networks (support@cavium.com). All rights 4 * reserved. 5 * 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions are 9 * met: 10 * 11 * * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 14 * * Redistributions in binary form must reproduce the above 15 * copyright notice, this list of conditions and the following 16 * disclaimer in the documentation and/or other materials provided 17 * with the distribution. 18 19 * * Neither the name of Cavium Networks nor the names of 20 * its contributors may be used to endorse or promote products 21 * derived from this software without specific prior written 22 * permission. 23 24 * This Software, including technical data, may be subject to U.S. export control 25 * laws, including the U.S. Export Administration Act and its associated 26 * regulations, and may be subject to export or import regulations in other 27 * countries. 28 29 * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS" 30 * AND WITH ALL FAULTS AND CAVIUM NETWORKS MAKES NO PROMISES, REPRESENTATIONS OR 31 * WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO 32 * THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY REPRESENTATION OR 33 * DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT DEFECTS, AND CAVIUM 34 * SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES OF TITLE, 35 * MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF 36 * VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR 37 * CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK ARISING OUT OF USE OR 38 * PERFORMANCE OF THE SOFTWARE LIES WITH YOU. 39 ***********************license end**************************************/ 40 41 42/** 43 * @file 44 * 45 * Helper utilities for qlm_jtag. 46 * 47 * <hr>$Revision: 42480 $<hr> 48 */ 49#ifdef CVMX_BUILD_FOR_LINUX_KERNEL 50#include <asm/octeon/cvmx.h> 51#include <asm/octeon/cvmx-clock.h> 52#include <asm/octeon/cvmx-helper-jtag.h> 53#else 54#include "executive-config.h" 55#include "cvmx-config.h" 56#include "cvmx.h" 57#endif 58 59/** 60 * Initialize the internal QLM JTAG logic to allow programming 61 * of the JTAG chain by the cvmx_helper_qlm_jtag_*() functions. 62 * These functions should only be used at the direction of Cavium 63 * Networks. Programming incorrect values into the JTAG chain 64 * can cause chip damage. 65 */ 66void cvmx_helper_qlm_jtag_init(void) 67{ 68 cvmx_ciu_qlm_jtgc_t jtgc; 69 int clock_div = 0; 70 int divisor = cvmx_clock_get_rate(CVMX_CLOCK_SCLK) / (25 * 1000000); 71 divisor = (divisor-1)>>2; 72 /* Convert the divisor into a power of 2 shift */ 73 while (divisor) 74 { 75 clock_div++; 76 divisor>>=1; 77 } 78 79 /* Clock divider for QLM JTAG operations. sclk is divided by 2^(CLK_DIV + 2) */ 80 jtgc.u64 = 0; 81 jtgc.s.clk_div = clock_div; 82 jtgc.s.mux_sel = 0; 83 if (OCTEON_IS_MODEL(OCTEON_CN52XX)) 84 jtgc.s.bypass = 0x3; 85 else if (OCTEON_IS_MODEL(OCTEON_CN63XX)) 86 jtgc.s.bypass = 0x7; 87 else 88 jtgc.s.bypass = 0xf; 89 cvmx_write_csr(CVMX_CIU_QLM_JTGC, jtgc.u64); 90 cvmx_read_csr(CVMX_CIU_QLM_JTGC); 91} 92 93 94/** 95 * Write up to 32bits into the QLM jtag chain. Bits are shifted 96 * into the MSB and out the LSB, so you should shift in the low 97 * order bits followed by the high order bits. The JTAG chain for 98 * CN52XX and CN56XX is 4 * 268 bits long, or 1072. The JTAG chain 99 * for CN63XX is 4 * 300 bits long, or 1200. 100 * 101 * @param qlm QLM to shift value into 102 * @param bits Number of bits to shift in (1-32). 103 * @param data Data to shift in. Bit 0 enters the chain first, followed by 104 * bit 1, etc. 105 * 106 * @return The low order bits of the JTAG chain that shifted out of the 107 * circle. 108 */ 109uint32_t cvmx_helper_qlm_jtag_shift(int qlm, int bits, uint32_t data) 110{ 111 cvmx_ciu_qlm_jtgc_t jtgc; 112 cvmx_ciu_qlm_jtgd_t jtgd; 113 114 jtgc.u64 = cvmx_read_csr(CVMX_CIU_QLM_JTGC); 115 jtgc.s.mux_sel = qlm; 116 if (!OCTEON_IS_MODEL(OCTEON_CN63XX)) 117 jtgc.s.bypass = 1<<qlm; 118 cvmx_write_csr(CVMX_CIU_QLM_JTGC, jtgc.u64); 119 cvmx_read_csr(CVMX_CIU_QLM_JTGC); 120 121 jtgd.u64 = 0; 122 jtgd.s.shift = 1; 123 jtgd.s.shft_cnt = bits-1; 124 jtgd.s.shft_reg = data; 125 if (!OCTEON_IS_MODEL(OCTEON_CN56XX_PASS1_X)) 126 jtgd.s.select = 1 << qlm; 127 cvmx_write_csr(CVMX_CIU_QLM_JTGD, jtgd.u64); 128 do 129 { 130 jtgd.u64 = cvmx_read_csr(CVMX_CIU_QLM_JTGD); 131 } while (jtgd.s.shift); 132 return jtgd.s.shft_reg >> (32-bits); 133} 134 135 136/** 137 * Shift long sequences of zeros into the QLM JTAG chain. It is 138 * common to need to shift more than 32 bits of zeros into the 139 * chain. This function is a convience wrapper around 140 * cvmx_helper_qlm_jtag_shift() to shift more than 32 bits of 141 * zeros at a time. 142 * 143 * @param qlm QLM to shift zeros into 144 * @param bits 145 */ 146void cvmx_helper_qlm_jtag_shift_zeros(int qlm, int bits) 147{ 148 while (bits > 0) 149 { 150 int n = bits; 151 if (n > 32) 152 n = 32; 153 cvmx_helper_qlm_jtag_shift(qlm, n, 0); 154 bits -= n; 155 } 156} 157 158 159/** 160 * Program the QLM JTAG chain into all lanes of the QLM. You must 161 * have already shifted in the proper number of bits into the 162 * JTAG chain. Updating invalid values can possibly cause chip damage. 163 * 164 * @param qlm QLM to program 165 */ 166void cvmx_helper_qlm_jtag_update(int qlm) 167{ 168 cvmx_ciu_qlm_jtgc_t jtgc; 169 cvmx_ciu_qlm_jtgd_t jtgd; 170 171 jtgc.u64 = cvmx_read_csr(CVMX_CIU_QLM_JTGC); 172 jtgc.s.mux_sel = qlm; 173 if (!OCTEON_IS_MODEL(OCTEON_CN63XX)) 174 jtgc.s.bypass = 1<<qlm; 175 176 cvmx_write_csr(CVMX_CIU_QLM_JTGC, jtgc.u64); 177 cvmx_read_csr(CVMX_CIU_QLM_JTGC); 178 179 /* Update the new data */ 180 jtgd.u64 = 0; 181 jtgd.s.update = 1; 182 if (!OCTEON_IS_MODEL(OCTEON_CN56XX_PASS1_X)) 183 jtgd.s.select = 1 << qlm; 184 cvmx_write_csr(CVMX_CIU_QLM_JTGD, jtgd.u64); 185 do 186 { 187 jtgd.u64 = cvmx_read_csr(CVMX_CIU_QLM_JTGD); 188 } while (jtgd.s.update); 189} 190 191 192/** 193 * Load the QLM JTAG chain with data from all lanes of the QLM. 194 * 195 * @param qlm QLM to program 196 */ 197void cvmx_helper_qlm_jtag_capture(int qlm) 198{ 199 cvmx_ciu_qlm_jtgc_t jtgc; 200 cvmx_ciu_qlm_jtgd_t jtgd; 201 202 jtgc.u64 = cvmx_read_csr(CVMX_CIU_QLM_JTGC); 203 jtgc.s.mux_sel = qlm; 204 if (!OCTEON_IS_MODEL(OCTEON_CN63XX)) 205 jtgc.s.bypass = 1<<qlm; 206 207 cvmx_write_csr(CVMX_CIU_QLM_JTGC, jtgc.u64); 208 cvmx_read_csr(CVMX_CIU_QLM_JTGC); 209 210 jtgd.u64 = 0; 211 jtgd.s.capture = 1; 212 if (!OCTEON_IS_MODEL(OCTEON_CN56XX_PASS1_X)) 213 jtgd.s.select = 1 << qlm; 214 cvmx_write_csr(CVMX_CIU_QLM_JTGD, jtgd.u64); 215 do 216 { 217 jtgd.u64 = cvmx_read_csr(CVMX_CIU_QLM_JTGD); 218 } while (jtgd.s.capture); 219} 220 221