void NvRmPrivGetSku( NvRmDeviceHandle rm ) { NvError e; NvRmChipId *id; NvU8 *FuseVirt; NvU32 reg; #if NV_USE_FUSE_CLOCK_ENABLE NvU8 *CarVirt = 0; #endif NV_ASSERT( rm ); id = &rm->ChipId; #if NV_USE_FUSE_CLOCK_ENABLE // Enable fuse clock e = NvRmPhysicalMemMap(0x60006000, 0x1000, NVOS_MEM_READ_WRITE, NvOsMemAttribute_Uncached, (void **)&CarVirt); if (e == NvSuccess) { reg = NV_READ32(CarVirt + CLK_RST_CONTROLLER_CLK_OUT_ENB_H_0); reg |= 0x80; NV_WRITE32(CarVirt + CLK_RST_CONTROLLER_CLK_OUT_ENB_H_0, reg); } #endif /* Read the fuse only on real silicon, as it was not gauranteed to be * preset on the eluation/simulation platforms. */ e = NvRmPhysicalMemMap(0x7000f800, 0x400, NVOS_MEM_READ_WRITE, NvOsMemAttribute_Uncached, (void **)&FuseVirt); if (e == NvSuccess) { // Read the SKU from the fuse module. reg = NV_READ32( FuseVirt + FUSE_SKU_INFO_0 ); id->SKU = (NvU16)reg; NvRmPhysicalMemUnmap(FuseVirt, 0x400); #if NV_USE_FUSE_CLOCK_ENABLE // Disable fuse clock if (CarVirt) { reg = NV_READ32(CarVirt + CLK_RST_CONTROLLER_CLK_OUT_ENB_H_0); reg &= ~0x80; NV_WRITE32(CarVirt + CLK_RST_CONTROLLER_CLK_OUT_ENB_H_0, reg); NvRmPhysicalMemUnmap(CarVirt, 0x1000); } #endif } else { NV_ASSERT(!"Cannot map the FUSE aperture to get the SKU"); id->SKU = 0; } }
void t30_UartD_Init(void) { NvU32 RegData; // Initialization is responsible for correct pin mux configuration // It also needs to wait for the correct osc frequency to be known // IMPORTANT, there is some unspecified logic in the UART that always // operate off PLLP_out3, mail from Robert Quan says that correct operation // of UART without starting PLLP requires // - to put PLLP in bypass // - to override the PLLP_ou3 divider to be 1 (or put in bypass) // This is done like that here to avoid any dependence on PLLP analog circuitry // operating correctly RegData = NV_READ32(NV_ADDRESS_MAP_PPSB_CLK_RST_BASE + CLK_RST_CONTROLLER_PLLP_BASE_0); RegData |= NV_DRF_DEF(CLK_RST_CONTROLLER, PLLP_BASE, PLLP_BYPASS, ENABLE); NV_WRITE32(NV_ADDRESS_MAP_PPSB_CLK_RST_BASE + CLK_RST_CONTROLLER_PLLP_BASE_0, RegData); RegData = NV_READ32(NV_ADDRESS_MAP_PPSB_CLK_RST_BASE + CLK_RST_CONTROLLER_PLLP_OUTB_0); RegData |= NV_DRF_DEF(CLK_RST_CONTROLLER, PLLP_OUTB, PLLP_OUT3_OVRRIDE, ENABLE); RegData |= NV_DRF_NUM(CLK_RST_CONTROLLER, PLLP_OUTB, PLLP_OUT3_RATIO, 0); NV_WRITE32(NV_ADDRESS_MAP_PPSB_CLK_RST_BASE + CLK_RST_CONTROLLER_PLLP_OUTB_0, RegData); // Set up the pinmuxes to bring UARTD out on ULPI_clk and ULPI_dir // for waluigi T30. All alternate mappings of UARTD are set to select an input other than UARTD. // // GMI_AD16 => Alternate 1 ( SPI4 instead of UD3_TXD) // GMI_AD17 => Alternate 1 ( SPI4 instead of UD3_RXD) // ULPI_CLK =>Alternate 2 (UD3_TXD) // ULPI_DIR =>Alternate 2 UD3_RXD) // // Last reviewed on 08/27/2010 SET_PIN(GMI_A16,PM,SPI4) ; SET_PIN(GMI_A17,PM,SPI4) ; SET_PIN(ULPI_CLK,PM,UARTD) ; SET_PIN(ULPI_DIR,PM,UARTD) ; // Enable the pads. SET_PIN(ULPI_CLK, TRISTATE, NORMAL); SET_PIN(ULPI_DIR, TRISTATE, NORMAL); // enable UART D clock, toggle reset RegData = NV_READ32(NV_ADDRESS_MAP_PPSB_CLK_RST_BASE + CLK_RST_CONTROLLER_CLK_OUT_ENB_U_0); RegData |= NV_DRF_DEF(CLK_RST_CONTROLLER, CLK_OUT_ENB_U, CLK_ENB_UARTD, ENABLE); NV_WRITE32(NV_ADDRESS_MAP_PPSB_CLK_RST_BASE + CLK_RST_CONTROLLER_CLK_OUT_ENB_U_0, RegData); RegData = NV_READ32(NV_ADDRESS_MAP_PPSB_CLK_RST_BASE + CLK_RST_CONTROLLER_RST_DEVICES_U_0); RegData = NV_FLD_SET_DRF_DEF(CLK_RST_CONTROLLER, RST_DEVICES_U, SWR_UARTD_RST, ENABLE, RegData); NV_WRITE32(NV_ADDRESS_MAP_PPSB_CLK_RST_BASE + CLK_RST_CONTROLLER_RST_DEVICES_U_0, RegData); RegData = NV_READ32(NV_ADDRESS_MAP_PPSB_CLK_RST_BASE + CLK_RST_CONTROLLER_RST_DEVICES_U_0); RegData = NV_FLD_SET_DRF_DEF(CLK_RST_CONTROLLER, RST_DEVICES_U, SWR_UARTD_RST, DISABLE, RegData); NV_WRITE32(NV_ADDRESS_MAP_PPSB_CLK_RST_BASE + CLK_RST_CONTROLLER_RST_DEVICES_U_0, RegData); // Then there is the specific set up for UART itself, including the clock configuration. // configure at top for source & configure the divider, internal to uart for obscure reasons // when UARTD_DIV_ENB is enable DLL/DLLM programming is not required //.Refer to the CLK_SOURCE_UARTD reg description in arclk_rst // UARTD_DIV_ENB is disabled as new divisor logic is not enabled on FPGA Bug #739606 #if 0 NV_WRITE32(NV_ADDRESS_MAP_CAR_BASE+ CLK_RST_CONTROLLER_CLK_SOURCE_UARTD_0 , (CLK_RST_CONTROLLER_CLK_SOURCE_UARTD_0_UARTD_CLK_SRC_CLK_M << CLK_RST_CONTROLLER_CLK_SOURCE_UARTD_0_UARTD_CLK_SRC_SHIFT) | (CLK_RST_CONTROLLER_CLK_SOURCE_UARTD_0_UARTD_DIV_ENB_DISABLE << CLK_RST_CONTROLLER_CLK_SOURCE_UARTD_0_UARTD_DIV_ENB_SHIFT) | 0); #endif }
void t30_UartC_Init(void) { NvU32 RegData; // Initialization is responsible for correct pin mux configuration // It also needs to wait for the correct osc frequency to be known // IMPORTANT, there is some unspecified logic in the UART that always // operate off PLLP_out3, mail from Robert Quan says that correct operation // of UART without starting PLLP requires // - to put PLLP in bypass // - to override the PLLP_ou3 divider to be 1 (or put in bypass) // This is done like that here to avoid any dependence on PLLP analog circuitry // operating correctly RegData = NV_READ32(NV_ADDRESS_MAP_PPSB_CLK_RST_BASE + CLK_RST_CONTROLLER_PLLP_BASE_0); RegData |= NV_DRF_DEF(CLK_RST_CONTROLLER, PLLP_BASE, PLLP_BYPASS, ENABLE); NV_WRITE32(NV_ADDRESS_MAP_PPSB_CLK_RST_BASE + CLK_RST_CONTROLLER_PLLP_BASE_0, RegData); RegData = NV_READ32(NV_ADDRESS_MAP_PPSB_CLK_RST_BASE + CLK_RST_CONTROLLER_PLLP_OUTB_0); RegData |= NV_DRF_DEF(CLK_RST_CONTROLLER, PLLP_OUTB, PLLP_OUT3_OVRRIDE, ENABLE); RegData |= NV_DRF_NUM(CLK_RST_CONTROLLER, PLLP_OUTB, PLLP_OUT3_RATIO, 0); NV_WRITE32(NV_ADDRESS_MAP_PPSB_CLK_RST_BASE + CLK_RST_CONTROLLER_PLLP_OUTB_0, RegData); // Set up the pinmuxes to bring UARTC out on uart3_txd and uart_rxd // for oregon T30. // // UART3_TXD =>primary 0 (UC3_TXD) // UART3_RXD =>primary 0(UC3_RXD) // SET_PIN(UART3_TXD,PM,UARTC) ; SET_PIN(UART3_RXD,PM,UARTC) ; // SET_PIN(UART3_CTS_N,PM,UARTC) ; // SET_PIN(UART3_RTS_N,PM,UARTC) ; // Enable the pads. SET_PIN(UART3_TXD, TRISTATE, NORMAL); SET_PIN(UART3_RXD, TRISTATE, NORMAL); // enable UART C clock, toggle reset RegData = NV_READ32(NV_ADDRESS_MAP_PPSB_CLK_RST_BASE + CLK_RST_CONTROLLER_CLK_OUT_ENB_H_0); RegData |= NV_DRF_DEF(CLK_RST_CONTROLLER, CLK_OUT_ENB_H, CLK_ENB_UARTC, ENABLE); NV_WRITE32(NV_ADDRESS_MAP_PPSB_CLK_RST_BASE + CLK_RST_CONTROLLER_CLK_OUT_ENB_H_0, RegData); RegData = NV_READ32(NV_ADDRESS_MAP_PPSB_CLK_RST_BASE + CLK_RST_CONTROLLER_RST_DEVICES_H_0); RegData = NV_FLD_SET_DRF_DEF(CLK_RST_CONTROLLER, RST_DEVICES_H, SWR_UARTC_RST, ENABLE, RegData); NV_WRITE32(NV_ADDRESS_MAP_PPSB_CLK_RST_BASE + CLK_RST_CONTROLLER_RST_DEVICES_H_0, RegData); RegData = NV_READ32(NV_ADDRESS_MAP_PPSB_CLK_RST_BASE + CLK_RST_CONTROLLER_RST_DEVICES_H_0); RegData = NV_FLD_SET_DRF_DEF(CLK_RST_CONTROLLER, RST_DEVICES_H, SWR_UARTC_RST, DISABLE, RegData); NV_WRITE32(NV_ADDRESS_MAP_PPSB_CLK_RST_BASE + CLK_RST_CONTROLLER_RST_DEVICES_H_0, RegData); // Then there is the specific set up for UART itself, including the clock configuration. // configure at top for source & configure the divider, internal to uart for obscure reasons // when UARTC_DIV_ENB is enable DLL/DLLM programming is not required //.Refer to the CLK_SOURCE_UARTD reg description in arclk_rst // UARTD_DIV_ENB is disabled as new divisor logic is not enabled on FPGA Bug #739606 #if 0 NV_WRITE32(NV_ADDRESS_MAP_CAR_BASE+ CLK_RST_CONTROLLER_CLK_SOURCE_UARTD_0 , (CLK_RST_CONTROLLER_CLK_SOURCE_UARTD_0_UARTD_CLK_SRC_CLK_M << CLK_RST_CONTROLLER_CLK_SOURCE_UARTD_0_UARTD_CLK_SRC_SHIFT) | (CLK_RST_CONTROLLER_CLK_SOURCE_UARTD_0_UARTD_DIV_ENB_DISABLE << CLK_RST_CONTROLLER_CLK_SOURCE_UARTD_0_UARTD_DIV_ENB_SHIFT) | 0); #endif }
void t30_UartA_Init(void) { NvU32 RegData; // Initialization is responsible for correct pin mux configuration // It also needs to wait for the correct osc frequency to be known // IMPORTANT, there is some unspecified logic in the UART that always // operate off PLLP_out3, mail from Robert Quan says that correct operation // of UART without starting PLLP requires // - to put PLLP in bypass // - to override the PLLP_ou3 divider to be 1 (or put in bypass) // This is done like that here to avoid any dependence on PLLP analog circuitry // operating correctly RegData = NV_READ32(NV_ADDRESS_MAP_PPSB_CLK_RST_BASE + CLK_RST_CONTROLLER_PLLP_BASE_0); RegData |= NV_DRF_DEF(CLK_RST_CONTROLLER, PLLP_BASE, PLLP_BYPASS, ENABLE); NV_WRITE32(NV_ADDRESS_MAP_PPSB_CLK_RST_BASE + CLK_RST_CONTROLLER_PLLP_BASE_0, RegData); RegData = NV_READ32(NV_ADDRESS_MAP_PPSB_CLK_RST_BASE + CLK_RST_CONTROLLER_PLLP_OUTB_0); RegData |= NV_DRF_DEF(CLK_RST_CONTROLLER, PLLP_OUTB, PLLP_OUT3_OVRRIDE, ENABLE); RegData |= NV_DRF_NUM(CLK_RST_CONTROLLER, PLLP_OUTB, PLLP_OUT3_RATIO, 0); NV_WRITE32(NV_ADDRESS_MAP_PPSB_CLK_RST_BASE + CLK_RST_CONTROLLER_PLLP_OUTB_0, RegData); // Set up the pinmuxes to bring UARTA out on ULPI_DATA0 and ULPI_DATA1 // for T30. All alternate mappings of UARTA are set to select an input other than UARTA. // // UART2_RTS_N => Alternate 3 ( SPI4 instead of UA3_TXD) // UART2_CTS_N => Alternate 3 ( SPI4 instead of UA3_TXD) // ULPI_DATA0 =>Alternate 2 (UA3_TXD) // ULPI_DATA1 =>Alternate 2 UA3_RXD) // SDMMC1_DAT3 => Primary (SDMMC1_DAT3 instead of UA3_TXD) // SDMMC1_DAT2 => Primary (SDMMC1_DAT2 instead of UA3_RXD) // GPIO_PU0 => Alternate 2 (GMI_A6 instead of UA3_TXD) // GPIO_PU1 => Alternate 2 (GMI_A7 instead of UA3_RXD) // SDMMC3_CLK => Alternate 2 (SDMMC3_SCLK instead of UA3_TXD) // SDMMC3_CMD => Alternate 2 (SDMMC3_CMD instead of UA3_RXD) // // Last reviewed on 08/27/2010 SET_PIN(UART2_RTS_N,PM,SPI4) ; SET_PIN(UART2_CTS_N,PM,SPI4) ; SET_PIN(ULPI_DATA0,PM,UARTA) ; SET_PIN(ULPI_DATA1,PM,UARTA) ; SET_PIN(SDMMC1_DAT3,PM,SDMMC1) ; SET_PIN(SDMMC1_DAT2,PM,SDMMC1) ; SET_PIN(GPIO_PU0,PM,GMI) ; SET_PIN(GPIO_PU1,PM,GMI) ; SET_PIN(SDMMC3_CLK, PM, SDMMC3); SET_PIN(SDMMC3_CMD, PM, SDMMC3); // Enable the pads. SET_PIN(ULPI_DATA0, TRISTATE, NORMAL); SET_PIN(ULPI_DATA1, TRISTATE, NORMAL); // enable UART A clock, toggle reset RegData = NV_READ32(NV_ADDRESS_MAP_PPSB_CLK_RST_BASE + CLK_RST_CONTROLLER_CLK_OUT_ENB_L_0); RegData |= NV_DRF_DEF(CLK_RST_CONTROLLER, CLK_OUT_ENB_L, CLK_ENB_UARTA, ENABLE); NV_WRITE32(NV_ADDRESS_MAP_PPSB_CLK_RST_BASE + CLK_RST_CONTROLLER_CLK_OUT_ENB_L_0, RegData); RegData = NV_READ32(NV_ADDRESS_MAP_PPSB_CLK_RST_BASE + CLK_RST_CONTROLLER_RST_DEVICES_L_0); RegData = NV_FLD_SET_DRF_DEF(CLK_RST_CONTROLLER, RST_DEVICES_L, SWR_UARTA_RST, ENABLE, RegData); NV_WRITE32(NV_ADDRESS_MAP_PPSB_CLK_RST_BASE + CLK_RST_CONTROLLER_RST_DEVICES_L_0, RegData); RegData = NV_READ32(NV_ADDRESS_MAP_PPSB_CLK_RST_BASE + CLK_RST_CONTROLLER_RST_DEVICES_L_0); RegData = NV_FLD_SET_DRF_DEF(CLK_RST_CONTROLLER, RST_DEVICES_L, SWR_UARTA_RST, DISABLE, RegData); NV_WRITE32(NV_ADDRESS_MAP_PPSB_CLK_RST_BASE + CLK_RST_CONTROLLER_RST_DEVICES_L_0, RegData); // Then there is the specific set up for UART itself, including the clock configuration. // configure at top for source & configure the divider, internal to uart for obscure reasons // when UARTA_DIV_ENB is enable DLL/DLLM programming is not required //.Refer to the CLK_SOURCE_UARTA reg description in arclk_rst // UARTA_DIV_ENB is disabled as new divisor logic is not enabled on FPGA Bug #739606 NV_WRITE32(NV_ADDRESS_MAP_CAR_BASE+ CLK_RST_CONTROLLER_CLK_SOURCE_UARTA_0 , (CLK_RST_CONTROLLER_CLK_SOURCE_UARTA_0_UARTA_CLK_SRC_CLK_M << CLK_RST_CONTROLLER_CLK_SOURCE_UARTA_0_UARTA_CLK_SRC_SHIFT) | (CLK_RST_CONTROLLER_CLK_SOURCE_UARTA_0_UARTA_DIV_ENB_DISABLE << CLK_RST_CONTROLLER_CLK_SOURCE_UARTA_0_UARTA_DIV_ENB_SHIFT) | 0); }
NvRmPmRequest NvRmPrivAp20GetPmRequest( NvRmDeviceHandle hRmDevice, const NvRmDfsSampler* pCpuSampler, NvRmFreqKHz* pCpuKHz) { // Assume initial slave CPU1 On request static NvRmPmRequest s_LastPmRequest = (NvRmPmRequest_CpuOnFlag | 0x1); static NvRmFreqKHz s_Cpu1OnMinKHz = 0, s_Cpu1OffMaxKHz = 0; static NvU32 s_Cpu1OnPendingCnt = 0, s_Cpu1OffPendingCnt = 0; NvU32 t; NvRmPmRequest PmRequest = NvRmPmRequest_None; NvBool Cpu1Off = (0 != NV_DRF_VAL(CLK_RST_CONTROLLER, RST_CPU_CMPLX_SET, SET_CPURESET1, NV_REGR(hRmDevice, NvRmPrivModuleID_ClockAndReset, 0, CLK_RST_CONTROLLER_RST_CPU_CMPLX_SET_0))); NvRmFreqKHz CpuLoadGaugeKHz; // Use clocks for load when no busy hint, otherwise use activity metrics if (NvRmPrivDfsGetBusyHintActive(NvRmDfsClockId_Cpu)) { CpuLoadGaugeKHz = pCpuSampler->AverageKHz; } else { CpuLoadGaugeKHz = *pCpuKHz; } // Slave CPU1 power management policy thresholds: // - use fixed values if they are defined explicitly, otherwise // - set CPU1 OffMax threshold at 3/4 of cpu frequency range, // and 1/2 of max frequency as CPU1 OnMin threshold if ((s_Cpu1OffMaxKHz == 0) && (s_Cpu1OnMinKHz == 0)) { NvRmFreqKHz MaxKHz = NvRmPrivGetSocClockLimits(NvRmModuleID_Cpu)->MaxKHz; s_Cpu1OnMinKHz = NVRM_CPU1_ON_MIN_KHZ ? NVRM_CPU1_ON_MIN_KHZ : (MaxKHz / 2); s_Cpu1OffMaxKHz = NVRM_CPU1_OFF_MAX_KHZ ? NVRM_CPU1_OFF_MAX_KHZ : (3 * MaxKHz / 4); NV_ASSERT(s_Cpu1OnMinKHz < s_Cpu1OffMaxKHz); } // Timestamp if (s_pTimerUs == NULL) s_pTimerUs = NvRmPrivAp15GetTimerUsVirtAddr(hRmDevice); t = NV_READ32(s_pTimerUs); /* * Request OS kernel to turn CPU1 Off if all of the following is true: * (a) CPU frequency is below OnMin threshold, * (b) CPU1 is actually On * * Request OS kernel to turn CPU1 On if all of the following is true: * (a) CPU frequency is above OffMax threshold * (b) CPU1 is actually Off */ if (CpuLoadGaugeKHz < s_Cpu1OnMinKHz) { s_Cpu1OnPendingCnt = 0; if ((s_Cpu1OffPendingCnt & 0x1) == 0) { s_Cpu1OffPendingCnt = t | 0x1; // Use LSb as a delay start flag return PmRequest; } if ((t - s_Cpu1OffPendingCnt) < (NVRM_CPU1_OFF_PENDING_MS * 1000)) return PmRequest; if (!Cpu1Off) { s_LastPmRequest = PmRequest = (NvRmPmRequest_CpuOffFlag | 0x1); s_Cpu1OffPendingCnt = 0; // re-start delay after request } #if NVRM_TEST_PMREQUEST_UP_MODE NV_REGW(hRmDevice, NvRmPrivModuleID_ClockAndReset, 0, CLK_RST_CONTROLLER_RST_CPU_CMPLX_SET_0, CLK_RST_CONTROLLER_RST_CPU_CMPLX_SET_0_SET_CPURESET1_FIELD); #endif } else if (CpuLoadGaugeKHz > s_Cpu1OffMaxKHz) { s_Cpu1OffPendingCnt = 0; if ((s_Cpu1OnPendingCnt & 0x1) == 0) { s_Cpu1OnPendingCnt = t | 0x1; // Use LSb as a delay start flag return PmRequest; } if ((t - s_Cpu1OnPendingCnt) < (NVRM_CPU1_ON_PENDING_MS * 1000)) return PmRequest; if (Cpu1Off) { s_LastPmRequest = PmRequest = (NvRmPmRequest_CpuOnFlag | 0x1); *pCpuKHz = NvRmPrivGetSocClockLimits(NvRmModuleID_Cpu)->MaxKHz; s_Cpu1OnPendingCnt = 0; // re-start delay after request } #if NVRM_TEST_PMREQUEST_UP_MODE NV_REGW(hRmDevice, NvRmPrivModuleID_ClockAndReset, 0, CLK_RST_CONTROLLER_RST_CPU_CMPLX_CLR_0, CLK_RST_CONTROLLER_RST_CPU_CMPLX_CLR_0_CLR_CPURESET1_FIELD); #endif } else { // Re-start both delays inside hysteresis loop s_Cpu1OnPendingCnt = 0; s_Cpu1OffPendingCnt = 0; } return PmRequest; }
void NvRmPrivReadChipId( NvRmDeviceHandle rm ) { #if (NVCPU_IS_X86 && NVOS_IS_WINDOWS) NvRmChipId *id; NV_ASSERT( rm ); id = &rm->ChipId; id->Family = NvRmChipFamily_HandheldSoc; id->Id = 0x15; id->Major = 0x0; id->Minor = 0x0; id->SKU = 0x0; id->Netlist = 0x0; id->Patch = 0x0; #else NvU32 reg; NvRmChipId *id; NvU32 fam; char *s; NvU8 *VirtAddr; NvError e; NV_ASSERT( rm ); id = &rm->ChipId; /* Hard coding the address of the chip ID address space, as we haven't yet * parsed the relocation table. */ e = NvRmPhysicalMemMap(0x70000000, 0x1000, NVOS_MEM_READ_WRITE, NvOsMemAttribute_Uncached, (void **)&VirtAddr); if (e != NvSuccess) { NV_DEBUG_PRINTF(("APB misc aperture map failure\n")); return; } /* chip id is in the misc aperture */ reg = NV_READ32( VirtAddr + APB_MISC_GP_HIDREV_0 ); id->Id = (NvU16)NV_DRF_VAL( APB_MISC_GP, HIDREV, CHIPID, reg ); id->Major = (NvU8)NV_DRF_VAL( APB_MISC_GP, HIDREV, MAJORREV, reg ); id->Minor = (NvU8)NV_DRF_VAL( APB_MISC_GP, HIDREV, MINORREV, reg ); fam = NV_DRF_VAL( APB_MISC_GP, HIDREV, HIDFAM, reg ); switch( fam ) { case APB_MISC_GP_HIDREV_0_HIDFAM_GPU: id->Family = NvRmChipFamily_Gpu; s = "GPU"; break; case APB_MISC_GP_HIDREV_0_HIDFAM_HANDHELD: id->Family = NvRmChipFamily_Handheld; s = "Handheld"; break; case APB_MISC_GP_HIDREV_0_HIDFAM_BR_CHIPS: id->Family = NvRmChipFamily_BrChips; s = "BrChips"; break; case APB_MISC_GP_HIDREV_0_HIDFAM_CRUSH: id->Family = NvRmChipFamily_Crush; s = "Crush"; break; case APB_MISC_GP_HIDREV_0_HIDFAM_MCP: id->Family = NvRmChipFamily_Mcp; s = "MCP"; break; case APB_MISC_GP_HIDREV_0_HIDFAM_CK: id->Family = NvRmChipFamily_Ck; s = "Ck"; break; case APB_MISC_GP_HIDREV_0_HIDFAM_VAIO: id->Family = NvRmChipFamily_Vaio; s = "Vaio"; break; case APB_MISC_GP_HIDREV_0_HIDFAM_HANDHELD_SOC: id->Family = NvRmChipFamily_HandheldSoc; s = "Handheld SOC"; break; default: NV_ASSERT( !"bad chip family" ); NvRmPhysicalMemUnmap(VirtAddr, 0x1000); return; } reg = NV_READ32( VirtAddr + APB_MISC_GP_EMU_REVID_0 ); id->Netlist = (NvU16)NV_DRF_VAL( APB_MISC_GP, EMU_REVID, NETLIST, reg ); id->Patch = (NvU16)NV_DRF_VAL( APB_MISC_GP, EMU_REVID, PATCH, reg ); if( id->Major == 0 ) { char *emu; if( id->Netlist == 0 ) { NvOsDebugPrintf( "Simulation Chip: 0x%x\n", id->Id ); } else { if( id->Minor == 0 ) { emu = "QuickTurn"; } else { emu = "FPGA"; } NvOsDebugPrintf( "Emulation (%s) Chip: 0x%x Netlist: 0x%x " "Patch: 0x%x\n", emu, id->Id, id->Netlist, id->Patch ); } } else { // on real silicon NvRmPrivGetSku( rm ); NvOsDebugPrintf( "Chip Id: 0x%x (%s) Major: 0x%x Minor: 0x%x " "SKU: 0x%x\n", id->Id, s, id->Major, id->Minor, id->SKU ); } // add a sanity check here, so that if we think we are on sim, but don't // detect a sim/quickturn netlist bail out with an error if ( NvRmIsSimulation() && id->Major != 0 ) { // this should all get optimized away in release builds because the // above will get evaluated to if ( 0 ) NV_ASSERT(!"invalid major version number for simulation"); } NvRmPhysicalMemUnmap(VirtAddr, 0x1000); #endif }