/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright (c) 1999-2000 by Sun Microsystems, Inc. * All rights reserved. */ /* * hci1394_csr.c * This code contains the code for the CSR registers handled by the HAL in * SW. The HW implemented CSR registers are in hci1394_ohci.c * * For more information on CSR registers, see * IEEE 1212 * IEEE 1394-1995 * section 8.3.2 * IEEE P1394A Draft 3.0 * sections 10.32,10.33 * * NOTE: A read/write to a CSR SW based register will first go to the Services * Layer which will do some filtering and then come through the s1394if. Look * in hci1394_s1394if.c to see which registers are implemented in HW and * which are implemented in SW. */ #include #include #include #include #include #include #include #include #include #include /* * The split_timeout_lo register cannot be set below 800 and above 7999. The * split_timeout_hi register cannot be set above 7. */ #define CSR_MIN_SPLIT_TIMEOUT_LO 800 #define CSR_MAX_SPLIT_TIMEOUT_LO 7999 #define CSR_MAX_SPLIT_TIMEOUT_HI 7 /* * We will convert the split_timeout_lo to return the data in most significant * 13 bits on the fly. */ #define CSR_SPLIT_TIMEOUT_LO_SHIFT 19 /* * This is what we report to the services layer as our node capabilities. * See IEEE 1212_1994, section 8.4.11 * * Split Timeout Registers are implemented (bit 15) * This node uses 64-bit addressing (bit 9) * This node uses fixed addressing scheme (bit 8) * STATE_BITS.lost is implemented * STATE_BITS.dreq is implemented */ #define CSR_INITIAL_NODE_CAPABILITIES 0x000083C0 /* * macro to calculate split_timeout based on split_timeout_lo and * split_timeout_hi */ #define CSR_SPLIT_TIMEOUT(split_hi, split_lo) \ ((split_hi * IEEE1394_BUS_CYCLES_PER_SEC) + split_lo) static void hci1394_csr_state_init(hci1394_csr_t *csr); /* * hci1394_csr_init() * Initialize CSR state and CSR SW based registers. */ void hci1394_csr_init(hci1394_drvinfo_t *drvinfo, hci1394_ohci_handle_t ohci, hci1394_csr_handle_t *csr_handle) { hci1394_csr_t *csr; ASSERT(drvinfo != NULL); ASSERT(ohci != NULL); ASSERT(csr_handle != NULL); /* alloc the space to keep track of the csr registers */ csr = kmem_alloc(sizeof (hci1394_csr_t), KM_SLEEP); /* setup the return parameter */ *csr_handle = csr; /* Initialize the csr structure */ csr->csr_drvinfo = drvinfo; csr->csr_ohci = ohci; mutex_init(&csr->csr_mutex, NULL, MUTEX_DRIVER, drvinfo->di_iblock_cookie); hci1394_csr_state_init(csr); } /* * hci1394_csr_fini() * Free up any space allocated and any mutexes used. */ void hci1394_csr_fini(hci1394_csr_handle_t *csr_handle) { hci1394_csr_t *csr; ASSERT(csr_handle != NULL); csr = (hci1394_csr_t *)*csr_handle; mutex_destroy(&csr->csr_mutex); kmem_free(csr, sizeof (hci1394_csr_t)); *csr_handle = NULL; } /* * hci1394_csr_resume() * When resuming power on a workstation, re-setup our CSR registers. */ void hci1394_csr_resume(hci1394_csr_handle_t csr_handle) { ASSERT(csr_handle != NULL); hci1394_csr_state_init(csr_handle); } /* * hci1394_csr_node_capabilities() * Return the CSR node capabilities. */ void hci1394_csr_node_capabilities(hci1394_csr_handle_t csr_handle, uint32_t *capabilities) { ASSERT(csr_handle != NULL); ASSERT(capabilities != NULL); mutex_enter(&csr_handle->csr_mutex); *capabilities = csr_handle->csr_capabilities; mutex_exit(&csr_handle->csr_mutex); } /* * hci1394_csr_state_get() * Read the CSR state register. Currently we only support the dreq, cmstr, * and abdicate bits in the CSR state register. See the specs mentioned * above for the behavior of these bits. */ void hci1394_csr_state_get(hci1394_csr_handle_t csr_handle, uint32_t *state) { ASSERT(csr_handle != NULL); ASSERT(state != NULL); mutex_enter(&csr_handle->csr_mutex); *state = csr_handle->csr_state; mutex_exit(&csr_handle->csr_mutex); } /* * hci1394_csr_state_bset() * Perform a bit set on the CSR state register. The value of state will be * or'd with the CSR state register. Currently we only support the dreq, * cmstr, and abdicate bits in the CSR state register. See the specs * mentioned above for the behavior of these bits. */ void hci1394_csr_state_bset(hci1394_csr_handle_t csr_handle, uint32_t state) { uint32_t supported_state; ASSERT(csr_handle != NULL); mutex_enter(&csr_handle->csr_mutex); /* only support dreq, cmstr, and abdicate bits */ supported_state = state & (IEEE1394_CSR_STATE_ABDICATE | IEEE1394_CSR_STATE_CMSTR | IEEE1394_CSR_STATE_DREQ); /* * If we are setting the Cycle Master bit and we are the root node, * enable Cycle Start Packets. */ if ((supported_state & IEEE1394_CSR_STATE_CMSTR) && (hci1394_ohci_root_check(csr_handle->csr_ohci))) { hci1394_ohci_cycle_master_enable(csr_handle->csr_ohci); } /* set the supported bits in csr_state */ csr_handle->csr_state |= supported_state; mutex_exit(&csr_handle->csr_mutex); } /* * hci1394_csr_state_bclr() * Perform a bit clear on the CSR state register. The inverted value of * state will be and'd with CSR state register. Currently we only support * the dreq, cmstr, and abdicate bits in the CSR state register. See the * specs mentioned above for the behavior of these bits. */ void hci1394_csr_state_bclr(hci1394_csr_handle_t csr_handle, uint32_t state) { uint32_t supported_state; ASSERT(csr_handle != NULL); mutex_enter(&csr_handle->csr_mutex); /* only support dreq, cmstr, and abdicate bits */ supported_state = state & (IEEE1394_CSR_STATE_ABDICATE | IEEE1394_CSR_STATE_CMSTR | IEEE1394_CSR_STATE_DREQ); /* * If we are clearing the Cycle Master bit and we are the root node, * disable Cycle Start Packets. */ if ((supported_state & IEEE1394_CSR_STATE_CMSTR) && (hci1394_ohci_root_check(csr_handle->csr_ohci))) { hci1394_ohci_cycle_master_disable(csr_handle->csr_ohci); } /* Clear the supported bits in csr_state */ csr_handle->csr_state &= ~state; mutex_exit(&csr_handle->csr_mutex); } /* * hci1394_csr_split_timeout_hi_get() * Read the CSR split_timeout_hi register. */ void hci1394_csr_split_timeout_hi_get(hci1394_csr_handle_t csr_handle, uint32_t *split_timeout_hi) { ASSERT(csr_handle != NULL); ASSERT(split_timeout_hi != NULL); mutex_enter(&csr_handle->csr_mutex); *split_timeout_hi = csr_handle->csr_split_timeout_hi; mutex_exit(&csr_handle->csr_mutex); } /* * hci1394_csr_split_timeout_lo_get() * Read the CSR split_timeout_lo register. */ void hci1394_csr_split_timeout_lo_get(hci1394_csr_handle_t csr_handle, uint32_t *split_timeout_lo) { ASSERT(csr_handle != NULL); ASSERT(split_timeout_lo != NULL); mutex_enter(&csr_handle->csr_mutex); /* * Read the split_timeout_lo CSR register. Convert split_timeout_lo to * use the data in most significant 13 bits on the fly. */ *split_timeout_lo = csr_handle->csr_split_timeout_lo << CSR_SPLIT_TIMEOUT_LO_SHIFT; mutex_exit(&csr_handle->csr_mutex); } /* * hci1394_csr_split_timeout_hi_set() * Write the CSR split_timeout_hi register. This routine will also * re-calculate the "split_timeout" which is used internally in the HAL * driver. The only accesses to split_timeout_hi and split_timeout_lo * should be over the 1394 bus. Only the least significant 3 bits are * relevant in the split_timeout_hi register. */ void hci1394_csr_split_timeout_hi_set(hci1394_csr_handle_t csr_handle, uint32_t split_timeout_hi) { ASSERT(csr_handle != NULL); mutex_enter(&csr_handle->csr_mutex); /* * update the split_timeout_hi CSR register. Only look at the 3 LSBits. * Update our internal split_timeout value. */ csr_handle->csr_split_timeout_hi = split_timeout_hi & CSR_MAX_SPLIT_TIMEOUT_HI; csr_handle->csr_split_timeout = CSR_SPLIT_TIMEOUT( csr_handle->csr_split_timeout_hi, csr_handle->csr_split_timeout_lo); mutex_exit(&csr_handle->csr_mutex); } /* * hci1394_csr_split_timeout_lo_set() * Write the CSR split_timeout_lo register. This routine will also * re-calculate the "split_timeout" which is used internally in the HAL * driver. The only accesses to split_timeout_hi and split_timeout_lo * should be over the 1394 bus. Only the most significant 13 bits are * relevant in the split_timeout_lo register. */ void hci1394_csr_split_timeout_lo_set(hci1394_csr_handle_t csr_handle, uint32_t split_timeout_lo) { ASSERT(csr_handle != NULL); mutex_enter(&csr_handle->csr_mutex); /* * Update the split_timeout_lo CSR register. Only look at the 3 LSBits. * Convert the split_timeout_lo to use the data in most significant 13 * bits on the fly. */ csr_handle->csr_split_timeout_lo = split_timeout_lo >> CSR_SPLIT_TIMEOUT_LO_SHIFT; /* threshold the split_timeout_lo value */ if (csr_handle->csr_split_timeout_lo < CSR_MIN_SPLIT_TIMEOUT_LO) { csr_handle->csr_split_timeout_lo = CSR_MIN_SPLIT_TIMEOUT_LO; } else if (csr_handle->csr_split_timeout_lo > CSR_MAX_SPLIT_TIMEOUT_LO) { csr_handle->csr_split_timeout_lo = CSR_MAX_SPLIT_TIMEOUT_LO; } /* Update our internal split_timeout value */ csr_handle->csr_split_timeout = CSR_SPLIT_TIMEOUT( csr_handle->csr_split_timeout_hi, csr_handle->csr_split_timeout_lo); mutex_exit(&csr_handle->csr_mutex); } /* * hci1394_csr_split_timeout_get() * Return the current value of split_timeout. This is the only routine * which should be used to get the split timeout for use in a calculation * (e.g. for calculating ACK pending timeout). */ uint_t hci1394_csr_split_timeout_get(hci1394_csr_handle_t csr_handle) { uint_t split_timeout; ASSERT(csr_handle != NULL); mutex_enter(&csr_handle->csr_mutex); /* read our internal split_timeout value */ split_timeout = csr_handle->csr_split_timeout; mutex_exit(&csr_handle->csr_mutex); return (split_timeout); } /* * hci1394_csr_bus_reset() * Perform required bus reset processing on CSR registers. This includes * clearing the abdicate bit, and setting/clearing the Cycle Master bit. * See sections 10.32 and 10.33 in the IEEE P1394A Draft 3.0 spec. See * section 8.3.2.2.1 in the IEEE 1394-1995 spec. This routine should be * called every bus reset. */ void hci1394_csr_bus_reset(hci1394_csr_handle_t csr_handle) { ASSERT(csr_handle != NULL); mutex_enter(&csr_handle->csr_mutex); /* Clear the abdicate bit. Always do this. */ csr_handle->csr_state &= ~IEEE1394_CSR_STATE_ABDICATE; /* if we are NOT currently the root node on the bus */ if (hci1394_ohci_root_check(csr_handle->csr_ohci) == B_FALSE) { /* * Set the was_root state. This is needed for the Cycle Master * state machine below. */ csr_handle->csr_was_root = B_FALSE; /* * Clear the Cycle Master bit. We do not have to shut off cycle * master in OpenHCI. The HW will automatically stop generating * Cycle Start packets when it is not the root node. */ csr_handle->csr_state &= ~IEEE1394_CSR_STATE_CMSTR; /* * if we are currently the root node on the bus and we were NOT * the root before the reset. */ } else if (csr_handle->csr_was_root == B_FALSE) { /* set the was_root state to TRUE */ csr_handle->csr_was_root = B_TRUE; /* * if we are cycle master capable, set the Cycle Master bit and * start Cycle Start packets. We should always be Cycle Master * capable. */ if (hci1394_ohci_cmc_check(csr_handle->csr_ohci)) { csr_handle->csr_state |= IEEE1394_CSR_STATE_CMSTR; hci1394_ohci_cycle_master_enable(csr_handle->csr_ohci); /* * if we are NOT cycle master capable, clear the Cycle Master * bit and stop Cycle Start packets. We should never see this * in OpenHCI. I think? :-) */ } else { csr_handle->csr_state &= ~IEEE1394_CSR_STATE_CMSTR; hci1394_ohci_cycle_master_disable(csr_handle->csr_ohci); } } /* * else {} * else we are root now. We were root before, keep cmstr the same. * Nothing to do. */ mutex_exit(&csr_handle->csr_mutex); } /* * hci1394_csr_state_init() * set the CSR SW registers and state variables to their initial settings. */ static void hci1394_csr_state_init(hci1394_csr_t *csr) { ASSERT(csr != NULL); mutex_enter(&csr->csr_mutex); /* * Initialize the split timeout to be 0 seconds (split_timeout_hi) and * use a patchable variable for the initial split_timeout_lo. This * variable must be patched before the driver attaches. It is never * looked at again after this code is run. * * Calculate the split_timeout which we will use in the driver based on * split_timeout_lo and split_timeout_hi. */ csr->csr_split_timeout_hi = 0; csr->csr_split_timeout_lo = hci1394_split_timeout; csr->csr_split_timeout = CSR_SPLIT_TIMEOUT( csr->csr_split_timeout_hi, csr->csr_split_timeout_lo); /* Set the initial CSR State register to 0 */ csr->csr_state = 0; /* * was_root is an internal state variable which tracks if we were root * last bus reset. This is needed for the required state register bus * reset processing. */ csr->csr_was_root = B_FALSE; /* setup our initial capabilities setting */ csr->csr_capabilities = CSR_INITIAL_NODE_CAPABILITIES; mutex_exit(&csr->csr_mutex); }