/******************************************************************************
Copyright (c) 2009
Infineon Technologies AG
Am Campeon 1-12; 81726 Munich, Germany
For licensing information, see the file 'LICENSE' in the root folder of
this software module.
******************************************************************************/
/*!
\defgroup AMAZON_S_MEI Amazon-S MEI Driver Module
\brief Amazon-S MEI driver module
*/
/*!
\defgroup Internal Compile Parametere
\ingroup AMAZON_S_MEI
\brief exported functions for other driver use
*/
/*!
\file amazon_s_mei_bsp.c
\ingroup AMAZON_S_MEI
\brief Amazon-S MEI driver file
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/version.h>
#include <generated/utsrelease.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/proc_fs.h>
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/sched.h>
#include <linux/platform_device.h>
#include <asm/uaccess.h>
#include <asm/hardirq.h>
#include "lantiq_atm.h"
#include <lantiq_soc.h>
//#include "ifxmips_atm.h"
#define IFX_MEI_BSP
#include "ifxmips_mei_interface.h"
/*#define LTQ_RCU_RST IFX_RCU_RST_REQ
#define LTQ_RCU_RST_REQ_ARC_JTAG IFX_RCU_RST_REQ_ARC_JTAG
#define LTQ_RCU_RST_REQ_DFE IFX_RCU_RST_REQ_DFE
#define LTQ_RCU_RST_REQ_AFE IFX_RCU_RST_REQ_AFE
#define IFXMIPS_FUSE_BASE_ADDR IFX_FUSE_BASE_ADDR
#define IFXMIPS_ICU_IM0_IER IFX_ICU_IM0_IER
#define IFXMIPS_ICU_IM2_IER IFX_ICU_IM2_IER
#define LTQ_MEI_INT IFX_MEI_INT
#define LTQ_MEI_DYING_GASP_INT IFX_MEI_DYING_GASP_INT
#define LTQ_MEI_BASE_ADDR IFX_MEI_SPACE_ACCESS
#define IFXMIPS_PMU_PWDCR IFX_PMU_PWDCR
#define IFXMIPS_MPS_CHIPID IFX_MPS_CHIPID
#define ifxmips_port_reserve_pin ifx_gpio_pin_reserve
#define ifxmips_port_set_dir_in ifx_gpio_dir_in_set
#define ifxmips_port_clear_altsel0 ifx_gpio_altsel0_set
#define ifxmips_port_clear_altsel1 ifx_gpio_altsel1_clear
#define ifxmips_port_set_open_drain ifx_gpio_open_drain_clear
#define ifxmips_port_free_pin ifx_gpio_pin_free
#define ifxmips_mask_and_ack_irq bsp_mask_and_ack_irq
#define IFXMIPS_MPS_CHIPID_VERSION_GET IFX_MCD_CHIPID_VERSION_GET
#define ltq_r32(reg) __raw_readl(reg)
#define ltq_w32(val, reg) __raw_writel(val, reg)
#define ltq_w32_mask(clear, set, reg) ltq_w32((ltq_r32(reg) & ~clear) | set, reg)
*/
#define LTQ_RCU_BASE_ADDR 0x1F203000
#define LTQ_ICU_BASE_ADDR 0x1F880200
#define LTQ_MEI_BASE_ADDR 0x1E116000
#define LTQ_PMU_BASE_ADDR 0x1F102000
#ifdef CONFIG_DANUBE
# define LTQ_MEI_INT (INT_NUM_IM1_IRL0 + 23)
# define LTQ_MEI_DYING_GASP_INT (INT_NUM_IM1_IRL0 + 21)
# define LTQ_USB_OC_INT (INT_NUM_IM4_IRL0 + 23)
#endif
#ifdef CONFIG_AMAZON_SE
# define LTQ_MEI_INT (INT_NUM_IM2_IRL0 + 9)
# define LTQ_MEI_DYING_GASP_INT (INT_NUM_IM2_IRL0 + 11)
# define LTQ_USB_OC_INT (INT_NUM_IM2_IRL0 + 20)
#endif
#ifdef CONFIG_AR9
# define LTQ_MEI_INT (INT_NUM_IM1_IRL0 + 23)
# define LTQ_MEI_DYING_GASP_INT (INT_NUM_IM1_IRL0 + 21)
# define LTQ_USB_OC_INT (INT_NUM_IM1_IRL0 + 28)
#endif
#ifndef LTQ_MEI_INT
#error "Unknown Lantiq ARCH!"
#endif
#define LTQ_RCU_RST_REQ_DFE (1 << 7)
#define LTQ_RCU_RST_REQ_AFE (1 << 11)
#define LTQ_PMU_BASE (KSEG1 + LTQ_PMU_BASE_ADDR)
#define LTQ_RCU_BASE (KSEG1 + LTQ_RCU_BASE_ADDR)
#define LTQ_ICU_BASE (KSEG1 + LTQ_ICU_BASE_ADDR)
#define LTQ_PMU_PWDCR ((u32 *)(LTQ_PMU_BASE + 0x001C))
#define LTQ_PMU_PWDSR ((u32 *)(LTQ_PMU_BASE + 0x0020))
#define LTQ_RCU_RST ((u32 *)(LTQ_RCU_BASE + 0x0010))
#define LTQ_RCU_RST_ALL 0x40000000
#define LTQ_ICU_IM0_ISR ((u32 *)(LTQ_ICU_BASE + 0x0000))
#define LTQ_ICU_IM0_IER ((u32 *)(LTQ_ICU_BASE + 0x0008))
#define LTQ_ICU_IM0_IOSR ((u32 *)(LTQ_ICU_BASE + 0x0010))
#define LTQ_ICU_IM0_IRSR ((u32 *)(LTQ_ICU_BASE + 0x0018))
#define LTQ_ICU_IM0_IMR ((u32 *)(LTQ_ICU_BASE + 0x0020))
#define LTQ_ICU_IM1_ISR ((u32 *)(LTQ_ICU_BASE + 0x0028))
#define LTQ_ICU_IM2_ISR ((u32 *)(LTQ_ICU_BASE + 0x0050))
#define LTQ_ICU_IM3_ISR ((u32 *)(LTQ_ICU_BASE + 0x0078))
#define LTQ_ICU_IM4_ISR ((u32 *)(LTQ_ICU_BASE + 0x00A0))
#define LTQ_ICU_OFFSET (LTQ_ICU_IM1_ISR - LTQ_ICU_IM0_ISR)
#define LTQ_ICU_IM2_IER (LTQ_ICU_IM0_IER + LTQ_ICU_OFFSET)
#define IFX_MEI_EMSG(fmt, args...) pr_err("[%s %d]: " fmt,__FUNCTION__, __LINE__, ## args)
#define IFX_MEI_DMSG(fmt, args...) pr_debug("[%s %d]: " fmt,__FUNCTION__, __LINE__, ## args)
#define LTQ_FUSE_BASE (KSEG1 + 0x1F107354)
#ifdef CONFIG_LTQ_MEI_FW_LOOPBACK
//#define DFE_MEM_TEST
//#define DFE_PING_TEST
#define DFE_ATM_LOOPBACK
#ifdef DFE_ATM_LOOPBACK
#include <asm/ifxmips/ifxmips_mei_fw_loopback.h>
#endif
void dfe_loopback_irq_handler (DSL_DEV_Device_t *pDev);
#endif //CONFIG_AMAZON_S_MEI_FW_LOOPBACK
DSL_DEV_Version_t bsp_mei_version = {
major: 5,
minor: 0,
revision:0
};
DSL_DEV_HwVersion_t bsp_chip_info;
#define IFX_MEI_DEVNAME "ifx_mei"
#define BSP_MAX_DEVICES 1
#define MEI_DIRNAME "ifxmips_mei"
DSL_DEV_MeiError_t DSL_BSP_FWDownload (DSL_DEV_Device_t *, const char *, unsigned long, long *, long *);
DSL_DEV_MeiError_t DSL_BSP_Showtime (DSL_DEV_Device_t *, DSL_uint32_t, DSL_uint32_t);
DSL_DEV_MeiError_t DSL_BSP_AdslLedInit (DSL_DEV_Device_t *, DSL_DEV_LedId_t, DSL_DEV_LedType_t, DSL_DEV_LedHandler_t);
//DSL_DEV_MeiError_t DSL_BSP_AdslLedSet (DSL_DEV_Device_t *, DSL_DEV_LedId_t, DSL_DEV_LedMode_t);
DSL_DEV_MeiError_t DSL_BSP_MemoryDebugAccess (DSL_DEV_Device_t *, DSL_BSP_MemoryAccessType_t, DSL_uint32_t, DSL_uint32_t*, DSL_uint32_t);
DSL_DEV_MeiError_t DSL_BSP_SendCMV (DSL_DEV_Device_t *, u16 *, int, u16 *);
int DSL_BSP_KernelIoctls (DSL_DEV_Device_t *, unsigned int, unsigned long);
static DSL_DEV_MeiError_t IFX_MEI_RunAdslModem (DSL_DEV_Device_t *);
static DSL_DEV_MeiError_t IFX_MEI_CpuModeSet (DSL_DEV_Device_t *, DSL_DEV_CpuMode_t);
static DSL_DEV_MeiError_t IFX_MEI_DownloadBootCode (DSL_DEV_Device_t *);
static DSL_DEV_MeiError_t IFX_MEI_ArcJtagEnable (DSL_DEV_Device_t *, int);
static DSL_DEV_MeiError_t IFX_MEI_AdslMailboxIRQEnable (DSL_DEV_Device_t *, int);
static int IFX_MEI_GetPage (DSL_DEV_Device_t *, u32, u32, u32, u32 *, u32 *);
static int IFX_MEI_BarUpdate (DSL_DEV_Device_t *, int);
static ssize_t IFX_MEI_Write (DSL_DRV_file_t *, const char *, size_t, loff_t *);
static long IFX_MEI_UserIoctls (DSL_DRV_file_t *, unsigned int, unsigned long);
static int IFX_MEI_Open (DSL_DRV_inode_t *, DSL_DRV_file_t *);
static int IFX_MEI_Release (DSL_DRV_inode_t *, DSL_DRV_file_t *);
void AMAZON_SE_MEI_ARC_MUX_Test(void);
void IFX_MEI_ARC_MUX_Test(void);
static int adsl_dummy_ledcallback(void);
int (*ifx_mei_atm_showtime_enter)(struct port_cell_info *, void *) = NULL;
EXPORT_SYMBOL(ifx_mei_atm_showtime_enter);
int (*ifx_mei_atm_showtime_exit)(void) = NULL;
EXPORT_SYMBOL(ifx_mei_atm_showtime_exit);
static int (*g_adsl_ledcallback)(void) = adsl_dummy_ledcallback;
static unsigned int g_tx_link_rate[2] = {0};
static void *g_xdata_addr = NULL;
static u32 *mei_arc_swap_buff = NULL; // holding swap pages
extern void ltq_mask_and_ack_irq(struct irq_data *d);
static void inline MEI_MASK_AND_ACK_IRQ(int x)
{
struct irq_data d;
d.hwirq = x;
ltq_mask_and_ack_irq(&d);
}
#define MEI_MAJOR 105
static int dev_major = MEI_MAJOR;
static struct file_operations bsp_mei_operations = {
owner:THIS_MODULE,
open:IFX_MEI_Open,
release:IFX_MEI_Release,
write:IFX_MEI_Write,
unlocked_ioctl:IFX_MEI_UserIoctls,
};
static DSL_DEV_Device_t dsl_devices[BSP_MAX_DEVICES];