10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
51617Sgovinda * Common Development and Distribution License (the "License").
61617Sgovinda * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate * See the License for the specific language governing permissions
110Sstevel@tonic-gate * and limitations under the License.
120Sstevel@tonic-gate *
130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * CDDL HEADER END
200Sstevel@tonic-gate */
21*12619Sandrew.rutz@sun.com
220Sstevel@tonic-gate /*
23*12619Sandrew.rutz@sun.com * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
240Sstevel@tonic-gate */
250Sstevel@tonic-gate
260Sstevel@tonic-gate #include <sys/types.h>
270Sstevel@tonic-gate #include <sys/cmn_err.h>
280Sstevel@tonic-gate #include <sys/vmsystm.h>
290Sstevel@tonic-gate #include <sys/vmem.h>
300Sstevel@tonic-gate #include <sys/machsystm.h> /* lddphys() */
310Sstevel@tonic-gate #include <sys/iommutsb.h>
320Sstevel@tonic-gate #include <px_obj.h>
3310923SEvan.Yan@Sun.COM #include <sys/hotplug/pci/pcie_hp.h>
340Sstevel@tonic-gate #include "px_regs.h"
351772Sjl139090 #include "oberon_regs.h"
360Sstevel@tonic-gate #include "px_csr.h"
370Sstevel@tonic-gate #include "px_lib4u.h"
382587Spjha #include "px_err.h"
390Sstevel@tonic-gate
400Sstevel@tonic-gate /*
410Sstevel@tonic-gate * Registers that need to be saved and restored during suspend/resume.
420Sstevel@tonic-gate */
430Sstevel@tonic-gate
440Sstevel@tonic-gate /*
450Sstevel@tonic-gate * Registers in the PEC Module.
460Sstevel@tonic-gate * LPU_RESET should be set to 0ull during resume
471772Sjl139090 *
481772Sjl139090 * This array is in reg,chip form. PX_CHIP_UNIDENTIFIED is for all chips
491772Sjl139090 * or PX_CHIP_FIRE for Fire only, or PX_CHIP_OBERON for Oberon only.
500Sstevel@tonic-gate */
511772Sjl139090 static struct px_pec_regs {
521772Sjl139090 uint64_t reg;
531772Sjl139090 uint64_t chip;
541772Sjl139090 } pec_config_state_regs[] = {
551772Sjl139090 {PEC_CORE_AND_BLOCK_INTERRUPT_ENABLE, PX_CHIP_UNIDENTIFIED},
561772Sjl139090 {ILU_ERROR_LOG_ENABLE, PX_CHIP_UNIDENTIFIED},
571772Sjl139090 {ILU_INTERRUPT_ENABLE, PX_CHIP_UNIDENTIFIED},
581772Sjl139090 {TLU_CONTROL, PX_CHIP_UNIDENTIFIED},
591772Sjl139090 {TLU_OTHER_EVENT_LOG_ENABLE, PX_CHIP_UNIDENTIFIED},
601772Sjl139090 {TLU_OTHER_EVENT_INTERRUPT_ENABLE, PX_CHIP_UNIDENTIFIED},
611772Sjl139090 {TLU_DEVICE_CONTROL, PX_CHIP_UNIDENTIFIED},
621772Sjl139090 {TLU_LINK_CONTROL, PX_CHIP_UNIDENTIFIED},
631772Sjl139090 {TLU_UNCORRECTABLE_ERROR_LOG_ENABLE, PX_CHIP_UNIDENTIFIED},
641772Sjl139090 {TLU_UNCORRECTABLE_ERROR_INTERRUPT_ENABLE, PX_CHIP_UNIDENTIFIED},
651772Sjl139090 {TLU_CORRECTABLE_ERROR_LOG_ENABLE, PX_CHIP_UNIDENTIFIED},
661772Sjl139090 {TLU_CORRECTABLE_ERROR_INTERRUPT_ENABLE, PX_CHIP_UNIDENTIFIED},
671772Sjl139090 {DLU_LINK_LAYER_CONFIG, PX_CHIP_OBERON},
681772Sjl139090 {DLU_FLOW_CONTROL_UPDATE_CONTROL, PX_CHIP_OBERON},
691772Sjl139090 {DLU_TXLINK_REPLAY_TIMER_THRESHOLD, PX_CHIP_OBERON},
701772Sjl139090 {LPU_LINK_LAYER_INTERRUPT_MASK, PX_CHIP_FIRE},
711772Sjl139090 {LPU_PHY_INTERRUPT_MASK, PX_CHIP_FIRE},
721772Sjl139090 {LPU_RECEIVE_PHY_INTERRUPT_MASK, PX_CHIP_FIRE},
731772Sjl139090 {LPU_TRANSMIT_PHY_INTERRUPT_MASK, PX_CHIP_FIRE},
741772Sjl139090 {LPU_GIGABLAZE_GLUE_INTERRUPT_MASK, PX_CHIP_FIRE},
751772Sjl139090 {LPU_LTSSM_INTERRUPT_MASK, PX_CHIP_FIRE},
761772Sjl139090 {LPU_RESET, PX_CHIP_FIRE},
771772Sjl139090 {LPU_DEBUG_CONFIG, PX_CHIP_FIRE},
781772Sjl139090 {LPU_INTERRUPT_MASK, PX_CHIP_FIRE},
791772Sjl139090 {LPU_LINK_LAYER_CONFIG, PX_CHIP_FIRE},
801772Sjl139090 {LPU_FLOW_CONTROL_UPDATE_CONTROL, PX_CHIP_FIRE},
811772Sjl139090 {LPU_TXLINK_FREQUENT_NAK_LATENCY_TIMER_THRESHOLD, PX_CHIP_FIRE},
821772Sjl139090 {LPU_TXLINK_REPLAY_TIMER_THRESHOLD, PX_CHIP_FIRE},
831772Sjl139090 {LPU_REPLAY_BUFFER_MAX_ADDRESS, PX_CHIP_FIRE},
841772Sjl139090 {LPU_TXLINK_RETRY_FIFO_POINTER, PX_CHIP_FIRE},
851772Sjl139090 {LPU_LTSSM_CONFIG2, PX_CHIP_FIRE},
861772Sjl139090 {LPU_LTSSM_CONFIG3, PX_CHIP_FIRE},
871772Sjl139090 {LPU_LTSSM_CONFIG4, PX_CHIP_FIRE},
881772Sjl139090 {LPU_LTSSM_CONFIG5, PX_CHIP_FIRE},
891772Sjl139090 {DMC_CORE_AND_BLOCK_INTERRUPT_ENABLE, PX_CHIP_UNIDENTIFIED},
901772Sjl139090 {DMC_DEBUG_SELECT_FOR_PORT_A, PX_CHIP_UNIDENTIFIED},
911772Sjl139090 {DMC_DEBUG_SELECT_FOR_PORT_B, PX_CHIP_UNIDENTIFIED}
920Sstevel@tonic-gate };
931772Sjl139090
941772Sjl139090 #define PEC_KEYS \
951772Sjl139090 ((sizeof (pec_config_state_regs))/sizeof (struct px_pec_regs))
961772Sjl139090
971772Sjl139090 #define PEC_SIZE (PEC_KEYS * sizeof (uint64_t))
980Sstevel@tonic-gate
990Sstevel@tonic-gate /*
1000Sstevel@tonic-gate * Registers for the MMU module.
1010Sstevel@tonic-gate * MMU_TTE_CACHE_INVALIDATE needs to be cleared. (-1ull)
1020Sstevel@tonic-gate */
1030Sstevel@tonic-gate static uint64_t mmu_config_state_regs[] = {
1040Sstevel@tonic-gate MMU_TSB_CONTROL,
1050Sstevel@tonic-gate MMU_CONTROL_AND_STATUS,
10627Sjchu MMU_ERROR_LOG_ENABLE,
1070Sstevel@tonic-gate MMU_INTERRUPT_ENABLE
1080Sstevel@tonic-gate };
1090Sstevel@tonic-gate #define MMU_SIZE (sizeof (mmu_config_state_regs))
1100Sstevel@tonic-gate #define MMU_KEYS (MMU_SIZE / sizeof (uint64_t))
1110Sstevel@tonic-gate
1120Sstevel@tonic-gate /*
1130Sstevel@tonic-gate * Registers for the IB Module
1140Sstevel@tonic-gate */
1150Sstevel@tonic-gate static uint64_t ib_config_state_regs[] = {
1160Sstevel@tonic-gate IMU_ERROR_LOG_ENABLE,
1170Sstevel@tonic-gate IMU_INTERRUPT_ENABLE
1180Sstevel@tonic-gate };
1190Sstevel@tonic-gate #define IB_SIZE (sizeof (ib_config_state_regs))
1200Sstevel@tonic-gate #define IB_KEYS (IB_SIZE / sizeof (uint64_t))
1210Sstevel@tonic-gate #define IB_MAP_SIZE (INTERRUPT_MAPPING_ENTRIES * sizeof (uint64_t))
1220Sstevel@tonic-gate
1230Sstevel@tonic-gate /*
1241772Sjl139090 * Registers for the JBC module.
1250Sstevel@tonic-gate * JBC_ERROR_STATUS_CLEAR needs to be cleared. (-1ull)
1260Sstevel@tonic-gate */
1271772Sjl139090 static uint64_t jbc_config_state_regs[] = {
1280Sstevel@tonic-gate JBUS_PARITY_CONTROL,
1290Sstevel@tonic-gate JBC_FATAL_RESET_ENABLE,
1300Sstevel@tonic-gate JBC_CORE_AND_BLOCK_INTERRUPT_ENABLE,
1310Sstevel@tonic-gate JBC_ERROR_LOG_ENABLE,
1320Sstevel@tonic-gate JBC_INTERRUPT_ENABLE
1330Sstevel@tonic-gate };
1341772Sjl139090 #define JBC_SIZE (sizeof (jbc_config_state_regs))
1351772Sjl139090 #define JBC_KEYS (JBC_SIZE / sizeof (uint64_t))
1361772Sjl139090
1371772Sjl139090 /*
1381772Sjl139090 * Registers for the UBC module.
1391772Sjl139090 * UBC_ERROR_STATUS_CLEAR needs to be cleared. (-1ull)
1401772Sjl139090 */
1411772Sjl139090 static uint64_t ubc_config_state_regs[] = {
1421772Sjl139090 UBC_ERROR_LOG_ENABLE,
1431772Sjl139090 UBC_INTERRUPT_ENABLE
1441772Sjl139090 };
1451772Sjl139090 #define UBC_SIZE (sizeof (ubc_config_state_regs))
1461772Sjl139090 #define UBC_KEYS (UBC_SIZE / sizeof (uint64_t))
1470Sstevel@tonic-gate
1480Sstevel@tonic-gate static uint64_t msiq_config_other_regs[] = {
1490Sstevel@tonic-gate ERR_COR_MAPPING,
1500Sstevel@tonic-gate ERR_NONFATAL_MAPPING,
1510Sstevel@tonic-gate ERR_FATAL_MAPPING,
1520Sstevel@tonic-gate PM_PME_MAPPING,
1530Sstevel@tonic-gate PME_TO_ACK_MAPPING,
1540Sstevel@tonic-gate MSI_32_BIT_ADDRESS,
1550Sstevel@tonic-gate MSI_64_BIT_ADDRESS
1560Sstevel@tonic-gate };
1570Sstevel@tonic-gate #define MSIQ_OTHER_SIZE (sizeof (msiq_config_other_regs))
1580Sstevel@tonic-gate #define MSIQ_OTHER_KEYS (MSIQ_OTHER_SIZE / sizeof (uint64_t))
1590Sstevel@tonic-gate
1600Sstevel@tonic-gate #define MSIQ_STATE_SIZE (EVENT_QUEUE_STATE_ENTRIES * sizeof (uint64_t))
1610Sstevel@tonic-gate #define MSIQ_MAPPING_SIZE (MSI_MAPPING_ENTRIES * sizeof (uint64_t))
1620Sstevel@tonic-gate
1632587Spjha /* OPL tuning variables for link unstable issue */
1643485Spjha int wait_perst = 5000000; /* step 9, default: 5s */
1653485Spjha int wait_enable_port = 30000; /* step 11, default: 30ms */
1662587Spjha int link_retry_count = 2; /* step 11, default: 2 */
1673485Spjha int link_status_check = 400000; /* step 11, default: 400ms */
1682587Spjha
1690Sstevel@tonic-gate static uint64_t msiq_suspend(devhandle_t dev_hdl, pxu_t *pxu_p);
1700Sstevel@tonic-gate static void msiq_resume(devhandle_t dev_hdl, pxu_t *pxu_p);
1711772Sjl139090 static void jbc_init(caddr_t xbc_csr_base, pxu_t *pxu_p);
1721772Sjl139090 static void ubc_init(caddr_t xbc_csr_base, pxu_t *pxu_p);
1730Sstevel@tonic-gate
1747596SAlan.Adamson@Sun.COM extern int px_acknak_timer_table[LINK_MAX_PKT_ARR_SIZE][LINK_WIDTH_ARR_SIZE];
1757596SAlan.Adamson@Sun.COM extern int px_replay_timer_table[LINK_MAX_PKT_ARR_SIZE][LINK_WIDTH_ARR_SIZE];
1767596SAlan.Adamson@Sun.COM
17727Sjchu /*
1781772Sjl139090 * Initialize the bus, but do not enable interrupts.
17927Sjchu */
1800Sstevel@tonic-gate /* ARGSUSED */
1810Sstevel@tonic-gate void
hvio_cb_init(caddr_t xbc_csr_base,pxu_t * pxu_p)1820Sstevel@tonic-gate hvio_cb_init(caddr_t xbc_csr_base, pxu_t *pxu_p)
1830Sstevel@tonic-gate {
1841772Sjl139090 switch (PX_CHIP_TYPE(pxu_p)) {
1851772Sjl139090 case PX_CHIP_OBERON:
1861772Sjl139090 ubc_init(xbc_csr_base, pxu_p);
1871772Sjl139090 break;
1881772Sjl139090 case PX_CHIP_FIRE:
1891772Sjl139090 jbc_init(xbc_csr_base, pxu_p);
1901772Sjl139090 break;
1911772Sjl139090 default:
1921772Sjl139090 DBG(DBG_CB, NULL, "hvio_cb_init - unknown chip type: 0x%x\n",
1931772Sjl139090 PX_CHIP_TYPE(pxu_p));
1941772Sjl139090 break;
1951772Sjl139090 }
1961772Sjl139090 }
1971772Sjl139090
1981772Sjl139090 /*
1991772Sjl139090 * Initialize the JBC module, but do not enable interrupts.
2001772Sjl139090 */
2011772Sjl139090 /* ARGSUSED */
2021772Sjl139090 static void
jbc_init(caddr_t xbc_csr_base,pxu_t * pxu_p)2031772Sjl139090 jbc_init(caddr_t xbc_csr_base, pxu_t *pxu_p)
2041772Sjl139090 {
2050Sstevel@tonic-gate uint64_t val;
2060Sstevel@tonic-gate
2070Sstevel@tonic-gate /* Check if we need to enable inverted parity */
2080Sstevel@tonic-gate val = (1ULL << JBUS_PARITY_CONTROL_P_EN);
2090Sstevel@tonic-gate CSR_XS(xbc_csr_base, JBUS_PARITY_CONTROL, val);
2101772Sjl139090 DBG(DBG_CB, NULL, "jbc_init, JBUS_PARITY_CONTROL: 0x%llx\n",
21127Sjchu CSR_XR(xbc_csr_base, JBUS_PARITY_CONTROL));
21227Sjchu
21327Sjchu val = (1 << JBC_FATAL_RESET_ENABLE_SPARE_P_INT_EN) |
21427Sjchu (1 << JBC_FATAL_RESET_ENABLE_MB_PEA_P_INT_EN) |
21527Sjchu (1 << JBC_FATAL_RESET_ENABLE_CPE_P_INT_EN) |
21627Sjchu (1 << JBC_FATAL_RESET_ENABLE_APE_P_INT_EN) |
21727Sjchu (1 << JBC_FATAL_RESET_ENABLE_PIO_CPE_INT_EN) |
21827Sjchu (1 << JBC_FATAL_RESET_ENABLE_JTCEEW_P_INT_EN) |
21927Sjchu (1 << JBC_FATAL_RESET_ENABLE_JTCEEI_P_INT_EN) |
22027Sjchu (1 << JBC_FATAL_RESET_ENABLE_JTCEER_P_INT_EN);
2210Sstevel@tonic-gate CSR_XS(xbc_csr_base, JBC_FATAL_RESET_ENABLE, val);
2221772Sjl139090 DBG(DBG_CB, NULL, "jbc_init, JBC_FATAL_RESET_ENABLE: 0x%llx\n",
2236953Sanbui CSR_XR(xbc_csr_base, JBC_FATAL_RESET_ENABLE));
2240Sstevel@tonic-gate
2250Sstevel@tonic-gate /*
2260Sstevel@tonic-gate * Enable merge, jbc and dmc interrupts.
2270Sstevel@tonic-gate */
2280Sstevel@tonic-gate CSR_XS(xbc_csr_base, JBC_CORE_AND_BLOCK_INTERRUPT_ENABLE, -1ull);
2290Sstevel@tonic-gate DBG(DBG_CB, NULL,
2301772Sjl139090 "jbc_init, JBC_CORE_AND_BLOCK_INTERRUPT_ENABLE: 0x%llx\n",
23127Sjchu CSR_XR(xbc_csr_base, JBC_CORE_AND_BLOCK_INTERRUPT_ENABLE));
2320Sstevel@tonic-gate
2330Sstevel@tonic-gate /*
2341772Sjl139090 * CSR_V JBC's interrupt regs (log, enable, status, clear)
2350Sstevel@tonic-gate */
2361772Sjl139090 DBG(DBG_CB, NULL, "jbc_init, JBC_ERROR_LOG_ENABLE: 0x%llx\n",
23727Sjchu CSR_XR(xbc_csr_base, JBC_ERROR_LOG_ENABLE));
23827Sjchu
2391772Sjl139090 DBG(DBG_CB, NULL, "jbc_init, JBC_INTERRUPT_ENABLE: 0x%llx\n",
24027Sjchu CSR_XR(xbc_csr_base, JBC_INTERRUPT_ENABLE));
24127Sjchu
2421772Sjl139090 DBG(DBG_CB, NULL, "jbc_init, JBC_INTERRUPT_STATUS: 0x%llx\n",
24327Sjchu CSR_XR(xbc_csr_base, JBC_INTERRUPT_STATUS));
24427Sjchu
2451772Sjl139090 DBG(DBG_CB, NULL, "jbc_init, JBC_ERROR_STATUS_CLEAR: 0x%llx\n",
24627Sjchu CSR_XR(xbc_csr_base, JBC_ERROR_STATUS_CLEAR));
2470Sstevel@tonic-gate }
2480Sstevel@tonic-gate
24927Sjchu /*
2501772Sjl139090 * Initialize the UBC module, but do not enable interrupts.
2511772Sjl139090 */
2521772Sjl139090 /* ARGSUSED */
2531772Sjl139090 static void
ubc_init(caddr_t xbc_csr_base,pxu_t * pxu_p)2541772Sjl139090 ubc_init(caddr_t xbc_csr_base, pxu_t *pxu_p)
2551772Sjl139090 {
2561772Sjl139090 /*
2571772Sjl139090 * Enable Uranus bus error log bits.
2581772Sjl139090 */
2591772Sjl139090 CSR_XS(xbc_csr_base, UBC_ERROR_LOG_ENABLE, -1ull);
2601772Sjl139090 DBG(DBG_CB, NULL, "ubc_init, UBC_ERROR_LOG_ENABLE: 0x%llx\n",
2611772Sjl139090 CSR_XR(xbc_csr_base, UBC_ERROR_LOG_ENABLE));
2621772Sjl139090
2631772Sjl139090 /*
2641772Sjl139090 * Clear Uranus bus errors.
2651772Sjl139090 */
2661772Sjl139090 CSR_XS(xbc_csr_base, UBC_ERROR_STATUS_CLEAR, -1ull);
2671772Sjl139090 DBG(DBG_CB, NULL, "ubc_init, UBC_ERROR_STATUS_CLEAR: 0x%llx\n",
2681772Sjl139090 CSR_XR(xbc_csr_base, UBC_ERROR_STATUS_CLEAR));
2691772Sjl139090
2701772Sjl139090 /*
2711772Sjl139090 * CSR_V UBC's interrupt regs (log, enable, status, clear)
2721772Sjl139090 */
2731772Sjl139090 DBG(DBG_CB, NULL, "ubc_init, UBC_ERROR_LOG_ENABLE: 0x%llx\n",
2741772Sjl139090 CSR_XR(xbc_csr_base, UBC_ERROR_LOG_ENABLE));
2751772Sjl139090
2761772Sjl139090 DBG(DBG_CB, NULL, "ubc_init, UBC_INTERRUPT_ENABLE: 0x%llx\n",
2771772Sjl139090 CSR_XR(xbc_csr_base, UBC_INTERRUPT_ENABLE));
2781772Sjl139090
2791772Sjl139090 DBG(DBG_CB, NULL, "ubc_init, UBC_INTERRUPT_STATUS: 0x%llx\n",
2801772Sjl139090 CSR_XR(xbc_csr_base, UBC_INTERRUPT_STATUS));
2811772Sjl139090
2821772Sjl139090 DBG(DBG_CB, NULL, "ubc_init, UBC_ERROR_STATUS_CLEAR: 0x%llx\n",
2831772Sjl139090 CSR_XR(xbc_csr_base, UBC_ERROR_STATUS_CLEAR));
2841772Sjl139090 }
2851772Sjl139090
2861772Sjl139090 /*
28727Sjchu * Initialize the module, but do not enable interrupts.
28827Sjchu */
2890Sstevel@tonic-gate /* ARGSUSED */
2900Sstevel@tonic-gate void
hvio_ib_init(caddr_t csr_base,pxu_t * pxu_p)2910Sstevel@tonic-gate hvio_ib_init(caddr_t csr_base, pxu_t *pxu_p)
2920Sstevel@tonic-gate {
2930Sstevel@tonic-gate /*
29427Sjchu * CSR_V IB's interrupt regs (log, enable, status, clear)
2950Sstevel@tonic-gate */
2960Sstevel@tonic-gate DBG(DBG_IB, NULL, "hvio_ib_init - IMU_ERROR_LOG_ENABLE: 0x%llx\n",
29727Sjchu CSR_XR(csr_base, IMU_ERROR_LOG_ENABLE));
29827Sjchu
2990Sstevel@tonic-gate DBG(DBG_IB, NULL, "hvio_ib_init - IMU_INTERRUPT_ENABLE: 0x%llx\n",
30027Sjchu CSR_XR(csr_base, IMU_INTERRUPT_ENABLE));
30127Sjchu
3020Sstevel@tonic-gate DBG(DBG_IB, NULL, "hvio_ib_init - IMU_INTERRUPT_STATUS: 0x%llx\n",
30327Sjchu CSR_XR(csr_base, IMU_INTERRUPT_STATUS));
30427Sjchu
3050Sstevel@tonic-gate DBG(DBG_IB, NULL, "hvio_ib_init - IMU_ERROR_STATUS_CLEAR: 0x%llx\n",
30627Sjchu CSR_XR(csr_base, IMU_ERROR_STATUS_CLEAR));
3070Sstevel@tonic-gate }
3080Sstevel@tonic-gate
30927Sjchu /*
31027Sjchu * Initialize the module, but do not enable interrupts.
31127Sjchu */
3120Sstevel@tonic-gate /* ARGSUSED */
3130Sstevel@tonic-gate static void
ilu_init(caddr_t csr_base,pxu_t * pxu_p)3140Sstevel@tonic-gate ilu_init(caddr_t csr_base, pxu_t *pxu_p)
3150Sstevel@tonic-gate {
3160Sstevel@tonic-gate /*
31727Sjchu * CSR_V ILU's interrupt regs (log, enable, status, clear)
3180Sstevel@tonic-gate */
31927Sjchu DBG(DBG_ILU, NULL, "ilu_init - ILU_ERROR_LOG_ENABLE: 0x%llx\n",
32027Sjchu CSR_XR(csr_base, ILU_ERROR_LOG_ENABLE));
32127Sjchu
3220Sstevel@tonic-gate DBG(DBG_ILU, NULL, "ilu_init - ILU_INTERRUPT_ENABLE: 0x%llx\n",
32327Sjchu CSR_XR(csr_base, ILU_INTERRUPT_ENABLE));
32427Sjchu
3250Sstevel@tonic-gate DBG(DBG_ILU, NULL, "ilu_init - ILU_INTERRUPT_STATUS: 0x%llx\n",
32627Sjchu CSR_XR(csr_base, ILU_INTERRUPT_STATUS));
32727Sjchu
3280Sstevel@tonic-gate DBG(DBG_ILU, NULL, "ilu_init - ILU_ERROR_STATUS_CLEAR: 0x%llx\n",
32927Sjchu CSR_XR(csr_base, ILU_ERROR_STATUS_CLEAR));
3300Sstevel@tonic-gate }
3310Sstevel@tonic-gate
33227Sjchu /*
33327Sjchu * Initialize the module, but do not enable interrupts.
33427Sjchu */
335225Sess /* ARGSUSED */
3360Sstevel@tonic-gate static void
tlu_init(caddr_t csr_base,pxu_t * pxu_p)3370Sstevel@tonic-gate tlu_init(caddr_t csr_base, pxu_t *pxu_p)
3380Sstevel@tonic-gate {
3390Sstevel@tonic-gate uint64_t val;
3400Sstevel@tonic-gate
3410Sstevel@tonic-gate /*
3420Sstevel@tonic-gate * CSR_V TLU_CONTROL Expect OBP ???
3430Sstevel@tonic-gate */
3440Sstevel@tonic-gate
3450Sstevel@tonic-gate /*
3460Sstevel@tonic-gate * L0s entry default timer value - 7.0 us
3470Sstevel@tonic-gate * Completion timeout select default value - 67.1 ms and
3480Sstevel@tonic-gate * OBP will set this value.
3490Sstevel@tonic-gate *
3500Sstevel@tonic-gate * Configuration - Bit 0 should always be 0 for upstream port.
3510Sstevel@tonic-gate * Bit 1 is clock - how is this related to the clock bit in TLU
3520Sstevel@tonic-gate * Link Control register? Both are hardware dependent and likely
3530Sstevel@tonic-gate * set by OBP.
3540Sstevel@tonic-gate *
3552017Sjroberts * NOTE: Do not set the NPWR_EN bit. The desired value of this bit
3562017Sjroberts * will be set by OBP.
3570Sstevel@tonic-gate */
3580Sstevel@tonic-gate val = CSR_XR(csr_base, TLU_CONTROL);
359225Sess val |= (TLU_CONTROL_L0S_TIM_DEFAULT << TLU_CONTROL_L0S_TIM) |
3602017Sjroberts TLU_CONTROL_CONFIG_DEFAULT;
3610Sstevel@tonic-gate
362118Sjchu /*
3631772Sjl139090 * For Oberon, NPWR_EN is set to 0 to prevent PIO reads from blocking
3641772Sjl139090 * behind non-posted PIO writes. This blocking could cause a master or
3651772Sjl139090 * slave timeout on the host bus if multiple serialized PIOs were to
3661772Sjl139090 * suffer Completion Timeouts because the CTO delays for each PIO ahead
3671772Sjl139090 * of the read would accumulate. Since the Olympus processor can have
3681772Sjl139090 * only 1 PIO outstanding, there is no possibility of PIO accesses from
3691772Sjl139090 * a given CPU to a given device being re-ordered by the PCIe fabric;
3701772Sjl139090 * therefore turning off serialization should be safe from a PCIe
3711772Sjl139090 * ordering perspective.
3721772Sjl139090 */
3731772Sjl139090 if (PX_CHIP_TYPE(pxu_p) == PX_CHIP_OBERON)
3741772Sjl139090 val &= ~(1ull << TLU_CONTROL_NPWR_EN);
3751772Sjl139090
3761772Sjl139090 /*
377118Sjchu * Set Detect.Quiet. This will disable automatic link
378118Sjchu * re-training, if the link goes down e.g. power management
379118Sjchu * turns off power to the downstream device. This will enable
380118Sjchu * Fire to go to Drain state, after link down. The drain state
381118Sjchu * forces a reset to the FC state machine, which is required for
382118Sjchu * proper link re-training.
383118Sjchu */
384118Sjchu val |= (1ull << TLU_REMAIN_DETECT_QUIET);
3850Sstevel@tonic-gate CSR_XS(csr_base, TLU_CONTROL, val);
3860Sstevel@tonic-gate DBG(DBG_TLU, NULL, "tlu_init - TLU_CONTROL: 0x%llx\n",
3870Sstevel@tonic-gate CSR_XR(csr_base, TLU_CONTROL));
3880Sstevel@tonic-gate
3890Sstevel@tonic-gate /*
3900Sstevel@tonic-gate * CSR_V TLU_STATUS Expect HW 0x4
3910Sstevel@tonic-gate */
3920Sstevel@tonic-gate
3930Sstevel@tonic-gate /*
3940Sstevel@tonic-gate * Only bit [7:0] are currently defined. Bits [2:0]
3950Sstevel@tonic-gate * are the state, which should likely be in state active,
3960Sstevel@tonic-gate * 100b. Bit three is 'recovery', which is not understood.
3970Sstevel@tonic-gate * All other bits are reserved.
3980Sstevel@tonic-gate */
3990Sstevel@tonic-gate DBG(DBG_TLU, NULL, "tlu_init - TLU_STATUS: 0x%llx\n",
40027Sjchu CSR_XR(csr_base, TLU_STATUS));
4010Sstevel@tonic-gate
4020Sstevel@tonic-gate /*
4030Sstevel@tonic-gate * CSR_V TLU_PME_TURN_OFF_GENERATE Expect HW 0x0
4040Sstevel@tonic-gate */
4050Sstevel@tonic-gate DBG(DBG_TLU, NULL, "tlu_init - TLU_PME_TURN_OFF_GENERATE: 0x%llx\n",
40627Sjchu CSR_XR(csr_base, TLU_PME_TURN_OFF_GENERATE));
4070Sstevel@tonic-gate
4080Sstevel@tonic-gate /*
4090Sstevel@tonic-gate * CSR_V TLU_INGRESS_CREDITS_INITIAL Expect HW 0x10000200C0
4100Sstevel@tonic-gate */
4110Sstevel@tonic-gate
4120Sstevel@tonic-gate /*
4130Sstevel@tonic-gate * Ingress credits initial register. Bits [39:32] should be
4140Sstevel@tonic-gate * 0x10, bits [19:12] should be 0x20, and bits [11:0] should
4150Sstevel@tonic-gate * be 0xC0. These are the reset values, and should be set by
4160Sstevel@tonic-gate * HW.
4170Sstevel@tonic-gate */
4180Sstevel@tonic-gate DBG(DBG_TLU, NULL, "tlu_init - TLU_INGRESS_CREDITS_INITIAL: 0x%llx\n",
41927Sjchu CSR_XR(csr_base, TLU_INGRESS_CREDITS_INITIAL));
4200Sstevel@tonic-gate
4210Sstevel@tonic-gate /*
4220Sstevel@tonic-gate * CSR_V TLU_DIAGNOSTIC Expect HW 0x0
4230Sstevel@tonic-gate */
4240Sstevel@tonic-gate
4250Sstevel@tonic-gate /*
4260Sstevel@tonic-gate * Diagnostic register - always zero unless we are debugging.
4270Sstevel@tonic-gate */
4280Sstevel@tonic-gate DBG(DBG_TLU, NULL, "tlu_init - TLU_DIAGNOSTIC: 0x%llx\n",
42927Sjchu CSR_XR(csr_base, TLU_DIAGNOSTIC));
4300Sstevel@tonic-gate
4310Sstevel@tonic-gate /*
4320Sstevel@tonic-gate * CSR_V TLU_EGRESS_CREDITS_CONSUMED Expect HW 0x0
4330Sstevel@tonic-gate */
4340Sstevel@tonic-gate DBG(DBG_TLU, NULL, "tlu_init - TLU_EGRESS_CREDITS_CONSUMED: 0x%llx\n",
43527Sjchu CSR_XR(csr_base, TLU_EGRESS_CREDITS_CONSUMED));
4360Sstevel@tonic-gate
4370Sstevel@tonic-gate /*
4380Sstevel@tonic-gate * CSR_V TLU_EGRESS_CREDIT_LIMIT Expect HW 0x0
4390Sstevel@tonic-gate */
4400Sstevel@tonic-gate DBG(DBG_TLU, NULL, "tlu_init - TLU_EGRESS_CREDIT_LIMIT: 0x%llx\n",
44127Sjchu CSR_XR(csr_base, TLU_EGRESS_CREDIT_LIMIT));
4420Sstevel@tonic-gate
4430Sstevel@tonic-gate /*
4440Sstevel@tonic-gate * CSR_V TLU_EGRESS_RETRY_BUFFER Expect HW 0x0
4450Sstevel@tonic-gate */
4460Sstevel@tonic-gate DBG(DBG_TLU, NULL, "tlu_init - TLU_EGRESS_RETRY_BUFFER: 0x%llx\n",
44727Sjchu CSR_XR(csr_base, TLU_EGRESS_RETRY_BUFFER));
4480Sstevel@tonic-gate
4490Sstevel@tonic-gate /*
4500Sstevel@tonic-gate * CSR_V TLU_INGRESS_CREDITS_ALLOCATED Expected HW 0x0
4510Sstevel@tonic-gate */
4520Sstevel@tonic-gate DBG(DBG_TLU, NULL,
45327Sjchu "tlu_init - TLU_INGRESS_CREDITS_ALLOCATED: 0x%llx\n",
45427Sjchu CSR_XR(csr_base, TLU_INGRESS_CREDITS_ALLOCATED));
4550Sstevel@tonic-gate
4560Sstevel@tonic-gate /*
4570Sstevel@tonic-gate * CSR_V TLU_INGRESS_CREDITS_RECEIVED Expected HW 0x0
4580Sstevel@tonic-gate */
4590Sstevel@tonic-gate DBG(DBG_TLU, NULL,
46027Sjchu "tlu_init - TLU_INGRESS_CREDITS_RECEIVED: 0x%llx\n",
46127Sjchu CSR_XR(csr_base, TLU_INGRESS_CREDITS_RECEIVED));
4620Sstevel@tonic-gate
4630Sstevel@tonic-gate /*
46427Sjchu * CSR_V TLU's interrupt regs (log, enable, status, clear)
4650Sstevel@tonic-gate */
4660Sstevel@tonic-gate DBG(DBG_TLU, NULL,
46727Sjchu "tlu_init - TLU_OTHER_EVENT_LOG_ENABLE: 0x%llx\n",
46827Sjchu CSR_XR(csr_base, TLU_OTHER_EVENT_LOG_ENABLE));
46927Sjchu
4700Sstevel@tonic-gate DBG(DBG_TLU, NULL,
47127Sjchu "tlu_init - TLU_OTHER_EVENT_INTERRUPT_ENABLE: 0x%llx\n",
47227Sjchu CSR_XR(csr_base, TLU_OTHER_EVENT_INTERRUPT_ENABLE));
47327Sjchu
47427Sjchu DBG(DBG_TLU, NULL,
47527Sjchu "tlu_init - TLU_OTHER_EVENT_INTERRUPT_STATUS: 0x%llx\n",
47627Sjchu CSR_XR(csr_base, TLU_OTHER_EVENT_INTERRUPT_STATUS));
47727Sjchu
47827Sjchu DBG(DBG_TLU, NULL,
47927Sjchu "tlu_init - TLU_OTHER_EVENT_STATUS_CLEAR: 0x%llx\n",
48027Sjchu CSR_XR(csr_base, TLU_OTHER_EVENT_STATUS_CLEAR));
4810Sstevel@tonic-gate
4820Sstevel@tonic-gate /*
4830Sstevel@tonic-gate * CSR_V TLU_RECEIVE_OTHER_EVENT_HEADER1_LOG Expect HW 0x0
4840Sstevel@tonic-gate */
4850Sstevel@tonic-gate DBG(DBG_TLU, NULL,
48627Sjchu "tlu_init - TLU_RECEIVE_OTHER_EVENT_HEADER1_LOG: 0x%llx\n",
48727Sjchu CSR_XR(csr_base, TLU_RECEIVE_OTHER_EVENT_HEADER1_LOG));
4880Sstevel@tonic-gate
4890Sstevel@tonic-gate /*
4900Sstevel@tonic-gate * CSR_V TLU_RECEIVE_OTHER_EVENT_HEADER2_LOG Expect HW 0x0
4910Sstevel@tonic-gate */
4920Sstevel@tonic-gate DBG(DBG_TLU, NULL,
49327Sjchu "tlu_init - TLU_RECEIVE_OTHER_EVENT_HEADER2_LOG: 0x%llx\n",
49427Sjchu CSR_XR(csr_base, TLU_RECEIVE_OTHER_EVENT_HEADER2_LOG));
4950Sstevel@tonic-gate
4960Sstevel@tonic-gate /*
4970Sstevel@tonic-gate * CSR_V TLU_TRANSMIT_OTHER_EVENT_HEADER1_LOG Expect HW 0x0
4980Sstevel@tonic-gate */
4990Sstevel@tonic-gate DBG(DBG_TLU, NULL,
50027Sjchu "tlu_init - TLU_TRANSMIT_OTHER_EVENT_HEADER1_LOG: 0x%llx\n",
50127Sjchu CSR_XR(csr_base, TLU_TRANSMIT_OTHER_EVENT_HEADER1_LOG));
5020Sstevel@tonic-gate
5030Sstevel@tonic-gate /*
5040Sstevel@tonic-gate * CSR_V TLU_TRANSMIT_OTHER_EVENT_HEADER2_LOG Expect HW 0x0
5050Sstevel@tonic-gate */
5060Sstevel@tonic-gate DBG(DBG_TLU, NULL,
50727Sjchu "tlu_init - TLU_TRANSMIT_OTHER_EVENT_HEADER2_LOG: 0x%llx\n",
50827Sjchu CSR_XR(csr_base, TLU_TRANSMIT_OTHER_EVENT_HEADER2_LOG));
5090Sstevel@tonic-gate
5100Sstevel@tonic-gate /*
5110Sstevel@tonic-gate * CSR_V TLU_PERFORMANCE_COUNTER_SELECT Expect HW 0x0
5120Sstevel@tonic-gate */
5130Sstevel@tonic-gate DBG(DBG_TLU, NULL,
51427Sjchu "tlu_init - TLU_PERFORMANCE_COUNTER_SELECT: 0x%llx\n",
51527Sjchu CSR_XR(csr_base, TLU_PERFORMANCE_COUNTER_SELECT));
5160Sstevel@tonic-gate
5170Sstevel@tonic-gate /*
5180Sstevel@tonic-gate * CSR_V TLU_PERFORMANCE_COUNTER_ZERO Expect HW 0x0
5190Sstevel@tonic-gate */
5200Sstevel@tonic-gate DBG(DBG_TLU, NULL,
52127Sjchu "tlu_init - TLU_PERFORMANCE_COUNTER_ZERO: 0x%llx\n",
52227Sjchu CSR_XR(csr_base, TLU_PERFORMANCE_COUNTER_ZERO));
5230Sstevel@tonic-gate
5240Sstevel@tonic-gate /*
5250Sstevel@tonic-gate * CSR_V TLU_PERFORMANCE_COUNTER_ONE Expect HW 0x0
5260Sstevel@tonic-gate */
5270Sstevel@tonic-gate DBG(DBG_TLU, NULL, "tlu_init - TLU_PERFORMANCE_COUNTER_ONE: 0x%llx\n",
52827Sjchu CSR_XR(csr_base, TLU_PERFORMANCE_COUNTER_ONE));
5290Sstevel@tonic-gate
5300Sstevel@tonic-gate /*
5310Sstevel@tonic-gate * CSR_V TLU_PERFORMANCE_COUNTER_TWO Expect HW 0x0
5320Sstevel@tonic-gate */
5330Sstevel@tonic-gate DBG(DBG_TLU, NULL, "tlu_init - TLU_PERFORMANCE_COUNTER_TWO: 0x%llx\n",
53427Sjchu CSR_XR(csr_base, TLU_PERFORMANCE_COUNTER_TWO));
5350Sstevel@tonic-gate
5360Sstevel@tonic-gate /*
5370Sstevel@tonic-gate * CSR_V TLU_DEBUG_SELECT_A Expect HW 0x0
5380Sstevel@tonic-gate */
5390Sstevel@tonic-gate
5400Sstevel@tonic-gate DBG(DBG_TLU, NULL, "tlu_init - TLU_DEBUG_SELECT_A: 0x%llx\n",
54127Sjchu CSR_XR(csr_base, TLU_DEBUG_SELECT_A));
5420Sstevel@tonic-gate
5430Sstevel@tonic-gate /*
5440Sstevel@tonic-gate * CSR_V TLU_DEBUG_SELECT_B Expect HW 0x0
5450Sstevel@tonic-gate */
5460Sstevel@tonic-gate DBG(DBG_TLU, NULL, "tlu_init - TLU_DEBUG_SELECT_B: 0x%llx\n",
54727Sjchu CSR_XR(csr_base, TLU_DEBUG_SELECT_B));
5480Sstevel@tonic-gate
5490Sstevel@tonic-gate /*
5500Sstevel@tonic-gate * CSR_V TLU_DEVICE_CAPABILITIES Expect HW 0xFC2
5510Sstevel@tonic-gate */
5520Sstevel@tonic-gate DBG(DBG_TLU, NULL, "tlu_init - TLU_DEVICE_CAPABILITIES: 0x%llx\n",
55327Sjchu CSR_XR(csr_base, TLU_DEVICE_CAPABILITIES));
5540Sstevel@tonic-gate
5550Sstevel@tonic-gate /*
5560Sstevel@tonic-gate * CSR_V TLU_DEVICE_CONTROL Expect HW 0x0
5570Sstevel@tonic-gate */
5580Sstevel@tonic-gate
5590Sstevel@tonic-gate /*
5600Sstevel@tonic-gate * Bits [14:12] are the Max Read Request Size, which is always 64
5610Sstevel@tonic-gate * bytes which is 000b. Bits [7:5] are Max Payload Size, which
5620Sstevel@tonic-gate * start at 128 bytes which is 000b. This may be revisited if
5630Sstevel@tonic-gate * init_child finds greater values.
5640Sstevel@tonic-gate */
5650Sstevel@tonic-gate val = 0x0ull;
5660Sstevel@tonic-gate CSR_XS(csr_base, TLU_DEVICE_CONTROL, val);
5670Sstevel@tonic-gate DBG(DBG_TLU, NULL, "tlu_init - TLU_DEVICE_CONTROL: 0x%llx\n",
56827Sjchu CSR_XR(csr_base, TLU_DEVICE_CONTROL));
5690Sstevel@tonic-gate
5700Sstevel@tonic-gate /*
5710Sstevel@tonic-gate * CSR_V TLU_DEVICE_STATUS Expect HW 0x0
5720Sstevel@tonic-gate */
5730Sstevel@tonic-gate DBG(DBG_TLU, NULL, "tlu_init - TLU_DEVICE_STATUS: 0x%llx\n",
57427Sjchu CSR_XR(csr_base, TLU_DEVICE_STATUS));
5750Sstevel@tonic-gate
5760Sstevel@tonic-gate /*
5770Sstevel@tonic-gate * CSR_V TLU_LINK_CAPABILITIES Expect HW 0x15C81
5780Sstevel@tonic-gate */
5790Sstevel@tonic-gate DBG(DBG_TLU, NULL, "tlu_init - TLU_LINK_CAPABILITIES: 0x%llx\n",
58027Sjchu CSR_XR(csr_base, TLU_LINK_CAPABILITIES));
5810Sstevel@tonic-gate
5820Sstevel@tonic-gate /*
5830Sstevel@tonic-gate * CSR_V TLU_LINK_CONTROL Expect OBP 0x40
5840Sstevel@tonic-gate */
5850Sstevel@tonic-gate
5860Sstevel@tonic-gate /*
5870Sstevel@tonic-gate * The CLOCK bit should be set by OBP if the hardware dictates,
5880Sstevel@tonic-gate * and if it is set then ASPM should be used since then L0s exit
5890Sstevel@tonic-gate * latency should be lower than L1 exit latency.
5900Sstevel@tonic-gate *
5910Sstevel@tonic-gate * Note that we will not enable power management during bringup
5920Sstevel@tonic-gate * since it has not been test and is creating some problems in
5930Sstevel@tonic-gate * simulation.
5940Sstevel@tonic-gate */
5950Sstevel@tonic-gate val = (1ull << TLU_LINK_CONTROL_CLOCK);
5960Sstevel@tonic-gate
5970Sstevel@tonic-gate CSR_XS(csr_base, TLU_LINK_CONTROL, val);
5980Sstevel@tonic-gate DBG(DBG_TLU, NULL, "tlu_init - TLU_LINK_CONTROL: 0x%llx\n",
59927Sjchu CSR_XR(csr_base, TLU_LINK_CONTROL));
6000Sstevel@tonic-gate
6010Sstevel@tonic-gate /*
6020Sstevel@tonic-gate * CSR_V TLU_LINK_STATUS Expect OBP 0x1011
6030Sstevel@tonic-gate */
6040Sstevel@tonic-gate
6050Sstevel@tonic-gate /*
6060Sstevel@tonic-gate * Not sure if HW or OBP will be setting this read only
6070Sstevel@tonic-gate * register. Bit 12 is Clock, and it should always be 1
6080Sstevel@tonic-gate * signifying that the component uses the same physical
6090Sstevel@tonic-gate * clock as the platform. Bits [9:4] are for the width,
6100Sstevel@tonic-gate * with the expected value above signifying a x1 width.
6110Sstevel@tonic-gate * Bits [3:0] are the speed, with 1b signifying 2.5 Gb/s,
6120Sstevel@tonic-gate * the only speed as yet supported by the PCI-E spec.
6130Sstevel@tonic-gate */
6140Sstevel@tonic-gate DBG(DBG_TLU, NULL, "tlu_init - TLU_LINK_STATUS: 0x%llx\n",
61527Sjchu CSR_XR(csr_base, TLU_LINK_STATUS));
6160Sstevel@tonic-gate
6170Sstevel@tonic-gate /*
6180Sstevel@tonic-gate * CSR_V TLU_SLOT_CAPABILITIES Expect OBP ???
6190Sstevel@tonic-gate */
6200Sstevel@tonic-gate
6210Sstevel@tonic-gate /*
6220Sstevel@tonic-gate * Power Limits for the slots. Will be platform
6230Sstevel@tonic-gate * dependent, and OBP will need to set after consulting
6240Sstevel@tonic-gate * with the HW guys.
6250Sstevel@tonic-gate *
6260Sstevel@tonic-gate * Bits [16:15] are power limit scale, which most likely
6270Sstevel@tonic-gate * will be 0b signifying 1x. Bits [14:7] are the Set
6280Sstevel@tonic-gate * Power Limit Value, which is a number which is multiplied
6290Sstevel@tonic-gate * by the power limit scale to get the actual power limit.
6300Sstevel@tonic-gate */
6310Sstevel@tonic-gate DBG(DBG_TLU, NULL, "tlu_init - TLU_SLOT_CAPABILITIES: 0x%llx\n",
63227Sjchu CSR_XR(csr_base, TLU_SLOT_CAPABILITIES));
6330Sstevel@tonic-gate
6340Sstevel@tonic-gate /*
6350Sstevel@tonic-gate * CSR_V TLU_UNCORRECTABLE_ERROR_LOG_ENABLE Expect Kernel 0x17F011
6360Sstevel@tonic-gate */
6370Sstevel@tonic-gate DBG(DBG_TLU, NULL,
63827Sjchu "tlu_init - TLU_UNCORRECTABLE_ERROR_LOG_ENABLE: 0x%llx\n",
63927Sjchu CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_LOG_ENABLE));
6400Sstevel@tonic-gate
6410Sstevel@tonic-gate /*
64227Sjchu * CSR_V TLU_UNCORRECTABLE_ERROR_INTERRUPT_ENABLE Expect
64327Sjchu * Kernel 0x17F0110017F011
6440Sstevel@tonic-gate */
6450Sstevel@tonic-gate DBG(DBG_TLU, NULL,
64627Sjchu "tlu_init - TLU_UNCORRECTABLE_ERROR_INTERRUPT_ENABLE: 0x%llx\n",
64727Sjchu CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_INTERRUPT_ENABLE));
6480Sstevel@tonic-gate
6490Sstevel@tonic-gate /*
6500Sstevel@tonic-gate * CSR_V TLU_UNCORRECTABLE_ERROR_INTERRUPT_STATUS Expect HW 0x0
6510Sstevel@tonic-gate */
6520Sstevel@tonic-gate DBG(DBG_TLU, NULL,
65327Sjchu "tlu_init - TLU_UNCORRECTABLE_ERROR_INTERRUPT_STATUS: 0x%llx\n",
65427Sjchu CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_INTERRUPT_STATUS));
6550Sstevel@tonic-gate
6560Sstevel@tonic-gate /*
6570Sstevel@tonic-gate * CSR_V TLU_UNCORRECTABLE_ERROR_STATUS_CLEAR Expect HW 0x0
6580Sstevel@tonic-gate */
6590Sstevel@tonic-gate DBG(DBG_TLU, NULL,
66027Sjchu "tlu_init - TLU_UNCORRECTABLE_ERROR_STATUS_CLEAR: 0x%llx\n",
66127Sjchu CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_STATUS_CLEAR));
6620Sstevel@tonic-gate
6630Sstevel@tonic-gate /*
6640Sstevel@tonic-gate * CSR_V TLU_RECEIVE_UNCORRECTABLE_ERROR_HEADER1_LOG HW 0x0
6650Sstevel@tonic-gate */
6660Sstevel@tonic-gate DBG(DBG_TLU, NULL,
6670Sstevel@tonic-gate "tlu_init - TLU_RECEIVE_UNCORRECTABLE_ERROR_HEADER1_LOG: 0x%llx\n",
6680Sstevel@tonic-gate CSR_XR(csr_base, TLU_RECEIVE_UNCORRECTABLE_ERROR_HEADER1_LOG));
6690Sstevel@tonic-gate
6700Sstevel@tonic-gate /*
6710Sstevel@tonic-gate * CSR_V TLU_RECEIVE_UNCORRECTABLE_ERROR_HEADER2_LOG HW 0x0
6720Sstevel@tonic-gate */
6730Sstevel@tonic-gate DBG(DBG_TLU, NULL,
6740Sstevel@tonic-gate "tlu_init - TLU_RECEIVE_UNCORRECTABLE_ERROR_HEADER2_LOG: 0x%llx\n",
6750Sstevel@tonic-gate CSR_XR(csr_base, TLU_RECEIVE_UNCORRECTABLE_ERROR_HEADER2_LOG));
6760Sstevel@tonic-gate
6770Sstevel@tonic-gate /*
6780Sstevel@tonic-gate * CSR_V TLU_TRANSMIT_UNCORRECTABLE_ERROR_HEADER1_LOG HW 0x0
6790Sstevel@tonic-gate */
6800Sstevel@tonic-gate DBG(DBG_TLU, NULL,
6810Sstevel@tonic-gate "tlu_init - TLU_TRANSMIT_UNCORRECTABLE_ERROR_HEADER1_LOG: 0x%llx\n",
6820Sstevel@tonic-gate CSR_XR(csr_base, TLU_TRANSMIT_UNCORRECTABLE_ERROR_HEADER1_LOG));
6830Sstevel@tonic-gate
6840Sstevel@tonic-gate /*
6850Sstevel@tonic-gate * CSR_V TLU_TRANSMIT_UNCORRECTABLE_ERROR_HEADER2_LOG HW 0x0
6860Sstevel@tonic-gate */
6870Sstevel@tonic-gate DBG(DBG_TLU, NULL,
6880Sstevel@tonic-gate "tlu_init - TLU_TRANSMIT_UNCORRECTABLE_ERROR_HEADER2_LOG: 0x%llx\n",
6890Sstevel@tonic-gate CSR_XR(csr_base, TLU_TRANSMIT_UNCORRECTABLE_ERROR_HEADER2_LOG));
6900Sstevel@tonic-gate
69127Sjchu
6920Sstevel@tonic-gate /*
69327Sjchu * CSR_V TLU's CE interrupt regs (log, enable, status, clear)
69427Sjchu * Plus header logs
6950Sstevel@tonic-gate */
6960Sstevel@tonic-gate
6970Sstevel@tonic-gate /*
69827Sjchu * CSR_V TLU_CORRECTABLE_ERROR_LOG_ENABLE Expect Kernel 0x11C1
6990Sstevel@tonic-gate */
7000Sstevel@tonic-gate DBG(DBG_TLU, NULL,
70127Sjchu "tlu_init - TLU_CORRECTABLE_ERROR_LOG_ENABLE: 0x%llx\n",
70227Sjchu CSR_XR(csr_base, TLU_CORRECTABLE_ERROR_LOG_ENABLE));
7030Sstevel@tonic-gate
7040Sstevel@tonic-gate /*
7050Sstevel@tonic-gate * CSR_V TLU_CORRECTABLE_ERROR_INTERRUPT_ENABLE Kernel 0x11C1000011C1
7060Sstevel@tonic-gate */
7070Sstevel@tonic-gate DBG(DBG_TLU, NULL,
70827Sjchu "tlu_init - TLU_CORRECTABLE_ERROR_INTERRUPT_ENABLE: 0x%llx\n",
70927Sjchu CSR_XR(csr_base, TLU_CORRECTABLE_ERROR_INTERRUPT_ENABLE));
7100Sstevel@tonic-gate
7110Sstevel@tonic-gate /*
7120Sstevel@tonic-gate * CSR_V TLU_CORRECTABLE_ERROR_INTERRUPT_STATUS Expect HW 0x0
7130Sstevel@tonic-gate */
7140Sstevel@tonic-gate DBG(DBG_TLU, NULL,
71527Sjchu "tlu_init - TLU_CORRECTABLE_ERROR_INTERRUPT_STATUS: 0x%llx\n",
71627Sjchu CSR_XR(csr_base, TLU_CORRECTABLE_ERROR_INTERRUPT_STATUS));
7170Sstevel@tonic-gate
7180Sstevel@tonic-gate /*
7190Sstevel@tonic-gate * CSR_V TLU_CORRECTABLE_ERROR_STATUS_CLEAR Expect HW 0x0
7200Sstevel@tonic-gate */
7210Sstevel@tonic-gate DBG(DBG_TLU, NULL,
72227Sjchu "tlu_init - TLU_CORRECTABLE_ERROR_STATUS_CLEAR: 0x%llx\n",
72327Sjchu CSR_XR(csr_base, TLU_CORRECTABLE_ERROR_STATUS_CLEAR));
7240Sstevel@tonic-gate }
7250Sstevel@tonic-gate
726225Sess /* ARGSUSED */
7270Sstevel@tonic-gate static void
lpu_init(caddr_t csr_base,pxu_t * pxu_p)7280Sstevel@tonic-gate lpu_init(caddr_t csr_base, pxu_t *pxu_p)
7290Sstevel@tonic-gate {
7300Sstevel@tonic-gate /* Variables used to set the ACKNAK Latency Timer and Replay Timer */
7310Sstevel@tonic-gate int link_width, max_payload;
7320Sstevel@tonic-gate
7330Sstevel@tonic-gate uint64_t val;
7340Sstevel@tonic-gate
7350Sstevel@tonic-gate /*
7360Sstevel@tonic-gate * Get the Link Width. See table above LINK_WIDTH_ARR_SIZE #define
7370Sstevel@tonic-gate * Only Link Widths of x1, x4, and x8 are supported.
7380Sstevel@tonic-gate * If any width is reported other than x8, set default to x8.
7390Sstevel@tonic-gate */
7400Sstevel@tonic-gate link_width = CSR_FR(csr_base, TLU_LINK_STATUS, WIDTH);
7410Sstevel@tonic-gate DBG(DBG_LPU, NULL, "lpu_init - Link Width: x%d\n", link_width);
7420Sstevel@tonic-gate
7430Sstevel@tonic-gate /*
7440Sstevel@tonic-gate * Convert link_width to match timer array configuration.
7450Sstevel@tonic-gate */
7460Sstevel@tonic-gate switch (link_width) {
7470Sstevel@tonic-gate case 1:
7480Sstevel@tonic-gate link_width = 0;
7490Sstevel@tonic-gate break;
7500Sstevel@tonic-gate case 4:
7510Sstevel@tonic-gate link_width = 1;
7520Sstevel@tonic-gate break;
7530Sstevel@tonic-gate case 8:
7540Sstevel@tonic-gate link_width = 2;
7550Sstevel@tonic-gate break;
7560Sstevel@tonic-gate case 16:
7570Sstevel@tonic-gate link_width = 3;
7580Sstevel@tonic-gate break;
7590Sstevel@tonic-gate default:
7600Sstevel@tonic-gate link_width = 0;
7610Sstevel@tonic-gate }
7620Sstevel@tonic-gate
7630Sstevel@tonic-gate /*
7640Sstevel@tonic-gate * Get the Max Payload Size.
7650Sstevel@tonic-gate * See table above LINK_MAX_PKT_ARR_SIZE #define
7660Sstevel@tonic-gate */
767225Sess max_payload = ((CSR_FR(csr_base, TLU_CONTROL, CONFIG) &
768225Sess TLU_CONTROL_MPS_MASK) >> TLU_CONTROL_MPS_SHIFT);
7690Sstevel@tonic-gate
7700Sstevel@tonic-gate DBG(DBG_LPU, NULL, "lpu_init - May Payload: %d\n",
7710Sstevel@tonic-gate (0x80 << max_payload));
7720Sstevel@tonic-gate
7730Sstevel@tonic-gate /* Make sure the packet size is not greater than 4096 */
7740Sstevel@tonic-gate max_payload = (max_payload >= LINK_MAX_PKT_ARR_SIZE) ?
7750Sstevel@tonic-gate (LINK_MAX_PKT_ARR_SIZE - 1) : max_payload;
7760Sstevel@tonic-gate
7770Sstevel@tonic-gate /*
7780Sstevel@tonic-gate * CSR_V LPU_ID Expect HW 0x0
7790Sstevel@tonic-gate */
7800Sstevel@tonic-gate
7810Sstevel@tonic-gate /*
7820Sstevel@tonic-gate * This register has link id, phy id and gigablaze id.
7830Sstevel@tonic-gate * Should be set by HW.
7840Sstevel@tonic-gate */
7850Sstevel@tonic-gate DBG(DBG_LPU, NULL, "lpu_init - LPU_ID: 0x%llx\n",
78627Sjchu CSR_XR(csr_base, LPU_ID));
7870Sstevel@tonic-gate
7880Sstevel@tonic-gate /*
7890Sstevel@tonic-gate * CSR_V LPU_RESET Expect Kernel 0x0
7900Sstevel@tonic-gate */
7910Sstevel@tonic-gate
7920Sstevel@tonic-gate /*
7930Sstevel@tonic-gate * No reason to have any reset bits high until an error is
7940Sstevel@tonic-gate * detected on the link.
7950Sstevel@tonic-gate */
7960Sstevel@tonic-gate val = 0ull;
7970Sstevel@tonic-gate CSR_XS(csr_base, LPU_RESET, val);
7980Sstevel@tonic-gate DBG(DBG_LPU, NULL, "lpu_init - LPU_RESET: 0x%llx\n",
79927Sjchu CSR_XR(csr_base, LPU_RESET));
8000Sstevel@tonic-gate
8010Sstevel@tonic-gate /*
8020Sstevel@tonic-gate * CSR_V LPU_DEBUG_STATUS Expect HW 0x0
8030Sstevel@tonic-gate */
8040Sstevel@tonic-gate
8050Sstevel@tonic-gate /*
8060Sstevel@tonic-gate * Bits [15:8] are Debug B, and bit [7:0] are Debug A.
8070Sstevel@tonic-gate * They are read-only. What do the 8 bits mean, and
8080Sstevel@tonic-gate * how do they get set if they are read only?
8090Sstevel@tonic-gate */
8100Sstevel@tonic-gate DBG(DBG_LPU, NULL, "lpu_init - LPU_DEBUG_STATUS: 0x%llx\n",
81127Sjchu CSR_XR(csr_base, LPU_DEBUG_STATUS));
8120Sstevel@tonic-gate
8130Sstevel@tonic-gate /*
8140Sstevel@tonic-gate * CSR_V LPU_DEBUG_CONFIG Expect Kernel 0x0
8150Sstevel@tonic-gate */
8160Sstevel@tonic-gate DBG(DBG_LPU, NULL, "lpu_init - LPU_DEBUG_CONFIG: 0x%llx\n",
81727Sjchu CSR_XR(csr_base, LPU_DEBUG_CONFIG));
8180Sstevel@tonic-gate
8190Sstevel@tonic-gate /*
8200Sstevel@tonic-gate * CSR_V LPU_LTSSM_CONTROL Expect HW 0x0
8210Sstevel@tonic-gate */
8220Sstevel@tonic-gate DBG(DBG_LPU, NULL, "lpu_init - LPU_LTSSM_CONTROL: 0x%llx\n",
82327Sjchu CSR_XR(csr_base, LPU_LTSSM_CONTROL));
8240Sstevel@tonic-gate
8250Sstevel@tonic-gate /*
8260Sstevel@tonic-gate * CSR_V LPU_LINK_STATUS Expect HW 0x101
8270Sstevel@tonic-gate */
8280Sstevel@tonic-gate
8290Sstevel@tonic-gate /*
8300Sstevel@tonic-gate * This register has bits [9:4] for link width, and the
8310Sstevel@tonic-gate * default 0x10, means a width of x16. The problem is
8320Sstevel@tonic-gate * this width is not supported according to the TLU
8330Sstevel@tonic-gate * link status register.
8340Sstevel@tonic-gate */
8350Sstevel@tonic-gate DBG(DBG_LPU, NULL, "lpu_init - LPU_LINK_STATUS: 0x%llx\n",
83627Sjchu CSR_XR(csr_base, LPU_LINK_STATUS));
8370Sstevel@tonic-gate
8380Sstevel@tonic-gate /*
8390Sstevel@tonic-gate * CSR_V LPU_INTERRUPT_STATUS Expect HW 0x0
8400Sstevel@tonic-gate */
8410Sstevel@tonic-gate DBG(DBG_LPU, NULL, "lpu_init - LPU_INTERRUPT_STATUS: 0x%llx\n",
84227Sjchu CSR_XR(csr_base, LPU_INTERRUPT_STATUS));
8430Sstevel@tonic-gate
8440Sstevel@tonic-gate /*
8450Sstevel@tonic-gate * CSR_V LPU_INTERRUPT_MASK Expect HW 0x0
8460Sstevel@tonic-gate */
8470Sstevel@tonic-gate DBG(DBG_LPU, NULL, "lpu_init - LPU_INTERRUPT_MASK: 0x%llx\n",
84827Sjchu CSR_XR(csr_base, LPU_INTERRUPT_MASK));
8490Sstevel@tonic-gate
8500Sstevel@tonic-gate /*
8510Sstevel@tonic-gate * CSR_V LPU_LINK_PERFORMANCE_COUNTER_SELECT Expect HW 0x0
8520Sstevel@tonic-gate */
8530Sstevel@tonic-gate DBG(DBG_LPU, NULL,
85427Sjchu "lpu_init - LPU_LINK_PERFORMANCE_COUNTER_SELECT: 0x%llx\n",
85527Sjchu CSR_XR(csr_base, LPU_LINK_PERFORMANCE_COUNTER_SELECT));
8560Sstevel@tonic-gate
8570Sstevel@tonic-gate /*
8580Sstevel@tonic-gate * CSR_V LPU_LINK_PERFORMANCE_COUNTER_CONTROL Expect HW 0x0
8590Sstevel@tonic-gate */
8600Sstevel@tonic-gate DBG(DBG_LPU, NULL,
86127Sjchu "lpu_init - LPU_LINK_PERFORMANCE_COUNTER_CONTROL: 0x%llx\n",
86227Sjchu CSR_XR(csr_base, LPU_LINK_PERFORMANCE_COUNTER_CONTROL));
8630Sstevel@tonic-gate
8640Sstevel@tonic-gate /*
8650Sstevel@tonic-gate * CSR_V LPU_LINK_PERFORMANCE_COUNTER1 Expect HW 0x0
8660Sstevel@tonic-gate */
8670Sstevel@tonic-gate DBG(DBG_LPU, NULL,
86827Sjchu "lpu_init - LPU_LINK_PERFORMANCE_COUNTER1: 0x%llx\n",
86927Sjchu CSR_XR(csr_base, LPU_LINK_PERFORMANCE_COUNTER1));
8700Sstevel@tonic-gate
8710Sstevel@tonic-gate /*
8720Sstevel@tonic-gate * CSR_V LPU_LINK_PERFORMANCE_COUNTER1_TEST Expect HW 0x0
8730Sstevel@tonic-gate */
8740Sstevel@tonic-gate DBG(DBG_LPU, NULL,
87527Sjchu "lpu_init - LPU_LINK_PERFORMANCE_COUNTER1_TEST: 0x%llx\n",
87627Sjchu CSR_XR(csr_base, LPU_LINK_PERFORMANCE_COUNTER1_TEST));
8770Sstevel@tonic-gate
8780Sstevel@tonic-gate /*
8790Sstevel@tonic-gate * CSR_V LPU_LINK_PERFORMANCE_COUNTER2 Expect HW 0x0
8800Sstevel@tonic-gate */
8810Sstevel@tonic-gate DBG(DBG_LPU, NULL,
88227Sjchu "lpu_init - LPU_LINK_PERFORMANCE_COUNTER2: 0x%llx\n",
88327Sjchu CSR_XR(csr_base, LPU_LINK_PERFORMANCE_COUNTER2));
8840Sstevel@tonic-gate
8850Sstevel@tonic-gate /*
8860Sstevel@tonic-gate * CSR_V LPU_LINK_PERFORMANCE_COUNTER2_TEST Expect HW 0x0
8870Sstevel@tonic-gate */
8880Sstevel@tonic-gate DBG(DBG_LPU, NULL,
88927Sjchu "lpu_init - LPU_LINK_PERFORMANCE_COUNTER2_TEST: 0x%llx\n",
89027Sjchu CSR_XR(csr_base, LPU_LINK_PERFORMANCE_COUNTER2_TEST));
8910Sstevel@tonic-gate
8920Sstevel@tonic-gate /*
8930Sstevel@tonic-gate * CSR_V LPU_LINK_LAYER_CONFIG Expect HW 0x100
8940Sstevel@tonic-gate */
8950Sstevel@tonic-gate
8960Sstevel@tonic-gate /*
8970Sstevel@tonic-gate * This is another place where Max Payload can be set,
8980Sstevel@tonic-gate * this time for the link layer. It will be set to
8990Sstevel@tonic-gate * 128B, which is the default, but this will need to
9000Sstevel@tonic-gate * be revisited.
9010Sstevel@tonic-gate */
9020Sstevel@tonic-gate val = (1ull << LPU_LINK_LAYER_CONFIG_VC0_EN);
9030Sstevel@tonic-gate CSR_XS(csr_base, LPU_LINK_LAYER_CONFIG, val);
9040Sstevel@tonic-gate DBG(DBG_LPU, NULL, "lpu_init - LPU_LINK_LAYER_CONFIG: 0x%llx\n",
90527Sjchu CSR_XR(csr_base, LPU_LINK_LAYER_CONFIG));
9060Sstevel@tonic-gate
9070Sstevel@tonic-gate /*
9080Sstevel@tonic-gate * CSR_V LPU_LINK_LAYER_STATUS Expect OBP 0x5
9090Sstevel@tonic-gate */
9100Sstevel@tonic-gate
9110Sstevel@tonic-gate /*
9120Sstevel@tonic-gate * Another R/W status register. Bit 3, DL up Status, will
9130Sstevel@tonic-gate * be set high. The link state machine status bits [2:0]
9140Sstevel@tonic-gate * are set to 0x1, but the status bits are not defined in the
9150Sstevel@tonic-gate * PRM. What does 0x1 mean, what others values are possible
9160Sstevel@tonic-gate * and what are thier meanings?
9170Sstevel@tonic-gate *
9180Sstevel@tonic-gate * This register has been giving us problems in simulation.
9190Sstevel@tonic-gate * It has been mentioned that software should not program
9200Sstevel@tonic-gate * any registers with WE bits except during debug. So
9210Sstevel@tonic-gate * this register will no longer be programmed.
9220Sstevel@tonic-gate */
9230Sstevel@tonic-gate
9240Sstevel@tonic-gate DBG(DBG_LPU, NULL, "lpu_init - LPU_LINK_LAYER_STATUS: 0x%llx\n",
92527Sjchu CSR_XR(csr_base, LPU_LINK_LAYER_STATUS));
9260Sstevel@tonic-gate
9270Sstevel@tonic-gate /*
9280Sstevel@tonic-gate * CSR_V LPU_LINK_LAYER_INTERRUPT_AND_STATUS_TEST Expect HW 0x0
9290Sstevel@tonic-gate */
9300Sstevel@tonic-gate DBG(DBG_LPU, NULL,
93127Sjchu "lpu_init - LPU_LINK_LAYER_INTERRUPT_AND_STATUS_TEST: 0x%llx\n",
93227Sjchu CSR_XR(csr_base, LPU_LINK_LAYER_INTERRUPT_AND_STATUS_TEST));
9330Sstevel@tonic-gate
9340Sstevel@tonic-gate /*
93527Sjchu * CSR_V LPU Link Layer interrupt regs (mask, status)
9360Sstevel@tonic-gate */
9370Sstevel@tonic-gate DBG(DBG_LPU, NULL,
93827Sjchu "lpu_init - LPU_LINK_LAYER_INTERRUPT_MASK: 0x%llx\n",
93927Sjchu CSR_XR(csr_base, LPU_LINK_LAYER_INTERRUPT_MASK));
94027Sjchu
94127Sjchu DBG(DBG_LPU, NULL,
94227Sjchu "lpu_init - LPU_LINK_LAYER_INTERRUPT_AND_STATUS: 0x%llx\n",
94327Sjchu CSR_XR(csr_base, LPU_LINK_LAYER_INTERRUPT_AND_STATUS));
9440Sstevel@tonic-gate
9450Sstevel@tonic-gate /*
9460Sstevel@tonic-gate * CSR_V LPU_FLOW_CONTROL_UPDATE_CONTROL Expect OBP 0x7
9470Sstevel@tonic-gate */
9480Sstevel@tonic-gate
9490Sstevel@tonic-gate /*
9500Sstevel@tonic-gate * The PRM says that only the first two bits will be set
9510Sstevel@tonic-gate * high by default, which will enable flow control for
9520Sstevel@tonic-gate * posted and non-posted updates, but NOT completetion
9530Sstevel@tonic-gate * updates.
9540Sstevel@tonic-gate */
9550Sstevel@tonic-gate val = (1ull << LPU_FLOW_CONTROL_UPDATE_CONTROL_FC0_U_NP_EN) |
95627Sjchu (1ull << LPU_FLOW_CONTROL_UPDATE_CONTROL_FC0_U_P_EN);
9570Sstevel@tonic-gate CSR_XS(csr_base, LPU_FLOW_CONTROL_UPDATE_CONTROL, val);
9580Sstevel@tonic-gate DBG(DBG_LPU, NULL,
95927Sjchu "lpu_init - LPU_FLOW_CONTROL_UPDATE_CONTROL: 0x%llx\n",
96027Sjchu CSR_XR(csr_base, LPU_FLOW_CONTROL_UPDATE_CONTROL));
9610Sstevel@tonic-gate
9620Sstevel@tonic-gate /*
9630Sstevel@tonic-gate * CSR_V LPU_LINK_LAYER_FLOW_CONTROL_UPDATE_TIMEOUT_VALUE
9640Sstevel@tonic-gate * Expect OBP 0x1D4C
9650Sstevel@tonic-gate */
9660Sstevel@tonic-gate
9670Sstevel@tonic-gate /*
9680Sstevel@tonic-gate * This should be set by OBP. We'll check to make sure.
9690Sstevel@tonic-gate */
97027Sjchu DBG(DBG_LPU, NULL, "lpu_init - "
97127Sjchu "LPU_LINK_LAYER_FLOW_CONTROL_UPDATE_TIMEOUT_VALUE: 0x%llx\n",
97227Sjchu CSR_XR(csr_base,
97327Sjchu LPU_LINK_LAYER_FLOW_CONTROL_UPDATE_TIMEOUT_VALUE));
9740Sstevel@tonic-gate
9750Sstevel@tonic-gate /*
9760Sstevel@tonic-gate * CSR_V LPU_LINK_LAYER_VC0_FLOW_CONTROL_UPDATE_TIMER0 Expect OBP ???
9770Sstevel@tonic-gate */
9780Sstevel@tonic-gate
9790Sstevel@tonic-gate /*
9800Sstevel@tonic-gate * This register has Flow Control Update Timer values for
9810Sstevel@tonic-gate * non-posted and posted requests, bits [30:16] and bits
9820Sstevel@tonic-gate * [14:0], respectively. These are read-only to SW so
9830Sstevel@tonic-gate * either HW or OBP needs to set them.
9840Sstevel@tonic-gate */
98527Sjchu DBG(DBG_LPU, NULL, "lpu_init - "
98627Sjchu "LPU_LINK_LAYER_VC0_FLOW_CONTROL_UPDATE_TIMER0: 0x%llx\n",
98727Sjchu CSR_XR(csr_base,
98827Sjchu LPU_LINK_LAYER_VC0_FLOW_CONTROL_UPDATE_TIMER0));
9890Sstevel@tonic-gate
9900Sstevel@tonic-gate /*
9910Sstevel@tonic-gate * CSR_V LPU_LINK_LAYER_VC0_FLOW_CONTROL_UPDATE_TIMER1 Expect OBP ???
9920Sstevel@tonic-gate */
9930Sstevel@tonic-gate
9940Sstevel@tonic-gate /*
9950Sstevel@tonic-gate * Same as timer0 register above, except for bits [14:0]
9960Sstevel@tonic-gate * have the timer values for completetions. Read-only to
9970Sstevel@tonic-gate * SW; OBP or HW need to set it.
9980Sstevel@tonic-gate */
99927Sjchu DBG(DBG_LPU, NULL, "lpu_init - "
100027Sjchu "LPU_LINK_LAYER_VC0_FLOW_CONTROL_UPDATE_TIMER1: 0x%llx\n",
100127Sjchu CSR_XR(csr_base,
100227Sjchu LPU_LINK_LAYER_VC0_FLOW_CONTROL_UPDATE_TIMER1));
10030Sstevel@tonic-gate
10040Sstevel@tonic-gate /*
10050Sstevel@tonic-gate * CSR_V LPU_TXLINK_FREQUENT_NAK_LATENCY_TIMER_THRESHOLD
10060Sstevel@tonic-gate */
10077596SAlan.Adamson@Sun.COM val = px_acknak_timer_table[max_payload][link_width];
1008225Sess CSR_XS(csr_base, LPU_TXLINK_FREQUENT_NAK_LATENCY_TIMER_THRESHOLD, val);
10090Sstevel@tonic-gate
10100Sstevel@tonic-gate DBG(DBG_LPU, NULL, "lpu_init - "
10110Sstevel@tonic-gate "LPU_TXLINK_FREQUENT_NAK_LATENCY_TIMER_THRESHOLD: 0x%llx\n",
10120Sstevel@tonic-gate CSR_XR(csr_base, LPU_TXLINK_FREQUENT_NAK_LATENCY_TIMER_THRESHOLD));
10130Sstevel@tonic-gate
10140Sstevel@tonic-gate /*
10150Sstevel@tonic-gate * CSR_V LPU_TXLINK_ACKNAK_LATENCY_TIMER Expect HW 0x0
10160Sstevel@tonic-gate */
10170Sstevel@tonic-gate DBG(DBG_LPU, NULL,
101827Sjchu "lpu_init - LPU_TXLINK_ACKNAK_LATENCY_TIMER: 0x%llx\n",
101927Sjchu CSR_XR(csr_base, LPU_TXLINK_ACKNAK_LATENCY_TIMER));
10200Sstevel@tonic-gate
10210Sstevel@tonic-gate /*
10220Sstevel@tonic-gate * CSR_V LPU_TXLINK_REPLAY_TIMER_THRESHOLD
10230Sstevel@tonic-gate */
10247596SAlan.Adamson@Sun.COM val = px_replay_timer_table[max_payload][link_width];
10250Sstevel@tonic-gate CSR_XS(csr_base, LPU_TXLINK_REPLAY_TIMER_THRESHOLD, val);
10260Sstevel@tonic-gate
10270Sstevel@tonic-gate DBG(DBG_LPU, NULL,
10280Sstevel@tonic-gate "lpu_init - LPU_TXLINK_REPLAY_TIMER_THRESHOLD: 0x%llx\n",
10290Sstevel@tonic-gate CSR_XR(csr_base, LPU_TXLINK_REPLAY_TIMER_THRESHOLD));
10300Sstevel@tonic-gate
10310Sstevel@tonic-gate /*
10320Sstevel@tonic-gate * CSR_V LPU_TXLINK_REPLAY_TIMER Expect HW 0x0
10330Sstevel@tonic-gate */
10340Sstevel@tonic-gate DBG(DBG_LPU, NULL, "lpu_init - LPU_TXLINK_REPLAY_TIMER: 0x%llx\n",
103527Sjchu CSR_XR(csr_base, LPU_TXLINK_REPLAY_TIMER));
10360Sstevel@tonic-gate
10370Sstevel@tonic-gate /*
10380Sstevel@tonic-gate * CSR_V LPU_TXLINK_REPLAY_NUMBER_STATUS Expect OBP 0x3
10390Sstevel@tonic-gate */
10400Sstevel@tonic-gate DBG(DBG_LPU, NULL,
104127Sjchu "lpu_init - LPU_TXLINK_REPLAY_NUMBER_STATUS: 0x%llx\n",
104227Sjchu CSR_XR(csr_base, LPU_TXLINK_REPLAY_NUMBER_STATUS));
10430Sstevel@tonic-gate
10440Sstevel@tonic-gate /*
10450Sstevel@tonic-gate * CSR_V LPU_REPLAY_BUFFER_MAX_ADDRESS Expect OBP 0xB3F
10460Sstevel@tonic-gate */
10470Sstevel@tonic-gate DBG(DBG_LPU, NULL,
10480Sstevel@tonic-gate "lpu_init - LPU_REPLAY_BUFFER_MAX_ADDRESS: 0x%llx\n",
10490Sstevel@tonic-gate CSR_XR(csr_base, LPU_REPLAY_BUFFER_MAX_ADDRESS));
10500Sstevel@tonic-gate
10510Sstevel@tonic-gate /*
10520Sstevel@tonic-gate * CSR_V LPU_TXLINK_RETRY_FIFO_POINTER Expect OBP 0xFFFF0000
10530Sstevel@tonic-gate */
10540Sstevel@tonic-gate val = ((LPU_TXLINK_RETRY_FIFO_POINTER_RTRY_FIFO_TLPTR_DEFAULT <<
105527Sjchu LPU_TXLINK_RETRY_FIFO_POINTER_RTRY_FIFO_TLPTR) |
105627Sjchu (LPU_TXLINK_RETRY_FIFO_POINTER_RTRY_FIFO_HDPTR_DEFAULT <<
105727Sjchu LPU_TXLINK_RETRY_FIFO_POINTER_RTRY_FIFO_HDPTR));
10580Sstevel@tonic-gate
10590Sstevel@tonic-gate CSR_XS(csr_base, LPU_TXLINK_RETRY_FIFO_POINTER, val);
10600Sstevel@tonic-gate DBG(DBG_LPU, NULL,
106127Sjchu "lpu_init - LPU_TXLINK_RETRY_FIFO_POINTER: 0x%llx\n",
106227Sjchu CSR_XR(csr_base, LPU_TXLINK_RETRY_FIFO_POINTER));
10630Sstevel@tonic-gate
10640Sstevel@tonic-gate /*
10650Sstevel@tonic-gate * CSR_V LPU_TXLINK_RETRY_FIFO_R_W_POINTER Expect OBP 0x0
10660Sstevel@tonic-gate */
10670Sstevel@tonic-gate DBG(DBG_LPU, NULL,
10680Sstevel@tonic-gate "lpu_init - LPU_TXLINK_RETRY_FIFO_R_W_POINTER: 0x%llx\n",
10690Sstevel@tonic-gate CSR_XR(csr_base, LPU_TXLINK_RETRY_FIFO_R_W_POINTER));
10700Sstevel@tonic-gate
10710Sstevel@tonic-gate /*
10720Sstevel@tonic-gate * CSR_V LPU_TXLINK_RETRY_FIFO_CREDIT Expect HW 0x1580
10730Sstevel@tonic-gate */
10740Sstevel@tonic-gate DBG(DBG_LPU, NULL,
107527Sjchu "lpu_init - LPU_TXLINK_RETRY_FIFO_CREDIT: 0x%llx\n",
107627Sjchu CSR_XR(csr_base, LPU_TXLINK_RETRY_FIFO_CREDIT));
10770Sstevel@tonic-gate
10780Sstevel@tonic-gate /*
10790Sstevel@tonic-gate * CSR_V LPU_TXLINK_SEQUENCE_COUNTER Expect OBP 0xFFF0000
10800Sstevel@tonic-gate */
10810Sstevel@tonic-gate DBG(DBG_LPU, NULL, "lpu_init - LPU_TXLINK_SEQUENCE_COUNTER: 0x%llx\n",
108227Sjchu CSR_XR(csr_base, LPU_TXLINK_SEQUENCE_COUNTER));
10830Sstevel@tonic-gate
10840Sstevel@tonic-gate /*
10850Sstevel@tonic-gate * CSR_V LPU_TXLINK_ACK_SENT_SEQUENCE_NUMBER Expect HW 0xFFF
10860Sstevel@tonic-gate */
10870Sstevel@tonic-gate DBG(DBG_LPU, NULL,
108827Sjchu "lpu_init - LPU_TXLINK_ACK_SENT_SEQUENCE_NUMBER: 0x%llx\n",
108927Sjchu CSR_XR(csr_base, LPU_TXLINK_ACK_SENT_SEQUENCE_NUMBER));
10900Sstevel@tonic-gate
10910Sstevel@tonic-gate /*
10920Sstevel@tonic-gate * CSR_V LPU_TXLINK_SEQUENCE_COUNT_FIFO_MAX_ADDR Expect OBP 0x157
10930Sstevel@tonic-gate */
10940Sstevel@tonic-gate
10950Sstevel@tonic-gate /*
10960Sstevel@tonic-gate * Test only register. Will not be programmed.
10970Sstevel@tonic-gate */
10980Sstevel@tonic-gate DBG(DBG_LPU, NULL,
109927Sjchu "lpu_init - LPU_TXLINK_SEQUENCE_COUNT_FIFO_MAX_ADDR: 0x%llx\n",
110027Sjchu CSR_XR(csr_base, LPU_TXLINK_SEQUENCE_COUNT_FIFO_MAX_ADDR));
11010Sstevel@tonic-gate
11020Sstevel@tonic-gate /*
11030Sstevel@tonic-gate * CSR_V LPU_TXLINK_SEQUENCE_COUNT_FIFO_POINTERS Expect HW 0xFFF0000
11040Sstevel@tonic-gate */
11050Sstevel@tonic-gate
11060Sstevel@tonic-gate /*
11070Sstevel@tonic-gate * Test only register. Will not be programmed.
11080Sstevel@tonic-gate */
11090Sstevel@tonic-gate DBG(DBG_LPU, NULL,
111027Sjchu "lpu_init - LPU_TXLINK_SEQUENCE_COUNT_FIFO_POINTERS: 0x%llx\n",
111127Sjchu CSR_XR(csr_base, LPU_TXLINK_SEQUENCE_COUNT_FIFO_POINTERS));
11120Sstevel@tonic-gate
11130Sstevel@tonic-gate /*
11140Sstevel@tonic-gate * CSR_V LPU_TXLINK_SEQUENCE_COUNT_R_W_POINTERS Expect HW 0x0
11150Sstevel@tonic-gate */
11160Sstevel@tonic-gate DBG(DBG_LPU, NULL,
111727Sjchu "lpu_init - LPU_TXLINK_SEQUENCE_COUNT_R_W_POINTERS: 0x%llx\n",
111827Sjchu CSR_XR(csr_base, LPU_TXLINK_SEQUENCE_COUNT_R_W_POINTERS));
11190Sstevel@tonic-gate
11200Sstevel@tonic-gate /*
11210Sstevel@tonic-gate * CSR_V LPU_TXLINK_TEST_CONTROL Expect HW 0x0
11220Sstevel@tonic-gate */
11230Sstevel@tonic-gate DBG(DBG_LPU, NULL, "lpu_init - LPU_TXLINK_TEST_CONTROL: 0x%llx\n",
112427Sjchu CSR_XR(csr_base, LPU_TXLINK_TEST_CONTROL));
11250Sstevel@tonic-gate
11260Sstevel@tonic-gate /*
11270Sstevel@tonic-gate * CSR_V LPU_TXLINK_MEMORY_ADDRESS_CONTROL Expect HW 0x0
11280Sstevel@tonic-gate */
11290Sstevel@tonic-gate
11300Sstevel@tonic-gate /*
11310Sstevel@tonic-gate * Test only register. Will not be programmed.
11320Sstevel@tonic-gate */
11330Sstevel@tonic-gate DBG(DBG_LPU, NULL,
11340Sstevel@tonic-gate "lpu_init - LPU_TXLINK_MEMORY_ADDRESS_CONTROL: 0x%llx\n",
11350Sstevel@tonic-gate CSR_XR(csr_base, LPU_TXLINK_MEMORY_ADDRESS_CONTROL));
11360Sstevel@tonic-gate
11370Sstevel@tonic-gate /*
11380Sstevel@tonic-gate * CSR_V LPU_TXLINK_MEMORY_DATA_LOAD0 Expect HW 0x0
11390Sstevel@tonic-gate */
11400Sstevel@tonic-gate DBG(DBG_LPU, NULL,
114127Sjchu "lpu_init - LPU_TXLINK_MEMORY_DATA_LOAD0: 0x%llx\n",
114227Sjchu CSR_XR(csr_base, LPU_TXLINK_MEMORY_DATA_LOAD0));
11430Sstevel@tonic-gate
11440Sstevel@tonic-gate /*
11450Sstevel@tonic-gate * CSR_V LPU_TXLINK_MEMORY_DATA_LOAD1 Expect HW 0x0
11460Sstevel@tonic-gate */
11470Sstevel@tonic-gate DBG(DBG_LPU, NULL,
114827Sjchu "lpu_init - LPU_TXLINK_MEMORY_DATA_LOAD1: 0x%llx\n",
114927Sjchu CSR_XR(csr_base, LPU_TXLINK_MEMORY_DATA_LOAD1));
11500Sstevel@tonic-gate
11510Sstevel@tonic-gate /*
11520Sstevel@tonic-gate * CSR_V LPU_TXLINK_MEMORY_DATA_LOAD2 Expect HW 0x0
11530Sstevel@tonic-gate */
11540Sstevel@tonic-gate DBG(DBG_LPU, NULL,
115527Sjchu "lpu_init - LPU_TXLINK_MEMORY_DATA_LOAD2: 0x%llx\n",
115627Sjchu CSR_XR(csr_base, LPU_TXLINK_MEMORY_DATA_LOAD2));
11570Sstevel@tonic-gate
11580Sstevel@tonic-gate /*
11590Sstevel@tonic-gate * CSR_V LPU_TXLINK_MEMORY_DATA_LOAD3 Expect HW 0x0
11600Sstevel@tonic-gate */
11610Sstevel@tonic-gate DBG(DBG_LPU, NULL,
116227Sjchu "lpu_init - LPU_TXLINK_MEMORY_DATA_LOAD3: 0x%llx\n",
116327Sjchu CSR_XR(csr_base, LPU_TXLINK_MEMORY_DATA_LOAD3));
11640Sstevel@tonic-gate
11650Sstevel@tonic-gate /*
11660Sstevel@tonic-gate * CSR_V LPU_TXLINK_MEMORY_DATA_LOAD4 Expect HW 0x0
11670Sstevel@tonic-gate */
11680Sstevel@tonic-gate DBG(DBG_LPU, NULL,
116927Sjchu "lpu_init - LPU_TXLINK_MEMORY_DATA_LOAD4: 0x%llx\n",
117027Sjchu CSR_XR(csr_base, LPU_TXLINK_MEMORY_DATA_LOAD4));
11710Sstevel@tonic-gate
11720Sstevel@tonic-gate /*
11730Sstevel@tonic-gate * CSR_V LPU_TXLINK_RETRY_DATA_COUNT Expect HW 0x0
11740Sstevel@tonic-gate */
11750Sstevel@tonic-gate
11760Sstevel@tonic-gate /*
11770Sstevel@tonic-gate * Test only register. Will not be programmed.
11780Sstevel@tonic-gate */
11790Sstevel@tonic-gate DBG(DBG_LPU, NULL, "lpu_init - LPU_TXLINK_RETRY_DATA_COUNT: 0x%llx\n",
118027Sjchu CSR_XR(csr_base, LPU_TXLINK_RETRY_DATA_COUNT));
11810Sstevel@tonic-gate
11820Sstevel@tonic-gate /*
11830Sstevel@tonic-gate * CSR_V LPU_TXLINK_SEQUENCE_BUFFER_COUNT Expect HW 0x0
11840Sstevel@tonic-gate */
11850Sstevel@tonic-gate
11860Sstevel@tonic-gate /*
11870Sstevel@tonic-gate * Test only register. Will not be programmed.
11880Sstevel@tonic-gate */
11890Sstevel@tonic-gate DBG(DBG_LPU, NULL,
119027Sjchu "lpu_init - LPU_TXLINK_SEQUENCE_BUFFER_COUNT: 0x%llx\n",
119127Sjchu CSR_XR(csr_base, LPU_TXLINK_SEQUENCE_BUFFER_COUNT));
11920Sstevel@tonic-gate
11930Sstevel@tonic-gate /*
11940Sstevel@tonic-gate * CSR_V LPU_TXLINK_SEQUENCE_BUFFER_BOTTOM_DATA Expect HW 0x0
11950Sstevel@tonic-gate */
11960Sstevel@tonic-gate
11970Sstevel@tonic-gate /*
11980Sstevel@tonic-gate * Test only register.
11990Sstevel@tonic-gate */
12000Sstevel@tonic-gate DBG(DBG_LPU, NULL,
120127Sjchu "lpu_init - LPU_TXLINK_SEQUENCE_BUFFER_BOTTOM_DATA: 0x%llx\n",
120227Sjchu CSR_XR(csr_base, LPU_TXLINK_SEQUENCE_BUFFER_BOTTOM_DATA));
12030Sstevel@tonic-gate
12040Sstevel@tonic-gate /*
12050Sstevel@tonic-gate * CSR_V LPU_RXLINK_NEXT_RECEIVE_SEQUENCE_1_COUNTER Expect HW 0x0
12060Sstevel@tonic-gate */
12070Sstevel@tonic-gate DBG(DBG_LPU, NULL, "lpu_init - "
120827Sjchu "LPU_RXLINK_NEXT_RECEIVE_SEQUENCE_1_COUNTER: 0x%llx\n",
120927Sjchu CSR_XR(csr_base, LPU_RXLINK_NEXT_RECEIVE_SEQUENCE_1_COUNTER));
12100Sstevel@tonic-gate
12110Sstevel@tonic-gate /*
12120Sstevel@tonic-gate * CSR_V LPU_RXLINK_UNSUPPORTED_DLLP_RECEIVED Expect HW 0x0
12130Sstevel@tonic-gate */
12140Sstevel@tonic-gate
12150Sstevel@tonic-gate /*
12160Sstevel@tonic-gate * test only register.
12170Sstevel@tonic-gate */
12180Sstevel@tonic-gate DBG(DBG_LPU, NULL,
121927Sjchu "lpu_init - LPU_RXLINK_UNSUPPORTED_DLLP_RECEIVED: 0x%llx\n",
122027Sjchu CSR_XR(csr_base, LPU_RXLINK_UNSUPPORTED_DLLP_RECEIVED));
12210Sstevel@tonic-gate
12220Sstevel@tonic-gate /*
12230Sstevel@tonic-gate * CSR_V LPU_RXLINK_TEST_CONTROL Expect HW 0x0
12240Sstevel@tonic-gate */
12250Sstevel@tonic-gate
12260Sstevel@tonic-gate /*
12270Sstevel@tonic-gate * test only register.
12280Sstevel@tonic-gate */
12290Sstevel@tonic-gate DBG(DBG_LPU, NULL, "lpu_init - LPU_RXLINK_TEST_CONTROL: 0x%llx\n",
123027Sjchu CSR_XR(csr_base, LPU_RXLINK_TEST_CONTROL));
12310Sstevel@tonic-gate
12320Sstevel@tonic-gate /*
12330Sstevel@tonic-gate * CSR_V LPU_PHYSICAL_LAYER_CONFIGURATION Expect HW 0x10
12340Sstevel@tonic-gate */
12350Sstevel@tonic-gate DBG(DBG_LPU, NULL,
123627Sjchu "lpu_init - LPU_PHYSICAL_LAYER_CONFIGURATION: 0x%llx\n",
123727Sjchu CSR_XR(csr_base, LPU_PHYSICAL_LAYER_CONFIGURATION));
12380Sstevel@tonic-gate
12390Sstevel@tonic-gate /*
12400Sstevel@tonic-gate * CSR_V LPU_PHY_LAYER_STATUS Expect HW 0x0
12410Sstevel@tonic-gate */
12420Sstevel@tonic-gate DBG(DBG_LPU, NULL, "lpu_init - LPU_PHY_LAYER_STATUS: 0x%llx\n",
124327Sjchu CSR_XR(csr_base, LPU_PHY_LAYER_STATUS));
12440Sstevel@tonic-gate
12450Sstevel@tonic-gate /*
12460Sstevel@tonic-gate * CSR_V LPU_PHY_INTERRUPT_AND_STATUS_TEST Expect HW 0x0
12470Sstevel@tonic-gate */
12480Sstevel@tonic-gate DBG(DBG_LPU, NULL,
12490Sstevel@tonic-gate "lpu_init - LPU_PHY_INTERRUPT_AND_STATUS_TEST: 0x%llx\n",
12500Sstevel@tonic-gate CSR_XR(csr_base, LPU_PHY_INTERRUPT_AND_STATUS_TEST));
12510Sstevel@tonic-gate
12520Sstevel@tonic-gate /*
125327Sjchu * CSR_V LPU PHY LAYER interrupt regs (mask, status)
12540Sstevel@tonic-gate */
12550Sstevel@tonic-gate DBG(DBG_LPU, NULL, "lpu_init - LPU_PHY_INTERRUPT_MASK: 0x%llx\n",
125627Sjchu CSR_XR(csr_base, LPU_PHY_INTERRUPT_MASK));
125727Sjchu
125827Sjchu DBG(DBG_LPU, NULL,
125927Sjchu "lpu_init - LPU_PHY_LAYER_INTERRUPT_AND_STATUS: 0x%llx\n",
126027Sjchu CSR_XR(csr_base, LPU_PHY_LAYER_INTERRUPT_AND_STATUS));
12610Sstevel@tonic-gate
12620Sstevel@tonic-gate /*
12630Sstevel@tonic-gate * CSR_V LPU_RECEIVE_PHY_CONFIG Expect HW 0x0
12640Sstevel@tonic-gate */
12650Sstevel@tonic-gate
12660Sstevel@tonic-gate /*
12670Sstevel@tonic-gate * This also needs some explanation. What is the best value
12680Sstevel@tonic-gate * for the water mark? Test mode enables which test mode?
12690Sstevel@tonic-gate * Programming model needed for the Receiver Reset Lane N
12700Sstevel@tonic-gate * bits.
12710Sstevel@tonic-gate */
12720Sstevel@tonic-gate DBG(DBG_LPU, NULL, "lpu_init - LPU_RECEIVE_PHY_CONFIG: 0x%llx\n",
127327Sjchu CSR_XR(csr_base, LPU_RECEIVE_PHY_CONFIG));
12740Sstevel@tonic-gate
12750Sstevel@tonic-gate /*
12760Sstevel@tonic-gate * CSR_V LPU_RECEIVE_PHY_STATUS1 Expect HW 0x0
12770Sstevel@tonic-gate */
12780Sstevel@tonic-gate DBG(DBG_LPU, NULL, "lpu_init - LPU_RECEIVE_PHY_STATUS1: 0x%llx\n",
127927Sjchu CSR_XR(csr_base, LPU_RECEIVE_PHY_STATUS1));
12800Sstevel@tonic-gate
12810Sstevel@tonic-gate /*
12820Sstevel@tonic-gate * CSR_V LPU_RECEIVE_PHY_STATUS2 Expect HW 0x0
12830Sstevel@tonic-gate */
12840Sstevel@tonic-gate DBG(DBG_LPU, NULL, "lpu_init - LPU_RECEIVE_PHY_STATUS2: 0x%llx\n",
128527Sjchu CSR_XR(csr_base, LPU_RECEIVE_PHY_STATUS2));
12860Sstevel@tonic-gate
12870Sstevel@tonic-gate /*
12880Sstevel@tonic-gate * CSR_V LPU_RECEIVE_PHY_STATUS3 Expect HW 0x0
12890Sstevel@tonic-gate */
12900Sstevel@tonic-gate DBG(DBG_LPU, NULL, "lpu_init - LPU_RECEIVE_PHY_STATUS3: 0x%llx\n",
129127Sjchu CSR_XR(csr_base, LPU_RECEIVE_PHY_STATUS3));
12920Sstevel@tonic-gate
12930Sstevel@tonic-gate /*
12940Sstevel@tonic-gate * CSR_V LPU_RECEIVE_PHY_INTERRUPT_AND_STATUS_TEST Expect HW 0x0
12950Sstevel@tonic-gate */
12960Sstevel@tonic-gate DBG(DBG_LPU, NULL,
12970Sstevel@tonic-gate "lpu_init - LPU_RECEIVE_PHY_INTERRUPT_AND_STATUS_TEST: 0x%llx\n",
12980Sstevel@tonic-gate CSR_XR(csr_base, LPU_RECEIVE_PHY_INTERRUPT_AND_STATUS_TEST));
12990Sstevel@tonic-gate
13000Sstevel@tonic-gate /*
130127Sjchu * CSR_V LPU RX LAYER interrupt regs (mask, status)
13020Sstevel@tonic-gate */
13030Sstevel@tonic-gate DBG(DBG_LPU, NULL,
130427Sjchu "lpu_init - LPU_RECEIVE_PHY_INTERRUPT_MASK: 0x%llx\n",
130527Sjchu CSR_XR(csr_base, LPU_RECEIVE_PHY_INTERRUPT_MASK));
130627Sjchu
130727Sjchu DBG(DBG_LPU, NULL,
130827Sjchu "lpu_init - LPU_RECEIVE_PHY_INTERRUPT_AND_STATUS: 0x%llx\n",
130927Sjchu CSR_XR(csr_base, LPU_RECEIVE_PHY_INTERRUPT_AND_STATUS));
13100Sstevel@tonic-gate
13110Sstevel@tonic-gate /*
13120Sstevel@tonic-gate * CSR_V LPU_TRANSMIT_PHY_CONFIG Expect HW 0x0
13130Sstevel@tonic-gate */
13140Sstevel@tonic-gate DBG(DBG_LPU, NULL, "lpu_init - LPU_TRANSMIT_PHY_CONFIG: 0x%llx\n",
131527Sjchu CSR_XR(csr_base, LPU_TRANSMIT_PHY_CONFIG));
13160Sstevel@tonic-gate
13170Sstevel@tonic-gate /*
13180Sstevel@tonic-gate * CSR_V LPU_TRANSMIT_PHY_STATUS Expect HW 0x0
13190Sstevel@tonic-gate */
13200Sstevel@tonic-gate DBG(DBG_LPU, NULL, "lpu_init - LPU_TRANSMIT_PHY_STATUS: 0x%llx\n",
13216953Sanbui CSR_XR(csr_base, LPU_TRANSMIT_PHY_STATUS));
13220Sstevel@tonic-gate
13230Sstevel@tonic-gate /*
13240Sstevel@tonic-gate * CSR_V LPU_TRANSMIT_PHY_INTERRUPT_AND_STATUS_TEST Expect HW 0x0
13250Sstevel@tonic-gate */
13260Sstevel@tonic-gate DBG(DBG_LPU, NULL,
13270Sstevel@tonic-gate "lpu_init - LPU_TRANSMIT_PHY_INTERRUPT_AND_STATUS_TEST: 0x%llx\n",
13280Sstevel@tonic-gate CSR_XR(csr_base,
13290Sstevel@tonic-gate LPU_TRANSMIT_PHY_INTERRUPT_AND_STATUS_TEST));
13300Sstevel@tonic-gate
13310Sstevel@tonic-gate /*
133227Sjchu * CSR_V LPU TX LAYER interrupt regs (mask, status)
13330Sstevel@tonic-gate */
13340Sstevel@tonic-gate DBG(DBG_LPU, NULL,
133527Sjchu "lpu_init - LPU_TRANSMIT_PHY_INTERRUPT_MASK: 0x%llx\n",
133627Sjchu CSR_XR(csr_base, LPU_TRANSMIT_PHY_INTERRUPT_MASK));
133727Sjchu
133827Sjchu DBG(DBG_LPU, NULL,
133927Sjchu "lpu_init - LPU_TRANSMIT_PHY_INTERRUPT_AND_STATUS: 0x%llx\n",
134027Sjchu CSR_XR(csr_base, LPU_TRANSMIT_PHY_INTERRUPT_AND_STATUS));
13410Sstevel@tonic-gate
13420Sstevel@tonic-gate /*
13430Sstevel@tonic-gate * CSR_V LPU_TRANSMIT_PHY_STATUS_2 Expect HW 0x0
13440Sstevel@tonic-gate */
13450Sstevel@tonic-gate DBG(DBG_LPU, NULL, "lpu_init - LPU_TRANSMIT_PHY_STATUS_2: 0x%llx\n",
134627Sjchu CSR_XR(csr_base, LPU_TRANSMIT_PHY_STATUS_2));
13470Sstevel@tonic-gate
13480Sstevel@tonic-gate /*
13490Sstevel@tonic-gate * CSR_V LPU_LTSSM_CONFIG1 Expect OBP 0x205
13500Sstevel@tonic-gate */
13510Sstevel@tonic-gate
13520Sstevel@tonic-gate /*
13530Sstevel@tonic-gate * The new PRM has values for LTSSM 8 ns timeout value and
13540Sstevel@tonic-gate * LTSSM 20 ns timeout value. But what do these values mean?
13550Sstevel@tonic-gate * Most of the other bits are questions as well.
13560Sstevel@tonic-gate *
13570Sstevel@tonic-gate * As such we will use the reset value.
13580Sstevel@tonic-gate */
13590Sstevel@tonic-gate DBG(DBG_LPU, NULL, "lpu_init - LPU_LTSSM_CONFIG1: 0x%llx\n",
136027Sjchu CSR_XR(csr_base, LPU_LTSSM_CONFIG1));
13610Sstevel@tonic-gate
13620Sstevel@tonic-gate /*
13630Sstevel@tonic-gate * CSR_V LPU_LTSSM_CONFIG2 Expect OBP 0x2DC6C0
13640Sstevel@tonic-gate */
13650Sstevel@tonic-gate
13660Sstevel@tonic-gate /*
13670Sstevel@tonic-gate * Again, what does '12 ms timeout value mean'?
13680Sstevel@tonic-gate */
13690Sstevel@tonic-gate val = (LPU_LTSSM_CONFIG2_LTSSM_12_TO_DEFAULT <<
137027Sjchu LPU_LTSSM_CONFIG2_LTSSM_12_TO);
13710Sstevel@tonic-gate CSR_XS(csr_base, LPU_LTSSM_CONFIG2, val);
13720Sstevel@tonic-gate DBG(DBG_LPU, NULL, "lpu_init - LPU_LTSSM_CONFIG2: 0x%llx\n",
137327Sjchu CSR_XR(csr_base, LPU_LTSSM_CONFIG2));
13740Sstevel@tonic-gate
13750Sstevel@tonic-gate /*
13760Sstevel@tonic-gate * CSR_V LPU_LTSSM_CONFIG3 Expect OBP 0x7A120
13770Sstevel@tonic-gate */
13780Sstevel@tonic-gate val = (LPU_LTSSM_CONFIG3_LTSSM_2_TO_DEFAULT <<
137927Sjchu LPU_LTSSM_CONFIG3_LTSSM_2_TO);
13800Sstevel@tonic-gate CSR_XS(csr_base, LPU_LTSSM_CONFIG3, val);
13810Sstevel@tonic-gate DBG(DBG_LPU, NULL, "lpu_init - LPU_LTSSM_CONFIG3: 0x%llx\n",
138227Sjchu CSR_XR(csr_base, LPU_LTSSM_CONFIG3));
13830Sstevel@tonic-gate
13840Sstevel@tonic-gate /*
13850Sstevel@tonic-gate * CSR_V LPU_LTSSM_CONFIG4 Expect OBP 0x21300
13860Sstevel@tonic-gate */
13870Sstevel@tonic-gate val = ((LPU_LTSSM_CONFIG4_DATA_RATE_DEFAULT <<
138827Sjchu LPU_LTSSM_CONFIG4_DATA_RATE) |
13896953Sanbui (LPU_LTSSM_CONFIG4_N_FTS_DEFAULT <<
13906953Sanbui LPU_LTSSM_CONFIG4_N_FTS));
139110923SEvan.Yan@Sun.COM
13920Sstevel@tonic-gate CSR_XS(csr_base, LPU_LTSSM_CONFIG4, val);
13930Sstevel@tonic-gate DBG(DBG_LPU, NULL, "lpu_init - LPU_LTSSM_CONFIG4: 0x%llx\n",
139427Sjchu CSR_XR(csr_base, LPU_LTSSM_CONFIG4));
13950Sstevel@tonic-gate
13960Sstevel@tonic-gate /*
13970Sstevel@tonic-gate * CSR_V LPU_LTSSM_CONFIG5 Expect OBP 0x0
13980Sstevel@tonic-gate */
13990Sstevel@tonic-gate val = 0ull;
14000Sstevel@tonic-gate CSR_XS(csr_base, LPU_LTSSM_CONFIG5, val);
14010Sstevel@tonic-gate DBG(DBG_LPU, NULL, "lpu_init - LPU_LTSSM_CONFIG5: 0x%llx\n",
140227Sjchu CSR_XR(csr_base, LPU_LTSSM_CONFIG5));
14030Sstevel@tonic-gate
14040Sstevel@tonic-gate /*
14050Sstevel@tonic-gate * CSR_V LPU_LTSSM_STATUS1 Expect OBP 0x0
14060Sstevel@tonic-gate */
14070Sstevel@tonic-gate
14080Sstevel@tonic-gate /*
14090Sstevel@tonic-gate * LTSSM Status registers are test only.
14100Sstevel@tonic-gate */
14110Sstevel@tonic-gate DBG(DBG_LPU, NULL, "lpu_init - LPU_LTSSM_STATUS1: 0x%llx\n",
141227Sjchu CSR_XR(csr_base, LPU_LTSSM_STATUS1));
14130Sstevel@tonic-gate
14140Sstevel@tonic-gate /*
14150Sstevel@tonic-gate * CSR_V LPU_LTSSM_STATUS2 Expect OBP 0x0
14160Sstevel@tonic-gate */
14170Sstevel@tonic-gate DBG(DBG_LPU, NULL, "lpu_init - LPU_LTSSM_STATUS2: 0x%llx\n",
141827Sjchu CSR_XR(csr_base, LPU_LTSSM_STATUS2));
14190Sstevel@tonic-gate
14200Sstevel@tonic-gate /*
14210Sstevel@tonic-gate * CSR_V LPU_LTSSM_INTERRUPT_AND_STATUS_TEST Expect HW 0x0
14220Sstevel@tonic-gate */
14230Sstevel@tonic-gate DBG(DBG_LPU, NULL,
142427Sjchu "lpu_init - LPU_LTSSM_INTERRUPT_AND_STATUS_TEST: 0x%llx\n",
142527Sjchu CSR_XR(csr_base, LPU_LTSSM_INTERRUPT_AND_STATUS_TEST));
14260Sstevel@tonic-gate
14270Sstevel@tonic-gate /*
142827Sjchu * CSR_V LPU LTSSM LAYER interrupt regs (mask, status)
14290Sstevel@tonic-gate */
14300Sstevel@tonic-gate DBG(DBG_LPU, NULL, "lpu_init - LPU_LTSSM_INTERRUPT_MASK: 0x%llx\n",
143127Sjchu CSR_XR(csr_base, LPU_LTSSM_INTERRUPT_MASK));
143227Sjchu
143327Sjchu DBG(DBG_LPU, NULL,
143427Sjchu "lpu_init - LPU_LTSSM_INTERRUPT_AND_STATUS: 0x%llx\n",
143527Sjchu CSR_XR(csr_base, LPU_LTSSM_INTERRUPT_AND_STATUS));
14360Sstevel@tonic-gate
14370Sstevel@tonic-gate /*
14380Sstevel@tonic-gate * CSR_V LPU_LTSSM_STATUS_WRITE_ENABLE Expect OBP 0x0
14390Sstevel@tonic-gate */
14400Sstevel@tonic-gate DBG(DBG_LPU, NULL,
144127Sjchu "lpu_init - LPU_LTSSM_STATUS_WRITE_ENABLE: 0x%llx\n",
144227Sjchu CSR_XR(csr_base, LPU_LTSSM_STATUS_WRITE_ENABLE));
14430Sstevel@tonic-gate
14440Sstevel@tonic-gate /*
14450Sstevel@tonic-gate * CSR_V LPU_GIGABLAZE_GLUE_CONFIG1 Expect OBP 0x88407
14460Sstevel@tonic-gate */
14470Sstevel@tonic-gate DBG(DBG_LPU, NULL, "lpu_init - LPU_GIGABLAZE_GLUE_CONFIG1: 0x%llx\n",
144827Sjchu CSR_XR(csr_base, LPU_GIGABLAZE_GLUE_CONFIG1));
14490Sstevel@tonic-gate
14500Sstevel@tonic-gate /*
14510Sstevel@tonic-gate * CSR_V LPU_GIGABLAZE_GLUE_CONFIG2 Expect OBP 0x35
14520Sstevel@tonic-gate */
14530Sstevel@tonic-gate DBG(DBG_LPU, NULL, "lpu_init - LPU_GIGABLAZE_GLUE_CONFIG2: 0x%llx\n",
145427Sjchu CSR_XR(csr_base, LPU_GIGABLAZE_GLUE_CONFIG2));
14550Sstevel@tonic-gate
14560Sstevel@tonic-gate /*
14570Sstevel@tonic-gate * CSR_V LPU_GIGABLAZE_GLUE_CONFIG3 Expect OBP 0x4400FA
14580Sstevel@tonic-gate */
14590Sstevel@tonic-gate DBG(DBG_LPU, NULL, "lpu_init - LPU_GIGABLAZE_GLUE_CONFIG3: 0x%llx\n",
146027Sjchu CSR_XR(csr_base, LPU_GIGABLAZE_GLUE_CONFIG3));
14610Sstevel@tonic-gate
14620Sstevel@tonic-gate /*
14630Sstevel@tonic-gate * CSR_V LPU_GIGABLAZE_GLUE_CONFIG4 Expect OBP 0x1E848
14640Sstevel@tonic-gate */
14650Sstevel@tonic-gate DBG(DBG_LPU, NULL, "lpu_init - LPU_GIGABLAZE_GLUE_CONFIG4: 0x%llx\n",
146627Sjchu CSR_XR(csr_base, LPU_GIGABLAZE_GLUE_CONFIG4));
14670Sstevel@tonic-gate
14680Sstevel@tonic-gate /*
14690Sstevel@tonic-gate * CSR_V LPU_GIGABLAZE_GLUE_STATUS Expect OBP 0x0
14700Sstevel@tonic-gate */
14710Sstevel@tonic-gate DBG(DBG_LPU, NULL, "lpu_init - LPU_GIGABLAZE_GLUE_STATUS: 0x%llx\n",
147227Sjchu CSR_XR(csr_base, LPU_GIGABLAZE_GLUE_STATUS));
14730Sstevel@tonic-gate
14740Sstevel@tonic-gate /*
14750Sstevel@tonic-gate * CSR_V LPU_GIGABLAZE_GLUE_INTERRUPT_AND_STATUS_TEST Expect OBP 0x0
14760Sstevel@tonic-gate */
147727Sjchu DBG(DBG_LPU, NULL, "lpu_init - "
147827Sjchu "LPU_GIGABLAZE_GLUE_INTERRUPT_AND_STATUS_TEST: 0x%llx\n",
147927Sjchu CSR_XR(csr_base,
148027Sjchu LPU_GIGABLAZE_GLUE_INTERRUPT_AND_STATUS_TEST));
14810Sstevel@tonic-gate
14820Sstevel@tonic-gate /*
148327Sjchu * CSR_V LPU GIGABLASE LAYER interrupt regs (mask, status)
14840Sstevel@tonic-gate */
14850Sstevel@tonic-gate DBG(DBG_LPU, NULL,
14860Sstevel@tonic-gate "lpu_init - LPU_GIGABLAZE_GLUE_INTERRUPT_MASK: 0x%llx\n",
14870Sstevel@tonic-gate CSR_XR(csr_base, LPU_GIGABLAZE_GLUE_INTERRUPT_MASK));
14880Sstevel@tonic-gate
148927Sjchu DBG(DBG_LPU, NULL,
149027Sjchu "lpu_init - LPU_GIGABLAZE_GLUE_INTERRUPT_AND_STATUS: 0x%llx\n",
149127Sjchu CSR_XR(csr_base, LPU_GIGABLAZE_GLUE_INTERRUPT_AND_STATUS));
149227Sjchu
14930Sstevel@tonic-gate /*
14940Sstevel@tonic-gate * CSR_V LPU_GIGABLAZE_GLUE_POWER_DOWN1 Expect HW 0x0
14950Sstevel@tonic-gate */
14960Sstevel@tonic-gate DBG(DBG_LPU, NULL,
149727Sjchu "lpu_init - LPU_GIGABLAZE_GLUE_POWER_DOWN1: 0x%llx\n",
149827Sjchu CSR_XR(csr_base, LPU_GIGABLAZE_GLUE_POWER_DOWN1));
14990Sstevel@tonic-gate
15000Sstevel@tonic-gate /*
15010Sstevel@tonic-gate * CSR_V LPU_GIGABLAZE_GLUE_POWER_DOWN2 Expect HW 0x0
15020Sstevel@tonic-gate */
15030Sstevel@tonic-gate DBG(DBG_LPU, NULL,
150427Sjchu "lpu_init - LPU_GIGABLAZE_GLUE_POWER_DOWN2: 0x%llx\n",
150527Sjchu CSR_XR(csr_base, LPU_GIGABLAZE_GLUE_POWER_DOWN2));
15060Sstevel@tonic-gate
15070Sstevel@tonic-gate /*
15080Sstevel@tonic-gate * CSR_V LPU_GIGABLAZE_GLUE_CONFIG5 Expect OBP 0x0
15090Sstevel@tonic-gate */
15100Sstevel@tonic-gate DBG(DBG_LPU, NULL, "lpu_init - LPU_GIGABLAZE_GLUE_CONFIG5: 0x%llx\n",
151127Sjchu CSR_XR(csr_base, LPU_GIGABLAZE_GLUE_CONFIG5));
15120Sstevel@tonic-gate }
15130Sstevel@tonic-gate
15140Sstevel@tonic-gate /* ARGSUSED */
15150Sstevel@tonic-gate static void
dlu_init(caddr_t csr_base,pxu_t * pxu_p)15161772Sjl139090 dlu_init(caddr_t csr_base, pxu_t *pxu_p)
15171772Sjl139090 {
15181772Sjl139090 uint64_t val;
15191772Sjl139090
15201772Sjl139090 CSR_XS(csr_base, DLU_INTERRUPT_MASK, 0ull);
15211772Sjl139090 DBG(DBG_TLU, NULL, "dlu_init - DLU_INTERRUPT_MASK: 0x%llx\n",
15221772Sjl139090 CSR_XR(csr_base, DLU_INTERRUPT_MASK));
15231772Sjl139090
15241772Sjl139090 val = (1ull << DLU_LINK_LAYER_CONFIG_VC0_EN);
15251772Sjl139090 CSR_XS(csr_base, DLU_LINK_LAYER_CONFIG, val);
15261772Sjl139090 DBG(DBG_TLU, NULL, "dlu_init - DLU_LINK_LAYER_CONFIG: 0x%llx\n",
15271772Sjl139090 CSR_XR(csr_base, DLU_LINK_LAYER_CONFIG));
15281772Sjl139090
15291772Sjl139090 val = (1ull << DLU_FLOW_CONTROL_UPDATE_CONTROL_FC0_U_NP_EN) |
15301772Sjl139090 (1ull << DLU_FLOW_CONTROL_UPDATE_CONTROL_FC0_U_P_EN);
15311772Sjl139090
15321772Sjl139090 CSR_XS(csr_base, DLU_FLOW_CONTROL_UPDATE_CONTROL, val);
15331772Sjl139090 DBG(DBG_TLU, NULL, "dlu_init - DLU_FLOW_CONTROL_UPDATE_CONTROL: "
15341772Sjl139090 "0x%llx\n", CSR_XR(csr_base, DLU_FLOW_CONTROL_UPDATE_CONTROL));
15351772Sjl139090
15361772Sjl139090 val = (DLU_TXLINK_REPLAY_TIMER_THRESHOLD_DEFAULT <<
15371772Sjl139090 DLU_TXLINK_REPLAY_TIMER_THRESHOLD_RPLAY_TMR_THR);
15381772Sjl139090
15391772Sjl139090 CSR_XS(csr_base, DLU_TXLINK_REPLAY_TIMER_THRESHOLD, val);
15401772Sjl139090
15411772Sjl139090 DBG(DBG_TLU, NULL, "dlu_init - DLU_TXLINK_REPLAY_TIMER_THRESHOLD: "
15421772Sjl139090 "0x%llx\n", CSR_XR(csr_base, DLU_TXLINK_REPLAY_TIMER_THRESHOLD));
15431772Sjl139090 }
15441772Sjl139090
15451772Sjl139090 /* ARGSUSED */
15461772Sjl139090 static void
dmc_init(caddr_t csr_base,pxu_t * pxu_p)15470Sstevel@tonic-gate dmc_init(caddr_t csr_base, pxu_t *pxu_p)
15480Sstevel@tonic-gate {
15490Sstevel@tonic-gate uint64_t val;
15500Sstevel@tonic-gate
15510Sstevel@tonic-gate /*
15520Sstevel@tonic-gate * CSR_V DMC_CORE_AND_BLOCK_INTERRUPT_ENABLE Expect OBP 0x8000000000000003
15530Sstevel@tonic-gate */
15540Sstevel@tonic-gate
15550Sstevel@tonic-gate val = -1ull;
15560Sstevel@tonic-gate CSR_XS(csr_base, DMC_CORE_AND_BLOCK_INTERRUPT_ENABLE, val);
15570Sstevel@tonic-gate DBG(DBG_DMC, NULL,
155827Sjchu "dmc_init - DMC_CORE_AND_BLOCK_INTERRUPT_ENABLE: 0x%llx\n",
155927Sjchu CSR_XR(csr_base, DMC_CORE_AND_BLOCK_INTERRUPT_ENABLE));
15600Sstevel@tonic-gate
15610Sstevel@tonic-gate /*
15620Sstevel@tonic-gate * CSR_V DMC_CORE_AND_BLOCK_ERROR_STATUS Expect HW 0x0
15630Sstevel@tonic-gate */
15640Sstevel@tonic-gate DBG(DBG_DMC, NULL,
156527Sjchu "dmc_init - DMC_CORE_AND_BLOCK_ERROR_STATUS: 0x%llx\n",
156627Sjchu CSR_XR(csr_base, DMC_CORE_AND_BLOCK_ERROR_STATUS));
15670Sstevel@tonic-gate
15680Sstevel@tonic-gate /*
15690Sstevel@tonic-gate * CSR_V DMC_DEBUG_SELECT_FOR_PORT_A Expect HW 0x0
15700Sstevel@tonic-gate */
15710Sstevel@tonic-gate val = 0x0ull;
15720Sstevel@tonic-gate CSR_XS(csr_base, DMC_DEBUG_SELECT_FOR_PORT_A, val);
15730Sstevel@tonic-gate DBG(DBG_DMC, NULL, "dmc_init - DMC_DEBUG_SELECT_FOR_PORT_A: 0x%llx\n",
157427Sjchu CSR_XR(csr_base, DMC_DEBUG_SELECT_FOR_PORT_A));
15750Sstevel@tonic-gate
15760Sstevel@tonic-gate /*
15770Sstevel@tonic-gate * CSR_V DMC_DEBUG_SELECT_FOR_PORT_B Expect HW 0x0
15780Sstevel@tonic-gate */
15790Sstevel@tonic-gate val = 0x0ull;
15800Sstevel@tonic-gate CSR_XS(csr_base, DMC_DEBUG_SELECT_FOR_PORT_B, val);
15810Sstevel@tonic-gate DBG(DBG_DMC, NULL, "dmc_init - DMC_DEBUG_SELECT_FOR_PORT_B: 0x%llx\n",
158227Sjchu CSR_XR(csr_base, DMC_DEBUG_SELECT_FOR_PORT_B));
15830Sstevel@tonic-gate }
15840Sstevel@tonic-gate
15850Sstevel@tonic-gate void
hvio_pec_init(caddr_t csr_base,pxu_t * pxu_p)15860Sstevel@tonic-gate hvio_pec_init(caddr_t csr_base, pxu_t *pxu_p)
15870Sstevel@tonic-gate {
15880Sstevel@tonic-gate uint64_t val;
15890Sstevel@tonic-gate
15900Sstevel@tonic-gate ilu_init(csr_base, pxu_p);
15910Sstevel@tonic-gate tlu_init(csr_base, pxu_p);
15921772Sjl139090
15931772Sjl139090 switch (PX_CHIP_TYPE(pxu_p)) {
15941772Sjl139090 case PX_CHIP_OBERON:
15951772Sjl139090 dlu_init(csr_base, pxu_p);
15961772Sjl139090 break;
15971772Sjl139090 case PX_CHIP_FIRE:
15981772Sjl139090 lpu_init(csr_base, pxu_p);
15991772Sjl139090 break;
16001772Sjl139090 default:
16011772Sjl139090 DBG(DBG_PEC, NULL, "hvio_pec_init - unknown chip type: 0x%x\n",
16021772Sjl139090 PX_CHIP_TYPE(pxu_p));
16031772Sjl139090 break;
16041772Sjl139090 }
16051772Sjl139090
16060Sstevel@tonic-gate dmc_init(csr_base, pxu_p);
16070Sstevel@tonic-gate
16080Sstevel@tonic-gate /*
16090Sstevel@tonic-gate * CSR_V PEC_CORE_AND_BLOCK_INTERRUPT_ENABLE Expect Kernel 0x800000000000000F
16100Sstevel@tonic-gate */
16110Sstevel@tonic-gate
16120Sstevel@tonic-gate val = -1ull;
16130Sstevel@tonic-gate CSR_XS(csr_base, PEC_CORE_AND_BLOCK_INTERRUPT_ENABLE, val);
16140Sstevel@tonic-gate DBG(DBG_PEC, NULL,
161527Sjchu "hvio_pec_init - PEC_CORE_AND_BLOCK_INTERRUPT_ENABLE: 0x%llx\n",
161627Sjchu CSR_XR(csr_base, PEC_CORE_AND_BLOCK_INTERRUPT_ENABLE));
16170Sstevel@tonic-gate
16180Sstevel@tonic-gate /*
16190Sstevel@tonic-gate * CSR_V PEC_CORE_AND_BLOCK_INTERRUPT_STATUS Expect HW 0x0
16200Sstevel@tonic-gate */
16210Sstevel@tonic-gate DBG(DBG_PEC, NULL,
162227Sjchu "hvio_pec_init - PEC_CORE_AND_BLOCK_INTERRUPT_STATUS: 0x%llx\n",
162327Sjchu CSR_XR(csr_base, PEC_CORE_AND_BLOCK_INTERRUPT_STATUS));
16240Sstevel@tonic-gate }
16250Sstevel@tonic-gate
162627Sjchu /*
16271772Sjl139090 * Convert a TTE to physical address
16281772Sjl139090 */
16291772Sjl139090 static r_addr_t
mmu_tte_to_pa(uint64_t tte,pxu_t * pxu_p)16301772Sjl139090 mmu_tte_to_pa(uint64_t tte, pxu_t *pxu_p)
16311772Sjl139090 {
16321772Sjl139090 uint64_t pa_mask;
16331772Sjl139090
16341772Sjl139090 switch (PX_CHIP_TYPE(pxu_p)) {
16351772Sjl139090 case PX_CHIP_OBERON:
16361772Sjl139090 pa_mask = MMU_OBERON_PADDR_MASK;
16371772Sjl139090 break;
16381772Sjl139090 case PX_CHIP_FIRE:
16391772Sjl139090 pa_mask = MMU_FIRE_PADDR_MASK;
16401772Sjl139090 break;
16411772Sjl139090 default:
16421772Sjl139090 DBG(DBG_MMU, NULL, "mmu_tte_to_pa - unknown chip type: 0x%x\n",
16431772Sjl139090 PX_CHIP_TYPE(pxu_p));
16441772Sjl139090 pa_mask = 0;
16451772Sjl139090 break;
16461772Sjl139090 }
16471772Sjl139090 return ((tte & pa_mask) >> MMU_PAGE_SHIFT);
16481772Sjl139090 }
16491772Sjl139090
16501772Sjl139090 /*
16511772Sjl139090 * Return MMU bypass noncache bit for chip
16521772Sjl139090 */
16531772Sjl139090 static r_addr_t
mmu_bypass_noncache(pxu_t * pxu_p)16541772Sjl139090 mmu_bypass_noncache(pxu_t *pxu_p)
16551772Sjl139090 {
16561772Sjl139090 r_addr_t bypass_noncache_bit;
16571772Sjl139090
16581772Sjl139090 switch (PX_CHIP_TYPE(pxu_p)) {
16591772Sjl139090 case PX_CHIP_OBERON:
16601772Sjl139090 bypass_noncache_bit = MMU_OBERON_BYPASS_NONCACHE;
16611772Sjl139090 break;
16621772Sjl139090 case PX_CHIP_FIRE:
16631772Sjl139090 bypass_noncache_bit = MMU_FIRE_BYPASS_NONCACHE;
16641772Sjl139090 break;
16651772Sjl139090 default:
16661772Sjl139090 DBG(DBG_MMU, NULL,
16671772Sjl139090 "mmu_bypass_nocache - unknown chip type: 0x%x\n",
16681772Sjl139090 PX_CHIP_TYPE(pxu_p));
16691772Sjl139090 bypass_noncache_bit = 0;
16701772Sjl139090 break;
16711772Sjl139090 }
16721772Sjl139090 return (bypass_noncache_bit);
16731772Sjl139090 }
16741772Sjl139090
16751772Sjl139090 /*
16761772Sjl139090 * Calculate number of TSB entries for the chip.
16771772Sjl139090 */
16781772Sjl139090 /* ARGSUSED */
16791772Sjl139090 static uint_t
mmu_tsb_entries(caddr_t csr_base,pxu_t * pxu_p)16801772Sjl139090 mmu_tsb_entries(caddr_t csr_base, pxu_t *pxu_p)
16811772Sjl139090 {
16821772Sjl139090 uint64_t tsb_ctrl;
16831772Sjl139090 uint_t obp_tsb_entries, obp_tsb_size;
16841772Sjl139090
16851772Sjl139090 tsb_ctrl = CSR_XR(csr_base, MMU_TSB_CONTROL);
16861772Sjl139090
16871772Sjl139090 obp_tsb_size = tsb_ctrl & 0xF;
16881772Sjl139090
16891772Sjl139090 obp_tsb_entries = MMU_TSBSIZE_TO_TSBENTRIES(obp_tsb_size);
16901772Sjl139090
16911772Sjl139090 return (obp_tsb_entries);
16921772Sjl139090 }
16931772Sjl139090
16941772Sjl139090 /*
169527Sjchu * Initialize the module, but do not enable interrupts.
169627Sjchu */
16970Sstevel@tonic-gate void
hvio_mmu_init(caddr_t csr_base,pxu_t * pxu_p)16980Sstevel@tonic-gate hvio_mmu_init(caddr_t csr_base, pxu_t *pxu_p)
16990Sstevel@tonic-gate {
1700*12619Sandrew.rutz@sun.com uint64_t val, i, obp_tsb_pa;
17011772Sjl139090 uint_t obp_tsb_entries;
17020Sstevel@tonic-gate
17030Sstevel@tonic-gate bzero(pxu_p->tsb_vaddr, pxu_p->tsb_size);
17040Sstevel@tonic-gate
17050Sstevel@tonic-gate /*
17060Sstevel@tonic-gate * Preserve OBP's TSB
17070Sstevel@tonic-gate */
17081772Sjl139090 obp_tsb_pa = CSR_XR(csr_base, MMU_TSB_CONTROL) & MMU_TSB_PA_MASK;
17091772Sjl139090
17101772Sjl139090 obp_tsb_entries = mmu_tsb_entries(csr_base, pxu_p);
17110Sstevel@tonic-gate
1712*12619Sandrew.rutz@sun.com /* save "shape" of OBP's TSB for use during Detach */
1713*12619Sandrew.rutz@sun.com pxu_p->obp_tsb_paddr = obp_tsb_pa;
1714*12619Sandrew.rutz@sun.com pxu_p->obp_tsb_entries = obp_tsb_entries;
1715*12619Sandrew.rutz@sun.com
1716*12619Sandrew.rutz@sun.com /* For each Valid TTE in OBP's TSB, save its value in px's IOTSB */
1717*12619Sandrew.rutz@sun.com hvio_obptsb_attach(pxu_p);
17180Sstevel@tonic-gate
17190Sstevel@tonic-gate /*
17200Sstevel@tonic-gate * Invalidate the TLB through the diagnostic register.
17210Sstevel@tonic-gate */
17220Sstevel@tonic-gate
17230Sstevel@tonic-gate CSR_XS(csr_base, MMU_TTE_CACHE_INVALIDATE, -1ull);
17240Sstevel@tonic-gate
17250Sstevel@tonic-gate /*
17260Sstevel@tonic-gate * Configure the Fire MMU TSB Control Register. Determine
17270Sstevel@tonic-gate * the encoding for either 8KB pages (0) or 64KB pages (1).
17280Sstevel@tonic-gate *
17290Sstevel@tonic-gate * Write the most significant 30 bits of the TSB physical address
17300Sstevel@tonic-gate * and the encoded TSB table size.
17310Sstevel@tonic-gate */
173210923SEvan.Yan@Sun.COM for (i = 8; i && (pxu_p->tsb_size < (0x2000 << i)); i--)
173310923SEvan.Yan@Sun.COM ;
17340Sstevel@tonic-gate
17350Sstevel@tonic-gate val = (((((va_to_pa(pxu_p->tsb_vaddr)) >> 13) << 13) |
17360Sstevel@tonic-gate ((MMU_PAGE_SHIFT == 13) ? 0 : 1) << 8) | i);
17370Sstevel@tonic-gate
17380Sstevel@tonic-gate CSR_XS(csr_base, MMU_TSB_CONTROL, val);
17390Sstevel@tonic-gate
17400Sstevel@tonic-gate /*
17410Sstevel@tonic-gate * Enable the MMU, set the "TSB Cache Snoop Enable",
17420Sstevel@tonic-gate * the "Cache Mode", the "Bypass Enable" and
17430Sstevel@tonic-gate * the "Translation Enable" bits.
17440Sstevel@tonic-gate */
17450Sstevel@tonic-gate val = CSR_XR(csr_base, MMU_CONTROL_AND_STATUS);
17460Sstevel@tonic-gate val |= ((1ull << MMU_CONTROL_AND_STATUS_SE)
17478691SLida.Horn@Sun.COM | (MMU_CONTROL_AND_STATUS_ROE_BIT63_ENABLE <<
17488691SLida.Horn@Sun.COM MMU_CONTROL_AND_STATUS_ROE)
174927Sjchu | (MMU_CONTROL_AND_STATUS_CM_MASK << MMU_CONTROL_AND_STATUS_CM)
175027Sjchu | (1ull << MMU_CONTROL_AND_STATUS_BE)
175127Sjchu | (1ull << MMU_CONTROL_AND_STATUS_TE));
17520Sstevel@tonic-gate
17530Sstevel@tonic-gate CSR_XS(csr_base, MMU_CONTROL_AND_STATUS, val);
17540Sstevel@tonic-gate
17550Sstevel@tonic-gate /*
17560Sstevel@tonic-gate * Read the register here to ensure that the previous writes to
17570Sstevel@tonic-gate * the Fire MMU registers have been flushed. (Technically, this
17580Sstevel@tonic-gate * is not entirely necessary here as we will likely do later reads
17590Sstevel@tonic-gate * during Fire initialization, but it is a small price to pay for
17600Sstevel@tonic-gate * more modular code.)
17610Sstevel@tonic-gate */
17620Sstevel@tonic-gate (void) CSR_XR(csr_base, MMU_CONTROL_AND_STATUS);
17630Sstevel@tonic-gate
17640Sstevel@tonic-gate /*
176527Sjchu * CSR_V TLU's UE interrupt regs (log, enable, status, clear)
176627Sjchu * Plus header logs
17670Sstevel@tonic-gate */
176827Sjchu DBG(DBG_MMU, NULL, "mmu_init - MMU_ERROR_LOG_ENABLE: 0x%llx\n",
176927Sjchu CSR_XR(csr_base, MMU_ERROR_LOG_ENABLE));
177027Sjchu
177127Sjchu DBG(DBG_MMU, NULL, "mmu_init - MMU_INTERRUPT_ENABLE: 0x%llx\n",
177227Sjchu CSR_XR(csr_base, MMU_INTERRUPT_ENABLE));
177327Sjchu
177427Sjchu DBG(DBG_MMU, NULL, "mmu_init - MMU_INTERRUPT_STATUS: 0x%llx\n",
177527Sjchu CSR_XR(csr_base, MMU_INTERRUPT_STATUS));
177627Sjchu
177727Sjchu DBG(DBG_MMU, NULL, "mmu_init - MMU_ERROR_STATUS_CLEAR: 0x%llx\n",
177827Sjchu CSR_XR(csr_base, MMU_ERROR_STATUS_CLEAR));
17790Sstevel@tonic-gate }
17800Sstevel@tonic-gate
17810Sstevel@tonic-gate /*
17820Sstevel@tonic-gate * Generic IOMMU Servies
17830Sstevel@tonic-gate */
17840Sstevel@tonic-gate
17850Sstevel@tonic-gate /* ARGSUSED */
17860Sstevel@tonic-gate uint64_t
hvio_iommu_map(devhandle_t dev_hdl,pxu_t * pxu_p,tsbid_t tsbid,pages_t pages,io_attributes_t io_attr,void * addr,size_t pfn_index,int flags)17871617Sgovinda hvio_iommu_map(devhandle_t dev_hdl, pxu_t *pxu_p, tsbid_t tsbid, pages_t pages,
17881617Sgovinda io_attributes_t io_attr, void *addr, size_t pfn_index, int flags)
17890Sstevel@tonic-gate {
17900Sstevel@tonic-gate tsbindex_t tsb_index = PCI_TSBID_TO_TSBINDEX(tsbid);
17910Sstevel@tonic-gate uint64_t attr = MMU_TTE_V;
17920Sstevel@tonic-gate int i;
17930Sstevel@tonic-gate
17941617Sgovinda if (io_attr & PCI_MAP_ATTR_WRITE)
17950Sstevel@tonic-gate attr |= MMU_TTE_W;
17960Sstevel@tonic-gate
17971772Sjl139090 if ((PX_CHIP_TYPE(pxu_p) == PX_CHIP_OBERON) &&
17981772Sjl139090 (io_attr & PCI_MAP_ATTR_RO))
17991772Sjl139090 attr |= MMU_TTE_RO;
18001772Sjl139090
18011772Sjl139090 if (attr & MMU_TTE_RO) {
18021772Sjl139090 DBG(DBG_MMU, NULL, "hvio_iommu_map: pfn_index=0x%x "
18031772Sjl139090 "pages=0x%x attr = 0x%lx\n", pfn_index, pages, attr);
18041772Sjl139090 }
18051772Sjl139090
18061617Sgovinda if (flags & MMU_MAP_PFN) {
18071617Sgovinda ddi_dma_impl_t *mp = (ddi_dma_impl_t *)addr;
18080Sstevel@tonic-gate for (i = 0; i < pages; i++, pfn_index++, tsb_index++) {
18091617Sgovinda px_iopfn_t pfn = PX_GET_MP_PFN(mp, pfn_index);
18101617Sgovinda pxu_p->tsb_vaddr[tsb_index] = MMU_PTOB(pfn) | attr;
18111772Sjl139090
18121772Sjl139090 /*
18131772Sjl139090 * Oberon will need to flush the corresponding TTEs in
18141772Sjl139090 * Cache. We only need to flush every cache line.
18151772Sjl139090 * Extra PIO's are expensive.
18161772Sjl139090 */
18171772Sjl139090 if (PX_CHIP_TYPE(pxu_p) == PX_CHIP_OBERON) {
18181772Sjl139090 if ((i == (pages-1))||!((tsb_index+1) & 0x7)) {
18191772Sjl139090 CSR_XS(dev_hdl,
18201772Sjl139090 MMU_TTE_CACHE_FLUSH_ADDRESS,
18211772Sjl139090 (pxu_p->tsb_paddr+
18221772Sjl139090 (tsb_index*MMU_TTE_SIZE)));
18231772Sjl139090 }
18241772Sjl139090 }
18250Sstevel@tonic-gate }
18260Sstevel@tonic-gate } else {
18271617Sgovinda caddr_t a = (caddr_t)addr;
18280Sstevel@tonic-gate for (i = 0; i < pages; i++, a += MMU_PAGE_SIZE, tsb_index++) {
18290Sstevel@tonic-gate px_iopfn_t pfn = hat_getpfnum(kas.a_hat, a);
18301617Sgovinda pxu_p->tsb_vaddr[tsb_index] = MMU_PTOB(pfn) | attr;
18311772Sjl139090
18321772Sjl139090 /*
18331772Sjl139090 * Oberon will need to flush the corresponding TTEs in
18341772Sjl139090 * Cache. We only need to flush every cache line.
18351772Sjl139090 * Extra PIO's are expensive.
18361772Sjl139090 */
18371772Sjl139090 if (PX_CHIP_TYPE(pxu_p) == PX_CHIP_OBERON) {
18381772Sjl139090 if ((i == (pages-1))||!((tsb_index+1) & 0x7)) {
18391772Sjl139090 CSR_XS(dev_hdl,
18401772Sjl139090 MMU_TTE_CACHE_FLUSH_ADDRESS,
18411772Sjl139090 (pxu_p->tsb_paddr+
18421772Sjl139090 (tsb_index*MMU_TTE_SIZE)));
18431772Sjl139090 }
18441772Sjl139090 }
18450Sstevel@tonic-gate }
18460Sstevel@tonic-gate }
18470Sstevel@tonic-gate
18480Sstevel@tonic-gate return (H_EOK);
18490Sstevel@tonic-gate }
18500Sstevel@tonic-gate
18510Sstevel@tonic-gate /* ARGSUSED */
18520Sstevel@tonic-gate uint64_t
hvio_iommu_demap(devhandle_t dev_hdl,pxu_t * pxu_p,tsbid_t tsbid,pages_t pages)18530Sstevel@tonic-gate hvio_iommu_demap(devhandle_t dev_hdl, pxu_t *pxu_p, tsbid_t tsbid,
18540Sstevel@tonic-gate pages_t pages)
18550Sstevel@tonic-gate {
18560Sstevel@tonic-gate tsbindex_t tsb_index = PCI_TSBID_TO_TSBINDEX(tsbid);
18570Sstevel@tonic-gate int i;
18580Sstevel@tonic-gate
18591772Sjl139090 for (i = 0; i < pages; i++, tsb_index++) {
18600Sstevel@tonic-gate pxu_p->tsb_vaddr[tsb_index] = MMU_INVALID_TTE;
18610Sstevel@tonic-gate
18621772Sjl139090 /*
18631772Sjl139090 * Oberon will need to flush the corresponding TTEs in
18641772Sjl139090 * Cache. We only need to flush every cache line.
18651772Sjl139090 * Extra PIO's are expensive.
18661772Sjl139090 */
18671772Sjl139090 if (PX_CHIP_TYPE(pxu_p) == PX_CHIP_OBERON) {
18681772Sjl139090 if ((i == (pages-1))||!((tsb_index+1) & 0x7)) {
18691772Sjl139090 CSR_XS(dev_hdl,
18701772Sjl139090 MMU_TTE_CACHE_FLUSH_ADDRESS,
18711772Sjl139090 (pxu_p->tsb_paddr+
18721772Sjl139090 (tsb_index*MMU_TTE_SIZE)));
18731772Sjl139090 }
18741772Sjl139090 }
18751772Sjl139090 }
18761772Sjl139090
18770Sstevel@tonic-gate return (H_EOK);
18780Sstevel@tonic-gate }
18790Sstevel@tonic-gate
18800Sstevel@tonic-gate /* ARGSUSED */
18810Sstevel@tonic-gate uint64_t
hvio_iommu_getmap(devhandle_t dev_hdl,pxu_t * pxu_p,tsbid_t tsbid,io_attributes_t * attr_p,r_addr_t * r_addr_p)18820Sstevel@tonic-gate hvio_iommu_getmap(devhandle_t dev_hdl, pxu_t *pxu_p, tsbid_t tsbid,
18831617Sgovinda io_attributes_t *attr_p, r_addr_t *r_addr_p)
18840Sstevel@tonic-gate {
18850Sstevel@tonic-gate tsbindex_t tsb_index = PCI_TSBID_TO_TSBINDEX(tsbid);
18860Sstevel@tonic-gate uint64_t *tte_addr;
18870Sstevel@tonic-gate uint64_t ret = H_EOK;
18880Sstevel@tonic-gate
18890Sstevel@tonic-gate tte_addr = (uint64_t *)(pxu_p->tsb_vaddr) + tsb_index;
18900Sstevel@tonic-gate
18910Sstevel@tonic-gate if (*tte_addr & MMU_TTE_V) {
18921772Sjl139090 *r_addr_p = mmu_tte_to_pa(*tte_addr, pxu_p);
18931617Sgovinda *attr_p = (*tte_addr & MMU_TTE_W) ?
18940Sstevel@tonic-gate PCI_MAP_ATTR_WRITE:PCI_MAP_ATTR_READ;
18950Sstevel@tonic-gate } else {
18960Sstevel@tonic-gate *r_addr_p = 0;
18971617Sgovinda *attr_p = 0;
18980Sstevel@tonic-gate ret = H_ENOMAP;
18990Sstevel@tonic-gate }
19000Sstevel@tonic-gate
19010Sstevel@tonic-gate return (ret);
19020Sstevel@tonic-gate }
19030Sstevel@tonic-gate
1904*12619Sandrew.rutz@sun.com /*
1905*12619Sandrew.rutz@sun.com * Copy each Valid OBP TTE from OBP's IOTSB to px's IOTSB.
1906*12619Sandrew.rutz@sun.com */
1907*12619Sandrew.rutz@sun.com void
hvio_obptsb_attach(pxu_t * pxu_p)1908*12619Sandrew.rutz@sun.com hvio_obptsb_attach(pxu_t *pxu_p)
1909*12619Sandrew.rutz@sun.com {
1910*12619Sandrew.rutz@sun.com uint64_t obp_tsb_pa;
1911*12619Sandrew.rutz@sun.com uint64_t *base_tte_addr;
1912*12619Sandrew.rutz@sun.com uint64_t i;
1913*12619Sandrew.rutz@sun.com uint_t obp_tsb_entries;
1914*12619Sandrew.rutz@sun.com
1915*12619Sandrew.rutz@sun.com obp_tsb_pa = pxu_p->obp_tsb_paddr;
1916*12619Sandrew.rutz@sun.com obp_tsb_entries = pxu_p->obp_tsb_entries;
1917*12619Sandrew.rutz@sun.com
1918*12619Sandrew.rutz@sun.com /*
1919*12619Sandrew.rutz@sun.com * Compute the starting addr of the area reserved for
1920*12619Sandrew.rutz@sun.com * OBP's TTEs; OBP's TTEs are stored at the highest addrs
1921*12619Sandrew.rutz@sun.com * of px's IOTSB.
1922*12619Sandrew.rutz@sun.com */
1923*12619Sandrew.rutz@sun.com base_tte_addr = pxu_p->tsb_vaddr +
1924*12619Sandrew.rutz@sun.com ((pxu_p->tsb_size >> 3) - obp_tsb_entries);
1925*12619Sandrew.rutz@sun.com
1926*12619Sandrew.rutz@sun.com for (i = 0; i < obp_tsb_entries; i++) {
1927*12619Sandrew.rutz@sun.com uint64_t tte = lddphys(obp_tsb_pa + i * 8);
1928*12619Sandrew.rutz@sun.com
1929*12619Sandrew.rutz@sun.com if (!MMU_TTE_VALID(tte))
1930*12619Sandrew.rutz@sun.com continue;
1931*12619Sandrew.rutz@sun.com
1932*12619Sandrew.rutz@sun.com base_tte_addr[i] = tte;
1933*12619Sandrew.rutz@sun.com }
1934*12619Sandrew.rutz@sun.com }
1935*12619Sandrew.rutz@sun.com
1936*12619Sandrew.rutz@sun.com /*
1937*12619Sandrew.rutz@sun.com * For each Valid OBP TTE, deallocate space from the vmem Arena used
1938*12619Sandrew.rutz@sun.com * to manage the TTE's associated DVMA addr space. (Allocation from
1939*12619Sandrew.rutz@sun.com * the DVMA Arena was done in px_mmu_attach).
1940*12619Sandrew.rutz@sun.com */
1941*12619Sandrew.rutz@sun.com void
hvio_obptsb_detach(px_t * px_p)1942*12619Sandrew.rutz@sun.com hvio_obptsb_detach(px_t *px_p)
1943*12619Sandrew.rutz@sun.com {
1944*12619Sandrew.rutz@sun.com uint64_t obp_tsb_pa;
1945*12619Sandrew.rutz@sun.com uint64_t i;
1946*12619Sandrew.rutz@sun.com uint_t obp_tsb_entries;
1947*12619Sandrew.rutz@sun.com uint_t obp_tsb_bias;
1948*12619Sandrew.rutz@sun.com px_mmu_t *mmu_p = px_p->px_mmu_p;
1949*12619Sandrew.rutz@sun.com vmem_t *dvma_map;
1950*12619Sandrew.rutz@sun.com pxu_t *pxu_p = (pxu_t *)px_p->px_plat_p;
1951*12619Sandrew.rutz@sun.com
1952*12619Sandrew.rutz@sun.com dvma_map = mmu_p->mmu_dvma_map;
1953*12619Sandrew.rutz@sun.com
1954*12619Sandrew.rutz@sun.com obp_tsb_pa = pxu_p->obp_tsb_paddr;
1955*12619Sandrew.rutz@sun.com obp_tsb_entries = pxu_p->obp_tsb_entries;
1956*12619Sandrew.rutz@sun.com /*
1957*12619Sandrew.rutz@sun.com * OBP's TTEs are located at the high end of px's IOTSB.
1958*12619Sandrew.rutz@sun.com * Equivalently, OBP's DVMA space is allocated at the high end
1959*12619Sandrew.rutz@sun.com * of px's DVMA space. Compute the bias that references
1960*12619Sandrew.rutz@sun.com * OBP's first possible page of DVMA space.
1961*12619Sandrew.rutz@sun.com */
1962*12619Sandrew.rutz@sun.com obp_tsb_bias = (pxu_p->tsb_size >> 3) - obp_tsb_entries;
1963*12619Sandrew.rutz@sun.com
1964*12619Sandrew.rutz@sun.com for (i = 0; i < obp_tsb_entries; i++) {
1965*12619Sandrew.rutz@sun.com caddr_t va;
1966*12619Sandrew.rutz@sun.com uint64_t tte = lddphys(obp_tsb_pa + i * 8);
1967*12619Sandrew.rutz@sun.com
1968*12619Sandrew.rutz@sun.com if (!MMU_TTE_VALID(tte))
1969*12619Sandrew.rutz@sun.com continue;
1970*12619Sandrew.rutz@sun.com
1971*12619Sandrew.rutz@sun.com /* deallocate the TTE's associated page of DVMA space */
1972*12619Sandrew.rutz@sun.com va = (caddr_t)(MMU_PTOB(mmu_p->dvma_base_pg + obp_tsb_bias +
1973*12619Sandrew.rutz@sun.com i));
1974*12619Sandrew.rutz@sun.com vmem_xfree(dvma_map, va, MMU_PAGE_SIZE);
1975*12619Sandrew.rutz@sun.com }
1976*12619Sandrew.rutz@sun.com }
1977*12619Sandrew.rutz@sun.com
19780Sstevel@tonic-gate /* ARGSUSED */
19790Sstevel@tonic-gate uint64_t
hvio_get_bypass_base(pxu_t * pxu_p)19801772Sjl139090 hvio_get_bypass_base(pxu_t *pxu_p)
19811772Sjl139090 {
19821772Sjl139090 uint64_t base;
19831772Sjl139090
19841772Sjl139090 switch (PX_CHIP_TYPE(pxu_p)) {
19851772Sjl139090 case PX_CHIP_OBERON:
19861772Sjl139090 base = MMU_OBERON_BYPASS_BASE;
19871772Sjl139090 break;
19881772Sjl139090 case PX_CHIP_FIRE:
19891772Sjl139090 base = MMU_FIRE_BYPASS_BASE;
19901772Sjl139090 break;
19911772Sjl139090 default:
19921772Sjl139090 DBG(DBG_MMU, NULL,
19931772Sjl139090 "hvio_get_bypass_base - unknown chip type: 0x%x\n",
19941772Sjl139090 PX_CHIP_TYPE(pxu_p));
19951772Sjl139090 base = 0;
19961772Sjl139090 break;
19971772Sjl139090 }
19981772Sjl139090 return (base);
19991772Sjl139090 }
20001772Sjl139090
20011772Sjl139090 /* ARGSUSED */
20021772Sjl139090 uint64_t
hvio_get_bypass_end(pxu_t * pxu_p)20031772Sjl139090 hvio_get_bypass_end(pxu_t *pxu_p)
20041772Sjl139090 {
20051772Sjl139090 uint64_t end;
20061772Sjl139090
20071772Sjl139090 switch (PX_CHIP_TYPE(pxu_p)) {
20081772Sjl139090 case PX_CHIP_OBERON:
20091772Sjl139090 end = MMU_OBERON_BYPASS_END;
20101772Sjl139090 break;
20111772Sjl139090 case PX_CHIP_FIRE:
20121772Sjl139090 end = MMU_FIRE_BYPASS_END;
20131772Sjl139090 break;
20141772Sjl139090 default:
20151772Sjl139090 DBG(DBG_MMU, NULL,
20161772Sjl139090 "hvio_get_bypass_end - unknown chip type: 0x%x\n",
20171772Sjl139090 PX_CHIP_TYPE(pxu_p));
20181772Sjl139090 end = 0;
20191772Sjl139090 break;
20201772Sjl139090 }
20211772Sjl139090 return (end);
20221772Sjl139090 }
20231772Sjl139090
20241772Sjl139090 /* ARGSUSED */
20251772Sjl139090 uint64_t
hvio_iommu_getbypass(devhandle_t dev_hdl,pxu_t * pxu_p,r_addr_t ra,io_attributes_t attr,io_addr_t * io_addr_p)20261772Sjl139090 hvio_iommu_getbypass(devhandle_t dev_hdl, pxu_t *pxu_p, r_addr_t ra,
20271772Sjl139090 io_attributes_t attr, io_addr_t *io_addr_p)
20280Sstevel@tonic-gate {
20290Sstevel@tonic-gate uint64_t pfn = MMU_BTOP(ra);
20300Sstevel@tonic-gate
20311772Sjl139090 *io_addr_p = hvio_get_bypass_base(pxu_p) | ra |
20321772Sjl139090 (pf_is_memory(pfn) ? 0 : mmu_bypass_noncache(pxu_p));
20330Sstevel@tonic-gate
20340Sstevel@tonic-gate return (H_EOK);
20350Sstevel@tonic-gate }
20360Sstevel@tonic-gate
20370Sstevel@tonic-gate /*
20380Sstevel@tonic-gate * Generic IO Interrupt Servies
20390Sstevel@tonic-gate */
20400Sstevel@tonic-gate
20410Sstevel@tonic-gate /*
20420Sstevel@tonic-gate * Converts a device specific interrupt number given by the
20430Sstevel@tonic-gate * arguments devhandle and devino into a system specific ino.
20440Sstevel@tonic-gate */
20450Sstevel@tonic-gate /* ARGSUSED */
20460Sstevel@tonic-gate uint64_t
hvio_intr_devino_to_sysino(devhandle_t dev_hdl,pxu_t * pxu_p,devino_t devino,sysino_t * sysino)20470Sstevel@tonic-gate hvio_intr_devino_to_sysino(devhandle_t dev_hdl, pxu_t *pxu_p, devino_t devino,
20480Sstevel@tonic-gate sysino_t *sysino)
20490Sstevel@tonic-gate {
20500Sstevel@tonic-gate if (devino > INTERRUPT_MAPPING_ENTRIES) {
20510Sstevel@tonic-gate DBG(DBG_IB, NULL, "ino %x is invalid\n", devino);
20520Sstevel@tonic-gate return (H_ENOINTR);
20530Sstevel@tonic-gate }
20540Sstevel@tonic-gate
20550Sstevel@tonic-gate *sysino = DEVINO_TO_SYSINO(pxu_p->portid, devino);
20560Sstevel@tonic-gate
20570Sstevel@tonic-gate return (H_EOK);
20580Sstevel@tonic-gate }
20590Sstevel@tonic-gate
20600Sstevel@tonic-gate /*
20610Sstevel@tonic-gate * Returns state in intr_valid_state if the interrupt defined by sysino
20620Sstevel@tonic-gate * is valid (enabled) or not-valid (disabled).
20630Sstevel@tonic-gate */
20640Sstevel@tonic-gate uint64_t
hvio_intr_getvalid(devhandle_t dev_hdl,sysino_t sysino,intr_valid_state_t * intr_valid_state)20650Sstevel@tonic-gate hvio_intr_getvalid(devhandle_t dev_hdl, sysino_t sysino,
20660Sstevel@tonic-gate intr_valid_state_t *intr_valid_state)
20670Sstevel@tonic-gate {
20680Sstevel@tonic-gate if (CSRA_BR((caddr_t)dev_hdl, INTERRUPT_MAPPING,
20690Sstevel@tonic-gate SYSINO_TO_DEVINO(sysino), ENTRIES_V)) {
20700Sstevel@tonic-gate *intr_valid_state = INTR_VALID;
20710Sstevel@tonic-gate } else {
20720Sstevel@tonic-gate *intr_valid_state = INTR_NOTVALID;
20730Sstevel@tonic-gate }
20740Sstevel@tonic-gate
20750Sstevel@tonic-gate return (H_EOK);
20760Sstevel@tonic-gate }
20770Sstevel@tonic-gate
20780Sstevel@tonic-gate /*
20790Sstevel@tonic-gate * Sets the 'valid' state of the interrupt defined by
20800Sstevel@tonic-gate * the argument sysino to the state defined by the
20810Sstevel@tonic-gate * argument intr_valid_state.
20820Sstevel@tonic-gate */
20830Sstevel@tonic-gate uint64_t
hvio_intr_setvalid(devhandle_t dev_hdl,sysino_t sysino,intr_valid_state_t intr_valid_state)20840Sstevel@tonic-gate hvio_intr_setvalid(devhandle_t dev_hdl, sysino_t sysino,
20850Sstevel@tonic-gate intr_valid_state_t intr_valid_state)
20860Sstevel@tonic-gate {
20870Sstevel@tonic-gate switch (intr_valid_state) {
20880Sstevel@tonic-gate case INTR_VALID:
20890Sstevel@tonic-gate CSRA_BS((caddr_t)dev_hdl, INTERRUPT_MAPPING,
20900Sstevel@tonic-gate SYSINO_TO_DEVINO(sysino), ENTRIES_V);
20910Sstevel@tonic-gate break;
20920Sstevel@tonic-gate case INTR_NOTVALID:
20930Sstevel@tonic-gate CSRA_BC((caddr_t)dev_hdl, INTERRUPT_MAPPING,
20940Sstevel@tonic-gate SYSINO_TO_DEVINO(sysino), ENTRIES_V);
20950Sstevel@tonic-gate break;
20960Sstevel@tonic-gate default:
20970Sstevel@tonic-gate return (EINVAL);
20980Sstevel@tonic-gate }
20990Sstevel@tonic-gate
21000Sstevel@tonic-gate return (H_EOK);
21010Sstevel@tonic-gate }
21020Sstevel@tonic-gate
21030Sstevel@tonic-gate /*
21040Sstevel@tonic-gate * Returns the current state of the interrupt given by the sysino
21050Sstevel@tonic-gate * argument.
21060Sstevel@tonic-gate */
21070Sstevel@tonic-gate uint64_t
hvio_intr_getstate(devhandle_t dev_hdl,sysino_t sysino,intr_state_t * intr_state)21080Sstevel@tonic-gate hvio_intr_getstate(devhandle_t dev_hdl, sysino_t sysino,
21090Sstevel@tonic-gate intr_state_t *intr_state)
21100Sstevel@tonic-gate {
21110Sstevel@tonic-gate intr_state_t state;
21120Sstevel@tonic-gate
21130Sstevel@tonic-gate state = CSRA_FR((caddr_t)dev_hdl, INTERRUPT_CLEAR,
21140Sstevel@tonic-gate SYSINO_TO_DEVINO(sysino), ENTRIES_INT_STATE);
21150Sstevel@tonic-gate
21160Sstevel@tonic-gate switch (state) {
21170Sstevel@tonic-gate case INTERRUPT_IDLE_STATE:
21180Sstevel@tonic-gate *intr_state = INTR_IDLE_STATE;
21190Sstevel@tonic-gate break;
21200Sstevel@tonic-gate case INTERRUPT_RECEIVED_STATE:
21210Sstevel@tonic-gate *intr_state = INTR_RECEIVED_STATE;
21220Sstevel@tonic-gate break;
21230Sstevel@tonic-gate case INTERRUPT_PENDING_STATE:
21240Sstevel@tonic-gate *intr_state = INTR_DELIVERED_STATE;
21250Sstevel@tonic-gate break;
21260Sstevel@tonic-gate default:
21270Sstevel@tonic-gate return (EINVAL);
21280Sstevel@tonic-gate }
21290Sstevel@tonic-gate
21300Sstevel@tonic-gate return (H_EOK);
21310Sstevel@tonic-gate
21320Sstevel@tonic-gate }
21330Sstevel@tonic-gate
21340Sstevel@tonic-gate /*
21350Sstevel@tonic-gate * Sets the current state of the interrupt given by the sysino
21360Sstevel@tonic-gate * argument to the value given in the argument intr_state.
21370Sstevel@tonic-gate *
21380Sstevel@tonic-gate * Note: Setting the state to INTR_IDLE clears any pending
21390Sstevel@tonic-gate * interrupt for sysino.
21400Sstevel@tonic-gate */
21410Sstevel@tonic-gate uint64_t
hvio_intr_setstate(devhandle_t dev_hdl,sysino_t sysino,intr_state_t intr_state)21420Sstevel@tonic-gate hvio_intr_setstate(devhandle_t dev_hdl, sysino_t sysino,
21430Sstevel@tonic-gate intr_state_t intr_state)
21440Sstevel@tonic-gate {
21450Sstevel@tonic-gate intr_state_t state;
21460Sstevel@tonic-gate
21470Sstevel@tonic-gate switch (intr_state) {
21480Sstevel@tonic-gate case INTR_IDLE_STATE:
21490Sstevel@tonic-gate state = INTERRUPT_IDLE_STATE;
21500Sstevel@tonic-gate break;
21510Sstevel@tonic-gate case INTR_DELIVERED_STATE:
21520Sstevel@tonic-gate state = INTERRUPT_PENDING_STATE;
21530Sstevel@tonic-gate break;
21540Sstevel@tonic-gate default:
21550Sstevel@tonic-gate return (EINVAL);
21560Sstevel@tonic-gate }
21570Sstevel@tonic-gate
21580Sstevel@tonic-gate CSRA_FS((caddr_t)dev_hdl, INTERRUPT_CLEAR,
21590Sstevel@tonic-gate SYSINO_TO_DEVINO(sysino), ENTRIES_INT_STATE, state);
21600Sstevel@tonic-gate
21610Sstevel@tonic-gate return (H_EOK);
21620Sstevel@tonic-gate }
21630Sstevel@tonic-gate
21640Sstevel@tonic-gate /*
21650Sstevel@tonic-gate * Returns the cpuid that is the current target of the
21660Sstevel@tonic-gate * interrupt given by the sysino argument.
21670Sstevel@tonic-gate *
21680Sstevel@tonic-gate * The cpuid value returned is undefined if the target
21690Sstevel@tonic-gate * has not been set via intr_settarget.
21700Sstevel@tonic-gate */
21710Sstevel@tonic-gate uint64_t
hvio_intr_gettarget(devhandle_t dev_hdl,pxu_t * pxu_p,sysino_t sysino,cpuid_t * cpuid)21721772Sjl139090 hvio_intr_gettarget(devhandle_t dev_hdl, pxu_t *pxu_p, sysino_t sysino,
21731772Sjl139090 cpuid_t *cpuid)
21740Sstevel@tonic-gate {
21751772Sjl139090 switch (PX_CHIP_TYPE(pxu_p)) {
21761772Sjl139090 case PX_CHIP_OBERON:
21771772Sjl139090 *cpuid = CSRA_FR((caddr_t)dev_hdl, INTERRUPT_MAPPING,
21781772Sjl139090 SYSINO_TO_DEVINO(sysino), ENTRIES_T_DESTID);
21791772Sjl139090 break;
21801772Sjl139090 case PX_CHIP_FIRE:
21811772Sjl139090 *cpuid = CSRA_FR((caddr_t)dev_hdl, INTERRUPT_MAPPING,
21821772Sjl139090 SYSINO_TO_DEVINO(sysino), ENTRIES_T_JPID);
21831772Sjl139090 break;
21841772Sjl139090 default:
21851772Sjl139090 DBG(DBG_CB, NULL, "hvio_intr_gettarget - "
21861772Sjl139090 "unknown chip type: 0x%x\n", PX_CHIP_TYPE(pxu_p));
21871772Sjl139090 return (EINVAL);
21881772Sjl139090 }
21890Sstevel@tonic-gate
21900Sstevel@tonic-gate return (H_EOK);
21910Sstevel@tonic-gate }
21920Sstevel@tonic-gate
21930Sstevel@tonic-gate /*
21940Sstevel@tonic-gate * Set the target cpu for the interrupt defined by the argument
21950Sstevel@tonic-gate * sysino to the target cpu value defined by the argument cpuid.
21960Sstevel@tonic-gate */
21970Sstevel@tonic-gate uint64_t
hvio_intr_settarget(devhandle_t dev_hdl,pxu_t * pxu_p,sysino_t sysino,cpuid_t cpuid)21981772Sjl139090 hvio_intr_settarget(devhandle_t dev_hdl, pxu_t *pxu_p, sysino_t sysino,
21991772Sjl139090 cpuid_t cpuid)
22000Sstevel@tonic-gate {
22010Sstevel@tonic-gate uint64_t val, intr_controller;
22020Sstevel@tonic-gate uint32_t ino = SYSINO_TO_DEVINO(sysino);
22030Sstevel@tonic-gate
22040Sstevel@tonic-gate /*
22050Sstevel@tonic-gate * For now, we assign interrupt controller in a round
22060Sstevel@tonic-gate * robin fashion. Later, we may need to come up with
22070Sstevel@tonic-gate * a more efficient assignment algorithm.
22080Sstevel@tonic-gate */
22090Sstevel@tonic-gate intr_controller = 0x1ull << (cpuid % 4);
22100Sstevel@tonic-gate
22111772Sjl139090 switch (PX_CHIP_TYPE(pxu_p)) {
22121772Sjl139090 case PX_CHIP_OBERON:
22131772Sjl139090 val = (((cpuid &
22141772Sjl139090 INTERRUPT_MAPPING_ENTRIES_T_DESTID_MASK) <<
22151772Sjl139090 INTERRUPT_MAPPING_ENTRIES_T_DESTID) |
22161772Sjl139090 ((intr_controller &
22171772Sjl139090 INTERRUPT_MAPPING_ENTRIES_INT_CNTRL_NUM_MASK)
22181772Sjl139090 << INTERRUPT_MAPPING_ENTRIES_INT_CNTRL_NUM));
22191772Sjl139090 break;
22201772Sjl139090 case PX_CHIP_FIRE:
22211772Sjl139090 val = (((cpuid & INTERRUPT_MAPPING_ENTRIES_T_JPID_MASK) <<
22221772Sjl139090 INTERRUPT_MAPPING_ENTRIES_T_JPID) |
22231772Sjl139090 ((intr_controller &
22241772Sjl139090 INTERRUPT_MAPPING_ENTRIES_INT_CNTRL_NUM_MASK)
22251772Sjl139090 << INTERRUPT_MAPPING_ENTRIES_INT_CNTRL_NUM));
22261772Sjl139090 break;
22271772Sjl139090 default:
22281772Sjl139090 DBG(DBG_CB, NULL, "hvio_intr_settarget - "
22291772Sjl139090 "unknown chip type: 0x%x\n", PX_CHIP_TYPE(pxu_p));
22301772Sjl139090 return (EINVAL);
22311772Sjl139090 }
22320Sstevel@tonic-gate
22330Sstevel@tonic-gate /* For EQ interrupts, set DATA MONDO bit */
223410923SEvan.Yan@Sun.COM if ((ino >= EQ_1ST_DEVINO) && (ino < (EQ_1ST_DEVINO + EQ_CNT)))
22350Sstevel@tonic-gate val |= (0x1ull << INTERRUPT_MAPPING_ENTRIES_MDO_MODE);
22360Sstevel@tonic-gate
22370Sstevel@tonic-gate CSRA_XS((caddr_t)dev_hdl, INTERRUPT_MAPPING, ino, val);
22380Sstevel@tonic-gate
22390Sstevel@tonic-gate return (H_EOK);
22400Sstevel@tonic-gate }
22410Sstevel@tonic-gate
22420Sstevel@tonic-gate /*
22430Sstevel@tonic-gate * MSIQ Functions:
22440Sstevel@tonic-gate */
22450Sstevel@tonic-gate uint64_t
hvio_msiq_init(devhandle_t dev_hdl,pxu_t * pxu_p)22460Sstevel@tonic-gate hvio_msiq_init(devhandle_t dev_hdl, pxu_t *pxu_p)
22470Sstevel@tonic-gate {
22480Sstevel@tonic-gate CSRA_XS((caddr_t)dev_hdl, EVENT_QUEUE_BASE_ADDRESS, 0,
22490Sstevel@tonic-gate (uint64_t)pxu_p->msiq_mapped_p);
22500Sstevel@tonic-gate DBG(DBG_IB, NULL,
22510Sstevel@tonic-gate "hvio_msiq_init: EVENT_QUEUE_BASE_ADDRESS 0x%llx\n",
22520Sstevel@tonic-gate CSR_XR((caddr_t)dev_hdl, EVENT_QUEUE_BASE_ADDRESS));
22530Sstevel@tonic-gate
22540Sstevel@tonic-gate CSRA_XS((caddr_t)dev_hdl, INTERRUPT_MONDO_DATA_0, 0,
22552091Sam139583 (uint64_t)ID_TO_IGN(PX_CHIP_TYPE(pxu_p),
22562091Sam139583 pxu_p->portid) << INO_BITS);
22570Sstevel@tonic-gate DBG(DBG_IB, NULL, "hvio_msiq_init: "
22580Sstevel@tonic-gate "INTERRUPT_MONDO_DATA_0: 0x%llx\n",
22590Sstevel@tonic-gate CSR_XR((caddr_t)dev_hdl, INTERRUPT_MONDO_DATA_0));
22600Sstevel@tonic-gate
22610Sstevel@tonic-gate return (H_EOK);
22620Sstevel@tonic-gate }
22630Sstevel@tonic-gate
22640Sstevel@tonic-gate uint64_t
hvio_msiq_getvalid(devhandle_t dev_hdl,msiqid_t msiq_id,pci_msiq_valid_state_t * msiq_valid_state)22650Sstevel@tonic-gate hvio_msiq_getvalid(devhandle_t dev_hdl, msiqid_t msiq_id,
22660Sstevel@tonic-gate pci_msiq_valid_state_t *msiq_valid_state)
22670Sstevel@tonic-gate {
22680Sstevel@tonic-gate uint32_t eq_state;
22690Sstevel@tonic-gate uint64_t ret = H_EOK;
22700Sstevel@tonic-gate
22710Sstevel@tonic-gate eq_state = CSRA_FR((caddr_t)dev_hdl, EVENT_QUEUE_STATE,
22720Sstevel@tonic-gate msiq_id, ENTRIES_STATE);
22730Sstevel@tonic-gate
22740Sstevel@tonic-gate switch (eq_state) {
22750Sstevel@tonic-gate case EQ_IDLE_STATE:
22760Sstevel@tonic-gate *msiq_valid_state = PCI_MSIQ_INVALID;
22770Sstevel@tonic-gate break;
22780Sstevel@tonic-gate case EQ_ACTIVE_STATE:
22790Sstevel@tonic-gate case EQ_ERROR_STATE:
22800Sstevel@tonic-gate *msiq_valid_state = PCI_MSIQ_VALID;
22810Sstevel@tonic-gate break;
22820Sstevel@tonic-gate default:
22830Sstevel@tonic-gate ret = H_EIO;
22840Sstevel@tonic-gate break;
22850Sstevel@tonic-gate }
22860Sstevel@tonic-gate
22870Sstevel@tonic-gate return (ret);
22880Sstevel@tonic-gate }
22890Sstevel@tonic-gate
22900Sstevel@tonic-gate uint64_t
hvio_msiq_setvalid(devhandle_t dev_hdl,msiqid_t msiq_id,pci_msiq_valid_state_t msiq_valid_state)22910Sstevel@tonic-gate hvio_msiq_setvalid(devhandle_t dev_hdl, msiqid_t msiq_id,
22920Sstevel@tonic-gate pci_msiq_valid_state_t msiq_valid_state)
22930Sstevel@tonic-gate {
22940Sstevel@tonic-gate uint64_t ret = H_EOK;
22950Sstevel@tonic-gate
22960Sstevel@tonic-gate switch (msiq_valid_state) {
22970Sstevel@tonic-gate case PCI_MSIQ_INVALID:
22980Sstevel@tonic-gate CSRA_BS((caddr_t)dev_hdl, EVENT_QUEUE_CONTROL_CLEAR,
22990Sstevel@tonic-gate msiq_id, ENTRIES_DIS);
23000Sstevel@tonic-gate break;
23010Sstevel@tonic-gate case PCI_MSIQ_VALID:
23020Sstevel@tonic-gate CSRA_BS((caddr_t)dev_hdl, EVENT_QUEUE_CONTROL_SET,
23030Sstevel@tonic-gate msiq_id, ENTRIES_EN);
23040Sstevel@tonic-gate break;
23050Sstevel@tonic-gate default:
23060Sstevel@tonic-gate ret = H_EINVAL;
23070Sstevel@tonic-gate break;
23080Sstevel@tonic-gate }
23090Sstevel@tonic-gate
23100Sstevel@tonic-gate return (ret);
23110Sstevel@tonic-gate }
23120Sstevel@tonic-gate
23130Sstevel@tonic-gate uint64_t
hvio_msiq_getstate(devhandle_t dev_hdl,msiqid_t msiq_id,pci_msiq_state_t * msiq_state)23140Sstevel@tonic-gate hvio_msiq_getstate(devhandle_t dev_hdl, msiqid_t msiq_id,
23150Sstevel@tonic-gate pci_msiq_state_t *msiq_state)
23160Sstevel@tonic-gate {
23170Sstevel@tonic-gate uint32_t eq_state;
23180Sstevel@tonic-gate uint64_t ret = H_EOK;
23190Sstevel@tonic-gate
23200Sstevel@tonic-gate eq_state = CSRA_FR((caddr_t)dev_hdl, EVENT_QUEUE_STATE,
23210Sstevel@tonic-gate msiq_id, ENTRIES_STATE);
23220Sstevel@tonic-gate
23230Sstevel@tonic-gate switch (eq_state) {
23240Sstevel@tonic-gate case EQ_IDLE_STATE:
23250Sstevel@tonic-gate case EQ_ACTIVE_STATE:
23260Sstevel@tonic-gate *msiq_state = PCI_MSIQ_STATE_IDLE;
23270Sstevel@tonic-gate break;
23280Sstevel@tonic-gate case EQ_ERROR_STATE:
23290Sstevel@tonic-gate *msiq_state = PCI_MSIQ_STATE_ERROR;
23300Sstevel@tonic-gate break;
23310Sstevel@tonic-gate default:
23320Sstevel@tonic-gate ret = H_EIO;
23330Sstevel@tonic-gate }
23340Sstevel@tonic-gate
23350Sstevel@tonic-gate return (ret);
23360Sstevel@tonic-gate }
23370Sstevel@tonic-gate
23380Sstevel@tonic-gate uint64_t
hvio_msiq_setstate(devhandle_t dev_hdl,msiqid_t msiq_id,pci_msiq_state_t msiq_state)23390Sstevel@tonic-gate hvio_msiq_setstate(devhandle_t dev_hdl, msiqid_t msiq_id,
23400Sstevel@tonic-gate pci_msiq_state_t msiq_state)
23410Sstevel@tonic-gate {
23420Sstevel@tonic-gate uint32_t eq_state;
23430Sstevel@tonic-gate uint64_t ret = H_EOK;
23440Sstevel@tonic-gate
23450Sstevel@tonic-gate eq_state = CSRA_FR((caddr_t)dev_hdl, EVENT_QUEUE_STATE,
23460Sstevel@tonic-gate msiq_id, ENTRIES_STATE);
23470Sstevel@tonic-gate
23480Sstevel@tonic-gate switch (eq_state) {
23490Sstevel@tonic-gate case EQ_IDLE_STATE:
23500Sstevel@tonic-gate if (msiq_state == PCI_MSIQ_STATE_ERROR)
23510Sstevel@tonic-gate ret = H_EIO;
23520Sstevel@tonic-gate break;
23530Sstevel@tonic-gate case EQ_ACTIVE_STATE:
23540Sstevel@tonic-gate if (msiq_state == PCI_MSIQ_STATE_ERROR)
23550Sstevel@tonic-gate CSRA_BS((caddr_t)dev_hdl, EVENT_QUEUE_CONTROL_SET,
23560Sstevel@tonic-gate msiq_id, ENTRIES_ENOVERR);
23570Sstevel@tonic-gate else
23580Sstevel@tonic-gate ret = H_EIO;
23590Sstevel@tonic-gate break;
23600Sstevel@tonic-gate case EQ_ERROR_STATE:
23610Sstevel@tonic-gate if (msiq_state == PCI_MSIQ_STATE_IDLE)
23620Sstevel@tonic-gate CSRA_BS((caddr_t)dev_hdl, EVENT_QUEUE_CONTROL_CLEAR,
23630Sstevel@tonic-gate msiq_id, ENTRIES_E2I);
23640Sstevel@tonic-gate else
23650Sstevel@tonic-gate ret = H_EIO;
23660Sstevel@tonic-gate break;
23670Sstevel@tonic-gate default:
23680Sstevel@tonic-gate ret = H_EIO;
23690Sstevel@tonic-gate }
23700Sstevel@tonic-gate
23710Sstevel@tonic-gate return (ret);
23720Sstevel@tonic-gate }
23730Sstevel@tonic-gate
23740Sstevel@tonic-gate uint64_t
hvio_msiq_gethead(devhandle_t dev_hdl,msiqid_t msiq_id,msiqhead_t * msiq_head)23750Sstevel@tonic-gate hvio_msiq_gethead(devhandle_t dev_hdl, msiqid_t msiq_id,
23760Sstevel@tonic-gate msiqhead_t *msiq_head)
23770Sstevel@tonic-gate {
23780Sstevel@tonic-gate *msiq_head = CSRA_FR((caddr_t)dev_hdl, EVENT_QUEUE_HEAD,
23790Sstevel@tonic-gate msiq_id, ENTRIES_HEAD);
23800Sstevel@tonic-gate
23810Sstevel@tonic-gate return (H_EOK);
23820Sstevel@tonic-gate }
23830Sstevel@tonic-gate
23840Sstevel@tonic-gate uint64_t
hvio_msiq_sethead(devhandle_t dev_hdl,msiqid_t msiq_id,msiqhead_t msiq_head)23850Sstevel@tonic-gate hvio_msiq_sethead(devhandle_t dev_hdl, msiqid_t msiq_id,
23860Sstevel@tonic-gate msiqhead_t msiq_head)
23870Sstevel@tonic-gate {
23880Sstevel@tonic-gate CSRA_FS((caddr_t)dev_hdl, EVENT_QUEUE_HEAD, msiq_id,
23890Sstevel@tonic-gate ENTRIES_HEAD, msiq_head);
23900Sstevel@tonic-gate
23910Sstevel@tonic-gate return (H_EOK);
23920Sstevel@tonic-gate }
23930Sstevel@tonic-gate
23940Sstevel@tonic-gate uint64_t
hvio_msiq_gettail(devhandle_t dev_hdl,msiqid_t msiq_id,msiqtail_t * msiq_tail)23950Sstevel@tonic-gate hvio_msiq_gettail(devhandle_t dev_hdl, msiqid_t msiq_id,
23960Sstevel@tonic-gate msiqtail_t *msiq_tail)
23970Sstevel@tonic-gate {
23980Sstevel@tonic-gate *msiq_tail = CSRA_FR((caddr_t)dev_hdl, EVENT_QUEUE_TAIL,
23990Sstevel@tonic-gate msiq_id, ENTRIES_TAIL);
24000Sstevel@tonic-gate
24010Sstevel@tonic-gate return (H_EOK);
24020Sstevel@tonic-gate }
24030Sstevel@tonic-gate
24040Sstevel@tonic-gate /*
24050Sstevel@tonic-gate * MSI Functions:
24060Sstevel@tonic-gate */
24070Sstevel@tonic-gate uint64_t
hvio_msi_init(devhandle_t dev_hdl,uint64_t addr32,uint64_t addr64)24080Sstevel@tonic-gate hvio_msi_init(devhandle_t dev_hdl, uint64_t addr32, uint64_t addr64)
24090Sstevel@tonic-gate {
24100Sstevel@tonic-gate /* PCI MEM 32 resources to perform 32 bit MSI transactions */
24110Sstevel@tonic-gate CSRA_FS((caddr_t)dev_hdl, MSI_32_BIT_ADDRESS, 0,
24120Sstevel@tonic-gate ADDR, (uint64_t)addr32 >> MSI_32_BIT_ADDRESS_ADDR);
24136953Sanbui DBG(DBG_IB, NULL, "hvio_msi_init: MSI_32_BIT_ADDRESS: 0x%llx\n",
24140Sstevel@tonic-gate CSR_XR((caddr_t)dev_hdl, MSI_32_BIT_ADDRESS));
24150Sstevel@tonic-gate
24160Sstevel@tonic-gate /* Reserve PCI MEM 64 resources to perform 64 bit MSI transactions */
24170Sstevel@tonic-gate CSRA_FS((caddr_t)dev_hdl, MSI_64_BIT_ADDRESS, 0,
24180Sstevel@tonic-gate ADDR, (uint64_t)addr64 >> MSI_64_BIT_ADDRESS_ADDR);
24196953Sanbui DBG(DBG_IB, NULL, "hvio_msi_init: MSI_64_BIT_ADDRESS: 0x%llx\n",
24200Sstevel@tonic-gate CSR_XR((caddr_t)dev_hdl, MSI_64_BIT_ADDRESS));
24210Sstevel@tonic-gate
24220Sstevel@tonic-gate return (H_EOK);
24230Sstevel@tonic-gate }
24240Sstevel@tonic-gate
24250Sstevel@tonic-gate uint64_t
hvio_msi_getmsiq(devhandle_t dev_hdl,msinum_t msi_num,msiqid_t * msiq_id)24260Sstevel@tonic-gate hvio_msi_getmsiq(devhandle_t dev_hdl, msinum_t msi_num,
24270Sstevel@tonic-gate msiqid_t *msiq_id)
24280Sstevel@tonic-gate {
24290Sstevel@tonic-gate *msiq_id = CSRA_FR((caddr_t)dev_hdl, MSI_MAPPING,
24300Sstevel@tonic-gate msi_num, ENTRIES_EQNUM);
24310Sstevel@tonic-gate
24320Sstevel@tonic-gate return (H_EOK);
24330Sstevel@tonic-gate }
24340Sstevel@tonic-gate
24350Sstevel@tonic-gate uint64_t
hvio_msi_setmsiq(devhandle_t dev_hdl,msinum_t msi_num,msiqid_t msiq_id)24360Sstevel@tonic-gate hvio_msi_setmsiq(devhandle_t dev_hdl, msinum_t msi_num,
24370Sstevel@tonic-gate msiqid_t msiq_id)
24380Sstevel@tonic-gate {
24390Sstevel@tonic-gate CSRA_FS((caddr_t)dev_hdl, MSI_MAPPING, msi_num,
24400Sstevel@tonic-gate ENTRIES_EQNUM, msiq_id);
24410Sstevel@tonic-gate
24420Sstevel@tonic-gate return (H_EOK);
24430Sstevel@tonic-gate }
24440Sstevel@tonic-gate
24450Sstevel@tonic-gate uint64_t
hvio_msi_getvalid(devhandle_t dev_hdl,msinum_t msi_num,pci_msi_valid_state_t * msi_valid_state)24460Sstevel@tonic-gate hvio_msi_getvalid(devhandle_t dev_hdl, msinum_t msi_num,
24470Sstevel@tonic-gate pci_msi_valid_state_t *msi_valid_state)
24480Sstevel@tonic-gate {
24490Sstevel@tonic-gate *msi_valid_state = CSRA_BR((caddr_t)dev_hdl, MSI_MAPPING,
24500Sstevel@tonic-gate msi_num, ENTRIES_V);
24510Sstevel@tonic-gate
24520Sstevel@tonic-gate return (H_EOK);
24530Sstevel@tonic-gate }
24540Sstevel@tonic-gate
24550Sstevel@tonic-gate uint64_t
hvio_msi_setvalid(devhandle_t dev_hdl,msinum_t msi_num,pci_msi_valid_state_t msi_valid_state)24560Sstevel@tonic-gate hvio_msi_setvalid(devhandle_t dev_hdl, msinum_t msi_num,
24570Sstevel@tonic-gate pci_msi_valid_state_t msi_valid_state)
24580Sstevel@tonic-gate {
24590Sstevel@tonic-gate uint64_t ret = H_EOK;
24600Sstevel@tonic-gate
24610Sstevel@tonic-gate switch (msi_valid_state) {
24620Sstevel@tonic-gate case PCI_MSI_VALID:
24630Sstevel@tonic-gate CSRA_BS((caddr_t)dev_hdl, MSI_MAPPING, msi_num,
24640Sstevel@tonic-gate ENTRIES_V);
24650Sstevel@tonic-gate break;
24660Sstevel@tonic-gate case PCI_MSI_INVALID:
24670Sstevel@tonic-gate CSRA_BC((caddr_t)dev_hdl, MSI_MAPPING, msi_num,
24680Sstevel@tonic-gate ENTRIES_V);
24690Sstevel@tonic-gate break;
24700Sstevel@tonic-gate default:
24710Sstevel@tonic-gate ret = H_EINVAL;
24720Sstevel@tonic-gate }
24730Sstevel@tonic-gate
24740Sstevel@tonic-gate return (ret);
24750Sstevel@tonic-gate }
24760Sstevel@tonic-gate
24770Sstevel@tonic-gate uint64_t
hvio_msi_getstate(devhandle_t dev_hdl,msinum_t msi_num,pci_msi_state_t * msi_state)24780Sstevel@tonic-gate hvio_msi_getstate(devhandle_t dev_hdl, msinum_t msi_num,
24790Sstevel@tonic-gate pci_msi_state_t *msi_state)
24800Sstevel@tonic-gate {
24810Sstevel@tonic-gate *msi_state = CSRA_BR((caddr_t)dev_hdl, MSI_MAPPING,
24820Sstevel@tonic-gate msi_num, ENTRIES_EQWR_N);
24830Sstevel@tonic-gate
24840Sstevel@tonic-gate return (H_EOK);
24850Sstevel@tonic-gate }
24860Sstevel@tonic-gate
24870Sstevel@tonic-gate uint64_t
hvio_msi_setstate(devhandle_t dev_hdl,msinum_t msi_num,pci_msi_state_t msi_state)24880Sstevel@tonic-gate hvio_msi_setstate(devhandle_t dev_hdl, msinum_t msi_num,
24890Sstevel@tonic-gate pci_msi_state_t msi_state)
24900Sstevel@tonic-gate {
24910Sstevel@tonic-gate uint64_t ret = H_EOK;
24920Sstevel@tonic-gate
24930Sstevel@tonic-gate switch (msi_state) {
24940Sstevel@tonic-gate case PCI_MSI_STATE_IDLE:
24950Sstevel@tonic-gate CSRA_BS((caddr_t)dev_hdl, MSI_CLEAR, msi_num,
24960Sstevel@tonic-gate ENTRIES_EQWR_N);
24970Sstevel@tonic-gate break;
24980Sstevel@tonic-gate case PCI_MSI_STATE_DELIVERED:
24990Sstevel@tonic-gate default:
25000Sstevel@tonic-gate ret = H_EINVAL;
25010Sstevel@tonic-gate break;
25020Sstevel@tonic-gate }
25030Sstevel@tonic-gate
25040Sstevel@tonic-gate return (ret);
25050Sstevel@tonic-gate }
25060Sstevel@tonic-gate
25070Sstevel@tonic-gate /*
25080Sstevel@tonic-gate * MSG Functions:
25090Sstevel@tonic-gate */
25100Sstevel@tonic-gate uint64_t
hvio_msg_getmsiq(devhandle_t dev_hdl,pcie_msg_type_t msg_type,msiqid_t * msiq_id)25110Sstevel@tonic-gate hvio_msg_getmsiq(devhandle_t dev_hdl, pcie_msg_type_t msg_type,
25120Sstevel@tonic-gate msiqid_t *msiq_id)
25130Sstevel@tonic-gate {
25140Sstevel@tonic-gate uint64_t ret = H_EOK;
25150Sstevel@tonic-gate
25160Sstevel@tonic-gate switch (msg_type) {
25170Sstevel@tonic-gate case PCIE_PME_MSG:
25180Sstevel@tonic-gate *msiq_id = CSR_FR((caddr_t)dev_hdl, PM_PME_MAPPING, EQNUM);
25190Sstevel@tonic-gate break;
25200Sstevel@tonic-gate case PCIE_PME_ACK_MSG:
25210Sstevel@tonic-gate *msiq_id = CSR_FR((caddr_t)dev_hdl, PME_TO_ACK_MAPPING,
25220Sstevel@tonic-gate EQNUM);
25230Sstevel@tonic-gate break;
25240Sstevel@tonic-gate case PCIE_CORR_MSG:
25250Sstevel@tonic-gate *msiq_id = CSR_FR((caddr_t)dev_hdl, ERR_COR_MAPPING, EQNUM);
25260Sstevel@tonic-gate break;
25270Sstevel@tonic-gate case PCIE_NONFATAL_MSG:
25280Sstevel@tonic-gate *msiq_id = CSR_FR((caddr_t)dev_hdl, ERR_NONFATAL_MAPPING,
25290Sstevel@tonic-gate EQNUM);
25300Sstevel@tonic-gate break;
25310Sstevel@tonic-gate case PCIE_FATAL_MSG:
25320Sstevel@tonic-gate *msiq_id = CSR_FR((caddr_t)dev_hdl, ERR_FATAL_MAPPING, EQNUM);
25330Sstevel@tonic-gate break;
25340Sstevel@tonic-gate default:
25350Sstevel@tonic-gate ret = H_EINVAL;
25360Sstevel@tonic-gate break;
25370Sstevel@tonic-gate }
25380Sstevel@tonic-gate
25390Sstevel@tonic-gate return (ret);
25400Sstevel@tonic-gate }
25410Sstevel@tonic-gate
25420Sstevel@tonic-gate uint64_t
hvio_msg_setmsiq(devhandle_t dev_hdl,pcie_msg_type_t msg_type,msiqid_t msiq_id)25430Sstevel@tonic-gate hvio_msg_setmsiq(devhandle_t dev_hdl, pcie_msg_type_t msg_type,
25440Sstevel@tonic-gate msiqid_t msiq_id)
25450Sstevel@tonic-gate {
25460Sstevel@tonic-gate uint64_t ret = H_EOK;
25470Sstevel@tonic-gate
25480Sstevel@tonic-gate switch (msg_type) {
25490Sstevel@tonic-gate case PCIE_PME_MSG:
25500Sstevel@tonic-gate CSR_FS((caddr_t)dev_hdl, PM_PME_MAPPING, EQNUM, msiq_id);
25510Sstevel@tonic-gate break;
25520Sstevel@tonic-gate case PCIE_PME_ACK_MSG:
25530Sstevel@tonic-gate CSR_FS((caddr_t)dev_hdl, PME_TO_ACK_MAPPING, EQNUM, msiq_id);
25540Sstevel@tonic-gate break;
25550Sstevel@tonic-gate case PCIE_CORR_MSG:
25560Sstevel@tonic-gate CSR_FS((caddr_t)dev_hdl, ERR_COR_MAPPING, EQNUM, msiq_id);
25570Sstevel@tonic-gate break;
25580Sstevel@tonic-gate case PCIE_NONFATAL_MSG:
25590Sstevel@tonic-gate CSR_FS((caddr_t)dev_hdl, ERR_NONFATAL_MAPPING, EQNUM, msiq_id);
25600Sstevel@tonic-gate break;
25610Sstevel@tonic-gate case PCIE_FATAL_MSG:
25620Sstevel@tonic-gate CSR_FS((caddr_t)dev_hdl, ERR_FATAL_MAPPING, EQNUM, msiq_id);
25630Sstevel@tonic-gate break;
25640Sstevel@tonic-gate default:
25650Sstevel@tonic-gate ret = H_EINVAL;
25660Sstevel@tonic-gate break;
25670Sstevel@tonic-gate }
25680Sstevel@tonic-gate
25690Sstevel@tonic-gate return (ret);
25700Sstevel@tonic-gate }
25710Sstevel@tonic-gate
25720Sstevel@tonic-gate uint64_t
hvio_msg_getvalid(devhandle_t dev_hdl,pcie_msg_type_t msg_type,pcie_msg_valid_state_t * msg_valid_state)25730Sstevel@tonic-gate hvio_msg_getvalid(devhandle_t dev_hdl, pcie_msg_type_t msg_type,
25740Sstevel@tonic-gate pcie_msg_valid_state_t *msg_valid_state)
25750Sstevel@tonic-gate {
25760Sstevel@tonic-gate uint64_t ret = H_EOK;
25770Sstevel@tonic-gate
25780Sstevel@tonic-gate switch (msg_type) {
25790Sstevel@tonic-gate case PCIE_PME_MSG:
25800Sstevel@tonic-gate *msg_valid_state = CSR_BR((caddr_t)dev_hdl, PM_PME_MAPPING, V);
25810Sstevel@tonic-gate break;
25820Sstevel@tonic-gate case PCIE_PME_ACK_MSG:
25830Sstevel@tonic-gate *msg_valid_state = CSR_BR((caddr_t)dev_hdl,
25840Sstevel@tonic-gate PME_TO_ACK_MAPPING, V);
25850Sstevel@tonic-gate break;
25860Sstevel@tonic-gate case PCIE_CORR_MSG:
25870Sstevel@tonic-gate *msg_valid_state = CSR_BR((caddr_t)dev_hdl, ERR_COR_MAPPING, V);
25880Sstevel@tonic-gate break;
25890Sstevel@tonic-gate case PCIE_NONFATAL_MSG:
25900Sstevel@tonic-gate *msg_valid_state = CSR_BR((caddr_t)dev_hdl,
25910Sstevel@tonic-gate ERR_NONFATAL_MAPPING, V);
25920Sstevel@tonic-gate break;
25930Sstevel@tonic-gate case PCIE_FATAL_MSG:
25940Sstevel@tonic-gate *msg_valid_state = CSR_BR((caddr_t)dev_hdl, ERR_FATAL_MAPPING,
25950Sstevel@tonic-gate V);
25960Sstevel@tonic-gate break;
25970Sstevel@tonic-gate default:
25980Sstevel@tonic-gate ret = H_EINVAL;
25990Sstevel@tonic-gate break;
26000Sstevel@tonic-gate }
26010Sstevel@tonic-gate
26020Sstevel@tonic-gate return (ret);
26030Sstevel@tonic-gate }
26040Sstevel@tonic-gate
26050Sstevel@tonic-gate uint64_t
hvio_msg_setvalid(devhandle_t dev_hdl,pcie_msg_type_t msg_type,pcie_msg_valid_state_t msg_valid_state)26060Sstevel@tonic-gate hvio_msg_setvalid(devhandle_t dev_hdl, pcie_msg_type_t msg_type,
26070Sstevel@tonic-gate pcie_msg_valid_state_t msg_valid_state)
26080Sstevel@tonic-gate {
26090Sstevel@tonic-gate uint64_t ret = H_EOK;
26100Sstevel@tonic-gate
26110Sstevel@tonic-gate switch (msg_valid_state) {
26120Sstevel@tonic-gate case PCIE_MSG_VALID:
26130Sstevel@tonic-gate switch (msg_type) {
26140Sstevel@tonic-gate case PCIE_PME_MSG:
26150Sstevel@tonic-gate CSR_BS((caddr_t)dev_hdl, PM_PME_MAPPING, V);
26160Sstevel@tonic-gate break;
26170Sstevel@tonic-gate case PCIE_PME_ACK_MSG:
26180Sstevel@tonic-gate CSR_BS((caddr_t)dev_hdl, PME_TO_ACK_MAPPING, V);
26190Sstevel@tonic-gate break;
26200Sstevel@tonic-gate case PCIE_CORR_MSG:
26210Sstevel@tonic-gate CSR_BS((caddr_t)dev_hdl, ERR_COR_MAPPING, V);
26220Sstevel@tonic-gate break;
26230Sstevel@tonic-gate case PCIE_NONFATAL_MSG:
26240Sstevel@tonic-gate CSR_BS((caddr_t)dev_hdl, ERR_NONFATAL_MAPPING, V);
26250Sstevel@tonic-gate break;
26260Sstevel@tonic-gate case PCIE_FATAL_MSG:
26270Sstevel@tonic-gate CSR_BS((caddr_t)dev_hdl, ERR_FATAL_MAPPING, V);
26280Sstevel@tonic-gate break;
26290Sstevel@tonic-gate default:
26300Sstevel@tonic-gate ret = H_EINVAL;
26310Sstevel@tonic-gate break;
26320Sstevel@tonic-gate }
26330Sstevel@tonic-gate
26340Sstevel@tonic-gate break;
26350Sstevel@tonic-gate case PCIE_MSG_INVALID:
26360Sstevel@tonic-gate switch (msg_type) {
26370Sstevel@tonic-gate case PCIE_PME_MSG:
26380Sstevel@tonic-gate CSR_BC((caddr_t)dev_hdl, PM_PME_MAPPING, V);
26390Sstevel@tonic-gate break;
26400Sstevel@tonic-gate case PCIE_PME_ACK_MSG:
26410Sstevel@tonic-gate CSR_BC((caddr_t)dev_hdl, PME_TO_ACK_MAPPING, V);
26420Sstevel@tonic-gate break;
26430Sstevel@tonic-gate case PCIE_CORR_MSG:
26440Sstevel@tonic-gate CSR_BC((caddr_t)dev_hdl, ERR_COR_MAPPING, V);
26450Sstevel@tonic-gate break;
26460Sstevel@tonic-gate case PCIE_NONFATAL_MSG:
26470Sstevel@tonic-gate CSR_BC((caddr_t)dev_hdl, ERR_NONFATAL_MAPPING, V);
26480Sstevel@tonic-gate break;
26490Sstevel@tonic-gate case PCIE_FATAL_MSG:
26500Sstevel@tonic-gate CSR_BC((caddr_t)dev_hdl, ERR_FATAL_MAPPING, V);
26510Sstevel@tonic-gate break;
26520Sstevel@tonic-gate default:
26530Sstevel@tonic-gate ret = H_EINVAL;
26540Sstevel@tonic-gate break;
26550Sstevel@tonic-gate }
26560Sstevel@tonic-gate break;
26570Sstevel@tonic-gate default:
26580Sstevel@tonic-gate ret = H_EINVAL;
26590Sstevel@tonic-gate }
26600Sstevel@tonic-gate
26610Sstevel@tonic-gate return (ret);
26620Sstevel@tonic-gate }
26630Sstevel@tonic-gate
26640Sstevel@tonic-gate /*
26650Sstevel@tonic-gate * Suspend/Resume Functions:
26660Sstevel@tonic-gate * (pec, mmu, ib)
26670Sstevel@tonic-gate * cb
26680Sstevel@tonic-gate * Registers saved have all been touched in the XXX_init functions.
26690Sstevel@tonic-gate */
26700Sstevel@tonic-gate uint64_t
hvio_suspend(devhandle_t dev_hdl,pxu_t * pxu_p)26710Sstevel@tonic-gate hvio_suspend(devhandle_t dev_hdl, pxu_t *pxu_p)
26720Sstevel@tonic-gate {
26730Sstevel@tonic-gate uint64_t *config_state;
26740Sstevel@tonic-gate int total_size;
26750Sstevel@tonic-gate int i;
26760Sstevel@tonic-gate
26770Sstevel@tonic-gate if (msiq_suspend(dev_hdl, pxu_p) != H_EOK)
26780Sstevel@tonic-gate return (H_EIO);
26790Sstevel@tonic-gate
26800Sstevel@tonic-gate total_size = PEC_SIZE + MMU_SIZE + IB_SIZE + IB_MAP_SIZE;
26810Sstevel@tonic-gate config_state = kmem_zalloc(total_size, KM_NOSLEEP);
26820Sstevel@tonic-gate
26830Sstevel@tonic-gate if (config_state == NULL) {
26840Sstevel@tonic-gate return (H_EIO);
26850Sstevel@tonic-gate }
26860Sstevel@tonic-gate
26870Sstevel@tonic-gate /*
26880Sstevel@tonic-gate * Soft state for suspend/resume from pxu_t
26890Sstevel@tonic-gate * uint64_t *pec_config_state;
26900Sstevel@tonic-gate * uint64_t *mmu_config_state;
26910Sstevel@tonic-gate * uint64_t *ib_intr_map;
26920Sstevel@tonic-gate * uint64_t *ib_config_state;
26930Sstevel@tonic-gate * uint64_t *xcb_config_state;
26940Sstevel@tonic-gate */
26950Sstevel@tonic-gate
26960Sstevel@tonic-gate /* Save the PEC configuration states */
26970Sstevel@tonic-gate pxu_p->pec_config_state = config_state;
26980Sstevel@tonic-gate for (i = 0; i < PEC_KEYS; i++) {
26991772Sjl139090 if ((pec_config_state_regs[i].chip == PX_CHIP_TYPE(pxu_p)) ||
27001772Sjl139090 (pec_config_state_regs[i].chip == PX_CHIP_UNIDENTIFIED)) {
27011772Sjl139090 pxu_p->pec_config_state[i] =
27021772Sjl139090 CSR_XR((caddr_t)dev_hdl,
27031772Sjl139090 pec_config_state_regs[i].reg);
27046953Sanbui }
27050Sstevel@tonic-gate }
27060Sstevel@tonic-gate
27070Sstevel@tonic-gate /* Save the MMU configuration states */
27080Sstevel@tonic-gate pxu_p->mmu_config_state = pxu_p->pec_config_state + PEC_KEYS;
27090Sstevel@tonic-gate for (i = 0; i < MMU_KEYS; i++) {
27100Sstevel@tonic-gate pxu_p->mmu_config_state[i] =
27110Sstevel@tonic-gate CSR_XR((caddr_t)dev_hdl, mmu_config_state_regs[i]);
27120Sstevel@tonic-gate }
27130Sstevel@tonic-gate
27140Sstevel@tonic-gate /* Save the interrupt mapping registers */
27150Sstevel@tonic-gate pxu_p->ib_intr_map = pxu_p->mmu_config_state + MMU_KEYS;
27160Sstevel@tonic-gate for (i = 0; i < INTERRUPT_MAPPING_ENTRIES; i++) {
27170Sstevel@tonic-gate pxu_p->ib_intr_map[i] =
27180Sstevel@tonic-gate CSRA_XR((caddr_t)dev_hdl, INTERRUPT_MAPPING, i);
27190Sstevel@tonic-gate }
27200Sstevel@tonic-gate
27210Sstevel@tonic-gate /* Save the IB configuration states */
27220Sstevel@tonic-gate pxu_p->ib_config_state = pxu_p->ib_intr_map + INTERRUPT_MAPPING_ENTRIES;
27230Sstevel@tonic-gate for (i = 0; i < IB_KEYS; i++) {
27240Sstevel@tonic-gate pxu_p->ib_config_state[i] =
27250Sstevel@tonic-gate CSR_XR((caddr_t)dev_hdl, ib_config_state_regs[i]);
27260Sstevel@tonic-gate }
27270Sstevel@tonic-gate
27280Sstevel@tonic-gate return (H_EOK);
27290Sstevel@tonic-gate }
27300Sstevel@tonic-gate
27310Sstevel@tonic-gate void
hvio_resume(devhandle_t dev_hdl,devino_t devino,pxu_t * pxu_p)27320Sstevel@tonic-gate hvio_resume(devhandle_t dev_hdl, devino_t devino, pxu_t *pxu_p)
27330Sstevel@tonic-gate {
27340Sstevel@tonic-gate int total_size;
27350Sstevel@tonic-gate sysino_t sysino;
27360Sstevel@tonic-gate int i;
27377124Sanbui uint64_t ret;
27380Sstevel@tonic-gate
27390Sstevel@tonic-gate /* Make sure that suspend actually did occur */
27400Sstevel@tonic-gate if (!pxu_p->pec_config_state) {
27410Sstevel@tonic-gate return;
27420Sstevel@tonic-gate }
27430Sstevel@tonic-gate
27440Sstevel@tonic-gate /* Restore IB configuration states */
27450Sstevel@tonic-gate for (i = 0; i < IB_KEYS; i++) {
27460Sstevel@tonic-gate CSR_XS((caddr_t)dev_hdl, ib_config_state_regs[i],
27470Sstevel@tonic-gate pxu_p->ib_config_state[i]);
27480Sstevel@tonic-gate }
27490Sstevel@tonic-gate
27500Sstevel@tonic-gate /*
27510Sstevel@tonic-gate * Restore the interrupt mapping registers
27520Sstevel@tonic-gate * And make sure the intrs are idle.
27530Sstevel@tonic-gate */
27540Sstevel@tonic-gate for (i = 0; i < INTERRUPT_MAPPING_ENTRIES; i++) {
27550Sstevel@tonic-gate CSRA_FS((caddr_t)dev_hdl, INTERRUPT_CLEAR, i,
27560Sstevel@tonic-gate ENTRIES_INT_STATE, INTERRUPT_IDLE_STATE);
27570Sstevel@tonic-gate CSRA_XS((caddr_t)dev_hdl, INTERRUPT_MAPPING, i,
27580Sstevel@tonic-gate pxu_p->ib_intr_map[i]);
27590Sstevel@tonic-gate }
27600Sstevel@tonic-gate
27610Sstevel@tonic-gate /* Restore MMU configuration states */
27620Sstevel@tonic-gate /* Clear the cache. */
27630Sstevel@tonic-gate CSR_XS((caddr_t)dev_hdl, MMU_TTE_CACHE_INVALIDATE, -1ull);
27640Sstevel@tonic-gate
27650Sstevel@tonic-gate for (i = 0; i < MMU_KEYS; i++) {
27660Sstevel@tonic-gate CSR_XS((caddr_t)dev_hdl, mmu_config_state_regs[i],
27670Sstevel@tonic-gate pxu_p->mmu_config_state[i]);
27680Sstevel@tonic-gate }
27690Sstevel@tonic-gate
27700Sstevel@tonic-gate /* Restore PEC configuration states */
27710Sstevel@tonic-gate /* Make sure all reset bits are low until error is detected */
27720Sstevel@tonic-gate CSR_XS((caddr_t)dev_hdl, LPU_RESET, 0ull);
27730Sstevel@tonic-gate
27740Sstevel@tonic-gate for (i = 0; i < PEC_KEYS; i++) {
27751772Sjl139090 if ((pec_config_state_regs[i].chip == PX_CHIP_TYPE(pxu_p)) ||
27761772Sjl139090 (pec_config_state_regs[i].chip == PX_CHIP_UNIDENTIFIED)) {
27771772Sjl139090 CSR_XS((caddr_t)dev_hdl, pec_config_state_regs[i].reg,
27781772Sjl139090 pxu_p->pec_config_state[i]);
27796953Sanbui }
27800Sstevel@tonic-gate }
27810Sstevel@tonic-gate
27820Sstevel@tonic-gate /* Enable PCI-E interrupt */
27837124Sanbui if ((ret = hvio_intr_devino_to_sysino(dev_hdl, pxu_p, devino,
27847124Sanbui &sysino)) != H_EOK) {
27857124Sanbui cmn_err(CE_WARN,
27867124Sanbui "hvio_resume: hvio_intr_devino_to_sysino failed, "
27877124Sanbui "ret 0x%lx", ret);
27887124Sanbui }
27897124Sanbui
27907124Sanbui if ((ret = hvio_intr_setstate(dev_hdl, sysino, INTR_IDLE_STATE))
27917124Sanbui != H_EOK) {
27927124Sanbui cmn_err(CE_WARN,
27937124Sanbui "hvio_resume: hvio_intr_setstate failed, "
27947124Sanbui "ret 0x%lx", ret);
27957124Sanbui }
27960Sstevel@tonic-gate
27970Sstevel@tonic-gate total_size = PEC_SIZE + MMU_SIZE + IB_SIZE + IB_MAP_SIZE;
27980Sstevel@tonic-gate kmem_free(pxu_p->pec_config_state, total_size);
27990Sstevel@tonic-gate
28000Sstevel@tonic-gate pxu_p->pec_config_state = NULL;
28010Sstevel@tonic-gate pxu_p->mmu_config_state = NULL;
28020Sstevel@tonic-gate pxu_p->ib_config_state = NULL;
28030Sstevel@tonic-gate pxu_p->ib_intr_map = NULL;
28040Sstevel@tonic-gate
28050Sstevel@tonic-gate msiq_resume(dev_hdl, pxu_p);
28060Sstevel@tonic-gate }
28070Sstevel@tonic-gate
28080Sstevel@tonic-gate uint64_t
hvio_cb_suspend(devhandle_t dev_hdl,pxu_t * pxu_p)28090Sstevel@tonic-gate hvio_cb_suspend(devhandle_t dev_hdl, pxu_t *pxu_p)
28100Sstevel@tonic-gate {
28111772Sjl139090 uint64_t *config_state, *cb_regs;
28121772Sjl139090 int i, cb_size, cb_keys;
28131772Sjl139090
28141772Sjl139090 switch (PX_CHIP_TYPE(pxu_p)) {
28151772Sjl139090 case PX_CHIP_OBERON:
28161772Sjl139090 cb_size = UBC_SIZE;
28171772Sjl139090 cb_keys = UBC_KEYS;
28181772Sjl139090 cb_regs = ubc_config_state_regs;
28191772Sjl139090 break;
28201772Sjl139090 case PX_CHIP_FIRE:
28211772Sjl139090 cb_size = JBC_SIZE;
28221772Sjl139090 cb_keys = JBC_KEYS;
28231772Sjl139090 cb_regs = jbc_config_state_regs;
28241772Sjl139090 break;
28251772Sjl139090 default:
28261772Sjl139090 DBG(DBG_CB, NULL, "hvio_cb_suspend - unknown chip type: 0x%x\n",
28271772Sjl139090 PX_CHIP_TYPE(pxu_p));
28281772Sjl139090 break;
28291772Sjl139090 }
28301772Sjl139090
28311772Sjl139090 config_state = kmem_zalloc(cb_size, KM_NOSLEEP);
28320Sstevel@tonic-gate
28330Sstevel@tonic-gate if (config_state == NULL) {
28340Sstevel@tonic-gate return (H_EIO);
28350Sstevel@tonic-gate }
28360Sstevel@tonic-gate
28370Sstevel@tonic-gate /* Save the configuration states */
28380Sstevel@tonic-gate pxu_p->xcb_config_state = config_state;
28391772Sjl139090 for (i = 0; i < cb_keys; i++) {
28400Sstevel@tonic-gate pxu_p->xcb_config_state[i] =
28411772Sjl139090 CSR_XR((caddr_t)dev_hdl, cb_regs[i]);
28420Sstevel@tonic-gate }
28430Sstevel@tonic-gate
28440Sstevel@tonic-gate return (H_EOK);
28450Sstevel@tonic-gate }
28460Sstevel@tonic-gate
28470Sstevel@tonic-gate void
hvio_cb_resume(devhandle_t pci_dev_hdl,devhandle_t xbus_dev_hdl,devino_t devino,pxu_t * pxu_p)28480Sstevel@tonic-gate hvio_cb_resume(devhandle_t pci_dev_hdl, devhandle_t xbus_dev_hdl,
28490Sstevel@tonic-gate devino_t devino, pxu_t *pxu_p)
28500Sstevel@tonic-gate {
28511772Sjl139090 sysino_t sysino;
28521772Sjl139090 uint64_t *cb_regs;
28531772Sjl139090 int i, cb_size, cb_keys;
28547124Sanbui uint64_t ret;
28551772Sjl139090
28561772Sjl139090 switch (PX_CHIP_TYPE(pxu_p)) {
28571772Sjl139090 case PX_CHIP_OBERON:
28581772Sjl139090 cb_size = UBC_SIZE;
28591772Sjl139090 cb_keys = UBC_KEYS;
28601772Sjl139090 cb_regs = ubc_config_state_regs;
28611772Sjl139090 /*
28621772Sjl139090 * No reason to have any reset bits high until an error is
28631772Sjl139090 * detected on the link.
28641772Sjl139090 */
28651772Sjl139090 CSR_XS((caddr_t)xbus_dev_hdl, UBC_ERROR_STATUS_CLEAR, -1ull);
28661772Sjl139090 break;
28671772Sjl139090 case PX_CHIP_FIRE:
28681772Sjl139090 cb_size = JBC_SIZE;
28691772Sjl139090 cb_keys = JBC_KEYS;
28701772Sjl139090 cb_regs = jbc_config_state_regs;
28711772Sjl139090 /*
28721772Sjl139090 * No reason to have any reset bits high until an error is
28731772Sjl139090 * detected on the link.
28741772Sjl139090 */
28751772Sjl139090 CSR_XS((caddr_t)xbus_dev_hdl, JBC_ERROR_STATUS_CLEAR, -1ull);
28761772Sjl139090 break;
28771772Sjl139090 default:
28781772Sjl139090 DBG(DBG_CB, NULL, "hvio_cb_resume - unknown chip type: 0x%x\n",
28791772Sjl139090 PX_CHIP_TYPE(pxu_p));
28801772Sjl139090 break;
28811772Sjl139090 }
28820Sstevel@tonic-gate
28830Sstevel@tonic-gate ASSERT(pxu_p->xcb_config_state);
28840Sstevel@tonic-gate
28850Sstevel@tonic-gate /* Restore the configuration states */
28861772Sjl139090 for (i = 0; i < cb_keys; i++) {
28871772Sjl139090 CSR_XS((caddr_t)xbus_dev_hdl, cb_regs[i],
28880Sstevel@tonic-gate pxu_p->xcb_config_state[i]);
28890Sstevel@tonic-gate }
28900Sstevel@tonic-gate
28910Sstevel@tonic-gate /* Enable XBC interrupt */
28927124Sanbui if ((ret = hvio_intr_devino_to_sysino(pci_dev_hdl, pxu_p, devino,
28937124Sanbui &sysino)) != H_EOK) {
28947124Sanbui cmn_err(CE_WARN,
28957124Sanbui "hvio_cb_resume: hvio_intr_devino_to_sysino failed, "
28967124Sanbui "ret 0x%lx", ret);
28977124Sanbui }
28987124Sanbui
28997124Sanbui if ((ret = hvio_intr_setstate(pci_dev_hdl, sysino, INTR_IDLE_STATE))
29007124Sanbui != H_EOK) {
29017124Sanbui cmn_err(CE_WARN,
29027124Sanbui "hvio_cb_resume: hvio_intr_setstate failed, "
29037124Sanbui "ret 0x%lx", ret);
29047124Sanbui }
29050Sstevel@tonic-gate
29061772Sjl139090 kmem_free(pxu_p->xcb_config_state, cb_size);
29070Sstevel@tonic-gate
29080Sstevel@tonic-gate pxu_p->xcb_config_state = NULL;
29090Sstevel@tonic-gate }
29100Sstevel@tonic-gate
29110Sstevel@tonic-gate static uint64_t
msiq_suspend(devhandle_t dev_hdl,pxu_t * pxu_p)29120Sstevel@tonic-gate msiq_suspend(devhandle_t dev_hdl, pxu_t *pxu_p)
29130Sstevel@tonic-gate {
29140Sstevel@tonic-gate size_t bufsz;
29150Sstevel@tonic-gate volatile uint64_t *cur_p;
29160Sstevel@tonic-gate int i;
29170Sstevel@tonic-gate
29180Sstevel@tonic-gate bufsz = MSIQ_STATE_SIZE + MSIQ_MAPPING_SIZE + MSIQ_OTHER_SIZE;
29190Sstevel@tonic-gate if ((pxu_p->msiq_config_state = kmem_zalloc(bufsz, KM_NOSLEEP)) ==
29200Sstevel@tonic-gate NULL)
29210Sstevel@tonic-gate return (H_EIO);
29220Sstevel@tonic-gate
29230Sstevel@tonic-gate cur_p = pxu_p->msiq_config_state;
29240Sstevel@tonic-gate
29250Sstevel@tonic-gate /* Save each EQ state */
29260Sstevel@tonic-gate for (i = 0; i < EVENT_QUEUE_STATE_ENTRIES; i++, cur_p++)
29270Sstevel@tonic-gate *cur_p = CSRA_XR((caddr_t)dev_hdl, EVENT_QUEUE_STATE, i);
29280Sstevel@tonic-gate
29290Sstevel@tonic-gate /* Save MSI mapping registers */
29300Sstevel@tonic-gate for (i = 0; i < MSI_MAPPING_ENTRIES; i++, cur_p++)
29310Sstevel@tonic-gate *cur_p = CSRA_XR((caddr_t)dev_hdl, MSI_MAPPING, i);
29320Sstevel@tonic-gate
29330Sstevel@tonic-gate /* Save all other MSIQ registers */
29340Sstevel@tonic-gate for (i = 0; i < MSIQ_OTHER_KEYS; i++, cur_p++)
29350Sstevel@tonic-gate *cur_p = CSR_XR((caddr_t)dev_hdl, msiq_config_other_regs[i]);
29360Sstevel@tonic-gate return (H_EOK);
29370Sstevel@tonic-gate }
29380Sstevel@tonic-gate
29390Sstevel@tonic-gate static void
msiq_resume(devhandle_t dev_hdl,pxu_t * pxu_p)29400Sstevel@tonic-gate msiq_resume(devhandle_t dev_hdl, pxu_t *pxu_p)
29410Sstevel@tonic-gate {
29420Sstevel@tonic-gate size_t bufsz;
29431046Sjchu uint64_t *cur_p, state;
29440Sstevel@tonic-gate int i;
29457124Sanbui uint64_t ret;
29460Sstevel@tonic-gate
29470Sstevel@tonic-gate bufsz = MSIQ_STATE_SIZE + MSIQ_MAPPING_SIZE + MSIQ_OTHER_SIZE;
29480Sstevel@tonic-gate cur_p = pxu_p->msiq_config_state;
29490Sstevel@tonic-gate /*
29500Sstevel@tonic-gate * Initialize EQ base address register and
29510Sstevel@tonic-gate * Interrupt Mondo Data 0 register.
29520Sstevel@tonic-gate */
29537124Sanbui if ((ret = hvio_msiq_init(dev_hdl, pxu_p)) != H_EOK) {
29547124Sanbui cmn_err(CE_WARN,
29557124Sanbui "msiq_resume: hvio_msiq_init failed, "
29567124Sanbui "ret 0x%lx", ret);
29577124Sanbui }
29580Sstevel@tonic-gate
29590Sstevel@tonic-gate /* Restore EQ states */
29600Sstevel@tonic-gate for (i = 0; i < EVENT_QUEUE_STATE_ENTRIES; i++, cur_p++) {
29611046Sjchu state = (*cur_p) & EVENT_QUEUE_STATE_ENTRIES_STATE_MASK;
29621046Sjchu if ((state == EQ_ACTIVE_STATE) || (state == EQ_ERROR_STATE))
29630Sstevel@tonic-gate CSRA_BS((caddr_t)dev_hdl, EVENT_QUEUE_CONTROL_SET,
29640Sstevel@tonic-gate i, ENTRIES_EN);
29650Sstevel@tonic-gate }
29660Sstevel@tonic-gate
29670Sstevel@tonic-gate /* Restore MSI mapping */
29680Sstevel@tonic-gate for (i = 0; i < MSI_MAPPING_ENTRIES; i++, cur_p++)
29690Sstevel@tonic-gate CSRA_XS((caddr_t)dev_hdl, MSI_MAPPING, i, *cur_p);
29700Sstevel@tonic-gate
29710Sstevel@tonic-gate /*
29720Sstevel@tonic-gate * Restore all other registers. MSI 32 bit address and
29730Sstevel@tonic-gate * MSI 64 bit address are restored as part of this.
29740Sstevel@tonic-gate */
29750Sstevel@tonic-gate for (i = 0; i < MSIQ_OTHER_KEYS; i++, cur_p++)
29760Sstevel@tonic-gate CSR_XS((caddr_t)dev_hdl, msiq_config_other_regs[i], *cur_p);
29770Sstevel@tonic-gate
29780Sstevel@tonic-gate kmem_free(pxu_p->msiq_config_state, bufsz);
29790Sstevel@tonic-gate pxu_p->msiq_config_state = NULL;
29800Sstevel@tonic-gate }
29810Sstevel@tonic-gate
29820Sstevel@tonic-gate /*
29830Sstevel@tonic-gate * sends PME_Turn_Off message to put the link in L2/L3 ready state.
29840Sstevel@tonic-gate * called by px_goto_l23ready.
29850Sstevel@tonic-gate * returns DDI_SUCCESS or DDI_FAILURE
29860Sstevel@tonic-gate */
29870Sstevel@tonic-gate int
px_send_pme_turnoff(caddr_t csr_base)29880Sstevel@tonic-gate px_send_pme_turnoff(caddr_t csr_base)
29890Sstevel@tonic-gate {
29900Sstevel@tonic-gate volatile uint64_t reg;
29910Sstevel@tonic-gate
29920Sstevel@tonic-gate reg = CSR_XR(csr_base, TLU_PME_TURN_OFF_GENERATE);
29930Sstevel@tonic-gate /* If already pending, return failure */
29940Sstevel@tonic-gate if (reg & (1ull << TLU_PME_TURN_OFF_GENERATE_PTO)) {
2995118Sjchu DBG(DBG_PWR, NULL, "send_pme_turnoff: pending PTO bit "
2996118Sjchu "tlu_pme_turn_off_generate = %x\n", reg);
29970Sstevel@tonic-gate return (DDI_FAILURE);
29980Sstevel@tonic-gate }
299927Sjchu
30000Sstevel@tonic-gate /* write to PME_Turn_off reg to boradcast */
30010Sstevel@tonic-gate reg |= (1ull << TLU_PME_TURN_OFF_GENERATE_PTO);
30020Sstevel@tonic-gate CSR_XS(csr_base, TLU_PME_TURN_OFF_GENERATE, reg);
3003118Sjchu
30040Sstevel@tonic-gate return (DDI_SUCCESS);
30050Sstevel@tonic-gate }
3006118Sjchu
3007118Sjchu /*
3008118Sjchu * Checks for link being in L1idle state.
3009118Sjchu * Returns
3010118Sjchu * DDI_SUCCESS - if the link is in L1idle
3011118Sjchu * DDI_FAILURE - if the link is not in L1idle
3012118Sjchu */
3013118Sjchu int
px_link_wait4l1idle(caddr_t csr_base)3014118Sjchu px_link_wait4l1idle(caddr_t csr_base)
3015118Sjchu {
3016118Sjchu uint8_t ltssm_state;
3017118Sjchu int ntries = px_max_l1_tries;
3018118Sjchu
3019118Sjchu while (ntries > 0) {
3020118Sjchu ltssm_state = CSR_FR(csr_base, LPU_LTSSM_STATUS1, LTSSM_STATE);
3021118Sjchu if (ltssm_state == LPU_LTSSM_L1_IDLE || (--ntries <= 0))
3022118Sjchu break;
3023118Sjchu delay(1);
3024118Sjchu }
3025118Sjchu DBG(DBG_PWR, NULL, "check_for_l1idle: ltssm_state %x\n", ltssm_state);
3026118Sjchu return ((ltssm_state == LPU_LTSSM_L1_IDLE) ? DDI_SUCCESS : DDI_FAILURE);
3027118Sjchu }
3028118Sjchu
3029118Sjchu /*
3030118Sjchu * Tranisition the link to L0, after it is down.
3031118Sjchu */
3032118Sjchu int
px_link_retrain(caddr_t csr_base)3033118Sjchu px_link_retrain(caddr_t csr_base)
3034118Sjchu {
3035118Sjchu volatile uint64_t reg;
3036118Sjchu
3037118Sjchu reg = CSR_XR(csr_base, TLU_CONTROL);
3038118Sjchu if (!(reg & (1ull << TLU_REMAIN_DETECT_QUIET))) {
3039118Sjchu DBG(DBG_PWR, NULL, "retrain_link: detect.quiet bit not set\n");
3040118Sjchu return (DDI_FAILURE);
3041118Sjchu }
3042118Sjchu
3043118Sjchu /* Clear link down bit in TLU Other Event Clear Status Register. */
3044118Sjchu CSR_BS(csr_base, TLU_OTHER_EVENT_STATUS_CLEAR, LDN_P);
3045118Sjchu
3046118Sjchu /* Clear Drain bit in TLU Status Register */
3047118Sjchu CSR_BS(csr_base, TLU_STATUS, DRAIN);
3048118Sjchu
3049118Sjchu /* Clear Remain in Detect.Quiet bit in TLU Control Register */
3050118Sjchu reg = CSR_XR(csr_base, TLU_CONTROL);
3051118Sjchu reg &= ~(1ull << TLU_REMAIN_DETECT_QUIET);
3052118Sjchu CSR_XS(csr_base, TLU_CONTROL, reg);
3053118Sjchu
3054118Sjchu return (DDI_SUCCESS);
3055118Sjchu }
3056118Sjchu
3057118Sjchu void
px_enable_detect_quiet(caddr_t csr_base)3058118Sjchu px_enable_detect_quiet(caddr_t csr_base)
3059118Sjchu {
3060118Sjchu volatile uint64_t tlu_ctrl;
3061118Sjchu
3062118Sjchu tlu_ctrl = CSR_XR(csr_base, TLU_CONTROL);
3063118Sjchu tlu_ctrl |= (1ull << TLU_REMAIN_DETECT_QUIET);
3064118Sjchu CSR_XS(csr_base, TLU_CONTROL, tlu_ctrl);
3065118Sjchu }
30661772Sjl139090
30671772Sjl139090 static uint_t
oberon_hp_pwron(caddr_t csr_base)30681772Sjl139090 oberon_hp_pwron(caddr_t csr_base)
30691772Sjl139090 {
30701772Sjl139090 volatile uint64_t reg;
30712587Spjha boolean_t link_retry, link_up;
30722587Spjha int loop, i;
30731772Sjl139090
30741786Sjj156685 DBG(DBG_HP, NULL, "oberon_hp_pwron the slot\n");
30751772Sjl139090
30761772Sjl139090 /* Check Leaf Reset status */
30771772Sjl139090 reg = CSR_XR(csr_base, ILU_ERROR_LOG_ENABLE);
30781772Sjl139090 if (!(reg & (1ull << ILU_ERROR_LOG_ENABLE_SPARE3))) {
30791786Sjj156685 DBG(DBG_HP, NULL, "oberon_hp_pwron fails: leaf not reset\n");
30801772Sjl139090 goto fail;
30811772Sjl139090 }
30821772Sjl139090
30833485Spjha /* Check HP Capable */
30843485Spjha if (!CSR_BR(csr_base, TLU_SLOT_CAPABILITIES, HP)) {
30853485Spjha DBG(DBG_HP, NULL, "oberon_hp_pwron fails: leaf not "
30866953Sanbui "hotplugable\n");
30873485Spjha goto fail;
30883485Spjha }
30893485Spjha
30901772Sjl139090 /* Check Slot status */
30911772Sjl139090 reg = CSR_XR(csr_base, TLU_SLOT_STATUS);
30921772Sjl139090 if (!(reg & (1ull << TLU_SLOT_STATUS_PSD)) ||
30931983Sjj156685 (reg & (1ull << TLU_SLOT_STATUS_MRLS))) {
30941786Sjj156685 DBG(DBG_HP, NULL, "oberon_hp_pwron fails: slot status %lx\n",
30951772Sjl139090 reg);
30961772Sjl139090 goto fail;
30971772Sjl139090 }
30981772Sjl139090
30991772Sjl139090 /* Blink power LED, this is done from pciehpc already */
31001772Sjl139090
31011772Sjl139090 /* Turn on slot power */
31021772Sjl139090 CSR_BS(csr_base, HOTPLUG_CONTROL, PWREN);
31031772Sjl139090
31041983Sjj156685 /* power fault detection */
31051983Sjj156685 delay(drv_usectohz(25000));
31061983Sjj156685 CSR_BS(csr_base, TLU_SLOT_STATUS, PWFD);
31071983Sjj156685 CSR_BC(csr_base, HOTPLUG_CONTROL, PWREN);
31081983Sjj156685
31091772Sjl139090 /* wait to check power state */
31101772Sjl139090 delay(drv_usectohz(25000));
31111772Sjl139090
31121983Sjj156685 if (!CSR_BR(csr_base, TLU_SLOT_STATUS, PWFD)) {
31131850Sjj156685 DBG(DBG_HP, NULL, "oberon_hp_pwron fails: power fault\n");
31141850Sjj156685 goto fail1;
31151850Sjj156685 }
31161850Sjj156685
31171850Sjj156685 /* power is good */
31181983Sjj156685 CSR_BS(csr_base, HOTPLUG_CONTROL, PWREN);
31191983Sjj156685
31201983Sjj156685 delay(drv_usectohz(25000));
31211983Sjj156685 CSR_BS(csr_base, TLU_SLOT_STATUS, PWFD);
31221850Sjj156685 CSR_BS(csr_base, TLU_SLOT_CONTROL, PWFDEN);
31231850Sjj156685
31241850Sjj156685 /* Turn on slot clock */
31251850Sjj156685 CSR_BS(csr_base, HOTPLUG_CONTROL, CLKEN);
31261850Sjj156685
31272587Spjha link_up = B_FALSE;
31282587Spjha link_retry = B_FALSE;
31292587Spjha
31302587Spjha for (loop = 0; (loop < link_retry_count) && (link_up == B_FALSE);
31316953Sanbui loop++) {
31322587Spjha if (link_retry == B_TRUE) {
31332587Spjha DBG(DBG_HP, NULL, "oberon_hp_pwron : retry link loop "
31346953Sanbui "%d\n", loop);
31352587Spjha CSR_BS(csr_base, TLU_CONTROL, DRN_TR_DIS);
31362587Spjha CSR_XS(csr_base, FLP_PORT_CONTROL, 0x1);
31372587Spjha delay(drv_usectohz(10000));
31382587Spjha CSR_BC(csr_base, TLU_CONTROL, DRN_TR_DIS);
31392587Spjha CSR_BS(csr_base, TLU_DIAGNOSTIC, IFC_DIS);
31402587Spjha CSR_BC(csr_base, HOTPLUG_CONTROL, N_PERST);
31412587Spjha delay(drv_usectohz(50000));
31422587Spjha }
31432587Spjha
31442587Spjha /* Release PCI-E Reset */
31452587Spjha delay(drv_usectohz(wait_perst));
31462587Spjha CSR_BS(csr_base, HOTPLUG_CONTROL, N_PERST);
31472587Spjha
31482587Spjha /*
31492587Spjha * Open events' mask
31502587Spjha * This should be done from pciehpc already
31512587Spjha */
31522587Spjha
31532587Spjha /* Enable PCIE port */
31542587Spjha delay(drv_usectohz(wait_enable_port));
31552587Spjha CSR_BS(csr_base, TLU_CONTROL, DRN_TR_DIS);
31562587Spjha CSR_XS(csr_base, FLP_PORT_CONTROL, 0x20);
31572587Spjha
31582587Spjha /* wait for the link up */
31596953Sanbui /* BEGIN CSTYLED */
31602587Spjha for (i = 0; (i < 2) && (link_up == B_FALSE); i++) {
31613485Spjha delay(drv_usectohz(link_status_check));
31622587Spjha reg = CSR_XR(csr_base, DLU_LINK_LAYER_STATUS);
31632587Spjha
316410923SEvan.Yan@Sun.COM if ((((reg >> DLU_LINK_LAYER_STATUS_INIT_FC_SM_STS) &
316510923SEvan.Yan@Sun.COM DLU_LINK_LAYER_STATUS_INIT_FC_SM_STS_MASK) ==
316610923SEvan.Yan@Sun.COM DLU_LINK_LAYER_STATUS_INIT_FC_SM_STS_FC_INIT_DONE) &&
316710923SEvan.Yan@Sun.COM (reg & (1ull << DLU_LINK_LAYER_STATUS_DLUP_STS)) &&
316810923SEvan.Yan@Sun.COM ((reg &
316910923SEvan.Yan@Sun.COM DLU_LINK_LAYER_STATUS_LNK_STATE_MACH_STS_MASK) ==
317010923SEvan.Yan@Sun.COM DLU_LINK_LAYER_STATUS_LNK_STATE_MACH_STS_DL_ACTIVE)) {
317110923SEvan.Yan@Sun.COM DBG(DBG_HP, NULL, "oberon_hp_pwron : "
317210923SEvan.Yan@Sun.COM "link is up\n");
317310923SEvan.Yan@Sun.COM link_up = B_TRUE;
317410923SEvan.Yan@Sun.COM } else
31752587Spjha link_retry = B_TRUE;
317610923SEvan.Yan@Sun.COM
31772587Spjha }
31786953Sanbui /* END CSTYLED */
31792587Spjha }
31802587Spjha
31812587Spjha if (link_up == B_FALSE) {
31822587Spjha DBG(DBG_HP, NULL, "oberon_hp_pwron fails to enable "
31832587Spjha "PCI-E port\n");
31842587Spjha goto fail2;
31852587Spjha }
31862587Spjha
31872587Spjha /* link is up */
31882587Spjha CSR_BC(csr_base, TLU_DIAGNOSTIC, IFC_DIS);
31892587Spjha CSR_BS(csr_base, FLP_PORT_ACTIVE_STATUS, TRAIN_ERROR);
31902587Spjha CSR_BS(csr_base, TLU_UNCORRECTABLE_ERROR_STATUS_CLEAR, TE_P);
31912587Spjha CSR_BS(csr_base, TLU_UNCORRECTABLE_ERROR_STATUS_CLEAR, TE_S);
31922587Spjha CSR_BC(csr_base, TLU_CONTROL, DRN_TR_DIS);
31932587Spjha
31942587Spjha /* Restore LUP/LDN */
31952587Spjha reg = CSR_XR(csr_base, TLU_OTHER_EVENT_LOG_ENABLE);
31962587Spjha if (px_tlu_oe_log_mask & (1ull << TLU_OTHER_EVENT_STATUS_SET_LUP_P))
31972587Spjha reg |= 1ull << TLU_OTHER_EVENT_STATUS_SET_LUP_P;
31982587Spjha if (px_tlu_oe_log_mask & (1ull << TLU_OTHER_EVENT_STATUS_SET_LDN_P))
31992587Spjha reg |= 1ull << TLU_OTHER_EVENT_STATUS_SET_LDN_P;
32002587Spjha if (px_tlu_oe_log_mask & (1ull << TLU_OTHER_EVENT_STATUS_SET_LUP_S))
32012587Spjha reg |= 1ull << TLU_OTHER_EVENT_STATUS_SET_LUP_S;
32022587Spjha if (px_tlu_oe_log_mask & (1ull << TLU_OTHER_EVENT_STATUS_SET_LDN_S))
32032587Spjha reg |= 1ull << TLU_OTHER_EVENT_STATUS_SET_LDN_S;
32042587Spjha CSR_XS(csr_base, TLU_OTHER_EVENT_LOG_ENABLE, reg);
32051850Sjj156685
32061850Sjj156685 /*
32071850Sjj156685 * Initialize Leaf
32081850Sjj156685 * SPLS = 00b, SPLV = 11001b, i.e. 25W
32091850Sjj156685 */
32101850Sjj156685 reg = CSR_XR(csr_base, TLU_SLOT_CAPABILITIES);
32111850Sjj156685 reg &= ~(TLU_SLOT_CAPABILITIES_SPLS_MASK <<
32121850Sjj156685 TLU_SLOT_CAPABILITIES_SPLS);
32131850Sjj156685 reg &= ~(TLU_SLOT_CAPABILITIES_SPLV_MASK <<
32143485Spjha TLU_SLOT_CAPABILITIES_SPLV);
32153485Spjha reg |= (0x19 << TLU_SLOT_CAPABILITIES_SPLV);
32161850Sjj156685 CSR_XS(csr_base, TLU_SLOT_CAPABILITIES, reg);
32171850Sjj156685
32181850Sjj156685 /* Turn on Power LED */
32191850Sjj156685 reg = CSR_XR(csr_base, TLU_SLOT_CONTROL);
32201850Sjj156685 reg &= ~PCIE_SLOTCTL_PWR_INDICATOR_MASK;
32211850Sjj156685 reg = pcie_slotctl_pwr_indicator_set(reg,
32221850Sjj156685 PCIE_SLOTCTL_INDICATOR_STATE_ON);
32231850Sjj156685 CSR_XS(csr_base, TLU_SLOT_CONTROL, reg);
32241850Sjj156685
32251850Sjj156685 /* Notify to SCF */
32261983Sjj156685 if (CSR_BR(csr_base, HOTPLUG_CONTROL, SLOTPON))
32271983Sjj156685 CSR_BC(csr_base, HOTPLUG_CONTROL, SLOTPON);
32281983Sjj156685 else
32291983Sjj156685 CSR_BS(csr_base, HOTPLUG_CONTROL, SLOTPON);
32301983Sjj156685
32314395Sgovinda /* Wait for one second */
32324395Sgovinda delay(drv_usectohz(1000000));
32334395Sgovinda
32341772Sjl139090 return (DDI_SUCCESS);
32351772Sjl139090
32361850Sjj156685 fail2:
32371850Sjj156685 /* Link up is failed */
32381850Sjj156685 CSR_BS(csr_base, FLP_PORT_CONTROL, PORT_DIS);
32391850Sjj156685 CSR_BC(csr_base, HOTPLUG_CONTROL, N_PERST);
32401850Sjj156685 delay(drv_usectohz(150));
32411850Sjj156685
32421850Sjj156685 CSR_BC(csr_base, HOTPLUG_CONTROL, CLKEN);
32431850Sjj156685 delay(drv_usectohz(100));
32441850Sjj156685
32451850Sjj156685 fail1:
32461850Sjj156685 CSR_BC(csr_base, TLU_SLOT_CONTROL, PWFDEN);
32471850Sjj156685
32481850Sjj156685 CSR_BC(csr_base, HOTPLUG_CONTROL, PWREN);
32491850Sjj156685
32501850Sjj156685 reg = CSR_XR(csr_base, TLU_SLOT_CONTROL);
32511850Sjj156685 reg &= ~PCIE_SLOTCTL_PWR_INDICATOR_MASK;
32521850Sjj156685 reg = pcie_slotctl_pwr_indicator_set(reg,
32531850Sjj156685 PCIE_SLOTCTL_INDICATOR_STATE_OFF);
32541850Sjj156685 CSR_XS(csr_base, TLU_SLOT_CONTROL, reg);
32551850Sjj156685
32561850Sjj156685 CSR_BC(csr_base, TLU_SLOT_STATUS, PWFD);
32571850Sjj156685
32581772Sjl139090 fail:
32592840Scarlsonj return ((uint_t)DDI_FAILURE);
32601772Sjl139090 }
32611772Sjl139090
32624395Sgovinda hrtime_t oberon_leaf_reset_timeout = 120ll * NANOSEC; /* 120 seconds */
32634395Sgovinda
32641772Sjl139090 static uint_t
oberon_hp_pwroff(caddr_t csr_base)32651772Sjl139090 oberon_hp_pwroff(caddr_t csr_base)
32661772Sjl139090 {
32671772Sjl139090 volatile uint64_t reg;
32682044Sjj156685 volatile uint64_t reg_tluue, reg_tluce;
32694395Sgovinda hrtime_t start_time, end_time;
32701772Sjl139090
32711786Sjj156685 DBG(DBG_HP, NULL, "oberon_hp_pwroff the slot\n");
32721772Sjl139090
32731772Sjl139090 /* Blink power LED, this is done from pciehpc already */
32741772Sjl139090
32751772Sjl139090 /* Clear Slot Event */
32761772Sjl139090 CSR_BS(csr_base, TLU_SLOT_STATUS, PSDC);
32771983Sjj156685 CSR_BS(csr_base, TLU_SLOT_STATUS, PWFD);
32781772Sjl139090
32791772Sjl139090 /* DRN_TR_DIS on */
32801772Sjl139090 CSR_BS(csr_base, TLU_CONTROL, DRN_TR_DIS);
32811983Sjj156685 delay(drv_usectohz(10000));
32821772Sjl139090
32832587Spjha /* Disable LUP/LDN */
32842587Spjha reg = CSR_XR(csr_base, TLU_OTHER_EVENT_LOG_ENABLE);
32852587Spjha reg &= ~((1ull << TLU_OTHER_EVENT_STATUS_SET_LDN_P) |
32862587Spjha (1ull << TLU_OTHER_EVENT_STATUS_SET_LUP_P) |
32872587Spjha (1ull << TLU_OTHER_EVENT_STATUS_SET_LDN_S) |
32882587Spjha (1ull << TLU_OTHER_EVENT_STATUS_SET_LUP_S));
32892587Spjha CSR_XS(csr_base, TLU_OTHER_EVENT_LOG_ENABLE, reg);
32902587Spjha
32912044Sjj156685 /* Save the TLU registers */
32922044Sjj156685 reg_tluue = CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_LOG_ENABLE);
32932044Sjj156685 reg_tluce = CSR_XR(csr_base, TLU_CORRECTABLE_ERROR_LOG_ENABLE);
32942044Sjj156685 /* All clear */
32952044Sjj156685 CSR_XS(csr_base, TLU_UNCORRECTABLE_ERROR_LOG_ENABLE, 0);
32962044Sjj156685 CSR_XS(csr_base, TLU_CORRECTABLE_ERROR_LOG_ENABLE, 0);
32972044Sjj156685
32981772Sjl139090 /* Disable port */
32991772Sjl139090 CSR_BS(csr_base, FLP_PORT_CONTROL, PORT_DIS);
33001772Sjl139090
33011983Sjj156685 /* PCIE reset */
33021772Sjl139090 delay(drv_usectohz(10000));
33031772Sjl139090 CSR_BC(csr_base, HOTPLUG_CONTROL, N_PERST);
33041772Sjl139090
33051772Sjl139090 /* PCIE clock stop */
33061983Sjj156685 delay(drv_usectohz(150));
33071772Sjl139090 CSR_BC(csr_base, HOTPLUG_CONTROL, CLKEN);
33081772Sjl139090
33091772Sjl139090 /* Turn off slot power */
33101983Sjj156685 delay(drv_usectohz(100));
33111772Sjl139090 CSR_BC(csr_base, TLU_SLOT_CONTROL, PWFDEN);
33121772Sjl139090 CSR_BC(csr_base, HOTPLUG_CONTROL, PWREN);
33131983Sjj156685 delay(drv_usectohz(25000));
33141983Sjj156685 CSR_BS(csr_base, TLU_SLOT_STATUS, PWFD);
33151772Sjl139090
33161772Sjl139090 /* write 0 to bit 7 of ILU Error Log Enable Register */
33171983Sjj156685 CSR_BC(csr_base, ILU_ERROR_LOG_ENABLE, SPARE3);
33181772Sjl139090
33192044Sjj156685 /* Set back TLU registers */
33202044Sjj156685 CSR_XS(csr_base, TLU_UNCORRECTABLE_ERROR_LOG_ENABLE, reg_tluue);
33212044Sjj156685 CSR_XS(csr_base, TLU_CORRECTABLE_ERROR_LOG_ENABLE, reg_tluce);
33222044Sjj156685
33231772Sjl139090 /* Power LED off */
33241772Sjl139090 reg = CSR_XR(csr_base, TLU_SLOT_CONTROL);
33251772Sjl139090 reg &= ~PCIE_SLOTCTL_PWR_INDICATOR_MASK;
33261772Sjl139090 reg = pcie_slotctl_pwr_indicator_set(reg,
33271772Sjl139090 PCIE_SLOTCTL_INDICATOR_STATE_OFF);
33281772Sjl139090 CSR_XS(csr_base, TLU_SLOT_CONTROL, reg);
33291772Sjl139090
33301772Sjl139090 /* Indicator LED blink */
33311772Sjl139090 reg = CSR_XR(csr_base, TLU_SLOT_CONTROL);
33321772Sjl139090 reg &= ~PCIE_SLOTCTL_ATTN_INDICATOR_MASK;
33331772Sjl139090 reg = pcie_slotctl_attn_indicator_set(reg,
33341772Sjl139090 PCIE_SLOTCTL_INDICATOR_STATE_BLINK);
33351772Sjl139090 CSR_XS(csr_base, TLU_SLOT_CONTROL, reg);
33361772Sjl139090
33371772Sjl139090 /* Notify to SCF */
33381983Sjj156685 if (CSR_BR(csr_base, HOTPLUG_CONTROL, SLOTPON))
33391983Sjj156685 CSR_BC(csr_base, HOTPLUG_CONTROL, SLOTPON);
33401983Sjj156685 else
33414395Sgovinda CSR_BS(csr_base, HOTPLUG_CONTROL, SLOTPON);
33424395Sgovinda
33434395Sgovinda start_time = gethrtime();
33444395Sgovinda /* Check Leaf Reset status */
33454395Sgovinda while (!(CSR_BR(csr_base, ILU_ERROR_LOG_ENABLE, SPARE3))) {
33464395Sgovinda if ((end_time = (gethrtime() - start_time)) >
33474395Sgovinda oberon_leaf_reset_timeout) {
33484395Sgovinda cmn_err(CE_WARN, "Oberon leaf reset is not completed, "
33494395Sgovinda "even after waiting %llx ticks", end_time);
33504395Sgovinda
33514395Sgovinda break;
33524395Sgovinda }
33534395Sgovinda
33544395Sgovinda /* Wait for one second */
33554395Sgovinda delay(drv_usectohz(1000000));
33564395Sgovinda }
33571772Sjl139090
33581772Sjl139090 /* Indicator LED off */
33591772Sjl139090 reg = CSR_XR(csr_base, TLU_SLOT_CONTROL);
33601772Sjl139090 reg &= ~PCIE_SLOTCTL_ATTN_INDICATOR_MASK;
33611772Sjl139090 reg = pcie_slotctl_attn_indicator_set(reg,
33621772Sjl139090 PCIE_SLOTCTL_INDICATOR_STATE_OFF);
33631772Sjl139090 CSR_XS(csr_base, TLU_SLOT_CONTROL, reg);
33641772Sjl139090
33651772Sjl139090 return (DDI_SUCCESS);
33661772Sjl139090 }
33671772Sjl139090
33681772Sjl139090 static uint_t
oberon_hpreg_get(void * cookie,off_t off)33691772Sjl139090 oberon_hpreg_get(void *cookie, off_t off)
33701772Sjl139090 {
33711772Sjl139090 caddr_t csr_base = *(caddr_t *)cookie;
33721772Sjl139090 volatile uint64_t val = -1ull;
33731772Sjl139090
33741772Sjl139090 switch (off) {
33751772Sjl139090 case PCIE_SLOTCAP:
33761772Sjl139090 val = CSR_XR(csr_base, TLU_SLOT_CAPABILITIES);
33771772Sjl139090 break;
33781772Sjl139090 case PCIE_SLOTCTL:
33791772Sjl139090 val = CSR_XR(csr_base, TLU_SLOT_CONTROL);
33801772Sjl139090
33811772Sjl139090 /* Get the power state */
33821772Sjl139090 val |= (CSR_XR(csr_base, HOTPLUG_CONTROL) &
33831772Sjl139090 (1ull << HOTPLUG_CONTROL_PWREN)) ?
33841772Sjl139090 0 : PCIE_SLOTCTL_PWR_CONTROL;
33851772Sjl139090 break;
33861772Sjl139090 case PCIE_SLOTSTS:
33871772Sjl139090 val = CSR_XR(csr_base, TLU_SLOT_STATUS);
33881772Sjl139090 break;
33891850Sjj156685 case PCIE_LINKCAP:
33901850Sjj156685 val = CSR_XR(csr_base, TLU_LINK_CAPABILITIES);
33911850Sjj156685 break;
33921850Sjj156685 case PCIE_LINKSTS:
33931850Sjj156685 val = CSR_XR(csr_base, TLU_LINK_STATUS);
33941850Sjj156685 break;
33951772Sjl139090 default:
33961786Sjj156685 DBG(DBG_HP, NULL, "oberon_hpreg_get(): "
33971772Sjl139090 "unsupported offset 0x%lx\n", off);
33981772Sjl139090 break;
33991772Sjl139090 }
34001772Sjl139090
34011772Sjl139090 return ((uint_t)val);
34021772Sjl139090 }
34031772Sjl139090
34041772Sjl139090 static uint_t
oberon_hpreg_put(void * cookie,off_t off,uint_t val)34051772Sjl139090 oberon_hpreg_put(void *cookie, off_t off, uint_t val)
34061772Sjl139090 {
34071772Sjl139090 caddr_t csr_base = *(caddr_t *)cookie;
34081850Sjj156685 volatile uint64_t pwr_state_on, pwr_fault;
34091772Sjl139090 uint_t pwr_off, ret = DDI_SUCCESS;
34101772Sjl139090
34111786Sjj156685 DBG(DBG_HP, NULL, "oberon_hpreg_put 0x%lx: cur %x, new %x\n",
34121772Sjl139090 off, oberon_hpreg_get(cookie, off), val);
34131772Sjl139090
34141772Sjl139090 switch (off) {
34151772Sjl139090 case PCIE_SLOTCTL:
34161772Sjl139090 /*
34171772Sjl139090 * Depending on the current state, insertion or removal
34181772Sjl139090 * will go through their respective sequences.
34191772Sjl139090 */
34201772Sjl139090 pwr_state_on = CSR_BR(csr_base, HOTPLUG_CONTROL, PWREN);
34211772Sjl139090 pwr_off = val & PCIE_SLOTCTL_PWR_CONTROL;
34221772Sjl139090
34231772Sjl139090 if (!pwr_off && !pwr_state_on)
34241772Sjl139090 ret = oberon_hp_pwron(csr_base);
34251772Sjl139090 else if (pwr_off && pwr_state_on) {
34261772Sjl139090 pwr_fault = CSR_XR(csr_base, TLU_SLOT_STATUS) &
34271772Sjl139090 (1ull << TLU_SLOT_STATUS_PWFD);
34281772Sjl139090
34291983Sjj156685 if (pwr_fault) {
34301983Sjj156685 DBG(DBG_HP, NULL, "oberon_hpreg_put: power "
34311983Sjj156685 "off because of power fault\n");
34321772Sjl139090 CSR_BC(csr_base, HOTPLUG_CONTROL, PWREN);
34331983Sjj156685 }
34341772Sjl139090 else
34351772Sjl139090 ret = oberon_hp_pwroff(csr_base);
34361850Sjj156685 } else
34371772Sjl139090 CSR_XS(csr_base, TLU_SLOT_CONTROL, val);
34381772Sjl139090 break;
34391772Sjl139090 case PCIE_SLOTSTS:
34401772Sjl139090 CSR_XS(csr_base, TLU_SLOT_STATUS, val);
34411772Sjl139090 break;
34421772Sjl139090 default:
34431786Sjj156685 DBG(DBG_HP, NULL, "oberon_hpreg_put(): "
34441772Sjl139090 "unsupported offset 0x%lx\n", off);
34452840Scarlsonj ret = (uint_t)DDI_FAILURE;
34461772Sjl139090 break;
34471772Sjl139090 }
34481772Sjl139090
34491772Sjl139090 return (ret);
34501772Sjl139090 }
34511772Sjl139090
34521772Sjl139090 int
hvio_hotplug_init(dev_info_t * dip,void * arg)34531772Sjl139090 hvio_hotplug_init(dev_info_t *dip, void *arg)
34541772Sjl139090 {
345510923SEvan.Yan@Sun.COM pcie_hp_regops_t *regops = (pcie_hp_regops_t *)arg;
34561772Sjl139090 px_t *px_p = DIP_TO_STATE(dip);
34571772Sjl139090 pxu_t *pxu_p = (pxu_t *)px_p->px_plat_p;
34582587Spjha volatile uint64_t reg;
34591772Sjl139090
34601772Sjl139090 if (PX_CHIP_TYPE(pxu_p) == PX_CHIP_OBERON) {
34611772Sjl139090 if (!CSR_BR((caddr_t)pxu_p->px_address[PX_REG_CSR],
34621772Sjl139090 TLU_SLOT_CAPABILITIES, HP)) {
34631786Sjj156685 DBG(DBG_HP, NULL, "%s%d: hotplug capabale not set\n",
34641772Sjl139090 ddi_driver_name(dip), ddi_get_instance(dip));
34651772Sjl139090 return (DDI_FAILURE);
34661772Sjl139090 }
34671772Sjl139090
34682587Spjha /* For empty or disconnected slot, disable LUP/LDN */
34692587Spjha if (!CSR_BR((caddr_t)pxu_p->px_address[PX_REG_CSR],
34706953Sanbui TLU_SLOT_STATUS, PSD) ||
34712587Spjha !CSR_BR((caddr_t)pxu_p->px_address[PX_REG_CSR],
34726953Sanbui HOTPLUG_CONTROL, PWREN)) {
34732587Spjha
34742587Spjha reg = CSR_XR((caddr_t)pxu_p->px_address[PX_REG_CSR],
34752587Spjha TLU_OTHER_EVENT_LOG_ENABLE);
34762587Spjha reg &= ~((1ull << TLU_OTHER_EVENT_STATUS_SET_LDN_P) |
34772587Spjha (1ull << TLU_OTHER_EVENT_STATUS_SET_LUP_P) |
34782587Spjha (1ull << TLU_OTHER_EVENT_STATUS_SET_LDN_S) |
34792587Spjha (1ull << TLU_OTHER_EVENT_STATUS_SET_LUP_S));
34802587Spjha CSR_XS((caddr_t)pxu_p->px_address[PX_REG_CSR],
34812587Spjha TLU_OTHER_EVENT_LOG_ENABLE, reg);
34822587Spjha }
34832587Spjha
34841772Sjl139090 regops->get = oberon_hpreg_get;
34851772Sjl139090 regops->put = oberon_hpreg_put;
34861772Sjl139090
34871772Sjl139090 /* cookie is the csr_base */
34881772Sjl139090 regops->cookie = (void *)&pxu_p->px_address[PX_REG_CSR];
34891772Sjl139090
34901772Sjl139090 return (DDI_SUCCESS);
34911772Sjl139090 }
34921772Sjl139090
34931772Sjl139090 return (DDI_ENOTSUP);
34941772Sjl139090 }
34951772Sjl139090
34961772Sjl139090 int
hvio_hotplug_uninit(dev_info_t * dip)34971772Sjl139090 hvio_hotplug_uninit(dev_info_t *dip)
34981772Sjl139090 {
34991772Sjl139090 px_t *px_p = DIP_TO_STATE(dip);
35001772Sjl139090 pxu_t *pxu_p = (pxu_t *)px_p->px_plat_p;
35011772Sjl139090
35021772Sjl139090 if (PX_CHIP_TYPE(pxu_p) == PX_CHIP_OBERON)
35031772Sjl139090 return (DDI_SUCCESS);
35041772Sjl139090
35051772Sjl139090 return (DDI_FAILURE);
35061772Sjl139090 }
3507