xref: /onnv-gate/usr/src/uts/sun4u/io/px/px_hlib.c (revision 7124:544a27e30fd2)
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  */
210Sstevel@tonic-gate /*
226953Sanbui  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
230Sstevel@tonic-gate  * Use is subject to license terms.
240Sstevel@tonic-gate  */
250Sstevel@tonic-gate 
260Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
270Sstevel@tonic-gate 
280Sstevel@tonic-gate #include <sys/types.h>
290Sstevel@tonic-gate #include <sys/cmn_err.h>
300Sstevel@tonic-gate #include <sys/vmsystm.h>
310Sstevel@tonic-gate #include <sys/vmem.h>
320Sstevel@tonic-gate #include <sys/machsystm.h>	/* lddphys() */
330Sstevel@tonic-gate #include <sys/iommutsb.h>
340Sstevel@tonic-gate #include <sys/pci.h>
351772Sjl139090 #include <sys/hotplug/pci/pciehpc.h>
360Sstevel@tonic-gate #include <pcie_pwr.h>
370Sstevel@tonic-gate #include <px_obj.h>
380Sstevel@tonic-gate #include "px_regs.h"
391772Sjl139090 #include "oberon_regs.h"
400Sstevel@tonic-gate #include "px_csr.h"
410Sstevel@tonic-gate #include "px_lib4u.h"
422587Spjha #include "px_err.h"
430Sstevel@tonic-gate 
440Sstevel@tonic-gate /*
450Sstevel@tonic-gate  * Registers that need to be saved and restored during suspend/resume.
460Sstevel@tonic-gate  */
470Sstevel@tonic-gate 
480Sstevel@tonic-gate /*
490Sstevel@tonic-gate  * Registers in the PEC Module.
500Sstevel@tonic-gate  * LPU_RESET should be set to 0ull during resume
511772Sjl139090  *
521772Sjl139090  * This array is in reg,chip form. PX_CHIP_UNIDENTIFIED is for all chips
531772Sjl139090  * or PX_CHIP_FIRE for Fire only, or PX_CHIP_OBERON for Oberon only.
540Sstevel@tonic-gate  */
551772Sjl139090 static struct px_pec_regs {
561772Sjl139090 	uint64_t reg;
571772Sjl139090 	uint64_t chip;
581772Sjl139090 } pec_config_state_regs[] = {
591772Sjl139090 	{PEC_CORE_AND_BLOCK_INTERRUPT_ENABLE, PX_CHIP_UNIDENTIFIED},
601772Sjl139090 	{ILU_ERROR_LOG_ENABLE, PX_CHIP_UNIDENTIFIED},
611772Sjl139090 	{ILU_INTERRUPT_ENABLE, PX_CHIP_UNIDENTIFIED},
621772Sjl139090 	{TLU_CONTROL, PX_CHIP_UNIDENTIFIED},
631772Sjl139090 	{TLU_OTHER_EVENT_LOG_ENABLE, PX_CHIP_UNIDENTIFIED},
641772Sjl139090 	{TLU_OTHER_EVENT_INTERRUPT_ENABLE, PX_CHIP_UNIDENTIFIED},
651772Sjl139090 	{TLU_DEVICE_CONTROL, PX_CHIP_UNIDENTIFIED},
661772Sjl139090 	{TLU_LINK_CONTROL, PX_CHIP_UNIDENTIFIED},
671772Sjl139090 	{TLU_UNCORRECTABLE_ERROR_LOG_ENABLE, PX_CHIP_UNIDENTIFIED},
681772Sjl139090 	{TLU_UNCORRECTABLE_ERROR_INTERRUPT_ENABLE, PX_CHIP_UNIDENTIFIED},
691772Sjl139090 	{TLU_CORRECTABLE_ERROR_LOG_ENABLE, PX_CHIP_UNIDENTIFIED},
701772Sjl139090 	{TLU_CORRECTABLE_ERROR_INTERRUPT_ENABLE, PX_CHIP_UNIDENTIFIED},
711772Sjl139090 	{DLU_LINK_LAYER_CONFIG, PX_CHIP_OBERON},
721772Sjl139090 	{DLU_FLOW_CONTROL_UPDATE_CONTROL, PX_CHIP_OBERON},
731772Sjl139090 	{DLU_TXLINK_REPLAY_TIMER_THRESHOLD, PX_CHIP_OBERON},
741772Sjl139090 	{LPU_LINK_LAYER_INTERRUPT_MASK, PX_CHIP_FIRE},
751772Sjl139090 	{LPU_PHY_INTERRUPT_MASK, PX_CHIP_FIRE},
761772Sjl139090 	{LPU_RECEIVE_PHY_INTERRUPT_MASK, PX_CHIP_FIRE},
771772Sjl139090 	{LPU_TRANSMIT_PHY_INTERRUPT_MASK, PX_CHIP_FIRE},
781772Sjl139090 	{LPU_GIGABLAZE_GLUE_INTERRUPT_MASK, PX_CHIP_FIRE},
791772Sjl139090 	{LPU_LTSSM_INTERRUPT_MASK, PX_CHIP_FIRE},
801772Sjl139090 	{LPU_RESET, PX_CHIP_FIRE},
811772Sjl139090 	{LPU_DEBUG_CONFIG, PX_CHIP_FIRE},
821772Sjl139090 	{LPU_INTERRUPT_MASK, PX_CHIP_FIRE},
831772Sjl139090 	{LPU_LINK_LAYER_CONFIG, PX_CHIP_FIRE},
841772Sjl139090 	{LPU_FLOW_CONTROL_UPDATE_CONTROL, PX_CHIP_FIRE},
851772Sjl139090 	{LPU_TXLINK_FREQUENT_NAK_LATENCY_TIMER_THRESHOLD, PX_CHIP_FIRE},
861772Sjl139090 	{LPU_TXLINK_REPLAY_TIMER_THRESHOLD, PX_CHIP_FIRE},
871772Sjl139090 	{LPU_REPLAY_BUFFER_MAX_ADDRESS, PX_CHIP_FIRE},
881772Sjl139090 	{LPU_TXLINK_RETRY_FIFO_POINTER, PX_CHIP_FIRE},
891772Sjl139090 	{LPU_LTSSM_CONFIG2, PX_CHIP_FIRE},
901772Sjl139090 	{LPU_LTSSM_CONFIG3, PX_CHIP_FIRE},
911772Sjl139090 	{LPU_LTSSM_CONFIG4, PX_CHIP_FIRE},
921772Sjl139090 	{LPU_LTSSM_CONFIG5, PX_CHIP_FIRE},
931772Sjl139090 	{DMC_CORE_AND_BLOCK_INTERRUPT_ENABLE, PX_CHIP_UNIDENTIFIED},
941772Sjl139090 	{DMC_DEBUG_SELECT_FOR_PORT_A, PX_CHIP_UNIDENTIFIED},
951772Sjl139090 	{DMC_DEBUG_SELECT_FOR_PORT_B, PX_CHIP_UNIDENTIFIED}
960Sstevel@tonic-gate };
971772Sjl139090 
981772Sjl139090 #define	PEC_KEYS	\
991772Sjl139090 	((sizeof (pec_config_state_regs))/sizeof (struct px_pec_regs))
1001772Sjl139090 
1011772Sjl139090 #define	PEC_SIZE	(PEC_KEYS * sizeof (uint64_t))
1020Sstevel@tonic-gate 
1030Sstevel@tonic-gate /*
1040Sstevel@tonic-gate  * Registers for the MMU module.
1050Sstevel@tonic-gate  * MMU_TTE_CACHE_INVALIDATE needs to be cleared. (-1ull)
1060Sstevel@tonic-gate  */
1070Sstevel@tonic-gate static uint64_t mmu_config_state_regs[] = {
1080Sstevel@tonic-gate 	MMU_TSB_CONTROL,
1090Sstevel@tonic-gate 	MMU_CONTROL_AND_STATUS,
11027Sjchu 	MMU_ERROR_LOG_ENABLE,
1110Sstevel@tonic-gate 	MMU_INTERRUPT_ENABLE
1120Sstevel@tonic-gate };
1130Sstevel@tonic-gate #define	MMU_SIZE (sizeof (mmu_config_state_regs))
1140Sstevel@tonic-gate #define	MMU_KEYS (MMU_SIZE / sizeof (uint64_t))
1150Sstevel@tonic-gate 
1160Sstevel@tonic-gate /*
1170Sstevel@tonic-gate  * Registers for the IB Module
1180Sstevel@tonic-gate  */
1190Sstevel@tonic-gate static uint64_t ib_config_state_regs[] = {
1200Sstevel@tonic-gate 	IMU_ERROR_LOG_ENABLE,
1210Sstevel@tonic-gate 	IMU_INTERRUPT_ENABLE
1220Sstevel@tonic-gate };
1230Sstevel@tonic-gate #define	IB_SIZE (sizeof (ib_config_state_regs))
1240Sstevel@tonic-gate #define	IB_KEYS (IB_SIZE / sizeof (uint64_t))
1250Sstevel@tonic-gate #define	IB_MAP_SIZE (INTERRUPT_MAPPING_ENTRIES * sizeof (uint64_t))
1260Sstevel@tonic-gate 
1270Sstevel@tonic-gate /*
1281772Sjl139090  * Registers for the JBC module.
1290Sstevel@tonic-gate  * JBC_ERROR_STATUS_CLEAR needs to be cleared. (-1ull)
1300Sstevel@tonic-gate  */
1311772Sjl139090 static uint64_t	jbc_config_state_regs[] = {
1320Sstevel@tonic-gate 	JBUS_PARITY_CONTROL,
1330Sstevel@tonic-gate 	JBC_FATAL_RESET_ENABLE,
1340Sstevel@tonic-gate 	JBC_CORE_AND_BLOCK_INTERRUPT_ENABLE,
1350Sstevel@tonic-gate 	JBC_ERROR_LOG_ENABLE,
1360Sstevel@tonic-gate 	JBC_INTERRUPT_ENABLE
1370Sstevel@tonic-gate };
1381772Sjl139090 #define	JBC_SIZE (sizeof (jbc_config_state_regs))
1391772Sjl139090 #define	JBC_KEYS (JBC_SIZE / sizeof (uint64_t))
1401772Sjl139090 
1411772Sjl139090 /*
1421772Sjl139090  * Registers for the UBC module.
1431772Sjl139090  * UBC_ERROR_STATUS_CLEAR needs to be cleared. (-1ull)
1441772Sjl139090  */
1451772Sjl139090 static uint64_t	ubc_config_state_regs[] = {
1461772Sjl139090 	UBC_ERROR_LOG_ENABLE,
1471772Sjl139090 	UBC_INTERRUPT_ENABLE
1481772Sjl139090 };
1491772Sjl139090 #define	UBC_SIZE (sizeof (ubc_config_state_regs))
1501772Sjl139090 #define	UBC_KEYS (UBC_SIZE / sizeof (uint64_t))
1510Sstevel@tonic-gate 
1520Sstevel@tonic-gate static uint64_t	msiq_config_other_regs[] = {
1530Sstevel@tonic-gate 	ERR_COR_MAPPING,
1540Sstevel@tonic-gate 	ERR_NONFATAL_MAPPING,
1550Sstevel@tonic-gate 	ERR_FATAL_MAPPING,
1560Sstevel@tonic-gate 	PM_PME_MAPPING,
1570Sstevel@tonic-gate 	PME_TO_ACK_MAPPING,
1580Sstevel@tonic-gate 	MSI_32_BIT_ADDRESS,
1590Sstevel@tonic-gate 	MSI_64_BIT_ADDRESS
1600Sstevel@tonic-gate };
1610Sstevel@tonic-gate #define	MSIQ_OTHER_SIZE	(sizeof (msiq_config_other_regs))
1620Sstevel@tonic-gate #define	MSIQ_OTHER_KEYS	(MSIQ_OTHER_SIZE / sizeof (uint64_t))
1630Sstevel@tonic-gate 
1640Sstevel@tonic-gate #define	MSIQ_STATE_SIZE		(EVENT_QUEUE_STATE_ENTRIES * sizeof (uint64_t))
1650Sstevel@tonic-gate #define	MSIQ_MAPPING_SIZE	(MSI_MAPPING_ENTRIES * sizeof (uint64_t))
1660Sstevel@tonic-gate 
1672587Spjha /* OPL tuning variables for link unstable issue */
1683485Spjha int wait_perst = 5000000; 	/* step 9, default: 5s */
1693485Spjha int wait_enable_port = 30000;	/* step 11, default: 30ms */
1702587Spjha int link_retry_count = 2; 	/* step 11, default: 2 */
1713485Spjha int link_status_check = 400000;	/* step 11, default: 400ms */
1722587Spjha 
1730Sstevel@tonic-gate static uint64_t msiq_suspend(devhandle_t dev_hdl, pxu_t *pxu_p);
1740Sstevel@tonic-gate static void msiq_resume(devhandle_t dev_hdl, pxu_t *pxu_p);
1751772Sjl139090 static void jbc_init(caddr_t xbc_csr_base, pxu_t *pxu_p);
1761772Sjl139090 static void ubc_init(caddr_t xbc_csr_base, pxu_t *pxu_p);
1770Sstevel@tonic-gate 
17827Sjchu /*
1791772Sjl139090  * Initialize the bus, but do not enable interrupts.
18027Sjchu  */
1810Sstevel@tonic-gate /* ARGSUSED */
1820Sstevel@tonic-gate void
1830Sstevel@tonic-gate hvio_cb_init(caddr_t xbc_csr_base, pxu_t *pxu_p)
1840Sstevel@tonic-gate {
1851772Sjl139090 	switch (PX_CHIP_TYPE(pxu_p)) {
1861772Sjl139090 	case PX_CHIP_OBERON:
1871772Sjl139090 		ubc_init(xbc_csr_base, pxu_p);
1881772Sjl139090 		break;
1891772Sjl139090 	case PX_CHIP_FIRE:
1901772Sjl139090 		jbc_init(xbc_csr_base, pxu_p);
1911772Sjl139090 		break;
1921772Sjl139090 	default:
1931772Sjl139090 		DBG(DBG_CB, NULL, "hvio_cb_init - unknown chip type: 0x%x\n",
1941772Sjl139090 		    PX_CHIP_TYPE(pxu_p));
1951772Sjl139090 		break;
1961772Sjl139090 	}
1971772Sjl139090 }
1981772Sjl139090 
1991772Sjl139090 /*
2001772Sjl139090  * Initialize the JBC module, but do not enable interrupts.
2011772Sjl139090  */
2021772Sjl139090 /* ARGSUSED */
2031772Sjl139090 static void
2041772Sjl139090 jbc_init(caddr_t xbc_csr_base, pxu_t *pxu_p)
2051772Sjl139090 {
2060Sstevel@tonic-gate 	uint64_t val;
2070Sstevel@tonic-gate 
2080Sstevel@tonic-gate 	/* Check if we need to enable inverted parity */
2090Sstevel@tonic-gate 	val = (1ULL << JBUS_PARITY_CONTROL_P_EN);
2100Sstevel@tonic-gate 	CSR_XS(xbc_csr_base, JBUS_PARITY_CONTROL, val);
2111772Sjl139090 	DBG(DBG_CB, NULL, "jbc_init, JBUS_PARITY_CONTROL: 0x%llx\n",
21227Sjchu 	    CSR_XR(xbc_csr_base, JBUS_PARITY_CONTROL));
21327Sjchu 
21427Sjchu 	val = (1 << JBC_FATAL_RESET_ENABLE_SPARE_P_INT_EN) |
21527Sjchu 	    (1 << JBC_FATAL_RESET_ENABLE_MB_PEA_P_INT_EN) |
21627Sjchu 	    (1 << JBC_FATAL_RESET_ENABLE_CPE_P_INT_EN) |
21727Sjchu 	    (1 << JBC_FATAL_RESET_ENABLE_APE_P_INT_EN) |
21827Sjchu 	    (1 << JBC_FATAL_RESET_ENABLE_PIO_CPE_INT_EN) |
21927Sjchu 	    (1 << JBC_FATAL_RESET_ENABLE_JTCEEW_P_INT_EN) |
22027Sjchu 	    (1 << JBC_FATAL_RESET_ENABLE_JTCEEI_P_INT_EN) |
22127Sjchu 	    (1 << JBC_FATAL_RESET_ENABLE_JTCEER_P_INT_EN);
2220Sstevel@tonic-gate 	CSR_XS(xbc_csr_base, JBC_FATAL_RESET_ENABLE, val);
2231772Sjl139090 	DBG(DBG_CB, NULL, "jbc_init, JBC_FATAL_RESET_ENABLE: 0x%llx\n",
2246953Sanbui 	    CSR_XR(xbc_csr_base, JBC_FATAL_RESET_ENABLE));
2250Sstevel@tonic-gate 
2260Sstevel@tonic-gate 	/*
2270Sstevel@tonic-gate 	 * Enable merge, jbc and dmc interrupts.
2280Sstevel@tonic-gate 	 */
2290Sstevel@tonic-gate 	CSR_XS(xbc_csr_base, JBC_CORE_AND_BLOCK_INTERRUPT_ENABLE, -1ull);
2300Sstevel@tonic-gate 	DBG(DBG_CB, NULL,
2311772Sjl139090 	    "jbc_init, JBC_CORE_AND_BLOCK_INTERRUPT_ENABLE: 0x%llx\n",
23227Sjchu 	    CSR_XR(xbc_csr_base, JBC_CORE_AND_BLOCK_INTERRUPT_ENABLE));
2330Sstevel@tonic-gate 
2340Sstevel@tonic-gate 	/*
2351772Sjl139090 	 * CSR_V JBC's interrupt regs (log, enable, status, clear)
2360Sstevel@tonic-gate 	 */
2371772Sjl139090 	DBG(DBG_CB, NULL, "jbc_init, JBC_ERROR_LOG_ENABLE: 0x%llx\n",
23827Sjchu 	    CSR_XR(xbc_csr_base, JBC_ERROR_LOG_ENABLE));
23927Sjchu 
2401772Sjl139090 	DBG(DBG_CB, NULL, "jbc_init, JBC_INTERRUPT_ENABLE: 0x%llx\n",
24127Sjchu 	    CSR_XR(xbc_csr_base, JBC_INTERRUPT_ENABLE));
24227Sjchu 
2431772Sjl139090 	DBG(DBG_CB, NULL, "jbc_init, JBC_INTERRUPT_STATUS: 0x%llx\n",
24427Sjchu 	    CSR_XR(xbc_csr_base, JBC_INTERRUPT_STATUS));
24527Sjchu 
2461772Sjl139090 	DBG(DBG_CB, NULL, "jbc_init, JBC_ERROR_STATUS_CLEAR: 0x%llx\n",
24727Sjchu 	    CSR_XR(xbc_csr_base, JBC_ERROR_STATUS_CLEAR));
2480Sstevel@tonic-gate }
2490Sstevel@tonic-gate 
25027Sjchu /*
2511772Sjl139090  * Initialize the UBC module, but do not enable interrupts.
2521772Sjl139090  */
2531772Sjl139090 /* ARGSUSED */
2541772Sjl139090 static void
2551772Sjl139090 ubc_init(caddr_t xbc_csr_base, pxu_t *pxu_p)
2561772Sjl139090 {
2571772Sjl139090 	/*
2581772Sjl139090 	 * Enable Uranus bus error log bits.
2591772Sjl139090 	 */
2601772Sjl139090 	CSR_XS(xbc_csr_base, UBC_ERROR_LOG_ENABLE, -1ull);
2611772Sjl139090 	DBG(DBG_CB, NULL, "ubc_init, UBC_ERROR_LOG_ENABLE: 0x%llx\n",
2621772Sjl139090 	    CSR_XR(xbc_csr_base, UBC_ERROR_LOG_ENABLE));
2631772Sjl139090 
2641772Sjl139090 	/*
2651772Sjl139090 	 * Clear Uranus bus errors.
2661772Sjl139090 	 */
2671772Sjl139090 	CSR_XS(xbc_csr_base, UBC_ERROR_STATUS_CLEAR, -1ull);
2681772Sjl139090 	DBG(DBG_CB, NULL, "ubc_init, UBC_ERROR_STATUS_CLEAR: 0x%llx\n",
2691772Sjl139090 	    CSR_XR(xbc_csr_base, UBC_ERROR_STATUS_CLEAR));
2701772Sjl139090 
2711772Sjl139090 	/*
2721772Sjl139090 	 * CSR_V UBC's interrupt regs (log, enable, status, clear)
2731772Sjl139090 	 */
2741772Sjl139090 	DBG(DBG_CB, NULL, "ubc_init, UBC_ERROR_LOG_ENABLE: 0x%llx\n",
2751772Sjl139090 	    CSR_XR(xbc_csr_base, UBC_ERROR_LOG_ENABLE));
2761772Sjl139090 
2771772Sjl139090 	DBG(DBG_CB, NULL, "ubc_init, UBC_INTERRUPT_ENABLE: 0x%llx\n",
2781772Sjl139090 	    CSR_XR(xbc_csr_base, UBC_INTERRUPT_ENABLE));
2791772Sjl139090 
2801772Sjl139090 	DBG(DBG_CB, NULL, "ubc_init, UBC_INTERRUPT_STATUS: 0x%llx\n",
2811772Sjl139090 	    CSR_XR(xbc_csr_base, UBC_INTERRUPT_STATUS));
2821772Sjl139090 
2831772Sjl139090 	DBG(DBG_CB, NULL, "ubc_init, UBC_ERROR_STATUS_CLEAR: 0x%llx\n",
2841772Sjl139090 	    CSR_XR(xbc_csr_base, UBC_ERROR_STATUS_CLEAR));
2851772Sjl139090 }
2861772Sjl139090 
2871772Sjl139090 /*
28827Sjchu  * Initialize the module, but do not enable interrupts.
28927Sjchu  */
2900Sstevel@tonic-gate /* ARGSUSED */
2910Sstevel@tonic-gate void
2920Sstevel@tonic-gate hvio_ib_init(caddr_t csr_base, pxu_t *pxu_p)
2930Sstevel@tonic-gate {
2940Sstevel@tonic-gate 	/*
29527Sjchu 	 * CSR_V IB's interrupt regs (log, enable, status, clear)
2960Sstevel@tonic-gate 	 */
2970Sstevel@tonic-gate 	DBG(DBG_IB, NULL, "hvio_ib_init - IMU_ERROR_LOG_ENABLE: 0x%llx\n",
29827Sjchu 	    CSR_XR(csr_base, IMU_ERROR_LOG_ENABLE));
29927Sjchu 
3000Sstevel@tonic-gate 	DBG(DBG_IB, NULL, "hvio_ib_init - IMU_INTERRUPT_ENABLE: 0x%llx\n",
30127Sjchu 	    CSR_XR(csr_base, IMU_INTERRUPT_ENABLE));
30227Sjchu 
3030Sstevel@tonic-gate 	DBG(DBG_IB, NULL, "hvio_ib_init - IMU_INTERRUPT_STATUS: 0x%llx\n",
30427Sjchu 	    CSR_XR(csr_base, IMU_INTERRUPT_STATUS));
30527Sjchu 
3060Sstevel@tonic-gate 	DBG(DBG_IB, NULL, "hvio_ib_init - IMU_ERROR_STATUS_CLEAR: 0x%llx\n",
30727Sjchu 	    CSR_XR(csr_base, IMU_ERROR_STATUS_CLEAR));
3080Sstevel@tonic-gate }
3090Sstevel@tonic-gate 
31027Sjchu /*
31127Sjchu  * Initialize the module, but do not enable interrupts.
31227Sjchu  */
3130Sstevel@tonic-gate /* ARGSUSED */
3140Sstevel@tonic-gate static void
3150Sstevel@tonic-gate ilu_init(caddr_t csr_base, pxu_t *pxu_p)
3160Sstevel@tonic-gate {
3170Sstevel@tonic-gate 	/*
31827Sjchu 	 * CSR_V ILU's interrupt regs (log, enable, status, clear)
3190Sstevel@tonic-gate 	 */
32027Sjchu 	DBG(DBG_ILU, NULL, "ilu_init - ILU_ERROR_LOG_ENABLE: 0x%llx\n",
32127Sjchu 	    CSR_XR(csr_base, ILU_ERROR_LOG_ENABLE));
32227Sjchu 
3230Sstevel@tonic-gate 	DBG(DBG_ILU, NULL, "ilu_init - ILU_INTERRUPT_ENABLE: 0x%llx\n",
32427Sjchu 	    CSR_XR(csr_base, ILU_INTERRUPT_ENABLE));
32527Sjchu 
3260Sstevel@tonic-gate 	DBG(DBG_ILU, NULL, "ilu_init - ILU_INTERRUPT_STATUS: 0x%llx\n",
32727Sjchu 	    CSR_XR(csr_base, ILU_INTERRUPT_STATUS));
32827Sjchu 
3290Sstevel@tonic-gate 	DBG(DBG_ILU, NULL, "ilu_init - ILU_ERROR_STATUS_CLEAR: 0x%llx\n",
33027Sjchu 	    CSR_XR(csr_base, ILU_ERROR_STATUS_CLEAR));
3310Sstevel@tonic-gate }
3320Sstevel@tonic-gate 
33327Sjchu /*
33427Sjchu  * Initialize the module, but do not enable interrupts.
33527Sjchu  */
336225Sess /* ARGSUSED */
3370Sstevel@tonic-gate static void
3380Sstevel@tonic-gate tlu_init(caddr_t csr_base, pxu_t *pxu_p)
3390Sstevel@tonic-gate {
3400Sstevel@tonic-gate 	uint64_t val;
3410Sstevel@tonic-gate 
3420Sstevel@tonic-gate 	/*
3430Sstevel@tonic-gate 	 * CSR_V TLU_CONTROL Expect OBP ???
3440Sstevel@tonic-gate 	 */
3450Sstevel@tonic-gate 
3460Sstevel@tonic-gate 	/*
3470Sstevel@tonic-gate 	 * L0s entry default timer value - 7.0 us
3480Sstevel@tonic-gate 	 * Completion timeout select default value - 67.1 ms and
3490Sstevel@tonic-gate 	 * OBP will set this value.
3500Sstevel@tonic-gate 	 *
3510Sstevel@tonic-gate 	 * Configuration - Bit 0 should always be 0 for upstream port.
3520Sstevel@tonic-gate 	 * Bit 1 is clock - how is this related to the clock bit in TLU
3530Sstevel@tonic-gate 	 * Link Control register?  Both are hardware dependent and likely
3540Sstevel@tonic-gate 	 * set by OBP.
3550Sstevel@tonic-gate 	 *
3562017Sjroberts 	 * NOTE: Do not set the NPWR_EN bit.  The desired value of this bit
3572017Sjroberts 	 * will be set by OBP.
3580Sstevel@tonic-gate 	 */
3590Sstevel@tonic-gate 	val = CSR_XR(csr_base, TLU_CONTROL);
360225Sess 	val |= (TLU_CONTROL_L0S_TIM_DEFAULT << TLU_CONTROL_L0S_TIM) |
3612017Sjroberts 	    TLU_CONTROL_CONFIG_DEFAULT;
3620Sstevel@tonic-gate 
363118Sjchu 	/*
3641772Sjl139090 	 * For Oberon, NPWR_EN is set to 0 to prevent PIO reads from blocking
3651772Sjl139090 	 * behind non-posted PIO writes. This blocking could cause a master or
3661772Sjl139090 	 * slave timeout on the host bus if multiple serialized PIOs were to
3671772Sjl139090 	 * suffer Completion Timeouts because the CTO delays for each PIO ahead
3681772Sjl139090 	 * of the read would accumulate. Since the Olympus processor can have
3691772Sjl139090 	 * only 1 PIO outstanding, there is no possibility of PIO accesses from
3701772Sjl139090 	 * a given CPU to a given device being re-ordered by the PCIe fabric;
3711772Sjl139090 	 * therefore turning off serialization should be safe from a PCIe
3721772Sjl139090 	 * ordering perspective.
3731772Sjl139090 	 */
3741772Sjl139090 	if (PX_CHIP_TYPE(pxu_p) == PX_CHIP_OBERON)
3751772Sjl139090 		val &= ~(1ull << TLU_CONTROL_NPWR_EN);
3761772Sjl139090 
3771772Sjl139090 	/*
378118Sjchu 	 * Set Detect.Quiet. This will disable automatic link
379118Sjchu 	 * re-training, if the link goes down e.g. power management
380118Sjchu 	 * turns off power to the downstream device. This will enable
381118Sjchu 	 * Fire to go to Drain state, after link down. The drain state
382118Sjchu 	 * forces a reset to the FC state machine, which is required for
383118Sjchu 	 * proper link re-training.
384118Sjchu 	 */
385118Sjchu 	val |= (1ull << TLU_REMAIN_DETECT_QUIET);
3860Sstevel@tonic-gate 	CSR_XS(csr_base, TLU_CONTROL, val);
3870Sstevel@tonic-gate 	DBG(DBG_TLU, NULL, "tlu_init - TLU_CONTROL: 0x%llx\n",
3880Sstevel@tonic-gate 	    CSR_XR(csr_base, TLU_CONTROL));
3890Sstevel@tonic-gate 
3900Sstevel@tonic-gate 	/*
3910Sstevel@tonic-gate 	 * CSR_V TLU_STATUS Expect HW 0x4
3920Sstevel@tonic-gate 	 */
3930Sstevel@tonic-gate 
3940Sstevel@tonic-gate 	/*
3950Sstevel@tonic-gate 	 * Only bit [7:0] are currently defined.  Bits [2:0]
3960Sstevel@tonic-gate 	 * are the state, which should likely be in state active,
3970Sstevel@tonic-gate 	 * 100b.  Bit three is 'recovery', which is not understood.
3980Sstevel@tonic-gate 	 * All other bits are reserved.
3990Sstevel@tonic-gate 	 */
4000Sstevel@tonic-gate 	DBG(DBG_TLU, NULL, "tlu_init - TLU_STATUS: 0x%llx\n",
40127Sjchu 	    CSR_XR(csr_base, TLU_STATUS));
4020Sstevel@tonic-gate 
4030Sstevel@tonic-gate 	/*
4040Sstevel@tonic-gate 	 * CSR_V TLU_PME_TURN_OFF_GENERATE Expect HW 0x0
4050Sstevel@tonic-gate 	 */
4060Sstevel@tonic-gate 	DBG(DBG_TLU, NULL, "tlu_init - TLU_PME_TURN_OFF_GENERATE: 0x%llx\n",
40727Sjchu 	    CSR_XR(csr_base, TLU_PME_TURN_OFF_GENERATE));
4080Sstevel@tonic-gate 
4090Sstevel@tonic-gate 	/*
4100Sstevel@tonic-gate 	 * CSR_V TLU_INGRESS_CREDITS_INITIAL Expect HW 0x10000200C0
4110Sstevel@tonic-gate 	 */
4120Sstevel@tonic-gate 
4130Sstevel@tonic-gate 	/*
4140Sstevel@tonic-gate 	 * Ingress credits initial register.  Bits [39:32] should be
4150Sstevel@tonic-gate 	 * 0x10, bits [19:12] should be 0x20, and bits [11:0] should
4160Sstevel@tonic-gate 	 * be 0xC0.  These are the reset values, and should be set by
4170Sstevel@tonic-gate 	 * HW.
4180Sstevel@tonic-gate 	 */
4190Sstevel@tonic-gate 	DBG(DBG_TLU, NULL, "tlu_init - TLU_INGRESS_CREDITS_INITIAL: 0x%llx\n",
42027Sjchu 	    CSR_XR(csr_base, TLU_INGRESS_CREDITS_INITIAL));
4210Sstevel@tonic-gate 
4220Sstevel@tonic-gate 	/*
4230Sstevel@tonic-gate 	 * CSR_V TLU_DIAGNOSTIC Expect HW 0x0
4240Sstevel@tonic-gate 	 */
4250Sstevel@tonic-gate 
4260Sstevel@tonic-gate 	/*
4270Sstevel@tonic-gate 	 * Diagnostic register - always zero unless we are debugging.
4280Sstevel@tonic-gate 	 */
4290Sstevel@tonic-gate 	DBG(DBG_TLU, NULL, "tlu_init - TLU_DIAGNOSTIC: 0x%llx\n",
43027Sjchu 	    CSR_XR(csr_base, TLU_DIAGNOSTIC));
4310Sstevel@tonic-gate 
4320Sstevel@tonic-gate 	/*
4330Sstevel@tonic-gate 	 * CSR_V TLU_EGRESS_CREDITS_CONSUMED Expect HW 0x0
4340Sstevel@tonic-gate 	 */
4350Sstevel@tonic-gate 	DBG(DBG_TLU, NULL, "tlu_init - TLU_EGRESS_CREDITS_CONSUMED: 0x%llx\n",
43627Sjchu 	    CSR_XR(csr_base, TLU_EGRESS_CREDITS_CONSUMED));
4370Sstevel@tonic-gate 
4380Sstevel@tonic-gate 	/*
4390Sstevel@tonic-gate 	 * CSR_V TLU_EGRESS_CREDIT_LIMIT Expect HW 0x0
4400Sstevel@tonic-gate 	 */
4410Sstevel@tonic-gate 	DBG(DBG_TLU, NULL, "tlu_init - TLU_EGRESS_CREDIT_LIMIT: 0x%llx\n",
44227Sjchu 	    CSR_XR(csr_base, TLU_EGRESS_CREDIT_LIMIT));
4430Sstevel@tonic-gate 
4440Sstevel@tonic-gate 	/*
4450Sstevel@tonic-gate 	 * CSR_V TLU_EGRESS_RETRY_BUFFER Expect HW 0x0
4460Sstevel@tonic-gate 	 */
4470Sstevel@tonic-gate 	DBG(DBG_TLU, NULL, "tlu_init - TLU_EGRESS_RETRY_BUFFER: 0x%llx\n",
44827Sjchu 	    CSR_XR(csr_base, TLU_EGRESS_RETRY_BUFFER));
4490Sstevel@tonic-gate 
4500Sstevel@tonic-gate 	/*
4510Sstevel@tonic-gate 	 * CSR_V TLU_INGRESS_CREDITS_ALLOCATED Expected HW 0x0
4520Sstevel@tonic-gate 	 */
4530Sstevel@tonic-gate 	DBG(DBG_TLU, NULL,
45427Sjchu 	    "tlu_init - TLU_INGRESS_CREDITS_ALLOCATED: 0x%llx\n",
45527Sjchu 	    CSR_XR(csr_base, TLU_INGRESS_CREDITS_ALLOCATED));
4560Sstevel@tonic-gate 
4570Sstevel@tonic-gate 	/*
4580Sstevel@tonic-gate 	 * CSR_V TLU_INGRESS_CREDITS_RECEIVED Expected HW 0x0
4590Sstevel@tonic-gate 	 */
4600Sstevel@tonic-gate 	DBG(DBG_TLU, NULL,
46127Sjchu 	    "tlu_init - TLU_INGRESS_CREDITS_RECEIVED: 0x%llx\n",
46227Sjchu 	    CSR_XR(csr_base, TLU_INGRESS_CREDITS_RECEIVED));
4630Sstevel@tonic-gate 
4640Sstevel@tonic-gate 	/*
46527Sjchu 	 * CSR_V TLU's interrupt regs (log, enable, status, clear)
4660Sstevel@tonic-gate 	 */
4670Sstevel@tonic-gate 	DBG(DBG_TLU, NULL,
46827Sjchu 	    "tlu_init - TLU_OTHER_EVENT_LOG_ENABLE: 0x%llx\n",
46927Sjchu 	    CSR_XR(csr_base, TLU_OTHER_EVENT_LOG_ENABLE));
47027Sjchu 
4710Sstevel@tonic-gate 	DBG(DBG_TLU, NULL,
47227Sjchu 	    "tlu_init - TLU_OTHER_EVENT_INTERRUPT_ENABLE: 0x%llx\n",
47327Sjchu 	    CSR_XR(csr_base, TLU_OTHER_EVENT_INTERRUPT_ENABLE));
47427Sjchu 
47527Sjchu 	DBG(DBG_TLU, NULL,
47627Sjchu 	    "tlu_init - TLU_OTHER_EVENT_INTERRUPT_STATUS: 0x%llx\n",
47727Sjchu 	    CSR_XR(csr_base, TLU_OTHER_EVENT_INTERRUPT_STATUS));
47827Sjchu 
47927Sjchu 	DBG(DBG_TLU, NULL,
48027Sjchu 	    "tlu_init - TLU_OTHER_EVENT_STATUS_CLEAR: 0x%llx\n",
48127Sjchu 	    CSR_XR(csr_base, TLU_OTHER_EVENT_STATUS_CLEAR));
4820Sstevel@tonic-gate 
4830Sstevel@tonic-gate 	/*
4840Sstevel@tonic-gate 	 * CSR_V TLU_RECEIVE_OTHER_EVENT_HEADER1_LOG Expect HW 0x0
4850Sstevel@tonic-gate 	 */
4860Sstevel@tonic-gate 	DBG(DBG_TLU, NULL,
48727Sjchu 	    "tlu_init - TLU_RECEIVE_OTHER_EVENT_HEADER1_LOG: 0x%llx\n",
48827Sjchu 	    CSR_XR(csr_base, TLU_RECEIVE_OTHER_EVENT_HEADER1_LOG));
4890Sstevel@tonic-gate 
4900Sstevel@tonic-gate 	/*
4910Sstevel@tonic-gate 	 * CSR_V TLU_RECEIVE_OTHER_EVENT_HEADER2_LOG Expect HW 0x0
4920Sstevel@tonic-gate 	 */
4930Sstevel@tonic-gate 	DBG(DBG_TLU, NULL,
49427Sjchu 	    "tlu_init - TLU_RECEIVE_OTHER_EVENT_HEADER2_LOG: 0x%llx\n",
49527Sjchu 	    CSR_XR(csr_base, TLU_RECEIVE_OTHER_EVENT_HEADER2_LOG));
4960Sstevel@tonic-gate 
4970Sstevel@tonic-gate 	/*
4980Sstevel@tonic-gate 	 * CSR_V TLU_TRANSMIT_OTHER_EVENT_HEADER1_LOG Expect HW 0x0
4990Sstevel@tonic-gate 	 */
5000Sstevel@tonic-gate 	DBG(DBG_TLU, NULL,
50127Sjchu 	    "tlu_init - TLU_TRANSMIT_OTHER_EVENT_HEADER1_LOG: 0x%llx\n",
50227Sjchu 	    CSR_XR(csr_base, TLU_TRANSMIT_OTHER_EVENT_HEADER1_LOG));
5030Sstevel@tonic-gate 
5040Sstevel@tonic-gate 	/*
5050Sstevel@tonic-gate 	 * CSR_V TLU_TRANSMIT_OTHER_EVENT_HEADER2_LOG Expect HW 0x0
5060Sstevel@tonic-gate 	 */
5070Sstevel@tonic-gate 	DBG(DBG_TLU, NULL,
50827Sjchu 	    "tlu_init - TLU_TRANSMIT_OTHER_EVENT_HEADER2_LOG: 0x%llx\n",
50927Sjchu 	    CSR_XR(csr_base, TLU_TRANSMIT_OTHER_EVENT_HEADER2_LOG));
5100Sstevel@tonic-gate 
5110Sstevel@tonic-gate 	/*
5120Sstevel@tonic-gate 	 * CSR_V TLU_PERFORMANCE_COUNTER_SELECT Expect HW 0x0
5130Sstevel@tonic-gate 	 */
5140Sstevel@tonic-gate 	DBG(DBG_TLU, NULL,
51527Sjchu 	    "tlu_init - TLU_PERFORMANCE_COUNTER_SELECT: 0x%llx\n",
51627Sjchu 	    CSR_XR(csr_base, TLU_PERFORMANCE_COUNTER_SELECT));
5170Sstevel@tonic-gate 
5180Sstevel@tonic-gate 	/*
5190Sstevel@tonic-gate 	 * CSR_V TLU_PERFORMANCE_COUNTER_ZERO Expect HW 0x0
5200Sstevel@tonic-gate 	 */
5210Sstevel@tonic-gate 	DBG(DBG_TLU, NULL,
52227Sjchu 	    "tlu_init - TLU_PERFORMANCE_COUNTER_ZERO: 0x%llx\n",
52327Sjchu 	    CSR_XR(csr_base, TLU_PERFORMANCE_COUNTER_ZERO));
5240Sstevel@tonic-gate 
5250Sstevel@tonic-gate 	/*
5260Sstevel@tonic-gate 	 * CSR_V TLU_PERFORMANCE_COUNTER_ONE Expect HW 0x0
5270Sstevel@tonic-gate 	 */
5280Sstevel@tonic-gate 	DBG(DBG_TLU, NULL, "tlu_init - TLU_PERFORMANCE_COUNTER_ONE: 0x%llx\n",
52927Sjchu 	    CSR_XR(csr_base, TLU_PERFORMANCE_COUNTER_ONE));
5300Sstevel@tonic-gate 
5310Sstevel@tonic-gate 	/*
5320Sstevel@tonic-gate 	 * CSR_V TLU_PERFORMANCE_COUNTER_TWO Expect HW 0x0
5330Sstevel@tonic-gate 	 */
5340Sstevel@tonic-gate 	DBG(DBG_TLU, NULL, "tlu_init - TLU_PERFORMANCE_COUNTER_TWO: 0x%llx\n",
53527Sjchu 	    CSR_XR(csr_base, TLU_PERFORMANCE_COUNTER_TWO));
5360Sstevel@tonic-gate 
5370Sstevel@tonic-gate 	/*
5380Sstevel@tonic-gate 	 * CSR_V TLU_DEBUG_SELECT_A Expect HW 0x0
5390Sstevel@tonic-gate 	 */
5400Sstevel@tonic-gate 
5410Sstevel@tonic-gate 	DBG(DBG_TLU, NULL, "tlu_init - TLU_DEBUG_SELECT_A: 0x%llx\n",
54227Sjchu 	    CSR_XR(csr_base, TLU_DEBUG_SELECT_A));
5430Sstevel@tonic-gate 
5440Sstevel@tonic-gate 	/*
5450Sstevel@tonic-gate 	 * CSR_V TLU_DEBUG_SELECT_B Expect HW 0x0
5460Sstevel@tonic-gate 	 */
5470Sstevel@tonic-gate 	DBG(DBG_TLU, NULL, "tlu_init - TLU_DEBUG_SELECT_B: 0x%llx\n",
54827Sjchu 	    CSR_XR(csr_base, TLU_DEBUG_SELECT_B));
5490Sstevel@tonic-gate 
5500Sstevel@tonic-gate 	/*
5510Sstevel@tonic-gate 	 * CSR_V TLU_DEVICE_CAPABILITIES Expect HW 0xFC2
5520Sstevel@tonic-gate 	 */
5530Sstevel@tonic-gate 	DBG(DBG_TLU, NULL, "tlu_init - TLU_DEVICE_CAPABILITIES: 0x%llx\n",
55427Sjchu 	    CSR_XR(csr_base, TLU_DEVICE_CAPABILITIES));
5550Sstevel@tonic-gate 
5560Sstevel@tonic-gate 	/*
5570Sstevel@tonic-gate 	 * CSR_V TLU_DEVICE_CONTROL Expect HW 0x0
5580Sstevel@tonic-gate 	 */
5590Sstevel@tonic-gate 
5600Sstevel@tonic-gate 	/*
5610Sstevel@tonic-gate 	 * Bits [14:12] are the Max Read Request Size, which is always 64
5620Sstevel@tonic-gate 	 * bytes which is 000b.  Bits [7:5] are Max Payload Size, which
5630Sstevel@tonic-gate 	 * start at 128 bytes which is 000b.  This may be revisited if
5640Sstevel@tonic-gate 	 * init_child finds greater values.
5650Sstevel@tonic-gate 	 */
5660Sstevel@tonic-gate 	val = 0x0ull;
5670Sstevel@tonic-gate 	CSR_XS(csr_base, TLU_DEVICE_CONTROL, val);
5680Sstevel@tonic-gate 	DBG(DBG_TLU, NULL, "tlu_init - TLU_DEVICE_CONTROL: 0x%llx\n",
56927Sjchu 	    CSR_XR(csr_base, TLU_DEVICE_CONTROL));
5700Sstevel@tonic-gate 
5710Sstevel@tonic-gate 	/*
5720Sstevel@tonic-gate 	 * CSR_V TLU_DEVICE_STATUS Expect HW 0x0
5730Sstevel@tonic-gate 	 */
5740Sstevel@tonic-gate 	DBG(DBG_TLU, NULL, "tlu_init - TLU_DEVICE_STATUS: 0x%llx\n",
57527Sjchu 	    CSR_XR(csr_base, TLU_DEVICE_STATUS));
5760Sstevel@tonic-gate 
5770Sstevel@tonic-gate 	/*
5780Sstevel@tonic-gate 	 * CSR_V TLU_LINK_CAPABILITIES Expect HW 0x15C81
5790Sstevel@tonic-gate 	 */
5800Sstevel@tonic-gate 	DBG(DBG_TLU, NULL, "tlu_init - TLU_LINK_CAPABILITIES: 0x%llx\n",
58127Sjchu 	    CSR_XR(csr_base, TLU_LINK_CAPABILITIES));
5820Sstevel@tonic-gate 
5830Sstevel@tonic-gate 	/*
5840Sstevel@tonic-gate 	 * CSR_V TLU_LINK_CONTROL Expect OBP 0x40
5850Sstevel@tonic-gate 	 */
5860Sstevel@tonic-gate 
5870Sstevel@tonic-gate 	/*
5880Sstevel@tonic-gate 	 * The CLOCK bit should be set by OBP if the hardware dictates,
5890Sstevel@tonic-gate 	 * and if it is set then ASPM should be used since then L0s exit
5900Sstevel@tonic-gate 	 * latency should be lower than L1 exit latency.
5910Sstevel@tonic-gate 	 *
5920Sstevel@tonic-gate 	 * Note that we will not enable power management during bringup
5930Sstevel@tonic-gate 	 * since it has not been test and is creating some problems in
5940Sstevel@tonic-gate 	 * simulation.
5950Sstevel@tonic-gate 	 */
5960Sstevel@tonic-gate 	val = (1ull << TLU_LINK_CONTROL_CLOCK);
5970Sstevel@tonic-gate 
5980Sstevel@tonic-gate 	CSR_XS(csr_base, TLU_LINK_CONTROL, val);
5990Sstevel@tonic-gate 	DBG(DBG_TLU, NULL, "tlu_init - TLU_LINK_CONTROL: 0x%llx\n",
60027Sjchu 	    CSR_XR(csr_base, TLU_LINK_CONTROL));
6010Sstevel@tonic-gate 
6020Sstevel@tonic-gate 	/*
6030Sstevel@tonic-gate 	 * CSR_V TLU_LINK_STATUS Expect OBP 0x1011
6040Sstevel@tonic-gate 	 */
6050Sstevel@tonic-gate 
6060Sstevel@tonic-gate 	/*
6070Sstevel@tonic-gate 	 * Not sure if HW or OBP will be setting this read only
6080Sstevel@tonic-gate 	 * register.  Bit 12 is Clock, and it should always be 1
6090Sstevel@tonic-gate 	 * signifying that the component uses the same physical
6100Sstevel@tonic-gate 	 * clock as the platform.  Bits [9:4] are for the width,
6110Sstevel@tonic-gate 	 * with the expected value above signifying a x1 width.
6120Sstevel@tonic-gate 	 * Bits [3:0] are the speed, with 1b signifying 2.5 Gb/s,
6130Sstevel@tonic-gate 	 * the only speed as yet supported by the PCI-E spec.
6140Sstevel@tonic-gate 	 */
6150Sstevel@tonic-gate 	DBG(DBG_TLU, NULL, "tlu_init - TLU_LINK_STATUS: 0x%llx\n",
61627Sjchu 	    CSR_XR(csr_base, TLU_LINK_STATUS));
6170Sstevel@tonic-gate 
6180Sstevel@tonic-gate 	/*
6190Sstevel@tonic-gate 	 * CSR_V TLU_SLOT_CAPABILITIES Expect OBP ???
6200Sstevel@tonic-gate 	 */
6210Sstevel@tonic-gate 
6220Sstevel@tonic-gate 	/*
6230Sstevel@tonic-gate 	 * Power Limits for the slots.  Will be platform
6240Sstevel@tonic-gate 	 * dependent, and OBP will need to set after consulting
6250Sstevel@tonic-gate 	 * with the HW guys.
6260Sstevel@tonic-gate 	 *
6270Sstevel@tonic-gate 	 * Bits [16:15] are power limit scale, which most likely
6280Sstevel@tonic-gate 	 * will be 0b signifying 1x.  Bits [14:7] are the Set
6290Sstevel@tonic-gate 	 * Power Limit Value, which is a number which is multiplied
6300Sstevel@tonic-gate 	 * by the power limit scale to get the actual power limit.
6310Sstevel@tonic-gate 	 */
6320Sstevel@tonic-gate 	DBG(DBG_TLU, NULL, "tlu_init - TLU_SLOT_CAPABILITIES: 0x%llx\n",
63327Sjchu 	    CSR_XR(csr_base, TLU_SLOT_CAPABILITIES));
6340Sstevel@tonic-gate 
6350Sstevel@tonic-gate 	/*
6360Sstevel@tonic-gate 	 * CSR_V TLU_UNCORRECTABLE_ERROR_LOG_ENABLE Expect Kernel 0x17F011
6370Sstevel@tonic-gate 	 */
6380Sstevel@tonic-gate 	DBG(DBG_TLU, NULL,
63927Sjchu 	    "tlu_init - TLU_UNCORRECTABLE_ERROR_LOG_ENABLE: 0x%llx\n",
64027Sjchu 	    CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_LOG_ENABLE));
6410Sstevel@tonic-gate 
6420Sstevel@tonic-gate 	/*
64327Sjchu 	 * CSR_V TLU_UNCORRECTABLE_ERROR_INTERRUPT_ENABLE Expect
64427Sjchu 	 * Kernel 0x17F0110017F011
6450Sstevel@tonic-gate 	 */
6460Sstevel@tonic-gate 	DBG(DBG_TLU, NULL,
64727Sjchu 	    "tlu_init - TLU_UNCORRECTABLE_ERROR_INTERRUPT_ENABLE: 0x%llx\n",
64827Sjchu 	    CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_INTERRUPT_ENABLE));
6490Sstevel@tonic-gate 
6500Sstevel@tonic-gate 	/*
6510Sstevel@tonic-gate 	 * CSR_V TLU_UNCORRECTABLE_ERROR_INTERRUPT_STATUS Expect HW 0x0
6520Sstevel@tonic-gate 	 */
6530Sstevel@tonic-gate 	DBG(DBG_TLU, NULL,
65427Sjchu 	    "tlu_init - TLU_UNCORRECTABLE_ERROR_INTERRUPT_STATUS: 0x%llx\n",
65527Sjchu 	    CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_INTERRUPT_STATUS));
6560Sstevel@tonic-gate 
6570Sstevel@tonic-gate 	/*
6580Sstevel@tonic-gate 	 * CSR_V TLU_UNCORRECTABLE_ERROR_STATUS_CLEAR Expect HW 0x0
6590Sstevel@tonic-gate 	 */
6600Sstevel@tonic-gate 	DBG(DBG_TLU, NULL,
66127Sjchu 	    "tlu_init - TLU_UNCORRECTABLE_ERROR_STATUS_CLEAR: 0x%llx\n",
66227Sjchu 	    CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_STATUS_CLEAR));
6630Sstevel@tonic-gate 
6640Sstevel@tonic-gate 	/*
6650Sstevel@tonic-gate 	 * CSR_V TLU_RECEIVE_UNCORRECTABLE_ERROR_HEADER1_LOG HW 0x0
6660Sstevel@tonic-gate 	 */
6670Sstevel@tonic-gate 	DBG(DBG_TLU, NULL,
6680Sstevel@tonic-gate 	    "tlu_init - TLU_RECEIVE_UNCORRECTABLE_ERROR_HEADER1_LOG: 0x%llx\n",
6690Sstevel@tonic-gate 	    CSR_XR(csr_base, TLU_RECEIVE_UNCORRECTABLE_ERROR_HEADER1_LOG));
6700Sstevel@tonic-gate 
6710Sstevel@tonic-gate 	/*
6720Sstevel@tonic-gate 	 * CSR_V TLU_RECEIVE_UNCORRECTABLE_ERROR_HEADER2_LOG HW 0x0
6730Sstevel@tonic-gate 	 */
6740Sstevel@tonic-gate 	DBG(DBG_TLU, NULL,
6750Sstevel@tonic-gate 	    "tlu_init - TLU_RECEIVE_UNCORRECTABLE_ERROR_HEADER2_LOG: 0x%llx\n",
6760Sstevel@tonic-gate 	    CSR_XR(csr_base, TLU_RECEIVE_UNCORRECTABLE_ERROR_HEADER2_LOG));
6770Sstevel@tonic-gate 
6780Sstevel@tonic-gate 	/*
6790Sstevel@tonic-gate 	 * CSR_V TLU_TRANSMIT_UNCORRECTABLE_ERROR_HEADER1_LOG HW 0x0
6800Sstevel@tonic-gate 	 */
6810Sstevel@tonic-gate 	DBG(DBG_TLU, NULL,
6820Sstevel@tonic-gate 	    "tlu_init - TLU_TRANSMIT_UNCORRECTABLE_ERROR_HEADER1_LOG: 0x%llx\n",
6830Sstevel@tonic-gate 	    CSR_XR(csr_base, TLU_TRANSMIT_UNCORRECTABLE_ERROR_HEADER1_LOG));
6840Sstevel@tonic-gate 
6850Sstevel@tonic-gate 	/*
6860Sstevel@tonic-gate 	 * CSR_V TLU_TRANSMIT_UNCORRECTABLE_ERROR_HEADER2_LOG HW 0x0
6870Sstevel@tonic-gate 	 */
6880Sstevel@tonic-gate 	DBG(DBG_TLU, NULL,
6890Sstevel@tonic-gate 	    "tlu_init - TLU_TRANSMIT_UNCORRECTABLE_ERROR_HEADER2_LOG: 0x%llx\n",
6900Sstevel@tonic-gate 	    CSR_XR(csr_base, TLU_TRANSMIT_UNCORRECTABLE_ERROR_HEADER2_LOG));
6910Sstevel@tonic-gate 
69227Sjchu 
6930Sstevel@tonic-gate 	/*
69427Sjchu 	 * CSR_V TLU's CE interrupt regs (log, enable, status, clear)
69527Sjchu 	 * Plus header logs
6960Sstevel@tonic-gate 	 */
6970Sstevel@tonic-gate 
6980Sstevel@tonic-gate 	/*
69927Sjchu 	 * CSR_V TLU_CORRECTABLE_ERROR_LOG_ENABLE Expect Kernel 0x11C1
7000Sstevel@tonic-gate 	 */
7010Sstevel@tonic-gate 	DBG(DBG_TLU, NULL,
70227Sjchu 	    "tlu_init - TLU_CORRECTABLE_ERROR_LOG_ENABLE: 0x%llx\n",
70327Sjchu 	    CSR_XR(csr_base, TLU_CORRECTABLE_ERROR_LOG_ENABLE));
7040Sstevel@tonic-gate 
7050Sstevel@tonic-gate 	/*
7060Sstevel@tonic-gate 	 * CSR_V TLU_CORRECTABLE_ERROR_INTERRUPT_ENABLE Kernel 0x11C1000011C1
7070Sstevel@tonic-gate 	 */
7080Sstevel@tonic-gate 	DBG(DBG_TLU, NULL,
70927Sjchu 	    "tlu_init - TLU_CORRECTABLE_ERROR_INTERRUPT_ENABLE: 0x%llx\n",
71027Sjchu 	    CSR_XR(csr_base, TLU_CORRECTABLE_ERROR_INTERRUPT_ENABLE));
7110Sstevel@tonic-gate 
7120Sstevel@tonic-gate 	/*
7130Sstevel@tonic-gate 	 * CSR_V TLU_CORRECTABLE_ERROR_INTERRUPT_STATUS Expect HW 0x0
7140Sstevel@tonic-gate 	 */
7150Sstevel@tonic-gate 	DBG(DBG_TLU, NULL,
71627Sjchu 	    "tlu_init - TLU_CORRECTABLE_ERROR_INTERRUPT_STATUS: 0x%llx\n",
71727Sjchu 	    CSR_XR(csr_base, TLU_CORRECTABLE_ERROR_INTERRUPT_STATUS));
7180Sstevel@tonic-gate 
7190Sstevel@tonic-gate 	/*
7200Sstevel@tonic-gate 	 * CSR_V TLU_CORRECTABLE_ERROR_STATUS_CLEAR Expect HW 0x0
7210Sstevel@tonic-gate 	 */
7220Sstevel@tonic-gate 	DBG(DBG_TLU, NULL,
72327Sjchu 	    "tlu_init - TLU_CORRECTABLE_ERROR_STATUS_CLEAR: 0x%llx\n",
72427Sjchu 	    CSR_XR(csr_base, TLU_CORRECTABLE_ERROR_STATUS_CLEAR));
7250Sstevel@tonic-gate }
7260Sstevel@tonic-gate 
727225Sess /* ARGSUSED */
7280Sstevel@tonic-gate static void
7290Sstevel@tonic-gate lpu_init(caddr_t csr_base, pxu_t *pxu_p)
7300Sstevel@tonic-gate {
7310Sstevel@tonic-gate 	/* Variables used to set the ACKNAK Latency Timer and Replay Timer */
7320Sstevel@tonic-gate 	int link_width, max_payload;
7330Sstevel@tonic-gate 
7340Sstevel@tonic-gate 	uint64_t val;
7350Sstevel@tonic-gate 
7360Sstevel@tonic-gate 	/*
7370Sstevel@tonic-gate 	 * ACKNAK Latency Threshold Table.
7380Sstevel@tonic-gate 	 * See Fire PRM 2.0 section 1.2.12.2, table 1-17.
7390Sstevel@tonic-gate 	 */
7400Sstevel@tonic-gate 	int acknak_timer_table[LINK_MAX_PKT_ARR_SIZE][LINK_WIDTH_ARR_SIZE] = {
7410Sstevel@tonic-gate 		{0xED,   0x49,  0x43,  0x30},
7420Sstevel@tonic-gate 		{0x1A0,  0x76,  0x6B,  0x48},
7430Sstevel@tonic-gate 		{0x22F,  0x9A,  0x56,  0x56},
7440Sstevel@tonic-gate 		{0x42F,  0x11A, 0x96,  0x96},
7450Sstevel@tonic-gate 		{0x82F,  0x21A, 0x116, 0x116},
7460Sstevel@tonic-gate 		{0x102F, 0x41A, 0x216, 0x216}
7470Sstevel@tonic-gate 	};
7480Sstevel@tonic-gate 
7490Sstevel@tonic-gate 	/*
7500Sstevel@tonic-gate 	 * TxLink Replay Timer Latency Table
7510Sstevel@tonic-gate 	 * See Fire PRM 2.0 sections 1.2.12.3, table 1-18.
7520Sstevel@tonic-gate 	 */
7530Sstevel@tonic-gate 	int replay_timer_table[LINK_MAX_PKT_ARR_SIZE][LINK_WIDTH_ARR_SIZE] = {
7540Sstevel@tonic-gate 		{0x379,  0x112, 0xFC,  0xB4},
7550Sstevel@tonic-gate 		{0x618,  0x1BA, 0x192, 0x10E},
7560Sstevel@tonic-gate 		{0x831,  0x242, 0x143, 0x143},
7570Sstevel@tonic-gate 		{0xFB1,  0x422, 0x233, 0x233},
7580Sstevel@tonic-gate 		{0x1EB0, 0x7E1, 0x412, 0x412},
7590Sstevel@tonic-gate 		{0x3CB0, 0xF61, 0x7D2, 0x7D2}
7600Sstevel@tonic-gate 	};
761225Sess 
7620Sstevel@tonic-gate 	/*
7630Sstevel@tonic-gate 	 * Get the Link Width.  See table above LINK_WIDTH_ARR_SIZE #define
7640Sstevel@tonic-gate 	 * Only Link Widths of x1, x4, and x8 are supported.
7650Sstevel@tonic-gate 	 * If any width is reported other than x8, set default to x8.
7660Sstevel@tonic-gate 	 */
7670Sstevel@tonic-gate 	link_width = CSR_FR(csr_base, TLU_LINK_STATUS, WIDTH);
7680Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - Link Width: x%d\n", link_width);
7690Sstevel@tonic-gate 
7700Sstevel@tonic-gate 	/*
7710Sstevel@tonic-gate 	 * Convert link_width to match timer array configuration.
7720Sstevel@tonic-gate 	 */
7730Sstevel@tonic-gate 	switch (link_width) {
7740Sstevel@tonic-gate 	case 1:
7750Sstevel@tonic-gate 		link_width = 0;
7760Sstevel@tonic-gate 		break;
7770Sstevel@tonic-gate 	case 4:
7780Sstevel@tonic-gate 		link_width = 1;
7790Sstevel@tonic-gate 		break;
7800Sstevel@tonic-gate 	case 8:
7810Sstevel@tonic-gate 		link_width = 2;
7820Sstevel@tonic-gate 		break;
7830Sstevel@tonic-gate 	case 16:
7840Sstevel@tonic-gate 		link_width = 3;
7850Sstevel@tonic-gate 		break;
7860Sstevel@tonic-gate 	default:
7870Sstevel@tonic-gate 		link_width = 0;
7880Sstevel@tonic-gate 	}
7890Sstevel@tonic-gate 
7900Sstevel@tonic-gate 	/*
7910Sstevel@tonic-gate 	 * Get the Max Payload Size.
7920Sstevel@tonic-gate 	 * See table above LINK_MAX_PKT_ARR_SIZE #define
7930Sstevel@tonic-gate 	 */
794225Sess 	max_payload = ((CSR_FR(csr_base, TLU_CONTROL, CONFIG) &
795225Sess 	    TLU_CONTROL_MPS_MASK) >> TLU_CONTROL_MPS_SHIFT);
7960Sstevel@tonic-gate 
7970Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - May Payload: %d\n",
7980Sstevel@tonic-gate 	    (0x80 << max_payload));
7990Sstevel@tonic-gate 
8000Sstevel@tonic-gate 	/* Make sure the packet size is not greater than 4096 */
8010Sstevel@tonic-gate 	max_payload = (max_payload >= LINK_MAX_PKT_ARR_SIZE) ?
8020Sstevel@tonic-gate 	    (LINK_MAX_PKT_ARR_SIZE - 1) : max_payload;
8030Sstevel@tonic-gate 
8040Sstevel@tonic-gate 	/*
8050Sstevel@tonic-gate 	 * CSR_V LPU_ID Expect HW 0x0
8060Sstevel@tonic-gate 	 */
8070Sstevel@tonic-gate 
8080Sstevel@tonic-gate 	/*
8090Sstevel@tonic-gate 	 * This register has link id, phy id and gigablaze id.
8100Sstevel@tonic-gate 	 * Should be set by HW.
8110Sstevel@tonic-gate 	 */
8120Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - LPU_ID: 0x%llx\n",
81327Sjchu 	    CSR_XR(csr_base, LPU_ID));
8140Sstevel@tonic-gate 
8150Sstevel@tonic-gate 	/*
8160Sstevel@tonic-gate 	 * CSR_V LPU_RESET Expect Kernel 0x0
8170Sstevel@tonic-gate 	 */
8180Sstevel@tonic-gate 
8190Sstevel@tonic-gate 	/*
8200Sstevel@tonic-gate 	 * No reason to have any reset bits high until an error is
8210Sstevel@tonic-gate 	 * detected on the link.
8220Sstevel@tonic-gate 	 */
8230Sstevel@tonic-gate 	val = 0ull;
8240Sstevel@tonic-gate 	CSR_XS(csr_base, LPU_RESET, val);
8250Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - LPU_RESET: 0x%llx\n",
82627Sjchu 	    CSR_XR(csr_base, LPU_RESET));
8270Sstevel@tonic-gate 
8280Sstevel@tonic-gate 	/*
8290Sstevel@tonic-gate 	 * CSR_V LPU_DEBUG_STATUS Expect HW 0x0
8300Sstevel@tonic-gate 	 */
8310Sstevel@tonic-gate 
8320Sstevel@tonic-gate 	/*
8330Sstevel@tonic-gate 	 * Bits [15:8] are Debug B, and bit [7:0] are Debug A.
8340Sstevel@tonic-gate 	 * They are read-only.  What do the 8 bits mean, and
8350Sstevel@tonic-gate 	 * how do they get set if they are read only?
8360Sstevel@tonic-gate 	 */
8370Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - LPU_DEBUG_STATUS: 0x%llx\n",
83827Sjchu 	    CSR_XR(csr_base, LPU_DEBUG_STATUS));
8390Sstevel@tonic-gate 
8400Sstevel@tonic-gate 	/*
8410Sstevel@tonic-gate 	 * CSR_V LPU_DEBUG_CONFIG Expect Kernel 0x0
8420Sstevel@tonic-gate 	 */
8430Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - LPU_DEBUG_CONFIG: 0x%llx\n",
84427Sjchu 	    CSR_XR(csr_base, LPU_DEBUG_CONFIG));
8450Sstevel@tonic-gate 
8460Sstevel@tonic-gate 	/*
8470Sstevel@tonic-gate 	 * CSR_V LPU_LTSSM_CONTROL Expect HW 0x0
8480Sstevel@tonic-gate 	 */
8490Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - LPU_LTSSM_CONTROL: 0x%llx\n",
85027Sjchu 	    CSR_XR(csr_base, LPU_LTSSM_CONTROL));
8510Sstevel@tonic-gate 
8520Sstevel@tonic-gate 	/*
8530Sstevel@tonic-gate 	 * CSR_V LPU_LINK_STATUS Expect HW 0x101
8540Sstevel@tonic-gate 	 */
8550Sstevel@tonic-gate 
8560Sstevel@tonic-gate 	/*
8570Sstevel@tonic-gate 	 * This register has bits [9:4] for link width, and the
8580Sstevel@tonic-gate 	 * default 0x10, means a width of x16.  The problem is
8590Sstevel@tonic-gate 	 * this width is not supported according to the TLU
8600Sstevel@tonic-gate 	 * link status register.
8610Sstevel@tonic-gate 	 */
8620Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - LPU_LINK_STATUS: 0x%llx\n",
86327Sjchu 	    CSR_XR(csr_base, LPU_LINK_STATUS));
8640Sstevel@tonic-gate 
8650Sstevel@tonic-gate 	/*
8660Sstevel@tonic-gate 	 * CSR_V LPU_INTERRUPT_STATUS Expect HW 0x0
8670Sstevel@tonic-gate 	 */
8680Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - LPU_INTERRUPT_STATUS: 0x%llx\n",
86927Sjchu 	    CSR_XR(csr_base, LPU_INTERRUPT_STATUS));
8700Sstevel@tonic-gate 
8710Sstevel@tonic-gate 	/*
8720Sstevel@tonic-gate 	 * CSR_V LPU_INTERRUPT_MASK Expect HW 0x0
8730Sstevel@tonic-gate 	 */
8740Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - LPU_INTERRUPT_MASK: 0x%llx\n",
87527Sjchu 	    CSR_XR(csr_base, LPU_INTERRUPT_MASK));
8760Sstevel@tonic-gate 
8770Sstevel@tonic-gate 	/*
8780Sstevel@tonic-gate 	 * CSR_V LPU_LINK_PERFORMANCE_COUNTER_SELECT Expect HW 0x0
8790Sstevel@tonic-gate 	 */
8800Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
88127Sjchu 	    "lpu_init - LPU_LINK_PERFORMANCE_COUNTER_SELECT: 0x%llx\n",
88227Sjchu 	    CSR_XR(csr_base, LPU_LINK_PERFORMANCE_COUNTER_SELECT));
8830Sstevel@tonic-gate 
8840Sstevel@tonic-gate 	/*
8850Sstevel@tonic-gate 	 * CSR_V LPU_LINK_PERFORMANCE_COUNTER_CONTROL Expect HW 0x0
8860Sstevel@tonic-gate 	 */
8870Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
88827Sjchu 	    "lpu_init - LPU_LINK_PERFORMANCE_COUNTER_CONTROL: 0x%llx\n",
88927Sjchu 	    CSR_XR(csr_base, LPU_LINK_PERFORMANCE_COUNTER_CONTROL));
8900Sstevel@tonic-gate 
8910Sstevel@tonic-gate 	/*
8920Sstevel@tonic-gate 	 * CSR_V LPU_LINK_PERFORMANCE_COUNTER1 Expect HW 0x0
8930Sstevel@tonic-gate 	 */
8940Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
89527Sjchu 	    "lpu_init - LPU_LINK_PERFORMANCE_COUNTER1: 0x%llx\n",
89627Sjchu 	    CSR_XR(csr_base, LPU_LINK_PERFORMANCE_COUNTER1));
8970Sstevel@tonic-gate 
8980Sstevel@tonic-gate 	/*
8990Sstevel@tonic-gate 	 * CSR_V LPU_LINK_PERFORMANCE_COUNTER1_TEST Expect HW 0x0
9000Sstevel@tonic-gate 	 */
9010Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
90227Sjchu 	    "lpu_init - LPU_LINK_PERFORMANCE_COUNTER1_TEST: 0x%llx\n",
90327Sjchu 	    CSR_XR(csr_base, LPU_LINK_PERFORMANCE_COUNTER1_TEST));
9040Sstevel@tonic-gate 
9050Sstevel@tonic-gate 	/*
9060Sstevel@tonic-gate 	 * CSR_V LPU_LINK_PERFORMANCE_COUNTER2 Expect HW 0x0
9070Sstevel@tonic-gate 	 */
9080Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
90927Sjchu 	    "lpu_init - LPU_LINK_PERFORMANCE_COUNTER2: 0x%llx\n",
91027Sjchu 	    CSR_XR(csr_base, LPU_LINK_PERFORMANCE_COUNTER2));
9110Sstevel@tonic-gate 
9120Sstevel@tonic-gate 	/*
9130Sstevel@tonic-gate 	 * CSR_V LPU_LINK_PERFORMANCE_COUNTER2_TEST Expect HW 0x0
9140Sstevel@tonic-gate 	 */
9150Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
91627Sjchu 	    "lpu_init - LPU_LINK_PERFORMANCE_COUNTER2_TEST: 0x%llx\n",
91727Sjchu 	    CSR_XR(csr_base, LPU_LINK_PERFORMANCE_COUNTER2_TEST));
9180Sstevel@tonic-gate 
9190Sstevel@tonic-gate 	/*
9200Sstevel@tonic-gate 	 * CSR_V LPU_LINK_LAYER_CONFIG Expect HW 0x100
9210Sstevel@tonic-gate 	 */
9220Sstevel@tonic-gate 
9230Sstevel@tonic-gate 	/*
9240Sstevel@tonic-gate 	 * This is another place where Max Payload can be set,
9250Sstevel@tonic-gate 	 * this time for the link layer.  It will be set to
9260Sstevel@tonic-gate 	 * 128B, which is the default, but this will need to
9270Sstevel@tonic-gate 	 * be revisited.
9280Sstevel@tonic-gate 	 */
9290Sstevel@tonic-gate 	val = (1ull << LPU_LINK_LAYER_CONFIG_VC0_EN);
9300Sstevel@tonic-gate 	CSR_XS(csr_base, LPU_LINK_LAYER_CONFIG, val);
9310Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - LPU_LINK_LAYER_CONFIG: 0x%llx\n",
93227Sjchu 	    CSR_XR(csr_base, LPU_LINK_LAYER_CONFIG));
9330Sstevel@tonic-gate 
9340Sstevel@tonic-gate 	/*
9350Sstevel@tonic-gate 	 * CSR_V LPU_LINK_LAYER_STATUS Expect OBP 0x5
9360Sstevel@tonic-gate 	 */
9370Sstevel@tonic-gate 
9380Sstevel@tonic-gate 	/*
9390Sstevel@tonic-gate 	 * Another R/W status register.  Bit 3, DL up Status, will
9400Sstevel@tonic-gate 	 * be set high.  The link state machine status bits [2:0]
9410Sstevel@tonic-gate 	 * are set to 0x1, but the status bits are not defined in the
9420Sstevel@tonic-gate 	 * PRM.  What does 0x1 mean, what others values are possible
9430Sstevel@tonic-gate 	 * and what are thier meanings?
9440Sstevel@tonic-gate 	 *
9450Sstevel@tonic-gate 	 * This register has been giving us problems in simulation.
9460Sstevel@tonic-gate 	 * It has been mentioned that software should not program
9470Sstevel@tonic-gate 	 * any registers with WE bits except during debug.  So
9480Sstevel@tonic-gate 	 * this register will no longer be programmed.
9490Sstevel@tonic-gate 	 */
9500Sstevel@tonic-gate 
9510Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - LPU_LINK_LAYER_STATUS: 0x%llx\n",
95227Sjchu 	    CSR_XR(csr_base, LPU_LINK_LAYER_STATUS));
9530Sstevel@tonic-gate 
9540Sstevel@tonic-gate 	/*
9550Sstevel@tonic-gate 	 * CSR_V LPU_LINK_LAYER_INTERRUPT_AND_STATUS_TEST Expect HW 0x0
9560Sstevel@tonic-gate 	 */
9570Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
95827Sjchu 	    "lpu_init - LPU_LINK_LAYER_INTERRUPT_AND_STATUS_TEST: 0x%llx\n",
95927Sjchu 	    CSR_XR(csr_base, LPU_LINK_LAYER_INTERRUPT_AND_STATUS_TEST));
9600Sstevel@tonic-gate 
9610Sstevel@tonic-gate 	/*
96227Sjchu 	 * CSR_V LPU Link Layer interrupt regs (mask, status)
9630Sstevel@tonic-gate 	 */
9640Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
96527Sjchu 	    "lpu_init - LPU_LINK_LAYER_INTERRUPT_MASK: 0x%llx\n",
96627Sjchu 	    CSR_XR(csr_base, LPU_LINK_LAYER_INTERRUPT_MASK));
96727Sjchu 
96827Sjchu 	DBG(DBG_LPU, NULL,
96927Sjchu 	    "lpu_init - LPU_LINK_LAYER_INTERRUPT_AND_STATUS: 0x%llx\n",
97027Sjchu 	    CSR_XR(csr_base, LPU_LINK_LAYER_INTERRUPT_AND_STATUS));
9710Sstevel@tonic-gate 
9720Sstevel@tonic-gate 	/*
9730Sstevel@tonic-gate 	 * CSR_V LPU_FLOW_CONTROL_UPDATE_CONTROL Expect OBP 0x7
9740Sstevel@tonic-gate 	 */
9750Sstevel@tonic-gate 
9760Sstevel@tonic-gate 	/*
9770Sstevel@tonic-gate 	 * The PRM says that only the first two bits will be set
9780Sstevel@tonic-gate 	 * high by default, which will enable flow control for
9790Sstevel@tonic-gate 	 * posted and non-posted updates, but NOT completetion
9800Sstevel@tonic-gate 	 * updates.
9810Sstevel@tonic-gate 	 */
9820Sstevel@tonic-gate 	val = (1ull << LPU_FLOW_CONTROL_UPDATE_CONTROL_FC0_U_NP_EN) |
98327Sjchu 	    (1ull << LPU_FLOW_CONTROL_UPDATE_CONTROL_FC0_U_P_EN);
9840Sstevel@tonic-gate 	CSR_XS(csr_base, LPU_FLOW_CONTROL_UPDATE_CONTROL, val);
9850Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
98627Sjchu 	    "lpu_init - LPU_FLOW_CONTROL_UPDATE_CONTROL: 0x%llx\n",
98727Sjchu 	    CSR_XR(csr_base, LPU_FLOW_CONTROL_UPDATE_CONTROL));
9880Sstevel@tonic-gate 
9890Sstevel@tonic-gate 	/*
9900Sstevel@tonic-gate 	 * CSR_V LPU_LINK_LAYER_FLOW_CONTROL_UPDATE_TIMEOUT_VALUE
9910Sstevel@tonic-gate 	 * Expect OBP 0x1D4C
9920Sstevel@tonic-gate 	 */
9930Sstevel@tonic-gate 
9940Sstevel@tonic-gate 	/*
9950Sstevel@tonic-gate 	 * This should be set by OBP.  We'll check to make sure.
9960Sstevel@tonic-gate 	 */
99727Sjchu 	DBG(DBG_LPU, NULL, "lpu_init - "
99827Sjchu 	    "LPU_LINK_LAYER_FLOW_CONTROL_UPDATE_TIMEOUT_VALUE: 0x%llx\n",
99927Sjchu 	    CSR_XR(csr_base,
100027Sjchu 	    LPU_LINK_LAYER_FLOW_CONTROL_UPDATE_TIMEOUT_VALUE));
10010Sstevel@tonic-gate 
10020Sstevel@tonic-gate 	/*
10030Sstevel@tonic-gate 	 * CSR_V LPU_LINK_LAYER_VC0_FLOW_CONTROL_UPDATE_TIMER0 Expect OBP ???
10040Sstevel@tonic-gate 	 */
10050Sstevel@tonic-gate 
10060Sstevel@tonic-gate 	/*
10070Sstevel@tonic-gate 	 * This register has Flow Control Update Timer values for
10080Sstevel@tonic-gate 	 * non-posted and posted requests, bits [30:16] and bits
10090Sstevel@tonic-gate 	 * [14:0], respectively.  These are read-only to SW so
10100Sstevel@tonic-gate 	 * either HW or OBP needs to set them.
10110Sstevel@tonic-gate 	 */
101227Sjchu 	DBG(DBG_LPU, NULL, "lpu_init - "
101327Sjchu 	    "LPU_LINK_LAYER_VC0_FLOW_CONTROL_UPDATE_TIMER0: 0x%llx\n",
101427Sjchu 	    CSR_XR(csr_base,
101527Sjchu 	    LPU_LINK_LAYER_VC0_FLOW_CONTROL_UPDATE_TIMER0));
10160Sstevel@tonic-gate 
10170Sstevel@tonic-gate 	/*
10180Sstevel@tonic-gate 	 * CSR_V LPU_LINK_LAYER_VC0_FLOW_CONTROL_UPDATE_TIMER1 Expect OBP ???
10190Sstevel@tonic-gate 	 */
10200Sstevel@tonic-gate 
10210Sstevel@tonic-gate 	/*
10220Sstevel@tonic-gate 	 * Same as timer0 register above, except for bits [14:0]
10230Sstevel@tonic-gate 	 * have the timer values for completetions.  Read-only to
10240Sstevel@tonic-gate 	 * SW; OBP or HW need to set it.
10250Sstevel@tonic-gate 	 */
102627Sjchu 	DBG(DBG_LPU, NULL, "lpu_init - "
102727Sjchu 	    "LPU_LINK_LAYER_VC0_FLOW_CONTROL_UPDATE_TIMER1: 0x%llx\n",
102827Sjchu 	    CSR_XR(csr_base,
102927Sjchu 	    LPU_LINK_LAYER_VC0_FLOW_CONTROL_UPDATE_TIMER1));
10300Sstevel@tonic-gate 
10310Sstevel@tonic-gate 	/*
10320Sstevel@tonic-gate 	 * CSR_V LPU_TXLINK_FREQUENT_NAK_LATENCY_TIMER_THRESHOLD
10330Sstevel@tonic-gate 	 */
1034225Sess 	val = acknak_timer_table[max_payload][link_width];
1035225Sess 	CSR_XS(csr_base, LPU_TXLINK_FREQUENT_NAK_LATENCY_TIMER_THRESHOLD, val);
10360Sstevel@tonic-gate 
10370Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - "
10380Sstevel@tonic-gate 	    "LPU_TXLINK_FREQUENT_NAK_LATENCY_TIMER_THRESHOLD: 0x%llx\n",
10390Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_TXLINK_FREQUENT_NAK_LATENCY_TIMER_THRESHOLD));
10400Sstevel@tonic-gate 
10410Sstevel@tonic-gate 	/*
10420Sstevel@tonic-gate 	 * CSR_V LPU_TXLINK_ACKNAK_LATENCY_TIMER Expect HW 0x0
10430Sstevel@tonic-gate 	 */
10440Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
104527Sjchu 	    "lpu_init - LPU_TXLINK_ACKNAK_LATENCY_TIMER: 0x%llx\n",
104627Sjchu 	    CSR_XR(csr_base, LPU_TXLINK_ACKNAK_LATENCY_TIMER));
10470Sstevel@tonic-gate 
10480Sstevel@tonic-gate 	/*
10490Sstevel@tonic-gate 	 * CSR_V LPU_TXLINK_REPLAY_TIMER_THRESHOLD
10500Sstevel@tonic-gate 	 */
1051225Sess 	val = replay_timer_table[max_payload][link_width];
10520Sstevel@tonic-gate 	CSR_XS(csr_base, LPU_TXLINK_REPLAY_TIMER_THRESHOLD, val);
10530Sstevel@tonic-gate 
10540Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
10550Sstevel@tonic-gate 	    "lpu_init - LPU_TXLINK_REPLAY_TIMER_THRESHOLD: 0x%llx\n",
10560Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_TXLINK_REPLAY_TIMER_THRESHOLD));
10570Sstevel@tonic-gate 
10580Sstevel@tonic-gate 	/*
10590Sstevel@tonic-gate 	 * CSR_V LPU_TXLINK_REPLAY_TIMER Expect HW 0x0
10600Sstevel@tonic-gate 	 */
10610Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - LPU_TXLINK_REPLAY_TIMER: 0x%llx\n",
106227Sjchu 	    CSR_XR(csr_base, LPU_TXLINK_REPLAY_TIMER));
10630Sstevel@tonic-gate 
10640Sstevel@tonic-gate 	/*
10650Sstevel@tonic-gate 	 * CSR_V LPU_TXLINK_REPLAY_NUMBER_STATUS Expect OBP 0x3
10660Sstevel@tonic-gate 	 */
10670Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
106827Sjchu 	    "lpu_init - LPU_TXLINK_REPLAY_NUMBER_STATUS: 0x%llx\n",
106927Sjchu 	    CSR_XR(csr_base, LPU_TXLINK_REPLAY_NUMBER_STATUS));
10700Sstevel@tonic-gate 
10710Sstevel@tonic-gate 	/*
10720Sstevel@tonic-gate 	 * CSR_V LPU_REPLAY_BUFFER_MAX_ADDRESS Expect OBP 0xB3F
10730Sstevel@tonic-gate 	 */
10740Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
10750Sstevel@tonic-gate 	    "lpu_init - LPU_REPLAY_BUFFER_MAX_ADDRESS: 0x%llx\n",
10760Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_REPLAY_BUFFER_MAX_ADDRESS));
10770Sstevel@tonic-gate 
10780Sstevel@tonic-gate 	/*
10790Sstevel@tonic-gate 	 * CSR_V LPU_TXLINK_RETRY_FIFO_POINTER Expect OBP 0xFFFF0000
10800Sstevel@tonic-gate 	 */
10810Sstevel@tonic-gate 	val = ((LPU_TXLINK_RETRY_FIFO_POINTER_RTRY_FIFO_TLPTR_DEFAULT <<
108227Sjchu 	    LPU_TXLINK_RETRY_FIFO_POINTER_RTRY_FIFO_TLPTR) |
108327Sjchu 	    (LPU_TXLINK_RETRY_FIFO_POINTER_RTRY_FIFO_HDPTR_DEFAULT <<
108427Sjchu 	    LPU_TXLINK_RETRY_FIFO_POINTER_RTRY_FIFO_HDPTR));
10850Sstevel@tonic-gate 
10860Sstevel@tonic-gate 	CSR_XS(csr_base, LPU_TXLINK_RETRY_FIFO_POINTER, val);
10870Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
108827Sjchu 	    "lpu_init - LPU_TXLINK_RETRY_FIFO_POINTER: 0x%llx\n",
108927Sjchu 	    CSR_XR(csr_base, LPU_TXLINK_RETRY_FIFO_POINTER));
10900Sstevel@tonic-gate 
10910Sstevel@tonic-gate 	/*
10920Sstevel@tonic-gate 	 * CSR_V LPU_TXLINK_RETRY_FIFO_R_W_POINTER Expect OBP 0x0
10930Sstevel@tonic-gate 	 */
10940Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
10950Sstevel@tonic-gate 	    "lpu_init - LPU_TXLINK_RETRY_FIFO_R_W_POINTER: 0x%llx\n",
10960Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_TXLINK_RETRY_FIFO_R_W_POINTER));
10970Sstevel@tonic-gate 
10980Sstevel@tonic-gate 	/*
10990Sstevel@tonic-gate 	 * CSR_V LPU_TXLINK_RETRY_FIFO_CREDIT Expect HW 0x1580
11000Sstevel@tonic-gate 	 */
11010Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
110227Sjchu 	    "lpu_init - LPU_TXLINK_RETRY_FIFO_CREDIT: 0x%llx\n",
110327Sjchu 	    CSR_XR(csr_base, LPU_TXLINK_RETRY_FIFO_CREDIT));
11040Sstevel@tonic-gate 
11050Sstevel@tonic-gate 	/*
11060Sstevel@tonic-gate 	 * CSR_V LPU_TXLINK_SEQUENCE_COUNTER Expect OBP 0xFFF0000
11070Sstevel@tonic-gate 	 */
11080Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - LPU_TXLINK_SEQUENCE_COUNTER: 0x%llx\n",
110927Sjchu 	    CSR_XR(csr_base, LPU_TXLINK_SEQUENCE_COUNTER));
11100Sstevel@tonic-gate 
11110Sstevel@tonic-gate 	/*
11120Sstevel@tonic-gate 	 * CSR_V LPU_TXLINK_ACK_SENT_SEQUENCE_NUMBER Expect HW 0xFFF
11130Sstevel@tonic-gate 	 */
11140Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
111527Sjchu 	    "lpu_init - LPU_TXLINK_ACK_SENT_SEQUENCE_NUMBER: 0x%llx\n",
111627Sjchu 	    CSR_XR(csr_base, LPU_TXLINK_ACK_SENT_SEQUENCE_NUMBER));
11170Sstevel@tonic-gate 
11180Sstevel@tonic-gate 	/*
11190Sstevel@tonic-gate 	 * CSR_V LPU_TXLINK_SEQUENCE_COUNT_FIFO_MAX_ADDR Expect OBP 0x157
11200Sstevel@tonic-gate 	 */
11210Sstevel@tonic-gate 
11220Sstevel@tonic-gate 	/*
11230Sstevel@tonic-gate 	 * Test only register.  Will not be programmed.
11240Sstevel@tonic-gate 	 */
11250Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
112627Sjchu 	    "lpu_init - LPU_TXLINK_SEQUENCE_COUNT_FIFO_MAX_ADDR: 0x%llx\n",
112727Sjchu 	    CSR_XR(csr_base, LPU_TXLINK_SEQUENCE_COUNT_FIFO_MAX_ADDR));
11280Sstevel@tonic-gate 
11290Sstevel@tonic-gate 	/*
11300Sstevel@tonic-gate 	 * CSR_V LPU_TXLINK_SEQUENCE_COUNT_FIFO_POINTERS Expect HW 0xFFF0000
11310Sstevel@tonic-gate 	 */
11320Sstevel@tonic-gate 
11330Sstevel@tonic-gate 	/*
11340Sstevel@tonic-gate 	 * Test only register.  Will not be programmed.
11350Sstevel@tonic-gate 	 */
11360Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
113727Sjchu 	    "lpu_init - LPU_TXLINK_SEQUENCE_COUNT_FIFO_POINTERS: 0x%llx\n",
113827Sjchu 	    CSR_XR(csr_base, LPU_TXLINK_SEQUENCE_COUNT_FIFO_POINTERS));
11390Sstevel@tonic-gate 
11400Sstevel@tonic-gate 	/*
11410Sstevel@tonic-gate 	 * CSR_V LPU_TXLINK_SEQUENCE_COUNT_R_W_POINTERS Expect HW 0x0
11420Sstevel@tonic-gate 	 */
11430Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
114427Sjchu 	    "lpu_init - LPU_TXLINK_SEQUENCE_COUNT_R_W_POINTERS: 0x%llx\n",
114527Sjchu 	    CSR_XR(csr_base, LPU_TXLINK_SEQUENCE_COUNT_R_W_POINTERS));
11460Sstevel@tonic-gate 
11470Sstevel@tonic-gate 	/*
11480Sstevel@tonic-gate 	 * CSR_V LPU_TXLINK_TEST_CONTROL Expect HW 0x0
11490Sstevel@tonic-gate 	 */
11500Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - LPU_TXLINK_TEST_CONTROL: 0x%llx\n",
115127Sjchu 	    CSR_XR(csr_base, LPU_TXLINK_TEST_CONTROL));
11520Sstevel@tonic-gate 
11530Sstevel@tonic-gate 	/*
11540Sstevel@tonic-gate 	 * CSR_V LPU_TXLINK_MEMORY_ADDRESS_CONTROL Expect HW 0x0
11550Sstevel@tonic-gate 	 */
11560Sstevel@tonic-gate 
11570Sstevel@tonic-gate 	/*
11580Sstevel@tonic-gate 	 * Test only register.  Will not be programmed.
11590Sstevel@tonic-gate 	 */
11600Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
11610Sstevel@tonic-gate 	    "lpu_init - LPU_TXLINK_MEMORY_ADDRESS_CONTROL: 0x%llx\n",
11620Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_TXLINK_MEMORY_ADDRESS_CONTROL));
11630Sstevel@tonic-gate 
11640Sstevel@tonic-gate 	/*
11650Sstevel@tonic-gate 	 * CSR_V LPU_TXLINK_MEMORY_DATA_LOAD0 Expect HW 0x0
11660Sstevel@tonic-gate 	 */
11670Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
116827Sjchu 	    "lpu_init - LPU_TXLINK_MEMORY_DATA_LOAD0: 0x%llx\n",
116927Sjchu 	    CSR_XR(csr_base, LPU_TXLINK_MEMORY_DATA_LOAD0));
11700Sstevel@tonic-gate 
11710Sstevel@tonic-gate 	/*
11720Sstevel@tonic-gate 	 * CSR_V LPU_TXLINK_MEMORY_DATA_LOAD1 Expect HW 0x0
11730Sstevel@tonic-gate 	 */
11740Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
117527Sjchu 	    "lpu_init - LPU_TXLINK_MEMORY_DATA_LOAD1: 0x%llx\n",
117627Sjchu 	    CSR_XR(csr_base, LPU_TXLINK_MEMORY_DATA_LOAD1));
11770Sstevel@tonic-gate 
11780Sstevel@tonic-gate 	/*
11790Sstevel@tonic-gate 	 * CSR_V LPU_TXLINK_MEMORY_DATA_LOAD2 Expect HW 0x0
11800Sstevel@tonic-gate 	 */
11810Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
118227Sjchu 	    "lpu_init - LPU_TXLINK_MEMORY_DATA_LOAD2: 0x%llx\n",
118327Sjchu 	    CSR_XR(csr_base, LPU_TXLINK_MEMORY_DATA_LOAD2));
11840Sstevel@tonic-gate 
11850Sstevel@tonic-gate 	/*
11860Sstevel@tonic-gate 	 * CSR_V LPU_TXLINK_MEMORY_DATA_LOAD3 Expect HW 0x0
11870Sstevel@tonic-gate 	 */
11880Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
118927Sjchu 	    "lpu_init - LPU_TXLINK_MEMORY_DATA_LOAD3: 0x%llx\n",
119027Sjchu 	    CSR_XR(csr_base, LPU_TXLINK_MEMORY_DATA_LOAD3));
11910Sstevel@tonic-gate 
11920Sstevel@tonic-gate 	/*
11930Sstevel@tonic-gate 	 * CSR_V LPU_TXLINK_MEMORY_DATA_LOAD4 Expect HW 0x0
11940Sstevel@tonic-gate 	 */
11950Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
119627Sjchu 	    "lpu_init - LPU_TXLINK_MEMORY_DATA_LOAD4: 0x%llx\n",
119727Sjchu 	    CSR_XR(csr_base, LPU_TXLINK_MEMORY_DATA_LOAD4));
11980Sstevel@tonic-gate 
11990Sstevel@tonic-gate 	/*
12000Sstevel@tonic-gate 	 * CSR_V LPU_TXLINK_RETRY_DATA_COUNT Expect HW 0x0
12010Sstevel@tonic-gate 	 */
12020Sstevel@tonic-gate 
12030Sstevel@tonic-gate 	/*
12040Sstevel@tonic-gate 	 * Test only register.  Will not be programmed.
12050Sstevel@tonic-gate 	 */
12060Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - LPU_TXLINK_RETRY_DATA_COUNT: 0x%llx\n",
120727Sjchu 	    CSR_XR(csr_base, LPU_TXLINK_RETRY_DATA_COUNT));
12080Sstevel@tonic-gate 
12090Sstevel@tonic-gate 	/*
12100Sstevel@tonic-gate 	 * CSR_V LPU_TXLINK_SEQUENCE_BUFFER_COUNT Expect HW 0x0
12110Sstevel@tonic-gate 	 */
12120Sstevel@tonic-gate 
12130Sstevel@tonic-gate 	/*
12140Sstevel@tonic-gate 	 * Test only register.  Will not be programmed.
12150Sstevel@tonic-gate 	 */
12160Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
121727Sjchu 	    "lpu_init - LPU_TXLINK_SEQUENCE_BUFFER_COUNT: 0x%llx\n",
121827Sjchu 	    CSR_XR(csr_base, LPU_TXLINK_SEQUENCE_BUFFER_COUNT));
12190Sstevel@tonic-gate 
12200Sstevel@tonic-gate 	/*
12210Sstevel@tonic-gate 	 * CSR_V LPU_TXLINK_SEQUENCE_BUFFER_BOTTOM_DATA Expect HW 0x0
12220Sstevel@tonic-gate 	 */
12230Sstevel@tonic-gate 
12240Sstevel@tonic-gate 	/*
12250Sstevel@tonic-gate 	 * Test only register.
12260Sstevel@tonic-gate 	 */
12270Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
122827Sjchu 	    "lpu_init - LPU_TXLINK_SEQUENCE_BUFFER_BOTTOM_DATA: 0x%llx\n",
122927Sjchu 	    CSR_XR(csr_base, LPU_TXLINK_SEQUENCE_BUFFER_BOTTOM_DATA));
12300Sstevel@tonic-gate 
12310Sstevel@tonic-gate 	/*
12320Sstevel@tonic-gate 	 * CSR_V LPU_RXLINK_NEXT_RECEIVE_SEQUENCE_1_COUNTER Expect HW 0x0
12330Sstevel@tonic-gate 	 */
12340Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - "
123527Sjchu 	    "LPU_RXLINK_NEXT_RECEIVE_SEQUENCE_1_COUNTER: 0x%llx\n",
123627Sjchu 	    CSR_XR(csr_base, LPU_RXLINK_NEXT_RECEIVE_SEQUENCE_1_COUNTER));
12370Sstevel@tonic-gate 
12380Sstevel@tonic-gate 	/*
12390Sstevel@tonic-gate 	 * CSR_V LPU_RXLINK_UNSUPPORTED_DLLP_RECEIVED Expect HW 0x0
12400Sstevel@tonic-gate 	 */
12410Sstevel@tonic-gate 
12420Sstevel@tonic-gate 	/*
12430Sstevel@tonic-gate 	 * test only register.
12440Sstevel@tonic-gate 	 */
12450Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
124627Sjchu 	    "lpu_init - LPU_RXLINK_UNSUPPORTED_DLLP_RECEIVED: 0x%llx\n",
124727Sjchu 	    CSR_XR(csr_base, LPU_RXLINK_UNSUPPORTED_DLLP_RECEIVED));
12480Sstevel@tonic-gate 
12490Sstevel@tonic-gate 	/*
12500Sstevel@tonic-gate 	 * CSR_V LPU_RXLINK_TEST_CONTROL Expect HW 0x0
12510Sstevel@tonic-gate 	 */
12520Sstevel@tonic-gate 
12530Sstevel@tonic-gate 	/*
12540Sstevel@tonic-gate 	 * test only register.
12550Sstevel@tonic-gate 	 */
12560Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - LPU_RXLINK_TEST_CONTROL: 0x%llx\n",
125727Sjchu 	    CSR_XR(csr_base, LPU_RXLINK_TEST_CONTROL));
12580Sstevel@tonic-gate 
12590Sstevel@tonic-gate 	/*
12600Sstevel@tonic-gate 	 * CSR_V LPU_PHYSICAL_LAYER_CONFIGURATION Expect HW 0x10
12610Sstevel@tonic-gate 	 */
12620Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
126327Sjchu 	    "lpu_init - LPU_PHYSICAL_LAYER_CONFIGURATION: 0x%llx\n",
126427Sjchu 	    CSR_XR(csr_base, LPU_PHYSICAL_LAYER_CONFIGURATION));
12650Sstevel@tonic-gate 
12660Sstevel@tonic-gate 	/*
12670Sstevel@tonic-gate 	 * CSR_V LPU_PHY_LAYER_STATUS Expect HW 0x0
12680Sstevel@tonic-gate 	 */
12690Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - LPU_PHY_LAYER_STATUS: 0x%llx\n",
127027Sjchu 	    CSR_XR(csr_base, LPU_PHY_LAYER_STATUS));
12710Sstevel@tonic-gate 
12720Sstevel@tonic-gate 	/*
12730Sstevel@tonic-gate 	 * CSR_V LPU_PHY_INTERRUPT_AND_STATUS_TEST Expect HW 0x0
12740Sstevel@tonic-gate 	 */
12750Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
12760Sstevel@tonic-gate 	    "lpu_init - LPU_PHY_INTERRUPT_AND_STATUS_TEST: 0x%llx\n",
12770Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_PHY_INTERRUPT_AND_STATUS_TEST));
12780Sstevel@tonic-gate 
12790Sstevel@tonic-gate 	/*
128027Sjchu 	 * CSR_V LPU PHY LAYER interrupt regs (mask, status)
12810Sstevel@tonic-gate 	 */
12820Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - LPU_PHY_INTERRUPT_MASK: 0x%llx\n",
128327Sjchu 	    CSR_XR(csr_base, LPU_PHY_INTERRUPT_MASK));
128427Sjchu 
128527Sjchu 	DBG(DBG_LPU, NULL,
128627Sjchu 	    "lpu_init - LPU_PHY_LAYER_INTERRUPT_AND_STATUS: 0x%llx\n",
128727Sjchu 	    CSR_XR(csr_base, LPU_PHY_LAYER_INTERRUPT_AND_STATUS));
12880Sstevel@tonic-gate 
12890Sstevel@tonic-gate 	/*
12900Sstevel@tonic-gate 	 * CSR_V LPU_RECEIVE_PHY_CONFIG Expect HW 0x0
12910Sstevel@tonic-gate 	 */
12920Sstevel@tonic-gate 
12930Sstevel@tonic-gate 	/*
12940Sstevel@tonic-gate 	 * This also needs some explanation.  What is the best value
12950Sstevel@tonic-gate 	 * for the water mark?  Test mode enables which test mode?
12960Sstevel@tonic-gate 	 * Programming model needed for the Receiver Reset Lane N
12970Sstevel@tonic-gate 	 * bits.
12980Sstevel@tonic-gate 	 */
12990Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - LPU_RECEIVE_PHY_CONFIG: 0x%llx\n",
130027Sjchu 	    CSR_XR(csr_base, LPU_RECEIVE_PHY_CONFIG));
13010Sstevel@tonic-gate 
13020Sstevel@tonic-gate 	/*
13030Sstevel@tonic-gate 	 * CSR_V LPU_RECEIVE_PHY_STATUS1 Expect HW 0x0
13040Sstevel@tonic-gate 	 */
13050Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - LPU_RECEIVE_PHY_STATUS1: 0x%llx\n",
130627Sjchu 	    CSR_XR(csr_base, LPU_RECEIVE_PHY_STATUS1));
13070Sstevel@tonic-gate 
13080Sstevel@tonic-gate 	/*
13090Sstevel@tonic-gate 	 * CSR_V LPU_RECEIVE_PHY_STATUS2 Expect HW 0x0
13100Sstevel@tonic-gate 	 */
13110Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - LPU_RECEIVE_PHY_STATUS2: 0x%llx\n",
131227Sjchu 	    CSR_XR(csr_base, LPU_RECEIVE_PHY_STATUS2));
13130Sstevel@tonic-gate 
13140Sstevel@tonic-gate 	/*
13150Sstevel@tonic-gate 	 * CSR_V LPU_RECEIVE_PHY_STATUS3 Expect HW 0x0
13160Sstevel@tonic-gate 	 */
13170Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - LPU_RECEIVE_PHY_STATUS3: 0x%llx\n",
131827Sjchu 	    CSR_XR(csr_base, LPU_RECEIVE_PHY_STATUS3));
13190Sstevel@tonic-gate 
13200Sstevel@tonic-gate 	/*
13210Sstevel@tonic-gate 	 * CSR_V LPU_RECEIVE_PHY_INTERRUPT_AND_STATUS_TEST Expect HW 0x0
13220Sstevel@tonic-gate 	 */
13230Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
13240Sstevel@tonic-gate 	    "lpu_init - LPU_RECEIVE_PHY_INTERRUPT_AND_STATUS_TEST: 0x%llx\n",
13250Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_RECEIVE_PHY_INTERRUPT_AND_STATUS_TEST));
13260Sstevel@tonic-gate 
13270Sstevel@tonic-gate 	/*
132827Sjchu 	 * CSR_V LPU RX LAYER interrupt regs (mask, status)
13290Sstevel@tonic-gate 	 */
13300Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
133127Sjchu 	    "lpu_init - LPU_RECEIVE_PHY_INTERRUPT_MASK: 0x%llx\n",
133227Sjchu 	    CSR_XR(csr_base, LPU_RECEIVE_PHY_INTERRUPT_MASK));
133327Sjchu 
133427Sjchu 	DBG(DBG_LPU, NULL,
133527Sjchu 	    "lpu_init - LPU_RECEIVE_PHY_INTERRUPT_AND_STATUS: 0x%llx\n",
133627Sjchu 	    CSR_XR(csr_base, LPU_RECEIVE_PHY_INTERRUPT_AND_STATUS));
13370Sstevel@tonic-gate 
13380Sstevel@tonic-gate 	/*
13390Sstevel@tonic-gate 	 * CSR_V LPU_TRANSMIT_PHY_CONFIG Expect HW 0x0
13400Sstevel@tonic-gate 	 */
13410Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - LPU_TRANSMIT_PHY_CONFIG: 0x%llx\n",
134227Sjchu 	    CSR_XR(csr_base, LPU_TRANSMIT_PHY_CONFIG));
13430Sstevel@tonic-gate 
13440Sstevel@tonic-gate 	/*
13450Sstevel@tonic-gate 	 * CSR_V LPU_TRANSMIT_PHY_STATUS Expect HW 0x0
13460Sstevel@tonic-gate 	 */
13470Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - LPU_TRANSMIT_PHY_STATUS: 0x%llx\n",
13486953Sanbui 	    CSR_XR(csr_base, LPU_TRANSMIT_PHY_STATUS));
13490Sstevel@tonic-gate 
13500Sstevel@tonic-gate 	/*
13510Sstevel@tonic-gate 	 * CSR_V LPU_TRANSMIT_PHY_INTERRUPT_AND_STATUS_TEST Expect HW 0x0
13520Sstevel@tonic-gate 	 */
13530Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
13540Sstevel@tonic-gate 	    "lpu_init - LPU_TRANSMIT_PHY_INTERRUPT_AND_STATUS_TEST: 0x%llx\n",
13550Sstevel@tonic-gate 	    CSR_XR(csr_base,
13560Sstevel@tonic-gate 	    LPU_TRANSMIT_PHY_INTERRUPT_AND_STATUS_TEST));
13570Sstevel@tonic-gate 
13580Sstevel@tonic-gate 	/*
135927Sjchu 	 * CSR_V LPU TX LAYER interrupt regs (mask, status)
13600Sstevel@tonic-gate 	 */
13610Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
136227Sjchu 	    "lpu_init - LPU_TRANSMIT_PHY_INTERRUPT_MASK: 0x%llx\n",
136327Sjchu 	    CSR_XR(csr_base, LPU_TRANSMIT_PHY_INTERRUPT_MASK));
136427Sjchu 
136527Sjchu 	DBG(DBG_LPU, NULL,
136627Sjchu 	    "lpu_init - LPU_TRANSMIT_PHY_INTERRUPT_AND_STATUS: 0x%llx\n",
136727Sjchu 	    CSR_XR(csr_base, LPU_TRANSMIT_PHY_INTERRUPT_AND_STATUS));
13680Sstevel@tonic-gate 
13690Sstevel@tonic-gate 	/*
13700Sstevel@tonic-gate 	 * CSR_V LPU_TRANSMIT_PHY_STATUS_2 Expect HW 0x0
13710Sstevel@tonic-gate 	 */
13720Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - LPU_TRANSMIT_PHY_STATUS_2: 0x%llx\n",
137327Sjchu 	    CSR_XR(csr_base, LPU_TRANSMIT_PHY_STATUS_2));
13740Sstevel@tonic-gate 
13750Sstevel@tonic-gate 	/*
13760Sstevel@tonic-gate 	 * CSR_V LPU_LTSSM_CONFIG1 Expect OBP 0x205
13770Sstevel@tonic-gate 	 */
13780Sstevel@tonic-gate 
13790Sstevel@tonic-gate 	/*
13800Sstevel@tonic-gate 	 * The new PRM has values for LTSSM 8 ns timeout value and
13810Sstevel@tonic-gate 	 * LTSSM 20 ns timeout value.  But what do these values mean?
13820Sstevel@tonic-gate 	 * Most of the other bits are questions as well.
13830Sstevel@tonic-gate 	 *
13840Sstevel@tonic-gate 	 * As such we will use the reset value.
13850Sstevel@tonic-gate 	 */
13860Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - LPU_LTSSM_CONFIG1: 0x%llx\n",
138727Sjchu 	    CSR_XR(csr_base, LPU_LTSSM_CONFIG1));
13880Sstevel@tonic-gate 
13890Sstevel@tonic-gate 	/*
13900Sstevel@tonic-gate 	 * CSR_V LPU_LTSSM_CONFIG2 Expect OBP 0x2DC6C0
13910Sstevel@tonic-gate 	 */
13920Sstevel@tonic-gate 
13930Sstevel@tonic-gate 	/*
13940Sstevel@tonic-gate 	 * Again, what does '12 ms timeout value mean'?
13950Sstevel@tonic-gate 	 */
13960Sstevel@tonic-gate 	val = (LPU_LTSSM_CONFIG2_LTSSM_12_TO_DEFAULT <<
139727Sjchu 	    LPU_LTSSM_CONFIG2_LTSSM_12_TO);
13980Sstevel@tonic-gate 	CSR_XS(csr_base, LPU_LTSSM_CONFIG2, val);
13990Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - LPU_LTSSM_CONFIG2: 0x%llx\n",
140027Sjchu 	    CSR_XR(csr_base, LPU_LTSSM_CONFIG2));
14010Sstevel@tonic-gate 
14020Sstevel@tonic-gate 	/*
14030Sstevel@tonic-gate 	 * CSR_V LPU_LTSSM_CONFIG3 Expect OBP 0x7A120
14040Sstevel@tonic-gate 	 */
14050Sstevel@tonic-gate 	val = (LPU_LTSSM_CONFIG3_LTSSM_2_TO_DEFAULT <<
140627Sjchu 	    LPU_LTSSM_CONFIG3_LTSSM_2_TO);
14070Sstevel@tonic-gate 	CSR_XS(csr_base, LPU_LTSSM_CONFIG3, val);
14080Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - LPU_LTSSM_CONFIG3: 0x%llx\n",
140927Sjchu 	    CSR_XR(csr_base, LPU_LTSSM_CONFIG3));
14100Sstevel@tonic-gate 
14110Sstevel@tonic-gate 	/*
14120Sstevel@tonic-gate 	 * CSR_V LPU_LTSSM_CONFIG4 Expect OBP 0x21300
14130Sstevel@tonic-gate 	 */
14140Sstevel@tonic-gate 	val = ((LPU_LTSSM_CONFIG4_DATA_RATE_DEFAULT <<
141527Sjchu 	    LPU_LTSSM_CONFIG4_DATA_RATE) |
14166953Sanbui 	    (LPU_LTSSM_CONFIG4_N_FTS_DEFAULT <<
14176953Sanbui 	    LPU_LTSSM_CONFIG4_N_FTS));
14180Sstevel@tonic-gate 	CSR_XS(csr_base, LPU_LTSSM_CONFIG4, val);
14190Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - LPU_LTSSM_CONFIG4: 0x%llx\n",
142027Sjchu 	    CSR_XR(csr_base, LPU_LTSSM_CONFIG4));
14210Sstevel@tonic-gate 
14220Sstevel@tonic-gate 	/*
14230Sstevel@tonic-gate 	 * CSR_V LPU_LTSSM_CONFIG5 Expect OBP 0x0
14240Sstevel@tonic-gate 	 */
14250Sstevel@tonic-gate 	val = 0ull;
14260Sstevel@tonic-gate 	CSR_XS(csr_base, LPU_LTSSM_CONFIG5, val);
14270Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - LPU_LTSSM_CONFIG5: 0x%llx\n",
142827Sjchu 	    CSR_XR(csr_base, LPU_LTSSM_CONFIG5));
14290Sstevel@tonic-gate 
14300Sstevel@tonic-gate 	/*
14310Sstevel@tonic-gate 	 * CSR_V LPU_LTSSM_STATUS1 Expect OBP 0x0
14320Sstevel@tonic-gate 	 */
14330Sstevel@tonic-gate 
14340Sstevel@tonic-gate 	/*
14350Sstevel@tonic-gate 	 * LTSSM Status registers are test only.
14360Sstevel@tonic-gate 	 */
14370Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - LPU_LTSSM_STATUS1: 0x%llx\n",
143827Sjchu 	    CSR_XR(csr_base, LPU_LTSSM_STATUS1));
14390Sstevel@tonic-gate 
14400Sstevel@tonic-gate 	/*
14410Sstevel@tonic-gate 	 * CSR_V LPU_LTSSM_STATUS2 Expect OBP 0x0
14420Sstevel@tonic-gate 	 */
14430Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - LPU_LTSSM_STATUS2: 0x%llx\n",
144427Sjchu 	    CSR_XR(csr_base, LPU_LTSSM_STATUS2));
14450Sstevel@tonic-gate 
14460Sstevel@tonic-gate 	/*
14470Sstevel@tonic-gate 	 * CSR_V LPU_LTSSM_INTERRUPT_AND_STATUS_TEST Expect HW 0x0
14480Sstevel@tonic-gate 	 */
14490Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
145027Sjchu 	    "lpu_init - LPU_LTSSM_INTERRUPT_AND_STATUS_TEST: 0x%llx\n",
145127Sjchu 	    CSR_XR(csr_base, LPU_LTSSM_INTERRUPT_AND_STATUS_TEST));
14520Sstevel@tonic-gate 
14530Sstevel@tonic-gate 	/*
145427Sjchu 	 * CSR_V LPU LTSSM  LAYER interrupt regs (mask, status)
14550Sstevel@tonic-gate 	 */
14560Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - LPU_LTSSM_INTERRUPT_MASK: 0x%llx\n",
145727Sjchu 	    CSR_XR(csr_base, LPU_LTSSM_INTERRUPT_MASK));
145827Sjchu 
145927Sjchu 	DBG(DBG_LPU, NULL,
146027Sjchu 	    "lpu_init - LPU_LTSSM_INTERRUPT_AND_STATUS: 0x%llx\n",
146127Sjchu 	    CSR_XR(csr_base, LPU_LTSSM_INTERRUPT_AND_STATUS));
14620Sstevel@tonic-gate 
14630Sstevel@tonic-gate 	/*
14640Sstevel@tonic-gate 	 * CSR_V LPU_LTSSM_STATUS_WRITE_ENABLE Expect OBP 0x0
14650Sstevel@tonic-gate 	 */
14660Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
146727Sjchu 	    "lpu_init - LPU_LTSSM_STATUS_WRITE_ENABLE: 0x%llx\n",
146827Sjchu 	    CSR_XR(csr_base, LPU_LTSSM_STATUS_WRITE_ENABLE));
14690Sstevel@tonic-gate 
14700Sstevel@tonic-gate 	/*
14710Sstevel@tonic-gate 	 * CSR_V LPU_GIGABLAZE_GLUE_CONFIG1 Expect OBP 0x88407
14720Sstevel@tonic-gate 	 */
14730Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - LPU_GIGABLAZE_GLUE_CONFIG1: 0x%llx\n",
147427Sjchu 	    CSR_XR(csr_base, LPU_GIGABLAZE_GLUE_CONFIG1));
14750Sstevel@tonic-gate 
14760Sstevel@tonic-gate 	/*
14770Sstevel@tonic-gate 	 * CSR_V LPU_GIGABLAZE_GLUE_CONFIG2 Expect OBP 0x35
14780Sstevel@tonic-gate 	 */
14790Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - LPU_GIGABLAZE_GLUE_CONFIG2: 0x%llx\n",
148027Sjchu 	    CSR_XR(csr_base, LPU_GIGABLAZE_GLUE_CONFIG2));
14810Sstevel@tonic-gate 
14820Sstevel@tonic-gate 	/*
14830Sstevel@tonic-gate 	 * CSR_V LPU_GIGABLAZE_GLUE_CONFIG3 Expect OBP 0x4400FA
14840Sstevel@tonic-gate 	 */
14850Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - LPU_GIGABLAZE_GLUE_CONFIG3: 0x%llx\n",
148627Sjchu 	    CSR_XR(csr_base, LPU_GIGABLAZE_GLUE_CONFIG3));
14870Sstevel@tonic-gate 
14880Sstevel@tonic-gate 	/*
14890Sstevel@tonic-gate 	 * CSR_V LPU_GIGABLAZE_GLUE_CONFIG4 Expect OBP 0x1E848
14900Sstevel@tonic-gate 	 */
14910Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - LPU_GIGABLAZE_GLUE_CONFIG4: 0x%llx\n",
149227Sjchu 	    CSR_XR(csr_base, LPU_GIGABLAZE_GLUE_CONFIG4));
14930Sstevel@tonic-gate 
14940Sstevel@tonic-gate 	/*
14950Sstevel@tonic-gate 	 * CSR_V LPU_GIGABLAZE_GLUE_STATUS Expect OBP 0x0
14960Sstevel@tonic-gate 	 */
14970Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - LPU_GIGABLAZE_GLUE_STATUS: 0x%llx\n",
149827Sjchu 	    CSR_XR(csr_base, LPU_GIGABLAZE_GLUE_STATUS));
14990Sstevel@tonic-gate 
15000Sstevel@tonic-gate 	/*
15010Sstevel@tonic-gate 	 * CSR_V LPU_GIGABLAZE_GLUE_INTERRUPT_AND_STATUS_TEST Expect OBP 0x0
15020Sstevel@tonic-gate 	 */
150327Sjchu 	DBG(DBG_LPU, NULL, "lpu_init - "
150427Sjchu 	    "LPU_GIGABLAZE_GLUE_INTERRUPT_AND_STATUS_TEST: 0x%llx\n",
150527Sjchu 	    CSR_XR(csr_base,
150627Sjchu 	    LPU_GIGABLAZE_GLUE_INTERRUPT_AND_STATUS_TEST));
15070Sstevel@tonic-gate 
15080Sstevel@tonic-gate 	/*
150927Sjchu 	 * CSR_V LPU GIGABLASE LAYER interrupt regs (mask, status)
15100Sstevel@tonic-gate 	 */
15110Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
15120Sstevel@tonic-gate 	    "lpu_init - LPU_GIGABLAZE_GLUE_INTERRUPT_MASK: 0x%llx\n",
15130Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_GIGABLAZE_GLUE_INTERRUPT_MASK));
15140Sstevel@tonic-gate 
151527Sjchu 	DBG(DBG_LPU, NULL,
151627Sjchu 	    "lpu_init - LPU_GIGABLAZE_GLUE_INTERRUPT_AND_STATUS: 0x%llx\n",
151727Sjchu 	    CSR_XR(csr_base, LPU_GIGABLAZE_GLUE_INTERRUPT_AND_STATUS));
151827Sjchu 
15190Sstevel@tonic-gate 	/*
15200Sstevel@tonic-gate 	 * CSR_V LPU_GIGABLAZE_GLUE_POWER_DOWN1 Expect HW 0x0
15210Sstevel@tonic-gate 	 */
15220Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
152327Sjchu 	    "lpu_init - LPU_GIGABLAZE_GLUE_POWER_DOWN1: 0x%llx\n",
152427Sjchu 	    CSR_XR(csr_base, LPU_GIGABLAZE_GLUE_POWER_DOWN1));
15250Sstevel@tonic-gate 
15260Sstevel@tonic-gate 	/*
15270Sstevel@tonic-gate 	 * CSR_V LPU_GIGABLAZE_GLUE_POWER_DOWN2 Expect HW 0x0
15280Sstevel@tonic-gate 	 */
15290Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
153027Sjchu 	    "lpu_init - LPU_GIGABLAZE_GLUE_POWER_DOWN2: 0x%llx\n",
153127Sjchu 	    CSR_XR(csr_base, LPU_GIGABLAZE_GLUE_POWER_DOWN2));
15320Sstevel@tonic-gate 
15330Sstevel@tonic-gate 	/*
15340Sstevel@tonic-gate 	 * CSR_V LPU_GIGABLAZE_GLUE_CONFIG5 Expect OBP 0x0
15350Sstevel@tonic-gate 	 */
15360Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - LPU_GIGABLAZE_GLUE_CONFIG5: 0x%llx\n",
153727Sjchu 	    CSR_XR(csr_base, LPU_GIGABLAZE_GLUE_CONFIG5));
15380Sstevel@tonic-gate }
15390Sstevel@tonic-gate 
15400Sstevel@tonic-gate /* ARGSUSED */
15410Sstevel@tonic-gate static void
15421772Sjl139090 dlu_init(caddr_t csr_base, pxu_t *pxu_p)
15431772Sjl139090 {
15441772Sjl139090 uint64_t val;
15451772Sjl139090 
15461772Sjl139090 	CSR_XS(csr_base, DLU_INTERRUPT_MASK, 0ull);
15471772Sjl139090 	DBG(DBG_TLU, NULL, "dlu_init - DLU_INTERRUPT_MASK: 0x%llx\n",
15481772Sjl139090 	    CSR_XR(csr_base, DLU_INTERRUPT_MASK));
15491772Sjl139090 
15501772Sjl139090 	val = (1ull << DLU_LINK_LAYER_CONFIG_VC0_EN);
15511772Sjl139090 	CSR_XS(csr_base, DLU_LINK_LAYER_CONFIG, val);
15521772Sjl139090 	DBG(DBG_TLU, NULL, "dlu_init - DLU_LINK_LAYER_CONFIG: 0x%llx\n",
15531772Sjl139090 	    CSR_XR(csr_base, DLU_LINK_LAYER_CONFIG));
15541772Sjl139090 
15551772Sjl139090 	val = (1ull << DLU_FLOW_CONTROL_UPDATE_CONTROL_FC0_U_NP_EN) |
15561772Sjl139090 	    (1ull << DLU_FLOW_CONTROL_UPDATE_CONTROL_FC0_U_P_EN);
15571772Sjl139090 
15581772Sjl139090 	CSR_XS(csr_base, DLU_FLOW_CONTROL_UPDATE_CONTROL, val);
15591772Sjl139090 	DBG(DBG_TLU, NULL, "dlu_init - DLU_FLOW_CONTROL_UPDATE_CONTROL: "
15601772Sjl139090 	    "0x%llx\n", CSR_XR(csr_base, DLU_FLOW_CONTROL_UPDATE_CONTROL));
15611772Sjl139090 
15621772Sjl139090 	val = (DLU_TXLINK_REPLAY_TIMER_THRESHOLD_DEFAULT <<
15631772Sjl139090 	    DLU_TXLINK_REPLAY_TIMER_THRESHOLD_RPLAY_TMR_THR);
15641772Sjl139090 
15651772Sjl139090 	CSR_XS(csr_base, DLU_TXLINK_REPLAY_TIMER_THRESHOLD, val);
15661772Sjl139090 
15671772Sjl139090 	DBG(DBG_TLU, NULL, "dlu_init - DLU_TXLINK_REPLAY_TIMER_THRESHOLD: "
15681772Sjl139090 	    "0x%llx\n", CSR_XR(csr_base, DLU_TXLINK_REPLAY_TIMER_THRESHOLD));
15691772Sjl139090 }
15701772Sjl139090 
15711772Sjl139090 /* ARGSUSED */
15721772Sjl139090 static void
15730Sstevel@tonic-gate dmc_init(caddr_t csr_base, pxu_t *pxu_p)
15740Sstevel@tonic-gate {
15750Sstevel@tonic-gate 	uint64_t val;
15760Sstevel@tonic-gate 
15770Sstevel@tonic-gate /*
15780Sstevel@tonic-gate  * CSR_V DMC_CORE_AND_BLOCK_INTERRUPT_ENABLE Expect OBP 0x8000000000000003
15790Sstevel@tonic-gate  */
15800Sstevel@tonic-gate 
15810Sstevel@tonic-gate 	val = -1ull;
15820Sstevel@tonic-gate 	CSR_XS(csr_base, DMC_CORE_AND_BLOCK_INTERRUPT_ENABLE, val);
15830Sstevel@tonic-gate 	DBG(DBG_DMC, NULL,
158427Sjchu 	    "dmc_init - DMC_CORE_AND_BLOCK_INTERRUPT_ENABLE: 0x%llx\n",
158527Sjchu 	    CSR_XR(csr_base, DMC_CORE_AND_BLOCK_INTERRUPT_ENABLE));
15860Sstevel@tonic-gate 
15870Sstevel@tonic-gate 	/*
15880Sstevel@tonic-gate 	 * CSR_V DMC_CORE_AND_BLOCK_ERROR_STATUS Expect HW 0x0
15890Sstevel@tonic-gate 	 */
15900Sstevel@tonic-gate 	DBG(DBG_DMC, NULL,
159127Sjchu 	    "dmc_init - DMC_CORE_AND_BLOCK_ERROR_STATUS: 0x%llx\n",
159227Sjchu 	    CSR_XR(csr_base, DMC_CORE_AND_BLOCK_ERROR_STATUS));
15930Sstevel@tonic-gate 
15940Sstevel@tonic-gate 	/*
15950Sstevel@tonic-gate 	 * CSR_V DMC_DEBUG_SELECT_FOR_PORT_A Expect HW 0x0
15960Sstevel@tonic-gate 	 */
15970Sstevel@tonic-gate 	val = 0x0ull;
15980Sstevel@tonic-gate 	CSR_XS(csr_base, DMC_DEBUG_SELECT_FOR_PORT_A, val);
15990Sstevel@tonic-gate 	DBG(DBG_DMC, NULL, "dmc_init - DMC_DEBUG_SELECT_FOR_PORT_A: 0x%llx\n",
160027Sjchu 	    CSR_XR(csr_base, DMC_DEBUG_SELECT_FOR_PORT_A));
16010Sstevel@tonic-gate 
16020Sstevel@tonic-gate 	/*
16030Sstevel@tonic-gate 	 * CSR_V DMC_DEBUG_SELECT_FOR_PORT_B Expect HW 0x0
16040Sstevel@tonic-gate 	 */
16050Sstevel@tonic-gate 	val = 0x0ull;
16060Sstevel@tonic-gate 	CSR_XS(csr_base, DMC_DEBUG_SELECT_FOR_PORT_B, val);
16070Sstevel@tonic-gate 	DBG(DBG_DMC, NULL, "dmc_init - DMC_DEBUG_SELECT_FOR_PORT_B: 0x%llx\n",
160827Sjchu 	    CSR_XR(csr_base, DMC_DEBUG_SELECT_FOR_PORT_B));
16090Sstevel@tonic-gate }
16100Sstevel@tonic-gate 
16110Sstevel@tonic-gate void
16120Sstevel@tonic-gate hvio_pec_init(caddr_t csr_base, pxu_t *pxu_p)
16130Sstevel@tonic-gate {
16140Sstevel@tonic-gate 	uint64_t val;
16150Sstevel@tonic-gate 
16160Sstevel@tonic-gate 	ilu_init(csr_base, pxu_p);
16170Sstevel@tonic-gate 	tlu_init(csr_base, pxu_p);
16181772Sjl139090 
16191772Sjl139090 	switch (PX_CHIP_TYPE(pxu_p)) {
16201772Sjl139090 	case PX_CHIP_OBERON:
16211772Sjl139090 		dlu_init(csr_base, pxu_p);
16221772Sjl139090 		break;
16231772Sjl139090 	case PX_CHIP_FIRE:
16241772Sjl139090 		lpu_init(csr_base, pxu_p);
16251772Sjl139090 		break;
16261772Sjl139090 	default:
16271772Sjl139090 		DBG(DBG_PEC, NULL, "hvio_pec_init - unknown chip type: 0x%x\n",
16281772Sjl139090 		    PX_CHIP_TYPE(pxu_p));
16291772Sjl139090 		break;
16301772Sjl139090 	}
16311772Sjl139090 
16320Sstevel@tonic-gate 	dmc_init(csr_base, pxu_p);
16330Sstevel@tonic-gate 
16340Sstevel@tonic-gate /*
16350Sstevel@tonic-gate  * CSR_V PEC_CORE_AND_BLOCK_INTERRUPT_ENABLE Expect Kernel 0x800000000000000F
16360Sstevel@tonic-gate  */
16370Sstevel@tonic-gate 
16380Sstevel@tonic-gate 	val = -1ull;
16390Sstevel@tonic-gate 	CSR_XS(csr_base, PEC_CORE_AND_BLOCK_INTERRUPT_ENABLE, val);
16400Sstevel@tonic-gate 	DBG(DBG_PEC, NULL,
164127Sjchu 	    "hvio_pec_init - PEC_CORE_AND_BLOCK_INTERRUPT_ENABLE: 0x%llx\n",
164227Sjchu 	    CSR_XR(csr_base, PEC_CORE_AND_BLOCK_INTERRUPT_ENABLE));
16430Sstevel@tonic-gate 
16440Sstevel@tonic-gate 	/*
16450Sstevel@tonic-gate 	 * CSR_V PEC_CORE_AND_BLOCK_INTERRUPT_STATUS Expect HW 0x0
16460Sstevel@tonic-gate 	 */
16470Sstevel@tonic-gate 	DBG(DBG_PEC, NULL,
164827Sjchu 	    "hvio_pec_init - PEC_CORE_AND_BLOCK_INTERRUPT_STATUS: 0x%llx\n",
164927Sjchu 	    CSR_XR(csr_base, PEC_CORE_AND_BLOCK_INTERRUPT_STATUS));
16500Sstevel@tonic-gate }
16510Sstevel@tonic-gate 
165227Sjchu /*
16531772Sjl139090  * Convert a TTE to physical address
16541772Sjl139090  */
16551772Sjl139090 static r_addr_t
16561772Sjl139090 mmu_tte_to_pa(uint64_t tte, pxu_t *pxu_p)
16571772Sjl139090 {
16581772Sjl139090 	uint64_t pa_mask;
16591772Sjl139090 
16601772Sjl139090 	switch (PX_CHIP_TYPE(pxu_p)) {
16611772Sjl139090 	case PX_CHIP_OBERON:
16621772Sjl139090 		pa_mask = MMU_OBERON_PADDR_MASK;
16631772Sjl139090 		break;
16641772Sjl139090 	case PX_CHIP_FIRE:
16651772Sjl139090 		pa_mask = MMU_FIRE_PADDR_MASK;
16661772Sjl139090 		break;
16671772Sjl139090 	default:
16681772Sjl139090 		DBG(DBG_MMU, NULL, "mmu_tte_to_pa - unknown chip type: 0x%x\n",
16691772Sjl139090 		    PX_CHIP_TYPE(pxu_p));
16701772Sjl139090 		pa_mask = 0;
16711772Sjl139090 		break;
16721772Sjl139090 	}
16731772Sjl139090 	return ((tte & pa_mask) >> MMU_PAGE_SHIFT);
16741772Sjl139090 }
16751772Sjl139090 
16761772Sjl139090 /*
16771772Sjl139090  * Return MMU bypass noncache bit for chip
16781772Sjl139090  */
16791772Sjl139090 static r_addr_t
16801772Sjl139090 mmu_bypass_noncache(pxu_t *pxu_p)
16811772Sjl139090 {
16821772Sjl139090 	r_addr_t bypass_noncache_bit;
16831772Sjl139090 
16841772Sjl139090 	switch (PX_CHIP_TYPE(pxu_p)) {
16851772Sjl139090 	case PX_CHIP_OBERON:
16861772Sjl139090 		bypass_noncache_bit = MMU_OBERON_BYPASS_NONCACHE;
16871772Sjl139090 		break;
16881772Sjl139090 	case PX_CHIP_FIRE:
16891772Sjl139090 		bypass_noncache_bit = MMU_FIRE_BYPASS_NONCACHE;
16901772Sjl139090 		break;
16911772Sjl139090 	default:
16921772Sjl139090 		DBG(DBG_MMU, NULL,
16931772Sjl139090 		    "mmu_bypass_nocache - unknown chip type: 0x%x\n",
16941772Sjl139090 		    PX_CHIP_TYPE(pxu_p));
16951772Sjl139090 		bypass_noncache_bit = 0;
16961772Sjl139090 		break;
16971772Sjl139090 	}
16981772Sjl139090 	return (bypass_noncache_bit);
16991772Sjl139090 }
17001772Sjl139090 
17011772Sjl139090 /*
17021772Sjl139090  * Calculate number of TSB entries for the chip.
17031772Sjl139090  */
17041772Sjl139090 /* ARGSUSED */
17051772Sjl139090 static uint_t
17061772Sjl139090 mmu_tsb_entries(caddr_t csr_base, pxu_t *pxu_p)
17071772Sjl139090 {
17081772Sjl139090 	uint64_t tsb_ctrl;
17091772Sjl139090 	uint_t obp_tsb_entries, obp_tsb_size;
17101772Sjl139090 
17111772Sjl139090 	tsb_ctrl = CSR_XR(csr_base, MMU_TSB_CONTROL);
17121772Sjl139090 
17131772Sjl139090 	obp_tsb_size = tsb_ctrl & 0xF;
17141772Sjl139090 
17151772Sjl139090 	obp_tsb_entries = MMU_TSBSIZE_TO_TSBENTRIES(obp_tsb_size);
17161772Sjl139090 
17171772Sjl139090 	return (obp_tsb_entries);
17181772Sjl139090 }
17191772Sjl139090 
17201772Sjl139090 /*
172127Sjchu  * Initialize the module, but do not enable interrupts.
172227Sjchu  */
17230Sstevel@tonic-gate void
17240Sstevel@tonic-gate hvio_mmu_init(caddr_t csr_base, pxu_t *pxu_p)
17250Sstevel@tonic-gate {
17261772Sjl139090 	uint64_t	val, i, obp_tsb_pa, *base_tte_addr;
17271772Sjl139090 	uint_t obp_tsb_entries;
17280Sstevel@tonic-gate 
17290Sstevel@tonic-gate 	bzero(pxu_p->tsb_vaddr, pxu_p->tsb_size);
17300Sstevel@tonic-gate 
17310Sstevel@tonic-gate 	/*
17320Sstevel@tonic-gate 	 * Preserve OBP's TSB
17330Sstevel@tonic-gate 	 */
17341772Sjl139090 	obp_tsb_pa = CSR_XR(csr_base, MMU_TSB_CONTROL) & MMU_TSB_PA_MASK;
17351772Sjl139090 
17361772Sjl139090 	obp_tsb_entries = mmu_tsb_entries(csr_base, pxu_p);
17370Sstevel@tonic-gate 
17380Sstevel@tonic-gate 	base_tte_addr = pxu_p->tsb_vaddr +
17396953Sanbui 	    ((pxu_p->tsb_size >> 3) - obp_tsb_entries);
17400Sstevel@tonic-gate 
17410Sstevel@tonic-gate 	for (i = 0; i < obp_tsb_entries; i++) {
17420Sstevel@tonic-gate 		uint64_t tte = lddphys(obp_tsb_pa + i * 8);
17430Sstevel@tonic-gate 
17440Sstevel@tonic-gate 		if (!MMU_TTE_VALID(tte))
17450Sstevel@tonic-gate 			continue;
17460Sstevel@tonic-gate 
17470Sstevel@tonic-gate 		base_tte_addr[i] = tte;
17480Sstevel@tonic-gate 	}
17490Sstevel@tonic-gate 
17500Sstevel@tonic-gate 	/*
17510Sstevel@tonic-gate 	 * Invalidate the TLB through the diagnostic register.
17520Sstevel@tonic-gate 	 */
17530Sstevel@tonic-gate 
17540Sstevel@tonic-gate 	CSR_XS(csr_base, MMU_TTE_CACHE_INVALIDATE, -1ull);
17550Sstevel@tonic-gate 
17560Sstevel@tonic-gate 	/*
17570Sstevel@tonic-gate 	 * Configure the Fire MMU TSB Control Register.  Determine
17580Sstevel@tonic-gate 	 * the encoding for either 8KB pages (0) or 64KB pages (1).
17590Sstevel@tonic-gate 	 *
17600Sstevel@tonic-gate 	 * Write the most significant 30 bits of the TSB physical address
17610Sstevel@tonic-gate 	 * and the encoded TSB table size.
17620Sstevel@tonic-gate 	 */
17636953Sanbui 	for (i = 8; i && (pxu_p->tsb_size < (0x2000 << i)); i--) {}
17640Sstevel@tonic-gate 
17650Sstevel@tonic-gate 	val = (((((va_to_pa(pxu_p->tsb_vaddr)) >> 13) << 13) |
17660Sstevel@tonic-gate 	    ((MMU_PAGE_SHIFT == 13) ? 0 : 1) << 8) | i);
17670Sstevel@tonic-gate 
17680Sstevel@tonic-gate 	CSR_XS(csr_base, MMU_TSB_CONTROL, val);
17690Sstevel@tonic-gate 
17700Sstevel@tonic-gate 	/*
17710Sstevel@tonic-gate 	 * Enable the MMU, set the "TSB Cache Snoop Enable",
17720Sstevel@tonic-gate 	 * the "Cache Mode", the "Bypass Enable" and
17730Sstevel@tonic-gate 	 * the "Translation Enable" bits.
17740Sstevel@tonic-gate 	 */
17750Sstevel@tonic-gate 	val = CSR_XR(csr_base, MMU_CONTROL_AND_STATUS);
17760Sstevel@tonic-gate 	val |= ((1ull << MMU_CONTROL_AND_STATUS_SE)
177727Sjchu 	    | (MMU_CONTROL_AND_STATUS_CM_MASK << MMU_CONTROL_AND_STATUS_CM)
177827Sjchu 	    | (1ull << MMU_CONTROL_AND_STATUS_BE)
177927Sjchu 	    | (1ull << MMU_CONTROL_AND_STATUS_TE));
17800Sstevel@tonic-gate 
17810Sstevel@tonic-gate 	CSR_XS(csr_base, MMU_CONTROL_AND_STATUS, val);
17820Sstevel@tonic-gate 
17830Sstevel@tonic-gate 	/*
17840Sstevel@tonic-gate 	 * Read the register here to ensure that the previous writes to
17850Sstevel@tonic-gate 	 * the Fire MMU registers have been flushed.  (Technically, this
17860Sstevel@tonic-gate 	 * is not entirely necessary here as we will likely do later reads
17870Sstevel@tonic-gate 	 * during Fire initialization, but it is a small price to pay for
17880Sstevel@tonic-gate 	 * more modular code.)
17890Sstevel@tonic-gate 	 */
17900Sstevel@tonic-gate 	(void) CSR_XR(csr_base, MMU_CONTROL_AND_STATUS);
17910Sstevel@tonic-gate 
17920Sstevel@tonic-gate 	/*
179327Sjchu 	 * CSR_V TLU's UE interrupt regs (log, enable, status, clear)
179427Sjchu 	 * Plus header logs
17950Sstevel@tonic-gate 	 */
179627Sjchu 	DBG(DBG_MMU, NULL, "mmu_init - MMU_ERROR_LOG_ENABLE: 0x%llx\n",
179727Sjchu 	    CSR_XR(csr_base, MMU_ERROR_LOG_ENABLE));
179827Sjchu 
179927Sjchu 	DBG(DBG_MMU, NULL, "mmu_init - MMU_INTERRUPT_ENABLE: 0x%llx\n",
180027Sjchu 	    CSR_XR(csr_base, MMU_INTERRUPT_ENABLE));
180127Sjchu 
180227Sjchu 	DBG(DBG_MMU, NULL, "mmu_init - MMU_INTERRUPT_STATUS: 0x%llx\n",
180327Sjchu 	    CSR_XR(csr_base, MMU_INTERRUPT_STATUS));
180427Sjchu 
180527Sjchu 	DBG(DBG_MMU, NULL, "mmu_init - MMU_ERROR_STATUS_CLEAR: 0x%llx\n",
180627Sjchu 	    CSR_XR(csr_base, MMU_ERROR_STATUS_CLEAR));
18070Sstevel@tonic-gate }
18080Sstevel@tonic-gate 
18090Sstevel@tonic-gate /*
18100Sstevel@tonic-gate  * Generic IOMMU Servies
18110Sstevel@tonic-gate  */
18120Sstevel@tonic-gate 
18130Sstevel@tonic-gate /* ARGSUSED */
18140Sstevel@tonic-gate uint64_t
18151617Sgovinda hvio_iommu_map(devhandle_t dev_hdl, pxu_t *pxu_p, tsbid_t tsbid, pages_t pages,
18161617Sgovinda     io_attributes_t io_attr, void *addr, size_t pfn_index, int flags)
18170Sstevel@tonic-gate {
18180Sstevel@tonic-gate 	tsbindex_t	tsb_index = PCI_TSBID_TO_TSBINDEX(tsbid);
18190Sstevel@tonic-gate 	uint64_t	attr = MMU_TTE_V;
18200Sstevel@tonic-gate 	int		i;
18210Sstevel@tonic-gate 
18221617Sgovinda 	if (io_attr & PCI_MAP_ATTR_WRITE)
18230Sstevel@tonic-gate 		attr |= MMU_TTE_W;
18240Sstevel@tonic-gate 
18251772Sjl139090 	if ((PX_CHIP_TYPE(pxu_p) == PX_CHIP_OBERON) &&
18261772Sjl139090 	    (io_attr & PCI_MAP_ATTR_RO))
18271772Sjl139090 		attr |= MMU_TTE_RO;
18281772Sjl139090 
18291772Sjl139090 	if (attr & MMU_TTE_RO) {
18301772Sjl139090 		DBG(DBG_MMU, NULL, "hvio_iommu_map: pfn_index=0x%x "
18311772Sjl139090 		    "pages=0x%x attr = 0x%lx\n", pfn_index, pages, attr);
18321772Sjl139090 	}
18331772Sjl139090 
18341617Sgovinda 	if (flags & MMU_MAP_PFN) {
18351617Sgovinda 		ddi_dma_impl_t	*mp = (ddi_dma_impl_t *)addr;
18360Sstevel@tonic-gate 		for (i = 0; i < pages; i++, pfn_index++, tsb_index++) {
18371617Sgovinda 			px_iopfn_t pfn = PX_GET_MP_PFN(mp, pfn_index);
18381617Sgovinda 			pxu_p->tsb_vaddr[tsb_index] = MMU_PTOB(pfn) | attr;
18391772Sjl139090 
18401772Sjl139090 			/*
18411772Sjl139090 			 * Oberon will need to flush the corresponding TTEs in
18421772Sjl139090 			 * Cache. We only need to flush every cache line.
18431772Sjl139090 			 * Extra PIO's are expensive.
18441772Sjl139090 			 */
18451772Sjl139090 			if (PX_CHIP_TYPE(pxu_p) == PX_CHIP_OBERON) {
18461772Sjl139090 				if ((i == (pages-1))||!((tsb_index+1) & 0x7)) {
18471772Sjl139090 					CSR_XS(dev_hdl,
18481772Sjl139090 					    MMU_TTE_CACHE_FLUSH_ADDRESS,
18491772Sjl139090 					    (pxu_p->tsb_paddr+
18501772Sjl139090 					    (tsb_index*MMU_TTE_SIZE)));
18511772Sjl139090 				}
18521772Sjl139090 			}
18530Sstevel@tonic-gate 		}
18540Sstevel@tonic-gate 	} else {
18551617Sgovinda 		caddr_t	a = (caddr_t)addr;
18560Sstevel@tonic-gate 		for (i = 0; i < pages; i++, a += MMU_PAGE_SIZE, tsb_index++) {
18570Sstevel@tonic-gate 			px_iopfn_t pfn = hat_getpfnum(kas.a_hat, a);
18581617Sgovinda 			pxu_p->tsb_vaddr[tsb_index] = MMU_PTOB(pfn) | attr;
18591772Sjl139090 
18601772Sjl139090 			/*
18611772Sjl139090 			 * Oberon will need to flush the corresponding TTEs in
18621772Sjl139090 			 * Cache. We only need to flush every cache line.
18631772Sjl139090 			 * Extra PIO's are expensive.
18641772Sjl139090 			 */
18651772Sjl139090 			if (PX_CHIP_TYPE(pxu_p) == PX_CHIP_OBERON) {
18661772Sjl139090 				if ((i == (pages-1))||!((tsb_index+1) & 0x7)) {
18671772Sjl139090 					CSR_XS(dev_hdl,
18681772Sjl139090 					    MMU_TTE_CACHE_FLUSH_ADDRESS,
18691772Sjl139090 					    (pxu_p->tsb_paddr+
18701772Sjl139090 					    (tsb_index*MMU_TTE_SIZE)));
18711772Sjl139090 				}
18721772Sjl139090 			}
18730Sstevel@tonic-gate 		}
18740Sstevel@tonic-gate 	}
18750Sstevel@tonic-gate 
18760Sstevel@tonic-gate 	return (H_EOK);
18770Sstevel@tonic-gate }
18780Sstevel@tonic-gate 
18790Sstevel@tonic-gate /* ARGSUSED */
18800Sstevel@tonic-gate uint64_t
18810Sstevel@tonic-gate hvio_iommu_demap(devhandle_t dev_hdl, pxu_t *pxu_p, tsbid_t tsbid,
18820Sstevel@tonic-gate     pages_t pages)
18830Sstevel@tonic-gate {
18840Sstevel@tonic-gate 	tsbindex_t	tsb_index = PCI_TSBID_TO_TSBINDEX(tsbid);
18850Sstevel@tonic-gate 	int		i;
18860Sstevel@tonic-gate 
18871772Sjl139090 	for (i = 0; i < pages; i++, tsb_index++) {
18880Sstevel@tonic-gate 		pxu_p->tsb_vaddr[tsb_index] = MMU_INVALID_TTE;
18890Sstevel@tonic-gate 
18901772Sjl139090 			/*
18911772Sjl139090 			 * Oberon will need to flush the corresponding TTEs in
18921772Sjl139090 			 * Cache. We only need to flush every cache line.
18931772Sjl139090 			 * Extra PIO's are expensive.
18941772Sjl139090 			 */
18951772Sjl139090 			if (PX_CHIP_TYPE(pxu_p) == PX_CHIP_OBERON) {
18961772Sjl139090 				if ((i == (pages-1))||!((tsb_index+1) & 0x7)) {
18971772Sjl139090 					CSR_XS(dev_hdl,
18981772Sjl139090 					    MMU_TTE_CACHE_FLUSH_ADDRESS,
18991772Sjl139090 					    (pxu_p->tsb_paddr+
19001772Sjl139090 					    (tsb_index*MMU_TTE_SIZE)));
19011772Sjl139090 				}
19021772Sjl139090 			}
19031772Sjl139090 	}
19041772Sjl139090 
19050Sstevel@tonic-gate 	return (H_EOK);
19060Sstevel@tonic-gate }
19070Sstevel@tonic-gate 
19080Sstevel@tonic-gate /* ARGSUSED */
19090Sstevel@tonic-gate uint64_t
19100Sstevel@tonic-gate hvio_iommu_getmap(devhandle_t dev_hdl, pxu_t *pxu_p, tsbid_t tsbid,
19111617Sgovinda     io_attributes_t *attr_p, r_addr_t *r_addr_p)
19120Sstevel@tonic-gate {
19130Sstevel@tonic-gate 	tsbindex_t	tsb_index = PCI_TSBID_TO_TSBINDEX(tsbid);
19140Sstevel@tonic-gate 	uint64_t	*tte_addr;
19150Sstevel@tonic-gate 	uint64_t	ret = H_EOK;
19160Sstevel@tonic-gate 
19170Sstevel@tonic-gate 	tte_addr = (uint64_t *)(pxu_p->tsb_vaddr) + tsb_index;
19180Sstevel@tonic-gate 
19190Sstevel@tonic-gate 	if (*tte_addr & MMU_TTE_V) {
19201772Sjl139090 		*r_addr_p = mmu_tte_to_pa(*tte_addr, pxu_p);
19211617Sgovinda 		*attr_p = (*tte_addr & MMU_TTE_W) ?
19220Sstevel@tonic-gate 		    PCI_MAP_ATTR_WRITE:PCI_MAP_ATTR_READ;
19230Sstevel@tonic-gate 	} else {
19240Sstevel@tonic-gate 		*r_addr_p = 0;
19251617Sgovinda 		*attr_p = 0;
19260Sstevel@tonic-gate 		ret = H_ENOMAP;
19270Sstevel@tonic-gate 	}
19280Sstevel@tonic-gate 
19290Sstevel@tonic-gate 	return (ret);
19300Sstevel@tonic-gate }
19310Sstevel@tonic-gate 
19320Sstevel@tonic-gate /* ARGSUSED */
19330Sstevel@tonic-gate uint64_t
19341772Sjl139090 hvio_get_bypass_base(pxu_t *pxu_p)
19351772Sjl139090 {
19361772Sjl139090 	uint64_t base;
19371772Sjl139090 
19381772Sjl139090 	switch (PX_CHIP_TYPE(pxu_p)) {
19391772Sjl139090 	case PX_CHIP_OBERON:
19401772Sjl139090 		base = MMU_OBERON_BYPASS_BASE;
19411772Sjl139090 		break;
19421772Sjl139090 	case PX_CHIP_FIRE:
19431772Sjl139090 		base = MMU_FIRE_BYPASS_BASE;
19441772Sjl139090 		break;
19451772Sjl139090 	default:
19461772Sjl139090 		DBG(DBG_MMU, NULL,
19471772Sjl139090 		    "hvio_get_bypass_base - unknown chip type: 0x%x\n",
19481772Sjl139090 		    PX_CHIP_TYPE(pxu_p));
19491772Sjl139090 		base = 0;
19501772Sjl139090 		break;
19511772Sjl139090 	}
19521772Sjl139090 	return (base);
19531772Sjl139090 }
19541772Sjl139090 
19551772Sjl139090 /* ARGSUSED */
19561772Sjl139090 uint64_t
19571772Sjl139090 hvio_get_bypass_end(pxu_t *pxu_p)
19581772Sjl139090 {
19591772Sjl139090 	uint64_t end;
19601772Sjl139090 
19611772Sjl139090 	switch (PX_CHIP_TYPE(pxu_p)) {
19621772Sjl139090 	case PX_CHIP_OBERON:
19631772Sjl139090 		end = MMU_OBERON_BYPASS_END;
19641772Sjl139090 		break;
19651772Sjl139090 	case PX_CHIP_FIRE:
19661772Sjl139090 		end = MMU_FIRE_BYPASS_END;
19671772Sjl139090 		break;
19681772Sjl139090 	default:
19691772Sjl139090 		DBG(DBG_MMU, NULL,
19701772Sjl139090 		    "hvio_get_bypass_end - unknown chip type: 0x%x\n",
19711772Sjl139090 		    PX_CHIP_TYPE(pxu_p));
19721772Sjl139090 		end = 0;
19731772Sjl139090 		break;
19741772Sjl139090 	}
19751772Sjl139090 	return (end);
19761772Sjl139090 }
19771772Sjl139090 
19781772Sjl139090 /* ARGSUSED */
19791772Sjl139090 uint64_t
19801772Sjl139090 hvio_iommu_getbypass(devhandle_t dev_hdl, pxu_t *pxu_p, r_addr_t ra,
19811772Sjl139090     io_attributes_t attr, io_addr_t *io_addr_p)
19820Sstevel@tonic-gate {
19830Sstevel@tonic-gate 	uint64_t	pfn = MMU_BTOP(ra);
19840Sstevel@tonic-gate 
19851772Sjl139090 	*io_addr_p = hvio_get_bypass_base(pxu_p) | ra |
19861772Sjl139090 	    (pf_is_memory(pfn) ? 0 : mmu_bypass_noncache(pxu_p));
19870Sstevel@tonic-gate 
19880Sstevel@tonic-gate 	return (H_EOK);
19890Sstevel@tonic-gate }
19900Sstevel@tonic-gate 
19910Sstevel@tonic-gate /*
19920Sstevel@tonic-gate  * Generic IO Interrupt Servies
19930Sstevel@tonic-gate  */
19940Sstevel@tonic-gate 
19950Sstevel@tonic-gate /*
19960Sstevel@tonic-gate  * Converts a device specific interrupt number given by the
19970Sstevel@tonic-gate  * arguments devhandle and devino into a system specific ino.
19980Sstevel@tonic-gate  */
19990Sstevel@tonic-gate /* ARGSUSED */
20000Sstevel@tonic-gate uint64_t
20010Sstevel@tonic-gate hvio_intr_devino_to_sysino(devhandle_t dev_hdl, pxu_t *pxu_p, devino_t devino,
20020Sstevel@tonic-gate     sysino_t *sysino)
20030Sstevel@tonic-gate {
20040Sstevel@tonic-gate 	if (devino > INTERRUPT_MAPPING_ENTRIES) {
20050Sstevel@tonic-gate 		DBG(DBG_IB, NULL, "ino %x is invalid\n", devino);
20060Sstevel@tonic-gate 		return (H_ENOINTR);
20070Sstevel@tonic-gate 	}
20080Sstevel@tonic-gate 
20090Sstevel@tonic-gate 	*sysino = DEVINO_TO_SYSINO(pxu_p->portid, devino);
20100Sstevel@tonic-gate 
20110Sstevel@tonic-gate 	return (H_EOK);
20120Sstevel@tonic-gate }
20130Sstevel@tonic-gate 
20140Sstevel@tonic-gate /*
20150Sstevel@tonic-gate  * Returns state in intr_valid_state if the interrupt defined by sysino
20160Sstevel@tonic-gate  * is valid (enabled) or not-valid (disabled).
20170Sstevel@tonic-gate  */
20180Sstevel@tonic-gate uint64_t
20190Sstevel@tonic-gate hvio_intr_getvalid(devhandle_t dev_hdl, sysino_t sysino,
20200Sstevel@tonic-gate     intr_valid_state_t *intr_valid_state)
20210Sstevel@tonic-gate {
20220Sstevel@tonic-gate 	if (CSRA_BR((caddr_t)dev_hdl, INTERRUPT_MAPPING,
20230Sstevel@tonic-gate 	    SYSINO_TO_DEVINO(sysino), ENTRIES_V)) {
20240Sstevel@tonic-gate 		*intr_valid_state = INTR_VALID;
20250Sstevel@tonic-gate 	} else {
20260Sstevel@tonic-gate 		*intr_valid_state = INTR_NOTVALID;
20270Sstevel@tonic-gate 	}
20280Sstevel@tonic-gate 
20290Sstevel@tonic-gate 	return (H_EOK);
20300Sstevel@tonic-gate }
20310Sstevel@tonic-gate 
20320Sstevel@tonic-gate /*
20330Sstevel@tonic-gate  * Sets the 'valid' state of the interrupt defined by
20340Sstevel@tonic-gate  * the argument sysino to the state defined by the
20350Sstevel@tonic-gate  * argument intr_valid_state.
20360Sstevel@tonic-gate  */
20370Sstevel@tonic-gate uint64_t
20380Sstevel@tonic-gate hvio_intr_setvalid(devhandle_t dev_hdl, sysino_t sysino,
20390Sstevel@tonic-gate     intr_valid_state_t intr_valid_state)
20400Sstevel@tonic-gate {
20410Sstevel@tonic-gate 	switch (intr_valid_state) {
20420Sstevel@tonic-gate 	case INTR_VALID:
20430Sstevel@tonic-gate 		CSRA_BS((caddr_t)dev_hdl, INTERRUPT_MAPPING,
20440Sstevel@tonic-gate 		    SYSINO_TO_DEVINO(sysino), ENTRIES_V);
20450Sstevel@tonic-gate 		break;
20460Sstevel@tonic-gate 	case INTR_NOTVALID:
20470Sstevel@tonic-gate 		CSRA_BC((caddr_t)dev_hdl, INTERRUPT_MAPPING,
20480Sstevel@tonic-gate 		    SYSINO_TO_DEVINO(sysino), ENTRIES_V);
20490Sstevel@tonic-gate 		break;
20500Sstevel@tonic-gate 	default:
20510Sstevel@tonic-gate 		return (EINVAL);
20520Sstevel@tonic-gate 	}
20530Sstevel@tonic-gate 
20540Sstevel@tonic-gate 	return (H_EOK);
20550Sstevel@tonic-gate }
20560Sstevel@tonic-gate 
20570Sstevel@tonic-gate /*
20580Sstevel@tonic-gate  * Returns the current state of the interrupt given by the sysino
20590Sstevel@tonic-gate  * argument.
20600Sstevel@tonic-gate  */
20610Sstevel@tonic-gate uint64_t
20620Sstevel@tonic-gate hvio_intr_getstate(devhandle_t dev_hdl, sysino_t sysino,
20630Sstevel@tonic-gate     intr_state_t *intr_state)
20640Sstevel@tonic-gate {
20650Sstevel@tonic-gate 	intr_state_t state;
20660Sstevel@tonic-gate 
20670Sstevel@tonic-gate 	state = CSRA_FR((caddr_t)dev_hdl, INTERRUPT_CLEAR,
20680Sstevel@tonic-gate 	    SYSINO_TO_DEVINO(sysino), ENTRIES_INT_STATE);
20690Sstevel@tonic-gate 
20700Sstevel@tonic-gate 	switch (state) {
20710Sstevel@tonic-gate 	case INTERRUPT_IDLE_STATE:
20720Sstevel@tonic-gate 		*intr_state = INTR_IDLE_STATE;
20730Sstevel@tonic-gate 		break;
20740Sstevel@tonic-gate 	case INTERRUPT_RECEIVED_STATE:
20750Sstevel@tonic-gate 		*intr_state = INTR_RECEIVED_STATE;
20760Sstevel@tonic-gate 		break;
20770Sstevel@tonic-gate 	case INTERRUPT_PENDING_STATE:
20780Sstevel@tonic-gate 		*intr_state = INTR_DELIVERED_STATE;
20790Sstevel@tonic-gate 		break;
20800Sstevel@tonic-gate 	default:
20810Sstevel@tonic-gate 		return (EINVAL);
20820Sstevel@tonic-gate 	}
20830Sstevel@tonic-gate 
20840Sstevel@tonic-gate 	return (H_EOK);
20850Sstevel@tonic-gate 
20860Sstevel@tonic-gate }
20870Sstevel@tonic-gate 
20880Sstevel@tonic-gate /*
20890Sstevel@tonic-gate  * Sets the current state of the interrupt given by the sysino
20900Sstevel@tonic-gate  * argument to the value given in the argument intr_state.
20910Sstevel@tonic-gate  *
20920Sstevel@tonic-gate  * Note: Setting the state to INTR_IDLE clears any pending
20930Sstevel@tonic-gate  * interrupt for sysino.
20940Sstevel@tonic-gate  */
20950Sstevel@tonic-gate uint64_t
20960Sstevel@tonic-gate hvio_intr_setstate(devhandle_t dev_hdl, sysino_t sysino,
20970Sstevel@tonic-gate     intr_state_t intr_state)
20980Sstevel@tonic-gate {
20990Sstevel@tonic-gate 	intr_state_t state;
21000Sstevel@tonic-gate 
21010Sstevel@tonic-gate 	switch (intr_state) {
21020Sstevel@tonic-gate 	case INTR_IDLE_STATE:
21030Sstevel@tonic-gate 		state = INTERRUPT_IDLE_STATE;
21040Sstevel@tonic-gate 		break;
21050Sstevel@tonic-gate 	case INTR_DELIVERED_STATE:
21060Sstevel@tonic-gate 		state = INTERRUPT_PENDING_STATE;
21070Sstevel@tonic-gate 		break;
21080Sstevel@tonic-gate 	default:
21090Sstevel@tonic-gate 		return (EINVAL);
21100Sstevel@tonic-gate 	}
21110Sstevel@tonic-gate 
21120Sstevel@tonic-gate 	CSRA_FS((caddr_t)dev_hdl, INTERRUPT_CLEAR,
21130Sstevel@tonic-gate 	    SYSINO_TO_DEVINO(sysino), ENTRIES_INT_STATE, state);
21140Sstevel@tonic-gate 
21150Sstevel@tonic-gate 	return (H_EOK);
21160Sstevel@tonic-gate }
21170Sstevel@tonic-gate 
21180Sstevel@tonic-gate /*
21190Sstevel@tonic-gate  * Returns the cpuid that is the current target of the
21200Sstevel@tonic-gate  * interrupt given by the sysino argument.
21210Sstevel@tonic-gate  *
21220Sstevel@tonic-gate  * The cpuid value returned is undefined if the target
21230Sstevel@tonic-gate  * has not been set via intr_settarget.
21240Sstevel@tonic-gate  */
21250Sstevel@tonic-gate uint64_t
21261772Sjl139090 hvio_intr_gettarget(devhandle_t dev_hdl, pxu_t *pxu_p, sysino_t sysino,
21271772Sjl139090     cpuid_t *cpuid)
21280Sstevel@tonic-gate {
21291772Sjl139090 	switch (PX_CHIP_TYPE(pxu_p)) {
21301772Sjl139090 	case PX_CHIP_OBERON:
21311772Sjl139090 		*cpuid = CSRA_FR((caddr_t)dev_hdl, INTERRUPT_MAPPING,
21321772Sjl139090 		    SYSINO_TO_DEVINO(sysino), ENTRIES_T_DESTID);
21331772Sjl139090 		break;
21341772Sjl139090 	case PX_CHIP_FIRE:
21351772Sjl139090 		*cpuid = CSRA_FR((caddr_t)dev_hdl, INTERRUPT_MAPPING,
21361772Sjl139090 		    SYSINO_TO_DEVINO(sysino), ENTRIES_T_JPID);
21371772Sjl139090 		break;
21381772Sjl139090 	default:
21391772Sjl139090 		DBG(DBG_CB, NULL, "hvio_intr_gettarget - "
21401772Sjl139090 		    "unknown chip type: 0x%x\n", PX_CHIP_TYPE(pxu_p));
21411772Sjl139090 		return (EINVAL);
21421772Sjl139090 	}
21430Sstevel@tonic-gate 
21440Sstevel@tonic-gate 	return (H_EOK);
21450Sstevel@tonic-gate }
21460Sstevel@tonic-gate 
21470Sstevel@tonic-gate /*
21480Sstevel@tonic-gate  * Set the target cpu for the interrupt defined by the argument
21490Sstevel@tonic-gate  * sysino to the target cpu value defined by the argument cpuid.
21500Sstevel@tonic-gate  */
21510Sstevel@tonic-gate uint64_t
21521772Sjl139090 hvio_intr_settarget(devhandle_t dev_hdl, pxu_t *pxu_p, sysino_t sysino,
21531772Sjl139090     cpuid_t cpuid)
21540Sstevel@tonic-gate {
21550Sstevel@tonic-gate 
21560Sstevel@tonic-gate 	uint64_t	val, intr_controller;
21570Sstevel@tonic-gate 	uint32_t	ino = SYSINO_TO_DEVINO(sysino);
21580Sstevel@tonic-gate 
21590Sstevel@tonic-gate 	/*
21600Sstevel@tonic-gate 	 * For now, we assign interrupt controller in a round
21610Sstevel@tonic-gate 	 * robin fashion.  Later, we may need to come up with
21620Sstevel@tonic-gate 	 * a more efficient assignment algorithm.
21630Sstevel@tonic-gate 	 */
21640Sstevel@tonic-gate 	intr_controller = 0x1ull << (cpuid % 4);
21650Sstevel@tonic-gate 
21661772Sjl139090 	switch (PX_CHIP_TYPE(pxu_p)) {
21671772Sjl139090 	case PX_CHIP_OBERON:
21681772Sjl139090 		val = (((cpuid &
21691772Sjl139090 		    INTERRUPT_MAPPING_ENTRIES_T_DESTID_MASK) <<
21701772Sjl139090 		    INTERRUPT_MAPPING_ENTRIES_T_DESTID) |
21711772Sjl139090 		    ((intr_controller &
21721772Sjl139090 		    INTERRUPT_MAPPING_ENTRIES_INT_CNTRL_NUM_MASK)
21731772Sjl139090 		    << INTERRUPT_MAPPING_ENTRIES_INT_CNTRL_NUM));
21741772Sjl139090 		break;
21751772Sjl139090 	case PX_CHIP_FIRE:
21761772Sjl139090 		val = (((cpuid & INTERRUPT_MAPPING_ENTRIES_T_JPID_MASK) <<
21771772Sjl139090 		    INTERRUPT_MAPPING_ENTRIES_T_JPID) |
21781772Sjl139090 		    ((intr_controller &
21791772Sjl139090 		    INTERRUPT_MAPPING_ENTRIES_INT_CNTRL_NUM_MASK)
21801772Sjl139090 		    << INTERRUPT_MAPPING_ENTRIES_INT_CNTRL_NUM));
21811772Sjl139090 		break;
21821772Sjl139090 	default:
21831772Sjl139090 		DBG(DBG_CB, NULL, "hvio_intr_settarget - "
21841772Sjl139090 		    "unknown chip type: 0x%x\n", PX_CHIP_TYPE(pxu_p));
21851772Sjl139090 		return (EINVAL);
21861772Sjl139090 	}
21870Sstevel@tonic-gate 
21880Sstevel@tonic-gate 	/* For EQ interrupts, set DATA MONDO bit */
21890Sstevel@tonic-gate 	if ((ino >= PX_DEFAULT_MSIQ_1ST_DEVINO) &&
21900Sstevel@tonic-gate 	    (ino < (PX_DEFAULT_MSIQ_1ST_DEVINO + PX_DEFAULT_MSIQ_CNT)))
21910Sstevel@tonic-gate 		val |= (0x1ull << INTERRUPT_MAPPING_ENTRIES_MDO_MODE);
21920Sstevel@tonic-gate 
21930Sstevel@tonic-gate 	CSRA_XS((caddr_t)dev_hdl, INTERRUPT_MAPPING, ino, val);
21940Sstevel@tonic-gate 
21950Sstevel@tonic-gate 	return (H_EOK);
21960Sstevel@tonic-gate }
21970Sstevel@tonic-gate 
21980Sstevel@tonic-gate /*
21990Sstevel@tonic-gate  * MSIQ Functions:
22000Sstevel@tonic-gate  */
22010Sstevel@tonic-gate uint64_t
22020Sstevel@tonic-gate hvio_msiq_init(devhandle_t dev_hdl, pxu_t *pxu_p)
22030Sstevel@tonic-gate {
22040Sstevel@tonic-gate 	CSRA_XS((caddr_t)dev_hdl, EVENT_QUEUE_BASE_ADDRESS, 0,
22050Sstevel@tonic-gate 	    (uint64_t)pxu_p->msiq_mapped_p);
22060Sstevel@tonic-gate 	DBG(DBG_IB, NULL,
22070Sstevel@tonic-gate 	    "hvio_msiq_init: EVENT_QUEUE_BASE_ADDRESS 0x%llx\n",
22080Sstevel@tonic-gate 	    CSR_XR((caddr_t)dev_hdl, EVENT_QUEUE_BASE_ADDRESS));
22090Sstevel@tonic-gate 
22100Sstevel@tonic-gate 	CSRA_XS((caddr_t)dev_hdl, INTERRUPT_MONDO_DATA_0, 0,
22112091Sam139583 	    (uint64_t)ID_TO_IGN(PX_CHIP_TYPE(pxu_p),
22122091Sam139583 	    pxu_p->portid) << INO_BITS);
22130Sstevel@tonic-gate 	DBG(DBG_IB, NULL, "hvio_msiq_init: "
22140Sstevel@tonic-gate 	    "INTERRUPT_MONDO_DATA_0: 0x%llx\n",
22150Sstevel@tonic-gate 	    CSR_XR((caddr_t)dev_hdl, INTERRUPT_MONDO_DATA_0));
22160Sstevel@tonic-gate 
22170Sstevel@tonic-gate 	return (H_EOK);
22180Sstevel@tonic-gate }
22190Sstevel@tonic-gate 
22200Sstevel@tonic-gate uint64_t
22210Sstevel@tonic-gate hvio_msiq_getvalid(devhandle_t dev_hdl, msiqid_t msiq_id,
22220Sstevel@tonic-gate     pci_msiq_valid_state_t *msiq_valid_state)
22230Sstevel@tonic-gate {
22240Sstevel@tonic-gate 	uint32_t	eq_state;
22250Sstevel@tonic-gate 	uint64_t	ret = H_EOK;
22260Sstevel@tonic-gate 
22270Sstevel@tonic-gate 	eq_state = CSRA_FR((caddr_t)dev_hdl, EVENT_QUEUE_STATE,
22280Sstevel@tonic-gate 	    msiq_id, ENTRIES_STATE);
22290Sstevel@tonic-gate 
22300Sstevel@tonic-gate 	switch (eq_state) {
22310Sstevel@tonic-gate 	case EQ_IDLE_STATE:
22320Sstevel@tonic-gate 		*msiq_valid_state = PCI_MSIQ_INVALID;
22330Sstevel@tonic-gate 		break;
22340Sstevel@tonic-gate 	case EQ_ACTIVE_STATE:
22350Sstevel@tonic-gate 	case EQ_ERROR_STATE:
22360Sstevel@tonic-gate 		*msiq_valid_state = PCI_MSIQ_VALID;
22370Sstevel@tonic-gate 		break;
22380Sstevel@tonic-gate 	default:
22390Sstevel@tonic-gate 		ret = H_EIO;
22400Sstevel@tonic-gate 		break;
22410Sstevel@tonic-gate 	}
22420Sstevel@tonic-gate 
22430Sstevel@tonic-gate 	return (ret);
22440Sstevel@tonic-gate }
22450Sstevel@tonic-gate 
22460Sstevel@tonic-gate uint64_t
22470Sstevel@tonic-gate hvio_msiq_setvalid(devhandle_t dev_hdl, msiqid_t msiq_id,
22480Sstevel@tonic-gate     pci_msiq_valid_state_t msiq_valid_state)
22490Sstevel@tonic-gate {
22500Sstevel@tonic-gate 	uint64_t	ret = H_EOK;
22510Sstevel@tonic-gate 
22520Sstevel@tonic-gate 	switch (msiq_valid_state) {
22530Sstevel@tonic-gate 	case PCI_MSIQ_INVALID:
22540Sstevel@tonic-gate 		CSRA_BS((caddr_t)dev_hdl, EVENT_QUEUE_CONTROL_CLEAR,
22550Sstevel@tonic-gate 		    msiq_id, ENTRIES_DIS);
22560Sstevel@tonic-gate 		break;
22570Sstevel@tonic-gate 	case PCI_MSIQ_VALID:
22580Sstevel@tonic-gate 		CSRA_BS((caddr_t)dev_hdl, EVENT_QUEUE_CONTROL_SET,
22590Sstevel@tonic-gate 		    msiq_id, ENTRIES_EN);
22600Sstevel@tonic-gate 		break;
22610Sstevel@tonic-gate 	default:
22620Sstevel@tonic-gate 		ret = H_EINVAL;
22630Sstevel@tonic-gate 		break;
22640Sstevel@tonic-gate 	}
22650Sstevel@tonic-gate 
22660Sstevel@tonic-gate 	return (ret);
22670Sstevel@tonic-gate }
22680Sstevel@tonic-gate 
22690Sstevel@tonic-gate uint64_t
22700Sstevel@tonic-gate hvio_msiq_getstate(devhandle_t dev_hdl, msiqid_t msiq_id,
22710Sstevel@tonic-gate     pci_msiq_state_t *msiq_state)
22720Sstevel@tonic-gate {
22730Sstevel@tonic-gate 	uint32_t	eq_state;
22740Sstevel@tonic-gate 	uint64_t	ret = H_EOK;
22750Sstevel@tonic-gate 
22760Sstevel@tonic-gate 	eq_state = CSRA_FR((caddr_t)dev_hdl, EVENT_QUEUE_STATE,
22770Sstevel@tonic-gate 	    msiq_id, ENTRIES_STATE);
22780Sstevel@tonic-gate 
22790Sstevel@tonic-gate 	switch (eq_state) {
22800Sstevel@tonic-gate 	case EQ_IDLE_STATE:
22810Sstevel@tonic-gate 	case EQ_ACTIVE_STATE:
22820Sstevel@tonic-gate 		*msiq_state = PCI_MSIQ_STATE_IDLE;
22830Sstevel@tonic-gate 		break;
22840Sstevel@tonic-gate 	case EQ_ERROR_STATE:
22850Sstevel@tonic-gate 		*msiq_state = PCI_MSIQ_STATE_ERROR;
22860Sstevel@tonic-gate 		break;
22870Sstevel@tonic-gate 	default:
22880Sstevel@tonic-gate 		ret = H_EIO;
22890Sstevel@tonic-gate 	}
22900Sstevel@tonic-gate 
22910Sstevel@tonic-gate 	return (ret);
22920Sstevel@tonic-gate }
22930Sstevel@tonic-gate 
22940Sstevel@tonic-gate uint64_t
22950Sstevel@tonic-gate hvio_msiq_setstate(devhandle_t dev_hdl, msiqid_t msiq_id,
22960Sstevel@tonic-gate     pci_msiq_state_t msiq_state)
22970Sstevel@tonic-gate {
22980Sstevel@tonic-gate 	uint32_t	eq_state;
22990Sstevel@tonic-gate 	uint64_t	ret = H_EOK;
23000Sstevel@tonic-gate 
23010Sstevel@tonic-gate 	eq_state = CSRA_FR((caddr_t)dev_hdl, EVENT_QUEUE_STATE,
23020Sstevel@tonic-gate 	    msiq_id, ENTRIES_STATE);
23030Sstevel@tonic-gate 
23040Sstevel@tonic-gate 	switch (eq_state) {
23050Sstevel@tonic-gate 	case EQ_IDLE_STATE:
23060Sstevel@tonic-gate 		if (msiq_state == PCI_MSIQ_STATE_ERROR)
23070Sstevel@tonic-gate 			ret = H_EIO;
23080Sstevel@tonic-gate 		break;
23090Sstevel@tonic-gate 	case EQ_ACTIVE_STATE:
23100Sstevel@tonic-gate 		if (msiq_state == PCI_MSIQ_STATE_ERROR)
23110Sstevel@tonic-gate 			CSRA_BS((caddr_t)dev_hdl, EVENT_QUEUE_CONTROL_SET,
23120Sstevel@tonic-gate 			    msiq_id, ENTRIES_ENOVERR);
23130Sstevel@tonic-gate 		else
23140Sstevel@tonic-gate 			ret = H_EIO;
23150Sstevel@tonic-gate 		break;
23160Sstevel@tonic-gate 	case EQ_ERROR_STATE:
23170Sstevel@tonic-gate 		if (msiq_state == PCI_MSIQ_STATE_IDLE)
23180Sstevel@tonic-gate 			CSRA_BS((caddr_t)dev_hdl, EVENT_QUEUE_CONTROL_CLEAR,
23190Sstevel@tonic-gate 			    msiq_id, ENTRIES_E2I);
23200Sstevel@tonic-gate 		else
23210Sstevel@tonic-gate 			ret = H_EIO;
23220Sstevel@tonic-gate 		break;
23230Sstevel@tonic-gate 	default:
23240Sstevel@tonic-gate 		ret = H_EIO;
23250Sstevel@tonic-gate 	}
23260Sstevel@tonic-gate 
23270Sstevel@tonic-gate 	return (ret);
23280Sstevel@tonic-gate }
23290Sstevel@tonic-gate 
23300Sstevel@tonic-gate uint64_t
23310Sstevel@tonic-gate hvio_msiq_gethead(devhandle_t dev_hdl, msiqid_t msiq_id,
23320Sstevel@tonic-gate     msiqhead_t *msiq_head)
23330Sstevel@tonic-gate {
23340Sstevel@tonic-gate 	*msiq_head = CSRA_FR((caddr_t)dev_hdl, EVENT_QUEUE_HEAD,
23350Sstevel@tonic-gate 	    msiq_id, ENTRIES_HEAD);
23360Sstevel@tonic-gate 
23370Sstevel@tonic-gate 	return (H_EOK);
23380Sstevel@tonic-gate }
23390Sstevel@tonic-gate 
23400Sstevel@tonic-gate uint64_t
23410Sstevel@tonic-gate hvio_msiq_sethead(devhandle_t dev_hdl, msiqid_t msiq_id,
23420Sstevel@tonic-gate     msiqhead_t msiq_head)
23430Sstevel@tonic-gate {
23440Sstevel@tonic-gate 	CSRA_FS((caddr_t)dev_hdl, EVENT_QUEUE_HEAD, msiq_id,
23450Sstevel@tonic-gate 	    ENTRIES_HEAD, msiq_head);
23460Sstevel@tonic-gate 
23470Sstevel@tonic-gate 	return (H_EOK);
23480Sstevel@tonic-gate }
23490Sstevel@tonic-gate 
23500Sstevel@tonic-gate uint64_t
23510Sstevel@tonic-gate hvio_msiq_gettail(devhandle_t dev_hdl, msiqid_t msiq_id,
23520Sstevel@tonic-gate     msiqtail_t *msiq_tail)
23530Sstevel@tonic-gate {
23540Sstevel@tonic-gate 	*msiq_tail = CSRA_FR((caddr_t)dev_hdl, EVENT_QUEUE_TAIL,
23550Sstevel@tonic-gate 	    msiq_id, ENTRIES_TAIL);
23560Sstevel@tonic-gate 
23570Sstevel@tonic-gate 	return (H_EOK);
23580Sstevel@tonic-gate }
23590Sstevel@tonic-gate 
23600Sstevel@tonic-gate /*
23610Sstevel@tonic-gate  * MSI Functions:
23620Sstevel@tonic-gate  */
23630Sstevel@tonic-gate uint64_t
23640Sstevel@tonic-gate hvio_msi_init(devhandle_t dev_hdl, uint64_t addr32, uint64_t addr64)
23650Sstevel@tonic-gate {
23660Sstevel@tonic-gate 	/* PCI MEM 32 resources to perform 32 bit MSI transactions */
23670Sstevel@tonic-gate 	CSRA_FS((caddr_t)dev_hdl, MSI_32_BIT_ADDRESS, 0,
23680Sstevel@tonic-gate 	    ADDR, (uint64_t)addr32 >> MSI_32_BIT_ADDRESS_ADDR);
23696953Sanbui 	DBG(DBG_IB, NULL, "hvio_msi_init: MSI_32_BIT_ADDRESS: 0x%llx\n",
23700Sstevel@tonic-gate 	    CSR_XR((caddr_t)dev_hdl, MSI_32_BIT_ADDRESS));
23710Sstevel@tonic-gate 
23720Sstevel@tonic-gate 	/* Reserve PCI MEM 64 resources to perform 64 bit MSI transactions */
23730Sstevel@tonic-gate 	CSRA_FS((caddr_t)dev_hdl, MSI_64_BIT_ADDRESS, 0,
23740Sstevel@tonic-gate 	    ADDR, (uint64_t)addr64 >> MSI_64_BIT_ADDRESS_ADDR);
23756953Sanbui 	DBG(DBG_IB, NULL, "hvio_msi_init: MSI_64_BIT_ADDRESS: 0x%llx\n",
23760Sstevel@tonic-gate 	    CSR_XR((caddr_t)dev_hdl, MSI_64_BIT_ADDRESS));
23770Sstevel@tonic-gate 
23780Sstevel@tonic-gate 	return (H_EOK);
23790Sstevel@tonic-gate }
23800Sstevel@tonic-gate 
23810Sstevel@tonic-gate uint64_t
23820Sstevel@tonic-gate hvio_msi_getmsiq(devhandle_t dev_hdl, msinum_t msi_num,
23830Sstevel@tonic-gate     msiqid_t *msiq_id)
23840Sstevel@tonic-gate {
23850Sstevel@tonic-gate 	*msiq_id = CSRA_FR((caddr_t)dev_hdl, MSI_MAPPING,
23860Sstevel@tonic-gate 	    msi_num, ENTRIES_EQNUM);
23870Sstevel@tonic-gate 
23880Sstevel@tonic-gate 	return (H_EOK);
23890Sstevel@tonic-gate }
23900Sstevel@tonic-gate 
23910Sstevel@tonic-gate uint64_t
23920Sstevel@tonic-gate hvio_msi_setmsiq(devhandle_t dev_hdl, msinum_t msi_num,
23930Sstevel@tonic-gate     msiqid_t msiq_id)
23940Sstevel@tonic-gate {
23950Sstevel@tonic-gate 	CSRA_FS((caddr_t)dev_hdl, MSI_MAPPING, msi_num,
23960Sstevel@tonic-gate 	    ENTRIES_EQNUM, msiq_id);
23970Sstevel@tonic-gate 
23980Sstevel@tonic-gate 	return (H_EOK);
23990Sstevel@tonic-gate }
24000Sstevel@tonic-gate 
24010Sstevel@tonic-gate uint64_t
24020Sstevel@tonic-gate hvio_msi_getvalid(devhandle_t dev_hdl, msinum_t msi_num,
24030Sstevel@tonic-gate     pci_msi_valid_state_t *msi_valid_state)
24040Sstevel@tonic-gate {
24050Sstevel@tonic-gate 	*msi_valid_state = CSRA_BR((caddr_t)dev_hdl, MSI_MAPPING,
24060Sstevel@tonic-gate 	    msi_num, ENTRIES_V);
24070Sstevel@tonic-gate 
24080Sstevel@tonic-gate 	return (H_EOK);
24090Sstevel@tonic-gate }
24100Sstevel@tonic-gate 
24110Sstevel@tonic-gate uint64_t
24120Sstevel@tonic-gate hvio_msi_setvalid(devhandle_t dev_hdl, msinum_t msi_num,
24130Sstevel@tonic-gate     pci_msi_valid_state_t msi_valid_state)
24140Sstevel@tonic-gate {
24150Sstevel@tonic-gate 	uint64_t	ret = H_EOK;
24160Sstevel@tonic-gate 
24170Sstevel@tonic-gate 	switch (msi_valid_state) {
24180Sstevel@tonic-gate 	case PCI_MSI_VALID:
24190Sstevel@tonic-gate 		CSRA_BS((caddr_t)dev_hdl, MSI_MAPPING, msi_num,
24200Sstevel@tonic-gate 		    ENTRIES_V);
24210Sstevel@tonic-gate 		break;
24220Sstevel@tonic-gate 	case PCI_MSI_INVALID:
24230Sstevel@tonic-gate 		CSRA_BC((caddr_t)dev_hdl, MSI_MAPPING, msi_num,
24240Sstevel@tonic-gate 		    ENTRIES_V);
24250Sstevel@tonic-gate 		break;
24260Sstevel@tonic-gate 	default:
24270Sstevel@tonic-gate 		ret = H_EINVAL;
24280Sstevel@tonic-gate 	}
24290Sstevel@tonic-gate 
24300Sstevel@tonic-gate 	return (ret);
24310Sstevel@tonic-gate }
24320Sstevel@tonic-gate 
24330Sstevel@tonic-gate uint64_t
24340Sstevel@tonic-gate hvio_msi_getstate(devhandle_t dev_hdl, msinum_t msi_num,
24350Sstevel@tonic-gate     pci_msi_state_t *msi_state)
24360Sstevel@tonic-gate {
24370Sstevel@tonic-gate 	*msi_state = CSRA_BR((caddr_t)dev_hdl, MSI_MAPPING,
24380Sstevel@tonic-gate 	    msi_num, ENTRIES_EQWR_N);
24390Sstevel@tonic-gate 
24400Sstevel@tonic-gate 	return (H_EOK);
24410Sstevel@tonic-gate }
24420Sstevel@tonic-gate 
24430Sstevel@tonic-gate uint64_t
24440Sstevel@tonic-gate hvio_msi_setstate(devhandle_t dev_hdl, msinum_t msi_num,
24450Sstevel@tonic-gate     pci_msi_state_t msi_state)
24460Sstevel@tonic-gate {
24470Sstevel@tonic-gate 	uint64_t	ret = H_EOK;
24480Sstevel@tonic-gate 
24490Sstevel@tonic-gate 	switch (msi_state) {
24500Sstevel@tonic-gate 	case PCI_MSI_STATE_IDLE:
24510Sstevel@tonic-gate 		CSRA_BS((caddr_t)dev_hdl, MSI_CLEAR, msi_num,
24520Sstevel@tonic-gate 		    ENTRIES_EQWR_N);
24530Sstevel@tonic-gate 		break;
24540Sstevel@tonic-gate 	case PCI_MSI_STATE_DELIVERED:
24550Sstevel@tonic-gate 	default:
24560Sstevel@tonic-gate 		ret = H_EINVAL;
24570Sstevel@tonic-gate 		break;
24580Sstevel@tonic-gate 	}
24590Sstevel@tonic-gate 
24600Sstevel@tonic-gate 	return (ret);
24610Sstevel@tonic-gate }
24620Sstevel@tonic-gate 
24630Sstevel@tonic-gate /*
24640Sstevel@tonic-gate  * MSG Functions:
24650Sstevel@tonic-gate  */
24660Sstevel@tonic-gate uint64_t
24670Sstevel@tonic-gate hvio_msg_getmsiq(devhandle_t dev_hdl, pcie_msg_type_t msg_type,
24680Sstevel@tonic-gate     msiqid_t *msiq_id)
24690Sstevel@tonic-gate {
24700Sstevel@tonic-gate 	uint64_t	ret = H_EOK;
24710Sstevel@tonic-gate 
24720Sstevel@tonic-gate 	switch (msg_type) {
24730Sstevel@tonic-gate 	case PCIE_PME_MSG:
24740Sstevel@tonic-gate 		*msiq_id = CSR_FR((caddr_t)dev_hdl, PM_PME_MAPPING, EQNUM);
24750Sstevel@tonic-gate 		break;
24760Sstevel@tonic-gate 	case PCIE_PME_ACK_MSG:
24770Sstevel@tonic-gate 		*msiq_id = CSR_FR((caddr_t)dev_hdl, PME_TO_ACK_MAPPING,
24780Sstevel@tonic-gate 		    EQNUM);
24790Sstevel@tonic-gate 		break;
24800Sstevel@tonic-gate 	case PCIE_CORR_MSG:
24810Sstevel@tonic-gate 		*msiq_id = CSR_FR((caddr_t)dev_hdl, ERR_COR_MAPPING, EQNUM);
24820Sstevel@tonic-gate 		break;
24830Sstevel@tonic-gate 	case PCIE_NONFATAL_MSG:
24840Sstevel@tonic-gate 		*msiq_id = CSR_FR((caddr_t)dev_hdl, ERR_NONFATAL_MAPPING,
24850Sstevel@tonic-gate 		    EQNUM);
24860Sstevel@tonic-gate 		break;
24870Sstevel@tonic-gate 	case PCIE_FATAL_MSG:
24880Sstevel@tonic-gate 		*msiq_id = CSR_FR((caddr_t)dev_hdl, ERR_FATAL_MAPPING, EQNUM);
24890Sstevel@tonic-gate 		break;
24900Sstevel@tonic-gate 	default:
24910Sstevel@tonic-gate 		ret = H_EINVAL;
24920Sstevel@tonic-gate 		break;
24930Sstevel@tonic-gate 	}
24940Sstevel@tonic-gate 
24950Sstevel@tonic-gate 	return (ret);
24960Sstevel@tonic-gate }
24970Sstevel@tonic-gate 
24980Sstevel@tonic-gate uint64_t
24990Sstevel@tonic-gate hvio_msg_setmsiq(devhandle_t dev_hdl, pcie_msg_type_t msg_type,
25000Sstevel@tonic-gate     msiqid_t msiq_id)
25010Sstevel@tonic-gate {
25020Sstevel@tonic-gate 	uint64_t	ret = H_EOK;
25030Sstevel@tonic-gate 
25040Sstevel@tonic-gate 	switch (msg_type) {
25050Sstevel@tonic-gate 	case PCIE_PME_MSG:
25060Sstevel@tonic-gate 		CSR_FS((caddr_t)dev_hdl, PM_PME_MAPPING, EQNUM, msiq_id);
25070Sstevel@tonic-gate 		break;
25080Sstevel@tonic-gate 	case PCIE_PME_ACK_MSG:
25090Sstevel@tonic-gate 		CSR_FS((caddr_t)dev_hdl, PME_TO_ACK_MAPPING, EQNUM, msiq_id);
25100Sstevel@tonic-gate 		break;
25110Sstevel@tonic-gate 	case PCIE_CORR_MSG:
25120Sstevel@tonic-gate 		CSR_FS((caddr_t)dev_hdl, ERR_COR_MAPPING, EQNUM, msiq_id);
25130Sstevel@tonic-gate 		break;
25140Sstevel@tonic-gate 	case PCIE_NONFATAL_MSG:
25150Sstevel@tonic-gate 		CSR_FS((caddr_t)dev_hdl, ERR_NONFATAL_MAPPING, EQNUM, msiq_id);
25160Sstevel@tonic-gate 		break;
25170Sstevel@tonic-gate 	case PCIE_FATAL_MSG:
25180Sstevel@tonic-gate 		CSR_FS((caddr_t)dev_hdl, ERR_FATAL_MAPPING, EQNUM, msiq_id);
25190Sstevel@tonic-gate 		break;
25200Sstevel@tonic-gate 	default:
25210Sstevel@tonic-gate 		ret = H_EINVAL;
25220Sstevel@tonic-gate 		break;
25230Sstevel@tonic-gate 	}
25240Sstevel@tonic-gate 
25250Sstevel@tonic-gate 	return (ret);
25260Sstevel@tonic-gate }
25270Sstevel@tonic-gate 
25280Sstevel@tonic-gate uint64_t
25290Sstevel@tonic-gate hvio_msg_getvalid(devhandle_t dev_hdl, pcie_msg_type_t msg_type,
25300Sstevel@tonic-gate     pcie_msg_valid_state_t *msg_valid_state)
25310Sstevel@tonic-gate {
25320Sstevel@tonic-gate 	uint64_t	ret = H_EOK;
25330Sstevel@tonic-gate 
25340Sstevel@tonic-gate 	switch (msg_type) {
25350Sstevel@tonic-gate 	case PCIE_PME_MSG:
25360Sstevel@tonic-gate 		*msg_valid_state = CSR_BR((caddr_t)dev_hdl, PM_PME_MAPPING, V);
25370Sstevel@tonic-gate 		break;
25380Sstevel@tonic-gate 	case PCIE_PME_ACK_MSG:
25390Sstevel@tonic-gate 		*msg_valid_state = CSR_BR((caddr_t)dev_hdl,
25400Sstevel@tonic-gate 		    PME_TO_ACK_MAPPING, V);
25410Sstevel@tonic-gate 		break;
25420Sstevel@tonic-gate 	case PCIE_CORR_MSG:
25430Sstevel@tonic-gate 		*msg_valid_state = CSR_BR((caddr_t)dev_hdl, ERR_COR_MAPPING, V);
25440Sstevel@tonic-gate 		break;
25450Sstevel@tonic-gate 	case PCIE_NONFATAL_MSG:
25460Sstevel@tonic-gate 		*msg_valid_state = CSR_BR((caddr_t)dev_hdl,
25470Sstevel@tonic-gate 		    ERR_NONFATAL_MAPPING, V);
25480Sstevel@tonic-gate 		break;
25490Sstevel@tonic-gate 	case PCIE_FATAL_MSG:
25500Sstevel@tonic-gate 		*msg_valid_state = CSR_BR((caddr_t)dev_hdl, ERR_FATAL_MAPPING,
25510Sstevel@tonic-gate 		    V);
25520Sstevel@tonic-gate 		break;
25530Sstevel@tonic-gate 	default:
25540Sstevel@tonic-gate 		ret = H_EINVAL;
25550Sstevel@tonic-gate 		break;
25560Sstevel@tonic-gate 	}
25570Sstevel@tonic-gate 
25580Sstevel@tonic-gate 	return (ret);
25590Sstevel@tonic-gate }
25600Sstevel@tonic-gate 
25610Sstevel@tonic-gate uint64_t
25620Sstevel@tonic-gate hvio_msg_setvalid(devhandle_t dev_hdl, pcie_msg_type_t msg_type,
25630Sstevel@tonic-gate     pcie_msg_valid_state_t msg_valid_state)
25640Sstevel@tonic-gate {
25650Sstevel@tonic-gate 	uint64_t	ret = H_EOK;
25660Sstevel@tonic-gate 
25670Sstevel@tonic-gate 	switch (msg_valid_state) {
25680Sstevel@tonic-gate 	case PCIE_MSG_VALID:
25690Sstevel@tonic-gate 		switch (msg_type) {
25700Sstevel@tonic-gate 		case PCIE_PME_MSG:
25710Sstevel@tonic-gate 			CSR_BS((caddr_t)dev_hdl, PM_PME_MAPPING, V);
25720Sstevel@tonic-gate 			break;
25730Sstevel@tonic-gate 		case PCIE_PME_ACK_MSG:
25740Sstevel@tonic-gate 			CSR_BS((caddr_t)dev_hdl, PME_TO_ACK_MAPPING, V);
25750Sstevel@tonic-gate 			break;
25760Sstevel@tonic-gate 		case PCIE_CORR_MSG:
25770Sstevel@tonic-gate 			CSR_BS((caddr_t)dev_hdl, ERR_COR_MAPPING, V);
25780Sstevel@tonic-gate 			break;
25790Sstevel@tonic-gate 		case PCIE_NONFATAL_MSG:
25800Sstevel@tonic-gate 			CSR_BS((caddr_t)dev_hdl, ERR_NONFATAL_MAPPING, V);
25810Sstevel@tonic-gate 			break;
25820Sstevel@tonic-gate 		case PCIE_FATAL_MSG:
25830Sstevel@tonic-gate 			CSR_BS((caddr_t)dev_hdl, ERR_FATAL_MAPPING, V);
25840Sstevel@tonic-gate 			break;
25850Sstevel@tonic-gate 		default:
25860Sstevel@tonic-gate 			ret = H_EINVAL;
25870Sstevel@tonic-gate 			break;
25880Sstevel@tonic-gate 		}
25890Sstevel@tonic-gate 
25900Sstevel@tonic-gate 		break;
25910Sstevel@tonic-gate 	case PCIE_MSG_INVALID:
25920Sstevel@tonic-gate 		switch (msg_type) {
25930Sstevel@tonic-gate 		case PCIE_PME_MSG:
25940Sstevel@tonic-gate 			CSR_BC((caddr_t)dev_hdl, PM_PME_MAPPING, V);
25950Sstevel@tonic-gate 			break;
25960Sstevel@tonic-gate 		case PCIE_PME_ACK_MSG:
25970Sstevel@tonic-gate 			CSR_BC((caddr_t)dev_hdl, PME_TO_ACK_MAPPING, V);
25980Sstevel@tonic-gate 			break;
25990Sstevel@tonic-gate 		case PCIE_CORR_MSG:
26000Sstevel@tonic-gate 			CSR_BC((caddr_t)dev_hdl, ERR_COR_MAPPING, V);
26010Sstevel@tonic-gate 			break;
26020Sstevel@tonic-gate 		case PCIE_NONFATAL_MSG:
26030Sstevel@tonic-gate 			CSR_BC((caddr_t)dev_hdl, ERR_NONFATAL_MAPPING, V);
26040Sstevel@tonic-gate 			break;
26050Sstevel@tonic-gate 		case PCIE_FATAL_MSG:
26060Sstevel@tonic-gate 			CSR_BC((caddr_t)dev_hdl, ERR_FATAL_MAPPING, V);
26070Sstevel@tonic-gate 			break;
26080Sstevel@tonic-gate 		default:
26090Sstevel@tonic-gate 			ret = H_EINVAL;
26100Sstevel@tonic-gate 			break;
26110Sstevel@tonic-gate 		}
26120Sstevel@tonic-gate 		break;
26130Sstevel@tonic-gate 	default:
26140Sstevel@tonic-gate 		ret = H_EINVAL;
26150Sstevel@tonic-gate 	}
26160Sstevel@tonic-gate 
26170Sstevel@tonic-gate 	return (ret);
26180Sstevel@tonic-gate }
26190Sstevel@tonic-gate 
26200Sstevel@tonic-gate /*
26210Sstevel@tonic-gate  * Suspend/Resume Functions:
26220Sstevel@tonic-gate  *	(pec, mmu, ib)
26230Sstevel@tonic-gate  *	cb
26240Sstevel@tonic-gate  * Registers saved have all been touched in the XXX_init functions.
26250Sstevel@tonic-gate  */
26260Sstevel@tonic-gate uint64_t
26270Sstevel@tonic-gate hvio_suspend(devhandle_t dev_hdl, pxu_t *pxu_p)
26280Sstevel@tonic-gate {
26290Sstevel@tonic-gate 	uint64_t	*config_state;
26300Sstevel@tonic-gate 	int		total_size;
26310Sstevel@tonic-gate 	int		i;
26320Sstevel@tonic-gate 
26330Sstevel@tonic-gate 	if (msiq_suspend(dev_hdl, pxu_p) != H_EOK)
26340Sstevel@tonic-gate 		return (H_EIO);
26350Sstevel@tonic-gate 
26360Sstevel@tonic-gate 	total_size = PEC_SIZE + MMU_SIZE + IB_SIZE + IB_MAP_SIZE;
26370Sstevel@tonic-gate 	config_state = kmem_zalloc(total_size, KM_NOSLEEP);
26380Sstevel@tonic-gate 
26390Sstevel@tonic-gate 	if (config_state == NULL) {
26400Sstevel@tonic-gate 		return (H_EIO);
26410Sstevel@tonic-gate 	}
26420Sstevel@tonic-gate 
26430Sstevel@tonic-gate 	/*
26440Sstevel@tonic-gate 	 * Soft state for suspend/resume  from pxu_t
26450Sstevel@tonic-gate 	 * uint64_t	*pec_config_state;
26460Sstevel@tonic-gate 	 * uint64_t	*mmu_config_state;
26470Sstevel@tonic-gate 	 * uint64_t	*ib_intr_map;
26480Sstevel@tonic-gate 	 * uint64_t	*ib_config_state;
26490Sstevel@tonic-gate 	 * uint64_t	*xcb_config_state;
26500Sstevel@tonic-gate 	 */
26510Sstevel@tonic-gate 
26520Sstevel@tonic-gate 	/* Save the PEC configuration states */
26530Sstevel@tonic-gate 	pxu_p->pec_config_state = config_state;
26540Sstevel@tonic-gate 	for (i = 0; i < PEC_KEYS; i++) {
26551772Sjl139090 		if ((pec_config_state_regs[i].chip == PX_CHIP_TYPE(pxu_p)) ||
26561772Sjl139090 		    (pec_config_state_regs[i].chip == PX_CHIP_UNIDENTIFIED)) {
26571772Sjl139090 			pxu_p->pec_config_state[i] =
26581772Sjl139090 			    CSR_XR((caddr_t)dev_hdl,
26591772Sjl139090 			    pec_config_state_regs[i].reg);
26606953Sanbui 		}
26610Sstevel@tonic-gate 	}
26620Sstevel@tonic-gate 
26630Sstevel@tonic-gate 	/* Save the MMU configuration states */
26640Sstevel@tonic-gate 	pxu_p->mmu_config_state = pxu_p->pec_config_state + PEC_KEYS;
26650Sstevel@tonic-gate 	for (i = 0; i < MMU_KEYS; i++) {
26660Sstevel@tonic-gate 		pxu_p->mmu_config_state[i] =
26670Sstevel@tonic-gate 		    CSR_XR((caddr_t)dev_hdl, mmu_config_state_regs[i]);
26680Sstevel@tonic-gate 	}
26690Sstevel@tonic-gate 
26700Sstevel@tonic-gate 	/* Save the interrupt mapping registers */
26710Sstevel@tonic-gate 	pxu_p->ib_intr_map = pxu_p->mmu_config_state + MMU_KEYS;
26720Sstevel@tonic-gate 	for (i = 0; i < INTERRUPT_MAPPING_ENTRIES; i++) {
26730Sstevel@tonic-gate 		pxu_p->ib_intr_map[i] =
26740Sstevel@tonic-gate 		    CSRA_XR((caddr_t)dev_hdl, INTERRUPT_MAPPING, i);
26750Sstevel@tonic-gate 	}
26760Sstevel@tonic-gate 
26770Sstevel@tonic-gate 	/* Save the IB configuration states */
26780Sstevel@tonic-gate 	pxu_p->ib_config_state = pxu_p->ib_intr_map + INTERRUPT_MAPPING_ENTRIES;
26790Sstevel@tonic-gate 	for (i = 0; i < IB_KEYS; i++) {
26800Sstevel@tonic-gate 		pxu_p->ib_config_state[i] =
26810Sstevel@tonic-gate 		    CSR_XR((caddr_t)dev_hdl, ib_config_state_regs[i]);
26820Sstevel@tonic-gate 	}
26830Sstevel@tonic-gate 
26840Sstevel@tonic-gate 	return (H_EOK);
26850Sstevel@tonic-gate }
26860Sstevel@tonic-gate 
26870Sstevel@tonic-gate void
26880Sstevel@tonic-gate hvio_resume(devhandle_t dev_hdl, devino_t devino, pxu_t *pxu_p)
26890Sstevel@tonic-gate {
26900Sstevel@tonic-gate 	int		total_size;
26910Sstevel@tonic-gate 	sysino_t	sysino;
26920Sstevel@tonic-gate 	int		i;
2693*7124Sanbui 	uint64_t	ret;
26940Sstevel@tonic-gate 
26950Sstevel@tonic-gate 	/* Make sure that suspend actually did occur */
26960Sstevel@tonic-gate 	if (!pxu_p->pec_config_state) {
26970Sstevel@tonic-gate 		return;
26980Sstevel@tonic-gate 	}
26990Sstevel@tonic-gate 
27000Sstevel@tonic-gate 	/* Restore IB configuration states */
27010Sstevel@tonic-gate 	for (i = 0; i < IB_KEYS; i++) {
27020Sstevel@tonic-gate 		CSR_XS((caddr_t)dev_hdl, ib_config_state_regs[i],
27030Sstevel@tonic-gate 		    pxu_p->ib_config_state[i]);
27040Sstevel@tonic-gate 	}
27050Sstevel@tonic-gate 
27060Sstevel@tonic-gate 	/*
27070Sstevel@tonic-gate 	 * Restore the interrupt mapping registers
27080Sstevel@tonic-gate 	 * And make sure the intrs are idle.
27090Sstevel@tonic-gate 	 */
27100Sstevel@tonic-gate 	for (i = 0; i < INTERRUPT_MAPPING_ENTRIES; i++) {
27110Sstevel@tonic-gate 		CSRA_FS((caddr_t)dev_hdl, INTERRUPT_CLEAR, i,
27120Sstevel@tonic-gate 		    ENTRIES_INT_STATE, INTERRUPT_IDLE_STATE);
27130Sstevel@tonic-gate 		CSRA_XS((caddr_t)dev_hdl, INTERRUPT_MAPPING, i,
27140Sstevel@tonic-gate 		    pxu_p->ib_intr_map[i]);
27150Sstevel@tonic-gate 	}
27160Sstevel@tonic-gate 
27170Sstevel@tonic-gate 	/* Restore MMU configuration states */
27180Sstevel@tonic-gate 	/* Clear the cache. */
27190Sstevel@tonic-gate 	CSR_XS((caddr_t)dev_hdl, MMU_TTE_CACHE_INVALIDATE, -1ull);
27200Sstevel@tonic-gate 
27210Sstevel@tonic-gate 	for (i = 0; i < MMU_KEYS; i++) {
27220Sstevel@tonic-gate 		CSR_XS((caddr_t)dev_hdl, mmu_config_state_regs[i],
27230Sstevel@tonic-gate 		    pxu_p->mmu_config_state[i]);
27240Sstevel@tonic-gate 	}
27250Sstevel@tonic-gate 
27260Sstevel@tonic-gate 	/* Restore PEC configuration states */
27270Sstevel@tonic-gate 	/* Make sure all reset bits are low until error is detected */
27280Sstevel@tonic-gate 	CSR_XS((caddr_t)dev_hdl, LPU_RESET, 0ull);
27290Sstevel@tonic-gate 
27300Sstevel@tonic-gate 	for (i = 0; i < PEC_KEYS; i++) {
27311772Sjl139090 		if ((pec_config_state_regs[i].chip == PX_CHIP_TYPE(pxu_p)) ||
27321772Sjl139090 		    (pec_config_state_regs[i].chip == PX_CHIP_UNIDENTIFIED)) {
27331772Sjl139090 			CSR_XS((caddr_t)dev_hdl, pec_config_state_regs[i].reg,
27341772Sjl139090 			    pxu_p->pec_config_state[i]);
27356953Sanbui 		}
27360Sstevel@tonic-gate 	}
27370Sstevel@tonic-gate 
27380Sstevel@tonic-gate 	/* Enable PCI-E interrupt */
2739*7124Sanbui 	if ((ret = hvio_intr_devino_to_sysino(dev_hdl, pxu_p, devino,
2740*7124Sanbui 	    &sysino)) != H_EOK) {
2741*7124Sanbui 		cmn_err(CE_WARN,
2742*7124Sanbui 		    "hvio_resume: hvio_intr_devino_to_sysino failed, "
2743*7124Sanbui 		    "ret 0x%lx", ret);
2744*7124Sanbui 	}
2745*7124Sanbui 
2746*7124Sanbui 	if ((ret =  hvio_intr_setstate(dev_hdl, sysino, INTR_IDLE_STATE))
2747*7124Sanbui 	    != H_EOK) {
2748*7124Sanbui 		cmn_err(CE_WARN,
2749*7124Sanbui 		    "hvio_resume: hvio_intr_setstate failed, "
2750*7124Sanbui 		    "ret 0x%lx", ret);
2751*7124Sanbui 	}
27520Sstevel@tonic-gate 
27530Sstevel@tonic-gate 	total_size = PEC_SIZE + MMU_SIZE + IB_SIZE + IB_MAP_SIZE;
27540Sstevel@tonic-gate 	kmem_free(pxu_p->pec_config_state, total_size);
27550Sstevel@tonic-gate 
27560Sstevel@tonic-gate 	pxu_p->pec_config_state = NULL;
27570Sstevel@tonic-gate 	pxu_p->mmu_config_state = NULL;
27580Sstevel@tonic-gate 	pxu_p->ib_config_state = NULL;
27590Sstevel@tonic-gate 	pxu_p->ib_intr_map = NULL;
27600Sstevel@tonic-gate 
27610Sstevel@tonic-gate 	msiq_resume(dev_hdl, pxu_p);
27620Sstevel@tonic-gate }
27630Sstevel@tonic-gate 
27640Sstevel@tonic-gate uint64_t
27650Sstevel@tonic-gate hvio_cb_suspend(devhandle_t dev_hdl, pxu_t *pxu_p)
27660Sstevel@tonic-gate {
27671772Sjl139090 	uint64_t *config_state, *cb_regs;
27681772Sjl139090 	int i, cb_size, cb_keys;
27691772Sjl139090 
27701772Sjl139090 	switch (PX_CHIP_TYPE(pxu_p)) {
27711772Sjl139090 	case PX_CHIP_OBERON:
27721772Sjl139090 		cb_size = UBC_SIZE;
27731772Sjl139090 		cb_keys = UBC_KEYS;
27741772Sjl139090 		cb_regs = ubc_config_state_regs;
27751772Sjl139090 		break;
27761772Sjl139090 	case PX_CHIP_FIRE:
27771772Sjl139090 		cb_size = JBC_SIZE;
27781772Sjl139090 		cb_keys = JBC_KEYS;
27791772Sjl139090 		cb_regs = jbc_config_state_regs;
27801772Sjl139090 		break;
27811772Sjl139090 	default:
27821772Sjl139090 		DBG(DBG_CB, NULL, "hvio_cb_suspend - unknown chip type: 0x%x\n",
27831772Sjl139090 		    PX_CHIP_TYPE(pxu_p));
27841772Sjl139090 		break;
27851772Sjl139090 	}
27861772Sjl139090 
27871772Sjl139090 	config_state = kmem_zalloc(cb_size, KM_NOSLEEP);
27880Sstevel@tonic-gate 
27890Sstevel@tonic-gate 	if (config_state == NULL) {
27900Sstevel@tonic-gate 		return (H_EIO);
27910Sstevel@tonic-gate 	}
27920Sstevel@tonic-gate 
27930Sstevel@tonic-gate 	/* Save the configuration states */
27940Sstevel@tonic-gate 	pxu_p->xcb_config_state = config_state;
27951772Sjl139090 	for (i = 0; i < cb_keys; i++) {
27960Sstevel@tonic-gate 		pxu_p->xcb_config_state[i] =
27971772Sjl139090 		    CSR_XR((caddr_t)dev_hdl, cb_regs[i]);
27980Sstevel@tonic-gate 	}
27990Sstevel@tonic-gate 
28000Sstevel@tonic-gate 	return (H_EOK);
28010Sstevel@tonic-gate }
28020Sstevel@tonic-gate 
28030Sstevel@tonic-gate void
28040Sstevel@tonic-gate hvio_cb_resume(devhandle_t pci_dev_hdl, devhandle_t xbus_dev_hdl,
28050Sstevel@tonic-gate     devino_t devino, pxu_t *pxu_p)
28060Sstevel@tonic-gate {
28071772Sjl139090 	sysino_t sysino;
28081772Sjl139090 	uint64_t *cb_regs;
28091772Sjl139090 	int i, cb_size, cb_keys;
2810*7124Sanbui 	uint64_t ret;
28111772Sjl139090 
28121772Sjl139090 	switch (PX_CHIP_TYPE(pxu_p)) {
28131772Sjl139090 	case PX_CHIP_OBERON:
28141772Sjl139090 		cb_size = UBC_SIZE;
28151772Sjl139090 		cb_keys = UBC_KEYS;
28161772Sjl139090 		cb_regs = ubc_config_state_regs;
28171772Sjl139090 		/*
28181772Sjl139090 		 * No reason to have any reset bits high until an error is
28191772Sjl139090 		 * detected on the link.
28201772Sjl139090 		 */
28211772Sjl139090 		CSR_XS((caddr_t)xbus_dev_hdl, UBC_ERROR_STATUS_CLEAR, -1ull);
28221772Sjl139090 		break;
28231772Sjl139090 	case PX_CHIP_FIRE:
28241772Sjl139090 		cb_size = JBC_SIZE;
28251772Sjl139090 		cb_keys = JBC_KEYS;
28261772Sjl139090 		cb_regs = jbc_config_state_regs;
28271772Sjl139090 		/*
28281772Sjl139090 		 * No reason to have any reset bits high until an error is
28291772Sjl139090 		 * detected on the link.
28301772Sjl139090 		 */
28311772Sjl139090 		CSR_XS((caddr_t)xbus_dev_hdl, JBC_ERROR_STATUS_CLEAR, -1ull);
28321772Sjl139090 		break;
28331772Sjl139090 	default:
28341772Sjl139090 		DBG(DBG_CB, NULL, "hvio_cb_resume - unknown chip type: 0x%x\n",
28351772Sjl139090 		    PX_CHIP_TYPE(pxu_p));
28361772Sjl139090 		break;
28371772Sjl139090 	}
28380Sstevel@tonic-gate 
28390Sstevel@tonic-gate 	ASSERT(pxu_p->xcb_config_state);
28400Sstevel@tonic-gate 
28410Sstevel@tonic-gate 	/* Restore the configuration states */
28421772Sjl139090 	for (i = 0; i < cb_keys; i++) {
28431772Sjl139090 		CSR_XS((caddr_t)xbus_dev_hdl, cb_regs[i],
28440Sstevel@tonic-gate 		    pxu_p->xcb_config_state[i]);
28450Sstevel@tonic-gate 	}
28460Sstevel@tonic-gate 
28470Sstevel@tonic-gate 	/* Enable XBC interrupt */
2848*7124Sanbui 	if ((ret = hvio_intr_devino_to_sysino(pci_dev_hdl, pxu_p, devino,
2849*7124Sanbui 	    &sysino)) != H_EOK) {
2850*7124Sanbui 		cmn_err(CE_WARN,
2851*7124Sanbui 		    "hvio_cb_resume: hvio_intr_devino_to_sysino failed, "
2852*7124Sanbui 		    "ret 0x%lx", ret);
2853*7124Sanbui 	}
2854*7124Sanbui 
2855*7124Sanbui 	if ((ret = hvio_intr_setstate(pci_dev_hdl, sysino, INTR_IDLE_STATE))
2856*7124Sanbui 	    != H_EOK) {
2857*7124Sanbui 		cmn_err(CE_WARN,
2858*7124Sanbui 		    "hvio_cb_resume: hvio_intr_setstate failed, "
2859*7124Sanbui 		    "ret 0x%lx", ret);
2860*7124Sanbui 	}
28610Sstevel@tonic-gate 
28621772Sjl139090 	kmem_free(pxu_p->xcb_config_state, cb_size);
28630Sstevel@tonic-gate 
28640Sstevel@tonic-gate 	pxu_p->xcb_config_state = NULL;
28650Sstevel@tonic-gate }
28660Sstevel@tonic-gate 
28670Sstevel@tonic-gate static uint64_t
28680Sstevel@tonic-gate msiq_suspend(devhandle_t dev_hdl, pxu_t *pxu_p)
28690Sstevel@tonic-gate {
28700Sstevel@tonic-gate 	size_t	bufsz;
28710Sstevel@tonic-gate 	volatile uint64_t *cur_p;
28720Sstevel@tonic-gate 	int i;
28730Sstevel@tonic-gate 
28740Sstevel@tonic-gate 	bufsz = MSIQ_STATE_SIZE + MSIQ_MAPPING_SIZE + MSIQ_OTHER_SIZE;
28750Sstevel@tonic-gate 	if ((pxu_p->msiq_config_state = kmem_zalloc(bufsz, KM_NOSLEEP)) ==
28760Sstevel@tonic-gate 	    NULL)
28770Sstevel@tonic-gate 		return (H_EIO);
28780Sstevel@tonic-gate 
28790Sstevel@tonic-gate 	cur_p = pxu_p->msiq_config_state;
28800Sstevel@tonic-gate 
28810Sstevel@tonic-gate 	/* Save each EQ state */
28820Sstevel@tonic-gate 	for (i = 0; i < EVENT_QUEUE_STATE_ENTRIES; i++, cur_p++)
28830Sstevel@tonic-gate 		*cur_p = CSRA_XR((caddr_t)dev_hdl, EVENT_QUEUE_STATE, i);
28840Sstevel@tonic-gate 
28850Sstevel@tonic-gate 	/* Save MSI mapping registers */
28860Sstevel@tonic-gate 	for (i = 0; i < MSI_MAPPING_ENTRIES; i++, cur_p++)
28870Sstevel@tonic-gate 		*cur_p = CSRA_XR((caddr_t)dev_hdl, MSI_MAPPING, i);
28880Sstevel@tonic-gate 
28890Sstevel@tonic-gate 	/* Save all other MSIQ registers */
28900Sstevel@tonic-gate 	for (i = 0; i < MSIQ_OTHER_KEYS; i++, cur_p++)
28910Sstevel@tonic-gate 		*cur_p = CSR_XR((caddr_t)dev_hdl, msiq_config_other_regs[i]);
28920Sstevel@tonic-gate 	return (H_EOK);
28930Sstevel@tonic-gate }
28940Sstevel@tonic-gate 
28950Sstevel@tonic-gate static void
28960Sstevel@tonic-gate msiq_resume(devhandle_t dev_hdl, pxu_t *pxu_p)
28970Sstevel@tonic-gate {
28980Sstevel@tonic-gate 	size_t	bufsz;
28991046Sjchu 	uint64_t *cur_p, state;
29000Sstevel@tonic-gate 	int i;
2901*7124Sanbui 	uint64_t ret;
29020Sstevel@tonic-gate 
29030Sstevel@tonic-gate 	bufsz = MSIQ_STATE_SIZE + MSIQ_MAPPING_SIZE + MSIQ_OTHER_SIZE;
29040Sstevel@tonic-gate 	cur_p = pxu_p->msiq_config_state;
29050Sstevel@tonic-gate 	/*
29060Sstevel@tonic-gate 	 * Initialize EQ base address register and
29070Sstevel@tonic-gate 	 * Interrupt Mondo Data 0 register.
29080Sstevel@tonic-gate 	 */
2909*7124Sanbui 	if ((ret = hvio_msiq_init(dev_hdl, pxu_p)) != H_EOK) {
2910*7124Sanbui 		cmn_err(CE_WARN,
2911*7124Sanbui 		    "msiq_resume: hvio_msiq_init failed, "
2912*7124Sanbui 		    "ret 0x%lx", ret);
2913*7124Sanbui 	}
29140Sstevel@tonic-gate 
29150Sstevel@tonic-gate 	/* Restore EQ states */
29160Sstevel@tonic-gate 	for (i = 0; i < EVENT_QUEUE_STATE_ENTRIES; i++, cur_p++) {
29171046Sjchu 		state = (*cur_p) & EVENT_QUEUE_STATE_ENTRIES_STATE_MASK;
29181046Sjchu 		if ((state == EQ_ACTIVE_STATE) || (state == EQ_ERROR_STATE))
29190Sstevel@tonic-gate 			CSRA_BS((caddr_t)dev_hdl, EVENT_QUEUE_CONTROL_SET,
29200Sstevel@tonic-gate 			    i, ENTRIES_EN);
29210Sstevel@tonic-gate 	}
29220Sstevel@tonic-gate 
29230Sstevel@tonic-gate 	/* Restore MSI mapping */
29240Sstevel@tonic-gate 	for (i = 0; i < MSI_MAPPING_ENTRIES; i++, cur_p++)
29250Sstevel@tonic-gate 		CSRA_XS((caddr_t)dev_hdl, MSI_MAPPING, i, *cur_p);
29260Sstevel@tonic-gate 
29270Sstevel@tonic-gate 	/*
29280Sstevel@tonic-gate 	 * Restore all other registers. MSI 32 bit address and
29290Sstevel@tonic-gate 	 * MSI 64 bit address are restored as part of this.
29300Sstevel@tonic-gate 	 */
29310Sstevel@tonic-gate 	for (i = 0; i < MSIQ_OTHER_KEYS; i++, cur_p++)
29320Sstevel@tonic-gate 		CSR_XS((caddr_t)dev_hdl, msiq_config_other_regs[i], *cur_p);
29330Sstevel@tonic-gate 
29340Sstevel@tonic-gate 	kmem_free(pxu_p->msiq_config_state, bufsz);
29350Sstevel@tonic-gate 	pxu_p->msiq_config_state = NULL;
29360Sstevel@tonic-gate }
29370Sstevel@tonic-gate 
29380Sstevel@tonic-gate /*
29390Sstevel@tonic-gate  * sends PME_Turn_Off message to put the link in L2/L3 ready state.
29400Sstevel@tonic-gate  * called by px_goto_l23ready.
29410Sstevel@tonic-gate  * returns DDI_SUCCESS or DDI_FAILURE
29420Sstevel@tonic-gate  */
29430Sstevel@tonic-gate int
29440Sstevel@tonic-gate px_send_pme_turnoff(caddr_t csr_base)
29450Sstevel@tonic-gate {
29460Sstevel@tonic-gate 	volatile uint64_t reg;
29470Sstevel@tonic-gate 
29480Sstevel@tonic-gate 	reg = CSR_XR(csr_base, TLU_PME_TURN_OFF_GENERATE);
29490Sstevel@tonic-gate 	/* If already pending, return failure */
29500Sstevel@tonic-gate 	if (reg & (1ull << TLU_PME_TURN_OFF_GENERATE_PTO)) {
2951118Sjchu 		DBG(DBG_PWR, NULL, "send_pme_turnoff: pending PTO bit "
2952118Sjchu 		    "tlu_pme_turn_off_generate = %x\n", reg);
29530Sstevel@tonic-gate 		return (DDI_FAILURE);
29540Sstevel@tonic-gate 	}
295527Sjchu 
29560Sstevel@tonic-gate 	/* write to PME_Turn_off reg to boradcast */
29570Sstevel@tonic-gate 	reg |= (1ull << TLU_PME_TURN_OFF_GENERATE_PTO);
29580Sstevel@tonic-gate 	CSR_XS(csr_base,  TLU_PME_TURN_OFF_GENERATE, reg);
2959118Sjchu 
29600Sstevel@tonic-gate 	return (DDI_SUCCESS);
29610Sstevel@tonic-gate }
2962118Sjchu 
2963118Sjchu /*
2964118Sjchu  * Checks for link being in L1idle state.
2965118Sjchu  * Returns
2966118Sjchu  * DDI_SUCCESS - if the link is in L1idle
2967118Sjchu  * DDI_FAILURE - if the link is not in L1idle
2968118Sjchu  */
2969118Sjchu int
2970118Sjchu px_link_wait4l1idle(caddr_t csr_base)
2971118Sjchu {
2972118Sjchu 	uint8_t ltssm_state;
2973118Sjchu 	int ntries = px_max_l1_tries;
2974118Sjchu 
2975118Sjchu 	while (ntries > 0) {
2976118Sjchu 		ltssm_state = CSR_FR(csr_base, LPU_LTSSM_STATUS1, LTSSM_STATE);
2977118Sjchu 		if (ltssm_state == LPU_LTSSM_L1_IDLE || (--ntries <= 0))
2978118Sjchu 			break;
2979118Sjchu 		delay(1);
2980118Sjchu 	}
2981118Sjchu 	DBG(DBG_PWR, NULL, "check_for_l1idle: ltssm_state %x\n", ltssm_state);
2982118Sjchu 	return ((ltssm_state == LPU_LTSSM_L1_IDLE) ? DDI_SUCCESS : DDI_FAILURE);
2983118Sjchu }
2984118Sjchu 
2985118Sjchu /*
2986118Sjchu  * Tranisition the link to L0, after it is down.
2987118Sjchu  */
2988118Sjchu int
2989118Sjchu px_link_retrain(caddr_t csr_base)
2990118Sjchu {
2991118Sjchu 	volatile uint64_t reg;
2992118Sjchu 
2993118Sjchu 	reg = CSR_XR(csr_base, TLU_CONTROL);
2994118Sjchu 	if (!(reg & (1ull << TLU_REMAIN_DETECT_QUIET))) {
2995118Sjchu 		DBG(DBG_PWR, NULL, "retrain_link: detect.quiet bit not set\n");
2996118Sjchu 		return (DDI_FAILURE);
2997118Sjchu 	}
2998118Sjchu 
2999118Sjchu 	/* Clear link down bit in TLU Other Event Clear Status Register. */
3000118Sjchu 	CSR_BS(csr_base, TLU_OTHER_EVENT_STATUS_CLEAR, LDN_P);
3001118Sjchu 
3002118Sjchu 	/* Clear Drain bit in TLU Status Register */
3003118Sjchu 	CSR_BS(csr_base, TLU_STATUS, DRAIN);
3004118Sjchu 
3005118Sjchu 	/* Clear Remain in Detect.Quiet bit in TLU Control Register */
3006118Sjchu 	reg = CSR_XR(csr_base, TLU_CONTROL);
3007118Sjchu 	reg &= ~(1ull << TLU_REMAIN_DETECT_QUIET);
3008118Sjchu 	CSR_XS(csr_base, TLU_CONTROL, reg);
3009118Sjchu 
3010118Sjchu 	return (DDI_SUCCESS);
3011118Sjchu }
3012118Sjchu 
3013118Sjchu void
3014118Sjchu px_enable_detect_quiet(caddr_t csr_base)
3015118Sjchu {
3016118Sjchu 	volatile uint64_t tlu_ctrl;
3017118Sjchu 
3018118Sjchu 	tlu_ctrl = CSR_XR(csr_base, TLU_CONTROL);
3019118Sjchu 	tlu_ctrl |= (1ull << TLU_REMAIN_DETECT_QUIET);
3020118Sjchu 	CSR_XS(csr_base, TLU_CONTROL, tlu_ctrl);
3021118Sjchu }
30221772Sjl139090 
30231772Sjl139090 static uint_t
30241772Sjl139090 oberon_hp_pwron(caddr_t csr_base)
30251772Sjl139090 {
30261772Sjl139090 	volatile uint64_t reg;
30272587Spjha 	boolean_t link_retry, link_up;
30282587Spjha 	int loop, i;
30291772Sjl139090 
30301786Sjj156685 	DBG(DBG_HP, NULL, "oberon_hp_pwron the slot\n");
30311772Sjl139090 
30321772Sjl139090 	/* Check Leaf Reset status */
30331772Sjl139090 	reg = CSR_XR(csr_base, ILU_ERROR_LOG_ENABLE);
30341772Sjl139090 	if (!(reg & (1ull << ILU_ERROR_LOG_ENABLE_SPARE3))) {
30351786Sjj156685 		DBG(DBG_HP, NULL, "oberon_hp_pwron fails: leaf not reset\n");
30361772Sjl139090 		goto fail;
30371772Sjl139090 	}
30381772Sjl139090 
30393485Spjha 	/* Check HP Capable */
30403485Spjha 	if (!CSR_BR(csr_base, TLU_SLOT_CAPABILITIES, HP)) {
30413485Spjha 		DBG(DBG_HP, NULL, "oberon_hp_pwron fails: leaf not "
30426953Sanbui 		    "hotplugable\n");
30433485Spjha 		goto fail;
30443485Spjha 	}
30453485Spjha 
30461772Sjl139090 	/* Check Slot status */
30471772Sjl139090 	reg = CSR_XR(csr_base, TLU_SLOT_STATUS);
30481772Sjl139090 	if (!(reg & (1ull << TLU_SLOT_STATUS_PSD)) ||
30491983Sjj156685 	    (reg & (1ull << TLU_SLOT_STATUS_MRLS))) {
30501786Sjj156685 		DBG(DBG_HP, NULL, "oberon_hp_pwron fails: slot status %lx\n",
30511772Sjl139090 		    reg);
30521772Sjl139090 		goto fail;
30531772Sjl139090 	}
30541772Sjl139090 
30551772Sjl139090 	/* Blink power LED, this is done from pciehpc already */
30561772Sjl139090 
30571772Sjl139090 	/* Turn on slot power */
30581772Sjl139090 	CSR_BS(csr_base, HOTPLUG_CONTROL, PWREN);
30591772Sjl139090 
30601983Sjj156685 	/* power fault detection */
30611983Sjj156685 	delay(drv_usectohz(25000));
30621983Sjj156685 	CSR_BS(csr_base, TLU_SLOT_STATUS, PWFD);
30631983Sjj156685 	CSR_BC(csr_base, HOTPLUG_CONTROL, PWREN);
30641983Sjj156685 
30651772Sjl139090 	/* wait to check power state */
30661772Sjl139090 	delay(drv_usectohz(25000));
30671772Sjl139090 
30681983Sjj156685 	if (!CSR_BR(csr_base, TLU_SLOT_STATUS, PWFD)) {
30691850Sjj156685 		DBG(DBG_HP, NULL, "oberon_hp_pwron fails: power fault\n");
30701850Sjj156685 		goto fail1;
30711850Sjj156685 	}
30721850Sjj156685 
30731850Sjj156685 	/* power is good */
30741983Sjj156685 	CSR_BS(csr_base, HOTPLUG_CONTROL, PWREN);
30751983Sjj156685 
30761983Sjj156685 	delay(drv_usectohz(25000));
30771983Sjj156685 	CSR_BS(csr_base, TLU_SLOT_STATUS, PWFD);
30781850Sjj156685 	CSR_BS(csr_base, TLU_SLOT_CONTROL, PWFDEN);
30791850Sjj156685 
30801850Sjj156685 	/* Turn on slot clock */
30811850Sjj156685 	CSR_BS(csr_base, HOTPLUG_CONTROL, CLKEN);
30821850Sjj156685 
30832587Spjha 	link_up = B_FALSE;
30842587Spjha 	link_retry = B_FALSE;
30852587Spjha 
30862587Spjha 	for (loop = 0; (loop < link_retry_count) && (link_up == B_FALSE);
30876953Sanbui 	    loop++) {
30882587Spjha 		if (link_retry == B_TRUE) {
30892587Spjha 			DBG(DBG_HP, NULL, "oberon_hp_pwron : retry link loop "
30906953Sanbui 			    "%d\n", loop);
30912587Spjha 			CSR_BS(csr_base, TLU_CONTROL, DRN_TR_DIS);
30922587Spjha 			CSR_XS(csr_base, FLP_PORT_CONTROL, 0x1);
30932587Spjha 			delay(drv_usectohz(10000));
30942587Spjha 			CSR_BC(csr_base, TLU_CONTROL, DRN_TR_DIS);
30952587Spjha 			CSR_BS(csr_base, TLU_DIAGNOSTIC, IFC_DIS);
30962587Spjha 			CSR_BC(csr_base, HOTPLUG_CONTROL, N_PERST);
30972587Spjha 			delay(drv_usectohz(50000));
30982587Spjha 		}
30992587Spjha 
31002587Spjha 		/* Release PCI-E Reset */
31012587Spjha 		delay(drv_usectohz(wait_perst));
31022587Spjha 		CSR_BS(csr_base, HOTPLUG_CONTROL, N_PERST);
31032587Spjha 
31042587Spjha 		/*
31052587Spjha 		 * Open events' mask
31062587Spjha 		 * This should be done from pciehpc already
31072587Spjha 		 */
31082587Spjha 
31092587Spjha 		/* Enable PCIE port */
31102587Spjha 		delay(drv_usectohz(wait_enable_port));
31112587Spjha 		CSR_BS(csr_base, TLU_CONTROL, DRN_TR_DIS);
31122587Spjha 		CSR_XS(csr_base, FLP_PORT_CONTROL, 0x20);
31132587Spjha 
31142587Spjha 		/* wait for the link up */
31156953Sanbui 		/* BEGIN CSTYLED */
31162587Spjha 		for (i = 0; (i < 2) && (link_up == B_FALSE); i++) {
31173485Spjha 			delay(drv_usectohz(link_status_check));
31182587Spjha 			reg = CSR_XR(csr_base, DLU_LINK_LAYER_STATUS);
31192587Spjha 
31202587Spjha 		    if ((((reg >> DLU_LINK_LAYER_STATUS_INIT_FC_SM_STS) &
31212587Spjha 			DLU_LINK_LAYER_STATUS_INIT_FC_SM_STS_MASK) ==
31222587Spjha 			DLU_LINK_LAYER_STATUS_INIT_FC_SM_STS_FC_INIT_DONE) &&
31232587Spjha 			(reg & (1ull << DLU_LINK_LAYER_STATUS_DLUP_STS)) &&
31242587Spjha 			((reg & DLU_LINK_LAYER_STATUS_LNK_STATE_MACH_STS_MASK)
31252587Spjha 			==
31262587Spjha 			DLU_LINK_LAYER_STATUS_LNK_STATE_MACH_STS_DL_ACTIVE)) {
31272587Spjha 			DBG(DBG_HP, NULL, "oberon_hp_pwron : link is up\n");
31282587Spjha 				link_up = B_TRUE;
31292587Spjha 		    } else
31302587Spjha 			link_retry = B_TRUE;
31312587Spjha 		}
31326953Sanbui 		/* END CSTYLED */
31332587Spjha 	}
31342587Spjha 
31352587Spjha 	if (link_up == B_FALSE) {
31362587Spjha 		DBG(DBG_HP, NULL, "oberon_hp_pwron fails to enable "
31372587Spjha 		    "PCI-E port\n");
31382587Spjha 		goto fail2;
31392587Spjha 	}
31402587Spjha 
31412587Spjha 	/* link is up */
31422587Spjha 	CSR_BC(csr_base, TLU_DIAGNOSTIC, IFC_DIS);
31432587Spjha 	CSR_BS(csr_base, FLP_PORT_ACTIVE_STATUS, TRAIN_ERROR);
31442587Spjha 	CSR_BS(csr_base, TLU_UNCORRECTABLE_ERROR_STATUS_CLEAR, TE_P);
31452587Spjha 	CSR_BS(csr_base, TLU_UNCORRECTABLE_ERROR_STATUS_CLEAR, TE_S);
31462587Spjha 	CSR_BC(csr_base, TLU_CONTROL, DRN_TR_DIS);
31472587Spjha 
31482587Spjha 	/* Restore LUP/LDN */
31492587Spjha 	reg = CSR_XR(csr_base, TLU_OTHER_EVENT_LOG_ENABLE);
31502587Spjha 	if (px_tlu_oe_log_mask & (1ull << TLU_OTHER_EVENT_STATUS_SET_LUP_P))
31512587Spjha 		reg |= 1ull << TLU_OTHER_EVENT_STATUS_SET_LUP_P;
31522587Spjha 	if (px_tlu_oe_log_mask & (1ull << TLU_OTHER_EVENT_STATUS_SET_LDN_P))
31532587Spjha 		reg |= 1ull << TLU_OTHER_EVENT_STATUS_SET_LDN_P;
31542587Spjha 	if (px_tlu_oe_log_mask & (1ull << TLU_OTHER_EVENT_STATUS_SET_LUP_S))
31552587Spjha 		reg |= 1ull << TLU_OTHER_EVENT_STATUS_SET_LUP_S;
31562587Spjha 	if (px_tlu_oe_log_mask & (1ull << TLU_OTHER_EVENT_STATUS_SET_LDN_S))
31572587Spjha 		reg |= 1ull << TLU_OTHER_EVENT_STATUS_SET_LDN_S;
31582587Spjha 	CSR_XS(csr_base, TLU_OTHER_EVENT_LOG_ENABLE, reg);
31591850Sjj156685 
31601850Sjj156685 	/*
31611850Sjj156685 	 * Initialize Leaf
31621850Sjj156685 	 * SPLS = 00b, SPLV = 11001b, i.e. 25W
31631850Sjj156685 	 */
31641850Sjj156685 	reg = CSR_XR(csr_base, TLU_SLOT_CAPABILITIES);
31651850Sjj156685 	reg &= ~(TLU_SLOT_CAPABILITIES_SPLS_MASK <<
31661850Sjj156685 	    TLU_SLOT_CAPABILITIES_SPLS);
31671850Sjj156685 	reg &= ~(TLU_SLOT_CAPABILITIES_SPLV_MASK <<
31683485Spjha 	    TLU_SLOT_CAPABILITIES_SPLV);
31693485Spjha 	reg |= (0x19 << TLU_SLOT_CAPABILITIES_SPLV);
31701850Sjj156685 	CSR_XS(csr_base, TLU_SLOT_CAPABILITIES, reg);
31711850Sjj156685 
31721850Sjj156685 	/* Turn on Power LED */
31731850Sjj156685 	reg = CSR_XR(csr_base, TLU_SLOT_CONTROL);
31741850Sjj156685 	reg &= ~PCIE_SLOTCTL_PWR_INDICATOR_MASK;
31751850Sjj156685 	reg = pcie_slotctl_pwr_indicator_set(reg,
31761850Sjj156685 	    PCIE_SLOTCTL_INDICATOR_STATE_ON);
31771850Sjj156685 	CSR_XS(csr_base, TLU_SLOT_CONTROL, reg);
31781850Sjj156685 
31791850Sjj156685 	/* Notify to SCF */
31801983Sjj156685 	if (CSR_BR(csr_base, HOTPLUG_CONTROL, SLOTPON))
31811983Sjj156685 		CSR_BC(csr_base, HOTPLUG_CONTROL, SLOTPON);
31821983Sjj156685 	else
31831983Sjj156685 		CSR_BS(csr_base, HOTPLUG_CONTROL, SLOTPON);
31841983Sjj156685 
31854395Sgovinda 	/* Wait for one second */
31864395Sgovinda 	delay(drv_usectohz(1000000));
31874395Sgovinda 
31881772Sjl139090 	return (DDI_SUCCESS);
31891772Sjl139090 
31901850Sjj156685 fail2:
31911850Sjj156685 	/* Link up is failed */
31921850Sjj156685 	CSR_BS(csr_base, FLP_PORT_CONTROL, PORT_DIS);
31931850Sjj156685 	CSR_BC(csr_base, HOTPLUG_CONTROL, N_PERST);
31941850Sjj156685 	delay(drv_usectohz(150));
31951850Sjj156685 
31961850Sjj156685 	CSR_BC(csr_base, HOTPLUG_CONTROL, CLKEN);
31971850Sjj156685 	delay(drv_usectohz(100));
31981850Sjj156685 
31991850Sjj156685 fail1:
32001850Sjj156685 	CSR_BC(csr_base, TLU_SLOT_CONTROL, PWFDEN);
32011850Sjj156685 
32021850Sjj156685 	CSR_BC(csr_base, HOTPLUG_CONTROL, PWREN);
32031850Sjj156685 
32041850Sjj156685 	reg = CSR_XR(csr_base, TLU_SLOT_CONTROL);
32051850Sjj156685 	reg &= ~PCIE_SLOTCTL_PWR_INDICATOR_MASK;
32061850Sjj156685 	reg = pcie_slotctl_pwr_indicator_set(reg,
32071850Sjj156685 	    PCIE_SLOTCTL_INDICATOR_STATE_OFF);
32081850Sjj156685 	CSR_XS(csr_base, TLU_SLOT_CONTROL, reg);
32091850Sjj156685 
32101850Sjj156685 	CSR_BC(csr_base, TLU_SLOT_STATUS, PWFD);
32111850Sjj156685 
32121772Sjl139090 fail:
32132840Scarlsonj 	return ((uint_t)DDI_FAILURE);
32141772Sjl139090 }
32151772Sjl139090 
32164395Sgovinda hrtime_t oberon_leaf_reset_timeout = 120ll * NANOSEC;	/* 120 seconds */
32174395Sgovinda 
32181772Sjl139090 static uint_t
32191772Sjl139090 oberon_hp_pwroff(caddr_t csr_base)
32201772Sjl139090 {
32211772Sjl139090 	volatile uint64_t reg;
32222044Sjj156685 	volatile uint64_t reg_tluue, reg_tluce;
32234395Sgovinda 	hrtime_t start_time, end_time;
32241772Sjl139090 
32251786Sjj156685 	DBG(DBG_HP, NULL, "oberon_hp_pwroff the slot\n");
32261772Sjl139090 
32271772Sjl139090 	/* Blink power LED, this is done from pciehpc already */
32281772Sjl139090 
32291772Sjl139090 	/* Clear Slot Event */
32301772Sjl139090 	CSR_BS(csr_base, TLU_SLOT_STATUS, PSDC);
32311983Sjj156685 	CSR_BS(csr_base, TLU_SLOT_STATUS, PWFD);
32321772Sjl139090 
32331772Sjl139090 	/* DRN_TR_DIS on */
32341772Sjl139090 	CSR_BS(csr_base, TLU_CONTROL, DRN_TR_DIS);
32351983Sjj156685 	delay(drv_usectohz(10000));
32361772Sjl139090 
32372587Spjha 	/* Disable LUP/LDN */
32382587Spjha 	reg = CSR_XR(csr_base, TLU_OTHER_EVENT_LOG_ENABLE);
32392587Spjha 	reg &= ~((1ull << TLU_OTHER_EVENT_STATUS_SET_LDN_P) |
32402587Spjha 	    (1ull << TLU_OTHER_EVENT_STATUS_SET_LUP_P) |
32412587Spjha 	    (1ull << TLU_OTHER_EVENT_STATUS_SET_LDN_S) |
32422587Spjha 	    (1ull << TLU_OTHER_EVENT_STATUS_SET_LUP_S));
32432587Spjha 	CSR_XS(csr_base, TLU_OTHER_EVENT_LOG_ENABLE, reg);
32442587Spjha 
32452044Sjj156685 	/* Save the TLU registers */
32462044Sjj156685 	reg_tluue = CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_LOG_ENABLE);
32472044Sjj156685 	reg_tluce = CSR_XR(csr_base, TLU_CORRECTABLE_ERROR_LOG_ENABLE);
32482044Sjj156685 	/* All clear */
32492044Sjj156685 	CSR_XS(csr_base, TLU_UNCORRECTABLE_ERROR_LOG_ENABLE, 0);
32502044Sjj156685 	CSR_XS(csr_base, TLU_CORRECTABLE_ERROR_LOG_ENABLE, 0);
32512044Sjj156685 
32521772Sjl139090 	/* Disable port */
32531772Sjl139090 	CSR_BS(csr_base, FLP_PORT_CONTROL, PORT_DIS);
32541772Sjl139090 
32551983Sjj156685 	/* PCIE reset */
32561772Sjl139090 	delay(drv_usectohz(10000));
32571772Sjl139090 	CSR_BC(csr_base, HOTPLUG_CONTROL, N_PERST);
32581772Sjl139090 
32591772Sjl139090 	/* PCIE clock stop */
32601983Sjj156685 	delay(drv_usectohz(150));
32611772Sjl139090 	CSR_BC(csr_base, HOTPLUG_CONTROL, CLKEN);
32621772Sjl139090 
32631772Sjl139090 	/* Turn off slot power */
32641983Sjj156685 	delay(drv_usectohz(100));
32651772Sjl139090 	CSR_BC(csr_base, TLU_SLOT_CONTROL, PWFDEN);
32661772Sjl139090 	CSR_BC(csr_base, HOTPLUG_CONTROL, PWREN);
32671983Sjj156685 	delay(drv_usectohz(25000));
32681983Sjj156685 	CSR_BS(csr_base, TLU_SLOT_STATUS, PWFD);
32691772Sjl139090 
32701772Sjl139090 	/* write 0 to bit 7 of ILU Error Log Enable Register */
32711983Sjj156685 	CSR_BC(csr_base, ILU_ERROR_LOG_ENABLE, SPARE3);
32721772Sjl139090 
32732044Sjj156685 	/* Set back TLU registers */
32742044Sjj156685 	CSR_XS(csr_base, TLU_UNCORRECTABLE_ERROR_LOG_ENABLE, reg_tluue);
32752044Sjj156685 	CSR_XS(csr_base, TLU_CORRECTABLE_ERROR_LOG_ENABLE, reg_tluce);
32762044Sjj156685 
32771772Sjl139090 	/* Power LED off */
32781772Sjl139090 	reg = CSR_XR(csr_base, TLU_SLOT_CONTROL);
32791772Sjl139090 	reg &= ~PCIE_SLOTCTL_PWR_INDICATOR_MASK;
32801772Sjl139090 	reg = pcie_slotctl_pwr_indicator_set(reg,
32811772Sjl139090 	    PCIE_SLOTCTL_INDICATOR_STATE_OFF);
32821772Sjl139090 	CSR_XS(csr_base, TLU_SLOT_CONTROL, reg);
32831772Sjl139090 
32841772Sjl139090 	/* Indicator LED blink */
32851772Sjl139090 	reg = CSR_XR(csr_base, TLU_SLOT_CONTROL);
32861772Sjl139090 	reg &= ~PCIE_SLOTCTL_ATTN_INDICATOR_MASK;
32871772Sjl139090 	reg = pcie_slotctl_attn_indicator_set(reg,
32881772Sjl139090 	    PCIE_SLOTCTL_INDICATOR_STATE_BLINK);
32891772Sjl139090 	CSR_XS(csr_base, TLU_SLOT_CONTROL, reg);
32901772Sjl139090 
32911772Sjl139090 	/* Notify to SCF */
32921983Sjj156685 	if (CSR_BR(csr_base, HOTPLUG_CONTROL, SLOTPON))
32931983Sjj156685 		CSR_BC(csr_base, HOTPLUG_CONTROL, SLOTPON);
32941983Sjj156685 	else
32954395Sgovinda 		CSR_BS(csr_base, HOTPLUG_CONTROL, SLOTPON);
32964395Sgovinda 
32974395Sgovinda 	start_time = gethrtime();
32984395Sgovinda 	/* Check Leaf Reset status */
32994395Sgovinda 	while (!(CSR_BR(csr_base, ILU_ERROR_LOG_ENABLE, SPARE3))) {
33004395Sgovinda 		if ((end_time = (gethrtime() - start_time)) >
33014395Sgovinda 		    oberon_leaf_reset_timeout) {
33024395Sgovinda 			cmn_err(CE_WARN, "Oberon leaf reset is not completed, "
33034395Sgovinda 			    "even after waiting %llx ticks", end_time);
33044395Sgovinda 
33054395Sgovinda 			break;
33064395Sgovinda 		}
33074395Sgovinda 
33084395Sgovinda 		/* Wait for one second */
33094395Sgovinda 		delay(drv_usectohz(1000000));
33104395Sgovinda 	}
33111772Sjl139090 
33121772Sjl139090 	/* Indicator LED off */
33131772Sjl139090 	reg = CSR_XR(csr_base, TLU_SLOT_CONTROL);
33141772Sjl139090 	reg &= ~PCIE_SLOTCTL_ATTN_INDICATOR_MASK;
33151772Sjl139090 	reg = pcie_slotctl_attn_indicator_set(reg,
33161772Sjl139090 	    PCIE_SLOTCTL_INDICATOR_STATE_OFF);
33171772Sjl139090 	CSR_XS(csr_base, TLU_SLOT_CONTROL, reg);
33181772Sjl139090 
33191772Sjl139090 	return (DDI_SUCCESS);
33201772Sjl139090 }
33211772Sjl139090 
33221772Sjl139090 static uint_t
33231772Sjl139090 oberon_hpreg_get(void *cookie, off_t off)
33241772Sjl139090 {
33251772Sjl139090 	caddr_t csr_base = *(caddr_t *)cookie;
33261772Sjl139090 	volatile uint64_t val = -1ull;
33271772Sjl139090 
33281772Sjl139090 	switch (off) {
33291772Sjl139090 	case PCIE_SLOTCAP:
33301772Sjl139090 		val = CSR_XR(csr_base, TLU_SLOT_CAPABILITIES);
33311772Sjl139090 		break;
33321772Sjl139090 	case PCIE_SLOTCTL:
33331772Sjl139090 		val = CSR_XR(csr_base, TLU_SLOT_CONTROL);
33341772Sjl139090 
33351772Sjl139090 		/* Get the power state */
33361772Sjl139090 		val |= (CSR_XR(csr_base, HOTPLUG_CONTROL) &
33371772Sjl139090 		    (1ull << HOTPLUG_CONTROL_PWREN)) ?
33381772Sjl139090 		    0 : PCIE_SLOTCTL_PWR_CONTROL;
33391772Sjl139090 		break;
33401772Sjl139090 	case PCIE_SLOTSTS:
33411772Sjl139090 		val = CSR_XR(csr_base, TLU_SLOT_STATUS);
33421772Sjl139090 		break;
33431850Sjj156685 	case PCIE_LINKCAP:
33441850Sjj156685 		val = CSR_XR(csr_base, TLU_LINK_CAPABILITIES);
33451850Sjj156685 		break;
33461850Sjj156685 	case PCIE_LINKSTS:
33471850Sjj156685 		val = CSR_XR(csr_base, TLU_LINK_STATUS);
33481850Sjj156685 		break;
33491772Sjl139090 	default:
33501786Sjj156685 		DBG(DBG_HP, NULL, "oberon_hpreg_get(): "
33511772Sjl139090 		    "unsupported offset 0x%lx\n", off);
33521772Sjl139090 		break;
33531772Sjl139090 	}
33541772Sjl139090 
33551772Sjl139090 	return ((uint_t)val);
33561772Sjl139090 }
33571772Sjl139090 
33581772Sjl139090 static uint_t
33591772Sjl139090 oberon_hpreg_put(void *cookie, off_t off, uint_t val)
33601772Sjl139090 {
33611772Sjl139090 	caddr_t csr_base = *(caddr_t *)cookie;
33621850Sjj156685 	volatile uint64_t pwr_state_on, pwr_fault;
33631772Sjl139090 	uint_t pwr_off, ret = DDI_SUCCESS;
33641772Sjl139090 
33651786Sjj156685 	DBG(DBG_HP, NULL, "oberon_hpreg_put 0x%lx: cur %x, new %x\n",
33661772Sjl139090 	    off, oberon_hpreg_get(cookie, off), val);
33671772Sjl139090 
33681772Sjl139090 	switch (off) {
33691772Sjl139090 	case PCIE_SLOTCTL:
33701772Sjl139090 		/*
33711772Sjl139090 		 * Depending on the current state, insertion or removal
33721772Sjl139090 		 * will go through their respective sequences.
33731772Sjl139090 		 */
33741772Sjl139090 		pwr_state_on = CSR_BR(csr_base, HOTPLUG_CONTROL, PWREN);
33751772Sjl139090 		pwr_off = val & PCIE_SLOTCTL_PWR_CONTROL;
33761772Sjl139090 
33771772Sjl139090 		if (!pwr_off && !pwr_state_on)
33781772Sjl139090 			ret = oberon_hp_pwron(csr_base);
33791772Sjl139090 		else if (pwr_off && pwr_state_on) {
33801772Sjl139090 			pwr_fault = CSR_XR(csr_base, TLU_SLOT_STATUS) &
33811772Sjl139090 			    (1ull << TLU_SLOT_STATUS_PWFD);
33821772Sjl139090 
33831983Sjj156685 			if (pwr_fault) {
33841983Sjj156685 				DBG(DBG_HP, NULL, "oberon_hpreg_put: power "
33851983Sjj156685 				    "off because of power fault\n");
33861772Sjl139090 				CSR_BC(csr_base, HOTPLUG_CONTROL, PWREN);
33871983Sjj156685 			}
33881772Sjl139090 			else
33891772Sjl139090 				ret = oberon_hp_pwroff(csr_base);
33901850Sjj156685 		} else
33911772Sjl139090 			CSR_XS(csr_base, TLU_SLOT_CONTROL, val);
33921772Sjl139090 		break;
33931772Sjl139090 	case PCIE_SLOTSTS:
33941772Sjl139090 		CSR_XS(csr_base, TLU_SLOT_STATUS, val);
33951772Sjl139090 		break;
33961772Sjl139090 	default:
33971786Sjj156685 		DBG(DBG_HP, NULL, "oberon_hpreg_put(): "
33981772Sjl139090 		    "unsupported offset 0x%lx\n", off);
33992840Scarlsonj 		ret = (uint_t)DDI_FAILURE;
34001772Sjl139090 		break;
34011772Sjl139090 	}
34021772Sjl139090 
34031772Sjl139090 	return (ret);
34041772Sjl139090 }
34051772Sjl139090 
34061772Sjl139090 int
34071772Sjl139090 hvio_hotplug_init(dev_info_t *dip, void *arg)
34081772Sjl139090 {
34091772Sjl139090 	pciehpc_regops_t *regops = (pciehpc_regops_t *)arg;
34101772Sjl139090 	px_t	*px_p = DIP_TO_STATE(dip);
34111772Sjl139090 	pxu_t	*pxu_p = (pxu_t *)px_p->px_plat_p;
34122587Spjha 	volatile uint64_t reg;
34131772Sjl139090 
34141772Sjl139090 	if (PX_CHIP_TYPE(pxu_p) == PX_CHIP_OBERON) {
34151772Sjl139090 		if (!CSR_BR((caddr_t)pxu_p->px_address[PX_REG_CSR],
34161772Sjl139090 		    TLU_SLOT_CAPABILITIES, HP)) {
34171786Sjj156685 			DBG(DBG_HP, NULL, "%s%d: hotplug capabale not set\n",
34181772Sjl139090 			    ddi_driver_name(dip), ddi_get_instance(dip));
34191772Sjl139090 			return (DDI_FAILURE);
34201772Sjl139090 		}
34211772Sjl139090 
34222587Spjha 		/* For empty or disconnected slot, disable LUP/LDN */
34232587Spjha 		if (!CSR_BR((caddr_t)pxu_p->px_address[PX_REG_CSR],
34246953Sanbui 		    TLU_SLOT_STATUS, PSD) ||
34252587Spjha 		    !CSR_BR((caddr_t)pxu_p->px_address[PX_REG_CSR],
34266953Sanbui 		    HOTPLUG_CONTROL, PWREN)) {
34272587Spjha 
34282587Spjha 			reg = CSR_XR((caddr_t)pxu_p->px_address[PX_REG_CSR],
34292587Spjha 			    TLU_OTHER_EVENT_LOG_ENABLE);
34302587Spjha 			reg &= ~((1ull << TLU_OTHER_EVENT_STATUS_SET_LDN_P) |
34312587Spjha 			    (1ull << TLU_OTHER_EVENT_STATUS_SET_LUP_P) |
34322587Spjha 			    (1ull << TLU_OTHER_EVENT_STATUS_SET_LDN_S) |
34332587Spjha 			    (1ull << TLU_OTHER_EVENT_STATUS_SET_LUP_S));
34342587Spjha 			CSR_XS((caddr_t)pxu_p->px_address[PX_REG_CSR],
34352587Spjha 			    TLU_OTHER_EVENT_LOG_ENABLE, reg);
34362587Spjha 		}
34372587Spjha 
34381772Sjl139090 		regops->get = oberon_hpreg_get;
34391772Sjl139090 		regops->put = oberon_hpreg_put;
34401772Sjl139090 
34411772Sjl139090 		/* cookie is the csr_base */
34421772Sjl139090 		regops->cookie = (void *)&pxu_p->px_address[PX_REG_CSR];
34431772Sjl139090 
34441772Sjl139090 		return (DDI_SUCCESS);
34451772Sjl139090 	}
34461772Sjl139090 
34471772Sjl139090 	return (DDI_ENOTSUP);
34481772Sjl139090 }
34491772Sjl139090 
34501772Sjl139090 int
34511772Sjl139090 hvio_hotplug_uninit(dev_info_t *dip)
34521772Sjl139090 {
34531772Sjl139090 	px_t	*px_p = DIP_TO_STATE(dip);
34541772Sjl139090 	pxu_t	*pxu_p = (pxu_t *)px_p->px_plat_p;
34551772Sjl139090 
34561772Sjl139090 	if (PX_CHIP_TYPE(pxu_p) == PX_CHIP_OBERON)
34571772Sjl139090 		return (DDI_SUCCESS);
34581772Sjl139090 
34591772Sjl139090 	return (DDI_FAILURE);
34601772Sjl139090 }
3461