--- 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,463 @@ +/****************************************************************************** + + 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 +#include +#include +#include +#include +#include +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); +IFX_int32_t ifx_mps_wdog_callback (IFX_uint32_t wdog_cleared_ok_count); +extern IFXOS_event_t fw_ready_evt; +/* ============================= */ +/* Local function declaration */ +/* ============================= */ +static IFX_int32_t ifx_mps_fw_wdog_start_ar9(IFX_void_t); + +/* ============================= */ +/* 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 + ******************************************************************************/ + +/** + * Start AR9 EDSP firmware watchdog mechanism. + * Called after download and startup of VPE1. + * + * \param none + * \return 0 IFX_SUCCESS + * \return -1 IFX_ERROR + * \ingroup Internal + */ +IFX_int32_t ifx_mps_fw_wdog_start_ar9() +{ + return IFX_SUCCESS; +} + +/** + * 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 (); +#if 0 + /* start FW watchdog mechanism */ + ifx_mps_fw_wdog_start_ar9(); +#endif + /* 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 (); + /* start FW watchdog mechanism */ + ifx_mps_fw_wdog_start_ar9(); + 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 software watchdog timer */ + vpe1_sw_wdog_stop (0); + /* clean up the BSP callback function */ + vpe1_sw_wdog_register_reset_handler (IFX_NULL); + /* 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) + { + /* stop software watchdog timer first */ + vpe1_sw_wdog_stop (0); + 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); + } +} + +/** + * WDT callback. + * This function is called by BSP (module softdog_vpe) in case if software + * watchdog timer expiration is detected by BSP. + * This function needs to be registered at BSP as WDT callback using + * vpe1_sw_wdog_register_reset_handler() API. + * + * \return 0 IFX_SUCCESS, cannot fail + * \ingroup Internal + */ +IFX_int32_t ifx_mps_wdog_callback (IFX_uint32_t wdog_cleared_ok_count) +{ +#ifdef DEBUG + TRACE (MPS, DBG_LEVEL_HIGH, + ("MPS: watchdog callback! arg=0x%08x\r\n", wdog_cleared_ok_count)); +#endif /* DEBUG */ + + /* reset SmartSLIC is done by FW */ + /* 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); + + if (IFX_NULL != ifx_wdog_callback) + { + /* call VMMC driver */ + ifx_wdog_callback (wdog_cleared_ok_count); + } + else + { + TRACE (MPS, DBG_LEVEL_HIGH, + (KERN_WARNING "MPS: VMMC watchdog timer callback is NULL.\r\n")); + } + return 0; +} + +/** + * 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 # include #endif +#if defined(SYSTEM_FALCON) +#include +#include +#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 # include #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))