49acec5b5f
Signed-off-by: Stefan Koch <stefan.koch10@gmail.com>
902 lines
29 KiB
Diff
902 lines
29 KiB
Diff
--- a/configure.in
|
|
+++ b/configure.in
|
|
@@ -956,14 +956,15 @@ AC_DEFINE([VMMC],[1],[enable VMMC suppor
|
|
AM_CONDITIONAL(DANUBE, false)
|
|
AM_CONDITIONAL(AR9, false)
|
|
AM_CONDITIONAL(VR9, false)
|
|
+AM_CONDITIONAL(FALCON, false)
|
|
AC_ARG_WITH(device,
|
|
AC_HELP_STRING(
|
|
- [--with-device=DANUBE|TWINPASS|AR9|VR9],
|
|
+ [--with-device=DANUBE|TWINPASS|AR9|VR9|FALCON],
|
|
[Set device type, default is DANUBE]
|
|
),
|
|
[
|
|
if test "$withval" = yes; then
|
|
- AC_MSG_ERROR([Set device type! Valid choices are DANUBE|TWINPASS|AR9|VR9]);
|
|
+ AC_MSG_ERROR([Set device type! Valid choices are DANUBE|TWINPASS|AR9|VR9|FALCON]);
|
|
else
|
|
case $withval in
|
|
DANUBE)
|
|
@@ -986,8 +987,13 @@ AC_ARG_WITH(device,
|
|
AC_DEFINE([SYSTEM_VR9],[1],[enable VR9 specific code])
|
|
AM_CONDITIONAL(VR9, true)
|
|
;;
|
|
+ FALCON)
|
|
+ AC_MSG_RESULT(FALCON device is used);
|
|
+ AC_DEFINE([SYSTEM_FALCON],[1],[enable FALCON specific code])
|
|
+ AM_CONDITIONAL(FALCON, true)
|
|
+ ;;
|
|
*)
|
|
- AC_MSG_ERROR([Set device type! Valid choices are DANUBE|TWINPASS|AR9|VR9]);
|
|
+ AC_MSG_ERROR([Set device type! Valid choices are DANUBE|TWINPASS|AR9|VR9|FALCON]);
|
|
;;
|
|
esac
|
|
fi
|
|
--- a/src/Makefile.am
|
|
+++ b/src/Makefile.am
|
|
@@ -70,6 +70,11 @@ drv_vmmc_SOURCES +=\
|
|
mps/drv_mps_vmmc_ar9.c
|
|
endif
|
|
|
|
+if FALCON
|
|
+drv_vmmc_SOURCES +=\
|
|
+ mps/drv_mps_vmmc_falcon.c
|
|
+endif
|
|
+
|
|
endif
|
|
|
|
if PMC_SUPPORT
|
|
--- a/drv_version.h
|
|
+++ b/drv_version.h
|
|
@@ -36,6 +36,10 @@
|
|
#define MIN_FW_MAJORSTEP 2
|
|
#define MIN_FW_MINORSTEP 1
|
|
#define MIN_FW_HOTFIXSTEP 0
|
|
+#elif defined(SYSTEM_FALCON)
|
|
+#define MIN_FW_MAJORSTEP 0
|
|
+#define MIN_FW_MINORSTEP 1
|
|
+#define MIN_FW_HOTFIXSTEP 0
|
|
#else
|
|
#error unknown system
|
|
#endif
|
|
--- a/src/drv_vmmc_bbd.c
|
|
+++ b/src/drv_vmmc_bbd.c
|
|
@@ -34,6 +34,7 @@
|
|
#define VMMC_WL_SDD_BASIC_CFG 0x04000400
|
|
#define VMMC_WL_SDD_RING_CFG 0x04000500
|
|
#define VMMC_WL_SDD_DCDC_CFG 0x04000C00
|
|
+#define VMMC_WL_SDD_MWI_CFG 0x04000600
|
|
|
|
#define IDLE_EXT_TOGGLE_SLEEP_MS 5
|
|
|
|
@@ -52,6 +53,8 @@
|
|
#define BBD_VMMC_MAGIC 0x41523921 /* "AR9" */
|
|
#elif defined(SYSTEM_VR9)
|
|
#define BBD_VMMC_MAGIC 0x56523921 /* "VR9" */
|
|
+#elif defined(SYSTEM_FALCON)
|
|
+#define BBD_VMMC_MAGIC 0x46414C43 /* "FALC" */
|
|
#else
|
|
#error system undefined
|
|
#endif
|
|
@@ -525,9 +528,6 @@ static IFX_int32_t VMMC_BBD_BlockHandler
|
|
IFX_uint16_t slic_val;
|
|
IFX_int32_t ret = IFX_SUCCESS;
|
|
|
|
- TRACE(VMMC, DBG_LEVEL_LOW,
|
|
- ("bbd block with tag 0x%04X passed\n", pBBDblock->tag));
|
|
-
|
|
/* for FXO line allowed blocks are FXO_CRAM and TRANSPARENT */
|
|
if (pCh->pALM->line_type_fxs != IFX_TRUE)
|
|
{
|
|
@@ -686,6 +686,7 @@ static IFX_int32_t VMMC_BBD_BlockHandler
|
|
break;
|
|
}
|
|
} /* if */
|
|
+
|
|
return ret;
|
|
}
|
|
|
|
@@ -1026,6 +1027,7 @@ static IFX_int32_t vmmc_BBD_WhiteListedC
|
|
}
|
|
case VMMC_WL_SDD_RING_CFG:
|
|
case VMMC_WL_SDD_DCDC_CFG:
|
|
+ case VMMC_WL_SDD_MWI_CFG:
|
|
ret = CmdWrite (pCh->pParent, Msg.val, Msg.cmd.LENGTH);
|
|
break;
|
|
|
|
@@ -1068,7 +1070,7 @@ static IFX_int32_t vmmc_BBD_DownloadChCr
|
|
IFX_uint32_t countWords;
|
|
IFX_uint32_t posBytes = 0;
|
|
IFX_uint8_t lenBytes, *pByte;
|
|
-#if defined(SYSTEM_AR9) || defined(SYSTEM_VR9)
|
|
+#if defined(SYSTEM_AR9) || defined(SYSTEM_VR9) || defined(SYSTEM_FALCON)
|
|
IFX_uint8_t padBytes = 0;
|
|
#endif
|
|
IFX_uint16_t cram_offset, cram_crc,
|
|
@@ -1088,7 +1090,7 @@ static IFX_int32_t vmmc_BBD_DownloadChCr
|
|
#ifdef SYSTEM_DANUBE
|
|
/* CMD1 is a COP command */
|
|
pCmd[0] = (0x0200) | (pCh->nChannel - 1);
|
|
-#elif defined(SYSTEM_AR9) || defined(SYSTEM_VR9)
|
|
+#elif defined(SYSTEM_AR9) || defined(SYSTEM_VR9) || defined(SYSTEM_FALCON)
|
|
/* SDD_Coef command */
|
|
pCmd[0] = (0x0400) | (pCh->nChannel - 1);
|
|
pCmd[1] = (0x0D00);
|
|
@@ -1111,7 +1113,7 @@ static IFX_int32_t vmmc_BBD_DownloadChCr
|
|
pCmd[1] = ((cram_offset + (posBytes >> 1)) << 8);
|
|
/* set CRAM data while taking care of endianess */
|
|
cpb2w (&pCmd[2], &pByte[posBytes], lenBytes);
|
|
-#elif defined(SYSTEM_AR9) || defined(SYSTEM_VR9)
|
|
+#elif defined(SYSTEM_AR9) || defined(SYSTEM_VR9) || defined(SYSTEM_FALCON)
|
|
/* calculate length to download (in words = 16bit),
|
|
maximum allowed length for this message is 56 Bytes = 28 Words */
|
|
if (countWords > ((MAX_CMD_WORD - CMD_HDR_CNT - 1)))
|
|
@@ -1140,7 +1142,7 @@ static IFX_int32_t vmmc_BBD_DownloadChCr
|
|
/* write Data */
|
|
#if defined SYSTEM_DANUBE
|
|
ret = CmdWrite (pCh->pParent, (IFX_uint32_t *) pCmd, lenBytes);
|
|
-#elif defined(SYSTEM_AR9) || defined(SYSTEM_VR9)
|
|
+#elif defined(SYSTEM_AR9) || defined(SYSTEM_VR9) || defined(SYSTEM_FALCON)
|
|
#if 1
|
|
/* lenBytes + 2 bytes for block offset/length which are not calculated
|
|
in the download progress */
|
|
--- a/src/mps/drv_mps_version.h
|
|
+++ b/src/mps/drv_mps_version.h
|
|
@@ -17,7 +17,7 @@
|
|
#define VERSIONSTEP 2
|
|
#define VERS_TYPE 5
|
|
|
|
-#if defined(SYSTEM_AR9) || defined(SYSTEM_VR9)
|
|
+#if defined(SYSTEM_AR9) || defined(SYSTEM_VR9) || defined(SYSTEM_FALCON)
|
|
#define IFX_MPS_PLATFORM_NAME "MIPS34KEc"
|
|
#elif defined(SYSTEM_DANUBE)
|
|
#define IFX_MPS_PLATFORM_NAME "MIPS24KEc"
|
|
--- a/src/mps/drv_mps_vmmc_linux.c
|
|
+++ b/src/mps/drv_mps_vmmc_linux.c
|
|
@@ -2229,7 +2229,7 @@ IFX_int32_t __init ifx_mps_init_module (
|
|
#if defined(CONFIG_MIPS) && !defined(CONFIG_MIPS_UNCACHED)
|
|
#if defined(SYSTEM_DANUBE)
|
|
bDoCacheOps = IFX_TRUE; /* on Danube always perform cache ops */
|
|
-#elif defined(SYSTEM_AR9) || defined(SYSTEM_VR9)
|
|
+#elif defined(SYSTEM_AR9) || defined(SYSTEM_VR9) || defined(SYSTEM_FALCON)
|
|
/* on AR9/VR9 cache is configured by BSP;
|
|
here we check whether the D-cache is shared or partitioned;
|
|
1) in case of shared D-cache all cache operations are omitted;
|
|
@@ -2259,7 +2259,8 @@ IFX_int32_t __init ifx_mps_init_module (
|
|
|
|
/* reset the device before initializing the device driver */
|
|
ifx_mps_reset ();
|
|
- result = request_irq (INT_NUM_IM4_IRL18,
|
|
+
|
|
+ result = request_irq (INT_NUM_IM4_IRL18,
|
|
#ifdef LINUX_2_6
|
|
ifx_mps_ad0_irq, 0x0
|
|
#else /* */
|
|
@@ -2400,7 +2401,7 @@ IFX_int32_t __init ifx_mps_init_module (
|
|
if (result = ifx_mps_init_gpt_danube ())
|
|
return result;
|
|
#endif /*DANUBE*/
|
|
- TRACE (MPS, DBG_LEVEL_HIGH, ("Downloading Firmware...\n"));
|
|
+ TRACE (MPS, DBG_LEVEL_HIGH, ("Downloading Firmware...\n"));
|
|
ifx_mps_download_firmware (IFX_NULL, (mps_fw *) 0xa0a00000);
|
|
udelay (500);
|
|
TRACE (MPS, DBG_LEVEL_HIGH, ("Providing Buffers...\n"));
|
|
--- /dev/null
|
|
+++ b/src/mps/drv_mps_vmmc_falcon.c
|
|
@@ -0,0 +1,396 @@
|
|
+/******************************************************************************
|
|
+
|
|
+ Copyright (c) 2009
|
|
+ Lantiq Deutschland GmbH
|
|
+ Am Campeon 3; 85579 Neubiberg, Germany
|
|
+
|
|
+ For licensing information, see the file 'LICENSE' in the root folder of
|
|
+ this software module.
|
|
+
|
|
+****************************************************************************
|
|
+ Module : drv_mps_vmmc_falcon.c
|
|
+ Description : This file contains the implementation of the FALC-ON specific
|
|
+ driver functions.
|
|
+*******************************************************************************/
|
|
+
|
|
+/* ============================= */
|
|
+/* Includes */
|
|
+/* ============================= */
|
|
+#include "drv_config.h"
|
|
+
|
|
+#if defined(SYSTEM_FALCON) /* defined in drv_config.h */
|
|
+
|
|
+/* lib_ifxos headers */
|
|
+#include "ifx_types.h"
|
|
+#include "ifxos_linux_drv.h"
|
|
+#include "ifxos_copy_user_space.h"
|
|
+#include "ifxos_event.h"
|
|
+#include "ifxos_lock.h"
|
|
+#include "ifxos_select.h"
|
|
+#include "ifxos_interrupt.h"
|
|
+#include <linux/gpio.h>
|
|
+#include <sys1_reg.h>
|
|
+#include <falcon.h>
|
|
+#include <falcon_irq.h>
|
|
+#include <vpe.h>
|
|
+#include <sysctrl.h>
|
|
+void (*ifx_bsp_basic_mps_decrypt)(unsigned int addr, int n) = (void (*)(unsigned int, int))0xbf000290;
|
|
+
|
|
+#define IFX_MPS_SRAM IFXMIPS_MPS_SRAM
|
|
+
|
|
+/*#define USE_PLAIN_VOICE_FIRMWARE*/
|
|
+/* board specific headers */
|
|
+
|
|
+/* device specific headers */
|
|
+#include "drv_mps_vmmc.h"
|
|
+#include "drv_mps_vmmc_dbg.h"
|
|
+#include "drv_mps_vmmc_device.h"
|
|
+
|
|
+/* ============================= */
|
|
+/* Local Macros & Definitions */
|
|
+/* ============================= */
|
|
+/* Firmware watchdog timer counter address */
|
|
+#define VPE1_WDOG_CTR_ADDR ((IFX_uint32_t)((IFX_uint8_t* )IFX_MPS_SRAM + 432))
|
|
+
|
|
+/* Firmware watchdog timeout range, values in ms */
|
|
+#define VPE1_WDOG_TMOUT_MIN 20
|
|
+#define VPE1_WDOG_TMOUT_MAX 5000
|
|
+
|
|
+/* ============================= */
|
|
+/* Global variable definition */
|
|
+/* ============================= */
|
|
+extern mps_comm_dev *pMPSDev;
|
|
+
|
|
+/* ============================= */
|
|
+/* Global function declaration */
|
|
+/* ============================= */
|
|
+IFX_void_t ifx_mps_release (IFX_void_t);
|
|
+extern IFX_uint32_t ifx_mps_reset_structures (mps_comm_dev * pMPSDev);
|
|
+extern IFX_int32_t ifx_mps_bufman_close (IFX_void_t);
|
|
+extern IFXOS_event_t fw_ready_evt;
|
|
+
|
|
+/* ============================= */
|
|
+/* Local variable definition */
|
|
+/* ============================= */
|
|
+static IFX_int32_t vpe1_started = 0;
|
|
+/* VMMC watchdog timer callback */
|
|
+IFX_int32_t (*ifx_wdog_callback) (IFX_uint32_t flags) = IFX_NULL;
|
|
+
|
|
+/* ============================= */
|
|
+/* Local function definition */
|
|
+/* ============================= */
|
|
+
|
|
+/******************************************************************************
|
|
+ * AR9 Specific Routines
|
|
+ ******************************************************************************/
|
|
+
|
|
+/**
|
|
+ * Firmware download to Voice CPU
|
|
+ * This function performs a firmware download to the coprocessor.
|
|
+ *
|
|
+ * \param pMBDev Pointer to mailbox device structure
|
|
+ * \param pFWDwnld Pointer to firmware structure
|
|
+ * \return 0 IFX_SUCCESS, firmware ready
|
|
+ * \return -1 IFX_ERROR, firmware not downloaded.
|
|
+ * \ingroup Internal
|
|
+ */
|
|
+IFX_int32_t ifx_mps_download_firmware (mps_mbx_dev *pMBDev, mps_fw *pFWDwnld)
|
|
+{
|
|
+ IFX_uint32_t mem, cksum;
|
|
+ IFX_uint8_t crc;
|
|
+ IFX_boolean_t bMemReqNotPresent = IFX_FALSE;
|
|
+
|
|
+ /* VCC register */
|
|
+ /* dummy accesss on GTC for GPONC-55, otherwise upper bits are random on read */
|
|
+ ltq_r32 ((u32 *)((KSEG1 | 0x1DC000B0)));
|
|
+ /* NTR Frequency Select 1536 kHz per default or take existing,
|
|
+ NTR Output Enable and NTR8K Output Enable */
|
|
+ if ((ltq_r32 ((u32 *)(GPON_SYS_BASE + 0xBC)) & 7) == 0)
|
|
+ ltq_w32_mask (0x10187, 0x183, (u32 *)(GPON_SYS_BASE + 0xBC));
|
|
+ else
|
|
+ ltq_w32_mask (0x10180, 0x180, (u32 *)(GPON_SYS_BASE + 0xBC));
|
|
+#if 0
|
|
+ /* BIU-ICU1-IM1_ISR - IM1:FSCT_CMP1=1 and FSC_ROOT=1
|
|
+ (0x1f880328 = 0x00002800) */
|
|
+ ltq_w32 (0x00002800, (u32 *)(GPON_ICU1_BASE + 0x30));
|
|
+#endif
|
|
+ /* copy FW footer from user space */
|
|
+ if (IFX_NULL == IFXOS_CpyFromUser(pFW_img_data,
|
|
+ pFWDwnld->data+pFWDwnld->length/4-sizeof(*pFW_img_data)/4,
|
|
+ sizeof(*pFW_img_data)))
|
|
+ {
|
|
+ TRACE (MPS, DBG_LEVEL_HIGH,
|
|
+ (KERN_ERR "[%s %s %d]: copy_from_user error\r\n",
|
|
+ __FILE__, __func__, __LINE__));
|
|
+ return IFX_ERROR;
|
|
+ }
|
|
+
|
|
+ mem = pFW_img_data->mem;
|
|
+
|
|
+ /* memory requirement sanity check */
|
|
+ if ((crc = ~((mem >> 16) + (mem >> 8) + mem)) != (mem >> 24))
|
|
+ {
|
|
+ TRACE (MPS, DBG_LEVEL_HIGH,
|
|
+ ("[%s %s %d]: warning, image does not contain size - assuming 1MB!\n",
|
|
+ __FILE__, __func__, __LINE__));
|
|
+ mem = 1 * 1024 * 1024;
|
|
+ bMemReqNotPresent = IFX_TRUE;
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ mem &= 0x00FFFFFF;
|
|
+ }
|
|
+
|
|
+ /* check if FW image fits in available memory space */
|
|
+ if (mem > vpe1_get_max_mem(0))
|
|
+ {
|
|
+ TRACE (MPS, DBG_LEVEL_HIGH,
|
|
+ ("[%s %s %d]: error, firmware memory exceeds reserved space (%i > %i)!\n",
|
|
+ __FILE__, __func__, __LINE__, mem, vpe1_get_max_mem(0)));
|
|
+ return IFX_ERROR;
|
|
+ }
|
|
+
|
|
+ /* reset the driver */
|
|
+ ifx_mps_reset ();
|
|
+
|
|
+ /* call BSP to get cpu1 base address */
|
|
+ cpu1_base_addr = (IFX_uint32_t *)vpe1_get_load_addr(0);
|
|
+
|
|
+ /* check if CPU1 base address is sane
|
|
+ \todo: check if address is 1MB aligned,
|
|
+ also make it visible in a /proc fs */
|
|
+ if (!cpu1_base_addr)
|
|
+ {
|
|
+ TRACE (MPS, DBG_LEVEL_HIGH,
|
|
+ (KERN_ERR "IFX_MPS: CPU1 base address is invalid!\r\n"));
|
|
+ return IFX_ERROR;
|
|
+ }
|
|
+ /* further use uncached value */
|
|
+ cpu1_base_addr = (IFX_uint32_t *)KSEG1ADDR(cpu1_base_addr);
|
|
+
|
|
+ /* free all data buffers that might be currently used by FW */
|
|
+ if (IFX_NULL != ifx_mps_bufman_freeall)
|
|
+ {
|
|
+ ifx_mps_bufman_freeall();
|
|
+ }
|
|
+
|
|
+ if(FW_FORMAT_NEW)
|
|
+ {
|
|
+ /* adjust download length */
|
|
+ pFWDwnld->length -= (sizeof(*pFW_img_data)-sizeof(IFX_uint32_t));
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ pFWDwnld->length -= sizeof(IFX_uint32_t);
|
|
+
|
|
+ /* handle unlikely case if FW image does not contain memory requirement -
|
|
+ assumed for old format only */
|
|
+ if (IFX_TRUE == bMemReqNotPresent)
|
|
+ pFWDwnld->length += sizeof(IFX_uint32_t);
|
|
+
|
|
+ /* in case of old FW format always assume that FW is encrypted;
|
|
+ use compile switch USE_PLAIN_VOICE_FIRMWARE for plain FW */
|
|
+#ifndef USE_PLAIN_VOICE_FIRMWARE
|
|
+ pFW_img_data->enc = 1;
|
|
+#else
|
|
+#warning Using unencrypted firmware!
|
|
+ pFW_img_data->enc = 0;
|
|
+#endif /* USE_PLAIN_VOICE_FIRMWARE */
|
|
+ /* initializations for the old format */
|
|
+ pFW_img_data->st_addr_crc = 2*sizeof(IFX_uint32_t) +
|
|
+ FW_AR9_OLD_FMT_XCPT_AREA_SZ;
|
|
+ pFW_img_data->en_addr_crc = pFWDwnld->length;
|
|
+ pFW_img_data->fw_vers = 0;
|
|
+ pFW_img_data->magic = 0;
|
|
+ }
|
|
+
|
|
+ /* copy FW image to base address of CPU1 */
|
|
+ if (IFX_NULL ==
|
|
+ IFXOS_CpyFromUser ((IFX_void_t *)cpu1_base_addr,
|
|
+ (IFX_void_t *)pFWDwnld->data, pFWDwnld->length))
|
|
+ {
|
|
+ TRACE (MPS, DBG_LEVEL_HIGH,
|
|
+ (KERN_ERR "[%s %s %d]: copy_from_user error\r\n", __FILE__,
|
|
+ __func__, __LINE__));
|
|
+ return IFX_ERROR;
|
|
+ }
|
|
+
|
|
+ /* process firmware decryption */
|
|
+ if (pFW_img_data->enc == 1)
|
|
+ {
|
|
+ if(FW_FORMAT_NEW)
|
|
+ {
|
|
+ /* adjust decryption length (avoid decrypting CRC32 checksum) */
|
|
+ pFWDwnld->length -= sizeof(IFX_uint32_t);
|
|
+ }
|
|
+ /* BootROM actually decrypts n+4 bytes if n bytes were passed for
|
|
+ decryption. Subtract sizeof(u32) from length to avoid decryption
|
|
+ of data beyond the FW image code */
|
|
+ pFWDwnld->length -= sizeof(IFX_uint32_t);
|
|
+ ifx_bsp_basic_mps_decrypt((unsigned int)cpu1_base_addr, pFWDwnld->length);
|
|
+ }
|
|
+
|
|
+ /* calculate CRC32 checksum over downloaded image */
|
|
+ cksum = ifx_mps_fw_crc32(cpu1_base_addr, pFW_img_data);
|
|
+
|
|
+ /* verify the checksum */
|
|
+ if(FW_FORMAT_NEW)
|
|
+ {
|
|
+ if (cksum != pFW_img_data->crc32)
|
|
+ {
|
|
+ TRACE (MPS, DBG_LEVEL_HIGH,
|
|
+ ("MPS: FW checksum error: img=0x%08x calc=0x%08x\r\n",
|
|
+ pFW_img_data->crc32, cksum));
|
|
+ return IFX_ERROR;
|
|
+ }
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ /* just store self-calculated checksum */
|
|
+ pFW_img_data->crc32 = cksum;
|
|
+ }
|
|
+
|
|
+ /* start VPE1 */
|
|
+ ifx_mps_release ();
|
|
+
|
|
+ /* get FW version */
|
|
+ return ifx_mps_get_fw_version (0);
|
|
+}
|
|
+
|
|
+
|
|
+/**
|
|
+ * Restart CPU1
|
|
+ * This function restarts CPU1 by accessing the reset request register and
|
|
+ * reinitializes the mailbox.
|
|
+ *
|
|
+ * \return 0 IFX_SUCCESS, successful restart
|
|
+ * \return -1 IFX_ERROR, if reset failed
|
|
+ * \ingroup Internal
|
|
+ */
|
|
+IFX_int32_t ifx_mps_restart (IFX_void_t)
|
|
+{
|
|
+ /* raise reset request for CPU1 and reset driver structures */
|
|
+ ifx_mps_reset ();
|
|
+ /* Disable GPTC Interrupt to CPU1 */
|
|
+ ifx_mps_shutdown_gpt ();
|
|
+ /* re-configure GPTC */
|
|
+ ifx_mps_init_gpt ();
|
|
+ /* let CPU1 run */
|
|
+ ifx_mps_release ();
|
|
+ TRACE (MPS, DBG_LEVEL_HIGH, ("IFX_MPS: Restarting firmware..."));
|
|
+ return ifx_mps_get_fw_version (0);
|
|
+}
|
|
+
|
|
+/**
|
|
+ * Shutdown MPS - stop VPE1
|
|
+ * This function stops VPE1
|
|
+ *
|
|
+ * \ingroup Internal
|
|
+ */
|
|
+IFX_void_t ifx_mps_shutdown (IFX_void_t)
|
|
+{
|
|
+ if (vpe1_started)
|
|
+ {
|
|
+ /* stop VPE1 */
|
|
+ vpe1_sw_stop (0);
|
|
+ vpe1_started = 0;
|
|
+ }
|
|
+ /* free GPTC */
|
|
+ ifx_mps_shutdown_gpt ();
|
|
+}
|
|
+
|
|
+/**
|
|
+ * Reset CPU1
|
|
+ * This function causes a reset of CPU1 by clearing the CPU0 boot ready bit
|
|
+ * in the reset request register RCU_RST_REQ.
|
|
+ * It does not change the boot configuration registers for CPU0 or CPU1.
|
|
+ *
|
|
+ * \return 0 IFX_SUCCESS, cannot fail
|
|
+ * \ingroup Internal
|
|
+ */
|
|
+IFX_void_t ifx_mps_reset (IFX_void_t)
|
|
+{
|
|
+ /* if VPE1 is already started, stop it */
|
|
+ if (vpe1_started)
|
|
+ {
|
|
+ vpe1_sw_stop (0);
|
|
+ vpe1_started = 0;
|
|
+ }
|
|
+
|
|
+ /* reset driver */
|
|
+ ifx_mps_reset_structures (pMPSDev);
|
|
+ ifx_mps_bufman_close ();
|
|
+ return;
|
|
+}
|
|
+
|
|
+/**
|
|
+ * Let CPU1 run
|
|
+ * This function starts VPE1
|
|
+ *
|
|
+ * \return none
|
|
+ * \ingroup Internal
|
|
+ */
|
|
+IFX_void_t ifx_mps_release (IFX_void_t)
|
|
+{
|
|
+ IFX_int_t ret;
|
|
+ IFX_int32_t RetCode = 0;
|
|
+
|
|
+ /* Start VPE1 */
|
|
+ if (IFX_SUCCESS !=
|
|
+ vpe1_sw_start ((IFX_void_t *)cpu1_base_addr, 0, 0))
|
|
+ {
|
|
+ TRACE (MPS, DBG_LEVEL_HIGH, (KERN_ERR "Error starting VPE1\r\n"));
|
|
+ return;
|
|
+ }
|
|
+ vpe1_started = 1;
|
|
+
|
|
+ /* sleep 3 seconds until FW is ready */
|
|
+ ret = IFXOS_EventWait (&fw_ready_evt, 3000, &RetCode);
|
|
+ if ((ret == IFX_ERROR) && (RetCode == 1))
|
|
+ {
|
|
+ /* timeout */
|
|
+ TRACE (MPS, DBG_LEVEL_HIGH,
|
|
+ (KERN_ERR "[%s %s %d]: Timeout waiting for firmware ready.\r\n",
|
|
+ __FILE__, __func__, __LINE__));
|
|
+ /* recalculate and compare the firmware checksum */
|
|
+ ifx_mps_fw_crc_compare(cpu1_base_addr, pFW_img_data);
|
|
+ /* dump exception area on a console */
|
|
+ ifx_mps_dump_fw_xcpt(cpu1_base_addr, pFW_img_data);
|
|
+ }
|
|
+}
|
|
+
|
|
+/**
|
|
+ * Register WDT callback.
|
|
+ * This function is called by VMMC driver to register its callback in
|
|
+ * the MPS driver.
|
|
+ *
|
|
+ * \return 0 IFX_SUCCESS, cannot fail
|
|
+ * \ingroup Internal
|
|
+ */
|
|
+IFX_int32_t
|
|
+ifx_mps_register_wdog_callback (IFX_int32_t (*pfn) (IFX_uint32_t flags))
|
|
+{
|
|
+ ifx_wdog_callback = pfn;
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+/**
|
|
+ Hardware setup on FALC ON
|
|
+*/
|
|
+void sys_hw_setup (void)
|
|
+{
|
|
+ /* Set INFRAC register bit 1: clock enable of the GPE primary clock. */
|
|
+ sys_gpe_hw_activate (0);
|
|
+ /* enable 1.5 V */
|
|
+ ltq_w32_mask (0xf, 0x0b, (u32 *)(GPON_SYS1_BASE | 0xbc));
|
|
+ /* SYS1-CLKEN:GPTC = 1 and MPS, no longer FSCT = 1 */
|
|
+ sys1_hw_activate (ACTS_MPS | ACTS_GPTC);
|
|
+ /* GPTC:CLC:RMC = 1 */
|
|
+ ltq_w32 (0x00000100, (u32 *)(KSEG1 | 0x1E100E00));
|
|
+}
|
|
+
|
|
+#ifndef VMMC_WITH_MPS
|
|
+EXPORT_SYMBOL (ifx_mps_register_wdog_callback);
|
|
+#endif /* !VMMC_WITH_MPS */
|
|
+
|
|
+#endif /* SYSTEM_FALCON */
|
|
--- a/src/mps/drv_mps_vmmc_common.c
|
|
+++ b/src/mps/drv_mps_vmmc_common.c
|
|
@@ -66,6 +66,10 @@ static void inline bsp_mask_and_ack_irq(
|
|
# include <asm/ifx/ifx_regs.h>
|
|
# include <asm/ifx/ifx_gptu.h>
|
|
#endif
|
|
+#if defined(SYSTEM_FALCON)
|
|
+#include <sys1_reg.h>
|
|
+#include <sysctrl.h>
|
|
+#endif
|
|
|
|
#include "drv_mps_vmmc.h"
|
|
#include "drv_mps_vmmc_dbg.h"
|
|
@@ -1156,7 +1160,12 @@ IFX_uint32_t ifx_mps_init_structures (mp
|
|
mailbox, * upstream and downstream direction. */
|
|
memset (
|
|
/* avoid to overwrite CPU boot registers */
|
|
+#if defined(SYSTEM_FALCON)
|
|
+ (IFX_void_t *) MBX_Memory +
|
|
+ 2 * sizeof (mps_boot_cfg_reg),
|
|
+#else
|
|
(IFX_void_t *) MBX_Memory,
|
|
+#endif
|
|
0,
|
|
sizeof (mps_mbx_reg) - 2 * sizeof (mps_boot_cfg_reg));
|
|
MBX_Memory->MBX_UPSTR_CMD_BASE =
|
|
@@ -2651,7 +2660,6 @@ IFX_void_t ifx_mps_enable_mailbox_int ()
|
|
#endif
|
|
|
|
*IFX_MPS_AD0ENR = Ad0Reg.val;
|
|
-
|
|
}
|
|
|
|
/**
|
|
@@ -2669,6 +2677,7 @@ IFX_void_t ifx_mps_disable_mailbox_int (
|
|
Ad0Reg.fld.cu_mbx = 0;
|
|
Ad0Reg.fld.du_mbx = 0;
|
|
*IFX_MPS_AD0ENR = Ad0Reg.val;
|
|
+
|
|
}
|
|
|
|
/**
|
|
@@ -2766,11 +2775,13 @@ irqreturn_t ifx_mps_ad0_irq (IFX_int32_t
|
|
/* handle only enabled interrupts */
|
|
MPS_Ad0StatusReg.val &= *IFX_MPS_AD0ENR;
|
|
|
|
+#if !defined(SYSTEM_FALCON)
|
|
#ifdef LINUX_2_6
|
|
bsp_mask_and_ack_irq (irq);
|
|
#else /* */
|
|
mask_and_ack_danube_irq (irq);
|
|
#endif /* */
|
|
+#endif /* !defined(SYSTEM_FALCON) */
|
|
/* FW is up and ready to process commands */
|
|
if (MPS_Ad0StatusReg.fld.dl_end)
|
|
{
|
|
@@ -2919,11 +2930,13 @@ irqreturn_t ifx_mps_ad1_irq (IFX_int32_t
|
|
/* handle only enabled interrupts */
|
|
MPS_Ad1StatusReg.val &= *IFX_MPS_AD1ENR;
|
|
|
|
+#if !defined(SYSTEM_FALCON)
|
|
#ifdef LINUX_2_6
|
|
bsp_mask_and_ack_irq (irq);
|
|
#else /* */
|
|
mask_and_ack_danube_irq (irq);
|
|
#endif /* */
|
|
+#endif /* !defined(SYSTEM_FALCON) */
|
|
pMPSDev->event.MPS_Ad1Reg.val = MPS_Ad1StatusReg.val;
|
|
|
|
/* use callback function or queue wake up to notify about data reception */
|
|
@@ -2977,11 +2990,13 @@ irqreturn_t ifx_mps_vc_irq (IFX_int32_t
|
|
IFX_MPS_CVC0SR[chan] = MPS_VCStatusReg.val;
|
|
/* handle only enabled interrupts */
|
|
MPS_VCStatusReg.val &= IFX_MPS_VC0ENR[chan];
|
|
+#if !defined(SYSTEM_FALCON)
|
|
#ifdef LINUX_2_6
|
|
bsp_mask_and_ack_irq (irq);
|
|
#else /* */
|
|
mask_and_ack_danube_irq (irq);
|
|
#endif /* */
|
|
+#endif /* !defined(SYSTEM_FALCON) */
|
|
|
|
pMPSDev->event.MPS_VCStatReg[chan].val = MPS_VCStatusReg.val;
|
|
#ifdef PRINT_ON_ERR_INTERRUPT
|
|
@@ -3126,6 +3141,7 @@ IFX_int32_t ifx_mps_get_fw_version (IFX_
|
|
*/
|
|
IFX_return_t ifx_mps_init_gpt ()
|
|
{
|
|
+#if !defined(SYSTEM_FALCON)
|
|
unsigned long flags;
|
|
IFX_uint32_t timer_flags, timer, loops = 0;
|
|
IFX_ulong_t count;
|
|
@@ -3134,7 +3150,11 @@ IFX_return_t ifx_mps_init_gpt ()
|
|
#else /* Danube */
|
|
timer = TIMER1B;
|
|
#endif /* SYSTEM_AR9 || SYSTEM_VR9 */
|
|
+#endif
|
|
|
|
+#if defined(SYSTEM_FALCON)
|
|
+ sys_hw_setup ();
|
|
+#else
|
|
/* calibration loop - required to syncronize GPTC interrupt with falling
|
|
edge of FSC clock */
|
|
timer_flags =
|
|
@@ -3179,7 +3199,7 @@ Probably already in use.\r\n", __FILE__,
|
|
#endif /* DEBUG */
|
|
|
|
IFXOS_UNLOCKINT (flags);
|
|
-
|
|
+#endif
|
|
return IFX_SUCCESS;
|
|
}
|
|
|
|
@@ -3194,6 +3214,9 @@ Probably already in use.\r\n", __FILE__,
|
|
*/
|
|
IFX_void_t ifx_mps_shutdown_gpt (IFX_void_t)
|
|
{
|
|
+#if defined(SYSTEM_FALCON)
|
|
+ sys1_hw_deactivate (ACTS_MPS);
|
|
+#else
|
|
IFX_uint32_t timer;
|
|
#if defined(SYSTEM_AR9) || defined(SYSTEM_VR9)
|
|
timer = TIMER1A;
|
|
@@ -3202,6 +3225,7 @@ IFX_void_t ifx_mps_shutdown_gpt (IFX_voi
|
|
#endif /* SYSTEM_AR9 || SYSTEM_VR9 */
|
|
|
|
ifx_gptu_timer_free (timer);
|
|
+#endif
|
|
}
|
|
|
|
/**
|
|
--- a/src/mps/drv_mps_vmmc_device.h
|
|
+++ b/src/mps/drv_mps_vmmc_device.h
|
|
@@ -22,7 +22,12 @@
|
|
# include <lantiq_soc.h>
|
|
# include <linux/gpio.h>
|
|
#define IFXMIPS_MPS_SRAM ((u32 *)(KSEG1 + 0x1F200000))
|
|
+#if defined(SYSTEM_FALCON)
|
|
+#define IFXMIPS_MPS_BASE_ADDR (KSEG1 + 0x1D004000)
|
|
+#else
|
|
#define IFXMIPS_MPS_BASE_ADDR (KSEG1 + 0x1F107000)
|
|
+#endif
|
|
+
|
|
#define IFXMIPS_MPS_CHIPID ((u32 *)(IFXMIPS_MPS_BASE_ADDR + 0x0344))
|
|
#define IFXMIPS_MPS_VC0ENR ((u32 *)(IFXMIPS_MPS_BASE_ADDR + 0x0000))
|
|
#define IFXMIPS_MPS_RVC0SR ((u32 *)(IFXMIPS_MPS_BASE_ADDR + 0x0010))
|
|
@@ -73,10 +78,11 @@
|
|
/* MPS Common defines */
|
|
/* ============================= */
|
|
|
|
-#define MPS_BASEADDRESS 0xBF107000
|
|
-#define MPS_RAD0SR MPS_BASEADDRESS + 0x0004
|
|
-
|
|
+#if defined(SYSTEM_FALCON)
|
|
+#define MBX_BASEADDRESS 0xBF200040
|
|
+#else
|
|
#define MBX_BASEADDRESS 0xBF200000
|
|
+#endif
|
|
#define VCPU_BASEADDRESS 0xBF208000 /* 0xBF108000 */
|
|
/*---------------------------------------------------------------------------*/
|
|
#if !defined(CONFIG_LANTIQ)
|
|
@@ -118,7 +124,6 @@
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
#ifdef CONFIG_MPS_EVENT_MBX
|
|
-
|
|
#define MBX_CMD_FIFO_SIZE 64 /**< Size of command FIFO in bytes */
|
|
#define MBX_DATA_UPSTRM_FIFO_SIZE 64
|
|
#define MBX_DATA_DNSTRM_FIFO_SIZE 128
|
|
@@ -294,6 +299,10 @@ typedef struct
|
|
#ifdef CONFIG_MPS_EVENT_MBX
|
|
typedef struct
|
|
{
|
|
+#if defined(SYSTEM_FALCON)
|
|
+ mps_boot_cfg_reg MBX_CPU0_BOOT_CFG; /**< CPU0 Boot Configuration */
|
|
+ mps_boot_cfg_reg MBX_CPU1_BOOT_CFG; /**< CPU1 Boot Configuration */
|
|
+#endif
|
|
volatile IFX_uint32_t *MBX_UPSTR_CMD_BASE; /**< Upstream Command FIFO Base Address */
|
|
volatile IFX_uint32_t MBX_UPSTR_CMD_SIZE; /**< Upstream Command FIFO size in byte */
|
|
volatile IFX_uint32_t *MBX_DNSTR_CMD_BASE; /**< Downstream Command FIFO Base Address */
|
|
@@ -317,13 +326,19 @@ typedef struct
|
|
volatile IFX_uint32_t MBX_UPSTR_EVENT_WRITE; /**< Upstream Event FIFO Write Index */
|
|
volatile IFX_uint32_t MBX_EVENT[MBX_EVENT_DATA_WORDS];
|
|
volatile IFX_uint32_t reserved[4];
|
|
+#if !defined(SYSTEM_FALCON)
|
|
mps_boot_cfg_reg MBX_CPU0_BOOT_CFG; /**< CPU0 Boot Configuration */
|
|
mps_boot_cfg_reg MBX_CPU1_BOOT_CFG; /**< CPU1 Boot Configuration */
|
|
+#endif
|
|
} mps_mbx_reg;
|
|
|
|
#else /* */
|
|
typedef struct
|
|
{
|
|
+#if defined(SYSTEM_FALCON)
|
|
+ mps_boot_cfg_reg MBX_CPU0_BOOT_CFG; /**< CPU0 Boot Configuration */
|
|
+ mps_boot_cfg_reg MBX_CPU1_BOOT_CFG; /**< CPU1 Boot Configuration */
|
|
+#endif
|
|
volatile IFX_uint32_t *MBX_UPSTR_CMD_BASE; /**< Upstream Command FIFO Base Address */
|
|
volatile IFX_uint32_t MBX_UPSTR_CMD_SIZE; /**< Upstream Command FIFO size in byte */
|
|
volatile IFX_uint32_t *MBX_DNSTR_CMD_BASE; /**< Downstream Command FIFO Base Address */
|
|
@@ -341,8 +356,10 @@ typedef struct
|
|
volatile IFX_uint32_t MBX_DNSTR_DATA_READ; /**< Downstream Data FIFO Read Index */
|
|
volatile IFX_uint32_t MBX_DNSTR_DATA_WRITE; /**< Downstream Data FIFO Write Index */
|
|
volatile IFX_uint32_t MBX_DATA[MBX_DATA_WORDS];
|
|
+#if !defined(SYSTEM_FALCON)
|
|
mps_boot_cfg_reg MBX_CPU0_BOOT_CFG; /**< CPU0 Boot Configuration */
|
|
mps_boot_cfg_reg MBX_CPU1_BOOT_CFG; /**< CPU1 Boot Configuration */
|
|
+#endif
|
|
} mps_mbx_reg;
|
|
#endif /* CONFIG_MPS_EVENT_MBX */
|
|
|
|
--- a/src/drv_api.h
|
|
+++ b/src/drv_api.h
|
|
@@ -183,7 +183,7 @@
|
|
#endif
|
|
|
|
/* TAPI FXS Phone Detection feature is not available for Danube platform */
|
|
-#if defined(TAPI_PHONE_DETECTION) && (defined(SYSTEM_AR9) || defined(SYSTEM_VR9))
|
|
+#if defined(TAPI_PHONE_DETECTION) && (defined(SYSTEM_AR9) || defined(SYSTEM_VR9) || defined(SYSTEM_FALCON))
|
|
#define VMMC_CFG_ADD_FEAT_PHONE_DETECTION VMMC_FEAT_PHONE_DETECTION
|
|
#else
|
|
#define VMMC_CFG_ADD_FEAT_PHONE_DETECTION 0
|
|
--- a/src/drv_vmmc_alm.c
|
|
+++ b/src/drv_vmmc_alm.c
|
|
@@ -800,7 +800,7 @@ IFX_void_t VMMC_ALM_Free_Ch_Structures (
|
|
}
|
|
|
|
|
|
-#if defined(SYSTEM_AR9) || defined(SYSTEM_VR9)
|
|
+#if defined(SYSTEM_AR9) || defined(SYSTEM_VR9) || defined(SYSTEM_FALCON)
|
|
/**
|
|
Check whether SmartSLIC is connected
|
|
|
|
@@ -836,7 +836,7 @@ IFX_boolean_t VMMC_ALM_SmartSLIC_IsConne
|
|
#endif /*SYSTEM_AR9 || SYSTEM_VR9*/
|
|
|
|
|
|
-#if defined(SYSTEM_AR9) || defined(SYSTEM_VR9)
|
|
+#if defined(SYSTEM_AR9) || defined(SYSTEM_VR9) || defined(SYSTEM_FALCON)
|
|
/**
|
|
Read the number of channels on the SmartSLIC.
|
|
|
|
@@ -1876,7 +1876,7 @@ IFX_int32_t VMMC_TAPI_LL_ALM_VMMC_Test_L
|
|
/* write updated message contents */
|
|
ret = CmdWrite (pDev, (IFX_uint32_t *)((IFX_void_t *)&debugCfg),
|
|
DCCTL_CMD_LEN);
|
|
-#elif defined(SYSTEM_AR9) || defined(SYSTEM_VR9)
|
|
+#elif defined(SYSTEM_AR9) || defined(SYSTEM_VR9) || defined(SYSTEM_FALCON)
|
|
IFX_uint32_t dcctrlLoop[2];
|
|
IFX_uint32_t ch = (IFX_uint32_t)(pCh->nChannel - 1);
|
|
|
|
--- a/src/drv_vmmc_alm.h
|
|
+++ b/src/drv_vmmc_alm.h
|
|
@@ -65,7 +65,7 @@ extern IFX_void_t irq_VMMC_ALM_LineDisab
|
|
extern IFX_void_t VMMC_ALM_CorrectLinemodeCache (VMMC_CHANNEL *pCh,
|
|
IFX_uint16_t lm);
|
|
|
|
-#if defined(SYSTEM_AR9) || defined(SYSTEM_VR9)
|
|
+#if defined(SYSTEM_AR9) || defined(SYSTEM_VR9) || defined(SYSTEM_FALCON)
|
|
extern IFX_boolean_t VMMC_ALM_SmartSLIC_IsConnected (
|
|
VMMC_DEVICE *pDev);
|
|
|
|
--- a/src/drv_vmmc_init.c
|
|
+++ b/src/drv_vmmc_init.c
|
|
@@ -52,15 +52,6 @@
|
|
#include "ifx_pmu.h"
|
|
#endif /* PMU_SUPPORTED */
|
|
|
|
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,28))
|
|
-# define IFX_MPS_CAD0SR IFXMIPS_MPS_CAD0SR
|
|
-# define IFX_MPS_CAD1SR IFXMIPS_MPS_CAD1SR
|
|
-# define IFX_MPS_CVC0SR IFXMIPS_MPS_CVC0SR
|
|
-# define IFX_MPS_CVC1SR IFXMIPS_MPS_CVC1SR
|
|
-# define IFX_MPS_CVC2SR IFXMIPS_MPS_CVC2SR
|
|
-# define IFX_MPS_CVC3SR IFXMIPS_MPS_CVC3SR
|
|
-#endif
|
|
-
|
|
/* ============================= */
|
|
/* Local Macros & Definitions */
|
|
/* ============================= */
|
|
@@ -820,7 +811,7 @@ static IFX_int32_t VMMC_TAPI_LL_FW_Init(
|
|
MIN_FW_HOTFIXSTEP};
|
|
IFX_uint8_t tmp1, tmp2;
|
|
IFX_TAPI_RESOURCE nResource;
|
|
-#if defined(SYSTEM_AR9) || defined(SYSTEM_VR9)
|
|
+#if defined(SYSTEM_AR9) || defined(SYSTEM_VR9) || defined(SYSTEM_FALCON)
|
|
IFX_uint8_t nChannels, nFXOChannels;
|
|
#endif /*SYSTEM_AR9 || SYSTEM_VR9*/
|
|
IFX_int32_t ret = VMMC_statusOk;
|
|
@@ -874,7 +865,7 @@ static IFX_int32_t VMMC_TAPI_LL_FW_Init(
|
|
pDev->bSmartSlic = IFX_FALSE;
|
|
pDev->bSlicSupportsIdleMode = IFX_FALSE;
|
|
|
|
-#if defined(SYSTEM_AR9) || defined(SYSTEM_VR9)
|
|
+#if defined(SYSTEM_AR9) || defined(SYSTEM_VR9) || defined(SYSTEM_FALCON)
|
|
if (VMMC_SUCCESS(ret))
|
|
{
|
|
/* Reduce the number of ALM channels in the capabilities if the SLIC
|
|
--- a/src/drv_vmmc_ioctl.c
|
|
+++ b/src/drv_vmmc_ioctl.c
|
|
@@ -273,7 +273,7 @@ IFX_int32_t VMMC_Dev_Spec_Ioctl (IFX_TAP
|
|
case FIO_GET_VERS:
|
|
{
|
|
VMMC_IO_VERSION *pVers;
|
|
-#if defined(SYSTEM_AR9) || defined(SYSTEM_VR9)
|
|
+#if defined(SYSTEM_AR9) || defined(SYSTEM_VR9) || defined(SYSTEM_FALCON)
|
|
VMMC_SDD_REVISION_READ_t *pSDDVersCmd = IFX_NULL;
|
|
#endif /*SYSTEM_AR9 || SYSTEM_VR9*/
|
|
SYS_VER_t *pCmd;
|
|
@@ -322,7 +322,7 @@ IFX_int32_t VMMC_Dev_Spec_Ioctl (IFX_TAP
|
|
pVers->nTapiVers = 3;
|
|
pVers->nDrvVers = MAJORSTEP << 24 | MINORSTEP << 16 |
|
|
VERSIONSTEP << 8 | VERS_TYPE;
|
|
-#if defined(SYSTEM_AR9) || defined(SYSTEM_VR9)
|
|
+#if defined(SYSTEM_AR9) || defined(SYSTEM_VR9) || defined(SYSTEM_FALCON)
|
|
/* in case of SmartSLIC based systems, we can give some more
|
|
versions.*/
|
|
if (VMMC_ALM_SmartSLIC_IsConnected(pDev))
|