1215976Sjmallett 2215976Sjmallett/***********************license start*************** 3215976Sjmallett * Copyright (c) 2003-2010 Cavium Networks (support@cavium.com). All rights 4215976Sjmallett * reserved. 5215976Sjmallett * 6215976Sjmallett * 7215976Sjmallett * Redistribution and use in source and binary forms, with or without 8215976Sjmallett * modification, are permitted provided that the following conditions are 9215976Sjmallett * met: 10215976Sjmallett * 11215976Sjmallett * * Redistributions of source code must retain the above copyright 12215976Sjmallett * notice, this list of conditions and the following disclaimer. 13215976Sjmallett * 14215976Sjmallett * * Redistributions in binary form must reproduce the above 15215976Sjmallett * copyright notice, this list of conditions and the following 16215976Sjmallett * disclaimer in the documentation and/or other materials provided 17215976Sjmallett * with the distribution. 18215976Sjmallett 19215976Sjmallett * * Neither the name of Cavium Networks nor the names of 20215976Sjmallett * its contributors may be used to endorse or promote products 21215976Sjmallett * derived from this software without specific prior written 22215976Sjmallett * permission. 23215976Sjmallett 24215976Sjmallett * This Software, including technical data, may be subject to U.S. export control 25215976Sjmallett * laws, including the U.S. Export Administration Act and its associated 26215976Sjmallett * regulations, and may be subject to export or import regulations in other 27215976Sjmallett * countries. 28215976Sjmallett 29215976Sjmallett * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS" 30215976Sjmallett * AND WITH ALL FAULTS AND CAVIUM NETWORKS MAKES NO PROMISES, REPRESENTATIONS OR 31215976Sjmallett * WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO 32215976Sjmallett * THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY REPRESENTATION OR 33215976Sjmallett * DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT DEFECTS, AND CAVIUM 34215976Sjmallett * SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES OF TITLE, 35215976Sjmallett * MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF 36215976Sjmallett * VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR 37215976Sjmallett * CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK ARISING OUT OF USE OR 38215976Sjmallett * PERFORMANCE OF THE SOFTWARE LIES WITH YOU. 39215976Sjmallett ***********************license end**************************************/ 40215976Sjmallett 41215976Sjmallett 42215976Sjmallett/** 43215976Sjmallett * @file 44215976Sjmallett * 45215976Sjmallett * Helper utilities for qlm_jtag. 46215976Sjmallett * 47215976Sjmallett * <hr>$Revision: 42480 $<hr> 48215976Sjmallett */ 49215976Sjmallett#ifdef CVMX_BUILD_FOR_LINUX_KERNEL 50215976Sjmallett#include <asm/octeon/cvmx.h> 51215976Sjmallett#include <asm/octeon/cvmx-clock.h> 52215976Sjmallett#include <asm/octeon/cvmx-helper-jtag.h> 53215976Sjmallett#else 54215990Sjmallett#if !defined(__FreeBSD__) || !defined(_KERNEL) 55215976Sjmallett#include "executive-config.h" 56215976Sjmallett#include "cvmx-config.h" 57215990Sjmallett#endif 58215976Sjmallett#include "cvmx.h" 59215990Sjmallett#if defined(__FreeBSD__) && defined(_KERNEL) 60215990Sjmallett#include "cvmx-helper-jtag.h" 61215976Sjmallett#endif 62215990Sjmallett#endif 63215976Sjmallett 64215976Sjmallett/** 65215976Sjmallett * Initialize the internal QLM JTAG logic to allow programming 66215976Sjmallett * of the JTAG chain by the cvmx_helper_qlm_jtag_*() functions. 67215976Sjmallett * These functions should only be used at the direction of Cavium 68215976Sjmallett * Networks. Programming incorrect values into the JTAG chain 69215976Sjmallett * can cause chip damage. 70215976Sjmallett */ 71215976Sjmallettvoid cvmx_helper_qlm_jtag_init(void) 72215976Sjmallett{ 73215976Sjmallett cvmx_ciu_qlm_jtgc_t jtgc; 74215976Sjmallett int clock_div = 0; 75215976Sjmallett int divisor = cvmx_clock_get_rate(CVMX_CLOCK_SCLK) / (25 * 1000000); 76215976Sjmallett divisor = (divisor-1)>>2; 77215976Sjmallett /* Convert the divisor into a power of 2 shift */ 78215976Sjmallett while (divisor) 79215976Sjmallett { 80215976Sjmallett clock_div++; 81215976Sjmallett divisor>>=1; 82215976Sjmallett } 83215976Sjmallett 84215976Sjmallett /* Clock divider for QLM JTAG operations. sclk is divided by 2^(CLK_DIV + 2) */ 85215976Sjmallett jtgc.u64 = 0; 86215976Sjmallett jtgc.s.clk_div = clock_div; 87215976Sjmallett jtgc.s.mux_sel = 0; 88215976Sjmallett if (OCTEON_IS_MODEL(OCTEON_CN52XX)) 89215976Sjmallett jtgc.s.bypass = 0x3; 90215976Sjmallett else if (OCTEON_IS_MODEL(OCTEON_CN63XX)) 91215976Sjmallett jtgc.s.bypass = 0x7; 92215976Sjmallett else 93215976Sjmallett jtgc.s.bypass = 0xf; 94215976Sjmallett cvmx_write_csr(CVMX_CIU_QLM_JTGC, jtgc.u64); 95215976Sjmallett cvmx_read_csr(CVMX_CIU_QLM_JTGC); 96215976Sjmallett} 97215976Sjmallett 98215976Sjmallett 99215976Sjmallett/** 100215976Sjmallett * Write up to 32bits into the QLM jtag chain. Bits are shifted 101215976Sjmallett * into the MSB and out the LSB, so you should shift in the low 102215976Sjmallett * order bits followed by the high order bits. The JTAG chain for 103215976Sjmallett * CN52XX and CN56XX is 4 * 268 bits long, or 1072. The JTAG chain 104215976Sjmallett * for CN63XX is 4 * 300 bits long, or 1200. 105215976Sjmallett * 106215976Sjmallett * @param qlm QLM to shift value into 107215976Sjmallett * @param bits Number of bits to shift in (1-32). 108215976Sjmallett * @param data Data to shift in. Bit 0 enters the chain first, followed by 109215976Sjmallett * bit 1, etc. 110215976Sjmallett * 111215976Sjmallett * @return The low order bits of the JTAG chain that shifted out of the 112215976Sjmallett * circle. 113215976Sjmallett */ 114215976Sjmallettuint32_t cvmx_helper_qlm_jtag_shift(int qlm, int bits, uint32_t data) 115215976Sjmallett{ 116215976Sjmallett cvmx_ciu_qlm_jtgc_t jtgc; 117215976Sjmallett cvmx_ciu_qlm_jtgd_t jtgd; 118215976Sjmallett 119215976Sjmallett jtgc.u64 = cvmx_read_csr(CVMX_CIU_QLM_JTGC); 120215976Sjmallett jtgc.s.mux_sel = qlm; 121215976Sjmallett if (!OCTEON_IS_MODEL(OCTEON_CN63XX)) 122215976Sjmallett jtgc.s.bypass = 1<<qlm; 123215976Sjmallett cvmx_write_csr(CVMX_CIU_QLM_JTGC, jtgc.u64); 124215976Sjmallett cvmx_read_csr(CVMX_CIU_QLM_JTGC); 125215976Sjmallett 126215976Sjmallett jtgd.u64 = 0; 127215976Sjmallett jtgd.s.shift = 1; 128215976Sjmallett jtgd.s.shft_cnt = bits-1; 129215976Sjmallett jtgd.s.shft_reg = data; 130215976Sjmallett if (!OCTEON_IS_MODEL(OCTEON_CN56XX_PASS1_X)) 131215976Sjmallett jtgd.s.select = 1 << qlm; 132215976Sjmallett cvmx_write_csr(CVMX_CIU_QLM_JTGD, jtgd.u64); 133215976Sjmallett do 134215976Sjmallett { 135215976Sjmallett jtgd.u64 = cvmx_read_csr(CVMX_CIU_QLM_JTGD); 136215976Sjmallett } while (jtgd.s.shift); 137215976Sjmallett return jtgd.s.shft_reg >> (32-bits); 138215976Sjmallett} 139215976Sjmallett 140215976Sjmallett 141215976Sjmallett/** 142215976Sjmallett * Shift long sequences of zeros into the QLM JTAG chain. It is 143215976Sjmallett * common to need to shift more than 32 bits of zeros into the 144215976Sjmallett * chain. This function is a convience wrapper around 145215976Sjmallett * cvmx_helper_qlm_jtag_shift() to shift more than 32 bits of 146215976Sjmallett * zeros at a time. 147215976Sjmallett * 148215976Sjmallett * @param qlm QLM to shift zeros into 149215976Sjmallett * @param bits 150215976Sjmallett */ 151215976Sjmallettvoid cvmx_helper_qlm_jtag_shift_zeros(int qlm, int bits) 152215976Sjmallett{ 153215976Sjmallett while (bits > 0) 154215976Sjmallett { 155215976Sjmallett int n = bits; 156215976Sjmallett if (n > 32) 157215976Sjmallett n = 32; 158215976Sjmallett cvmx_helper_qlm_jtag_shift(qlm, n, 0); 159215976Sjmallett bits -= n; 160215976Sjmallett } 161215976Sjmallett} 162215976Sjmallett 163215976Sjmallett 164215976Sjmallett/** 165215976Sjmallett * Program the QLM JTAG chain into all lanes of the QLM. You must 166215976Sjmallett * have already shifted in the proper number of bits into the 167215976Sjmallett * JTAG chain. Updating invalid values can possibly cause chip damage. 168215976Sjmallett * 169215976Sjmallett * @param qlm QLM to program 170215976Sjmallett */ 171215976Sjmallettvoid cvmx_helper_qlm_jtag_update(int qlm) 172215976Sjmallett{ 173215976Sjmallett cvmx_ciu_qlm_jtgc_t jtgc; 174215976Sjmallett cvmx_ciu_qlm_jtgd_t jtgd; 175215976Sjmallett 176215976Sjmallett jtgc.u64 = cvmx_read_csr(CVMX_CIU_QLM_JTGC); 177215976Sjmallett jtgc.s.mux_sel = qlm; 178215976Sjmallett if (!OCTEON_IS_MODEL(OCTEON_CN63XX)) 179215976Sjmallett jtgc.s.bypass = 1<<qlm; 180215976Sjmallett 181215976Sjmallett cvmx_write_csr(CVMX_CIU_QLM_JTGC, jtgc.u64); 182215976Sjmallett cvmx_read_csr(CVMX_CIU_QLM_JTGC); 183215976Sjmallett 184215976Sjmallett /* Update the new data */ 185215976Sjmallett jtgd.u64 = 0; 186215976Sjmallett jtgd.s.update = 1; 187215976Sjmallett if (!OCTEON_IS_MODEL(OCTEON_CN56XX_PASS1_X)) 188215976Sjmallett jtgd.s.select = 1 << qlm; 189215976Sjmallett cvmx_write_csr(CVMX_CIU_QLM_JTGD, jtgd.u64); 190215976Sjmallett do 191215976Sjmallett { 192215976Sjmallett jtgd.u64 = cvmx_read_csr(CVMX_CIU_QLM_JTGD); 193215976Sjmallett } while (jtgd.s.update); 194215976Sjmallett} 195215976Sjmallett 196215976Sjmallett 197215976Sjmallett/** 198215976Sjmallett * Load the QLM JTAG chain with data from all lanes of the QLM. 199215976Sjmallett * 200215976Sjmallett * @param qlm QLM to program 201215976Sjmallett */ 202215976Sjmallettvoid cvmx_helper_qlm_jtag_capture(int qlm) 203215976Sjmallett{ 204215976Sjmallett cvmx_ciu_qlm_jtgc_t jtgc; 205215976Sjmallett cvmx_ciu_qlm_jtgd_t jtgd; 206215976Sjmallett 207215976Sjmallett jtgc.u64 = cvmx_read_csr(CVMX_CIU_QLM_JTGC); 208215976Sjmallett jtgc.s.mux_sel = qlm; 209215976Sjmallett if (!OCTEON_IS_MODEL(OCTEON_CN63XX)) 210215976Sjmallett jtgc.s.bypass = 1<<qlm; 211215976Sjmallett 212215976Sjmallett cvmx_write_csr(CVMX_CIU_QLM_JTGC, jtgc.u64); 213215976Sjmallett cvmx_read_csr(CVMX_CIU_QLM_JTGC); 214215976Sjmallett 215215976Sjmallett jtgd.u64 = 0; 216215976Sjmallett jtgd.s.capture = 1; 217215976Sjmallett if (!OCTEON_IS_MODEL(OCTEON_CN56XX_PASS1_X)) 218215976Sjmallett jtgd.s.select = 1 << qlm; 219215976Sjmallett cvmx_write_csr(CVMX_CIU_QLM_JTGD, jtgd.u64); 220215976Sjmallett do 221215976Sjmallett { 222215976Sjmallett jtgd.u64 = cvmx_read_csr(CVMX_CIU_QLM_JTGD); 223215976Sjmallett } while (jtgd.s.capture); 224215976Sjmallett} 225215976Sjmallett 226