| --- 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)) |