xref: /titanic_51/usr/src/uts/sun4u/io/px/px_hlib.c (revision 89b42a211fa7d3527b9615260f495d22e430c5c5)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
544bb982bSgovinda  * Common Development and Distribution License (the "License").
644bb982bSgovinda  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
21*89b42a21Sandrew.rutz@sun.com 
227c478bd9Sstevel@tonic-gate /*
23*89b42a21Sandrew.rutz@sun.com  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate #include <sys/types.h>
277c478bd9Sstevel@tonic-gate #include <sys/cmn_err.h>
287c478bd9Sstevel@tonic-gate #include <sys/vmsystm.h>
297c478bd9Sstevel@tonic-gate #include <sys/vmem.h>
307c478bd9Sstevel@tonic-gate #include <sys/machsystm.h>	/* lddphys() */
317c478bd9Sstevel@tonic-gate #include <sys/iommutsb.h>
327c478bd9Sstevel@tonic-gate #include <px_obj.h>
3326947304SEvan Yan #include <sys/hotplug/pci/pcie_hp.h>
347c478bd9Sstevel@tonic-gate #include "px_regs.h"
3525cf1a30Sjl139090 #include "oberon_regs.h"
367c478bd9Sstevel@tonic-gate #include "px_csr.h"
377c478bd9Sstevel@tonic-gate #include "px_lib4u.h"
383c4226f9Spjha #include "px_err.h"
397c478bd9Sstevel@tonic-gate 
407c478bd9Sstevel@tonic-gate /*
417c478bd9Sstevel@tonic-gate  * Registers that need to be saved and restored during suspend/resume.
427c478bd9Sstevel@tonic-gate  */
437c478bd9Sstevel@tonic-gate 
447c478bd9Sstevel@tonic-gate /*
457c478bd9Sstevel@tonic-gate  * Registers in the PEC Module.
467c478bd9Sstevel@tonic-gate  * LPU_RESET should be set to 0ull during resume
4725cf1a30Sjl139090  *
4825cf1a30Sjl139090  * This array is in reg,chip form. PX_CHIP_UNIDENTIFIED is for all chips
4925cf1a30Sjl139090  * or PX_CHIP_FIRE for Fire only, or PX_CHIP_OBERON for Oberon only.
507c478bd9Sstevel@tonic-gate  */
5125cf1a30Sjl139090 static struct px_pec_regs {
5225cf1a30Sjl139090 	uint64_t reg;
5325cf1a30Sjl139090 	uint64_t chip;
5425cf1a30Sjl139090 } pec_config_state_regs[] = {
5525cf1a30Sjl139090 	{PEC_CORE_AND_BLOCK_INTERRUPT_ENABLE, PX_CHIP_UNIDENTIFIED},
5625cf1a30Sjl139090 	{ILU_ERROR_LOG_ENABLE, PX_CHIP_UNIDENTIFIED},
5725cf1a30Sjl139090 	{ILU_INTERRUPT_ENABLE, PX_CHIP_UNIDENTIFIED},
5825cf1a30Sjl139090 	{TLU_CONTROL, PX_CHIP_UNIDENTIFIED},
5925cf1a30Sjl139090 	{TLU_OTHER_EVENT_LOG_ENABLE, PX_CHIP_UNIDENTIFIED},
6025cf1a30Sjl139090 	{TLU_OTHER_EVENT_INTERRUPT_ENABLE, PX_CHIP_UNIDENTIFIED},
6125cf1a30Sjl139090 	{TLU_DEVICE_CONTROL, PX_CHIP_UNIDENTIFIED},
6225cf1a30Sjl139090 	{TLU_LINK_CONTROL, PX_CHIP_UNIDENTIFIED},
6325cf1a30Sjl139090 	{TLU_UNCORRECTABLE_ERROR_LOG_ENABLE, PX_CHIP_UNIDENTIFIED},
6425cf1a30Sjl139090 	{TLU_UNCORRECTABLE_ERROR_INTERRUPT_ENABLE, PX_CHIP_UNIDENTIFIED},
6525cf1a30Sjl139090 	{TLU_CORRECTABLE_ERROR_LOG_ENABLE, PX_CHIP_UNIDENTIFIED},
6625cf1a30Sjl139090 	{TLU_CORRECTABLE_ERROR_INTERRUPT_ENABLE, PX_CHIP_UNIDENTIFIED},
6725cf1a30Sjl139090 	{DLU_LINK_LAYER_CONFIG, PX_CHIP_OBERON},
6825cf1a30Sjl139090 	{DLU_FLOW_CONTROL_UPDATE_CONTROL, PX_CHIP_OBERON},
6925cf1a30Sjl139090 	{DLU_TXLINK_REPLAY_TIMER_THRESHOLD, PX_CHIP_OBERON},
7025cf1a30Sjl139090 	{LPU_LINK_LAYER_INTERRUPT_MASK, PX_CHIP_FIRE},
7125cf1a30Sjl139090 	{LPU_PHY_INTERRUPT_MASK, PX_CHIP_FIRE},
7225cf1a30Sjl139090 	{LPU_RECEIVE_PHY_INTERRUPT_MASK, PX_CHIP_FIRE},
7325cf1a30Sjl139090 	{LPU_TRANSMIT_PHY_INTERRUPT_MASK, PX_CHIP_FIRE},
7425cf1a30Sjl139090 	{LPU_GIGABLAZE_GLUE_INTERRUPT_MASK, PX_CHIP_FIRE},
7525cf1a30Sjl139090 	{LPU_LTSSM_INTERRUPT_MASK, PX_CHIP_FIRE},
7625cf1a30Sjl139090 	{LPU_RESET, PX_CHIP_FIRE},
7725cf1a30Sjl139090 	{LPU_DEBUG_CONFIG, PX_CHIP_FIRE},
7825cf1a30Sjl139090 	{LPU_INTERRUPT_MASK, PX_CHIP_FIRE},
7925cf1a30Sjl139090 	{LPU_LINK_LAYER_CONFIG, PX_CHIP_FIRE},
8025cf1a30Sjl139090 	{LPU_FLOW_CONTROL_UPDATE_CONTROL, PX_CHIP_FIRE},
8125cf1a30Sjl139090 	{LPU_TXLINK_FREQUENT_NAK_LATENCY_TIMER_THRESHOLD, PX_CHIP_FIRE},
8225cf1a30Sjl139090 	{LPU_TXLINK_REPLAY_TIMER_THRESHOLD, PX_CHIP_FIRE},
8325cf1a30Sjl139090 	{LPU_REPLAY_BUFFER_MAX_ADDRESS, PX_CHIP_FIRE},
8425cf1a30Sjl139090 	{LPU_TXLINK_RETRY_FIFO_POINTER, PX_CHIP_FIRE},
8525cf1a30Sjl139090 	{LPU_LTSSM_CONFIG2, PX_CHIP_FIRE},
8625cf1a30Sjl139090 	{LPU_LTSSM_CONFIG3, PX_CHIP_FIRE},
8725cf1a30Sjl139090 	{LPU_LTSSM_CONFIG4, PX_CHIP_FIRE},
8825cf1a30Sjl139090 	{LPU_LTSSM_CONFIG5, PX_CHIP_FIRE},
8925cf1a30Sjl139090 	{DMC_CORE_AND_BLOCK_INTERRUPT_ENABLE, PX_CHIP_UNIDENTIFIED},
9025cf1a30Sjl139090 	{DMC_DEBUG_SELECT_FOR_PORT_A, PX_CHIP_UNIDENTIFIED},
9125cf1a30Sjl139090 	{DMC_DEBUG_SELECT_FOR_PORT_B, PX_CHIP_UNIDENTIFIED}
927c478bd9Sstevel@tonic-gate };
9325cf1a30Sjl139090 
9425cf1a30Sjl139090 #define	PEC_KEYS	\
9525cf1a30Sjl139090 	((sizeof (pec_config_state_regs))/sizeof (struct px_pec_regs))
9625cf1a30Sjl139090 
9725cf1a30Sjl139090 #define	PEC_SIZE	(PEC_KEYS * sizeof (uint64_t))
987c478bd9Sstevel@tonic-gate 
997c478bd9Sstevel@tonic-gate /*
1007c478bd9Sstevel@tonic-gate  * Registers for the MMU module.
1017c478bd9Sstevel@tonic-gate  * MMU_TTE_CACHE_INVALIDATE needs to be cleared. (-1ull)
1027c478bd9Sstevel@tonic-gate  */
1037c478bd9Sstevel@tonic-gate static uint64_t mmu_config_state_regs[] = {
1047c478bd9Sstevel@tonic-gate 	MMU_TSB_CONTROL,
1057c478bd9Sstevel@tonic-gate 	MMU_CONTROL_AND_STATUS,
106f8d2de6bSjchu 	MMU_ERROR_LOG_ENABLE,
1077c478bd9Sstevel@tonic-gate 	MMU_INTERRUPT_ENABLE
1087c478bd9Sstevel@tonic-gate };
1097c478bd9Sstevel@tonic-gate #define	MMU_SIZE (sizeof (mmu_config_state_regs))
1107c478bd9Sstevel@tonic-gate #define	MMU_KEYS (MMU_SIZE / sizeof (uint64_t))
1117c478bd9Sstevel@tonic-gate 
1127c478bd9Sstevel@tonic-gate /*
1137c478bd9Sstevel@tonic-gate  * Registers for the IB Module
1147c478bd9Sstevel@tonic-gate  */
1157c478bd9Sstevel@tonic-gate static uint64_t ib_config_state_regs[] = {
1167c478bd9Sstevel@tonic-gate 	IMU_ERROR_LOG_ENABLE,
1177c478bd9Sstevel@tonic-gate 	IMU_INTERRUPT_ENABLE
1187c478bd9Sstevel@tonic-gate };
1197c478bd9Sstevel@tonic-gate #define	IB_SIZE (sizeof (ib_config_state_regs))
1207c478bd9Sstevel@tonic-gate #define	IB_KEYS (IB_SIZE / sizeof (uint64_t))
1217c478bd9Sstevel@tonic-gate #define	IB_MAP_SIZE (INTERRUPT_MAPPING_ENTRIES * sizeof (uint64_t))
1227c478bd9Sstevel@tonic-gate 
1237c478bd9Sstevel@tonic-gate /*
12425cf1a30Sjl139090  * Registers for the JBC module.
1257c478bd9Sstevel@tonic-gate  * JBC_ERROR_STATUS_CLEAR needs to be cleared. (-1ull)
1267c478bd9Sstevel@tonic-gate  */
12725cf1a30Sjl139090 static uint64_t	jbc_config_state_regs[] = {
1287c478bd9Sstevel@tonic-gate 	JBUS_PARITY_CONTROL,
1297c478bd9Sstevel@tonic-gate 	JBC_FATAL_RESET_ENABLE,
1307c478bd9Sstevel@tonic-gate 	JBC_CORE_AND_BLOCK_INTERRUPT_ENABLE,
1317c478bd9Sstevel@tonic-gate 	JBC_ERROR_LOG_ENABLE,
1327c478bd9Sstevel@tonic-gate 	JBC_INTERRUPT_ENABLE
1337c478bd9Sstevel@tonic-gate };
13425cf1a30Sjl139090 #define	JBC_SIZE (sizeof (jbc_config_state_regs))
13525cf1a30Sjl139090 #define	JBC_KEYS (JBC_SIZE / sizeof (uint64_t))
13625cf1a30Sjl139090 
13725cf1a30Sjl139090 /*
13825cf1a30Sjl139090  * Registers for the UBC module.
13925cf1a30Sjl139090  * UBC_ERROR_STATUS_CLEAR needs to be cleared. (-1ull)
14025cf1a30Sjl139090  */
14125cf1a30Sjl139090 static uint64_t	ubc_config_state_regs[] = {
14225cf1a30Sjl139090 	UBC_ERROR_LOG_ENABLE,
14325cf1a30Sjl139090 	UBC_INTERRUPT_ENABLE
14425cf1a30Sjl139090 };
14525cf1a30Sjl139090 #define	UBC_SIZE (sizeof (ubc_config_state_regs))
14625cf1a30Sjl139090 #define	UBC_KEYS (UBC_SIZE / sizeof (uint64_t))
1477c478bd9Sstevel@tonic-gate 
1487c478bd9Sstevel@tonic-gate static uint64_t	msiq_config_other_regs[] = {
1497c478bd9Sstevel@tonic-gate 	ERR_COR_MAPPING,
1507c478bd9Sstevel@tonic-gate 	ERR_NONFATAL_MAPPING,
1517c478bd9Sstevel@tonic-gate 	ERR_FATAL_MAPPING,
1527c478bd9Sstevel@tonic-gate 	PM_PME_MAPPING,
1537c478bd9Sstevel@tonic-gate 	PME_TO_ACK_MAPPING,
1547c478bd9Sstevel@tonic-gate 	MSI_32_BIT_ADDRESS,
1557c478bd9Sstevel@tonic-gate 	MSI_64_BIT_ADDRESS
1567c478bd9Sstevel@tonic-gate };
1577c478bd9Sstevel@tonic-gate #define	MSIQ_OTHER_SIZE	(sizeof (msiq_config_other_regs))
1587c478bd9Sstevel@tonic-gate #define	MSIQ_OTHER_KEYS	(MSIQ_OTHER_SIZE / sizeof (uint64_t))
1597c478bd9Sstevel@tonic-gate 
1607c478bd9Sstevel@tonic-gate #define	MSIQ_STATE_SIZE		(EVENT_QUEUE_STATE_ENTRIES * sizeof (uint64_t))
1617c478bd9Sstevel@tonic-gate #define	MSIQ_MAPPING_SIZE	(MSI_MAPPING_ENTRIES * sizeof (uint64_t))
1627c478bd9Sstevel@tonic-gate 
1633c4226f9Spjha /* OPL tuning variables for link unstable issue */
164b6b3bf89Spjha int wait_perst = 5000000; 	/* step 9, default: 5s */
165b6b3bf89Spjha int wait_enable_port = 30000;	/* step 11, default: 30ms */
1663c4226f9Spjha int link_retry_count = 2; 	/* step 11, default: 2 */
167b6b3bf89Spjha int link_status_check = 400000;	/* step 11, default: 400ms */
1683c4226f9Spjha 
1697c478bd9Sstevel@tonic-gate static uint64_t msiq_suspend(devhandle_t dev_hdl, pxu_t *pxu_p);
1707c478bd9Sstevel@tonic-gate static void msiq_resume(devhandle_t dev_hdl, pxu_t *pxu_p);
17125cf1a30Sjl139090 static void jbc_init(caddr_t xbc_csr_base, pxu_t *pxu_p);
17225cf1a30Sjl139090 static void ubc_init(caddr_t xbc_csr_base, pxu_t *pxu_p);
1737c478bd9Sstevel@tonic-gate 
1740114761dSAlan Adamson, SD OSSD extern int px_acknak_timer_table[LINK_MAX_PKT_ARR_SIZE][LINK_WIDTH_ARR_SIZE];
1750114761dSAlan Adamson, SD OSSD extern int px_replay_timer_table[LINK_MAX_PKT_ARR_SIZE][LINK_WIDTH_ARR_SIZE];
1760114761dSAlan Adamson, SD OSSD 
177f8d2de6bSjchu /*
17825cf1a30Sjl139090  * Initialize the bus, but do not enable interrupts.
179f8d2de6bSjchu  */
1807c478bd9Sstevel@tonic-gate /* ARGSUSED */
1817c478bd9Sstevel@tonic-gate void
1827c478bd9Sstevel@tonic-gate hvio_cb_init(caddr_t xbc_csr_base, pxu_t *pxu_p)
1837c478bd9Sstevel@tonic-gate {
18425cf1a30Sjl139090 	switch (PX_CHIP_TYPE(pxu_p)) {
18525cf1a30Sjl139090 	case PX_CHIP_OBERON:
18625cf1a30Sjl139090 		ubc_init(xbc_csr_base, pxu_p);
18725cf1a30Sjl139090 		break;
18825cf1a30Sjl139090 	case PX_CHIP_FIRE:
18925cf1a30Sjl139090 		jbc_init(xbc_csr_base, pxu_p);
19025cf1a30Sjl139090 		break;
19125cf1a30Sjl139090 	default:
19225cf1a30Sjl139090 		DBG(DBG_CB, NULL, "hvio_cb_init - unknown chip type: 0x%x\n",
19325cf1a30Sjl139090 		    PX_CHIP_TYPE(pxu_p));
19425cf1a30Sjl139090 		break;
19525cf1a30Sjl139090 	}
19625cf1a30Sjl139090 }
19725cf1a30Sjl139090 
19825cf1a30Sjl139090 /*
19925cf1a30Sjl139090  * Initialize the JBC module, but do not enable interrupts.
20025cf1a30Sjl139090  */
20125cf1a30Sjl139090 /* ARGSUSED */
20225cf1a30Sjl139090 static void
20325cf1a30Sjl139090 jbc_init(caddr_t xbc_csr_base, pxu_t *pxu_p)
20425cf1a30Sjl139090 {
2057c478bd9Sstevel@tonic-gate 	uint64_t val;
2067c478bd9Sstevel@tonic-gate 
2077c478bd9Sstevel@tonic-gate 	/* Check if we need to enable inverted parity */
2087c478bd9Sstevel@tonic-gate 	val = (1ULL << JBUS_PARITY_CONTROL_P_EN);
2097c478bd9Sstevel@tonic-gate 	CSR_XS(xbc_csr_base, JBUS_PARITY_CONTROL, val);
21025cf1a30Sjl139090 	DBG(DBG_CB, NULL, "jbc_init, JBUS_PARITY_CONTROL: 0x%llx\n",
2117c478bd9Sstevel@tonic-gate 	    CSR_XR(xbc_csr_base, JBUS_PARITY_CONTROL));
2127c478bd9Sstevel@tonic-gate 
2137c478bd9Sstevel@tonic-gate 	val = (1 << JBC_FATAL_RESET_ENABLE_SPARE_P_INT_EN) |
2147c478bd9Sstevel@tonic-gate 	    (1 << JBC_FATAL_RESET_ENABLE_MB_PEA_P_INT_EN) |
2157c478bd9Sstevel@tonic-gate 	    (1 << JBC_FATAL_RESET_ENABLE_CPE_P_INT_EN) |
2167c478bd9Sstevel@tonic-gate 	    (1 << JBC_FATAL_RESET_ENABLE_APE_P_INT_EN) |
2177c478bd9Sstevel@tonic-gate 	    (1 << JBC_FATAL_RESET_ENABLE_PIO_CPE_INT_EN) |
2187c478bd9Sstevel@tonic-gate 	    (1 << JBC_FATAL_RESET_ENABLE_JTCEEW_P_INT_EN) |
2197c478bd9Sstevel@tonic-gate 	    (1 << JBC_FATAL_RESET_ENABLE_JTCEEI_P_INT_EN) |
2207c478bd9Sstevel@tonic-gate 	    (1 << JBC_FATAL_RESET_ENABLE_JTCEER_P_INT_EN);
2217c478bd9Sstevel@tonic-gate 	CSR_XS(xbc_csr_base, JBC_FATAL_RESET_ENABLE, val);
22225cf1a30Sjl139090 	DBG(DBG_CB, NULL, "jbc_init, JBC_FATAL_RESET_ENABLE: 0x%llx\n",
2237c478bd9Sstevel@tonic-gate 	    CSR_XR(xbc_csr_base, JBC_FATAL_RESET_ENABLE));
2247c478bd9Sstevel@tonic-gate 
2257c478bd9Sstevel@tonic-gate 	/*
2267c478bd9Sstevel@tonic-gate 	 * Enable merge, jbc and dmc interrupts.
2277c478bd9Sstevel@tonic-gate 	 */
2287c478bd9Sstevel@tonic-gate 	CSR_XS(xbc_csr_base, JBC_CORE_AND_BLOCK_INTERRUPT_ENABLE, -1ull);
2297c478bd9Sstevel@tonic-gate 	DBG(DBG_CB, NULL,
23025cf1a30Sjl139090 	    "jbc_init, JBC_CORE_AND_BLOCK_INTERRUPT_ENABLE: 0x%llx\n",
2317c478bd9Sstevel@tonic-gate 	    CSR_XR(xbc_csr_base, JBC_CORE_AND_BLOCK_INTERRUPT_ENABLE));
2327c478bd9Sstevel@tonic-gate 
2337c478bd9Sstevel@tonic-gate 	/*
23425cf1a30Sjl139090 	 * CSR_V JBC's interrupt regs (log, enable, status, clear)
2357c478bd9Sstevel@tonic-gate 	 */
23625cf1a30Sjl139090 	DBG(DBG_CB, NULL, "jbc_init, JBC_ERROR_LOG_ENABLE: 0x%llx\n",
2377c478bd9Sstevel@tonic-gate 	    CSR_XR(xbc_csr_base, JBC_ERROR_LOG_ENABLE));
2387c478bd9Sstevel@tonic-gate 
23925cf1a30Sjl139090 	DBG(DBG_CB, NULL, "jbc_init, JBC_INTERRUPT_ENABLE: 0x%llx\n",
2407c478bd9Sstevel@tonic-gate 	    CSR_XR(xbc_csr_base, JBC_INTERRUPT_ENABLE));
2417c478bd9Sstevel@tonic-gate 
24225cf1a30Sjl139090 	DBG(DBG_CB, NULL, "jbc_init, JBC_INTERRUPT_STATUS: 0x%llx\n",
243f8d2de6bSjchu 	    CSR_XR(xbc_csr_base, JBC_INTERRUPT_STATUS));
2447c478bd9Sstevel@tonic-gate 
24525cf1a30Sjl139090 	DBG(DBG_CB, NULL, "jbc_init, JBC_ERROR_STATUS_CLEAR: 0x%llx\n",
2467c478bd9Sstevel@tonic-gate 	    CSR_XR(xbc_csr_base, JBC_ERROR_STATUS_CLEAR));
2477c478bd9Sstevel@tonic-gate }
2487c478bd9Sstevel@tonic-gate 
249f8d2de6bSjchu /*
25025cf1a30Sjl139090  * Initialize the UBC module, but do not enable interrupts.
25125cf1a30Sjl139090  */
25225cf1a30Sjl139090 /* ARGSUSED */
25325cf1a30Sjl139090 static void
25425cf1a30Sjl139090 ubc_init(caddr_t xbc_csr_base, pxu_t *pxu_p)
25525cf1a30Sjl139090 {
25625cf1a30Sjl139090 	/*
25725cf1a30Sjl139090 	 * Enable Uranus bus error log bits.
25825cf1a30Sjl139090 	 */
25925cf1a30Sjl139090 	CSR_XS(xbc_csr_base, UBC_ERROR_LOG_ENABLE, -1ull);
26025cf1a30Sjl139090 	DBG(DBG_CB, NULL, "ubc_init, UBC_ERROR_LOG_ENABLE: 0x%llx\n",
26125cf1a30Sjl139090 	    CSR_XR(xbc_csr_base, UBC_ERROR_LOG_ENABLE));
26225cf1a30Sjl139090 
26325cf1a30Sjl139090 	/*
26425cf1a30Sjl139090 	 * Clear Uranus bus errors.
26525cf1a30Sjl139090 	 */
26625cf1a30Sjl139090 	CSR_XS(xbc_csr_base, UBC_ERROR_STATUS_CLEAR, -1ull);
26725cf1a30Sjl139090 	DBG(DBG_CB, NULL, "ubc_init, UBC_ERROR_STATUS_CLEAR: 0x%llx\n",
26825cf1a30Sjl139090 	    CSR_XR(xbc_csr_base, UBC_ERROR_STATUS_CLEAR));
26925cf1a30Sjl139090 
27025cf1a30Sjl139090 	/*
27125cf1a30Sjl139090 	 * CSR_V UBC's interrupt regs (log, enable, status, clear)
27225cf1a30Sjl139090 	 */
27325cf1a30Sjl139090 	DBG(DBG_CB, NULL, "ubc_init, UBC_ERROR_LOG_ENABLE: 0x%llx\n",
27425cf1a30Sjl139090 	    CSR_XR(xbc_csr_base, UBC_ERROR_LOG_ENABLE));
27525cf1a30Sjl139090 
27625cf1a30Sjl139090 	DBG(DBG_CB, NULL, "ubc_init, UBC_INTERRUPT_ENABLE: 0x%llx\n",
27725cf1a30Sjl139090 	    CSR_XR(xbc_csr_base, UBC_INTERRUPT_ENABLE));
27825cf1a30Sjl139090 
27925cf1a30Sjl139090 	DBG(DBG_CB, NULL, "ubc_init, UBC_INTERRUPT_STATUS: 0x%llx\n",
28025cf1a30Sjl139090 	    CSR_XR(xbc_csr_base, UBC_INTERRUPT_STATUS));
28125cf1a30Sjl139090 
28225cf1a30Sjl139090 	DBG(DBG_CB, NULL, "ubc_init, UBC_ERROR_STATUS_CLEAR: 0x%llx\n",
28325cf1a30Sjl139090 	    CSR_XR(xbc_csr_base, UBC_ERROR_STATUS_CLEAR));
28425cf1a30Sjl139090 }
28525cf1a30Sjl139090 
28625cf1a30Sjl139090 /*
287f8d2de6bSjchu  * Initialize the module, but do not enable interrupts.
288f8d2de6bSjchu  */
2897c478bd9Sstevel@tonic-gate /* ARGSUSED */
2907c478bd9Sstevel@tonic-gate void
2917c478bd9Sstevel@tonic-gate hvio_ib_init(caddr_t csr_base, pxu_t *pxu_p)
2927c478bd9Sstevel@tonic-gate {
2937c478bd9Sstevel@tonic-gate 	/*
294f8d2de6bSjchu 	 * CSR_V IB's interrupt regs (log, enable, status, clear)
2957c478bd9Sstevel@tonic-gate 	 */
2967c478bd9Sstevel@tonic-gate 	DBG(DBG_IB, NULL, "hvio_ib_init - IMU_ERROR_LOG_ENABLE: 0x%llx\n",
2977c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, IMU_ERROR_LOG_ENABLE));
2987c478bd9Sstevel@tonic-gate 
2997c478bd9Sstevel@tonic-gate 	DBG(DBG_IB, NULL, "hvio_ib_init - IMU_INTERRUPT_ENABLE: 0x%llx\n",
3007c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, IMU_INTERRUPT_ENABLE));
3017c478bd9Sstevel@tonic-gate 
3027c478bd9Sstevel@tonic-gate 	DBG(DBG_IB, NULL, "hvio_ib_init - IMU_INTERRUPT_STATUS: 0x%llx\n",
3037c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, IMU_INTERRUPT_STATUS));
3047c478bd9Sstevel@tonic-gate 
3057c478bd9Sstevel@tonic-gate 	DBG(DBG_IB, NULL, "hvio_ib_init - IMU_ERROR_STATUS_CLEAR: 0x%llx\n",
3067c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, IMU_ERROR_STATUS_CLEAR));
3077c478bd9Sstevel@tonic-gate }
3087c478bd9Sstevel@tonic-gate 
309f8d2de6bSjchu /*
310f8d2de6bSjchu  * Initialize the module, but do not enable interrupts.
311f8d2de6bSjchu  */
3127c478bd9Sstevel@tonic-gate /* ARGSUSED */
3137c478bd9Sstevel@tonic-gate static void
3147c478bd9Sstevel@tonic-gate ilu_init(caddr_t csr_base, pxu_t *pxu_p)
3157c478bd9Sstevel@tonic-gate {
3167c478bd9Sstevel@tonic-gate 	/*
317f8d2de6bSjchu 	 * CSR_V ILU's interrupt regs (log, enable, status, clear)
3187c478bd9Sstevel@tonic-gate 	 */
3197c478bd9Sstevel@tonic-gate 	DBG(DBG_ILU, NULL, "ilu_init - ILU_ERROR_LOG_ENABLE: 0x%llx\n",
3207c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, ILU_ERROR_LOG_ENABLE));
3217c478bd9Sstevel@tonic-gate 
3227c478bd9Sstevel@tonic-gate 	DBG(DBG_ILU, NULL, "ilu_init - ILU_INTERRUPT_ENABLE: 0x%llx\n",
3237c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, ILU_INTERRUPT_ENABLE));
3247c478bd9Sstevel@tonic-gate 
3257c478bd9Sstevel@tonic-gate 	DBG(DBG_ILU, NULL, "ilu_init - ILU_INTERRUPT_STATUS: 0x%llx\n",
3267c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, ILU_INTERRUPT_STATUS));
3277c478bd9Sstevel@tonic-gate 
3287c478bd9Sstevel@tonic-gate 	DBG(DBG_ILU, NULL, "ilu_init - ILU_ERROR_STATUS_CLEAR: 0x%llx\n",
3297c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, ILU_ERROR_STATUS_CLEAR));
3307c478bd9Sstevel@tonic-gate }
3317c478bd9Sstevel@tonic-gate 
332f8d2de6bSjchu /*
333f8d2de6bSjchu  * Initialize the module, but do not enable interrupts.
334f8d2de6bSjchu  */
3357510e228Sess /* ARGSUSED */
3367c478bd9Sstevel@tonic-gate static void
3377c478bd9Sstevel@tonic-gate tlu_init(caddr_t csr_base, pxu_t *pxu_p)
3387c478bd9Sstevel@tonic-gate {
3397c478bd9Sstevel@tonic-gate 	uint64_t val;
3407c478bd9Sstevel@tonic-gate 
3417c478bd9Sstevel@tonic-gate 	/*
3427c478bd9Sstevel@tonic-gate 	 * CSR_V TLU_CONTROL Expect OBP ???
3437c478bd9Sstevel@tonic-gate 	 */
3447c478bd9Sstevel@tonic-gate 
3457c478bd9Sstevel@tonic-gate 	/*
3467c478bd9Sstevel@tonic-gate 	 * L0s entry default timer value - 7.0 us
3477c478bd9Sstevel@tonic-gate 	 * Completion timeout select default value - 67.1 ms and
3487c478bd9Sstevel@tonic-gate 	 * OBP will set this value.
3497c478bd9Sstevel@tonic-gate 	 *
3507c478bd9Sstevel@tonic-gate 	 * Configuration - Bit 0 should always be 0 for upstream port.
3517c478bd9Sstevel@tonic-gate 	 * Bit 1 is clock - how is this related to the clock bit in TLU
3527c478bd9Sstevel@tonic-gate 	 * Link Control register?  Both are hardware dependent and likely
3537c478bd9Sstevel@tonic-gate 	 * set by OBP.
3547c478bd9Sstevel@tonic-gate 	 *
355de0f6141Sjroberts 	 * NOTE: Do not set the NPWR_EN bit.  The desired value of this bit
356de0f6141Sjroberts 	 * will be set by OBP.
3577c478bd9Sstevel@tonic-gate 	 */
3587c478bd9Sstevel@tonic-gate 	val = CSR_XR(csr_base, TLU_CONTROL);
3597c478bd9Sstevel@tonic-gate 	val |= (TLU_CONTROL_L0S_TIM_DEFAULT << TLU_CONTROL_L0S_TIM) |
360de0f6141Sjroberts 	    TLU_CONTROL_CONFIG_DEFAULT;
3617c478bd9Sstevel@tonic-gate 
3621a887b2eSjchu 	/*
36325cf1a30Sjl139090 	 * For Oberon, NPWR_EN is set to 0 to prevent PIO reads from blocking
36425cf1a30Sjl139090 	 * behind non-posted PIO writes. This blocking could cause a master or
36525cf1a30Sjl139090 	 * slave timeout on the host bus if multiple serialized PIOs were to
36625cf1a30Sjl139090 	 * suffer Completion Timeouts because the CTO delays for each PIO ahead
36725cf1a30Sjl139090 	 * of the read would accumulate. Since the Olympus processor can have
36825cf1a30Sjl139090 	 * only 1 PIO outstanding, there is no possibility of PIO accesses from
36925cf1a30Sjl139090 	 * a given CPU to a given device being re-ordered by the PCIe fabric;
37025cf1a30Sjl139090 	 * therefore turning off serialization should be safe from a PCIe
37125cf1a30Sjl139090 	 * ordering perspective.
37225cf1a30Sjl139090 	 */
37325cf1a30Sjl139090 	if (PX_CHIP_TYPE(pxu_p) == PX_CHIP_OBERON)
37425cf1a30Sjl139090 		val &= ~(1ull << TLU_CONTROL_NPWR_EN);
37525cf1a30Sjl139090 
37625cf1a30Sjl139090 	/*
3771a887b2eSjchu 	 * Set Detect.Quiet. This will disable automatic link
3781a887b2eSjchu 	 * re-training, if the link goes down e.g. power management
3791a887b2eSjchu 	 * turns off power to the downstream device. This will enable
3801a887b2eSjchu 	 * Fire to go to Drain state, after link down. The drain state
3811a887b2eSjchu 	 * forces a reset to the FC state machine, which is required for
3821a887b2eSjchu 	 * proper link re-training.
3831a887b2eSjchu 	 */
3841a887b2eSjchu 	val |= (1ull << TLU_REMAIN_DETECT_QUIET);
3857c478bd9Sstevel@tonic-gate 	CSR_XS(csr_base, TLU_CONTROL, val);
3867c478bd9Sstevel@tonic-gate 	DBG(DBG_TLU, NULL, "tlu_init - TLU_CONTROL: 0x%llx\n",
3877c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, TLU_CONTROL));
3887c478bd9Sstevel@tonic-gate 
3897c478bd9Sstevel@tonic-gate 	/*
3907c478bd9Sstevel@tonic-gate 	 * CSR_V TLU_STATUS Expect HW 0x4
3917c478bd9Sstevel@tonic-gate 	 */
3927c478bd9Sstevel@tonic-gate 
3937c478bd9Sstevel@tonic-gate 	/*
3947c478bd9Sstevel@tonic-gate 	 * Only bit [7:0] are currently defined.  Bits [2:0]
3957c478bd9Sstevel@tonic-gate 	 * are the state, which should likely be in state active,
3967c478bd9Sstevel@tonic-gate 	 * 100b.  Bit three is 'recovery', which is not understood.
3977c478bd9Sstevel@tonic-gate 	 * All other bits are reserved.
3987c478bd9Sstevel@tonic-gate 	 */
3997c478bd9Sstevel@tonic-gate 	DBG(DBG_TLU, NULL, "tlu_init - TLU_STATUS: 0x%llx\n",
4007c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, TLU_STATUS));
4017c478bd9Sstevel@tonic-gate 
4027c478bd9Sstevel@tonic-gate 	/*
4037c478bd9Sstevel@tonic-gate 	 * CSR_V TLU_PME_TURN_OFF_GENERATE Expect HW 0x0
4047c478bd9Sstevel@tonic-gate 	 */
4057c478bd9Sstevel@tonic-gate 	DBG(DBG_TLU, NULL, "tlu_init - TLU_PME_TURN_OFF_GENERATE: 0x%llx\n",
4067c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, TLU_PME_TURN_OFF_GENERATE));
4077c478bd9Sstevel@tonic-gate 
4087c478bd9Sstevel@tonic-gate 	/*
4097c478bd9Sstevel@tonic-gate 	 * CSR_V TLU_INGRESS_CREDITS_INITIAL Expect HW 0x10000200C0
4107c478bd9Sstevel@tonic-gate 	 */
4117c478bd9Sstevel@tonic-gate 
4127c478bd9Sstevel@tonic-gate 	/*
4137c478bd9Sstevel@tonic-gate 	 * Ingress credits initial register.  Bits [39:32] should be
4147c478bd9Sstevel@tonic-gate 	 * 0x10, bits [19:12] should be 0x20, and bits [11:0] should
4157c478bd9Sstevel@tonic-gate 	 * be 0xC0.  These are the reset values, and should be set by
4167c478bd9Sstevel@tonic-gate 	 * HW.
4177c478bd9Sstevel@tonic-gate 	 */
4187c478bd9Sstevel@tonic-gate 	DBG(DBG_TLU, NULL, "tlu_init - TLU_INGRESS_CREDITS_INITIAL: 0x%llx\n",
4197c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, TLU_INGRESS_CREDITS_INITIAL));
4207c478bd9Sstevel@tonic-gate 
4217c478bd9Sstevel@tonic-gate 	/*
4227c478bd9Sstevel@tonic-gate 	 * CSR_V TLU_DIAGNOSTIC Expect HW 0x0
4237c478bd9Sstevel@tonic-gate 	 */
4247c478bd9Sstevel@tonic-gate 
4257c478bd9Sstevel@tonic-gate 	/*
4267c478bd9Sstevel@tonic-gate 	 * Diagnostic register - always zero unless we are debugging.
4277c478bd9Sstevel@tonic-gate 	 */
4287c478bd9Sstevel@tonic-gate 	DBG(DBG_TLU, NULL, "tlu_init - TLU_DIAGNOSTIC: 0x%llx\n",
4297c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, TLU_DIAGNOSTIC));
4307c478bd9Sstevel@tonic-gate 
4317c478bd9Sstevel@tonic-gate 	/*
4327c478bd9Sstevel@tonic-gate 	 * CSR_V TLU_EGRESS_CREDITS_CONSUMED Expect HW 0x0
4337c478bd9Sstevel@tonic-gate 	 */
4347c478bd9Sstevel@tonic-gate 	DBG(DBG_TLU, NULL, "tlu_init - TLU_EGRESS_CREDITS_CONSUMED: 0x%llx\n",
4357c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, TLU_EGRESS_CREDITS_CONSUMED));
4367c478bd9Sstevel@tonic-gate 
4377c478bd9Sstevel@tonic-gate 	/*
4387c478bd9Sstevel@tonic-gate 	 * CSR_V TLU_EGRESS_CREDIT_LIMIT Expect HW 0x0
4397c478bd9Sstevel@tonic-gate 	 */
4407c478bd9Sstevel@tonic-gate 	DBG(DBG_TLU, NULL, "tlu_init - TLU_EGRESS_CREDIT_LIMIT: 0x%llx\n",
4417c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, TLU_EGRESS_CREDIT_LIMIT));
4427c478bd9Sstevel@tonic-gate 
4437c478bd9Sstevel@tonic-gate 	/*
4447c478bd9Sstevel@tonic-gate 	 * CSR_V TLU_EGRESS_RETRY_BUFFER Expect HW 0x0
4457c478bd9Sstevel@tonic-gate 	 */
4467c478bd9Sstevel@tonic-gate 	DBG(DBG_TLU, NULL, "tlu_init - TLU_EGRESS_RETRY_BUFFER: 0x%llx\n",
4477c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, TLU_EGRESS_RETRY_BUFFER));
4487c478bd9Sstevel@tonic-gate 
4497c478bd9Sstevel@tonic-gate 	/*
4507c478bd9Sstevel@tonic-gate 	 * CSR_V TLU_INGRESS_CREDITS_ALLOCATED Expected HW 0x0
4517c478bd9Sstevel@tonic-gate 	 */
4527c478bd9Sstevel@tonic-gate 	DBG(DBG_TLU, NULL,
4537c478bd9Sstevel@tonic-gate 	    "tlu_init - TLU_INGRESS_CREDITS_ALLOCATED: 0x%llx\n",
4547c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, TLU_INGRESS_CREDITS_ALLOCATED));
4557c478bd9Sstevel@tonic-gate 
4567c478bd9Sstevel@tonic-gate 	/*
4577c478bd9Sstevel@tonic-gate 	 * CSR_V TLU_INGRESS_CREDITS_RECEIVED Expected HW 0x0
4587c478bd9Sstevel@tonic-gate 	 */
4597c478bd9Sstevel@tonic-gate 	DBG(DBG_TLU, NULL,
4607c478bd9Sstevel@tonic-gate 	    "tlu_init - TLU_INGRESS_CREDITS_RECEIVED: 0x%llx\n",
4617c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, TLU_INGRESS_CREDITS_RECEIVED));
4627c478bd9Sstevel@tonic-gate 
4637c478bd9Sstevel@tonic-gate 	/*
464f8d2de6bSjchu 	 * CSR_V TLU's interrupt regs (log, enable, status, clear)
4657c478bd9Sstevel@tonic-gate 	 */
466f8d2de6bSjchu 	DBG(DBG_TLU, NULL,
467f8d2de6bSjchu 	    "tlu_init - TLU_OTHER_EVENT_LOG_ENABLE: 0x%llx\n",
4687c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, TLU_OTHER_EVENT_LOG_ENABLE));
4697c478bd9Sstevel@tonic-gate 
4707c478bd9Sstevel@tonic-gate 	DBG(DBG_TLU, NULL,
4717c478bd9Sstevel@tonic-gate 	    "tlu_init - TLU_OTHER_EVENT_INTERRUPT_ENABLE: 0x%llx\n",
4727c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, TLU_OTHER_EVENT_INTERRUPT_ENABLE));
4737c478bd9Sstevel@tonic-gate 
4747c478bd9Sstevel@tonic-gate 	DBG(DBG_TLU, NULL,
4757c478bd9Sstevel@tonic-gate 	    "tlu_init - TLU_OTHER_EVENT_INTERRUPT_STATUS: 0x%llx\n",
4767c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, TLU_OTHER_EVENT_INTERRUPT_STATUS));
4777c478bd9Sstevel@tonic-gate 
4787c478bd9Sstevel@tonic-gate 	DBG(DBG_TLU, NULL,
4797c478bd9Sstevel@tonic-gate 	    "tlu_init - TLU_OTHER_EVENT_STATUS_CLEAR: 0x%llx\n",
4807c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, TLU_OTHER_EVENT_STATUS_CLEAR));
4817c478bd9Sstevel@tonic-gate 
4827c478bd9Sstevel@tonic-gate 	/*
4837c478bd9Sstevel@tonic-gate 	 * CSR_V TLU_RECEIVE_OTHER_EVENT_HEADER1_LOG Expect HW 0x0
4847c478bd9Sstevel@tonic-gate 	 */
4857c478bd9Sstevel@tonic-gate 	DBG(DBG_TLU, NULL,
4867c478bd9Sstevel@tonic-gate 	    "tlu_init - TLU_RECEIVE_OTHER_EVENT_HEADER1_LOG: 0x%llx\n",
4877c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, TLU_RECEIVE_OTHER_EVENT_HEADER1_LOG));
4887c478bd9Sstevel@tonic-gate 
4897c478bd9Sstevel@tonic-gate 	/*
4907c478bd9Sstevel@tonic-gate 	 * CSR_V TLU_RECEIVE_OTHER_EVENT_HEADER2_LOG Expect HW 0x0
4917c478bd9Sstevel@tonic-gate 	 */
4927c478bd9Sstevel@tonic-gate 	DBG(DBG_TLU, NULL,
4937c478bd9Sstevel@tonic-gate 	    "tlu_init - TLU_RECEIVE_OTHER_EVENT_HEADER2_LOG: 0x%llx\n",
4947c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, TLU_RECEIVE_OTHER_EVENT_HEADER2_LOG));
4957c478bd9Sstevel@tonic-gate 
4967c478bd9Sstevel@tonic-gate 	/*
4977c478bd9Sstevel@tonic-gate 	 * CSR_V TLU_TRANSMIT_OTHER_EVENT_HEADER1_LOG Expect HW 0x0
4987c478bd9Sstevel@tonic-gate 	 */
4997c478bd9Sstevel@tonic-gate 	DBG(DBG_TLU, NULL,
5007c478bd9Sstevel@tonic-gate 	    "tlu_init - TLU_TRANSMIT_OTHER_EVENT_HEADER1_LOG: 0x%llx\n",
5017c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, TLU_TRANSMIT_OTHER_EVENT_HEADER1_LOG));
5027c478bd9Sstevel@tonic-gate 
5037c478bd9Sstevel@tonic-gate 	/*
5047c478bd9Sstevel@tonic-gate 	 * CSR_V TLU_TRANSMIT_OTHER_EVENT_HEADER2_LOG Expect HW 0x0
5057c478bd9Sstevel@tonic-gate 	 */
5067c478bd9Sstevel@tonic-gate 	DBG(DBG_TLU, NULL,
5077c478bd9Sstevel@tonic-gate 	    "tlu_init - TLU_TRANSMIT_OTHER_EVENT_HEADER2_LOG: 0x%llx\n",
5087c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, TLU_TRANSMIT_OTHER_EVENT_HEADER2_LOG));
5097c478bd9Sstevel@tonic-gate 
5107c478bd9Sstevel@tonic-gate 	/*
5117c478bd9Sstevel@tonic-gate 	 * CSR_V TLU_PERFORMANCE_COUNTER_SELECT Expect HW 0x0
5127c478bd9Sstevel@tonic-gate 	 */
5137c478bd9Sstevel@tonic-gate 	DBG(DBG_TLU, NULL,
5147c478bd9Sstevel@tonic-gate 	    "tlu_init - TLU_PERFORMANCE_COUNTER_SELECT: 0x%llx\n",
5157c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, TLU_PERFORMANCE_COUNTER_SELECT));
5167c478bd9Sstevel@tonic-gate 
5177c478bd9Sstevel@tonic-gate 	/*
5187c478bd9Sstevel@tonic-gate 	 * CSR_V TLU_PERFORMANCE_COUNTER_ZERO Expect HW 0x0
5197c478bd9Sstevel@tonic-gate 	 */
5207c478bd9Sstevel@tonic-gate 	DBG(DBG_TLU, NULL,
5217c478bd9Sstevel@tonic-gate 	    "tlu_init - TLU_PERFORMANCE_COUNTER_ZERO: 0x%llx\n",
5227c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, TLU_PERFORMANCE_COUNTER_ZERO));
5237c478bd9Sstevel@tonic-gate 
5247c478bd9Sstevel@tonic-gate 	/*
5257c478bd9Sstevel@tonic-gate 	 * CSR_V TLU_PERFORMANCE_COUNTER_ONE Expect HW 0x0
5267c478bd9Sstevel@tonic-gate 	 */
5277c478bd9Sstevel@tonic-gate 	DBG(DBG_TLU, NULL, "tlu_init - TLU_PERFORMANCE_COUNTER_ONE: 0x%llx\n",
5287c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, TLU_PERFORMANCE_COUNTER_ONE));
5297c478bd9Sstevel@tonic-gate 
5307c478bd9Sstevel@tonic-gate 	/*
5317c478bd9Sstevel@tonic-gate 	 * CSR_V TLU_PERFORMANCE_COUNTER_TWO Expect HW 0x0
5327c478bd9Sstevel@tonic-gate 	 */
5337c478bd9Sstevel@tonic-gate 	DBG(DBG_TLU, NULL, "tlu_init - TLU_PERFORMANCE_COUNTER_TWO: 0x%llx\n",
5347c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, TLU_PERFORMANCE_COUNTER_TWO));
5357c478bd9Sstevel@tonic-gate 
5367c478bd9Sstevel@tonic-gate 	/*
5377c478bd9Sstevel@tonic-gate 	 * CSR_V TLU_DEBUG_SELECT_A Expect HW 0x0
5387c478bd9Sstevel@tonic-gate 	 */
5397c478bd9Sstevel@tonic-gate 
5407c478bd9Sstevel@tonic-gate 	DBG(DBG_TLU, NULL, "tlu_init - TLU_DEBUG_SELECT_A: 0x%llx\n",
5417c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, TLU_DEBUG_SELECT_A));
5427c478bd9Sstevel@tonic-gate 
5437c478bd9Sstevel@tonic-gate 	/*
5447c478bd9Sstevel@tonic-gate 	 * CSR_V TLU_DEBUG_SELECT_B Expect HW 0x0
5457c478bd9Sstevel@tonic-gate 	 */
5467c478bd9Sstevel@tonic-gate 	DBG(DBG_TLU, NULL, "tlu_init - TLU_DEBUG_SELECT_B: 0x%llx\n",
5477c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, TLU_DEBUG_SELECT_B));
5487c478bd9Sstevel@tonic-gate 
5497c478bd9Sstevel@tonic-gate 	/*
5507c478bd9Sstevel@tonic-gate 	 * CSR_V TLU_DEVICE_CAPABILITIES Expect HW 0xFC2
5517c478bd9Sstevel@tonic-gate 	 */
5527c478bd9Sstevel@tonic-gate 	DBG(DBG_TLU, NULL, "tlu_init - TLU_DEVICE_CAPABILITIES: 0x%llx\n",
5537c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, TLU_DEVICE_CAPABILITIES));
5547c478bd9Sstevel@tonic-gate 
5557c478bd9Sstevel@tonic-gate 	/*
5567c478bd9Sstevel@tonic-gate 	 * CSR_V TLU_DEVICE_CONTROL Expect HW 0x0
5577c478bd9Sstevel@tonic-gate 	 */
5587c478bd9Sstevel@tonic-gate 
5597c478bd9Sstevel@tonic-gate 	/*
5607c478bd9Sstevel@tonic-gate 	 * Bits [14:12] are the Max Read Request Size, which is always 64
5617c478bd9Sstevel@tonic-gate 	 * bytes which is 000b.  Bits [7:5] are Max Payload Size, which
5627c478bd9Sstevel@tonic-gate 	 * start at 128 bytes which is 000b.  This may be revisited if
5637c478bd9Sstevel@tonic-gate 	 * init_child finds greater values.
5647c478bd9Sstevel@tonic-gate 	 */
5657c478bd9Sstevel@tonic-gate 	val = 0x0ull;
5667c478bd9Sstevel@tonic-gate 	CSR_XS(csr_base, TLU_DEVICE_CONTROL, val);
5677c478bd9Sstevel@tonic-gate 	DBG(DBG_TLU, NULL, "tlu_init - TLU_DEVICE_CONTROL: 0x%llx\n",
5687c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, TLU_DEVICE_CONTROL));
5697c478bd9Sstevel@tonic-gate 
5707c478bd9Sstevel@tonic-gate 	/*
5717c478bd9Sstevel@tonic-gate 	 * CSR_V TLU_DEVICE_STATUS Expect HW 0x0
5727c478bd9Sstevel@tonic-gate 	 */
5737c478bd9Sstevel@tonic-gate 	DBG(DBG_TLU, NULL, "tlu_init - TLU_DEVICE_STATUS: 0x%llx\n",
5747c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, TLU_DEVICE_STATUS));
5757c478bd9Sstevel@tonic-gate 
5767c478bd9Sstevel@tonic-gate 	/*
5777c478bd9Sstevel@tonic-gate 	 * CSR_V TLU_LINK_CAPABILITIES Expect HW 0x15C81
5787c478bd9Sstevel@tonic-gate 	 */
5797c478bd9Sstevel@tonic-gate 	DBG(DBG_TLU, NULL, "tlu_init - TLU_LINK_CAPABILITIES: 0x%llx\n",
5807c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, TLU_LINK_CAPABILITIES));
5817c478bd9Sstevel@tonic-gate 
5827c478bd9Sstevel@tonic-gate 	/*
5837c478bd9Sstevel@tonic-gate 	 * CSR_V TLU_LINK_CONTROL Expect OBP 0x40
5847c478bd9Sstevel@tonic-gate 	 */
5857c478bd9Sstevel@tonic-gate 
5867c478bd9Sstevel@tonic-gate 	/*
5877c478bd9Sstevel@tonic-gate 	 * The CLOCK bit should be set by OBP if the hardware dictates,
5887c478bd9Sstevel@tonic-gate 	 * and if it is set then ASPM should be used since then L0s exit
5897c478bd9Sstevel@tonic-gate 	 * latency should be lower than L1 exit latency.
5907c478bd9Sstevel@tonic-gate 	 *
5917c478bd9Sstevel@tonic-gate 	 * Note that we will not enable power management during bringup
5927c478bd9Sstevel@tonic-gate 	 * since it has not been test and is creating some problems in
5937c478bd9Sstevel@tonic-gate 	 * simulation.
5947c478bd9Sstevel@tonic-gate 	 */
5957c478bd9Sstevel@tonic-gate 	val = (1ull << TLU_LINK_CONTROL_CLOCK);
5967c478bd9Sstevel@tonic-gate 
5977c478bd9Sstevel@tonic-gate 	CSR_XS(csr_base, TLU_LINK_CONTROL, val);
5987c478bd9Sstevel@tonic-gate 	DBG(DBG_TLU, NULL, "tlu_init - TLU_LINK_CONTROL: 0x%llx\n",
5997c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, TLU_LINK_CONTROL));
6007c478bd9Sstevel@tonic-gate 
6017c478bd9Sstevel@tonic-gate 	/*
6027c478bd9Sstevel@tonic-gate 	 * CSR_V TLU_LINK_STATUS Expect OBP 0x1011
6037c478bd9Sstevel@tonic-gate 	 */
6047c478bd9Sstevel@tonic-gate 
6057c478bd9Sstevel@tonic-gate 	/*
6067c478bd9Sstevel@tonic-gate 	 * Not sure if HW or OBP will be setting this read only
6077c478bd9Sstevel@tonic-gate 	 * register.  Bit 12 is Clock, and it should always be 1
6087c478bd9Sstevel@tonic-gate 	 * signifying that the component uses the same physical
6097c478bd9Sstevel@tonic-gate 	 * clock as the platform.  Bits [9:4] are for the width,
6107c478bd9Sstevel@tonic-gate 	 * with the expected value above signifying a x1 width.
6117c478bd9Sstevel@tonic-gate 	 * Bits [3:0] are the speed, with 1b signifying 2.5 Gb/s,
6127c478bd9Sstevel@tonic-gate 	 * the only speed as yet supported by the PCI-E spec.
6137c478bd9Sstevel@tonic-gate 	 */
6147c478bd9Sstevel@tonic-gate 	DBG(DBG_TLU, NULL, "tlu_init - TLU_LINK_STATUS: 0x%llx\n",
6157c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, TLU_LINK_STATUS));
6167c478bd9Sstevel@tonic-gate 
6177c478bd9Sstevel@tonic-gate 	/*
6187c478bd9Sstevel@tonic-gate 	 * CSR_V TLU_SLOT_CAPABILITIES Expect OBP ???
6197c478bd9Sstevel@tonic-gate 	 */
6207c478bd9Sstevel@tonic-gate 
6217c478bd9Sstevel@tonic-gate 	/*
6227c478bd9Sstevel@tonic-gate 	 * Power Limits for the slots.  Will be platform
6237c478bd9Sstevel@tonic-gate 	 * dependent, and OBP will need to set after consulting
6247c478bd9Sstevel@tonic-gate 	 * with the HW guys.
6257c478bd9Sstevel@tonic-gate 	 *
6267c478bd9Sstevel@tonic-gate 	 * Bits [16:15] are power limit scale, which most likely
6277c478bd9Sstevel@tonic-gate 	 * will be 0b signifying 1x.  Bits [14:7] are the Set
6287c478bd9Sstevel@tonic-gate 	 * Power Limit Value, which is a number which is multiplied
6297c478bd9Sstevel@tonic-gate 	 * by the power limit scale to get the actual power limit.
6307c478bd9Sstevel@tonic-gate 	 */
6317c478bd9Sstevel@tonic-gate 	DBG(DBG_TLU, NULL, "tlu_init - TLU_SLOT_CAPABILITIES: 0x%llx\n",
6327c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, TLU_SLOT_CAPABILITIES));
6337c478bd9Sstevel@tonic-gate 
6347c478bd9Sstevel@tonic-gate 	/*
6357c478bd9Sstevel@tonic-gate 	 * CSR_V TLU_UNCORRECTABLE_ERROR_LOG_ENABLE Expect Kernel 0x17F011
6367c478bd9Sstevel@tonic-gate 	 */
6377c478bd9Sstevel@tonic-gate 	DBG(DBG_TLU, NULL,
6387c478bd9Sstevel@tonic-gate 	    "tlu_init - TLU_UNCORRECTABLE_ERROR_LOG_ENABLE: 0x%llx\n",
6397c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_LOG_ENABLE));
6407c478bd9Sstevel@tonic-gate 
6417c478bd9Sstevel@tonic-gate 	/*
642f8d2de6bSjchu 	 * CSR_V TLU_UNCORRECTABLE_ERROR_INTERRUPT_ENABLE Expect
643f8d2de6bSjchu 	 * Kernel 0x17F0110017F011
6447c478bd9Sstevel@tonic-gate 	 */
6457c478bd9Sstevel@tonic-gate 	DBG(DBG_TLU, NULL,
6467c478bd9Sstevel@tonic-gate 	    "tlu_init - TLU_UNCORRECTABLE_ERROR_INTERRUPT_ENABLE: 0x%llx\n",
6477c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_INTERRUPT_ENABLE));
6487c478bd9Sstevel@tonic-gate 
6497c478bd9Sstevel@tonic-gate 	/*
6507c478bd9Sstevel@tonic-gate 	 * CSR_V TLU_UNCORRECTABLE_ERROR_INTERRUPT_STATUS Expect HW 0x0
6517c478bd9Sstevel@tonic-gate 	 */
6527c478bd9Sstevel@tonic-gate 	DBG(DBG_TLU, NULL,
6537c478bd9Sstevel@tonic-gate 	    "tlu_init - TLU_UNCORRECTABLE_ERROR_INTERRUPT_STATUS: 0x%llx\n",
6547c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_INTERRUPT_STATUS));
6557c478bd9Sstevel@tonic-gate 
6567c478bd9Sstevel@tonic-gate 	/*
6577c478bd9Sstevel@tonic-gate 	 * CSR_V TLU_UNCORRECTABLE_ERROR_STATUS_CLEAR Expect HW 0x0
6587c478bd9Sstevel@tonic-gate 	 */
6597c478bd9Sstevel@tonic-gate 	DBG(DBG_TLU, NULL,
6607c478bd9Sstevel@tonic-gate 	    "tlu_init - TLU_UNCORRECTABLE_ERROR_STATUS_CLEAR: 0x%llx\n",
6617c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_STATUS_CLEAR));
6627c478bd9Sstevel@tonic-gate 
6637c478bd9Sstevel@tonic-gate 	/*
6647c478bd9Sstevel@tonic-gate 	 * CSR_V TLU_RECEIVE_UNCORRECTABLE_ERROR_HEADER1_LOG HW 0x0
6657c478bd9Sstevel@tonic-gate 	 */
6667c478bd9Sstevel@tonic-gate 	DBG(DBG_TLU, NULL,
6677c478bd9Sstevel@tonic-gate 	    "tlu_init - TLU_RECEIVE_UNCORRECTABLE_ERROR_HEADER1_LOG: 0x%llx\n",
6687c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, TLU_RECEIVE_UNCORRECTABLE_ERROR_HEADER1_LOG));
6697c478bd9Sstevel@tonic-gate 
6707c478bd9Sstevel@tonic-gate 	/*
6717c478bd9Sstevel@tonic-gate 	 * CSR_V TLU_RECEIVE_UNCORRECTABLE_ERROR_HEADER2_LOG HW 0x0
6727c478bd9Sstevel@tonic-gate 	 */
6737c478bd9Sstevel@tonic-gate 	DBG(DBG_TLU, NULL,
6747c478bd9Sstevel@tonic-gate 	    "tlu_init - TLU_RECEIVE_UNCORRECTABLE_ERROR_HEADER2_LOG: 0x%llx\n",
6757c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, TLU_RECEIVE_UNCORRECTABLE_ERROR_HEADER2_LOG));
6767c478bd9Sstevel@tonic-gate 
6777c478bd9Sstevel@tonic-gate 	/*
6787c478bd9Sstevel@tonic-gate 	 * CSR_V TLU_TRANSMIT_UNCORRECTABLE_ERROR_HEADER1_LOG HW 0x0
6797c478bd9Sstevel@tonic-gate 	 */
6807c478bd9Sstevel@tonic-gate 	DBG(DBG_TLU, NULL,
6817c478bd9Sstevel@tonic-gate 	    "tlu_init - TLU_TRANSMIT_UNCORRECTABLE_ERROR_HEADER1_LOG: 0x%llx\n",
6827c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, TLU_TRANSMIT_UNCORRECTABLE_ERROR_HEADER1_LOG));
6837c478bd9Sstevel@tonic-gate 
6847c478bd9Sstevel@tonic-gate 	/*
6857c478bd9Sstevel@tonic-gate 	 * CSR_V TLU_TRANSMIT_UNCORRECTABLE_ERROR_HEADER2_LOG HW 0x0
6867c478bd9Sstevel@tonic-gate 	 */
6877c478bd9Sstevel@tonic-gate 	DBG(DBG_TLU, NULL,
6887c478bd9Sstevel@tonic-gate 	    "tlu_init - TLU_TRANSMIT_UNCORRECTABLE_ERROR_HEADER2_LOG: 0x%llx\n",
6897c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, TLU_TRANSMIT_UNCORRECTABLE_ERROR_HEADER2_LOG));
6907c478bd9Sstevel@tonic-gate 
691f8d2de6bSjchu 
692f8d2de6bSjchu 	/*
693f8d2de6bSjchu 	 * CSR_V TLU's CE interrupt regs (log, enable, status, clear)
694f8d2de6bSjchu 	 * Plus header logs
695f8d2de6bSjchu 	 */
696f8d2de6bSjchu 
6977c478bd9Sstevel@tonic-gate 	/*
6987c478bd9Sstevel@tonic-gate 	 * CSR_V TLU_CORRECTABLE_ERROR_LOG_ENABLE Expect Kernel 0x11C1
6997c478bd9Sstevel@tonic-gate 	 */
7007c478bd9Sstevel@tonic-gate 	DBG(DBG_TLU, NULL,
7017c478bd9Sstevel@tonic-gate 	    "tlu_init - TLU_CORRECTABLE_ERROR_LOG_ENABLE: 0x%llx\n",
7027c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, TLU_CORRECTABLE_ERROR_LOG_ENABLE));
7037c478bd9Sstevel@tonic-gate 
7047c478bd9Sstevel@tonic-gate 	/*
7057c478bd9Sstevel@tonic-gate 	 * CSR_V TLU_CORRECTABLE_ERROR_INTERRUPT_ENABLE Kernel 0x11C1000011C1
7067c478bd9Sstevel@tonic-gate 	 */
7077c478bd9Sstevel@tonic-gate 	DBG(DBG_TLU, NULL,
7087c478bd9Sstevel@tonic-gate 	    "tlu_init - TLU_CORRECTABLE_ERROR_INTERRUPT_ENABLE: 0x%llx\n",
7097c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, TLU_CORRECTABLE_ERROR_INTERRUPT_ENABLE));
7107c478bd9Sstevel@tonic-gate 
7117c478bd9Sstevel@tonic-gate 	/*
7127c478bd9Sstevel@tonic-gate 	 * CSR_V TLU_CORRECTABLE_ERROR_INTERRUPT_STATUS Expect HW 0x0
7137c478bd9Sstevel@tonic-gate 	 */
7147c478bd9Sstevel@tonic-gate 	DBG(DBG_TLU, NULL,
7157c478bd9Sstevel@tonic-gate 	    "tlu_init - TLU_CORRECTABLE_ERROR_INTERRUPT_STATUS: 0x%llx\n",
7167c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, TLU_CORRECTABLE_ERROR_INTERRUPT_STATUS));
7177c478bd9Sstevel@tonic-gate 
7187c478bd9Sstevel@tonic-gate 	/*
7197c478bd9Sstevel@tonic-gate 	 * CSR_V TLU_CORRECTABLE_ERROR_STATUS_CLEAR Expect HW 0x0
7207c478bd9Sstevel@tonic-gate 	 */
7217c478bd9Sstevel@tonic-gate 	DBG(DBG_TLU, NULL,
7227c478bd9Sstevel@tonic-gate 	    "tlu_init - TLU_CORRECTABLE_ERROR_STATUS_CLEAR: 0x%llx\n",
7237c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, TLU_CORRECTABLE_ERROR_STATUS_CLEAR));
7247c478bd9Sstevel@tonic-gate }
7257c478bd9Sstevel@tonic-gate 
7267510e228Sess /* ARGSUSED */
7277c478bd9Sstevel@tonic-gate static void
7287c478bd9Sstevel@tonic-gate lpu_init(caddr_t csr_base, pxu_t *pxu_p)
7297c478bd9Sstevel@tonic-gate {
7307c478bd9Sstevel@tonic-gate 	/* Variables used to set the ACKNAK Latency Timer and Replay Timer */
7317c478bd9Sstevel@tonic-gate 	int link_width, max_payload;
7327c478bd9Sstevel@tonic-gate 
7337c478bd9Sstevel@tonic-gate 	uint64_t val;
7347c478bd9Sstevel@tonic-gate 
7357c478bd9Sstevel@tonic-gate 	/*
7367c478bd9Sstevel@tonic-gate 	 * Get the Link Width.  See table above LINK_WIDTH_ARR_SIZE #define
7377c478bd9Sstevel@tonic-gate 	 * Only Link Widths of x1, x4, and x8 are supported.
7387c478bd9Sstevel@tonic-gate 	 * If any width is reported other than x8, set default to x8.
7397c478bd9Sstevel@tonic-gate 	 */
7407c478bd9Sstevel@tonic-gate 	link_width = CSR_FR(csr_base, TLU_LINK_STATUS, WIDTH);
7417c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - Link Width: x%d\n", link_width);
7427c478bd9Sstevel@tonic-gate 
7437c478bd9Sstevel@tonic-gate 	/*
7447c478bd9Sstevel@tonic-gate 	 * Convert link_width to match timer array configuration.
7457c478bd9Sstevel@tonic-gate 	 */
7467c478bd9Sstevel@tonic-gate 	switch (link_width) {
7477c478bd9Sstevel@tonic-gate 	case 1:
7487c478bd9Sstevel@tonic-gate 		link_width = 0;
7497c478bd9Sstevel@tonic-gate 		break;
7507c478bd9Sstevel@tonic-gate 	case 4:
7517c478bd9Sstevel@tonic-gate 		link_width = 1;
7527c478bd9Sstevel@tonic-gate 		break;
7537c478bd9Sstevel@tonic-gate 	case 8:
7547c478bd9Sstevel@tonic-gate 		link_width = 2;
7557c478bd9Sstevel@tonic-gate 		break;
7567c478bd9Sstevel@tonic-gate 	case 16:
7577c478bd9Sstevel@tonic-gate 		link_width = 3;
7587c478bd9Sstevel@tonic-gate 		break;
7597c478bd9Sstevel@tonic-gate 	default:
7607c478bd9Sstevel@tonic-gate 		link_width = 0;
7617c478bd9Sstevel@tonic-gate 	}
7627c478bd9Sstevel@tonic-gate 
7637c478bd9Sstevel@tonic-gate 	/*
7647c478bd9Sstevel@tonic-gate 	 * Get the Max Payload Size.
7657c478bd9Sstevel@tonic-gate 	 * See table above LINK_MAX_PKT_ARR_SIZE #define
7667c478bd9Sstevel@tonic-gate 	 */
7677c478bd9Sstevel@tonic-gate 	max_payload = ((CSR_FR(csr_base, TLU_CONTROL, CONFIG) &
7687c478bd9Sstevel@tonic-gate 	    TLU_CONTROL_MPS_MASK) >> TLU_CONTROL_MPS_SHIFT);
7697c478bd9Sstevel@tonic-gate 
7707c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - May Payload: %d\n",
7717c478bd9Sstevel@tonic-gate 	    (0x80 << max_payload));
7727c478bd9Sstevel@tonic-gate 
7737c478bd9Sstevel@tonic-gate 	/* Make sure the packet size is not greater than 4096 */
7747c478bd9Sstevel@tonic-gate 	max_payload = (max_payload >= LINK_MAX_PKT_ARR_SIZE) ?
7757c478bd9Sstevel@tonic-gate 	    (LINK_MAX_PKT_ARR_SIZE - 1) : max_payload;
7767c478bd9Sstevel@tonic-gate 
7777c478bd9Sstevel@tonic-gate 	/*
7787c478bd9Sstevel@tonic-gate 	 * CSR_V LPU_ID Expect HW 0x0
7797c478bd9Sstevel@tonic-gate 	 */
7807c478bd9Sstevel@tonic-gate 
7817c478bd9Sstevel@tonic-gate 	/*
7827c478bd9Sstevel@tonic-gate 	 * This register has link id, phy id and gigablaze id.
7837c478bd9Sstevel@tonic-gate 	 * Should be set by HW.
7847c478bd9Sstevel@tonic-gate 	 */
7857c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - LPU_ID: 0x%llx\n",
7867c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_ID));
7877c478bd9Sstevel@tonic-gate 
7887c478bd9Sstevel@tonic-gate 	/*
7897c478bd9Sstevel@tonic-gate 	 * CSR_V LPU_RESET Expect Kernel 0x0
7907c478bd9Sstevel@tonic-gate 	 */
7917c478bd9Sstevel@tonic-gate 
7927c478bd9Sstevel@tonic-gate 	/*
7937c478bd9Sstevel@tonic-gate 	 * No reason to have any reset bits high until an error is
7947c478bd9Sstevel@tonic-gate 	 * detected on the link.
7957c478bd9Sstevel@tonic-gate 	 */
7967c478bd9Sstevel@tonic-gate 	val = 0ull;
7977c478bd9Sstevel@tonic-gate 	CSR_XS(csr_base, LPU_RESET, val);
7987c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - LPU_RESET: 0x%llx\n",
7997c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_RESET));
8007c478bd9Sstevel@tonic-gate 
8017c478bd9Sstevel@tonic-gate 	/*
8027c478bd9Sstevel@tonic-gate 	 * CSR_V LPU_DEBUG_STATUS Expect HW 0x0
8037c478bd9Sstevel@tonic-gate 	 */
8047c478bd9Sstevel@tonic-gate 
8057c478bd9Sstevel@tonic-gate 	/*
8067c478bd9Sstevel@tonic-gate 	 * Bits [15:8] are Debug B, and bit [7:0] are Debug A.
8077c478bd9Sstevel@tonic-gate 	 * They are read-only.  What do the 8 bits mean, and
8087c478bd9Sstevel@tonic-gate 	 * how do they get set if they are read only?
8097c478bd9Sstevel@tonic-gate 	 */
8107c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - LPU_DEBUG_STATUS: 0x%llx\n",
8117c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_DEBUG_STATUS));
8127c478bd9Sstevel@tonic-gate 
8137c478bd9Sstevel@tonic-gate 	/*
8147c478bd9Sstevel@tonic-gate 	 * CSR_V LPU_DEBUG_CONFIG Expect Kernel 0x0
8157c478bd9Sstevel@tonic-gate 	 */
8167c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - LPU_DEBUG_CONFIG: 0x%llx\n",
8177c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_DEBUG_CONFIG));
8187c478bd9Sstevel@tonic-gate 
8197c478bd9Sstevel@tonic-gate 	/*
8207c478bd9Sstevel@tonic-gate 	 * CSR_V LPU_LTSSM_CONTROL Expect HW 0x0
8217c478bd9Sstevel@tonic-gate 	 */
8227c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - LPU_LTSSM_CONTROL: 0x%llx\n",
8237c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_LTSSM_CONTROL));
8247c478bd9Sstevel@tonic-gate 
8257c478bd9Sstevel@tonic-gate 	/*
8267c478bd9Sstevel@tonic-gate 	 * CSR_V LPU_LINK_STATUS Expect HW 0x101
8277c478bd9Sstevel@tonic-gate 	 */
8287c478bd9Sstevel@tonic-gate 
8297c478bd9Sstevel@tonic-gate 	/*
8307c478bd9Sstevel@tonic-gate 	 * This register has bits [9:4] for link width, and the
8317c478bd9Sstevel@tonic-gate 	 * default 0x10, means a width of x16.  The problem is
8327c478bd9Sstevel@tonic-gate 	 * this width is not supported according to the TLU
8337c478bd9Sstevel@tonic-gate 	 * link status register.
8347c478bd9Sstevel@tonic-gate 	 */
8357c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - LPU_LINK_STATUS: 0x%llx\n",
8367c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_LINK_STATUS));
8377c478bd9Sstevel@tonic-gate 
8387c478bd9Sstevel@tonic-gate 	/*
8397c478bd9Sstevel@tonic-gate 	 * CSR_V LPU_INTERRUPT_STATUS Expect HW 0x0
8407c478bd9Sstevel@tonic-gate 	 */
8417c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - LPU_INTERRUPT_STATUS: 0x%llx\n",
8427c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_INTERRUPT_STATUS));
8437c478bd9Sstevel@tonic-gate 
8447c478bd9Sstevel@tonic-gate 	/*
8457c478bd9Sstevel@tonic-gate 	 * CSR_V LPU_INTERRUPT_MASK Expect HW 0x0
8467c478bd9Sstevel@tonic-gate 	 */
8477c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - LPU_INTERRUPT_MASK: 0x%llx\n",
8487c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_INTERRUPT_MASK));
8497c478bd9Sstevel@tonic-gate 
8507c478bd9Sstevel@tonic-gate 	/*
8517c478bd9Sstevel@tonic-gate 	 * CSR_V LPU_LINK_PERFORMANCE_COUNTER_SELECT Expect HW 0x0
8527c478bd9Sstevel@tonic-gate 	 */
8537c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
8547c478bd9Sstevel@tonic-gate 	    "lpu_init - LPU_LINK_PERFORMANCE_COUNTER_SELECT: 0x%llx\n",
8557c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_LINK_PERFORMANCE_COUNTER_SELECT));
8567c478bd9Sstevel@tonic-gate 
8577c478bd9Sstevel@tonic-gate 	/*
8587c478bd9Sstevel@tonic-gate 	 * CSR_V LPU_LINK_PERFORMANCE_COUNTER_CONTROL Expect HW 0x0
8597c478bd9Sstevel@tonic-gate 	 */
8607c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
8617c478bd9Sstevel@tonic-gate 	    "lpu_init - LPU_LINK_PERFORMANCE_COUNTER_CONTROL: 0x%llx\n",
8627c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_LINK_PERFORMANCE_COUNTER_CONTROL));
8637c478bd9Sstevel@tonic-gate 
8647c478bd9Sstevel@tonic-gate 	/*
8657c478bd9Sstevel@tonic-gate 	 * CSR_V LPU_LINK_PERFORMANCE_COUNTER1 Expect HW 0x0
8667c478bd9Sstevel@tonic-gate 	 */
8677c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
8687c478bd9Sstevel@tonic-gate 	    "lpu_init - LPU_LINK_PERFORMANCE_COUNTER1: 0x%llx\n",
8697c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_LINK_PERFORMANCE_COUNTER1));
8707c478bd9Sstevel@tonic-gate 
8717c478bd9Sstevel@tonic-gate 	/*
8727c478bd9Sstevel@tonic-gate 	 * CSR_V LPU_LINK_PERFORMANCE_COUNTER1_TEST Expect HW 0x0
8737c478bd9Sstevel@tonic-gate 	 */
8747c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
8757c478bd9Sstevel@tonic-gate 	    "lpu_init - LPU_LINK_PERFORMANCE_COUNTER1_TEST: 0x%llx\n",
8767c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_LINK_PERFORMANCE_COUNTER1_TEST));
8777c478bd9Sstevel@tonic-gate 
8787c478bd9Sstevel@tonic-gate 	/*
8797c478bd9Sstevel@tonic-gate 	 * CSR_V LPU_LINK_PERFORMANCE_COUNTER2 Expect HW 0x0
8807c478bd9Sstevel@tonic-gate 	 */
8817c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
8827c478bd9Sstevel@tonic-gate 	    "lpu_init - LPU_LINK_PERFORMANCE_COUNTER2: 0x%llx\n",
8837c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_LINK_PERFORMANCE_COUNTER2));
8847c478bd9Sstevel@tonic-gate 
8857c478bd9Sstevel@tonic-gate 	/*
8867c478bd9Sstevel@tonic-gate 	 * CSR_V LPU_LINK_PERFORMANCE_COUNTER2_TEST Expect HW 0x0
8877c478bd9Sstevel@tonic-gate 	 */
8887c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
8897c478bd9Sstevel@tonic-gate 	    "lpu_init - LPU_LINK_PERFORMANCE_COUNTER2_TEST: 0x%llx\n",
8907c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_LINK_PERFORMANCE_COUNTER2_TEST));
8917c478bd9Sstevel@tonic-gate 
8927c478bd9Sstevel@tonic-gate 	/*
8937c478bd9Sstevel@tonic-gate 	 * CSR_V LPU_LINK_LAYER_CONFIG Expect HW 0x100
8947c478bd9Sstevel@tonic-gate 	 */
8957c478bd9Sstevel@tonic-gate 
8967c478bd9Sstevel@tonic-gate 	/*
8977c478bd9Sstevel@tonic-gate 	 * This is another place where Max Payload can be set,
8987c478bd9Sstevel@tonic-gate 	 * this time for the link layer.  It will be set to
8997c478bd9Sstevel@tonic-gate 	 * 128B, which is the default, but this will need to
9007c478bd9Sstevel@tonic-gate 	 * be revisited.
9017c478bd9Sstevel@tonic-gate 	 */
9027c478bd9Sstevel@tonic-gate 	val = (1ull << LPU_LINK_LAYER_CONFIG_VC0_EN);
9037c478bd9Sstevel@tonic-gate 	CSR_XS(csr_base, LPU_LINK_LAYER_CONFIG, val);
9047c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - LPU_LINK_LAYER_CONFIG: 0x%llx\n",
9057c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_LINK_LAYER_CONFIG));
9067c478bd9Sstevel@tonic-gate 
9077c478bd9Sstevel@tonic-gate 	/*
9087c478bd9Sstevel@tonic-gate 	 * CSR_V LPU_LINK_LAYER_STATUS Expect OBP 0x5
9097c478bd9Sstevel@tonic-gate 	 */
9107c478bd9Sstevel@tonic-gate 
9117c478bd9Sstevel@tonic-gate 	/*
9127c478bd9Sstevel@tonic-gate 	 * Another R/W status register.  Bit 3, DL up Status, will
9137c478bd9Sstevel@tonic-gate 	 * be set high.  The link state machine status bits [2:0]
9147c478bd9Sstevel@tonic-gate 	 * are set to 0x1, but the status bits are not defined in the
9157c478bd9Sstevel@tonic-gate 	 * PRM.  What does 0x1 mean, what others values are possible
9167c478bd9Sstevel@tonic-gate 	 * and what are thier meanings?
9177c478bd9Sstevel@tonic-gate 	 *
9187c478bd9Sstevel@tonic-gate 	 * This register has been giving us problems in simulation.
9197c478bd9Sstevel@tonic-gate 	 * It has been mentioned that software should not program
9207c478bd9Sstevel@tonic-gate 	 * any registers with WE bits except during debug.  So
9217c478bd9Sstevel@tonic-gate 	 * this register will no longer be programmed.
9227c478bd9Sstevel@tonic-gate 	 */
9237c478bd9Sstevel@tonic-gate 
9247c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - LPU_LINK_LAYER_STATUS: 0x%llx\n",
9257c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_LINK_LAYER_STATUS));
9267c478bd9Sstevel@tonic-gate 
9277c478bd9Sstevel@tonic-gate 	/*
9287c478bd9Sstevel@tonic-gate 	 * CSR_V LPU_LINK_LAYER_INTERRUPT_AND_STATUS_TEST Expect HW 0x0
9297c478bd9Sstevel@tonic-gate 	 */
9307c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
9317c478bd9Sstevel@tonic-gate 	    "lpu_init - LPU_LINK_LAYER_INTERRUPT_AND_STATUS_TEST: 0x%llx\n",
9327c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_LINK_LAYER_INTERRUPT_AND_STATUS_TEST));
9337c478bd9Sstevel@tonic-gate 
9347c478bd9Sstevel@tonic-gate 	/*
935f8d2de6bSjchu 	 * CSR_V LPU Link Layer interrupt regs (mask, status)
9367c478bd9Sstevel@tonic-gate 	 */
9377c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
9387c478bd9Sstevel@tonic-gate 	    "lpu_init - LPU_LINK_LAYER_INTERRUPT_MASK: 0x%llx\n",
9397c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_LINK_LAYER_INTERRUPT_MASK));
9407c478bd9Sstevel@tonic-gate 
941f8d2de6bSjchu 	DBG(DBG_LPU, NULL,
942f8d2de6bSjchu 	    "lpu_init - LPU_LINK_LAYER_INTERRUPT_AND_STATUS: 0x%llx\n",
943f8d2de6bSjchu 	    CSR_XR(csr_base, LPU_LINK_LAYER_INTERRUPT_AND_STATUS));
944f8d2de6bSjchu 
9457c478bd9Sstevel@tonic-gate 	/*
9467c478bd9Sstevel@tonic-gate 	 * CSR_V LPU_FLOW_CONTROL_UPDATE_CONTROL Expect OBP 0x7
9477c478bd9Sstevel@tonic-gate 	 */
9487c478bd9Sstevel@tonic-gate 
9497c478bd9Sstevel@tonic-gate 	/*
9507c478bd9Sstevel@tonic-gate 	 * The PRM says that only the first two bits will be set
9517c478bd9Sstevel@tonic-gate 	 * high by default, which will enable flow control for
9527c478bd9Sstevel@tonic-gate 	 * posted and non-posted updates, but NOT completetion
9537c478bd9Sstevel@tonic-gate 	 * updates.
9547c478bd9Sstevel@tonic-gate 	 */
9557c478bd9Sstevel@tonic-gate 	val = (1ull << LPU_FLOW_CONTROL_UPDATE_CONTROL_FC0_U_NP_EN) |
9567c478bd9Sstevel@tonic-gate 	    (1ull << LPU_FLOW_CONTROL_UPDATE_CONTROL_FC0_U_P_EN);
9577c478bd9Sstevel@tonic-gate 	CSR_XS(csr_base, LPU_FLOW_CONTROL_UPDATE_CONTROL, val);
9587c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
9597c478bd9Sstevel@tonic-gate 	    "lpu_init - LPU_FLOW_CONTROL_UPDATE_CONTROL: 0x%llx\n",
9607c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_FLOW_CONTROL_UPDATE_CONTROL));
9617c478bd9Sstevel@tonic-gate 
9627c478bd9Sstevel@tonic-gate 	/*
9637c478bd9Sstevel@tonic-gate 	 * CSR_V LPU_LINK_LAYER_FLOW_CONTROL_UPDATE_TIMEOUT_VALUE
9647c478bd9Sstevel@tonic-gate 	 * Expect OBP 0x1D4C
9657c478bd9Sstevel@tonic-gate 	 */
9667c478bd9Sstevel@tonic-gate 
9677c478bd9Sstevel@tonic-gate 	/*
9687c478bd9Sstevel@tonic-gate 	 * This should be set by OBP.  We'll check to make sure.
9697c478bd9Sstevel@tonic-gate 	 */
970f8d2de6bSjchu 	DBG(DBG_LPU, NULL, "lpu_init - "
9717c478bd9Sstevel@tonic-gate 	    "LPU_LINK_LAYER_FLOW_CONTROL_UPDATE_TIMEOUT_VALUE: 0x%llx\n",
9727c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base,
9737c478bd9Sstevel@tonic-gate 	    LPU_LINK_LAYER_FLOW_CONTROL_UPDATE_TIMEOUT_VALUE));
9747c478bd9Sstevel@tonic-gate 
9757c478bd9Sstevel@tonic-gate 	/*
9767c478bd9Sstevel@tonic-gate 	 * CSR_V LPU_LINK_LAYER_VC0_FLOW_CONTROL_UPDATE_TIMER0 Expect OBP ???
9777c478bd9Sstevel@tonic-gate 	 */
9787c478bd9Sstevel@tonic-gate 
9797c478bd9Sstevel@tonic-gate 	/*
9807c478bd9Sstevel@tonic-gate 	 * This register has Flow Control Update Timer values for
9817c478bd9Sstevel@tonic-gate 	 * non-posted and posted requests, bits [30:16] and bits
9827c478bd9Sstevel@tonic-gate 	 * [14:0], respectively.  These are read-only to SW so
9837c478bd9Sstevel@tonic-gate 	 * either HW or OBP needs to set them.
9847c478bd9Sstevel@tonic-gate 	 */
985f8d2de6bSjchu 	DBG(DBG_LPU, NULL, "lpu_init - "
9867c478bd9Sstevel@tonic-gate 	    "LPU_LINK_LAYER_VC0_FLOW_CONTROL_UPDATE_TIMER0: 0x%llx\n",
9877c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base,
9887c478bd9Sstevel@tonic-gate 	    LPU_LINK_LAYER_VC0_FLOW_CONTROL_UPDATE_TIMER0));
9897c478bd9Sstevel@tonic-gate 
9907c478bd9Sstevel@tonic-gate 	/*
9917c478bd9Sstevel@tonic-gate 	 * CSR_V LPU_LINK_LAYER_VC0_FLOW_CONTROL_UPDATE_TIMER1 Expect OBP ???
9927c478bd9Sstevel@tonic-gate 	 */
9937c478bd9Sstevel@tonic-gate 
9947c478bd9Sstevel@tonic-gate 	/*
9957c478bd9Sstevel@tonic-gate 	 * Same as timer0 register above, except for bits [14:0]
9967c478bd9Sstevel@tonic-gate 	 * have the timer values for completetions.  Read-only to
9977c478bd9Sstevel@tonic-gate 	 * SW; OBP or HW need to set it.
9987c478bd9Sstevel@tonic-gate 	 */
999f8d2de6bSjchu 	DBG(DBG_LPU, NULL, "lpu_init - "
10007c478bd9Sstevel@tonic-gate 	    "LPU_LINK_LAYER_VC0_FLOW_CONTROL_UPDATE_TIMER1: 0x%llx\n",
10017c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base,
10027c478bd9Sstevel@tonic-gate 	    LPU_LINK_LAYER_VC0_FLOW_CONTROL_UPDATE_TIMER1));
10037c478bd9Sstevel@tonic-gate 
10047c478bd9Sstevel@tonic-gate 	/*
10057c478bd9Sstevel@tonic-gate 	 * CSR_V LPU_TXLINK_FREQUENT_NAK_LATENCY_TIMER_THRESHOLD
10067c478bd9Sstevel@tonic-gate 	 */
10070114761dSAlan Adamson, SD OSSD 	val = px_acknak_timer_table[max_payload][link_width];
10087510e228Sess 	CSR_XS(csr_base, LPU_TXLINK_FREQUENT_NAK_LATENCY_TIMER_THRESHOLD, val);
10097c478bd9Sstevel@tonic-gate 
10107c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - "
10117c478bd9Sstevel@tonic-gate 	    "LPU_TXLINK_FREQUENT_NAK_LATENCY_TIMER_THRESHOLD: 0x%llx\n",
10127c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_TXLINK_FREQUENT_NAK_LATENCY_TIMER_THRESHOLD));
10137c478bd9Sstevel@tonic-gate 
10147c478bd9Sstevel@tonic-gate 	/*
10157c478bd9Sstevel@tonic-gate 	 * CSR_V LPU_TXLINK_ACKNAK_LATENCY_TIMER Expect HW 0x0
10167c478bd9Sstevel@tonic-gate 	 */
10177c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
10187c478bd9Sstevel@tonic-gate 	    "lpu_init - LPU_TXLINK_ACKNAK_LATENCY_TIMER: 0x%llx\n",
10197c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_TXLINK_ACKNAK_LATENCY_TIMER));
10207c478bd9Sstevel@tonic-gate 
10217c478bd9Sstevel@tonic-gate 	/*
10227c478bd9Sstevel@tonic-gate 	 * CSR_V LPU_TXLINK_REPLAY_TIMER_THRESHOLD
10237c478bd9Sstevel@tonic-gate 	 */
10240114761dSAlan Adamson, SD OSSD 	val = px_replay_timer_table[max_payload][link_width];
10257c478bd9Sstevel@tonic-gate 	CSR_XS(csr_base, LPU_TXLINK_REPLAY_TIMER_THRESHOLD, val);
10267c478bd9Sstevel@tonic-gate 
10277c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
10287c478bd9Sstevel@tonic-gate 	    "lpu_init - LPU_TXLINK_REPLAY_TIMER_THRESHOLD: 0x%llx\n",
10297c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_TXLINK_REPLAY_TIMER_THRESHOLD));
10307c478bd9Sstevel@tonic-gate 
10317c478bd9Sstevel@tonic-gate 	/*
10327c478bd9Sstevel@tonic-gate 	 * CSR_V LPU_TXLINK_REPLAY_TIMER Expect HW 0x0
10337c478bd9Sstevel@tonic-gate 	 */
10347c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - LPU_TXLINK_REPLAY_TIMER: 0x%llx\n",
10357c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_TXLINK_REPLAY_TIMER));
10367c478bd9Sstevel@tonic-gate 
10377c478bd9Sstevel@tonic-gate 	/*
10387c478bd9Sstevel@tonic-gate 	 * CSR_V LPU_TXLINK_REPLAY_NUMBER_STATUS Expect OBP 0x3
10397c478bd9Sstevel@tonic-gate 	 */
10407c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
10417c478bd9Sstevel@tonic-gate 	    "lpu_init - LPU_TXLINK_REPLAY_NUMBER_STATUS: 0x%llx\n",
10427c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_TXLINK_REPLAY_NUMBER_STATUS));
10437c478bd9Sstevel@tonic-gate 
10447c478bd9Sstevel@tonic-gate 	/*
10457c478bd9Sstevel@tonic-gate 	 * CSR_V LPU_REPLAY_BUFFER_MAX_ADDRESS Expect OBP 0xB3F
10467c478bd9Sstevel@tonic-gate 	 */
10477c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
10487c478bd9Sstevel@tonic-gate 	    "lpu_init - LPU_REPLAY_BUFFER_MAX_ADDRESS: 0x%llx\n",
10497c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_REPLAY_BUFFER_MAX_ADDRESS));
10507c478bd9Sstevel@tonic-gate 
10517c478bd9Sstevel@tonic-gate 	/*
10527c478bd9Sstevel@tonic-gate 	 * CSR_V LPU_TXLINK_RETRY_FIFO_POINTER Expect OBP 0xFFFF0000
10537c478bd9Sstevel@tonic-gate 	 */
10547c478bd9Sstevel@tonic-gate 	val = ((LPU_TXLINK_RETRY_FIFO_POINTER_RTRY_FIFO_TLPTR_DEFAULT <<
10557c478bd9Sstevel@tonic-gate 	    LPU_TXLINK_RETRY_FIFO_POINTER_RTRY_FIFO_TLPTR) |
10567c478bd9Sstevel@tonic-gate 	    (LPU_TXLINK_RETRY_FIFO_POINTER_RTRY_FIFO_HDPTR_DEFAULT <<
10577c478bd9Sstevel@tonic-gate 	    LPU_TXLINK_RETRY_FIFO_POINTER_RTRY_FIFO_HDPTR));
10587c478bd9Sstevel@tonic-gate 
10597c478bd9Sstevel@tonic-gate 	CSR_XS(csr_base, LPU_TXLINK_RETRY_FIFO_POINTER, val);
10607c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
10617c478bd9Sstevel@tonic-gate 	    "lpu_init - LPU_TXLINK_RETRY_FIFO_POINTER: 0x%llx\n",
10627c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_TXLINK_RETRY_FIFO_POINTER));
10637c478bd9Sstevel@tonic-gate 
10647c478bd9Sstevel@tonic-gate 	/*
10657c478bd9Sstevel@tonic-gate 	 * CSR_V LPU_TXLINK_RETRY_FIFO_R_W_POINTER Expect OBP 0x0
10667c478bd9Sstevel@tonic-gate 	 */
10677c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
10687c478bd9Sstevel@tonic-gate 	    "lpu_init - LPU_TXLINK_RETRY_FIFO_R_W_POINTER: 0x%llx\n",
10697c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_TXLINK_RETRY_FIFO_R_W_POINTER));
10707c478bd9Sstevel@tonic-gate 
10717c478bd9Sstevel@tonic-gate 	/*
10727c478bd9Sstevel@tonic-gate 	 * CSR_V LPU_TXLINK_RETRY_FIFO_CREDIT Expect HW 0x1580
10737c478bd9Sstevel@tonic-gate 	 */
10747c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
10757c478bd9Sstevel@tonic-gate 	    "lpu_init - LPU_TXLINK_RETRY_FIFO_CREDIT: 0x%llx\n",
10767c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_TXLINK_RETRY_FIFO_CREDIT));
10777c478bd9Sstevel@tonic-gate 
10787c478bd9Sstevel@tonic-gate 	/*
10797c478bd9Sstevel@tonic-gate 	 * CSR_V LPU_TXLINK_SEQUENCE_COUNTER Expect OBP 0xFFF0000
10807c478bd9Sstevel@tonic-gate 	 */
10817c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - LPU_TXLINK_SEQUENCE_COUNTER: 0x%llx\n",
10827c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_TXLINK_SEQUENCE_COUNTER));
10837c478bd9Sstevel@tonic-gate 
10847c478bd9Sstevel@tonic-gate 	/*
10857c478bd9Sstevel@tonic-gate 	 * CSR_V LPU_TXLINK_ACK_SENT_SEQUENCE_NUMBER Expect HW 0xFFF
10867c478bd9Sstevel@tonic-gate 	 */
10877c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
10887c478bd9Sstevel@tonic-gate 	    "lpu_init - LPU_TXLINK_ACK_SENT_SEQUENCE_NUMBER: 0x%llx\n",
10897c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_TXLINK_ACK_SENT_SEQUENCE_NUMBER));
10907c478bd9Sstevel@tonic-gate 
10917c478bd9Sstevel@tonic-gate 	/*
10927c478bd9Sstevel@tonic-gate 	 * CSR_V LPU_TXLINK_SEQUENCE_COUNT_FIFO_MAX_ADDR Expect OBP 0x157
10937c478bd9Sstevel@tonic-gate 	 */
10947c478bd9Sstevel@tonic-gate 
10957c478bd9Sstevel@tonic-gate 	/*
10967c478bd9Sstevel@tonic-gate 	 * Test only register.  Will not be programmed.
10977c478bd9Sstevel@tonic-gate 	 */
10987c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
10997c478bd9Sstevel@tonic-gate 	    "lpu_init - LPU_TXLINK_SEQUENCE_COUNT_FIFO_MAX_ADDR: 0x%llx\n",
11007c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_TXLINK_SEQUENCE_COUNT_FIFO_MAX_ADDR));
11017c478bd9Sstevel@tonic-gate 
11027c478bd9Sstevel@tonic-gate 	/*
11037c478bd9Sstevel@tonic-gate 	 * CSR_V LPU_TXLINK_SEQUENCE_COUNT_FIFO_POINTERS Expect HW 0xFFF0000
11047c478bd9Sstevel@tonic-gate 	 */
11057c478bd9Sstevel@tonic-gate 
11067c478bd9Sstevel@tonic-gate 	/*
11077c478bd9Sstevel@tonic-gate 	 * Test only register.  Will not be programmed.
11087c478bd9Sstevel@tonic-gate 	 */
11097c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
11107c478bd9Sstevel@tonic-gate 	    "lpu_init - LPU_TXLINK_SEQUENCE_COUNT_FIFO_POINTERS: 0x%llx\n",
11117c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_TXLINK_SEQUENCE_COUNT_FIFO_POINTERS));
11127c478bd9Sstevel@tonic-gate 
11137c478bd9Sstevel@tonic-gate 	/*
11147c478bd9Sstevel@tonic-gate 	 * CSR_V LPU_TXLINK_SEQUENCE_COUNT_R_W_POINTERS Expect HW 0x0
11157c478bd9Sstevel@tonic-gate 	 */
11167c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
11177c478bd9Sstevel@tonic-gate 	    "lpu_init - LPU_TXLINK_SEQUENCE_COUNT_R_W_POINTERS: 0x%llx\n",
11187c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_TXLINK_SEQUENCE_COUNT_R_W_POINTERS));
11197c478bd9Sstevel@tonic-gate 
11207c478bd9Sstevel@tonic-gate 	/*
11217c478bd9Sstevel@tonic-gate 	 * CSR_V LPU_TXLINK_TEST_CONTROL Expect HW 0x0
11227c478bd9Sstevel@tonic-gate 	 */
11237c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - LPU_TXLINK_TEST_CONTROL: 0x%llx\n",
11247c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_TXLINK_TEST_CONTROL));
11257c478bd9Sstevel@tonic-gate 
11267c478bd9Sstevel@tonic-gate 	/*
11277c478bd9Sstevel@tonic-gate 	 * CSR_V LPU_TXLINK_MEMORY_ADDRESS_CONTROL Expect HW 0x0
11287c478bd9Sstevel@tonic-gate 	 */
11297c478bd9Sstevel@tonic-gate 
11307c478bd9Sstevel@tonic-gate 	/*
11317c478bd9Sstevel@tonic-gate 	 * Test only register.  Will not be programmed.
11327c478bd9Sstevel@tonic-gate 	 */
11337c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
11347c478bd9Sstevel@tonic-gate 	    "lpu_init - LPU_TXLINK_MEMORY_ADDRESS_CONTROL: 0x%llx\n",
11357c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_TXLINK_MEMORY_ADDRESS_CONTROL));
11367c478bd9Sstevel@tonic-gate 
11377c478bd9Sstevel@tonic-gate 	/*
11387c478bd9Sstevel@tonic-gate 	 * CSR_V LPU_TXLINK_MEMORY_DATA_LOAD0 Expect HW 0x0
11397c478bd9Sstevel@tonic-gate 	 */
11407c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
11417c478bd9Sstevel@tonic-gate 	    "lpu_init - LPU_TXLINK_MEMORY_DATA_LOAD0: 0x%llx\n",
11427c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_TXLINK_MEMORY_DATA_LOAD0));
11437c478bd9Sstevel@tonic-gate 
11447c478bd9Sstevel@tonic-gate 	/*
11457c478bd9Sstevel@tonic-gate 	 * CSR_V LPU_TXLINK_MEMORY_DATA_LOAD1 Expect HW 0x0
11467c478bd9Sstevel@tonic-gate 	 */
11477c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
11487c478bd9Sstevel@tonic-gate 	    "lpu_init - LPU_TXLINK_MEMORY_DATA_LOAD1: 0x%llx\n",
11497c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_TXLINK_MEMORY_DATA_LOAD1));
11507c478bd9Sstevel@tonic-gate 
11517c478bd9Sstevel@tonic-gate 	/*
11527c478bd9Sstevel@tonic-gate 	 * CSR_V LPU_TXLINK_MEMORY_DATA_LOAD2 Expect HW 0x0
11537c478bd9Sstevel@tonic-gate 	 */
11547c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
11557c478bd9Sstevel@tonic-gate 	    "lpu_init - LPU_TXLINK_MEMORY_DATA_LOAD2: 0x%llx\n",
11567c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_TXLINK_MEMORY_DATA_LOAD2));
11577c478bd9Sstevel@tonic-gate 
11587c478bd9Sstevel@tonic-gate 	/*
11597c478bd9Sstevel@tonic-gate 	 * CSR_V LPU_TXLINK_MEMORY_DATA_LOAD3 Expect HW 0x0
11607c478bd9Sstevel@tonic-gate 	 */
11617c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
11627c478bd9Sstevel@tonic-gate 	    "lpu_init - LPU_TXLINK_MEMORY_DATA_LOAD3: 0x%llx\n",
11637c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_TXLINK_MEMORY_DATA_LOAD3));
11647c478bd9Sstevel@tonic-gate 
11657c478bd9Sstevel@tonic-gate 	/*
11667c478bd9Sstevel@tonic-gate 	 * CSR_V LPU_TXLINK_MEMORY_DATA_LOAD4 Expect HW 0x0
11677c478bd9Sstevel@tonic-gate 	 */
11687c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
11697c478bd9Sstevel@tonic-gate 	    "lpu_init - LPU_TXLINK_MEMORY_DATA_LOAD4: 0x%llx\n",
11707c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_TXLINK_MEMORY_DATA_LOAD4));
11717c478bd9Sstevel@tonic-gate 
11727c478bd9Sstevel@tonic-gate 	/*
11737c478bd9Sstevel@tonic-gate 	 * CSR_V LPU_TXLINK_RETRY_DATA_COUNT Expect HW 0x0
11747c478bd9Sstevel@tonic-gate 	 */
11757c478bd9Sstevel@tonic-gate 
11767c478bd9Sstevel@tonic-gate 	/*
11777c478bd9Sstevel@tonic-gate 	 * Test only register.  Will not be programmed.
11787c478bd9Sstevel@tonic-gate 	 */
11797c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - LPU_TXLINK_RETRY_DATA_COUNT: 0x%llx\n",
11807c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_TXLINK_RETRY_DATA_COUNT));
11817c478bd9Sstevel@tonic-gate 
11827c478bd9Sstevel@tonic-gate 	/*
11837c478bd9Sstevel@tonic-gate 	 * CSR_V LPU_TXLINK_SEQUENCE_BUFFER_COUNT Expect HW 0x0
11847c478bd9Sstevel@tonic-gate 	 */
11857c478bd9Sstevel@tonic-gate 
11867c478bd9Sstevel@tonic-gate 	/*
11877c478bd9Sstevel@tonic-gate 	 * Test only register.  Will not be programmed.
11887c478bd9Sstevel@tonic-gate 	 */
11897c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
11907c478bd9Sstevel@tonic-gate 	    "lpu_init - LPU_TXLINK_SEQUENCE_BUFFER_COUNT: 0x%llx\n",
11917c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_TXLINK_SEQUENCE_BUFFER_COUNT));
11927c478bd9Sstevel@tonic-gate 
11937c478bd9Sstevel@tonic-gate 	/*
11947c478bd9Sstevel@tonic-gate 	 * CSR_V LPU_TXLINK_SEQUENCE_BUFFER_BOTTOM_DATA Expect HW 0x0
11957c478bd9Sstevel@tonic-gate 	 */
11967c478bd9Sstevel@tonic-gate 
11977c478bd9Sstevel@tonic-gate 	/*
11987c478bd9Sstevel@tonic-gate 	 * Test only register.
11997c478bd9Sstevel@tonic-gate 	 */
12007c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
12017c478bd9Sstevel@tonic-gate 	    "lpu_init - LPU_TXLINK_SEQUENCE_BUFFER_BOTTOM_DATA: 0x%llx\n",
12027c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_TXLINK_SEQUENCE_BUFFER_BOTTOM_DATA));
12037c478bd9Sstevel@tonic-gate 
12047c478bd9Sstevel@tonic-gate 	/*
12057c478bd9Sstevel@tonic-gate 	 * CSR_V LPU_RXLINK_NEXT_RECEIVE_SEQUENCE_1_COUNTER Expect HW 0x0
12067c478bd9Sstevel@tonic-gate 	 */
12077c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - "
12087c478bd9Sstevel@tonic-gate 	    "LPU_RXLINK_NEXT_RECEIVE_SEQUENCE_1_COUNTER: 0x%llx\n",
12097c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_RXLINK_NEXT_RECEIVE_SEQUENCE_1_COUNTER));
12107c478bd9Sstevel@tonic-gate 
12117c478bd9Sstevel@tonic-gate 	/*
12127c478bd9Sstevel@tonic-gate 	 * CSR_V LPU_RXLINK_UNSUPPORTED_DLLP_RECEIVED Expect HW 0x0
12137c478bd9Sstevel@tonic-gate 	 */
12147c478bd9Sstevel@tonic-gate 
12157c478bd9Sstevel@tonic-gate 	/*
12167c478bd9Sstevel@tonic-gate 	 * test only register.
12177c478bd9Sstevel@tonic-gate 	 */
12187c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
12197c478bd9Sstevel@tonic-gate 	    "lpu_init - LPU_RXLINK_UNSUPPORTED_DLLP_RECEIVED: 0x%llx\n",
12207c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_RXLINK_UNSUPPORTED_DLLP_RECEIVED));
12217c478bd9Sstevel@tonic-gate 
12227c478bd9Sstevel@tonic-gate 	/*
12237c478bd9Sstevel@tonic-gate 	 * CSR_V LPU_RXLINK_TEST_CONTROL Expect HW 0x0
12247c478bd9Sstevel@tonic-gate 	 */
12257c478bd9Sstevel@tonic-gate 
12267c478bd9Sstevel@tonic-gate 	/*
12277c478bd9Sstevel@tonic-gate 	 * test only register.
12287c478bd9Sstevel@tonic-gate 	 */
12297c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - LPU_RXLINK_TEST_CONTROL: 0x%llx\n",
12307c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_RXLINK_TEST_CONTROL));
12317c478bd9Sstevel@tonic-gate 
12327c478bd9Sstevel@tonic-gate 	/*
12337c478bd9Sstevel@tonic-gate 	 * CSR_V LPU_PHYSICAL_LAYER_CONFIGURATION Expect HW 0x10
12347c478bd9Sstevel@tonic-gate 	 */
12357c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
12367c478bd9Sstevel@tonic-gate 	    "lpu_init - LPU_PHYSICAL_LAYER_CONFIGURATION: 0x%llx\n",
12377c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_PHYSICAL_LAYER_CONFIGURATION));
12387c478bd9Sstevel@tonic-gate 
12397c478bd9Sstevel@tonic-gate 	/*
12407c478bd9Sstevel@tonic-gate 	 * CSR_V LPU_PHY_LAYER_STATUS Expect HW 0x0
12417c478bd9Sstevel@tonic-gate 	 */
12427c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - LPU_PHY_LAYER_STATUS: 0x%llx\n",
12437c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_PHY_LAYER_STATUS));
12447c478bd9Sstevel@tonic-gate 
12457c478bd9Sstevel@tonic-gate 	/*
12467c478bd9Sstevel@tonic-gate 	 * CSR_V LPU_PHY_INTERRUPT_AND_STATUS_TEST Expect HW 0x0
12477c478bd9Sstevel@tonic-gate 	 */
12487c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
12497c478bd9Sstevel@tonic-gate 	    "lpu_init - LPU_PHY_INTERRUPT_AND_STATUS_TEST: 0x%llx\n",
12507c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_PHY_INTERRUPT_AND_STATUS_TEST));
12517c478bd9Sstevel@tonic-gate 
12527c478bd9Sstevel@tonic-gate 	/*
1253f8d2de6bSjchu 	 * CSR_V LPU PHY LAYER interrupt regs (mask, status)
12547c478bd9Sstevel@tonic-gate 	 */
12557c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - LPU_PHY_INTERRUPT_MASK: 0x%llx\n",
12567c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_PHY_INTERRUPT_MASK));
12577c478bd9Sstevel@tonic-gate 
1258f8d2de6bSjchu 	DBG(DBG_LPU, NULL,
1259f8d2de6bSjchu 	    "lpu_init - LPU_PHY_LAYER_INTERRUPT_AND_STATUS: 0x%llx\n",
1260f8d2de6bSjchu 	    CSR_XR(csr_base, LPU_PHY_LAYER_INTERRUPT_AND_STATUS));
1261f8d2de6bSjchu 
12627c478bd9Sstevel@tonic-gate 	/*
12637c478bd9Sstevel@tonic-gate 	 * CSR_V LPU_RECEIVE_PHY_CONFIG Expect HW 0x0
12647c478bd9Sstevel@tonic-gate 	 */
12657c478bd9Sstevel@tonic-gate 
12667c478bd9Sstevel@tonic-gate 	/*
12677c478bd9Sstevel@tonic-gate 	 * This also needs some explanation.  What is the best value
12687c478bd9Sstevel@tonic-gate 	 * for the water mark?  Test mode enables which test mode?
12697c478bd9Sstevel@tonic-gate 	 * Programming model needed for the Receiver Reset Lane N
12707c478bd9Sstevel@tonic-gate 	 * bits.
12717c478bd9Sstevel@tonic-gate 	 */
12727c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - LPU_RECEIVE_PHY_CONFIG: 0x%llx\n",
12737c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_RECEIVE_PHY_CONFIG));
12747c478bd9Sstevel@tonic-gate 
12757c478bd9Sstevel@tonic-gate 	/*
12767c478bd9Sstevel@tonic-gate 	 * CSR_V LPU_RECEIVE_PHY_STATUS1 Expect HW 0x0
12777c478bd9Sstevel@tonic-gate 	 */
12787c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - LPU_RECEIVE_PHY_STATUS1: 0x%llx\n",
12797c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_RECEIVE_PHY_STATUS1));
12807c478bd9Sstevel@tonic-gate 
12817c478bd9Sstevel@tonic-gate 	/*
12827c478bd9Sstevel@tonic-gate 	 * CSR_V LPU_RECEIVE_PHY_STATUS2 Expect HW 0x0
12837c478bd9Sstevel@tonic-gate 	 */
12847c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - LPU_RECEIVE_PHY_STATUS2: 0x%llx\n",
12857c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_RECEIVE_PHY_STATUS2));
12867c478bd9Sstevel@tonic-gate 
12877c478bd9Sstevel@tonic-gate 	/*
12887c478bd9Sstevel@tonic-gate 	 * CSR_V LPU_RECEIVE_PHY_STATUS3 Expect HW 0x0
12897c478bd9Sstevel@tonic-gate 	 */
12907c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - LPU_RECEIVE_PHY_STATUS3: 0x%llx\n",
12917c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_RECEIVE_PHY_STATUS3));
12927c478bd9Sstevel@tonic-gate 
12937c478bd9Sstevel@tonic-gate 	/*
12947c478bd9Sstevel@tonic-gate 	 * CSR_V LPU_RECEIVE_PHY_INTERRUPT_AND_STATUS_TEST Expect HW 0x0
12957c478bd9Sstevel@tonic-gate 	 */
12967c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
12977c478bd9Sstevel@tonic-gate 	    "lpu_init - LPU_RECEIVE_PHY_INTERRUPT_AND_STATUS_TEST: 0x%llx\n",
12987c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_RECEIVE_PHY_INTERRUPT_AND_STATUS_TEST));
12997c478bd9Sstevel@tonic-gate 
13007c478bd9Sstevel@tonic-gate 	/*
1301f8d2de6bSjchu 	 * CSR_V LPU RX LAYER interrupt regs (mask, status)
13027c478bd9Sstevel@tonic-gate 	 */
13037c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
13047c478bd9Sstevel@tonic-gate 	    "lpu_init - LPU_RECEIVE_PHY_INTERRUPT_MASK: 0x%llx\n",
13057c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_RECEIVE_PHY_INTERRUPT_MASK));
13067c478bd9Sstevel@tonic-gate 
1307f8d2de6bSjchu 	DBG(DBG_LPU, NULL,
1308f8d2de6bSjchu 	    "lpu_init - LPU_RECEIVE_PHY_INTERRUPT_AND_STATUS: 0x%llx\n",
1309f8d2de6bSjchu 	    CSR_XR(csr_base, LPU_RECEIVE_PHY_INTERRUPT_AND_STATUS));
1310f8d2de6bSjchu 
13117c478bd9Sstevel@tonic-gate 	/*
13127c478bd9Sstevel@tonic-gate 	 * CSR_V LPU_TRANSMIT_PHY_CONFIG Expect HW 0x0
13137c478bd9Sstevel@tonic-gate 	 */
13147c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - LPU_TRANSMIT_PHY_CONFIG: 0x%llx\n",
13157c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_TRANSMIT_PHY_CONFIG));
13167c478bd9Sstevel@tonic-gate 
13177c478bd9Sstevel@tonic-gate 	/*
13187c478bd9Sstevel@tonic-gate 	 * CSR_V LPU_TRANSMIT_PHY_STATUS Expect HW 0x0
13197c478bd9Sstevel@tonic-gate 	 */
13207c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - LPU_TRANSMIT_PHY_STATUS: 0x%llx\n",
13217c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_TRANSMIT_PHY_STATUS));
13227c478bd9Sstevel@tonic-gate 
13237c478bd9Sstevel@tonic-gate 	/*
13247c478bd9Sstevel@tonic-gate 	 * CSR_V LPU_TRANSMIT_PHY_INTERRUPT_AND_STATUS_TEST Expect HW 0x0
13257c478bd9Sstevel@tonic-gate 	 */
13267c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
13277c478bd9Sstevel@tonic-gate 	    "lpu_init - LPU_TRANSMIT_PHY_INTERRUPT_AND_STATUS_TEST: 0x%llx\n",
13287c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base,
13297c478bd9Sstevel@tonic-gate 	    LPU_TRANSMIT_PHY_INTERRUPT_AND_STATUS_TEST));
13307c478bd9Sstevel@tonic-gate 
13317c478bd9Sstevel@tonic-gate 	/*
1332f8d2de6bSjchu 	 * CSR_V LPU TX LAYER interrupt regs (mask, status)
13337c478bd9Sstevel@tonic-gate 	 */
13347c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
13357c478bd9Sstevel@tonic-gate 	    "lpu_init - LPU_TRANSMIT_PHY_INTERRUPT_MASK: 0x%llx\n",
13367c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_TRANSMIT_PHY_INTERRUPT_MASK));
13377c478bd9Sstevel@tonic-gate 
1338f8d2de6bSjchu 	DBG(DBG_LPU, NULL,
1339f8d2de6bSjchu 	    "lpu_init - LPU_TRANSMIT_PHY_INTERRUPT_AND_STATUS: 0x%llx\n",
1340f8d2de6bSjchu 	    CSR_XR(csr_base, LPU_TRANSMIT_PHY_INTERRUPT_AND_STATUS));
1341f8d2de6bSjchu 
13427c478bd9Sstevel@tonic-gate 	/*
13437c478bd9Sstevel@tonic-gate 	 * CSR_V LPU_TRANSMIT_PHY_STATUS_2 Expect HW 0x0
13447c478bd9Sstevel@tonic-gate 	 */
13457c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - LPU_TRANSMIT_PHY_STATUS_2: 0x%llx\n",
13467c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_TRANSMIT_PHY_STATUS_2));
13477c478bd9Sstevel@tonic-gate 
13487c478bd9Sstevel@tonic-gate 	/*
13497c478bd9Sstevel@tonic-gate 	 * CSR_V LPU_LTSSM_CONFIG1 Expect OBP 0x205
13507c478bd9Sstevel@tonic-gate 	 */
13517c478bd9Sstevel@tonic-gate 
13527c478bd9Sstevel@tonic-gate 	/*
13537c478bd9Sstevel@tonic-gate 	 * The new PRM has values for LTSSM 8 ns timeout value and
13547c478bd9Sstevel@tonic-gate 	 * LTSSM 20 ns timeout value.  But what do these values mean?
13557c478bd9Sstevel@tonic-gate 	 * Most of the other bits are questions as well.
13567c478bd9Sstevel@tonic-gate 	 *
13577c478bd9Sstevel@tonic-gate 	 * As such we will use the reset value.
13587c478bd9Sstevel@tonic-gate 	 */
13597c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - LPU_LTSSM_CONFIG1: 0x%llx\n",
13607c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_LTSSM_CONFIG1));
13617c478bd9Sstevel@tonic-gate 
13627c478bd9Sstevel@tonic-gate 	/*
13637c478bd9Sstevel@tonic-gate 	 * CSR_V LPU_LTSSM_CONFIG2 Expect OBP 0x2DC6C0
13647c478bd9Sstevel@tonic-gate 	 */
13657c478bd9Sstevel@tonic-gate 
13667c478bd9Sstevel@tonic-gate 	/*
13677c478bd9Sstevel@tonic-gate 	 * Again, what does '12 ms timeout value mean'?
13687c478bd9Sstevel@tonic-gate 	 */
13697c478bd9Sstevel@tonic-gate 	val = (LPU_LTSSM_CONFIG2_LTSSM_12_TO_DEFAULT <<
13707c478bd9Sstevel@tonic-gate 	    LPU_LTSSM_CONFIG2_LTSSM_12_TO);
13717c478bd9Sstevel@tonic-gate 	CSR_XS(csr_base, LPU_LTSSM_CONFIG2, val);
13727c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - LPU_LTSSM_CONFIG2: 0x%llx\n",
13737c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_LTSSM_CONFIG2));
13747c478bd9Sstevel@tonic-gate 
13757c478bd9Sstevel@tonic-gate 	/*
13767c478bd9Sstevel@tonic-gate 	 * CSR_V LPU_LTSSM_CONFIG3 Expect OBP 0x7A120
13777c478bd9Sstevel@tonic-gate 	 */
13787c478bd9Sstevel@tonic-gate 	val = (LPU_LTSSM_CONFIG3_LTSSM_2_TO_DEFAULT <<
13797c478bd9Sstevel@tonic-gate 	    LPU_LTSSM_CONFIG3_LTSSM_2_TO);
13807c478bd9Sstevel@tonic-gate 	CSR_XS(csr_base, LPU_LTSSM_CONFIG3, val);
13817c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - LPU_LTSSM_CONFIG3: 0x%llx\n",
13827c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_LTSSM_CONFIG3));
13837c478bd9Sstevel@tonic-gate 
13847c478bd9Sstevel@tonic-gate 	/*
13857c478bd9Sstevel@tonic-gate 	 * CSR_V LPU_LTSSM_CONFIG4 Expect OBP 0x21300
13867c478bd9Sstevel@tonic-gate 	 */
13877c478bd9Sstevel@tonic-gate 	val = ((LPU_LTSSM_CONFIG4_DATA_RATE_DEFAULT <<
13887c478bd9Sstevel@tonic-gate 	    LPU_LTSSM_CONFIG4_DATA_RATE) |
13897c478bd9Sstevel@tonic-gate 	    (LPU_LTSSM_CONFIG4_N_FTS_DEFAULT <<
13907c478bd9Sstevel@tonic-gate 	    LPU_LTSSM_CONFIG4_N_FTS));
139126947304SEvan Yan 
13927c478bd9Sstevel@tonic-gate 	CSR_XS(csr_base, LPU_LTSSM_CONFIG4, val);
13937c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - LPU_LTSSM_CONFIG4: 0x%llx\n",
13947c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_LTSSM_CONFIG4));
13957c478bd9Sstevel@tonic-gate 
13967c478bd9Sstevel@tonic-gate 	/*
13977c478bd9Sstevel@tonic-gate 	 * CSR_V LPU_LTSSM_CONFIG5 Expect OBP 0x0
13987c478bd9Sstevel@tonic-gate 	 */
13997c478bd9Sstevel@tonic-gate 	val = 0ull;
14007c478bd9Sstevel@tonic-gate 	CSR_XS(csr_base, LPU_LTSSM_CONFIG5, val);
14017c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - LPU_LTSSM_CONFIG5: 0x%llx\n",
14027c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_LTSSM_CONFIG5));
14037c478bd9Sstevel@tonic-gate 
14047c478bd9Sstevel@tonic-gate 	/*
14057c478bd9Sstevel@tonic-gate 	 * CSR_V LPU_LTSSM_STATUS1 Expect OBP 0x0
14067c478bd9Sstevel@tonic-gate 	 */
14077c478bd9Sstevel@tonic-gate 
14087c478bd9Sstevel@tonic-gate 	/*
14097c478bd9Sstevel@tonic-gate 	 * LTSSM Status registers are test only.
14107c478bd9Sstevel@tonic-gate 	 */
14117c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - LPU_LTSSM_STATUS1: 0x%llx\n",
14127c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_LTSSM_STATUS1));
14137c478bd9Sstevel@tonic-gate 
14147c478bd9Sstevel@tonic-gate 	/*
14157c478bd9Sstevel@tonic-gate 	 * CSR_V LPU_LTSSM_STATUS2 Expect OBP 0x0
14167c478bd9Sstevel@tonic-gate 	 */
14177c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - LPU_LTSSM_STATUS2: 0x%llx\n",
14187c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_LTSSM_STATUS2));
14197c478bd9Sstevel@tonic-gate 
14207c478bd9Sstevel@tonic-gate 	/*
14217c478bd9Sstevel@tonic-gate 	 * CSR_V LPU_LTSSM_INTERRUPT_AND_STATUS_TEST Expect HW 0x0
14227c478bd9Sstevel@tonic-gate 	 */
14237c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
14247c478bd9Sstevel@tonic-gate 	    "lpu_init - LPU_LTSSM_INTERRUPT_AND_STATUS_TEST: 0x%llx\n",
14257c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_LTSSM_INTERRUPT_AND_STATUS_TEST));
14267c478bd9Sstevel@tonic-gate 
14277c478bd9Sstevel@tonic-gate 	/*
1428f8d2de6bSjchu 	 * CSR_V LPU LTSSM  LAYER interrupt regs (mask, status)
14297c478bd9Sstevel@tonic-gate 	 */
14307c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - LPU_LTSSM_INTERRUPT_MASK: 0x%llx\n",
14317c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_LTSSM_INTERRUPT_MASK));
14327c478bd9Sstevel@tonic-gate 
1433f8d2de6bSjchu 	DBG(DBG_LPU, NULL,
1434f8d2de6bSjchu 	    "lpu_init - LPU_LTSSM_INTERRUPT_AND_STATUS: 0x%llx\n",
1435f8d2de6bSjchu 	    CSR_XR(csr_base, LPU_LTSSM_INTERRUPT_AND_STATUS));
1436f8d2de6bSjchu 
14377c478bd9Sstevel@tonic-gate 	/*
14387c478bd9Sstevel@tonic-gate 	 * CSR_V LPU_LTSSM_STATUS_WRITE_ENABLE Expect OBP 0x0
14397c478bd9Sstevel@tonic-gate 	 */
14407c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
14417c478bd9Sstevel@tonic-gate 	    "lpu_init - LPU_LTSSM_STATUS_WRITE_ENABLE: 0x%llx\n",
14427c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_LTSSM_STATUS_WRITE_ENABLE));
14437c478bd9Sstevel@tonic-gate 
14447c478bd9Sstevel@tonic-gate 	/*
14457c478bd9Sstevel@tonic-gate 	 * CSR_V LPU_GIGABLAZE_GLUE_CONFIG1 Expect OBP 0x88407
14467c478bd9Sstevel@tonic-gate 	 */
14477c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - LPU_GIGABLAZE_GLUE_CONFIG1: 0x%llx\n",
14487c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_GIGABLAZE_GLUE_CONFIG1));
14497c478bd9Sstevel@tonic-gate 
14507c478bd9Sstevel@tonic-gate 	/*
14517c478bd9Sstevel@tonic-gate 	 * CSR_V LPU_GIGABLAZE_GLUE_CONFIG2 Expect OBP 0x35
14527c478bd9Sstevel@tonic-gate 	 */
14537c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - LPU_GIGABLAZE_GLUE_CONFIG2: 0x%llx\n",
14547c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_GIGABLAZE_GLUE_CONFIG2));
14557c478bd9Sstevel@tonic-gate 
14567c478bd9Sstevel@tonic-gate 	/*
14577c478bd9Sstevel@tonic-gate 	 * CSR_V LPU_GIGABLAZE_GLUE_CONFIG3 Expect OBP 0x4400FA
14587c478bd9Sstevel@tonic-gate 	 */
14597c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - LPU_GIGABLAZE_GLUE_CONFIG3: 0x%llx\n",
14607c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_GIGABLAZE_GLUE_CONFIG3));
14617c478bd9Sstevel@tonic-gate 
14627c478bd9Sstevel@tonic-gate 	/*
14637c478bd9Sstevel@tonic-gate 	 * CSR_V LPU_GIGABLAZE_GLUE_CONFIG4 Expect OBP 0x1E848
14647c478bd9Sstevel@tonic-gate 	 */
14657c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - LPU_GIGABLAZE_GLUE_CONFIG4: 0x%llx\n",
14667c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_GIGABLAZE_GLUE_CONFIG4));
14677c478bd9Sstevel@tonic-gate 
14687c478bd9Sstevel@tonic-gate 	/*
14697c478bd9Sstevel@tonic-gate 	 * CSR_V LPU_GIGABLAZE_GLUE_STATUS Expect OBP 0x0
14707c478bd9Sstevel@tonic-gate 	 */
14717c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - LPU_GIGABLAZE_GLUE_STATUS: 0x%llx\n",
14727c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_GIGABLAZE_GLUE_STATUS));
14737c478bd9Sstevel@tonic-gate 
14747c478bd9Sstevel@tonic-gate 	/*
14757c478bd9Sstevel@tonic-gate 	 * CSR_V LPU_GIGABLAZE_GLUE_INTERRUPT_AND_STATUS_TEST Expect OBP 0x0
14767c478bd9Sstevel@tonic-gate 	 */
1477f8d2de6bSjchu 	DBG(DBG_LPU, NULL, "lpu_init - "
14787c478bd9Sstevel@tonic-gate 	    "LPU_GIGABLAZE_GLUE_INTERRUPT_AND_STATUS_TEST: 0x%llx\n",
14797c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base,
14807c478bd9Sstevel@tonic-gate 	    LPU_GIGABLAZE_GLUE_INTERRUPT_AND_STATUS_TEST));
14817c478bd9Sstevel@tonic-gate 
14827c478bd9Sstevel@tonic-gate 	/*
1483f8d2de6bSjchu 	 * CSR_V LPU GIGABLASE LAYER interrupt regs (mask, status)
14847c478bd9Sstevel@tonic-gate 	 */
14857c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
14867c478bd9Sstevel@tonic-gate 	    "lpu_init - LPU_GIGABLAZE_GLUE_INTERRUPT_MASK: 0x%llx\n",
14877c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_GIGABLAZE_GLUE_INTERRUPT_MASK));
14887c478bd9Sstevel@tonic-gate 
1489f8d2de6bSjchu 	DBG(DBG_LPU, NULL,
1490f8d2de6bSjchu 	    "lpu_init - LPU_GIGABLAZE_GLUE_INTERRUPT_AND_STATUS: 0x%llx\n",
1491f8d2de6bSjchu 	    CSR_XR(csr_base, LPU_GIGABLAZE_GLUE_INTERRUPT_AND_STATUS));
1492f8d2de6bSjchu 
14937c478bd9Sstevel@tonic-gate 	/*
14947c478bd9Sstevel@tonic-gate 	 * CSR_V LPU_GIGABLAZE_GLUE_POWER_DOWN1 Expect HW 0x0
14957c478bd9Sstevel@tonic-gate 	 */
14967c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
14977c478bd9Sstevel@tonic-gate 	    "lpu_init - LPU_GIGABLAZE_GLUE_POWER_DOWN1: 0x%llx\n",
14987c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_GIGABLAZE_GLUE_POWER_DOWN1));
14997c478bd9Sstevel@tonic-gate 
15007c478bd9Sstevel@tonic-gate 	/*
15017c478bd9Sstevel@tonic-gate 	 * CSR_V LPU_GIGABLAZE_GLUE_POWER_DOWN2 Expect HW 0x0
15027c478bd9Sstevel@tonic-gate 	 */
15037c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL,
15047c478bd9Sstevel@tonic-gate 	    "lpu_init - LPU_GIGABLAZE_GLUE_POWER_DOWN2: 0x%llx\n",
15057c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_GIGABLAZE_GLUE_POWER_DOWN2));
15067c478bd9Sstevel@tonic-gate 
15077c478bd9Sstevel@tonic-gate 	/*
15087c478bd9Sstevel@tonic-gate 	 * CSR_V LPU_GIGABLAZE_GLUE_CONFIG5 Expect OBP 0x0
15097c478bd9Sstevel@tonic-gate 	 */
15107c478bd9Sstevel@tonic-gate 	DBG(DBG_LPU, NULL, "lpu_init - LPU_GIGABLAZE_GLUE_CONFIG5: 0x%llx\n",
15117c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, LPU_GIGABLAZE_GLUE_CONFIG5));
15127c478bd9Sstevel@tonic-gate }
15137c478bd9Sstevel@tonic-gate 
15147c478bd9Sstevel@tonic-gate /* ARGSUSED */
15157c478bd9Sstevel@tonic-gate static void
151625cf1a30Sjl139090 dlu_init(caddr_t csr_base, pxu_t *pxu_p)
151725cf1a30Sjl139090 {
151825cf1a30Sjl139090 uint64_t val;
151925cf1a30Sjl139090 
152025cf1a30Sjl139090 	CSR_XS(csr_base, DLU_INTERRUPT_MASK, 0ull);
152125cf1a30Sjl139090 	DBG(DBG_TLU, NULL, "dlu_init - DLU_INTERRUPT_MASK: 0x%llx\n",
152225cf1a30Sjl139090 	    CSR_XR(csr_base, DLU_INTERRUPT_MASK));
152325cf1a30Sjl139090 
152425cf1a30Sjl139090 	val = (1ull << DLU_LINK_LAYER_CONFIG_VC0_EN);
152525cf1a30Sjl139090 	CSR_XS(csr_base, DLU_LINK_LAYER_CONFIG, val);
152625cf1a30Sjl139090 	DBG(DBG_TLU, NULL, "dlu_init - DLU_LINK_LAYER_CONFIG: 0x%llx\n",
152725cf1a30Sjl139090 	    CSR_XR(csr_base, DLU_LINK_LAYER_CONFIG));
152825cf1a30Sjl139090 
152925cf1a30Sjl139090 	val = (1ull << DLU_FLOW_CONTROL_UPDATE_CONTROL_FC0_U_NP_EN) |
153025cf1a30Sjl139090 	    (1ull << DLU_FLOW_CONTROL_UPDATE_CONTROL_FC0_U_P_EN);
153125cf1a30Sjl139090 
153225cf1a30Sjl139090 	CSR_XS(csr_base, DLU_FLOW_CONTROL_UPDATE_CONTROL, val);
153325cf1a30Sjl139090 	DBG(DBG_TLU, NULL, "dlu_init - DLU_FLOW_CONTROL_UPDATE_CONTROL: "
153425cf1a30Sjl139090 	    "0x%llx\n", CSR_XR(csr_base, DLU_FLOW_CONTROL_UPDATE_CONTROL));
153525cf1a30Sjl139090 
153625cf1a30Sjl139090 	val = (DLU_TXLINK_REPLAY_TIMER_THRESHOLD_DEFAULT <<
153725cf1a30Sjl139090 	    DLU_TXLINK_REPLAY_TIMER_THRESHOLD_RPLAY_TMR_THR);
153825cf1a30Sjl139090 
153925cf1a30Sjl139090 	CSR_XS(csr_base, DLU_TXLINK_REPLAY_TIMER_THRESHOLD, val);
154025cf1a30Sjl139090 
154125cf1a30Sjl139090 	DBG(DBG_TLU, NULL, "dlu_init - DLU_TXLINK_REPLAY_TIMER_THRESHOLD: "
154225cf1a30Sjl139090 	    "0x%llx\n", CSR_XR(csr_base, DLU_TXLINK_REPLAY_TIMER_THRESHOLD));
154325cf1a30Sjl139090 }
154425cf1a30Sjl139090 
154525cf1a30Sjl139090 /* ARGSUSED */
154625cf1a30Sjl139090 static void
15477c478bd9Sstevel@tonic-gate dmc_init(caddr_t csr_base, pxu_t *pxu_p)
15487c478bd9Sstevel@tonic-gate {
15497c478bd9Sstevel@tonic-gate 	uint64_t val;
15507c478bd9Sstevel@tonic-gate 
15517c478bd9Sstevel@tonic-gate /*
15527c478bd9Sstevel@tonic-gate  * CSR_V DMC_CORE_AND_BLOCK_INTERRUPT_ENABLE Expect OBP 0x8000000000000003
15537c478bd9Sstevel@tonic-gate  */
15547c478bd9Sstevel@tonic-gate 
15557c478bd9Sstevel@tonic-gate 	val = -1ull;
15567c478bd9Sstevel@tonic-gate 	CSR_XS(csr_base, DMC_CORE_AND_BLOCK_INTERRUPT_ENABLE, val);
15577c478bd9Sstevel@tonic-gate 	DBG(DBG_DMC, NULL,
15587c478bd9Sstevel@tonic-gate 	    "dmc_init - DMC_CORE_AND_BLOCK_INTERRUPT_ENABLE: 0x%llx\n",
15597c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, DMC_CORE_AND_BLOCK_INTERRUPT_ENABLE));
15607c478bd9Sstevel@tonic-gate 
15617c478bd9Sstevel@tonic-gate 	/*
15627c478bd9Sstevel@tonic-gate 	 * CSR_V DMC_CORE_AND_BLOCK_ERROR_STATUS Expect HW 0x0
15637c478bd9Sstevel@tonic-gate 	 */
15647c478bd9Sstevel@tonic-gate 	DBG(DBG_DMC, NULL,
15657c478bd9Sstevel@tonic-gate 	    "dmc_init - DMC_CORE_AND_BLOCK_ERROR_STATUS: 0x%llx\n",
15667c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, DMC_CORE_AND_BLOCK_ERROR_STATUS));
15677c478bd9Sstevel@tonic-gate 
15687c478bd9Sstevel@tonic-gate 	/*
15697c478bd9Sstevel@tonic-gate 	 * CSR_V DMC_DEBUG_SELECT_FOR_PORT_A Expect HW 0x0
15707c478bd9Sstevel@tonic-gate 	 */
15717c478bd9Sstevel@tonic-gate 	val = 0x0ull;
15727c478bd9Sstevel@tonic-gate 	CSR_XS(csr_base, DMC_DEBUG_SELECT_FOR_PORT_A, val);
15737c478bd9Sstevel@tonic-gate 	DBG(DBG_DMC, NULL, "dmc_init - DMC_DEBUG_SELECT_FOR_PORT_A: 0x%llx\n",
15747c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, DMC_DEBUG_SELECT_FOR_PORT_A));
15757c478bd9Sstevel@tonic-gate 
15767c478bd9Sstevel@tonic-gate 	/*
15777c478bd9Sstevel@tonic-gate 	 * CSR_V DMC_DEBUG_SELECT_FOR_PORT_B Expect HW 0x0
15787c478bd9Sstevel@tonic-gate 	 */
15797c478bd9Sstevel@tonic-gate 	val = 0x0ull;
15807c478bd9Sstevel@tonic-gate 	CSR_XS(csr_base, DMC_DEBUG_SELECT_FOR_PORT_B, val);
15817c478bd9Sstevel@tonic-gate 	DBG(DBG_DMC, NULL, "dmc_init - DMC_DEBUG_SELECT_FOR_PORT_B: 0x%llx\n",
15827c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, DMC_DEBUG_SELECT_FOR_PORT_B));
15837c478bd9Sstevel@tonic-gate }
15847c478bd9Sstevel@tonic-gate 
15857c478bd9Sstevel@tonic-gate void
15867c478bd9Sstevel@tonic-gate hvio_pec_init(caddr_t csr_base, pxu_t *pxu_p)
15877c478bd9Sstevel@tonic-gate {
15887c478bd9Sstevel@tonic-gate 	uint64_t val;
15897c478bd9Sstevel@tonic-gate 
15907c478bd9Sstevel@tonic-gate 	ilu_init(csr_base, pxu_p);
15917c478bd9Sstevel@tonic-gate 	tlu_init(csr_base, pxu_p);
159225cf1a30Sjl139090 
159325cf1a30Sjl139090 	switch (PX_CHIP_TYPE(pxu_p)) {
159425cf1a30Sjl139090 	case PX_CHIP_OBERON:
159525cf1a30Sjl139090 		dlu_init(csr_base, pxu_p);
159625cf1a30Sjl139090 		break;
159725cf1a30Sjl139090 	case PX_CHIP_FIRE:
15987c478bd9Sstevel@tonic-gate 		lpu_init(csr_base, pxu_p);
159925cf1a30Sjl139090 		break;
160025cf1a30Sjl139090 	default:
160125cf1a30Sjl139090 		DBG(DBG_PEC, NULL, "hvio_pec_init - unknown chip type: 0x%x\n",
160225cf1a30Sjl139090 		    PX_CHIP_TYPE(pxu_p));
160325cf1a30Sjl139090 		break;
160425cf1a30Sjl139090 	}
160525cf1a30Sjl139090 
16067c478bd9Sstevel@tonic-gate 	dmc_init(csr_base, pxu_p);
16077c478bd9Sstevel@tonic-gate 
16087c478bd9Sstevel@tonic-gate /*
16097c478bd9Sstevel@tonic-gate  * CSR_V PEC_CORE_AND_BLOCK_INTERRUPT_ENABLE Expect Kernel 0x800000000000000F
16107c478bd9Sstevel@tonic-gate  */
16117c478bd9Sstevel@tonic-gate 
16127c478bd9Sstevel@tonic-gate 	val = -1ull;
16137c478bd9Sstevel@tonic-gate 	CSR_XS(csr_base, PEC_CORE_AND_BLOCK_INTERRUPT_ENABLE, val);
16147c478bd9Sstevel@tonic-gate 	DBG(DBG_PEC, NULL,
16157c478bd9Sstevel@tonic-gate 	    "hvio_pec_init - PEC_CORE_AND_BLOCK_INTERRUPT_ENABLE: 0x%llx\n",
16167c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, PEC_CORE_AND_BLOCK_INTERRUPT_ENABLE));
16177c478bd9Sstevel@tonic-gate 
16187c478bd9Sstevel@tonic-gate 	/*
16197c478bd9Sstevel@tonic-gate 	 * CSR_V PEC_CORE_AND_BLOCK_INTERRUPT_STATUS Expect HW 0x0
16207c478bd9Sstevel@tonic-gate 	 */
16217c478bd9Sstevel@tonic-gate 	DBG(DBG_PEC, NULL,
16227c478bd9Sstevel@tonic-gate 	    "hvio_pec_init - PEC_CORE_AND_BLOCK_INTERRUPT_STATUS: 0x%llx\n",
16237c478bd9Sstevel@tonic-gate 	    CSR_XR(csr_base, PEC_CORE_AND_BLOCK_INTERRUPT_STATUS));
16247c478bd9Sstevel@tonic-gate }
16257c478bd9Sstevel@tonic-gate 
1626f8d2de6bSjchu /*
162725cf1a30Sjl139090  * Convert a TTE to physical address
162825cf1a30Sjl139090  */
162925cf1a30Sjl139090 static r_addr_t
163025cf1a30Sjl139090 mmu_tte_to_pa(uint64_t tte, pxu_t *pxu_p)
163125cf1a30Sjl139090 {
163225cf1a30Sjl139090 	uint64_t pa_mask;
163325cf1a30Sjl139090 
163425cf1a30Sjl139090 	switch (PX_CHIP_TYPE(pxu_p)) {
163525cf1a30Sjl139090 	case PX_CHIP_OBERON:
163625cf1a30Sjl139090 		pa_mask = MMU_OBERON_PADDR_MASK;
163725cf1a30Sjl139090 		break;
163825cf1a30Sjl139090 	case PX_CHIP_FIRE:
163925cf1a30Sjl139090 		pa_mask = MMU_FIRE_PADDR_MASK;
164025cf1a30Sjl139090 		break;
164125cf1a30Sjl139090 	default:
164225cf1a30Sjl139090 		DBG(DBG_MMU, NULL, "mmu_tte_to_pa - unknown chip type: 0x%x\n",
164325cf1a30Sjl139090 		    PX_CHIP_TYPE(pxu_p));
164425cf1a30Sjl139090 		pa_mask = 0;
164525cf1a30Sjl139090 		break;
164625cf1a30Sjl139090 	}
164725cf1a30Sjl139090 	return ((tte & pa_mask) >> MMU_PAGE_SHIFT);
164825cf1a30Sjl139090 }
164925cf1a30Sjl139090 
165025cf1a30Sjl139090 /*
165125cf1a30Sjl139090  * Return MMU bypass noncache bit for chip
165225cf1a30Sjl139090  */
165325cf1a30Sjl139090 static r_addr_t
165425cf1a30Sjl139090 mmu_bypass_noncache(pxu_t *pxu_p)
165525cf1a30Sjl139090 {
165625cf1a30Sjl139090 	r_addr_t bypass_noncache_bit;
165725cf1a30Sjl139090 
165825cf1a30Sjl139090 	switch (PX_CHIP_TYPE(pxu_p)) {
165925cf1a30Sjl139090 	case PX_CHIP_OBERON:
166025cf1a30Sjl139090 		bypass_noncache_bit = MMU_OBERON_BYPASS_NONCACHE;
166125cf1a30Sjl139090 		break;
166225cf1a30Sjl139090 	case PX_CHIP_FIRE:
166325cf1a30Sjl139090 		bypass_noncache_bit = MMU_FIRE_BYPASS_NONCACHE;
166425cf1a30Sjl139090 		break;
166525cf1a30Sjl139090 	default:
166625cf1a30Sjl139090 		DBG(DBG_MMU, NULL,
166725cf1a30Sjl139090 		    "mmu_bypass_nocache - unknown chip type: 0x%x\n",
166825cf1a30Sjl139090 		    PX_CHIP_TYPE(pxu_p));
166925cf1a30Sjl139090 		bypass_noncache_bit = 0;
167025cf1a30Sjl139090 		break;
167125cf1a30Sjl139090 	}
167225cf1a30Sjl139090 	return (bypass_noncache_bit);
167325cf1a30Sjl139090 }
167425cf1a30Sjl139090 
167525cf1a30Sjl139090 /*
167625cf1a30Sjl139090  * Calculate number of TSB entries for the chip.
167725cf1a30Sjl139090  */
167825cf1a30Sjl139090 /* ARGSUSED */
167925cf1a30Sjl139090 static uint_t
168025cf1a30Sjl139090 mmu_tsb_entries(caddr_t csr_base, pxu_t *pxu_p)
168125cf1a30Sjl139090 {
168225cf1a30Sjl139090 	uint64_t tsb_ctrl;
168325cf1a30Sjl139090 	uint_t obp_tsb_entries, obp_tsb_size;
168425cf1a30Sjl139090 
168525cf1a30Sjl139090 	tsb_ctrl = CSR_XR(csr_base, MMU_TSB_CONTROL);
168625cf1a30Sjl139090 
168725cf1a30Sjl139090 	obp_tsb_size = tsb_ctrl & 0xF;
168825cf1a30Sjl139090 
168925cf1a30Sjl139090 	obp_tsb_entries = MMU_TSBSIZE_TO_TSBENTRIES(obp_tsb_size);
169025cf1a30Sjl139090 
169125cf1a30Sjl139090 	return (obp_tsb_entries);
169225cf1a30Sjl139090 }
169325cf1a30Sjl139090 
169425cf1a30Sjl139090 /*
1695f8d2de6bSjchu  * Initialize the module, but do not enable interrupts.
1696f8d2de6bSjchu  */
16977c478bd9Sstevel@tonic-gate void
16987c478bd9Sstevel@tonic-gate hvio_mmu_init(caddr_t csr_base, pxu_t *pxu_p)
16997c478bd9Sstevel@tonic-gate {
1700*89b42a21Sandrew.rutz@sun.com 	uint64_t	val, i, obp_tsb_pa;
170125cf1a30Sjl139090 	uint_t obp_tsb_entries;
17027c478bd9Sstevel@tonic-gate 
17037c478bd9Sstevel@tonic-gate 	bzero(pxu_p->tsb_vaddr, pxu_p->tsb_size);
17047c478bd9Sstevel@tonic-gate 
17057c478bd9Sstevel@tonic-gate 	/*
17067c478bd9Sstevel@tonic-gate 	 * Preserve OBP's TSB
17077c478bd9Sstevel@tonic-gate 	 */
170825cf1a30Sjl139090 	obp_tsb_pa = CSR_XR(csr_base, MMU_TSB_CONTROL) & MMU_TSB_PA_MASK;
17097c478bd9Sstevel@tonic-gate 
171025cf1a30Sjl139090 	obp_tsb_entries = mmu_tsb_entries(csr_base, pxu_p);
17117c478bd9Sstevel@tonic-gate 
1712*89b42a21Sandrew.rutz@sun.com 	/* save "shape" of OBP's TSB for use during Detach */
1713*89b42a21Sandrew.rutz@sun.com 	pxu_p->obp_tsb_paddr = obp_tsb_pa;
1714*89b42a21Sandrew.rutz@sun.com 	pxu_p->obp_tsb_entries = obp_tsb_entries;
17157c478bd9Sstevel@tonic-gate 
1716*89b42a21Sandrew.rutz@sun.com 	/* For each Valid TTE in OBP's TSB, save its value in px's IOTSB */
1717*89b42a21Sandrew.rutz@sun.com 	hvio_obptsb_attach(pxu_p);
17187c478bd9Sstevel@tonic-gate 
17197c478bd9Sstevel@tonic-gate 	/*
17207c478bd9Sstevel@tonic-gate 	 * Invalidate the TLB through the diagnostic register.
17217c478bd9Sstevel@tonic-gate 	 */
17227c478bd9Sstevel@tonic-gate 
17237c478bd9Sstevel@tonic-gate 	CSR_XS(csr_base, MMU_TTE_CACHE_INVALIDATE, -1ull);
17247c478bd9Sstevel@tonic-gate 
17257c478bd9Sstevel@tonic-gate 	/*
17267c478bd9Sstevel@tonic-gate 	 * Configure the Fire MMU TSB Control Register.  Determine
17277c478bd9Sstevel@tonic-gate 	 * the encoding for either 8KB pages (0) or 64KB pages (1).
17287c478bd9Sstevel@tonic-gate 	 *
17297c478bd9Sstevel@tonic-gate 	 * Write the most significant 30 bits of the TSB physical address
17307c478bd9Sstevel@tonic-gate 	 * and the encoded TSB table size.
17317c478bd9Sstevel@tonic-gate 	 */
173226947304SEvan Yan 	for (i = 8; i && (pxu_p->tsb_size < (0x2000 << i)); i--)
173326947304SEvan Yan 		;
17347c478bd9Sstevel@tonic-gate 
17357c478bd9Sstevel@tonic-gate 	val = (((((va_to_pa(pxu_p->tsb_vaddr)) >> 13) << 13) |
17367c478bd9Sstevel@tonic-gate 	    ((MMU_PAGE_SHIFT == 13) ? 0 : 1) << 8) | i);
17377c478bd9Sstevel@tonic-gate 
17387c478bd9Sstevel@tonic-gate 	CSR_XS(csr_base, MMU_TSB_CONTROL, val);
17397c478bd9Sstevel@tonic-gate 
17407c478bd9Sstevel@tonic-gate 	/*
17417c478bd9Sstevel@tonic-gate 	 * Enable the MMU, set the "TSB Cache Snoop Enable",
17427c478bd9Sstevel@tonic-gate 	 * the "Cache Mode", the "Bypass Enable" and
17437c478bd9Sstevel@tonic-gate 	 * the "Translation Enable" bits.
17447c478bd9Sstevel@tonic-gate 	 */
17457c478bd9Sstevel@tonic-gate 	val = CSR_XR(csr_base, MMU_CONTROL_AND_STATUS);
17467c478bd9Sstevel@tonic-gate 	val |= ((1ull << MMU_CONTROL_AND_STATUS_SE)
1747a616a11eSLida.Horn 	    |  (MMU_CONTROL_AND_STATUS_ROE_BIT63_ENABLE <<
1748a616a11eSLida.Horn 	    MMU_CONTROL_AND_STATUS_ROE)
17497c478bd9Sstevel@tonic-gate 	    | (MMU_CONTROL_AND_STATUS_CM_MASK << MMU_CONTROL_AND_STATUS_CM)
17507c478bd9Sstevel@tonic-gate 	    | (1ull << MMU_CONTROL_AND_STATUS_BE)
17517c478bd9Sstevel@tonic-gate 	    | (1ull << MMU_CONTROL_AND_STATUS_TE));
17527c478bd9Sstevel@tonic-gate 
17537c478bd9Sstevel@tonic-gate 	CSR_XS(csr_base, MMU_CONTROL_AND_STATUS, val);
17547c478bd9Sstevel@tonic-gate 
17557c478bd9Sstevel@tonic-gate 	/*
17567c478bd9Sstevel@tonic-gate 	 * Read the register here to ensure that the previous writes to
17577c478bd9Sstevel@tonic-gate 	 * the Fire MMU registers have been flushed.  (Technically, this
17587c478bd9Sstevel@tonic-gate 	 * is not entirely necessary here as we will likely do later reads
17597c478bd9Sstevel@tonic-gate 	 * during Fire initialization, but it is a small price to pay for
17607c478bd9Sstevel@tonic-gate 	 * more modular code.)
17617c478bd9Sstevel@tonic-gate 	 */
17627c478bd9Sstevel@tonic-gate 	(void) CSR_XR(csr_base, MMU_CONTROL_AND_STATUS);
17637c478bd9Sstevel@tonic-gate 
17647c478bd9Sstevel@tonic-gate 	/*
1765f8d2de6bSjchu 	 * CSR_V TLU's UE interrupt regs (log, enable, status, clear)
1766f8d2de6bSjchu 	 * Plus header logs
17677c478bd9Sstevel@tonic-gate 	 */
1768f8d2de6bSjchu 	DBG(DBG_MMU, NULL, "mmu_init - MMU_ERROR_LOG_ENABLE: 0x%llx\n",
1769f8d2de6bSjchu 	    CSR_XR(csr_base, MMU_ERROR_LOG_ENABLE));
1770f8d2de6bSjchu 
1771f8d2de6bSjchu 	DBG(DBG_MMU, NULL, "mmu_init - MMU_INTERRUPT_ENABLE: 0x%llx\n",
1772f8d2de6bSjchu 	    CSR_XR(csr_base, MMU_INTERRUPT_ENABLE));
1773f8d2de6bSjchu 
1774f8d2de6bSjchu 	DBG(DBG_MMU, NULL, "mmu_init - MMU_INTERRUPT_STATUS: 0x%llx\n",
1775f8d2de6bSjchu 	    CSR_XR(csr_base, MMU_INTERRUPT_STATUS));
1776f8d2de6bSjchu 
1777f8d2de6bSjchu 	DBG(DBG_MMU, NULL, "mmu_init - MMU_ERROR_STATUS_CLEAR: 0x%llx\n",
1778f8d2de6bSjchu 	    CSR_XR(csr_base, MMU_ERROR_STATUS_CLEAR));
17797c478bd9Sstevel@tonic-gate }
17807c478bd9Sstevel@tonic-gate 
17817c478bd9Sstevel@tonic-gate /*
17827c478bd9Sstevel@tonic-gate  * Generic IOMMU Servies
17837c478bd9Sstevel@tonic-gate  */
17847c478bd9Sstevel@tonic-gate 
17857c478bd9Sstevel@tonic-gate /* ARGSUSED */
17867c478bd9Sstevel@tonic-gate uint64_t
178744bb982bSgovinda hvio_iommu_map(devhandle_t dev_hdl, pxu_t *pxu_p, tsbid_t tsbid, pages_t pages,
178844bb982bSgovinda     io_attributes_t io_attr, void *addr, size_t pfn_index, int flags)
17897c478bd9Sstevel@tonic-gate {
17907c478bd9Sstevel@tonic-gate 	tsbindex_t	tsb_index = PCI_TSBID_TO_TSBINDEX(tsbid);
17917c478bd9Sstevel@tonic-gate 	uint64_t	attr = MMU_TTE_V;
17927c478bd9Sstevel@tonic-gate 	int		i;
17937c478bd9Sstevel@tonic-gate 
179444bb982bSgovinda 	if (io_attr & PCI_MAP_ATTR_WRITE)
17957c478bd9Sstevel@tonic-gate 		attr |= MMU_TTE_W;
17967c478bd9Sstevel@tonic-gate 
179725cf1a30Sjl139090 	if ((PX_CHIP_TYPE(pxu_p) == PX_CHIP_OBERON) &&
179825cf1a30Sjl139090 	    (io_attr & PCI_MAP_ATTR_RO))
179925cf1a30Sjl139090 		attr |= MMU_TTE_RO;
180025cf1a30Sjl139090 
180125cf1a30Sjl139090 	if (attr & MMU_TTE_RO) {
180225cf1a30Sjl139090 		DBG(DBG_MMU, NULL, "hvio_iommu_map: pfn_index=0x%x "
180325cf1a30Sjl139090 		    "pages=0x%x attr = 0x%lx\n", pfn_index, pages, attr);
180425cf1a30Sjl139090 	}
180525cf1a30Sjl139090 
180644bb982bSgovinda 	if (flags & MMU_MAP_PFN) {
18077c478bd9Sstevel@tonic-gate 		ddi_dma_impl_t	*mp = (ddi_dma_impl_t *)addr;
18087c478bd9Sstevel@tonic-gate 		for (i = 0; i < pages; i++, pfn_index++, tsb_index++) {
18097c478bd9Sstevel@tonic-gate 			px_iopfn_t pfn = PX_GET_MP_PFN(mp, pfn_index);
181044bb982bSgovinda 			pxu_p->tsb_vaddr[tsb_index] = MMU_PTOB(pfn) | attr;
181125cf1a30Sjl139090 
181225cf1a30Sjl139090 			/*
181325cf1a30Sjl139090 			 * Oberon will need to flush the corresponding TTEs in
181425cf1a30Sjl139090 			 * Cache. We only need to flush every cache line.
181525cf1a30Sjl139090 			 * Extra PIO's are expensive.
181625cf1a30Sjl139090 			 */
181725cf1a30Sjl139090 			if (PX_CHIP_TYPE(pxu_p) == PX_CHIP_OBERON) {
181825cf1a30Sjl139090 				if ((i == (pages-1))||!((tsb_index+1) & 0x7)) {
181925cf1a30Sjl139090 					CSR_XS(dev_hdl,
182025cf1a30Sjl139090 					    MMU_TTE_CACHE_FLUSH_ADDRESS,
182125cf1a30Sjl139090 					    (pxu_p->tsb_paddr+
182225cf1a30Sjl139090 					    (tsb_index*MMU_TTE_SIZE)));
182325cf1a30Sjl139090 				}
182425cf1a30Sjl139090 			}
18257c478bd9Sstevel@tonic-gate 		}
18267c478bd9Sstevel@tonic-gate 	} else {
18277c478bd9Sstevel@tonic-gate 		caddr_t	a = (caddr_t)addr;
18287c478bd9Sstevel@tonic-gate 		for (i = 0; i < pages; i++, a += MMU_PAGE_SIZE, tsb_index++) {
18297c478bd9Sstevel@tonic-gate 			px_iopfn_t pfn = hat_getpfnum(kas.a_hat, a);
183044bb982bSgovinda 			pxu_p->tsb_vaddr[tsb_index] = MMU_PTOB(pfn) | attr;
183125cf1a30Sjl139090 
183225cf1a30Sjl139090 			/*
183325cf1a30Sjl139090 			 * Oberon will need to flush the corresponding TTEs in
183425cf1a30Sjl139090 			 * Cache. We only need to flush every cache line.
183525cf1a30Sjl139090 			 * Extra PIO's are expensive.
183625cf1a30Sjl139090 			 */
183725cf1a30Sjl139090 			if (PX_CHIP_TYPE(pxu_p) == PX_CHIP_OBERON) {
183825cf1a30Sjl139090 				if ((i == (pages-1))||!((tsb_index+1) & 0x7)) {
183925cf1a30Sjl139090 					CSR_XS(dev_hdl,
184025cf1a30Sjl139090 					    MMU_TTE_CACHE_FLUSH_ADDRESS,
184125cf1a30Sjl139090 					    (pxu_p->tsb_paddr+
184225cf1a30Sjl139090 					    (tsb_index*MMU_TTE_SIZE)));
184325cf1a30Sjl139090 				}
184425cf1a30Sjl139090 			}
18457c478bd9Sstevel@tonic-gate 		}
18467c478bd9Sstevel@tonic-gate 	}
18477c478bd9Sstevel@tonic-gate 
18487c478bd9Sstevel@tonic-gate 	return (H_EOK);
18497c478bd9Sstevel@tonic-gate }
18507c478bd9Sstevel@tonic-gate 
18517c478bd9Sstevel@tonic-gate /* ARGSUSED */
18527c478bd9Sstevel@tonic-gate uint64_t
18537c478bd9Sstevel@tonic-gate hvio_iommu_demap(devhandle_t dev_hdl, pxu_t *pxu_p, tsbid_t tsbid,
18547c478bd9Sstevel@tonic-gate     pages_t pages)
18557c478bd9Sstevel@tonic-gate {
18567c478bd9Sstevel@tonic-gate 	tsbindex_t	tsb_index = PCI_TSBID_TO_TSBINDEX(tsbid);
18577c478bd9Sstevel@tonic-gate 	int		i;
18587c478bd9Sstevel@tonic-gate 
185925cf1a30Sjl139090 	for (i = 0; i < pages; i++, tsb_index++) {
18607c478bd9Sstevel@tonic-gate 		pxu_p->tsb_vaddr[tsb_index] = MMU_INVALID_TTE;
18617c478bd9Sstevel@tonic-gate 
186225cf1a30Sjl139090 			/*
186325cf1a30Sjl139090 			 * Oberon will need to flush the corresponding TTEs in
186425cf1a30Sjl139090 			 * Cache. We only need to flush every cache line.
186525cf1a30Sjl139090 			 * Extra PIO's are expensive.
186625cf1a30Sjl139090 			 */
186725cf1a30Sjl139090 			if (PX_CHIP_TYPE(pxu_p) == PX_CHIP_OBERON) {
186825cf1a30Sjl139090 				if ((i == (pages-1))||!((tsb_index+1) & 0x7)) {
186925cf1a30Sjl139090 					CSR_XS(dev_hdl,
187025cf1a30Sjl139090 					    MMU_TTE_CACHE_FLUSH_ADDRESS,
187125cf1a30Sjl139090 					    (pxu_p->tsb_paddr+
187225cf1a30Sjl139090 					    (tsb_index*MMU_TTE_SIZE)));
187325cf1a30Sjl139090 				}
187425cf1a30Sjl139090 			}
187525cf1a30Sjl139090 	}
187625cf1a30Sjl139090 
18777c478bd9Sstevel@tonic-gate 	return (H_EOK);
18787c478bd9Sstevel@tonic-gate }
18797c478bd9Sstevel@tonic-gate 
18807c478bd9Sstevel@tonic-gate /* ARGSUSED */
18817c478bd9Sstevel@tonic-gate uint64_t
18827c478bd9Sstevel@tonic-gate hvio_iommu_getmap(devhandle_t dev_hdl, pxu_t *pxu_p, tsbid_t tsbid,
188344bb982bSgovinda     io_attributes_t *attr_p, r_addr_t *r_addr_p)
18847c478bd9Sstevel@tonic-gate {
18857c478bd9Sstevel@tonic-gate 	tsbindex_t	tsb_index = PCI_TSBID_TO_TSBINDEX(tsbid);
18867c478bd9Sstevel@tonic-gate 	uint64_t	*tte_addr;
18877c478bd9Sstevel@tonic-gate 	uint64_t	ret = H_EOK;
18887c478bd9Sstevel@tonic-gate 
18897c478bd9Sstevel@tonic-gate 	tte_addr = (uint64_t *)(pxu_p->tsb_vaddr) + tsb_index;
18907c478bd9Sstevel@tonic-gate 
18917c478bd9Sstevel@tonic-gate 	if (*tte_addr & MMU_TTE_V) {
189225cf1a30Sjl139090 		*r_addr_p = mmu_tte_to_pa(*tte_addr, pxu_p);
189344bb982bSgovinda 		*attr_p = (*tte_addr & MMU_TTE_W) ?
18947c478bd9Sstevel@tonic-gate 		    PCI_MAP_ATTR_WRITE:PCI_MAP_ATTR_READ;
18957c478bd9Sstevel@tonic-gate 	} else {
18967c478bd9Sstevel@tonic-gate 		*r_addr_p = 0;
189744bb982bSgovinda 		*attr_p = 0;
18987c478bd9Sstevel@tonic-gate 		ret = H_ENOMAP;
18997c478bd9Sstevel@tonic-gate 	}
19007c478bd9Sstevel@tonic-gate 
19017c478bd9Sstevel@tonic-gate 	return (ret);
19027c478bd9Sstevel@tonic-gate }
19037c478bd9Sstevel@tonic-gate 
1904*89b42a21Sandrew.rutz@sun.com /*
1905*89b42a21Sandrew.rutz@sun.com  * Copy each Valid OBP TTE from OBP's IOTSB to px's IOTSB.
1906*89b42a21Sandrew.rutz@sun.com  */
1907*89b42a21Sandrew.rutz@sun.com void
1908*89b42a21Sandrew.rutz@sun.com hvio_obptsb_attach(pxu_t *pxu_p)
1909*89b42a21Sandrew.rutz@sun.com {
1910*89b42a21Sandrew.rutz@sun.com 	uint64_t	obp_tsb_pa;
1911*89b42a21Sandrew.rutz@sun.com 	uint64_t	*base_tte_addr;
1912*89b42a21Sandrew.rutz@sun.com 	uint64_t	i;
1913*89b42a21Sandrew.rutz@sun.com 	uint_t		obp_tsb_entries;
1914*89b42a21Sandrew.rutz@sun.com 
1915*89b42a21Sandrew.rutz@sun.com 	obp_tsb_pa = pxu_p->obp_tsb_paddr;
1916*89b42a21Sandrew.rutz@sun.com 	obp_tsb_entries = pxu_p->obp_tsb_entries;
1917*89b42a21Sandrew.rutz@sun.com 
1918*89b42a21Sandrew.rutz@sun.com 	/*
1919*89b42a21Sandrew.rutz@sun.com 	 * Compute the starting addr of the area reserved for
1920*89b42a21Sandrew.rutz@sun.com 	 * OBP's TTEs; OBP's TTEs are stored at the highest addrs
1921*89b42a21Sandrew.rutz@sun.com 	 * of px's IOTSB.
1922*89b42a21Sandrew.rutz@sun.com 	 */
1923*89b42a21Sandrew.rutz@sun.com 	base_tte_addr = pxu_p->tsb_vaddr +
1924*89b42a21Sandrew.rutz@sun.com 	    ((pxu_p->tsb_size >> 3) - obp_tsb_entries);
1925*89b42a21Sandrew.rutz@sun.com 
1926*89b42a21Sandrew.rutz@sun.com 	for (i = 0; i < obp_tsb_entries; i++) {
1927*89b42a21Sandrew.rutz@sun.com 		uint64_t tte = lddphys(obp_tsb_pa + i * 8);
1928*89b42a21Sandrew.rutz@sun.com 
1929*89b42a21Sandrew.rutz@sun.com 		if (!MMU_TTE_VALID(tte))
1930*89b42a21Sandrew.rutz@sun.com 			continue;
1931*89b42a21Sandrew.rutz@sun.com 
1932*89b42a21Sandrew.rutz@sun.com 		base_tte_addr[i] = tte;
1933*89b42a21Sandrew.rutz@sun.com 	}
1934*89b42a21Sandrew.rutz@sun.com }
1935*89b42a21Sandrew.rutz@sun.com 
1936*89b42a21Sandrew.rutz@sun.com /*
1937*89b42a21Sandrew.rutz@sun.com  * For each Valid OBP TTE, deallocate space from the vmem Arena used
1938*89b42a21Sandrew.rutz@sun.com  * to manage the TTE's associated DVMA addr space.  (Allocation from
1939*89b42a21Sandrew.rutz@sun.com  * the DVMA Arena was done in px_mmu_attach).
1940*89b42a21Sandrew.rutz@sun.com  */
1941*89b42a21Sandrew.rutz@sun.com void
1942*89b42a21Sandrew.rutz@sun.com hvio_obptsb_detach(px_t *px_p)
1943*89b42a21Sandrew.rutz@sun.com {
1944*89b42a21Sandrew.rutz@sun.com 	uint64_t	obp_tsb_pa;
1945*89b42a21Sandrew.rutz@sun.com 	uint64_t	i;
1946*89b42a21Sandrew.rutz@sun.com 	uint_t		obp_tsb_entries;
1947*89b42a21Sandrew.rutz@sun.com 	uint_t		obp_tsb_bias;
1948*89b42a21Sandrew.rutz@sun.com 	px_mmu_t	*mmu_p = px_p->px_mmu_p;
1949*89b42a21Sandrew.rutz@sun.com 	vmem_t		*dvma_map;
1950*89b42a21Sandrew.rutz@sun.com 	pxu_t		*pxu_p = (pxu_t *)px_p->px_plat_p;
1951*89b42a21Sandrew.rutz@sun.com 
1952*89b42a21Sandrew.rutz@sun.com 	dvma_map = mmu_p->mmu_dvma_map;
1953*89b42a21Sandrew.rutz@sun.com 
1954*89b42a21Sandrew.rutz@sun.com 	obp_tsb_pa = pxu_p->obp_tsb_paddr;
1955*89b42a21Sandrew.rutz@sun.com 	obp_tsb_entries = pxu_p->obp_tsb_entries;
1956*89b42a21Sandrew.rutz@sun.com 	/*
1957*89b42a21Sandrew.rutz@sun.com 	 * OBP's TTEs are located at the high end of px's IOTSB.
1958*89b42a21Sandrew.rutz@sun.com 	 * Equivalently, OBP's DVMA space is allocated at the high end
1959*89b42a21Sandrew.rutz@sun.com 	 * of px's DVMA space.  Compute the bias that references
1960*89b42a21Sandrew.rutz@sun.com 	 * OBP's first possible page of DVMA space.
1961*89b42a21Sandrew.rutz@sun.com 	 */
1962*89b42a21Sandrew.rutz@sun.com 	obp_tsb_bias = (pxu_p->tsb_size >> 3) - obp_tsb_entries;
1963*89b42a21Sandrew.rutz@sun.com 
1964*89b42a21Sandrew.rutz@sun.com 	for (i = 0; i < obp_tsb_entries; i++) {
1965*89b42a21Sandrew.rutz@sun.com 		caddr_t va;
1966*89b42a21Sandrew.rutz@sun.com 		uint64_t tte = lddphys(obp_tsb_pa + i * 8);
1967*89b42a21Sandrew.rutz@sun.com 
1968*89b42a21Sandrew.rutz@sun.com 		if (!MMU_TTE_VALID(tte))
1969*89b42a21Sandrew.rutz@sun.com 			continue;
1970*89b42a21Sandrew.rutz@sun.com 
1971*89b42a21Sandrew.rutz@sun.com 		/* deallocate the TTE's associated page of DVMA space */
1972*89b42a21Sandrew.rutz@sun.com 		va = (caddr_t)(MMU_PTOB(mmu_p->dvma_base_pg + obp_tsb_bias +
1973*89b42a21Sandrew.rutz@sun.com 		    i));
1974*89b42a21Sandrew.rutz@sun.com 		vmem_xfree(dvma_map, va, MMU_PAGE_SIZE);
1975*89b42a21Sandrew.rutz@sun.com 	}
1976*89b42a21Sandrew.rutz@sun.com }
1977*89b42a21Sandrew.rutz@sun.com 
19787c478bd9Sstevel@tonic-gate /* ARGSUSED */
19797c478bd9Sstevel@tonic-gate uint64_t
198025cf1a30Sjl139090 hvio_get_bypass_base(pxu_t *pxu_p)
198125cf1a30Sjl139090 {
198225cf1a30Sjl139090 	uint64_t base;
198325cf1a30Sjl139090 
198425cf1a30Sjl139090 	switch (PX_CHIP_TYPE(pxu_p)) {
198525cf1a30Sjl139090 	case PX_CHIP_OBERON:
198625cf1a30Sjl139090 		base = MMU_OBERON_BYPASS_BASE;
198725cf1a30Sjl139090 		break;
198825cf1a30Sjl139090 	case PX_CHIP_FIRE:
198925cf1a30Sjl139090 		base = MMU_FIRE_BYPASS_BASE;
199025cf1a30Sjl139090 		break;
199125cf1a30Sjl139090 	default:
199225cf1a30Sjl139090 		DBG(DBG_MMU, NULL,
199325cf1a30Sjl139090 		    "hvio_get_bypass_base - unknown chip type: 0x%x\n",
199425cf1a30Sjl139090 		    PX_CHIP_TYPE(pxu_p));
199525cf1a30Sjl139090 		base = 0;
199625cf1a30Sjl139090 		break;
199725cf1a30Sjl139090 	}
199825cf1a30Sjl139090 	return (base);
199925cf1a30Sjl139090 }
200025cf1a30Sjl139090 
200125cf1a30Sjl139090 /* ARGSUSED */
200225cf1a30Sjl139090 uint64_t
200325cf1a30Sjl139090 hvio_get_bypass_end(pxu_t *pxu_p)
200425cf1a30Sjl139090 {
200525cf1a30Sjl139090 	uint64_t end;
200625cf1a30Sjl139090 
200725cf1a30Sjl139090 	switch (PX_CHIP_TYPE(pxu_p)) {
200825cf1a30Sjl139090 	case PX_CHIP_OBERON:
200925cf1a30Sjl139090 		end = MMU_OBERON_BYPASS_END;
201025cf1a30Sjl139090 		break;
201125cf1a30Sjl139090 	case PX_CHIP_FIRE:
201225cf1a30Sjl139090 		end = MMU_FIRE_BYPASS_END;
201325cf1a30Sjl139090 		break;
201425cf1a30Sjl139090 	default:
201525cf1a30Sjl139090 		DBG(DBG_MMU, NULL,
201625cf1a30Sjl139090 		    "hvio_get_bypass_end - unknown chip type: 0x%x\n",
201725cf1a30Sjl139090 		    PX_CHIP_TYPE(pxu_p));
201825cf1a30Sjl139090 		end = 0;
201925cf1a30Sjl139090 		break;
202025cf1a30Sjl139090 	}
202125cf1a30Sjl139090 	return (end);
202225cf1a30Sjl139090 }
202325cf1a30Sjl139090 
202425cf1a30Sjl139090 /* ARGSUSED */
202525cf1a30Sjl139090 uint64_t
202625cf1a30Sjl139090 hvio_iommu_getbypass(devhandle_t dev_hdl, pxu_t *pxu_p, r_addr_t ra,
202725cf1a30Sjl139090     io_attributes_t attr, io_addr_t *io_addr_p)
20287c478bd9Sstevel@tonic-gate {
20297c478bd9Sstevel@tonic-gate 	uint64_t	pfn = MMU_BTOP(ra);
20307c478bd9Sstevel@tonic-gate 
203125cf1a30Sjl139090 	*io_addr_p = hvio_get_bypass_base(pxu_p) | ra |
203225cf1a30Sjl139090 	    (pf_is_memory(pfn) ? 0 : mmu_bypass_noncache(pxu_p));
20337c478bd9Sstevel@tonic-gate 
20347c478bd9Sstevel@tonic-gate 	return (H_EOK);
20357c478bd9Sstevel@tonic-gate }
20367c478bd9Sstevel@tonic-gate 
20377c478bd9Sstevel@tonic-gate /*
20387c478bd9Sstevel@tonic-gate  * Generic IO Interrupt Servies
20397c478bd9Sstevel@tonic-gate  */
20407c478bd9Sstevel@tonic-gate 
20417c478bd9Sstevel@tonic-gate /*
20427c478bd9Sstevel@tonic-gate  * Converts a device specific interrupt number given by the
20437c478bd9Sstevel@tonic-gate  * arguments devhandle and devino into a system specific ino.
20447c478bd9Sstevel@tonic-gate  */
20457c478bd9Sstevel@tonic-gate /* ARGSUSED */
20467c478bd9Sstevel@tonic-gate uint64_t
20477c478bd9Sstevel@tonic-gate hvio_intr_devino_to_sysino(devhandle_t dev_hdl, pxu_t *pxu_p, devino_t devino,
20487c478bd9Sstevel@tonic-gate     sysino_t *sysino)
20497c478bd9Sstevel@tonic-gate {
20507c478bd9Sstevel@tonic-gate 	if (devino > INTERRUPT_MAPPING_ENTRIES) {
20517c478bd9Sstevel@tonic-gate 		DBG(DBG_IB, NULL, "ino %x is invalid\n", devino);
20527c478bd9Sstevel@tonic-gate 		return (H_ENOINTR);
20537c478bd9Sstevel@tonic-gate 	}
20547c478bd9Sstevel@tonic-gate 
20557c478bd9Sstevel@tonic-gate 	*sysino = DEVINO_TO_SYSINO(pxu_p->portid, devino);
20567c478bd9Sstevel@tonic-gate 
20577c478bd9Sstevel@tonic-gate 	return (H_EOK);
20587c478bd9Sstevel@tonic-gate }
20597c478bd9Sstevel@tonic-gate 
20607c478bd9Sstevel@tonic-gate /*
20617c478bd9Sstevel@tonic-gate  * Returns state in intr_valid_state if the interrupt defined by sysino
20627c478bd9Sstevel@tonic-gate  * is valid (enabled) or not-valid (disabled).
20637c478bd9Sstevel@tonic-gate  */
20647c478bd9Sstevel@tonic-gate uint64_t
20657c478bd9Sstevel@tonic-gate hvio_intr_getvalid(devhandle_t dev_hdl, sysino_t sysino,
20667c478bd9Sstevel@tonic-gate     intr_valid_state_t *intr_valid_state)
20677c478bd9Sstevel@tonic-gate {
20687c478bd9Sstevel@tonic-gate 	if (CSRA_BR((caddr_t)dev_hdl, INTERRUPT_MAPPING,
20697c478bd9Sstevel@tonic-gate 	    SYSINO_TO_DEVINO(sysino), ENTRIES_V)) {
20707c478bd9Sstevel@tonic-gate 		*intr_valid_state = INTR_VALID;
20717c478bd9Sstevel@tonic-gate 	} else {
20727c478bd9Sstevel@tonic-gate 		*intr_valid_state = INTR_NOTVALID;
20737c478bd9Sstevel@tonic-gate 	}
20747c478bd9Sstevel@tonic-gate 
20757c478bd9Sstevel@tonic-gate 	return (H_EOK);
20767c478bd9Sstevel@tonic-gate }
20777c478bd9Sstevel@tonic-gate 
20787c478bd9Sstevel@tonic-gate /*
20797c478bd9Sstevel@tonic-gate  * Sets the 'valid' state of the interrupt defined by
20807c478bd9Sstevel@tonic-gate  * the argument sysino to the state defined by the
20817c478bd9Sstevel@tonic-gate  * argument intr_valid_state.
20827c478bd9Sstevel@tonic-gate  */
20837c478bd9Sstevel@tonic-gate uint64_t
20847c478bd9Sstevel@tonic-gate hvio_intr_setvalid(devhandle_t dev_hdl, sysino_t sysino,
20857c478bd9Sstevel@tonic-gate     intr_valid_state_t intr_valid_state)
20867c478bd9Sstevel@tonic-gate {
20877c478bd9Sstevel@tonic-gate 	switch (intr_valid_state) {
20887c478bd9Sstevel@tonic-gate 	case INTR_VALID:
20897c478bd9Sstevel@tonic-gate 		CSRA_BS((caddr_t)dev_hdl, INTERRUPT_MAPPING,
20907c478bd9Sstevel@tonic-gate 		    SYSINO_TO_DEVINO(sysino), ENTRIES_V);
20917c478bd9Sstevel@tonic-gate 		break;
20927c478bd9Sstevel@tonic-gate 	case INTR_NOTVALID:
20937c478bd9Sstevel@tonic-gate 		CSRA_BC((caddr_t)dev_hdl, INTERRUPT_MAPPING,
20947c478bd9Sstevel@tonic-gate 		    SYSINO_TO_DEVINO(sysino), ENTRIES_V);
20957c478bd9Sstevel@tonic-gate 		break;
20967c478bd9Sstevel@tonic-gate 	default:
20977c478bd9Sstevel@tonic-gate 		return (EINVAL);
20987c478bd9Sstevel@tonic-gate 	}
20997c478bd9Sstevel@tonic-gate 
21007c478bd9Sstevel@tonic-gate 	return (H_EOK);
21017c478bd9Sstevel@tonic-gate }
21027c478bd9Sstevel@tonic-gate 
21037c478bd9Sstevel@tonic-gate /*
21047c478bd9Sstevel@tonic-gate  * Returns the current state of the interrupt given by the sysino
21057c478bd9Sstevel@tonic-gate  * argument.
21067c478bd9Sstevel@tonic-gate  */
21077c478bd9Sstevel@tonic-gate uint64_t
21087c478bd9Sstevel@tonic-gate hvio_intr_getstate(devhandle_t dev_hdl, sysino_t sysino,
21097c478bd9Sstevel@tonic-gate     intr_state_t *intr_state)
21107c478bd9Sstevel@tonic-gate {
21117c478bd9Sstevel@tonic-gate 	intr_state_t state;
21127c478bd9Sstevel@tonic-gate 
21137c478bd9Sstevel@tonic-gate 	state = CSRA_FR((caddr_t)dev_hdl, INTERRUPT_CLEAR,
21147c478bd9Sstevel@tonic-gate 	    SYSINO_TO_DEVINO(sysino), ENTRIES_INT_STATE);
21157c478bd9Sstevel@tonic-gate 
21167c478bd9Sstevel@tonic-gate 	switch (state) {
21177c478bd9Sstevel@tonic-gate 	case INTERRUPT_IDLE_STATE:
21187c478bd9Sstevel@tonic-gate 		*intr_state = INTR_IDLE_STATE;
21197c478bd9Sstevel@tonic-gate 		break;
21207c478bd9Sstevel@tonic-gate 	case INTERRUPT_RECEIVED_STATE:
21217c478bd9Sstevel@tonic-gate 		*intr_state = INTR_RECEIVED_STATE;
21227c478bd9Sstevel@tonic-gate 		break;
21237c478bd9Sstevel@tonic-gate 	case INTERRUPT_PENDING_STATE:
21247c478bd9Sstevel@tonic-gate 		*intr_state = INTR_DELIVERED_STATE;
21257c478bd9Sstevel@tonic-gate 		break;
21267c478bd9Sstevel@tonic-gate 	default:
21277c478bd9Sstevel@tonic-gate 		return (EINVAL);
21287c478bd9Sstevel@tonic-gate 	}
21297c478bd9Sstevel@tonic-gate 
21307c478bd9Sstevel@tonic-gate 	return (H_EOK);
21317c478bd9Sstevel@tonic-gate 
21327c478bd9Sstevel@tonic-gate }
21337c478bd9Sstevel@tonic-gate 
21347c478bd9Sstevel@tonic-gate /*
21357c478bd9Sstevel@tonic-gate  * Sets the current state of the interrupt given by the sysino
21367c478bd9Sstevel@tonic-gate  * argument to the value given in the argument intr_state.
21377c478bd9Sstevel@tonic-gate  *
21387c478bd9Sstevel@tonic-gate  * Note: Setting the state to INTR_IDLE clears any pending
21397c478bd9Sstevel@tonic-gate  * interrupt for sysino.
21407c478bd9Sstevel@tonic-gate  */
21417c478bd9Sstevel@tonic-gate uint64_t
21427c478bd9Sstevel@tonic-gate hvio_intr_setstate(devhandle_t dev_hdl, sysino_t sysino,
21437c478bd9Sstevel@tonic-gate     intr_state_t intr_state)
21447c478bd9Sstevel@tonic-gate {
21457c478bd9Sstevel@tonic-gate 	intr_state_t state;
21467c478bd9Sstevel@tonic-gate 
21477c478bd9Sstevel@tonic-gate 	switch (intr_state) {
21487c478bd9Sstevel@tonic-gate 	case INTR_IDLE_STATE:
21497c478bd9Sstevel@tonic-gate 		state = INTERRUPT_IDLE_STATE;
21507c478bd9Sstevel@tonic-gate 		break;
21517c478bd9Sstevel@tonic-gate 	case INTR_DELIVERED_STATE:
21527c478bd9Sstevel@tonic-gate 		state = INTERRUPT_PENDING_STATE;
21537c478bd9Sstevel@tonic-gate 		break;
21547c478bd9Sstevel@tonic-gate 	default:
21557c478bd9Sstevel@tonic-gate 		return (EINVAL);
21567c478bd9Sstevel@tonic-gate 	}
21577c478bd9Sstevel@tonic-gate 
21587c478bd9Sstevel@tonic-gate 	CSRA_FS((caddr_t)dev_hdl, INTERRUPT_CLEAR,
21597c478bd9Sstevel@tonic-gate 	    SYSINO_TO_DEVINO(sysino), ENTRIES_INT_STATE, state);
21607c478bd9Sstevel@tonic-gate 
21617c478bd9Sstevel@tonic-gate 	return (H_EOK);
21627c478bd9Sstevel@tonic-gate }
21637c478bd9Sstevel@tonic-gate 
21647c478bd9Sstevel@tonic-gate /*
21657c478bd9Sstevel@tonic-gate  * Returns the cpuid that is the current target of the
21667c478bd9Sstevel@tonic-gate  * interrupt given by the sysino argument.
21677c478bd9Sstevel@tonic-gate  *
21687c478bd9Sstevel@tonic-gate  * The cpuid value returned is undefined if the target
21697c478bd9Sstevel@tonic-gate  * has not been set via intr_settarget.
21707c478bd9Sstevel@tonic-gate  */
21717c478bd9Sstevel@tonic-gate uint64_t
217225cf1a30Sjl139090 hvio_intr_gettarget(devhandle_t dev_hdl, pxu_t *pxu_p, sysino_t sysino,
217325cf1a30Sjl139090     cpuid_t *cpuid)
21747c478bd9Sstevel@tonic-gate {
217525cf1a30Sjl139090 	switch (PX_CHIP_TYPE(pxu_p)) {
217625cf1a30Sjl139090 	case PX_CHIP_OBERON:
217725cf1a30Sjl139090 		*cpuid = CSRA_FR((caddr_t)dev_hdl, INTERRUPT_MAPPING,
217825cf1a30Sjl139090 		    SYSINO_TO_DEVINO(sysino), ENTRIES_T_DESTID);
217925cf1a30Sjl139090 		break;
218025cf1a30Sjl139090 	case PX_CHIP_FIRE:
21817c478bd9Sstevel@tonic-gate 		*cpuid = CSRA_FR((caddr_t)dev_hdl, INTERRUPT_MAPPING,
21827c478bd9Sstevel@tonic-gate 		    SYSINO_TO_DEVINO(sysino), ENTRIES_T_JPID);
218325cf1a30Sjl139090 		break;
218425cf1a30Sjl139090 	default:
218525cf1a30Sjl139090 		DBG(DBG_CB, NULL, "hvio_intr_gettarget - "
218625cf1a30Sjl139090 		    "unknown chip type: 0x%x\n", PX_CHIP_TYPE(pxu_p));
218725cf1a30Sjl139090 		return (EINVAL);
218825cf1a30Sjl139090 	}
21897c478bd9Sstevel@tonic-gate 
21907c478bd9Sstevel@tonic-gate 	return (H_EOK);
21917c478bd9Sstevel@tonic-gate }
21927c478bd9Sstevel@tonic-gate 
21937c478bd9Sstevel@tonic-gate /*
21947c478bd9Sstevel@tonic-gate  * Set the target cpu for the interrupt defined by the argument
21957c478bd9Sstevel@tonic-gate  * sysino to the target cpu value defined by the argument cpuid.
21967c478bd9Sstevel@tonic-gate  */
21977c478bd9Sstevel@tonic-gate uint64_t
219825cf1a30Sjl139090 hvio_intr_settarget(devhandle_t dev_hdl, pxu_t *pxu_p, sysino_t sysino,
219925cf1a30Sjl139090     cpuid_t cpuid)
22007c478bd9Sstevel@tonic-gate {
22017c478bd9Sstevel@tonic-gate 	uint64_t	val, intr_controller;
22027c478bd9Sstevel@tonic-gate 	uint32_t	ino = SYSINO_TO_DEVINO(sysino);
22037c478bd9Sstevel@tonic-gate 
22047c478bd9Sstevel@tonic-gate 	/*
22057c478bd9Sstevel@tonic-gate 	 * For now, we assign interrupt controller in a round
22067c478bd9Sstevel@tonic-gate 	 * robin fashion.  Later, we may need to come up with
22077c478bd9Sstevel@tonic-gate 	 * a more efficient assignment algorithm.
22087c478bd9Sstevel@tonic-gate 	 */
22097c478bd9Sstevel@tonic-gate 	intr_controller = 0x1ull << (cpuid % 4);
22107c478bd9Sstevel@tonic-gate 
221125cf1a30Sjl139090 	switch (PX_CHIP_TYPE(pxu_p)) {
221225cf1a30Sjl139090 	case PX_CHIP_OBERON:
221325cf1a30Sjl139090 		val = (((cpuid &
221425cf1a30Sjl139090 		    INTERRUPT_MAPPING_ENTRIES_T_DESTID_MASK) <<
221525cf1a30Sjl139090 		    INTERRUPT_MAPPING_ENTRIES_T_DESTID) |
221625cf1a30Sjl139090 		    ((intr_controller &
221725cf1a30Sjl139090 		    INTERRUPT_MAPPING_ENTRIES_INT_CNTRL_NUM_MASK)
221825cf1a30Sjl139090 		    << INTERRUPT_MAPPING_ENTRIES_INT_CNTRL_NUM));
221925cf1a30Sjl139090 		break;
222025cf1a30Sjl139090 	case PX_CHIP_FIRE:
22217c478bd9Sstevel@tonic-gate 		val = (((cpuid & INTERRUPT_MAPPING_ENTRIES_T_JPID_MASK) <<
22227c478bd9Sstevel@tonic-gate 		    INTERRUPT_MAPPING_ENTRIES_T_JPID) |
222325cf1a30Sjl139090 		    ((intr_controller &
222425cf1a30Sjl139090 		    INTERRUPT_MAPPING_ENTRIES_INT_CNTRL_NUM_MASK)
22257c478bd9Sstevel@tonic-gate 		    << INTERRUPT_MAPPING_ENTRIES_INT_CNTRL_NUM));
222625cf1a30Sjl139090 		break;
222725cf1a30Sjl139090 	default:
222825cf1a30Sjl139090 		DBG(DBG_CB, NULL, "hvio_intr_settarget - "
222925cf1a30Sjl139090 		    "unknown chip type: 0x%x\n", PX_CHIP_TYPE(pxu_p));
223025cf1a30Sjl139090 		return (EINVAL);
223125cf1a30Sjl139090 	}
22327c478bd9Sstevel@tonic-gate 
22337c478bd9Sstevel@tonic-gate 	/* For EQ interrupts, set DATA MONDO bit */
223426947304SEvan Yan 	if ((ino >= EQ_1ST_DEVINO) && (ino < (EQ_1ST_DEVINO + EQ_CNT)))
22357c478bd9Sstevel@tonic-gate 		val |= (0x1ull << INTERRUPT_MAPPING_ENTRIES_MDO_MODE);
22367c478bd9Sstevel@tonic-gate 
22377c478bd9Sstevel@tonic-gate 	CSRA_XS((caddr_t)dev_hdl, INTERRUPT_MAPPING, ino, val);
22387c478bd9Sstevel@tonic-gate 
22397c478bd9Sstevel@tonic-gate 	return (H_EOK);
22407c478bd9Sstevel@tonic-gate }
22417c478bd9Sstevel@tonic-gate 
22427c478bd9Sstevel@tonic-gate /*
22437c478bd9Sstevel@tonic-gate  * MSIQ Functions:
22447c478bd9Sstevel@tonic-gate  */
22457c478bd9Sstevel@tonic-gate uint64_t
22467c478bd9Sstevel@tonic-gate hvio_msiq_init(devhandle_t dev_hdl, pxu_t *pxu_p)
22477c478bd9Sstevel@tonic-gate {
22487c478bd9Sstevel@tonic-gate 	CSRA_XS((caddr_t)dev_hdl, EVENT_QUEUE_BASE_ADDRESS, 0,
22497c478bd9Sstevel@tonic-gate 	    (uint64_t)pxu_p->msiq_mapped_p);
22507c478bd9Sstevel@tonic-gate 	DBG(DBG_IB, NULL,
22517c478bd9Sstevel@tonic-gate 	    "hvio_msiq_init: EVENT_QUEUE_BASE_ADDRESS 0x%llx\n",
22527c478bd9Sstevel@tonic-gate 	    CSR_XR((caddr_t)dev_hdl, EVENT_QUEUE_BASE_ADDRESS));
22537c478bd9Sstevel@tonic-gate 
22547c478bd9Sstevel@tonic-gate 	CSRA_XS((caddr_t)dev_hdl, INTERRUPT_MONDO_DATA_0, 0,
2255bbe55e82Sam139583 	    (uint64_t)ID_TO_IGN(PX_CHIP_TYPE(pxu_p),
2256bbe55e82Sam139583 	    pxu_p->portid) << INO_BITS);
22577c478bd9Sstevel@tonic-gate 	DBG(DBG_IB, NULL, "hvio_msiq_init: "
22587c478bd9Sstevel@tonic-gate 	    "INTERRUPT_MONDO_DATA_0: 0x%llx\n",
22597c478bd9Sstevel@tonic-gate 	    CSR_XR((caddr_t)dev_hdl, INTERRUPT_MONDO_DATA_0));
22607c478bd9Sstevel@tonic-gate 
22617c478bd9Sstevel@tonic-gate 	return (H_EOK);
22627c478bd9Sstevel@tonic-gate }
22637c478bd9Sstevel@tonic-gate 
22647c478bd9Sstevel@tonic-gate uint64_t
22657c478bd9Sstevel@tonic-gate hvio_msiq_getvalid(devhandle_t dev_hdl, msiqid_t msiq_id,
22667c478bd9Sstevel@tonic-gate     pci_msiq_valid_state_t *msiq_valid_state)
22677c478bd9Sstevel@tonic-gate {
22687c478bd9Sstevel@tonic-gate 	uint32_t	eq_state;
22697c478bd9Sstevel@tonic-gate 	uint64_t	ret = H_EOK;
22707c478bd9Sstevel@tonic-gate 
22717c478bd9Sstevel@tonic-gate 	eq_state = CSRA_FR((caddr_t)dev_hdl, EVENT_QUEUE_STATE,
22727c478bd9Sstevel@tonic-gate 	    msiq_id, ENTRIES_STATE);
22737c478bd9Sstevel@tonic-gate 
22747c478bd9Sstevel@tonic-gate 	switch (eq_state) {
22757c478bd9Sstevel@tonic-gate 	case EQ_IDLE_STATE:
22767c478bd9Sstevel@tonic-gate 		*msiq_valid_state = PCI_MSIQ_INVALID;
22777c478bd9Sstevel@tonic-gate 		break;
22787c478bd9Sstevel@tonic-gate 	case EQ_ACTIVE_STATE:
22797c478bd9Sstevel@tonic-gate 	case EQ_ERROR_STATE:
22807c478bd9Sstevel@tonic-gate 		*msiq_valid_state = PCI_MSIQ_VALID;
22817c478bd9Sstevel@tonic-gate 		break;
22827c478bd9Sstevel@tonic-gate 	default:
22837c478bd9Sstevel@tonic-gate 		ret = H_EIO;
22847c478bd9Sstevel@tonic-gate 		break;
22857c478bd9Sstevel@tonic-gate 	}
22867c478bd9Sstevel@tonic-gate 
22877c478bd9Sstevel@tonic-gate 	return (ret);
22887c478bd9Sstevel@tonic-gate }
22897c478bd9Sstevel@tonic-gate 
22907c478bd9Sstevel@tonic-gate uint64_t
22917c478bd9Sstevel@tonic-gate hvio_msiq_setvalid(devhandle_t dev_hdl, msiqid_t msiq_id,
22927c478bd9Sstevel@tonic-gate     pci_msiq_valid_state_t msiq_valid_state)
22937c478bd9Sstevel@tonic-gate {
22947c478bd9Sstevel@tonic-gate 	uint64_t	ret = H_EOK;
22957c478bd9Sstevel@tonic-gate 
22967c478bd9Sstevel@tonic-gate 	switch (msiq_valid_state) {
22977c478bd9Sstevel@tonic-gate 	case PCI_MSIQ_INVALID:
22987c478bd9Sstevel@tonic-gate 		CSRA_BS((caddr_t)dev_hdl, EVENT_QUEUE_CONTROL_CLEAR,
22997c478bd9Sstevel@tonic-gate 		    msiq_id, ENTRIES_DIS);
23007c478bd9Sstevel@tonic-gate 		break;
23017c478bd9Sstevel@tonic-gate 	case PCI_MSIQ_VALID:
23027c478bd9Sstevel@tonic-gate 		CSRA_BS((caddr_t)dev_hdl, EVENT_QUEUE_CONTROL_SET,
23037c478bd9Sstevel@tonic-gate 		    msiq_id, ENTRIES_EN);
23047c478bd9Sstevel@tonic-gate 		break;
23057c478bd9Sstevel@tonic-gate 	default:
23067c478bd9Sstevel@tonic-gate 		ret = H_EINVAL;
23077c478bd9Sstevel@tonic-gate 		break;
23087c478bd9Sstevel@tonic-gate 	}
23097c478bd9Sstevel@tonic-gate 
23107c478bd9Sstevel@tonic-gate 	return (ret);
23117c478bd9Sstevel@tonic-gate }
23127c478bd9Sstevel@tonic-gate 
23137c478bd9Sstevel@tonic-gate uint64_t
23147c478bd9Sstevel@tonic-gate hvio_msiq_getstate(devhandle_t dev_hdl, msiqid_t msiq_id,
23157c478bd9Sstevel@tonic-gate     pci_msiq_state_t *msiq_state)
23167c478bd9Sstevel@tonic-gate {
23177c478bd9Sstevel@tonic-gate 	uint32_t	eq_state;
23187c478bd9Sstevel@tonic-gate 	uint64_t	ret = H_EOK;
23197c478bd9Sstevel@tonic-gate 
23207c478bd9Sstevel@tonic-gate 	eq_state = CSRA_FR((caddr_t)dev_hdl, EVENT_QUEUE_STATE,
23217c478bd9Sstevel@tonic-gate 	    msiq_id, ENTRIES_STATE);
23227c478bd9Sstevel@tonic-gate 
23237c478bd9Sstevel@tonic-gate 	switch (eq_state) {
23247c478bd9Sstevel@tonic-gate 	case EQ_IDLE_STATE:
23257c478bd9Sstevel@tonic-gate 	case EQ_ACTIVE_STATE:
23267c478bd9Sstevel@tonic-gate 		*msiq_state = PCI_MSIQ_STATE_IDLE;
23277c478bd9Sstevel@tonic-gate 		break;
23287c478bd9Sstevel@tonic-gate 	case EQ_ERROR_STATE:
23297c478bd9Sstevel@tonic-gate 		*msiq_state = PCI_MSIQ_STATE_ERROR;
23307c478bd9Sstevel@tonic-gate 		break;
23317c478bd9Sstevel@tonic-gate 	default:
23327c478bd9Sstevel@tonic-gate 		ret = H_EIO;
23337c478bd9Sstevel@tonic-gate 	}
23347c478bd9Sstevel@tonic-gate 
23357c478bd9Sstevel@tonic-gate 	return (ret);
23367c478bd9Sstevel@tonic-gate }
23377c478bd9Sstevel@tonic-gate 
23387c478bd9Sstevel@tonic-gate uint64_t
23397c478bd9Sstevel@tonic-gate hvio_msiq_setstate(devhandle_t dev_hdl, msiqid_t msiq_id,
23407c478bd9Sstevel@tonic-gate     pci_msiq_state_t msiq_state)
23417c478bd9Sstevel@tonic-gate {
23427c478bd9Sstevel@tonic-gate 	uint32_t	eq_state;
23437c478bd9Sstevel@tonic-gate 	uint64_t	ret = H_EOK;
23447c478bd9Sstevel@tonic-gate 
23457c478bd9Sstevel@tonic-gate 	eq_state = CSRA_FR((caddr_t)dev_hdl, EVENT_QUEUE_STATE,
23467c478bd9Sstevel@tonic-gate 	    msiq_id, ENTRIES_STATE);
23477c478bd9Sstevel@tonic-gate 
23487c478bd9Sstevel@tonic-gate 	switch (eq_state) {
23497c478bd9Sstevel@tonic-gate 	case EQ_IDLE_STATE:
23507c478bd9Sstevel@tonic-gate 		if (msiq_state == PCI_MSIQ_STATE_ERROR)
23517c478bd9Sstevel@tonic-gate 			ret = H_EIO;
23527c478bd9Sstevel@tonic-gate 		break;
23537c478bd9Sstevel@tonic-gate 	case EQ_ACTIVE_STATE:
23547c478bd9Sstevel@tonic-gate 		if (msiq_state == PCI_MSIQ_STATE_ERROR)
23557c478bd9Sstevel@tonic-gate 			CSRA_BS((caddr_t)dev_hdl, EVENT_QUEUE_CONTROL_SET,
23567c478bd9Sstevel@tonic-gate 			    msiq_id, ENTRIES_ENOVERR);
23577c478bd9Sstevel@tonic-gate 		else
23587c478bd9Sstevel@tonic-gate 			ret = H_EIO;
23597c478bd9Sstevel@tonic-gate 		break;
23607c478bd9Sstevel@tonic-gate 	case EQ_ERROR_STATE:
23617c478bd9Sstevel@tonic-gate 		if (msiq_state == PCI_MSIQ_STATE_IDLE)
23627c478bd9Sstevel@tonic-gate 			CSRA_BS((caddr_t)dev_hdl, EVENT_QUEUE_CONTROL_CLEAR,
23637c478bd9Sstevel@tonic-gate 			    msiq_id, ENTRIES_E2I);
23647c478bd9Sstevel@tonic-gate 		else
23657c478bd9Sstevel@tonic-gate 			ret = H_EIO;
23667c478bd9Sstevel@tonic-gate 		break;
23677c478bd9Sstevel@tonic-gate 	default:
23687c478bd9Sstevel@tonic-gate 		ret = H_EIO;
23697c478bd9Sstevel@tonic-gate 	}
23707c478bd9Sstevel@tonic-gate 
23717c478bd9Sstevel@tonic-gate 	return (ret);
23727c478bd9Sstevel@tonic-gate }
23737c478bd9Sstevel@tonic-gate 
23747c478bd9Sstevel@tonic-gate uint64_t
23757c478bd9Sstevel@tonic-gate hvio_msiq_gethead(devhandle_t dev_hdl, msiqid_t msiq_id,
23767c478bd9Sstevel@tonic-gate     msiqhead_t *msiq_head)
23777c478bd9Sstevel@tonic-gate {
23787c478bd9Sstevel@tonic-gate 	*msiq_head = CSRA_FR((caddr_t)dev_hdl, EVENT_QUEUE_HEAD,
23797c478bd9Sstevel@tonic-gate 	    msiq_id, ENTRIES_HEAD);
23807c478bd9Sstevel@tonic-gate 
23817c478bd9Sstevel@tonic-gate 	return (H_EOK);
23827c478bd9Sstevel@tonic-gate }
23837c478bd9Sstevel@tonic-gate 
23847c478bd9Sstevel@tonic-gate uint64_t
23857c478bd9Sstevel@tonic-gate hvio_msiq_sethead(devhandle_t dev_hdl, msiqid_t msiq_id,
23867c478bd9Sstevel@tonic-gate     msiqhead_t msiq_head)
23877c478bd9Sstevel@tonic-gate {
23887c478bd9Sstevel@tonic-gate 	CSRA_FS((caddr_t)dev_hdl, EVENT_QUEUE_HEAD, msiq_id,
23897c478bd9Sstevel@tonic-gate 	    ENTRIES_HEAD, msiq_head);
23907c478bd9Sstevel@tonic-gate 
23917c478bd9Sstevel@tonic-gate 	return (H_EOK);
23927c478bd9Sstevel@tonic-gate }
23937c478bd9Sstevel@tonic-gate 
23947c478bd9Sstevel@tonic-gate uint64_t
23957c478bd9Sstevel@tonic-gate hvio_msiq_gettail(devhandle_t dev_hdl, msiqid_t msiq_id,
23967c478bd9Sstevel@tonic-gate     msiqtail_t *msiq_tail)
23977c478bd9Sstevel@tonic-gate {
23987c478bd9Sstevel@tonic-gate 	*msiq_tail = CSRA_FR((caddr_t)dev_hdl, EVENT_QUEUE_TAIL,
23997c478bd9Sstevel@tonic-gate 	    msiq_id, ENTRIES_TAIL);
24007c478bd9Sstevel@tonic-gate 
24017c478bd9Sstevel@tonic-gate 	return (H_EOK);
24027c478bd9Sstevel@tonic-gate }
24037c478bd9Sstevel@tonic-gate 
24047c478bd9Sstevel@tonic-gate /*
24057c478bd9Sstevel@tonic-gate  * MSI Functions:
24067c478bd9Sstevel@tonic-gate  */
24077c478bd9Sstevel@tonic-gate uint64_t
24087c478bd9Sstevel@tonic-gate hvio_msi_init(devhandle_t dev_hdl, uint64_t addr32, uint64_t addr64)
24097c478bd9Sstevel@tonic-gate {
24107c478bd9Sstevel@tonic-gate 	/* PCI MEM 32 resources to perform 32 bit MSI transactions */
24117c478bd9Sstevel@tonic-gate 	CSRA_FS((caddr_t)dev_hdl, MSI_32_BIT_ADDRESS, 0,
24127c478bd9Sstevel@tonic-gate 	    ADDR, (uint64_t)addr32 >> MSI_32_BIT_ADDRESS_ADDR);
24131dcb0627Sanbui 	DBG(DBG_IB, NULL, "hvio_msi_init: MSI_32_BIT_ADDRESS: 0x%llx\n",
24147c478bd9Sstevel@tonic-gate 	    CSR_XR((caddr_t)dev_hdl, MSI_32_BIT_ADDRESS));
24157c478bd9Sstevel@tonic-gate 
24167c478bd9Sstevel@tonic-gate 	/* Reserve PCI MEM 64 resources to perform 64 bit MSI transactions */
24177c478bd9Sstevel@tonic-gate 	CSRA_FS((caddr_t)dev_hdl, MSI_64_BIT_ADDRESS, 0,
24187c478bd9Sstevel@tonic-gate 	    ADDR, (uint64_t)addr64 >> MSI_64_BIT_ADDRESS_ADDR);
24191dcb0627Sanbui 	DBG(DBG_IB, NULL, "hvio_msi_init: MSI_64_BIT_ADDRESS: 0x%llx\n",
24207c478bd9Sstevel@tonic-gate 	    CSR_XR((caddr_t)dev_hdl, MSI_64_BIT_ADDRESS));
24217c478bd9Sstevel@tonic-gate 
24227c478bd9Sstevel@tonic-gate 	return (H_EOK);
24237c478bd9Sstevel@tonic-gate }
24247c478bd9Sstevel@tonic-gate 
24257c478bd9Sstevel@tonic-gate uint64_t
24267c478bd9Sstevel@tonic-gate hvio_msi_getmsiq(devhandle_t dev_hdl, msinum_t msi_num,
24277c478bd9Sstevel@tonic-gate     msiqid_t *msiq_id)
24287c478bd9Sstevel@tonic-gate {
24297c478bd9Sstevel@tonic-gate 	*msiq_id = CSRA_FR((caddr_t)dev_hdl, MSI_MAPPING,
24307c478bd9Sstevel@tonic-gate 	    msi_num, ENTRIES_EQNUM);
24317c478bd9Sstevel@tonic-gate 
24327c478bd9Sstevel@tonic-gate 	return (H_EOK);
24337c478bd9Sstevel@tonic-gate }
24347c478bd9Sstevel@tonic-gate 
24357c478bd9Sstevel@tonic-gate uint64_t
24367c478bd9Sstevel@tonic-gate hvio_msi_setmsiq(devhandle_t dev_hdl, msinum_t msi_num,
24377c478bd9Sstevel@tonic-gate     msiqid_t msiq_id)
24387c478bd9Sstevel@tonic-gate {
24397c478bd9Sstevel@tonic-gate 	CSRA_FS((caddr_t)dev_hdl, MSI_MAPPING, msi_num,
24407c478bd9Sstevel@tonic-gate 	    ENTRIES_EQNUM, msiq_id);
24417c478bd9Sstevel@tonic-gate 
24427c478bd9Sstevel@tonic-gate 	return (H_EOK);
24437c478bd9Sstevel@tonic-gate }
24447c478bd9Sstevel@tonic-gate 
24457c478bd9Sstevel@tonic-gate uint64_t
24467c478bd9Sstevel@tonic-gate hvio_msi_getvalid(devhandle_t dev_hdl, msinum_t msi_num,
24477c478bd9Sstevel@tonic-gate     pci_msi_valid_state_t *msi_valid_state)
24487c478bd9Sstevel@tonic-gate {
24497c478bd9Sstevel@tonic-gate 	*msi_valid_state = CSRA_BR((caddr_t)dev_hdl, MSI_MAPPING,
24507c478bd9Sstevel@tonic-gate 	    msi_num, ENTRIES_V);
24517c478bd9Sstevel@tonic-gate 
24527c478bd9Sstevel@tonic-gate 	return (H_EOK);
24537c478bd9Sstevel@tonic-gate }
24547c478bd9Sstevel@tonic-gate 
24557c478bd9Sstevel@tonic-gate uint64_t
24567c478bd9Sstevel@tonic-gate hvio_msi_setvalid(devhandle_t dev_hdl, msinum_t msi_num,
24577c478bd9Sstevel@tonic-gate     pci_msi_valid_state_t msi_valid_state)
24587c478bd9Sstevel@tonic-gate {
24597c478bd9Sstevel@tonic-gate 	uint64_t	ret = H_EOK;
24607c478bd9Sstevel@tonic-gate 
24617c478bd9Sstevel@tonic-gate 	switch (msi_valid_state) {
24627c478bd9Sstevel@tonic-gate 	case PCI_MSI_VALID:
24637c478bd9Sstevel@tonic-gate 		CSRA_BS((caddr_t)dev_hdl, MSI_MAPPING, msi_num,
24647c478bd9Sstevel@tonic-gate 		    ENTRIES_V);
24657c478bd9Sstevel@tonic-gate 		break;
24667c478bd9Sstevel@tonic-gate 	case PCI_MSI_INVALID:
24677c478bd9Sstevel@tonic-gate 		CSRA_BC((caddr_t)dev_hdl, MSI_MAPPING, msi_num,
24687c478bd9Sstevel@tonic-gate 		    ENTRIES_V);
24697c478bd9Sstevel@tonic-gate 		break;
24707c478bd9Sstevel@tonic-gate 	default:
24717c478bd9Sstevel@tonic-gate 		ret = H_EINVAL;
24727c478bd9Sstevel@tonic-gate 	}
24737c478bd9Sstevel@tonic-gate 
24747c478bd9Sstevel@tonic-gate 	return (ret);
24757c478bd9Sstevel@tonic-gate }
24767c478bd9Sstevel@tonic-gate 
24777c478bd9Sstevel@tonic-gate uint64_t
24787c478bd9Sstevel@tonic-gate hvio_msi_getstate(devhandle_t dev_hdl, msinum_t msi_num,
24797c478bd9Sstevel@tonic-gate     pci_msi_state_t *msi_state)
24807c478bd9Sstevel@tonic-gate {
24817c478bd9Sstevel@tonic-gate 	*msi_state = CSRA_BR((caddr_t)dev_hdl, MSI_MAPPING,
24827c478bd9Sstevel@tonic-gate 	    msi_num, ENTRIES_EQWR_N);
24837c478bd9Sstevel@tonic-gate 
24847c478bd9Sstevel@tonic-gate 	return (H_EOK);
24857c478bd9Sstevel@tonic-gate }
24867c478bd9Sstevel@tonic-gate 
24877c478bd9Sstevel@tonic-gate uint64_t
24887c478bd9Sstevel@tonic-gate hvio_msi_setstate(devhandle_t dev_hdl, msinum_t msi_num,
24897c478bd9Sstevel@tonic-gate     pci_msi_state_t msi_state)
24907c478bd9Sstevel@tonic-gate {
24917c478bd9Sstevel@tonic-gate 	uint64_t	ret = H_EOK;
24927c478bd9Sstevel@tonic-gate 
24937c478bd9Sstevel@tonic-gate 	switch (msi_state) {
24947c478bd9Sstevel@tonic-gate 	case PCI_MSI_STATE_IDLE:
24957c478bd9Sstevel@tonic-gate 		CSRA_BS((caddr_t)dev_hdl, MSI_CLEAR, msi_num,
24967c478bd9Sstevel@tonic-gate 		    ENTRIES_EQWR_N);
24977c478bd9Sstevel@tonic-gate 		break;
24987c478bd9Sstevel@tonic-gate 	case PCI_MSI_STATE_DELIVERED:
24997c478bd9Sstevel@tonic-gate 	default:
25007c478bd9Sstevel@tonic-gate 		ret = H_EINVAL;
25017c478bd9Sstevel@tonic-gate 		break;
25027c478bd9Sstevel@tonic-gate 	}
25037c478bd9Sstevel@tonic-gate 
25047c478bd9Sstevel@tonic-gate 	return (ret);
25057c478bd9Sstevel@tonic-gate }
25067c478bd9Sstevel@tonic-gate 
25077c478bd9Sstevel@tonic-gate /*
25087c478bd9Sstevel@tonic-gate  * MSG Functions:
25097c478bd9Sstevel@tonic-gate  */
25107c478bd9Sstevel@tonic-gate uint64_t
25117c478bd9Sstevel@tonic-gate hvio_msg_getmsiq(devhandle_t dev_hdl, pcie_msg_type_t msg_type,
25127c478bd9Sstevel@tonic-gate     msiqid_t *msiq_id)
25137c478bd9Sstevel@tonic-gate {
25147c478bd9Sstevel@tonic-gate 	uint64_t	ret = H_EOK;
25157c478bd9Sstevel@tonic-gate 
25167c478bd9Sstevel@tonic-gate 	switch (msg_type) {
25177c478bd9Sstevel@tonic-gate 	case PCIE_PME_MSG:
25187c478bd9Sstevel@tonic-gate 		*msiq_id = CSR_FR((caddr_t)dev_hdl, PM_PME_MAPPING, EQNUM);
25197c478bd9Sstevel@tonic-gate 		break;
25207c478bd9Sstevel@tonic-gate 	case PCIE_PME_ACK_MSG:
25217c478bd9Sstevel@tonic-gate 		*msiq_id = CSR_FR((caddr_t)dev_hdl, PME_TO_ACK_MAPPING,
25227c478bd9Sstevel@tonic-gate 		    EQNUM);
25237c478bd9Sstevel@tonic-gate 		break;
25247c478bd9Sstevel@tonic-gate 	case PCIE_CORR_MSG:
25257c478bd9Sstevel@tonic-gate 		*msiq_id = CSR_FR((caddr_t)dev_hdl, ERR_COR_MAPPING, EQNUM);
25267c478bd9Sstevel@tonic-gate 		break;
25277c478bd9Sstevel@tonic-gate 	case PCIE_NONFATAL_MSG:
25287c478bd9Sstevel@tonic-gate 		*msiq_id = CSR_FR((caddr_t)dev_hdl, ERR_NONFATAL_MAPPING,
25297c478bd9Sstevel@tonic-gate 		    EQNUM);
25307c478bd9Sstevel@tonic-gate 		break;
25317c478bd9Sstevel@tonic-gate 	case PCIE_FATAL_MSG:
25327c478bd9Sstevel@tonic-gate 		*msiq_id = CSR_FR((caddr_t)dev_hdl, ERR_FATAL_MAPPING, EQNUM);
25337c478bd9Sstevel@tonic-gate 		break;
25347c478bd9Sstevel@tonic-gate 	default:
25357c478bd9Sstevel@tonic-gate 		ret = H_EINVAL;
25367c478bd9Sstevel@tonic-gate 		break;
25377c478bd9Sstevel@tonic-gate 	}
25387c478bd9Sstevel@tonic-gate 
25397c478bd9Sstevel@tonic-gate 	return (ret);
25407c478bd9Sstevel@tonic-gate }
25417c478bd9Sstevel@tonic-gate 
25427c478bd9Sstevel@tonic-gate uint64_t
25437c478bd9Sstevel@tonic-gate hvio_msg_setmsiq(devhandle_t dev_hdl, pcie_msg_type_t msg_type,
25447c478bd9Sstevel@tonic-gate     msiqid_t msiq_id)
25457c478bd9Sstevel@tonic-gate {
25467c478bd9Sstevel@tonic-gate 	uint64_t	ret = H_EOK;
25477c478bd9Sstevel@tonic-gate 
25487c478bd9Sstevel@tonic-gate 	switch (msg_type) {
25497c478bd9Sstevel@tonic-gate 	case PCIE_PME_MSG:
25507c478bd9Sstevel@tonic-gate 		CSR_FS((caddr_t)dev_hdl, PM_PME_MAPPING, EQNUM, msiq_id);
25517c478bd9Sstevel@tonic-gate 		break;
25527c478bd9Sstevel@tonic-gate 	case PCIE_PME_ACK_MSG:
25537c478bd9Sstevel@tonic-gate 		CSR_FS((caddr_t)dev_hdl, PME_TO_ACK_MAPPING, EQNUM, msiq_id);
25547c478bd9Sstevel@tonic-gate 		break;
25557c478bd9Sstevel@tonic-gate 	case PCIE_CORR_MSG:
25567c478bd9Sstevel@tonic-gate 		CSR_FS((caddr_t)dev_hdl, ERR_COR_MAPPING, EQNUM, msiq_id);
25577c478bd9Sstevel@tonic-gate 		break;
25587c478bd9Sstevel@tonic-gate 	case PCIE_NONFATAL_MSG:
25597c478bd9Sstevel@tonic-gate 		CSR_FS((caddr_t)dev_hdl, ERR_NONFATAL_MAPPING, EQNUM, msiq_id);
25607c478bd9Sstevel@tonic-gate 		break;
25617c478bd9Sstevel@tonic-gate 	case PCIE_FATAL_MSG:
25627c478bd9Sstevel@tonic-gate 		CSR_FS((caddr_t)dev_hdl, ERR_FATAL_MAPPING, EQNUM, msiq_id);
25637c478bd9Sstevel@tonic-gate 		break;
25647c478bd9Sstevel@tonic-gate 	default:
25657c478bd9Sstevel@tonic-gate 		ret = H_EINVAL;
25667c478bd9Sstevel@tonic-gate 		break;
25677c478bd9Sstevel@tonic-gate 	}
25687c478bd9Sstevel@tonic-gate 
25697c478bd9Sstevel@tonic-gate 	return (ret);
25707c478bd9Sstevel@tonic-gate }
25717c478bd9Sstevel@tonic-gate 
25727c478bd9Sstevel@tonic-gate uint64_t
25737c478bd9Sstevel@tonic-gate hvio_msg_getvalid(devhandle_t dev_hdl, pcie_msg_type_t msg_type,
25747c478bd9Sstevel@tonic-gate     pcie_msg_valid_state_t *msg_valid_state)
25757c478bd9Sstevel@tonic-gate {
25767c478bd9Sstevel@tonic-gate 	uint64_t	ret = H_EOK;
25777c478bd9Sstevel@tonic-gate 
25787c478bd9Sstevel@tonic-gate 	switch (msg_type) {
25797c478bd9Sstevel@tonic-gate 	case PCIE_PME_MSG:
25807c478bd9Sstevel@tonic-gate 		*msg_valid_state = CSR_BR((caddr_t)dev_hdl, PM_PME_MAPPING, V);
25817c478bd9Sstevel@tonic-gate 		break;
25827c478bd9Sstevel@tonic-gate 	case PCIE_PME_ACK_MSG:
25837c478bd9Sstevel@tonic-gate 		*msg_valid_state = CSR_BR((caddr_t)dev_hdl,
25847c478bd9Sstevel@tonic-gate 		    PME_TO_ACK_MAPPING, V);
25857c478bd9Sstevel@tonic-gate 		break;
25867c478bd9Sstevel@tonic-gate 	case PCIE_CORR_MSG:
25877c478bd9Sstevel@tonic-gate 		*msg_valid_state = CSR_BR((caddr_t)dev_hdl, ERR_COR_MAPPING, V);
25887c478bd9Sstevel@tonic-gate 		break;
25897c478bd9Sstevel@tonic-gate 	case PCIE_NONFATAL_MSG:
25907c478bd9Sstevel@tonic-gate 		*msg_valid_state = CSR_BR((caddr_t)dev_hdl,
25917c478bd9Sstevel@tonic-gate 		    ERR_NONFATAL_MAPPING, V);
25927c478bd9Sstevel@tonic-gate 		break;
25937c478bd9Sstevel@tonic-gate 	case PCIE_FATAL_MSG:
25947c478bd9Sstevel@tonic-gate 		*msg_valid_state = CSR_BR((caddr_t)dev_hdl, ERR_FATAL_MAPPING,
25957c478bd9Sstevel@tonic-gate 		    V);
25967c478bd9Sstevel@tonic-gate 		break;
25977c478bd9Sstevel@tonic-gate 	default:
25987c478bd9Sstevel@tonic-gate 		ret = H_EINVAL;
25997c478bd9Sstevel@tonic-gate 		break;
26007c478bd9Sstevel@tonic-gate 	}
26017c478bd9Sstevel@tonic-gate 
26027c478bd9Sstevel@tonic-gate 	return (ret);
26037c478bd9Sstevel@tonic-gate }
26047c478bd9Sstevel@tonic-gate 
26057c478bd9Sstevel@tonic-gate uint64_t
26067c478bd9Sstevel@tonic-gate hvio_msg_setvalid(devhandle_t dev_hdl, pcie_msg_type_t msg_type,
26077c478bd9Sstevel@tonic-gate     pcie_msg_valid_state_t msg_valid_state)
26087c478bd9Sstevel@tonic-gate {
26097c478bd9Sstevel@tonic-gate 	uint64_t	ret = H_EOK;
26107c478bd9Sstevel@tonic-gate 
26117c478bd9Sstevel@tonic-gate 	switch (msg_valid_state) {
26127c478bd9Sstevel@tonic-gate 	case PCIE_MSG_VALID:
26137c478bd9Sstevel@tonic-gate 		switch (msg_type) {
26147c478bd9Sstevel@tonic-gate 		case PCIE_PME_MSG:
26157c478bd9Sstevel@tonic-gate 			CSR_BS((caddr_t)dev_hdl, PM_PME_MAPPING, V);
26167c478bd9Sstevel@tonic-gate 			break;
26177c478bd9Sstevel@tonic-gate 		case PCIE_PME_ACK_MSG:
26187c478bd9Sstevel@tonic-gate 			CSR_BS((caddr_t)dev_hdl, PME_TO_ACK_MAPPING, V);
26197c478bd9Sstevel@tonic-gate 			break;
26207c478bd9Sstevel@tonic-gate 		case PCIE_CORR_MSG:
26217c478bd9Sstevel@tonic-gate 			CSR_BS((caddr_t)dev_hdl, ERR_COR_MAPPING, V);
26227c478bd9Sstevel@tonic-gate 			break;
26237c478bd9Sstevel@tonic-gate 		case PCIE_NONFATAL_MSG:
26247c478bd9Sstevel@tonic-gate 			CSR_BS((caddr_t)dev_hdl, ERR_NONFATAL_MAPPING, V);
26257c478bd9Sstevel@tonic-gate 			break;
26267c478bd9Sstevel@tonic-gate 		case PCIE_FATAL_MSG:
26277c478bd9Sstevel@tonic-gate 			CSR_BS((caddr_t)dev_hdl, ERR_FATAL_MAPPING, V);
26287c478bd9Sstevel@tonic-gate 			break;
26297c478bd9Sstevel@tonic-gate 		default:
26307c478bd9Sstevel@tonic-gate 			ret = H_EINVAL;
26317c478bd9Sstevel@tonic-gate 			break;
26327c478bd9Sstevel@tonic-gate 		}
26337c478bd9Sstevel@tonic-gate 
26347c478bd9Sstevel@tonic-gate 		break;
26357c478bd9Sstevel@tonic-gate 	case PCIE_MSG_INVALID:
26367c478bd9Sstevel@tonic-gate 		switch (msg_type) {
26377c478bd9Sstevel@tonic-gate 		case PCIE_PME_MSG:
26387c478bd9Sstevel@tonic-gate 			CSR_BC((caddr_t)dev_hdl, PM_PME_MAPPING, V);
26397c478bd9Sstevel@tonic-gate 			break;
26407c478bd9Sstevel@tonic-gate 		case PCIE_PME_ACK_MSG:
26417c478bd9Sstevel@tonic-gate 			CSR_BC((caddr_t)dev_hdl, PME_TO_ACK_MAPPING, V);
26427c478bd9Sstevel@tonic-gate 			break;
26437c478bd9Sstevel@tonic-gate 		case PCIE_CORR_MSG:
26447c478bd9Sstevel@tonic-gate 			CSR_BC((caddr_t)dev_hdl, ERR_COR_MAPPING, V);
26457c478bd9Sstevel@tonic-gate 			break;
26467c478bd9Sstevel@tonic-gate 		case PCIE_NONFATAL_MSG:
26477c478bd9Sstevel@tonic-gate 			CSR_BC((caddr_t)dev_hdl, ERR_NONFATAL_MAPPING, V);
26487c478bd9Sstevel@tonic-gate 			break;
26497c478bd9Sstevel@tonic-gate 		case PCIE_FATAL_MSG:
26507c478bd9Sstevel@tonic-gate 			CSR_BC((caddr_t)dev_hdl, ERR_FATAL_MAPPING, V);
26517c478bd9Sstevel@tonic-gate 			break;
26527c478bd9Sstevel@tonic-gate 		default:
26537c478bd9Sstevel@tonic-gate 			ret = H_EINVAL;
26547c478bd9Sstevel@tonic-gate 			break;
26557c478bd9Sstevel@tonic-gate 		}
26567c478bd9Sstevel@tonic-gate 		break;
26577c478bd9Sstevel@tonic-gate 	default:
26587c478bd9Sstevel@tonic-gate 		ret = H_EINVAL;
26597c478bd9Sstevel@tonic-gate 	}
26607c478bd9Sstevel@tonic-gate 
26617c478bd9Sstevel@tonic-gate 	return (ret);
26627c478bd9Sstevel@tonic-gate }
26637c478bd9Sstevel@tonic-gate 
26647c478bd9Sstevel@tonic-gate /*
26657c478bd9Sstevel@tonic-gate  * Suspend/Resume Functions:
26667c478bd9Sstevel@tonic-gate  *	(pec, mmu, ib)
26677c478bd9Sstevel@tonic-gate  *	cb
26687c478bd9Sstevel@tonic-gate  * Registers saved have all been touched in the XXX_init functions.
26697c478bd9Sstevel@tonic-gate  */
26707c478bd9Sstevel@tonic-gate uint64_t
26717c478bd9Sstevel@tonic-gate hvio_suspend(devhandle_t dev_hdl, pxu_t *pxu_p)
26727c478bd9Sstevel@tonic-gate {
26737c478bd9Sstevel@tonic-gate 	uint64_t	*config_state;
26747c478bd9Sstevel@tonic-gate 	int		total_size;
26757c478bd9Sstevel@tonic-gate 	int		i;
26767c478bd9Sstevel@tonic-gate 
26777c478bd9Sstevel@tonic-gate 	if (msiq_suspend(dev_hdl, pxu_p) != H_EOK)
26787c478bd9Sstevel@tonic-gate 		return (H_EIO);
26797c478bd9Sstevel@tonic-gate 
26807c478bd9Sstevel@tonic-gate 	total_size = PEC_SIZE + MMU_SIZE + IB_SIZE + IB_MAP_SIZE;
26817c478bd9Sstevel@tonic-gate 	config_state = kmem_zalloc(total_size, KM_NOSLEEP);
26827c478bd9Sstevel@tonic-gate 
26837c478bd9Sstevel@tonic-gate 	if (config_state == NULL) {
26847c478bd9Sstevel@tonic-gate 		return (H_EIO);
26857c478bd9Sstevel@tonic-gate 	}
26867c478bd9Sstevel@tonic-gate 
26877c478bd9Sstevel@tonic-gate 	/*
26887c478bd9Sstevel@tonic-gate 	 * Soft state for suspend/resume  from pxu_t
26897c478bd9Sstevel@tonic-gate 	 * uint64_t	*pec_config_state;
26907c478bd9Sstevel@tonic-gate 	 * uint64_t	*mmu_config_state;
26917c478bd9Sstevel@tonic-gate 	 * uint64_t	*ib_intr_map;
26927c478bd9Sstevel@tonic-gate 	 * uint64_t	*ib_config_state;
26937c478bd9Sstevel@tonic-gate 	 * uint64_t	*xcb_config_state;
26947c478bd9Sstevel@tonic-gate 	 */
26957c478bd9Sstevel@tonic-gate 
26967c478bd9Sstevel@tonic-gate 	/* Save the PEC configuration states */
26977c478bd9Sstevel@tonic-gate 	pxu_p->pec_config_state = config_state;
26987c478bd9Sstevel@tonic-gate 	for (i = 0; i < PEC_KEYS; i++) {
269925cf1a30Sjl139090 		if ((pec_config_state_regs[i].chip == PX_CHIP_TYPE(pxu_p)) ||
270025cf1a30Sjl139090 		    (pec_config_state_regs[i].chip == PX_CHIP_UNIDENTIFIED)) {
27017c478bd9Sstevel@tonic-gate 			pxu_p->pec_config_state[i] =
270225cf1a30Sjl139090 			    CSR_XR((caddr_t)dev_hdl,
270325cf1a30Sjl139090 			    pec_config_state_regs[i].reg);
270425cf1a30Sjl139090 		}
27057c478bd9Sstevel@tonic-gate 	}
27067c478bd9Sstevel@tonic-gate 
27077c478bd9Sstevel@tonic-gate 	/* Save the MMU configuration states */
27087c478bd9Sstevel@tonic-gate 	pxu_p->mmu_config_state = pxu_p->pec_config_state + PEC_KEYS;
27097c478bd9Sstevel@tonic-gate 	for (i = 0; i < MMU_KEYS; i++) {
27107c478bd9Sstevel@tonic-gate 		pxu_p->mmu_config_state[i] =
27117c478bd9Sstevel@tonic-gate 		    CSR_XR((caddr_t)dev_hdl, mmu_config_state_regs[i]);
27127c478bd9Sstevel@tonic-gate 	}
27137c478bd9Sstevel@tonic-gate 
27147c478bd9Sstevel@tonic-gate 	/* Save the interrupt mapping registers */
27157c478bd9Sstevel@tonic-gate 	pxu_p->ib_intr_map = pxu_p->mmu_config_state + MMU_KEYS;
27167c478bd9Sstevel@tonic-gate 	for (i = 0; i < INTERRUPT_MAPPING_ENTRIES; i++) {
27177c478bd9Sstevel@tonic-gate 		pxu_p->ib_intr_map[i] =
27187c478bd9Sstevel@tonic-gate 		    CSRA_XR((caddr_t)dev_hdl, INTERRUPT_MAPPING, i);
27197c478bd9Sstevel@tonic-gate 	}
27207c478bd9Sstevel@tonic-gate 
27217c478bd9Sstevel@tonic-gate 	/* Save the IB configuration states */
27227c478bd9Sstevel@tonic-gate 	pxu_p->ib_config_state = pxu_p->ib_intr_map + INTERRUPT_MAPPING_ENTRIES;
27237c478bd9Sstevel@tonic-gate 	for (i = 0; i < IB_KEYS; i++) {
27247c478bd9Sstevel@tonic-gate 		pxu_p->ib_config_state[i] =
27257c478bd9Sstevel@tonic-gate 		    CSR_XR((caddr_t)dev_hdl, ib_config_state_regs[i]);
27267c478bd9Sstevel@tonic-gate 	}
27277c478bd9Sstevel@tonic-gate 
27287c478bd9Sstevel@tonic-gate 	return (H_EOK);
27297c478bd9Sstevel@tonic-gate }
27307c478bd9Sstevel@tonic-gate 
27317c478bd9Sstevel@tonic-gate void
27327c478bd9Sstevel@tonic-gate hvio_resume(devhandle_t dev_hdl, devino_t devino, pxu_t *pxu_p)
27337c478bd9Sstevel@tonic-gate {
27347c478bd9Sstevel@tonic-gate 	int		total_size;
27357c478bd9Sstevel@tonic-gate 	sysino_t	sysino;
27367c478bd9Sstevel@tonic-gate 	int		i;
2737d8d130aeSanbui 	uint64_t	ret;
27387c478bd9Sstevel@tonic-gate 
27397c478bd9Sstevel@tonic-gate 	/* Make sure that suspend actually did occur */
27407c478bd9Sstevel@tonic-gate 	if (!pxu_p->pec_config_state) {
27417c478bd9Sstevel@tonic-gate 		return;
27427c478bd9Sstevel@tonic-gate 	}
27437c478bd9Sstevel@tonic-gate 
27447c478bd9Sstevel@tonic-gate 	/* Restore IB configuration states */
27457c478bd9Sstevel@tonic-gate 	for (i = 0; i < IB_KEYS; i++) {
27467c478bd9Sstevel@tonic-gate 		CSR_XS((caddr_t)dev_hdl, ib_config_state_regs[i],
27477c478bd9Sstevel@tonic-gate 		    pxu_p->ib_config_state[i]);
27487c478bd9Sstevel@tonic-gate 	}
27497c478bd9Sstevel@tonic-gate 
27507c478bd9Sstevel@tonic-gate 	/*
27517c478bd9Sstevel@tonic-gate 	 * Restore the interrupt mapping registers
27527c478bd9Sstevel@tonic-gate 	 * And make sure the intrs are idle.
27537c478bd9Sstevel@tonic-gate 	 */
27547c478bd9Sstevel@tonic-gate 	for (i = 0; i < INTERRUPT_MAPPING_ENTRIES; i++) {
27557c478bd9Sstevel@tonic-gate 		CSRA_FS((caddr_t)dev_hdl, INTERRUPT_CLEAR, i,
27567c478bd9Sstevel@tonic-gate 		    ENTRIES_INT_STATE, INTERRUPT_IDLE_STATE);
27577c478bd9Sstevel@tonic-gate 		CSRA_XS((caddr_t)dev_hdl, INTERRUPT_MAPPING, i,
27587c478bd9Sstevel@tonic-gate 		    pxu_p->ib_intr_map[i]);
27597c478bd9Sstevel@tonic-gate 	}
27607c478bd9Sstevel@tonic-gate 
27617c478bd9Sstevel@tonic-gate 	/* Restore MMU configuration states */
27627c478bd9Sstevel@tonic-gate 	/* Clear the cache. */
27637c478bd9Sstevel@tonic-gate 	CSR_XS((caddr_t)dev_hdl, MMU_TTE_CACHE_INVALIDATE, -1ull);
27647c478bd9Sstevel@tonic-gate 
27657c478bd9Sstevel@tonic-gate 	for (i = 0; i < MMU_KEYS; i++) {
27667c478bd9Sstevel@tonic-gate 		CSR_XS((caddr_t)dev_hdl, mmu_config_state_regs[i],
27677c478bd9Sstevel@tonic-gate 		    pxu_p->mmu_config_state[i]);
27687c478bd9Sstevel@tonic-gate 	}
27697c478bd9Sstevel@tonic-gate 
27707c478bd9Sstevel@tonic-gate 	/* Restore PEC configuration states */
27717c478bd9Sstevel@tonic-gate 	/* Make sure all reset bits are low until error is detected */
27727c478bd9Sstevel@tonic-gate 	CSR_XS((caddr_t)dev_hdl, LPU_RESET, 0ull);
27737c478bd9Sstevel@tonic-gate 
27747c478bd9Sstevel@tonic-gate 	for (i = 0; i < PEC_KEYS; i++) {
277525cf1a30Sjl139090 		if ((pec_config_state_regs[i].chip == PX_CHIP_TYPE(pxu_p)) ||
277625cf1a30Sjl139090 		    (pec_config_state_regs[i].chip == PX_CHIP_UNIDENTIFIED)) {
277725cf1a30Sjl139090 			CSR_XS((caddr_t)dev_hdl, pec_config_state_regs[i].reg,
27787c478bd9Sstevel@tonic-gate 			    pxu_p->pec_config_state[i]);
27797c478bd9Sstevel@tonic-gate 		}
278025cf1a30Sjl139090 	}
27817c478bd9Sstevel@tonic-gate 
27827c478bd9Sstevel@tonic-gate 	/* Enable PCI-E interrupt */
2783d8d130aeSanbui 	if ((ret = hvio_intr_devino_to_sysino(dev_hdl, pxu_p, devino,
2784d8d130aeSanbui 	    &sysino)) != H_EOK) {
2785d8d130aeSanbui 		cmn_err(CE_WARN,
2786d8d130aeSanbui 		    "hvio_resume: hvio_intr_devino_to_sysino failed, "
2787d8d130aeSanbui 		    "ret 0x%lx", ret);
2788d8d130aeSanbui 	}
27897c478bd9Sstevel@tonic-gate 
2790d8d130aeSanbui 	if ((ret =  hvio_intr_setstate(dev_hdl, sysino, INTR_IDLE_STATE))
2791d8d130aeSanbui 	    != H_EOK) {
2792d8d130aeSanbui 		cmn_err(CE_WARN,
2793d8d130aeSanbui 		    "hvio_resume: hvio_intr_setstate failed, "
2794d8d130aeSanbui 		    "ret 0x%lx", ret);
2795d8d130aeSanbui 	}
27967c478bd9Sstevel@tonic-gate 
27977c478bd9Sstevel@tonic-gate 	total_size = PEC_SIZE + MMU_SIZE + IB_SIZE + IB_MAP_SIZE;
27987c478bd9Sstevel@tonic-gate 	kmem_free(pxu_p->pec_config_state, total_size);
27997c478bd9Sstevel@tonic-gate 
28007c478bd9Sstevel@tonic-gate 	pxu_p->pec_config_state = NULL;
28017c478bd9Sstevel@tonic-gate 	pxu_p->mmu_config_state = NULL;
28027c478bd9Sstevel@tonic-gate 	pxu_p->ib_config_state = NULL;
28037c478bd9Sstevel@tonic-gate 	pxu_p->ib_intr_map = NULL;
28047c478bd9Sstevel@tonic-gate 
28057c478bd9Sstevel@tonic-gate 	msiq_resume(dev_hdl, pxu_p);
28067c478bd9Sstevel@tonic-gate }
28077c478bd9Sstevel@tonic-gate 
28087c478bd9Sstevel@tonic-gate uint64_t
28097c478bd9Sstevel@tonic-gate hvio_cb_suspend(devhandle_t dev_hdl, pxu_t *pxu_p)
28107c478bd9Sstevel@tonic-gate {
281125cf1a30Sjl139090 	uint64_t *config_state, *cb_regs;
281225cf1a30Sjl139090 	int i, cb_size, cb_keys;
28137c478bd9Sstevel@tonic-gate 
281425cf1a30Sjl139090 	switch (PX_CHIP_TYPE(pxu_p)) {
281525cf1a30Sjl139090 	case PX_CHIP_OBERON:
281625cf1a30Sjl139090 		cb_size = UBC_SIZE;
281725cf1a30Sjl139090 		cb_keys = UBC_KEYS;
281825cf1a30Sjl139090 		cb_regs = ubc_config_state_regs;
281925cf1a30Sjl139090 		break;
282025cf1a30Sjl139090 	case PX_CHIP_FIRE:
282125cf1a30Sjl139090 		cb_size = JBC_SIZE;
282225cf1a30Sjl139090 		cb_keys = JBC_KEYS;
282325cf1a30Sjl139090 		cb_regs = jbc_config_state_regs;
282425cf1a30Sjl139090 		break;
282525cf1a30Sjl139090 	default:
282625cf1a30Sjl139090 		DBG(DBG_CB, NULL, "hvio_cb_suspend - unknown chip type: 0x%x\n",
282725cf1a30Sjl139090 		    PX_CHIP_TYPE(pxu_p));
282825cf1a30Sjl139090 		break;
282925cf1a30Sjl139090 	}
283025cf1a30Sjl139090 
283125cf1a30Sjl139090 	config_state = kmem_zalloc(cb_size, KM_NOSLEEP);
28327c478bd9Sstevel@tonic-gate 
28337c478bd9Sstevel@tonic-gate 	if (config_state == NULL) {
28347c478bd9Sstevel@tonic-gate 		return (H_EIO);
28357c478bd9Sstevel@tonic-gate 	}
28367c478bd9Sstevel@tonic-gate 
28377c478bd9Sstevel@tonic-gate 	/* Save the configuration states */
28387c478bd9Sstevel@tonic-gate 	pxu_p->xcb_config_state = config_state;
283925cf1a30Sjl139090 	for (i = 0; i < cb_keys; i++) {
28407c478bd9Sstevel@tonic-gate 		pxu_p->xcb_config_state[i] =
284125cf1a30Sjl139090 		    CSR_XR((caddr_t)dev_hdl, cb_regs[i]);
28427c478bd9Sstevel@tonic-gate 	}
28437c478bd9Sstevel@tonic-gate 
28447c478bd9Sstevel@tonic-gate 	return (H_EOK);
28457c478bd9Sstevel@tonic-gate }
28467c478bd9Sstevel@tonic-gate 
28477c478bd9Sstevel@tonic-gate void
28487c478bd9Sstevel@tonic-gate hvio_cb_resume(devhandle_t pci_dev_hdl, devhandle_t xbus_dev_hdl,
28497c478bd9Sstevel@tonic-gate     devino_t devino, pxu_t *pxu_p)
28507c478bd9Sstevel@tonic-gate {
28517c478bd9Sstevel@tonic-gate 	sysino_t sysino;
285225cf1a30Sjl139090 	uint64_t *cb_regs;
285325cf1a30Sjl139090 	int i, cb_size, cb_keys;
2854d8d130aeSanbui 	uint64_t ret;
28557c478bd9Sstevel@tonic-gate 
285625cf1a30Sjl139090 	switch (PX_CHIP_TYPE(pxu_p)) {
285725cf1a30Sjl139090 	case PX_CHIP_OBERON:
285825cf1a30Sjl139090 		cb_size = UBC_SIZE;
285925cf1a30Sjl139090 		cb_keys = UBC_KEYS;
286025cf1a30Sjl139090 		cb_regs = ubc_config_state_regs;
286125cf1a30Sjl139090 		/*
286225cf1a30Sjl139090 		 * No reason to have any reset bits high until an error is
286325cf1a30Sjl139090 		 * detected on the link.
286425cf1a30Sjl139090 		 */
286525cf1a30Sjl139090 		CSR_XS((caddr_t)xbus_dev_hdl, UBC_ERROR_STATUS_CLEAR, -1ull);
286625cf1a30Sjl139090 		break;
286725cf1a30Sjl139090 	case PX_CHIP_FIRE:
286825cf1a30Sjl139090 		cb_size = JBC_SIZE;
286925cf1a30Sjl139090 		cb_keys = JBC_KEYS;
287025cf1a30Sjl139090 		cb_regs = jbc_config_state_regs;
28717c478bd9Sstevel@tonic-gate 		/*
28727c478bd9Sstevel@tonic-gate 		 * No reason to have any reset bits high until an error is
28737c478bd9Sstevel@tonic-gate 		 * detected on the link.
28747c478bd9Sstevel@tonic-gate 		 */
28757c478bd9Sstevel@tonic-gate 		CSR_XS((caddr_t)xbus_dev_hdl, JBC_ERROR_STATUS_CLEAR, -1ull);
287625cf1a30Sjl139090 		break;
287725cf1a30Sjl139090 	default:
287825cf1a30Sjl139090 		DBG(DBG_CB, NULL, "hvio_cb_resume - unknown chip type: 0x%x\n",
287925cf1a30Sjl139090 		    PX_CHIP_TYPE(pxu_p));
288025cf1a30Sjl139090 		break;
288125cf1a30Sjl139090 	}
28827c478bd9Sstevel@tonic-gate 
28837c478bd9Sstevel@tonic-gate 	ASSERT(pxu_p->xcb_config_state);
28847c478bd9Sstevel@tonic-gate 
28857c478bd9Sstevel@tonic-gate 	/* Restore the configuration states */
288625cf1a30Sjl139090 	for (i = 0; i < cb_keys; i++) {
288725cf1a30Sjl139090 		CSR_XS((caddr_t)xbus_dev_hdl, cb_regs[i],
28887c478bd9Sstevel@tonic-gate 		    pxu_p->xcb_config_state[i]);
28897c478bd9Sstevel@tonic-gate 	}
28907c478bd9Sstevel@tonic-gate 
28917c478bd9Sstevel@tonic-gate 	/* Enable XBC interrupt */
2892d8d130aeSanbui 	if ((ret = hvio_intr_devino_to_sysino(pci_dev_hdl, pxu_p, devino,
2893d8d130aeSanbui 	    &sysino)) != H_EOK) {
2894d8d130aeSanbui 		cmn_err(CE_WARN,
2895d8d130aeSanbui 		    "hvio_cb_resume: hvio_intr_devino_to_sysino failed, "
2896d8d130aeSanbui 		    "ret 0x%lx", ret);
2897d8d130aeSanbui 	}
28987c478bd9Sstevel@tonic-gate 
2899d8d130aeSanbui 	if ((ret = hvio_intr_setstate(pci_dev_hdl, sysino, INTR_IDLE_STATE))
2900d8d130aeSanbui 	    != H_EOK) {
2901d8d130aeSanbui 		cmn_err(CE_WARN,
2902d8d130aeSanbui 		    "hvio_cb_resume: hvio_intr_setstate failed, "
2903d8d130aeSanbui 		    "ret 0x%lx", ret);
2904d8d130aeSanbui 	}
29057c478bd9Sstevel@tonic-gate 
290625cf1a30Sjl139090 	kmem_free(pxu_p->xcb_config_state, cb_size);
29077c478bd9Sstevel@tonic-gate 
29087c478bd9Sstevel@tonic-gate 	pxu_p->xcb_config_state = NULL;
29097c478bd9Sstevel@tonic-gate }
29107c478bd9Sstevel@tonic-gate 
29117c478bd9Sstevel@tonic-gate static uint64_t
29127c478bd9Sstevel@tonic-gate msiq_suspend(devhandle_t dev_hdl, pxu_t *pxu_p)
29137c478bd9Sstevel@tonic-gate {
29147c478bd9Sstevel@tonic-gate 	size_t	bufsz;
29157c478bd9Sstevel@tonic-gate 	volatile uint64_t *cur_p;
29167c478bd9Sstevel@tonic-gate 	int i;
29177c478bd9Sstevel@tonic-gate 
29187c478bd9Sstevel@tonic-gate 	bufsz = MSIQ_STATE_SIZE + MSIQ_MAPPING_SIZE + MSIQ_OTHER_SIZE;
29197c478bd9Sstevel@tonic-gate 	if ((pxu_p->msiq_config_state = kmem_zalloc(bufsz, KM_NOSLEEP)) ==
29207c478bd9Sstevel@tonic-gate 	    NULL)
29217c478bd9Sstevel@tonic-gate 		return (H_EIO);
29227c478bd9Sstevel@tonic-gate 
29237c478bd9Sstevel@tonic-gate 	cur_p = pxu_p->msiq_config_state;
29247c478bd9Sstevel@tonic-gate 
29257c478bd9Sstevel@tonic-gate 	/* Save each EQ state */
29267c478bd9Sstevel@tonic-gate 	for (i = 0; i < EVENT_QUEUE_STATE_ENTRIES; i++, cur_p++)
29277c478bd9Sstevel@tonic-gate 		*cur_p = CSRA_XR((caddr_t)dev_hdl, EVENT_QUEUE_STATE, i);
29287c478bd9Sstevel@tonic-gate 
29297c478bd9Sstevel@tonic-gate 	/* Save MSI mapping registers */
29307c478bd9Sstevel@tonic-gate 	for (i = 0; i < MSI_MAPPING_ENTRIES; i++, cur_p++)
29317c478bd9Sstevel@tonic-gate 		*cur_p = CSRA_XR((caddr_t)dev_hdl, MSI_MAPPING, i);
29327c478bd9Sstevel@tonic-gate 
29337c478bd9Sstevel@tonic-gate 	/* Save all other MSIQ registers */
29347c478bd9Sstevel@tonic-gate 	for (i = 0; i < MSIQ_OTHER_KEYS; i++, cur_p++)
29357c478bd9Sstevel@tonic-gate 		*cur_p = CSR_XR((caddr_t)dev_hdl, msiq_config_other_regs[i]);
29367c478bd9Sstevel@tonic-gate 	return (H_EOK);
29377c478bd9Sstevel@tonic-gate }
29387c478bd9Sstevel@tonic-gate 
29397c478bd9Sstevel@tonic-gate static void
29407c478bd9Sstevel@tonic-gate msiq_resume(devhandle_t dev_hdl, pxu_t *pxu_p)
29417c478bd9Sstevel@tonic-gate {
29427c478bd9Sstevel@tonic-gate 	size_t	bufsz;
294301c39501Sjchu 	uint64_t *cur_p, state;
29447c478bd9Sstevel@tonic-gate 	int i;
2945d8d130aeSanbui 	uint64_t ret;
29467c478bd9Sstevel@tonic-gate 
29477c478bd9Sstevel@tonic-gate 	bufsz = MSIQ_STATE_SIZE + MSIQ_MAPPING_SIZE + MSIQ_OTHER_SIZE;
29487c478bd9Sstevel@tonic-gate 	cur_p = pxu_p->msiq_config_state;
29497c478bd9Sstevel@tonic-gate 	/*
29507c478bd9Sstevel@tonic-gate 	 * Initialize EQ base address register and
29517c478bd9Sstevel@tonic-gate 	 * Interrupt Mondo Data 0 register.
29527c478bd9Sstevel@tonic-gate 	 */
2953d8d130aeSanbui 	if ((ret = hvio_msiq_init(dev_hdl, pxu_p)) != H_EOK) {
2954d8d130aeSanbui 		cmn_err(CE_WARN,
2955d8d130aeSanbui 		    "msiq_resume: hvio_msiq_init failed, "
2956d8d130aeSanbui 		    "ret 0x%lx", ret);
2957d8d130aeSanbui 	}
29587c478bd9Sstevel@tonic-gate 
29597c478bd9Sstevel@tonic-gate 	/* Restore EQ states */
29607c478bd9Sstevel@tonic-gate 	for (i = 0; i < EVENT_QUEUE_STATE_ENTRIES; i++, cur_p++) {
296101c39501Sjchu 		state = (*cur_p) & EVENT_QUEUE_STATE_ENTRIES_STATE_MASK;
296201c39501Sjchu 		if ((state == EQ_ACTIVE_STATE) || (state == EQ_ERROR_STATE))
29637c478bd9Sstevel@tonic-gate 			CSRA_BS((caddr_t)dev_hdl, EVENT_QUEUE_CONTROL_SET,
29647c478bd9Sstevel@tonic-gate 			    i, ENTRIES_EN);
29657c478bd9Sstevel@tonic-gate 	}
29667c478bd9Sstevel@tonic-gate 
29677c478bd9Sstevel@tonic-gate 	/* Restore MSI mapping */
29687c478bd9Sstevel@tonic-gate 	for (i = 0; i < MSI_MAPPING_ENTRIES; i++, cur_p++)
29697c478bd9Sstevel@tonic-gate 		CSRA_XS((caddr_t)dev_hdl, MSI_MAPPING, i, *cur_p);
29707c478bd9Sstevel@tonic-gate 
29717c478bd9Sstevel@tonic-gate 	/*
29727c478bd9Sstevel@tonic-gate 	 * Restore all other registers. MSI 32 bit address and
29737c478bd9Sstevel@tonic-gate 	 * MSI 64 bit address are restored as part of this.
29747c478bd9Sstevel@tonic-gate 	 */
29757c478bd9Sstevel@tonic-gate 	for (i = 0; i < MSIQ_OTHER_KEYS; i++, cur_p++)
29767c478bd9Sstevel@tonic-gate 		CSR_XS((caddr_t)dev_hdl, msiq_config_other_regs[i], *cur_p);
29777c478bd9Sstevel@tonic-gate 
29787c478bd9Sstevel@tonic-gate 	kmem_free(pxu_p->msiq_config_state, bufsz);
29797c478bd9Sstevel@tonic-gate 	pxu_p->msiq_config_state = NULL;
29807c478bd9Sstevel@tonic-gate }
29817c478bd9Sstevel@tonic-gate 
29827c478bd9Sstevel@tonic-gate /*
29837c478bd9Sstevel@tonic-gate  * sends PME_Turn_Off message to put the link in L2/L3 ready state.
29847c478bd9Sstevel@tonic-gate  * called by px_goto_l23ready.
29857c478bd9Sstevel@tonic-gate  * returns DDI_SUCCESS or DDI_FAILURE
29867c478bd9Sstevel@tonic-gate  */
29877c478bd9Sstevel@tonic-gate int
29887c478bd9Sstevel@tonic-gate px_send_pme_turnoff(caddr_t csr_base)
29897c478bd9Sstevel@tonic-gate {
29907c478bd9Sstevel@tonic-gate 	volatile uint64_t reg;
29917c478bd9Sstevel@tonic-gate 
29927c478bd9Sstevel@tonic-gate 	reg = CSR_XR(csr_base, TLU_PME_TURN_OFF_GENERATE);
29937c478bd9Sstevel@tonic-gate 	/* If already pending, return failure */
29947c478bd9Sstevel@tonic-gate 	if (reg & (1ull << TLU_PME_TURN_OFF_GENERATE_PTO)) {
29951a887b2eSjchu 		DBG(DBG_PWR, NULL, "send_pme_turnoff: pending PTO bit "
29961a887b2eSjchu 		    "tlu_pme_turn_off_generate = %x\n", reg);
29977c478bd9Sstevel@tonic-gate 		return (DDI_FAILURE);
29987c478bd9Sstevel@tonic-gate 	}
2999f8d2de6bSjchu 
30007c478bd9Sstevel@tonic-gate 	/* write to PME_Turn_off reg to boradcast */
30017c478bd9Sstevel@tonic-gate 	reg |= (1ull << TLU_PME_TURN_OFF_GENERATE_PTO);
30027c478bd9Sstevel@tonic-gate 	CSR_XS(csr_base,  TLU_PME_TURN_OFF_GENERATE, reg);
30031a887b2eSjchu 
30047c478bd9Sstevel@tonic-gate 	return (DDI_SUCCESS);
30057c478bd9Sstevel@tonic-gate }
30061a887b2eSjchu 
30071a887b2eSjchu /*
30081a887b2eSjchu  * Checks for link being in L1idle state.
30091a887b2eSjchu  * Returns
30101a887b2eSjchu  * DDI_SUCCESS - if the link is in L1idle
30111a887b2eSjchu  * DDI_FAILURE - if the link is not in L1idle
30121a887b2eSjchu  */
30131a887b2eSjchu int
30141a887b2eSjchu px_link_wait4l1idle(caddr_t csr_base)
30151a887b2eSjchu {
30161a887b2eSjchu 	uint8_t ltssm_state;
30171a887b2eSjchu 	int ntries = px_max_l1_tries;
30181a887b2eSjchu 
30191a887b2eSjchu 	while (ntries > 0) {
30201a887b2eSjchu 		ltssm_state = CSR_FR(csr_base, LPU_LTSSM_STATUS1, LTSSM_STATE);
30211a887b2eSjchu 		if (ltssm_state == LPU_LTSSM_L1_IDLE || (--ntries <= 0))
30221a887b2eSjchu 			break;
30231a887b2eSjchu 		delay(1);
30241a887b2eSjchu 	}
30251a887b2eSjchu 	DBG(DBG_PWR, NULL, "check_for_l1idle: ltssm_state %x\n", ltssm_state);
30261a887b2eSjchu 	return ((ltssm_state == LPU_LTSSM_L1_IDLE) ? DDI_SUCCESS : DDI_FAILURE);
30271a887b2eSjchu }
30281a887b2eSjchu 
30291a887b2eSjchu /*
30301a887b2eSjchu  * Tranisition the link to L0, after it is down.
30311a887b2eSjchu  */
30321a887b2eSjchu int
30331a887b2eSjchu px_link_retrain(caddr_t csr_base)
30341a887b2eSjchu {
30351a887b2eSjchu 	volatile uint64_t reg;
30361a887b2eSjchu 
30371a887b2eSjchu 	reg = CSR_XR(csr_base, TLU_CONTROL);
30381a887b2eSjchu 	if (!(reg & (1ull << TLU_REMAIN_DETECT_QUIET))) {
30391a887b2eSjchu 		DBG(DBG_PWR, NULL, "retrain_link: detect.quiet bit not set\n");
30401a887b2eSjchu 		return (DDI_FAILURE);
30411a887b2eSjchu 	}
30421a887b2eSjchu 
30431a887b2eSjchu 	/* Clear link down bit in TLU Other Event Clear Status Register. */
30441a887b2eSjchu 	CSR_BS(csr_base, TLU_OTHER_EVENT_STATUS_CLEAR, LDN_P);
30451a887b2eSjchu 
30461a887b2eSjchu 	/* Clear Drain bit in TLU Status Register */
30471a887b2eSjchu 	CSR_BS(csr_base, TLU_STATUS, DRAIN);
30481a887b2eSjchu 
30491a887b2eSjchu 	/* Clear Remain in Detect.Quiet bit in TLU Control Register */
30501a887b2eSjchu 	reg = CSR_XR(csr_base, TLU_CONTROL);
30511a887b2eSjchu 	reg &= ~(1ull << TLU_REMAIN_DETECT_QUIET);
30521a887b2eSjchu 	CSR_XS(csr_base, TLU_CONTROL, reg);
30531a887b2eSjchu 
30541a887b2eSjchu 	return (DDI_SUCCESS);
30551a887b2eSjchu }
30561a887b2eSjchu 
30571a887b2eSjchu void
30581a887b2eSjchu px_enable_detect_quiet(caddr_t csr_base)
30591a887b2eSjchu {
30601a887b2eSjchu 	volatile uint64_t tlu_ctrl;
30611a887b2eSjchu 
30621a887b2eSjchu 	tlu_ctrl = CSR_XR(csr_base, TLU_CONTROL);
30631a887b2eSjchu 	tlu_ctrl |= (1ull << TLU_REMAIN_DETECT_QUIET);
30641a887b2eSjchu 	CSR_XS(csr_base, TLU_CONTROL, tlu_ctrl);
30651a887b2eSjchu }
306625cf1a30Sjl139090 
306725cf1a30Sjl139090 static uint_t
306825cf1a30Sjl139090 oberon_hp_pwron(caddr_t csr_base)
306925cf1a30Sjl139090 {
307025cf1a30Sjl139090 	volatile uint64_t reg;
30713c4226f9Spjha 	boolean_t link_retry, link_up;
30723c4226f9Spjha 	int loop, i;
307325cf1a30Sjl139090 
3074f94c6026Sjj156685 	DBG(DBG_HP, NULL, "oberon_hp_pwron the slot\n");
307525cf1a30Sjl139090 
307625cf1a30Sjl139090 	/* Check Leaf Reset status */
307725cf1a30Sjl139090 	reg = CSR_XR(csr_base, ILU_ERROR_LOG_ENABLE);
307825cf1a30Sjl139090 	if (!(reg & (1ull << ILU_ERROR_LOG_ENABLE_SPARE3))) {
3079f94c6026Sjj156685 		DBG(DBG_HP, NULL, "oberon_hp_pwron fails: leaf not reset\n");
308025cf1a30Sjl139090 		goto fail;
308125cf1a30Sjl139090 	}
308225cf1a30Sjl139090 
3083b6b3bf89Spjha 	/* Check HP Capable */
3084b6b3bf89Spjha 	if (!CSR_BR(csr_base, TLU_SLOT_CAPABILITIES, HP)) {
3085b6b3bf89Spjha 		DBG(DBG_HP, NULL, "oberon_hp_pwron fails: leaf not "
3086b6b3bf89Spjha 		    "hotplugable\n");
3087b6b3bf89Spjha 		goto fail;
3088b6b3bf89Spjha 	}
3089b6b3bf89Spjha 
309025cf1a30Sjl139090 	/* Check Slot status */
309125cf1a30Sjl139090 	reg = CSR_XR(csr_base, TLU_SLOT_STATUS);
309225cf1a30Sjl139090 	if (!(reg & (1ull << TLU_SLOT_STATUS_PSD)) ||
3093ba640a72Sjj156685 	    (reg & (1ull << TLU_SLOT_STATUS_MRLS))) {
3094f94c6026Sjj156685 		DBG(DBG_HP, NULL, "oberon_hp_pwron fails: slot status %lx\n",
309525cf1a30Sjl139090 		    reg);
309625cf1a30Sjl139090 		goto fail;
309725cf1a30Sjl139090 	}
309825cf1a30Sjl139090 
309925cf1a30Sjl139090 	/* Blink power LED, this is done from pciehpc already */
310025cf1a30Sjl139090 
310125cf1a30Sjl139090 	/* Turn on slot power */
310225cf1a30Sjl139090 	CSR_BS(csr_base, HOTPLUG_CONTROL, PWREN);
310325cf1a30Sjl139090 
3104ba640a72Sjj156685 	/* power fault detection */
3105ba640a72Sjj156685 	delay(drv_usectohz(25000));
3106ba640a72Sjj156685 	CSR_BS(csr_base, TLU_SLOT_STATUS, PWFD);
3107ba640a72Sjj156685 	CSR_BC(csr_base, HOTPLUG_CONTROL, PWREN);
3108ba640a72Sjj156685 
310925cf1a30Sjl139090 	/* wait to check power state */
311025cf1a30Sjl139090 	delay(drv_usectohz(25000));
311125cf1a30Sjl139090 
3112ba640a72Sjj156685 	if (!CSR_BR(csr_base, TLU_SLOT_STATUS, PWFD)) {
311392e1ac0dSjj156685 		DBG(DBG_HP, NULL, "oberon_hp_pwron fails: power fault\n");
311492e1ac0dSjj156685 		goto fail1;
311592e1ac0dSjj156685 	}
311692e1ac0dSjj156685 
311792e1ac0dSjj156685 	/* power is good */
3118ba640a72Sjj156685 	CSR_BS(csr_base, HOTPLUG_CONTROL, PWREN);
3119ba640a72Sjj156685 
3120ba640a72Sjj156685 	delay(drv_usectohz(25000));
3121ba640a72Sjj156685 	CSR_BS(csr_base, TLU_SLOT_STATUS, PWFD);
312292e1ac0dSjj156685 	CSR_BS(csr_base, TLU_SLOT_CONTROL, PWFDEN);
312392e1ac0dSjj156685 
312492e1ac0dSjj156685 	/* Turn on slot clock */
312592e1ac0dSjj156685 	CSR_BS(csr_base, HOTPLUG_CONTROL, CLKEN);
312692e1ac0dSjj156685 
31273c4226f9Spjha 	link_up = B_FALSE;
31283c4226f9Spjha 	link_retry = B_FALSE;
31293c4226f9Spjha 
31303c4226f9Spjha 	for (loop = 0; (loop < link_retry_count) && (link_up == B_FALSE);
31313c4226f9Spjha 	    loop++) {
31323c4226f9Spjha 		if (link_retry == B_TRUE) {
31333c4226f9Spjha 			DBG(DBG_HP, NULL, "oberon_hp_pwron : retry link loop "
31343c4226f9Spjha 			    "%d\n", loop);
31353c4226f9Spjha 			CSR_BS(csr_base, TLU_CONTROL, DRN_TR_DIS);
31363c4226f9Spjha 			CSR_XS(csr_base, FLP_PORT_CONTROL, 0x1);
31373c4226f9Spjha 			delay(drv_usectohz(10000));
31383c4226f9Spjha 			CSR_BC(csr_base, TLU_CONTROL, DRN_TR_DIS);
31393c4226f9Spjha 			CSR_BS(csr_base, TLU_DIAGNOSTIC, IFC_DIS);
31403c4226f9Spjha 			CSR_BC(csr_base, HOTPLUG_CONTROL, N_PERST);
31413c4226f9Spjha 			delay(drv_usectohz(50000));
31423c4226f9Spjha 		}
31433c4226f9Spjha 
314492e1ac0dSjj156685 		/* Release PCI-E Reset */
31453c4226f9Spjha 		delay(drv_usectohz(wait_perst));
314692e1ac0dSjj156685 		CSR_BS(csr_base, HOTPLUG_CONTROL, N_PERST);
314792e1ac0dSjj156685 
314892e1ac0dSjj156685 		/*
314992e1ac0dSjj156685 		 * Open events' mask
315092e1ac0dSjj156685 		 * This should be done from pciehpc already
315192e1ac0dSjj156685 		 */
315292e1ac0dSjj156685 
31533c4226f9Spjha 		/* Enable PCIE port */
31543c4226f9Spjha 		delay(drv_usectohz(wait_enable_port));
31553c4226f9Spjha 		CSR_BS(csr_base, TLU_CONTROL, DRN_TR_DIS);
31563c4226f9Spjha 		CSR_XS(csr_base, FLP_PORT_CONTROL, 0x20);
31573c4226f9Spjha 
31583c4226f9Spjha 		/* wait for the link up */
31591dcb0627Sanbui 		/* BEGIN CSTYLED */
31603c4226f9Spjha 		for (i = 0; (i < 2) && (link_up == B_FALSE); i++) {
3161b6b3bf89Spjha 			delay(drv_usectohz(link_status_check));
31623c4226f9Spjha 			reg = CSR_XR(csr_base, DLU_LINK_LAYER_STATUS);
31633c4226f9Spjha 
31643c4226f9Spjha 		if ((((reg >> DLU_LINK_LAYER_STATUS_INIT_FC_SM_STS) &
31653c4226f9Spjha 		    DLU_LINK_LAYER_STATUS_INIT_FC_SM_STS_MASK) ==
31663c4226f9Spjha 		    DLU_LINK_LAYER_STATUS_INIT_FC_SM_STS_FC_INIT_DONE) &&
31673c4226f9Spjha 		    (reg & (1ull << DLU_LINK_LAYER_STATUS_DLUP_STS)) &&
316826947304SEvan Yan 		    ((reg &
316926947304SEvan Yan 		    DLU_LINK_LAYER_STATUS_LNK_STATE_MACH_STS_MASK) ==
31703c4226f9Spjha 		    DLU_LINK_LAYER_STATUS_LNK_STATE_MACH_STS_DL_ACTIVE)) {
317126947304SEvan Yan 			DBG(DBG_HP, NULL, "oberon_hp_pwron : "
317226947304SEvan Yan 			    "link is up\n");
31733c4226f9Spjha 			link_up = B_TRUE;
31743c4226f9Spjha 		} else
31753c4226f9Spjha 			link_retry = B_TRUE;
317626947304SEvan Yan 
31773c4226f9Spjha 		}
31781dcb0627Sanbui 		/* END CSTYLED */
31793c4226f9Spjha 	}
31803c4226f9Spjha 
31813c4226f9Spjha 	if (link_up == B_FALSE) {
31823c4226f9Spjha 		DBG(DBG_HP, NULL, "oberon_hp_pwron fails to enable "
31833c4226f9Spjha 		    "PCI-E port\n");
31843c4226f9Spjha 		goto fail2;
31853c4226f9Spjha 	}
31863c4226f9Spjha 
31873c4226f9Spjha 	/* link is up */
31883c4226f9Spjha 	CSR_BC(csr_base, TLU_DIAGNOSTIC, IFC_DIS);
31893c4226f9Spjha 	CSR_BS(csr_base, FLP_PORT_ACTIVE_STATUS, TRAIN_ERROR);
31903c4226f9Spjha 	CSR_BS(csr_base, TLU_UNCORRECTABLE_ERROR_STATUS_CLEAR, TE_P);
31913c4226f9Spjha 	CSR_BS(csr_base, TLU_UNCORRECTABLE_ERROR_STATUS_CLEAR, TE_S);
31923c4226f9Spjha 	CSR_BC(csr_base, TLU_CONTROL, DRN_TR_DIS);
31933c4226f9Spjha 
31943c4226f9Spjha 	/* Restore LUP/LDN */
31953c4226f9Spjha 	reg = CSR_XR(csr_base, TLU_OTHER_EVENT_LOG_ENABLE);
31963c4226f9Spjha 	if (px_tlu_oe_log_mask & (1ull << TLU_OTHER_EVENT_STATUS_SET_LUP_P))
31973c4226f9Spjha 		reg |= 1ull << TLU_OTHER_EVENT_STATUS_SET_LUP_P;
31983c4226f9Spjha 	if (px_tlu_oe_log_mask & (1ull << TLU_OTHER_EVENT_STATUS_SET_LDN_P))
31993c4226f9Spjha 		reg |= 1ull << TLU_OTHER_EVENT_STATUS_SET_LDN_P;
32003c4226f9Spjha 	if (px_tlu_oe_log_mask & (1ull << TLU_OTHER_EVENT_STATUS_SET_LUP_S))
32013c4226f9Spjha 		reg |= 1ull << TLU_OTHER_EVENT_STATUS_SET_LUP_S;
32023c4226f9Spjha 	if (px_tlu_oe_log_mask & (1ull << TLU_OTHER_EVENT_STATUS_SET_LDN_S))
32033c4226f9Spjha 		reg |= 1ull << TLU_OTHER_EVENT_STATUS_SET_LDN_S;
32043c4226f9Spjha 	CSR_XS(csr_base, TLU_OTHER_EVENT_LOG_ENABLE, reg);
32053c4226f9Spjha 
320692e1ac0dSjj156685 	/*
320792e1ac0dSjj156685 	 * Initialize Leaf
320892e1ac0dSjj156685 	 * SPLS = 00b, SPLV = 11001b, i.e. 25W
320992e1ac0dSjj156685 	 */
321092e1ac0dSjj156685 	reg = CSR_XR(csr_base, TLU_SLOT_CAPABILITIES);
321192e1ac0dSjj156685 	reg &= ~(TLU_SLOT_CAPABILITIES_SPLS_MASK <<
321292e1ac0dSjj156685 	    TLU_SLOT_CAPABILITIES_SPLS);
321392e1ac0dSjj156685 	reg &= ~(TLU_SLOT_CAPABILITIES_SPLV_MASK <<
3214b6b3bf89Spjha 	    TLU_SLOT_CAPABILITIES_SPLV);
3215b6b3bf89Spjha 	reg |= (0x19 << TLU_SLOT_CAPABILITIES_SPLV);
321692e1ac0dSjj156685 	CSR_XS(csr_base, TLU_SLOT_CAPABILITIES, reg);
321792e1ac0dSjj156685 
321892e1ac0dSjj156685 	/* Turn on Power LED */
321992e1ac0dSjj156685 	reg = CSR_XR(csr_base, TLU_SLOT_CONTROL);
322092e1ac0dSjj156685 	reg &= ~PCIE_SLOTCTL_PWR_INDICATOR_MASK;
322192e1ac0dSjj156685 	reg = pcie_slotctl_pwr_indicator_set(reg,
322292e1ac0dSjj156685 	    PCIE_SLOTCTL_INDICATOR_STATE_ON);
322392e1ac0dSjj156685 	CSR_XS(csr_base, TLU_SLOT_CONTROL, reg);
322492e1ac0dSjj156685 
322592e1ac0dSjj156685 	/* Notify to SCF */
3226ba640a72Sjj156685 	if (CSR_BR(csr_base, HOTPLUG_CONTROL, SLOTPON))
3227ba640a72Sjj156685 		CSR_BC(csr_base, HOTPLUG_CONTROL, SLOTPON);
3228ba640a72Sjj156685 	else
322992e1ac0dSjj156685 		CSR_BS(csr_base, HOTPLUG_CONTROL, SLOTPON);
3230ba640a72Sjj156685 
32311f4643f9Sgovinda 	/* Wait for one second */
32321f4643f9Sgovinda 	delay(drv_usectohz(1000000));
32331f4643f9Sgovinda 
323425cf1a30Sjl139090 	return (DDI_SUCCESS);
323525cf1a30Sjl139090 
323692e1ac0dSjj156685 fail2:
323792e1ac0dSjj156685 	/* Link up is failed */
323892e1ac0dSjj156685 	CSR_BS(csr_base, FLP_PORT_CONTROL, PORT_DIS);
323992e1ac0dSjj156685 	CSR_BC(csr_base, HOTPLUG_CONTROL, N_PERST);
324092e1ac0dSjj156685 	delay(drv_usectohz(150));
324192e1ac0dSjj156685 
324292e1ac0dSjj156685 	CSR_BC(csr_base, HOTPLUG_CONTROL, CLKEN);
324392e1ac0dSjj156685 	delay(drv_usectohz(100));
324492e1ac0dSjj156685 
324592e1ac0dSjj156685 fail1:
324692e1ac0dSjj156685 	CSR_BC(csr_base, TLU_SLOT_CONTROL, PWFDEN);
324792e1ac0dSjj156685 
324892e1ac0dSjj156685 	CSR_BC(csr_base, HOTPLUG_CONTROL, PWREN);
324992e1ac0dSjj156685 
325092e1ac0dSjj156685 	reg = CSR_XR(csr_base, TLU_SLOT_CONTROL);
325192e1ac0dSjj156685 	reg &= ~PCIE_SLOTCTL_PWR_INDICATOR_MASK;
325292e1ac0dSjj156685 	reg = pcie_slotctl_pwr_indicator_set(reg,
325392e1ac0dSjj156685 	    PCIE_SLOTCTL_INDICATOR_STATE_OFF);
325492e1ac0dSjj156685 	CSR_XS(csr_base, TLU_SLOT_CONTROL, reg);
325592e1ac0dSjj156685 
325692e1ac0dSjj156685 	CSR_BC(csr_base, TLU_SLOT_STATUS, PWFD);
325792e1ac0dSjj156685 
325825cf1a30Sjl139090 fail:
3259055d7c80Scarlsonj 	return ((uint_t)DDI_FAILURE);
326025cf1a30Sjl139090 }
326125cf1a30Sjl139090 
32621f4643f9Sgovinda hrtime_t oberon_leaf_reset_timeout = 120ll * NANOSEC;	/* 120 seconds */
32631f4643f9Sgovinda 
326425cf1a30Sjl139090 static uint_t
326525cf1a30Sjl139090 oberon_hp_pwroff(caddr_t csr_base)
326625cf1a30Sjl139090 {
326725cf1a30Sjl139090 	volatile uint64_t reg;
3268597077b2Sjj156685 	volatile uint64_t reg_tluue, reg_tluce;
32691f4643f9Sgovinda 	hrtime_t start_time, end_time;
327025cf1a30Sjl139090 
3271f94c6026Sjj156685 	DBG(DBG_HP, NULL, "oberon_hp_pwroff the slot\n");
327225cf1a30Sjl139090 
327325cf1a30Sjl139090 	/* Blink power LED, this is done from pciehpc already */
327425cf1a30Sjl139090 
327525cf1a30Sjl139090 	/* Clear Slot Event */
327625cf1a30Sjl139090 	CSR_BS(csr_base, TLU_SLOT_STATUS, PSDC);
3277ba640a72Sjj156685 	CSR_BS(csr_base, TLU_SLOT_STATUS, PWFD);
327825cf1a30Sjl139090 
327925cf1a30Sjl139090 	/* DRN_TR_DIS on */
328025cf1a30Sjl139090 	CSR_BS(csr_base, TLU_CONTROL, DRN_TR_DIS);
3281ba640a72Sjj156685 	delay(drv_usectohz(10000));
328225cf1a30Sjl139090 
32833c4226f9Spjha 	/* Disable LUP/LDN */
32843c4226f9Spjha 	reg = CSR_XR(csr_base, TLU_OTHER_EVENT_LOG_ENABLE);
32853c4226f9Spjha 	reg &= ~((1ull << TLU_OTHER_EVENT_STATUS_SET_LDN_P) |
32863c4226f9Spjha 	    (1ull << TLU_OTHER_EVENT_STATUS_SET_LUP_P) |
32873c4226f9Spjha 	    (1ull << TLU_OTHER_EVENT_STATUS_SET_LDN_S) |
32883c4226f9Spjha 	    (1ull << TLU_OTHER_EVENT_STATUS_SET_LUP_S));
32893c4226f9Spjha 	CSR_XS(csr_base, TLU_OTHER_EVENT_LOG_ENABLE, reg);
32903c4226f9Spjha 
3291597077b2Sjj156685 	/* Save the TLU registers */
3292597077b2Sjj156685 	reg_tluue = CSR_XR(csr_base, TLU_UNCORRECTABLE_ERROR_LOG_ENABLE);
3293597077b2Sjj156685 	reg_tluce = CSR_XR(csr_base, TLU_CORRECTABLE_ERROR_LOG_ENABLE);
3294597077b2Sjj156685 	/* All clear */
3295597077b2Sjj156685 	CSR_XS(csr_base, TLU_UNCORRECTABLE_ERROR_LOG_ENABLE, 0);
3296597077b2Sjj156685 	CSR_XS(csr_base, TLU_CORRECTABLE_ERROR_LOG_ENABLE, 0);
3297597077b2Sjj156685 
329825cf1a30Sjl139090 	/* Disable port */
329925cf1a30Sjl139090 	CSR_BS(csr_base, FLP_PORT_CONTROL, PORT_DIS);
330025cf1a30Sjl139090 
330125cf1a30Sjl139090 	/* PCIE reset */
3302ba640a72Sjj156685 	delay(drv_usectohz(10000));
330325cf1a30Sjl139090 	CSR_BC(csr_base, HOTPLUG_CONTROL, N_PERST);
330425cf1a30Sjl139090 
330525cf1a30Sjl139090 	/* PCIE clock stop */
3306ba640a72Sjj156685 	delay(drv_usectohz(150));
330725cf1a30Sjl139090 	CSR_BC(csr_base, HOTPLUG_CONTROL, CLKEN);
330825cf1a30Sjl139090 
330925cf1a30Sjl139090 	/* Turn off slot power */
3310ba640a72Sjj156685 	delay(drv_usectohz(100));
331125cf1a30Sjl139090 	CSR_BC(csr_base, TLU_SLOT_CONTROL, PWFDEN);
331225cf1a30Sjl139090 	CSR_BC(csr_base, HOTPLUG_CONTROL, PWREN);
3313ba640a72Sjj156685 	delay(drv_usectohz(25000));
3314ba640a72Sjj156685 	CSR_BS(csr_base, TLU_SLOT_STATUS, PWFD);
331525cf1a30Sjl139090 
331625cf1a30Sjl139090 	/* write 0 to bit 7 of ILU Error Log Enable Register */
3317ba640a72Sjj156685 	CSR_BC(csr_base, ILU_ERROR_LOG_ENABLE, SPARE3);
331825cf1a30Sjl139090 
3319597077b2Sjj156685 	/* Set back TLU registers */
3320597077b2Sjj156685 	CSR_XS(csr_base, TLU_UNCORRECTABLE_ERROR_LOG_ENABLE, reg_tluue);
3321597077b2Sjj156685 	CSR_XS(csr_base, TLU_CORRECTABLE_ERROR_LOG_ENABLE, reg_tluce);
3322597077b2Sjj156685 
332325cf1a30Sjl139090 	/* Power LED off */
332425cf1a30Sjl139090 	reg = CSR_XR(csr_base, TLU_SLOT_CONTROL);
332525cf1a30Sjl139090 	reg &= ~PCIE_SLOTCTL_PWR_INDICATOR_MASK;
332625cf1a30Sjl139090 	reg = pcie_slotctl_pwr_indicator_set(reg,
332725cf1a30Sjl139090 	    PCIE_SLOTCTL_INDICATOR_STATE_OFF);
332825cf1a30Sjl139090 	CSR_XS(csr_base, TLU_SLOT_CONTROL, reg);
332925cf1a30Sjl139090 
333025cf1a30Sjl139090 	/* Indicator LED blink */
333125cf1a30Sjl139090 	reg = CSR_XR(csr_base, TLU_SLOT_CONTROL);
333225cf1a30Sjl139090 	reg &= ~PCIE_SLOTCTL_ATTN_INDICATOR_MASK;
333325cf1a30Sjl139090 	reg = pcie_slotctl_attn_indicator_set(reg,
333425cf1a30Sjl139090 	    PCIE_SLOTCTL_INDICATOR_STATE_BLINK);
333525cf1a30Sjl139090 	CSR_XS(csr_base, TLU_SLOT_CONTROL, reg);
333625cf1a30Sjl139090 
333725cf1a30Sjl139090 	/* Notify to SCF */
3338ba640a72Sjj156685 	if (CSR_BR(csr_base, HOTPLUG_CONTROL, SLOTPON))
333925cf1a30Sjl139090 		CSR_BC(csr_base, HOTPLUG_CONTROL, SLOTPON);
3340ba640a72Sjj156685 	else
33411f4643f9Sgovinda 		CSR_BS(csr_base, HOTPLUG_CONTROL, SLOTPON);
33421f4643f9Sgovinda 
33431f4643f9Sgovinda 	start_time = gethrtime();
33441f4643f9Sgovinda 	/* Check Leaf Reset status */
33451f4643f9Sgovinda 	while (!(CSR_BR(csr_base, ILU_ERROR_LOG_ENABLE, SPARE3))) {
33461f4643f9Sgovinda 		if ((end_time = (gethrtime() - start_time)) >
33471f4643f9Sgovinda 		    oberon_leaf_reset_timeout) {
33481f4643f9Sgovinda 			cmn_err(CE_WARN, "Oberon leaf reset is not completed, "
33491f4643f9Sgovinda 			    "even after waiting %llx ticks", end_time);
33501f4643f9Sgovinda 
33511f4643f9Sgovinda 			break;
33521f4643f9Sgovinda 		}
33531f4643f9Sgovinda 
33541f4643f9Sgovinda 		/* Wait for one second */
33551f4643f9Sgovinda 		delay(drv_usectohz(1000000));
33561f4643f9Sgovinda 	}
335725cf1a30Sjl139090 
335825cf1a30Sjl139090 	/* Indicator LED off */
335925cf1a30Sjl139090 	reg = CSR_XR(csr_base, TLU_SLOT_CONTROL);
336025cf1a30Sjl139090 	reg &= ~PCIE_SLOTCTL_ATTN_INDICATOR_MASK;
336125cf1a30Sjl139090 	reg = pcie_slotctl_attn_indicator_set(reg,
336225cf1a30Sjl139090 	    PCIE_SLOTCTL_INDICATOR_STATE_OFF);
336325cf1a30Sjl139090 	CSR_XS(csr_base, TLU_SLOT_CONTROL, reg);
336425cf1a30Sjl139090 
336525cf1a30Sjl139090 	return (DDI_SUCCESS);
336625cf1a30Sjl139090 }
336725cf1a30Sjl139090 
336825cf1a30Sjl139090 static uint_t
336925cf1a30Sjl139090 oberon_hpreg_get(void *cookie, off_t off)
337025cf1a30Sjl139090 {
337125cf1a30Sjl139090 	caddr_t csr_base = *(caddr_t *)cookie;
337225cf1a30Sjl139090 	volatile uint64_t val = -1ull;
337325cf1a30Sjl139090 
337425cf1a30Sjl139090 	switch (off) {
337525cf1a30Sjl139090 	case PCIE_SLOTCAP:
337625cf1a30Sjl139090 		val = CSR_XR(csr_base, TLU_SLOT_CAPABILITIES);
337725cf1a30Sjl139090 		break;
337825cf1a30Sjl139090 	case PCIE_SLOTCTL:
337925cf1a30Sjl139090 		val = CSR_XR(csr_base, TLU_SLOT_CONTROL);
338025cf1a30Sjl139090 
338125cf1a30Sjl139090 		/* Get the power state */
338225cf1a30Sjl139090 		val |= (CSR_XR(csr_base, HOTPLUG_CONTROL) &
338325cf1a30Sjl139090 		    (1ull << HOTPLUG_CONTROL_PWREN)) ?
338425cf1a30Sjl139090 		    0 : PCIE_SLOTCTL_PWR_CONTROL;
338525cf1a30Sjl139090 		break;
338625cf1a30Sjl139090 	case PCIE_SLOTSTS:
338725cf1a30Sjl139090 		val = CSR_XR(csr_base, TLU_SLOT_STATUS);
338825cf1a30Sjl139090 		break;
338992e1ac0dSjj156685 	case PCIE_LINKCAP:
339092e1ac0dSjj156685 		val = CSR_XR(csr_base, TLU_LINK_CAPABILITIES);
339192e1ac0dSjj156685 		break;
339292e1ac0dSjj156685 	case PCIE_LINKSTS:
339392e1ac0dSjj156685 		val = CSR_XR(csr_base, TLU_LINK_STATUS);
339492e1ac0dSjj156685 		break;
339525cf1a30Sjl139090 	default:
3396f94c6026Sjj156685 		DBG(DBG_HP, NULL, "oberon_hpreg_get(): "
339725cf1a30Sjl139090 		    "unsupported offset 0x%lx\n", off);
339825cf1a30Sjl139090 		break;
339925cf1a30Sjl139090 	}
340025cf1a30Sjl139090 
340125cf1a30Sjl139090 	return ((uint_t)val);
340225cf1a30Sjl139090 }
340325cf1a30Sjl139090 
340425cf1a30Sjl139090 static uint_t
340525cf1a30Sjl139090 oberon_hpreg_put(void *cookie, off_t off, uint_t val)
340625cf1a30Sjl139090 {
340725cf1a30Sjl139090 	caddr_t csr_base = *(caddr_t *)cookie;
340892e1ac0dSjj156685 	volatile uint64_t pwr_state_on, pwr_fault;
340925cf1a30Sjl139090 	uint_t pwr_off, ret = DDI_SUCCESS;
341025cf1a30Sjl139090 
3411f94c6026Sjj156685 	DBG(DBG_HP, NULL, "oberon_hpreg_put 0x%lx: cur %x, new %x\n",
341225cf1a30Sjl139090 	    off, oberon_hpreg_get(cookie, off), val);
341325cf1a30Sjl139090 
341425cf1a30Sjl139090 	switch (off) {
341525cf1a30Sjl139090 	case PCIE_SLOTCTL:
341625cf1a30Sjl139090 		/*
341725cf1a30Sjl139090 		 * Depending on the current state, insertion or removal
341825cf1a30Sjl139090 		 * will go through their respective sequences.
341925cf1a30Sjl139090 		 */
342025cf1a30Sjl139090 		pwr_state_on = CSR_BR(csr_base, HOTPLUG_CONTROL, PWREN);
342125cf1a30Sjl139090 		pwr_off = val & PCIE_SLOTCTL_PWR_CONTROL;
342225cf1a30Sjl139090 
342325cf1a30Sjl139090 		if (!pwr_off && !pwr_state_on)
342425cf1a30Sjl139090 			ret = oberon_hp_pwron(csr_base);
342525cf1a30Sjl139090 		else if (pwr_off && pwr_state_on) {
342625cf1a30Sjl139090 			pwr_fault = CSR_XR(csr_base, TLU_SLOT_STATUS) &
342725cf1a30Sjl139090 			    (1ull << TLU_SLOT_STATUS_PWFD);
342825cf1a30Sjl139090 
3429ba640a72Sjj156685 			if (pwr_fault) {
3430ba640a72Sjj156685 				DBG(DBG_HP, NULL, "oberon_hpreg_put: power "
3431ba640a72Sjj156685 				    "off because of power fault\n");
343225cf1a30Sjl139090 				CSR_BC(csr_base, HOTPLUG_CONTROL, PWREN);
3433ba640a72Sjj156685 			}
343425cf1a30Sjl139090 			else
343525cf1a30Sjl139090 				ret = oberon_hp_pwroff(csr_base);
343692e1ac0dSjj156685 		} else
343725cf1a30Sjl139090 			CSR_XS(csr_base, TLU_SLOT_CONTROL, val);
343825cf1a30Sjl139090 		break;
343925cf1a30Sjl139090 	case PCIE_SLOTSTS:
344025cf1a30Sjl139090 		CSR_XS(csr_base, TLU_SLOT_STATUS, val);
344125cf1a30Sjl139090 		break;
344225cf1a30Sjl139090 	default:
3443f94c6026Sjj156685 		DBG(DBG_HP, NULL, "oberon_hpreg_put(): "
344425cf1a30Sjl139090 		    "unsupported offset 0x%lx\n", off);
3445055d7c80Scarlsonj 		ret = (uint_t)DDI_FAILURE;
344625cf1a30Sjl139090 		break;
344725cf1a30Sjl139090 	}
344825cf1a30Sjl139090 
344925cf1a30Sjl139090 	return (ret);
345025cf1a30Sjl139090 }
345125cf1a30Sjl139090 
345225cf1a30Sjl139090 int
345325cf1a30Sjl139090 hvio_hotplug_init(dev_info_t *dip, void *arg)
345425cf1a30Sjl139090 {
345526947304SEvan Yan 	pcie_hp_regops_t *regops = (pcie_hp_regops_t *)arg;
345625cf1a30Sjl139090 	px_t	*px_p = DIP_TO_STATE(dip);
345725cf1a30Sjl139090 	pxu_t	*pxu_p = (pxu_t *)px_p->px_plat_p;
34583c4226f9Spjha 	volatile uint64_t reg;
345925cf1a30Sjl139090 
346025cf1a30Sjl139090 	if (PX_CHIP_TYPE(pxu_p) == PX_CHIP_OBERON) {
346125cf1a30Sjl139090 		if (!CSR_BR((caddr_t)pxu_p->px_address[PX_REG_CSR],
346225cf1a30Sjl139090 		    TLU_SLOT_CAPABILITIES, HP)) {
3463f94c6026Sjj156685 			DBG(DBG_HP, NULL, "%s%d: hotplug capabale not set\n",
346425cf1a30Sjl139090 			    ddi_driver_name(dip), ddi_get_instance(dip));
346525cf1a30Sjl139090 			return (DDI_FAILURE);
346625cf1a30Sjl139090 		}
346725cf1a30Sjl139090 
34683c4226f9Spjha 		/* For empty or disconnected slot, disable LUP/LDN */
34693c4226f9Spjha 		if (!CSR_BR((caddr_t)pxu_p->px_address[PX_REG_CSR],
34703c4226f9Spjha 		    TLU_SLOT_STATUS, PSD) ||
34713c4226f9Spjha 		    !CSR_BR((caddr_t)pxu_p->px_address[PX_REG_CSR],
34723c4226f9Spjha 		    HOTPLUG_CONTROL, PWREN)) {
34733c4226f9Spjha 
34743c4226f9Spjha 			reg = CSR_XR((caddr_t)pxu_p->px_address[PX_REG_CSR],
34753c4226f9Spjha 			    TLU_OTHER_EVENT_LOG_ENABLE);
34763c4226f9Spjha 			reg &= ~((1ull << TLU_OTHER_EVENT_STATUS_SET_LDN_P) |
34773c4226f9Spjha 			    (1ull << TLU_OTHER_EVENT_STATUS_SET_LUP_P) |
34783c4226f9Spjha 			    (1ull << TLU_OTHER_EVENT_STATUS_SET_LDN_S) |
34793c4226f9Spjha 			    (1ull << TLU_OTHER_EVENT_STATUS_SET_LUP_S));
34803c4226f9Spjha 			CSR_XS((caddr_t)pxu_p->px_address[PX_REG_CSR],
34813c4226f9Spjha 			    TLU_OTHER_EVENT_LOG_ENABLE, reg);
34823c4226f9Spjha 		}
34833c4226f9Spjha 
348425cf1a30Sjl139090 		regops->get = oberon_hpreg_get;
348525cf1a30Sjl139090 		regops->put = oberon_hpreg_put;
348625cf1a30Sjl139090 
348725cf1a30Sjl139090 		/* cookie is the csr_base */
348825cf1a30Sjl139090 		regops->cookie = (void *)&pxu_p->px_address[PX_REG_CSR];
348925cf1a30Sjl139090 
349025cf1a30Sjl139090 		return (DDI_SUCCESS);
349125cf1a30Sjl139090 	}
349225cf1a30Sjl139090 
349325cf1a30Sjl139090 	return (DDI_ENOTSUP);
349425cf1a30Sjl139090 }
349525cf1a30Sjl139090 
349625cf1a30Sjl139090 int
349725cf1a30Sjl139090 hvio_hotplug_uninit(dev_info_t *dip)
349825cf1a30Sjl139090 {
349925cf1a30Sjl139090 	px_t	*px_p = DIP_TO_STATE(dip);
350025cf1a30Sjl139090 	pxu_t	*pxu_p = (pxu_t *)px_p->px_plat_p;
350125cf1a30Sjl139090 
350225cf1a30Sjl139090 	if (PX_CHIP_TYPE(pxu_p) == PX_CHIP_OBERON)
350325cf1a30Sjl139090 		return (DDI_SUCCESS);
350425cf1a30Sjl139090 
350525cf1a30Sjl139090 	return (DDI_FAILURE);
350625cf1a30Sjl139090 }
3507