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