| Index: arch/arm/mach-tegra/nv/nvrm/core/ap15/ap15rm_init_common.c
|
| diff --git a/arch/arm/mach-tegra/nv/nvrm/core/ap15/ap15rm_init_common.c b/arch/arm/mach-tegra/nv/nvrm/core/ap15/ap15rm_init_common.c
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..fe3496ed65cd85ba0d360b219a22dc0d2d29491b
|
| --- /dev/null
|
| +++ b/arch/arm/mach-tegra/nv/nvrm/core/ap15/ap15rm_init_common.c
|
| @@ -0,0 +1,521 @@
|
| +/*
|
| + * Copyright (c) 2007-2009 NVIDIA Corporation.
|
| + * All rights reserved.
|
| + *
|
| + * Redistribution and use in source and binary forms, with or without
|
| + * modification, are permitted provided that the following conditions are met:
|
| + *
|
| + * Redistributions of source code must retain the above copyright notice,
|
| + * this list of conditions and the following disclaimer.
|
| + *
|
| + * Redistributions in binary form must reproduce the above copyright notice,
|
| + * this list of conditions and the following disclaimer in the documentation
|
| + * and/or other materials provided with the distribution.
|
| + *
|
| + * Neither the name of the NVIDIA Corporation nor the names of its contributors
|
| + * may be used to endorse or promote products derived from this software
|
| + * without specific prior written permission.
|
| + *
|
| + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
| + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
| + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
| + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
| + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
| + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
| + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
| + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
| + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
| + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
| + * POSSIBILITY OF SUCH DAMAGE.
|
| + *
|
| + */
|
| +
|
| +#include "nvcommon.h"
|
| +#include "nvos.h"
|
| +#include "nvutil.h"
|
| +#include "nvassert.h"
|
| +#include "nvrm_drf.h"
|
| +#include "nvrm_init.h"
|
| +#include "nvrm_rmctrace.h"
|
| +#include "nvrm_configuration.h"
|
| +#include "nvrm_chiplib.h"
|
| +#include "nvrm_pmu_private.h"
|
| +#include "nvrm_processor.h"
|
| +#include "nvrm_structure.h"
|
| +#include "ap15rm_private.h"
|
| +#include "ap15rm_private.h"
|
| +#include "ap15rm_clocks.h"
|
| +#include "nvodm_query.h"
|
| +#include "nvodm_query_pins.h"
|
| +#include "common/nvrm_hwintf.h"
|
| +#include "nvrm_pinmux_utils.h"
|
| +#include "nvrm_minikernel.h"
|
| +#include "ap15/arapb_misc.h" // chipid, has to be the same for all chips
|
| +#include "ap15/arapbpm.h"
|
| +#include "ap15/arfuse.h"
|
| +
|
| +extern NvRmCfgMap g_CfgMap[];
|
| +
|
| +void NvRmPrivMemoryInfo( NvRmDeviceHandle hDevice );
|
| +void NvRmPrivReadChipId( NvRmDeviceHandle rm );
|
| +void NvRmPrivGetSku( NvRmDeviceHandle rm );
|
| +/** Returns the pointer to the relocation table */
|
| +NvU32 *NvRmPrivGetRelocationTable( NvRmDeviceHandle hDevice );
|
| +NvError NvRmPrivMapApertures( NvRmDeviceHandle rm );
|
| +void NvRmPrivUnmapApertures( NvRmDeviceHandle rm );
|
| +NvU32 NvRmPrivGetBctCustomerOption(NvRmDeviceHandle hRm);
|
| +
|
| +NvRmCfgMap g_CfgMap[] =
|
| +{
|
| + { "NV_CFG_RMC_FILE", NvRmCfgType_String, (void *)"",
|
| + STRUCT_OFFSET(RmConfigurationVariables, RMCTraceFileName) },
|
| +
|
| + /* don't need chiplib for non-sim builds */
|
| + { "NV_CFG_CHIPLIB", NvRmCfgType_String, (void *)"",
|
| + STRUCT_OFFSET(RmConfigurationVariables, Chiplib) },
|
| +
|
| + { "NV_CFG_CHIPLIB_ARGS", NvRmCfgType_String, (void *)"",
|
| + STRUCT_OFFSET(RmConfigurationVariables, ChiplibArgs) },
|
| +
|
| + { 0 }
|
| +};
|
| +
|
| +NvRmModuleTable *
|
| +NvRmPrivGetModuleTable(
|
| + NvRmDeviceHandle hDevice )
|
| +{
|
| + return &hDevice->ModuleTable;
|
| +}
|
| +
|
| +NvU32 *
|
| +NvRmPrivGetRelocationTable( NvRmDeviceHandle hDevice )
|
| +{
|
| + switch( hDevice->ChipId.Id ) {
|
| + case 0x15:
|
| + return NvRmPrivAp15GetRelocationTable( hDevice );
|
| + case 0x16:
|
| + return NvRmPrivAp16GetRelocationTable( hDevice );
|
| + case 0x20:
|
| + return NvRmPrivAp20GetRelocationTable( hDevice );
|
| + default:
|
| + NV_ASSERT(!"Invalid Chip" );
|
| + return 0;
|
| + }
|
| +}
|
| +
|
| +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
|
| +}
|
| +
|
| +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;
|
| + }
|
| +}
|
| +
|
| +NvError
|
| +NvRmPrivMapApertures( NvRmDeviceHandle rm )
|
| +{
|
| + NvRmModuleTable *tbl;
|
| + NvRmModuleInstance *inst;
|
| + NvRmModule *mod;
|
| + NvU32 devid;
|
| + NvU32 i;
|
| + NvError e;
|
| +
|
| + NV_ASSERT( rm );
|
| +
|
| + /* loop over the instance list and map everything */
|
| + tbl = &rm->ModuleTable;
|
| + mod = tbl->Modules;
|
| + for( i = 0; i < NvRmPrivModuleID_Num; i++ )
|
| + {
|
| + if( mod[i].Index == NVRM_MODULE_INVALID )
|
| + {
|
| + continue;
|
| + }
|
| +
|
| + if ((i != NvRmPrivModuleID_Ahb_Arb_Ctrl ) &&
|
| + (i != NvRmPrivModuleID_ApbDma ) &&
|
| + (i != NvRmPrivModuleID_ApbDmaChannel ) &&
|
| + (i != NvRmPrivModuleID_ClockAndReset ) &&
|
| + (i != NvRmPrivModuleID_ExternalMemoryController ) &&
|
| + (i != NvRmPrivModuleID_Gpio ) &&
|
| + (i != NvRmPrivModuleID_Interrupt ) &&
|
| + (i != NvRmPrivModuleID_InterruptArbGnt ) &&
|
| + (i != NvRmPrivModuleID_InterruptDrq ) &&
|
| + (i != NvRmPrivModuleID_MemoryController ) &&
|
| + (i != NvRmModuleID_Misc) &&
|
| + (i != NvRmPrivModuleID_ArmPerif) &&
|
| + (i != NvRmModuleID_3D) &&
|
| + (i != NvRmModuleID_CacheMemCtrl ) &&
|
| + (i != NvRmModuleID_Display) &&
|
| + (i != NvRmModuleID_Dvc) &&
|
| + (i != NvRmModuleID_FlowCtrl ) &&
|
| + (i != NvRmModuleID_Fuse ) &&
|
| + (i != NvRmModuleID_GraphicsHost ) &&
|
| + (i != NvRmModuleID_I2c) &&
|
| + (i != NvRmModuleID_Isp) &&
|
| + (i != NvRmModuleID_Mpe) &&
|
| + (i != NvRmModuleID_Pmif ) &&
|
| + (i != NvRmModuleID_Mipi ) &&
|
| + (i != NvRmModuleID_ResourceSema ) &&
|
| + (i != NvRmModuleID_SysStatMonitor ) &&
|
| + (i != NvRmModuleID_TimerUs ) &&
|
| + (i != NvRmModuleID_Vde ) &&
|
| + (i != NvRmModuleID_ExceptionVector ) &&
|
| + (i != NvRmModuleID_Usb2Otg ) &&
|
| + (i != NvRmModuleID_Vi)
|
| + )
|
| + {
|
| + continue;
|
| + }
|
| +
|
| + /* FIXME If the multiple instances of the same module is adjacent to
|
| + * each other then we can do one allocation for all those modules.
|
| + */
|
| +
|
| + /* map all of the device instances */
|
| + inst = tbl->ModInst + mod[i].Index;
|
| + devid = inst->DeviceId;
|
| + while( devid == inst->DeviceId )
|
| + {
|
| + /* If this is a device that actually has an aperture... */
|
| + if (inst->PhysAddr)
|
| + {
|
| + e = NvRmPhysicalMemMap(
|
| + inst->PhysAddr, inst->Length, NVOS_MEM_READ_WRITE,
|
| + NvOsMemAttribute_Uncached, &inst->VirtAddr);
|
| + if (e != NvSuccess)
|
| + {
|
| + NV_DEBUG_PRINTF(("Device %d at physical addr 0x%X has no "
|
| + "virtual mapping\n", devid, inst->PhysAddr));
|
| + return e;
|
| + }
|
| + }
|
| +
|
| + inst++;
|
| + }
|
| + }
|
| +
|
| + return NvSuccess;
|
| +}
|
| +
|
| +void
|
| +NvRmPrivUnmapApertures( NvRmDeviceHandle rm )
|
| +{
|
| + NvRmModuleTable *tbl;
|
| + NvRmModuleInstance *inst;
|
| + NvRmModule *mod;
|
| + NvU32 devid;
|
| + NvU32 i;
|
| +
|
| + NV_ASSERT( rm );
|
| +
|
| + /* loop over the instance list and unmap everything */
|
| + tbl = &rm->ModuleTable;
|
| + mod = tbl->Modules;
|
| + for( i = 0; i < NvRmPrivModuleID_Num; i++ )
|
| + {
|
| + if( mod[i].Index == NVRM_MODULE_INVALID )
|
| + {
|
| + continue;
|
| + }
|
| +
|
| + /* map all of the device instances */
|
| + inst = tbl->ModInst + mod[i].Index;
|
| + devid = inst->DeviceId;
|
| + while( devid == inst->DeviceId )
|
| + {
|
| + NvRmPhysicalMemUnmap( inst->VirtAddr, inst->Length );
|
| + inst++;
|
| + }
|
| + }
|
| +}
|
| +
|
| +NvU32
|
| +NvRmPrivGetBctCustomerOption(NvRmDeviceHandle hRm)
|
| +{
|
| + if (!NvRmIsSimulation())
|
| + {
|
| + return NV_REGR(hRm, NvRmModuleID_Pmif, 0, APBDEV_PMC_SCRATCH20_0);
|
| + }
|
| + else
|
| + {
|
| + return 0;
|
| + }
|
| +}
|
| +
|
| +NvRmChipId *
|
| +NvRmPrivGetChipId(
|
| + NvRmDeviceHandle hDevice )
|
| +{
|
| + return &hDevice->ChipId;
|
| +}
|
| +
|
| +#if !NV_OAL
|
| +void NvRmBasicInit(NvRmDeviceHandle * pHandle)
|
| +{
|
| + NvRmDevice *rm = 0;
|
| + NvError err;
|
| + NvU32 *table = 0;
|
| + NvU32 BctCustomerOption = 0;
|
| +
|
| + *pHandle = 0;
|
| + rm = NvRmPrivGetRmDeviceHandle();
|
| +
|
| + if( rm->bBasicInit )
|
| + {
|
| + *pHandle = rm;
|
| + return;
|
| + }
|
| +
|
| + /* get the default configuration */
|
| + err = NvRmPrivGetDefaultCfg( g_CfgMap, &rm->cfg );
|
| + if( err != NvSuccess )
|
| + {
|
| + goto fail;
|
| + }
|
| +
|
| + /* get the requested configuration */
|
| + err = NvRmPrivReadCfgVars( g_CfgMap, &rm->cfg );
|
| + if( err != NvSuccess )
|
| + {
|
| + goto fail;
|
| + }
|
| +
|
| + /* Read the chip Id and store in the Rm structure. */
|
| + NvRmPrivReadChipId( rm );
|
| +
|
| + // init the module control (relocation table, resets, etc.)
|
| + table = NvRmPrivGetRelocationTable( rm );
|
| + if( !table )
|
| + {
|
| + goto fail;
|
| + }
|
| +
|
| + err = NvRmPrivModuleInit( &rm->ModuleTable, table );
|
| + if( err != NvSuccess )
|
| + {
|
| + goto fail;
|
| + }
|
| +
|
| + NvRmPrivMemoryInfo( rm );
|
| +
|
| + // setup the hw apertures
|
| + err = NvRmPrivMapApertures( rm );
|
| + if( err != NvSuccess )
|
| + {
|
| + goto fail;
|
| + }
|
| +
|
| + BctCustomerOption = NvRmPrivGetBctCustomerOption(rm);
|
| + err = NvRmPrivInitKeyList(rm, &BctCustomerOption, 1);
|
| + if (err != NvSuccess)
|
| + {
|
| + goto fail;
|
| + }
|
| +
|
| + // Now populate the logical interrupt table.
|
| + NvRmPrivInterruptTableInit( rm );
|
| +
|
| + rm->bBasicInit = NV_TRUE;
|
| + // basic init is a super-set of preinit
|
| + rm->bPreInit = NV_TRUE;
|
| + *pHandle = rm;
|
| +
|
| +fail:
|
| + return;
|
| +}
|
| +
|
| +void
|
| +NvRmBasicClose(NvRmDeviceHandle handle)
|
| +{
|
| + if (!NVOS_IS_WINDOWS_X86)
|
| + {
|
| + NvRmPrivDeInitKeyList(handle);
|
| + /* unmap the apertures */
|
| + NvRmPrivUnmapApertures( handle );
|
| + /* deallocate the instance table */
|
| + NvRmPrivModuleDeinit( &handle->ModuleTable );
|
| + }
|
| +}
|
| +#endif
|
|
|