1 /******************************************************************************
4 Infineon Technologies AG
5 Am Campeon 1-12; 81726 Munich, Germany
7 For licensing information, see the file 'LICENSE' in the root folder of
10 ******************************************************************************/
13 \defgroup AMAZON_S_MEI Amazon-S MEI Driver Module
14 \brief Amazon-S MEI driver module
18 \defgroup Internal Compile Parametere
20 \brief exported functions for other driver use
24 \file amazon_s_mei_bsp.c
26 \brief Amazon-S MEI driver file
29 #include <linux/kernel.h>
30 #include <linux/module.h>
31 #include <linux/version.h>
32 #include <generated/utsrelease.h>
33 #include <linux/types.h>
36 #include <linux/errno.h>
37 #include <linux/interrupt.h>
38 #include <linux/netdevice.h>
39 #include <linux/etherdevice.h>
40 #include <linux/proc_fs.h>
41 #include <linux/init.h>
42 #include <linux/ioport.h>
43 #include <linux/delay.h>
44 #include <linux/device.h>
45 #include <linux/sched.h>
46 #include <linux/platform_device.h>
47 #include <asm/uaccess.h>
48 #include <asm/hardirq.h>
50 #include "lantiq_atm.h"
51 #include <lantiq_soc.h>
52 //#include "ifxmips_atm.h"
54 #include "ifxmips_mei_interface.h"
56 /*#define LTQ_RCU_RST IFX_RCU_RST_REQ
57 #define LTQ_RCU_RST_REQ_ARC_JTAG IFX_RCU_RST_REQ_ARC_JTAG
58 #define LTQ_RCU_RST_REQ_DFE IFX_RCU_RST_REQ_DFE
59 #define LTQ_RCU_RST_REQ_AFE IFX_RCU_RST_REQ_AFE
60 #define IFXMIPS_FUSE_BASE_ADDR IFX_FUSE_BASE_ADDR
61 #define IFXMIPS_ICU_IM0_IER IFX_ICU_IM0_IER
62 #define IFXMIPS_ICU_IM2_IER IFX_ICU_IM2_IER
63 #define LTQ_MEI_INT IFX_MEI_INT
64 #define LTQ_MEI_DYING_GASP_INT IFX_MEI_DYING_GASP_INT
65 #define LTQ_MEI_BASE_ADDR IFX_MEI_SPACE_ACCESS
66 #define IFXMIPS_PMU_PWDCR IFX_PMU_PWDCR
67 #define IFXMIPS_MPS_CHIPID IFX_MPS_CHIPID
69 #define ifxmips_port_reserve_pin ifx_gpio_pin_reserve
70 #define ifxmips_port_set_dir_in ifx_gpio_dir_in_set
71 #define ifxmips_port_clear_altsel0 ifx_gpio_altsel0_set
72 #define ifxmips_port_clear_altsel1 ifx_gpio_altsel1_clear
73 #define ifxmips_port_set_open_drain ifx_gpio_open_drain_clear
74 #define ifxmips_port_free_pin ifx_gpio_pin_free
75 #define ifxmips_mask_and_ack_irq bsp_mask_and_ack_irq
76 #define IFXMIPS_MPS_CHIPID_VERSION_GET IFX_MCD_CHIPID_VERSION_GET
77 #define ltq_r32(reg) __raw_readl(reg)
78 #define ltq_w32(val, reg) __raw_writel(val, reg)
79 #define ltq_w32_mask(clear, set, reg) ltq_w32((ltq_r32(reg) & ~clear) | set, reg)
82 #define LTQ_RCU_BASE_ADDR 0x1F203000
83 #define LTQ_ICU_BASE_ADDR 0x1F880200
84 #define LTQ_MEI_BASE_ADDR 0x1E116000
85 #define LTQ_PMU_BASE_ADDR 0x1F102000
86 #define LTQ_MEI_DYING_GASP_INT (INT_NUM_IM1_IRL0 + 21)
87 #define LTQ_USB_OC_INT (INT_NUM_IM4_IRL0 + 23)
88 #define LTQ_MEI_INT (INT_NUM_IM1_IRL0 + 23)
90 #define LTQ_RCU_RST_REQ_DFE (1 << 7)
91 #define LTQ_RCU_RST_REQ_AFE (1 << 11)
93 #define LTQ_PMU_BASE (KSEG1 + LTQ_PMU_BASE_ADDR)
94 #define LTQ_RCU_BASE (KSEG1 + LTQ_RCU_BASE_ADDR)
95 #define LTQ_ICU_BASE (KSEG1 + LTQ_ICU_BASE_ADDR)
97 #define LTQ_PMU_PWDCR ((u32 *)(LTQ_PMU_BASE + 0x001C))
98 #define LTQ_PMU_PWDSR ((u32 *)(LTQ_PMU_BASE + 0x0020))
99 #define LTQ_RCU_RST ((u32 *)(LTQ_RCU_BASE + 0x0010))
100 #define LTQ_RCU_RST_ALL 0x40000000
102 #define LTQ_ICU_IM0_ISR ((u32 *)(LTQ_ICU_BASE + 0x0000))
103 #define LTQ_ICU_IM0_IER ((u32 *)(LTQ_ICU_BASE + 0x0008))
104 #define LTQ_ICU_IM0_IOSR ((u32 *)(LTQ_ICU_BASE + 0x0010))
105 #define LTQ_ICU_IM0_IRSR ((u32 *)(LTQ_ICU_BASE + 0x0018))
106 #define LTQ_ICU_IM0_IMR ((u32 *)(LTQ_ICU_BASE + 0x0020))
109 #define LTQ_ICU_IM1_ISR ((u32 *)(LTQ_ICU_BASE + 0x0028))
110 #define LTQ_ICU_IM2_ISR ((u32 *)(LTQ_ICU_BASE + 0x0050))
111 #define LTQ_ICU_IM3_ISR ((u32 *)(LTQ_ICU_BASE + 0x0078))
112 #define LTQ_ICU_IM4_ISR ((u32 *)(LTQ_ICU_BASE + 0x00A0))
114 #define LTQ_ICU_OFFSET (LTQ_ICU_IM1_ISR - LTQ_ICU_IM0_ISR)
115 #define LTQ_ICU_IM2_IER (LTQ_ICU_IM0_IER + LTQ_ICU_OFFSET)
117 #define IFX_MEI_EMSG(fmt, args...) pr_err("[%s %d]: " fmt,__FUNCTION__, __LINE__, ## args)
118 #define IFX_MEI_DMSG(fmt, args...) pr_debug("[%s %d]: " fmt,__FUNCTION__, __LINE__, ## args)
120 #define LTQ_FUSE_BASE (KSEG1 + 0x1F107354)
122 #ifdef CONFIG_LTQ_MEI_FW_LOOPBACK
123 //#define DFE_MEM_TEST
124 //#define DFE_PING_TEST
125 #define DFE_ATM_LOOPBACK
128 #ifdef DFE_ATM_LOOPBACK
129 #include <asm/ifxmips/ifxmips_mei_fw_loopback.h>
132 void dfe_loopback_irq_handler (DSL_DEV_Device_t *pDev);
134 #endif //CONFIG_AMAZON_S_MEI_FW_LOOPBACK
136 DSL_DEV_Version_t bsp_mei_version = {
141 DSL_DEV_HwVersion_t bsp_chip_info;
143 #define IFX_MEI_DEVNAME "ifx_mei"
144 #define BSP_MAX_DEVICES 1
145 #define MEI_DIRNAME "ifxmips_mei"
147 DSL_DEV_MeiError_t DSL_BSP_FWDownload (DSL_DEV_Device_t *, const char *, unsigned long, long *, long *);
148 DSL_DEV_MeiError_t DSL_BSP_Showtime (DSL_DEV_Device_t *, DSL_uint32_t, DSL_uint32_t);
149 DSL_DEV_MeiError_t DSL_BSP_AdslLedInit (DSL_DEV_Device_t *, DSL_DEV_LedId_t, DSL_DEV_LedType_t, DSL_DEV_LedHandler_t);
150 //DSL_DEV_MeiError_t DSL_BSP_AdslLedSet (DSL_DEV_Device_t *, DSL_DEV_LedId_t, DSL_DEV_LedMode_t);
151 DSL_DEV_MeiError_t DSL_BSP_MemoryDebugAccess (DSL_DEV_Device_t *, DSL_BSP_MemoryAccessType_t, DSL_uint32_t, DSL_uint32_t*, DSL_uint32_t);
152 DSL_DEV_MeiError_t DSL_BSP_SendCMV (DSL_DEV_Device_t *, u16 *, int, u16 *);
154 int DSL_BSP_KernelIoctls (DSL_DEV_Device_t *, unsigned int, unsigned long);
156 static DSL_DEV_MeiError_t IFX_MEI_RunAdslModem (DSL_DEV_Device_t *);
157 static DSL_DEV_MeiError_t IFX_MEI_CpuModeSet (DSL_DEV_Device_t *, DSL_DEV_CpuMode_t);
158 static DSL_DEV_MeiError_t IFX_MEI_DownloadBootCode (DSL_DEV_Device_t *);
159 static DSL_DEV_MeiError_t IFX_MEI_ArcJtagEnable (DSL_DEV_Device_t *, int);
160 static DSL_DEV_MeiError_t IFX_MEI_AdslMailboxIRQEnable (DSL_DEV_Device_t *, int);
162 static int IFX_MEI_GetPage (DSL_DEV_Device_t *, u32, u32, u32, u32 *, u32 *);
163 static int IFX_MEI_BarUpdate (DSL_DEV_Device_t *, int);
165 static ssize_t IFX_MEI_Write (DSL_DRV_file_t *, const char *, size_t, loff_t *);
166 static long IFX_MEI_UserIoctls (DSL_DRV_file_t *, unsigned int, unsigned long);
167 static int IFX_MEI_Open (DSL_DRV_inode_t *, DSL_DRV_file_t *);
168 static int IFX_MEI_Release (DSL_DRV_inode_t *, DSL_DRV_file_t *);
170 void AMAZON_SE_MEI_ARC_MUX_Test(void);
172 void IFX_MEI_ARC_MUX_Test(void);
174 static int adsl_dummy_ledcallback(void);
176 int (*ifx_mei_atm_showtime_enter)(struct port_cell_info *, void *) = NULL;
177 EXPORT_SYMBOL(ifx_mei_atm_showtime_enter);
179 int (*ifx_mei_atm_showtime_exit)(void) = NULL;
180 EXPORT_SYMBOL(ifx_mei_atm_showtime_exit);
182 static int (*g_adsl_ledcallback)(void) = adsl_dummy_ledcallback;
184 static unsigned int g_tx_link_rate[2] = {0};
186 static void *g_xdata_addr = NULL;
188 static u32 *mei_arc_swap_buff = NULL; // holding swap pages
190 extern void ltq_mask_and_ack_irq(struct irq_data *d);
191 static void inline MEI_MASK_AND_ACK_IRQ(int x)
195 ltq_mask_and_ack_irq(&d);
197 #define MEI_MAJOR 105
198 static int dev_major = MEI_MAJOR;
200 static struct file_operations bsp_mei_operations = {
203 release:IFX_MEI_Release,
205 unlocked_ioctl:IFX_MEI_UserIoctls,
208 static DSL_DEV_Device_t dsl_devices[BSP_MAX_DEVICES];
210 static ifx_mei_device_private_t
211 sDanube_Mei_Private[BSP_MAX_DEVICES];
213 static DSL_BSP_EventCallBack_t dsl_bsp_event_callback[DSL_BSP_CB_LAST + 1];
216 * Write a value to register
217 * This function writes a value to danube register
219 * \param ul_address The address to write
220 * \param ul_data The value to write
224 IFX_MEI_LongWordWrite (u32 ul_address, u32 ul_data)
226 IFX_MEI_WRITE_REGISTER_L (ul_data, ul_address);
232 * Write a value to register
233 * This function writes a value to danube register
235 * \param pDev the device pointer
236 * \param ul_address The address to write
237 * \param ul_data The value to write
241 IFX_MEI_LongWordWriteOffset (DSL_DEV_Device_t * pDev, u32 ul_address,
244 IFX_MEI_WRITE_REGISTER_L (ul_data, pDev->base_address + ul_address);
250 * Read the danube register
251 * This function read the value from danube register
253 * \param ul_address The address to write
254 * \param pul_data Pointer to the data
258 IFX_MEI_LongWordRead (u32 ul_address, u32 * pul_data)
260 *pul_data = IFX_MEI_READ_REGISTER_L (ul_address);
266 * Read the danube register
267 * This function read the value from danube register
269 * \param pDev the device pointer
270 * \param ul_address The address to write
271 * \param pul_data Pointer to the data
275 IFX_MEI_LongWordReadOffset (DSL_DEV_Device_t * pDev, u32 ul_address,
278 *pul_data = IFX_MEI_READ_REGISTER_L (pDev->base_address + ul_address);
284 * Write several DWORD datas to ARC memory via ARC DMA interface
285 * This function writes several DWORD datas to ARC memory via DMA interface.
287 * \param pDev the device pointer
288 * \param destaddr The address to write
289 * \param databuff Pointer to the data buffer
290 * \param databuffsize Number of DWORDs to write
291 * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
294 static DSL_DEV_MeiError_t
295 IFX_MEI_DMAWrite (DSL_DEV_Device_t * pDev, u32 destaddr,
296 u32 * databuff, u32 databuffsize)
302 return DSL_DEV_MEI_ERR_FAILURE;
304 // Set the write transfer address
305 IFX_MEI_LongWordWriteOffset (pDev, ME_DX_AD, destaddr);
307 // Write the data pushed across DMA
308 while (databuffsize--) {
310 if (destaddr == MEI_TO_ARC_MAILBOX)
311 MEI_HALF_WORD_SWAP (temp);
312 IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_DX_DATA, temp);
316 return DSL_DEV_MEI_ERR_SUCCESS;
321 * Read several DWORD datas from ARC memory via ARC DMA interface
322 * This function reads several DWORD datas from ARC memory via DMA interface.
324 * \param pDev the device pointer
325 * \param srcaddr The address to read
326 * \param databuff Pointer to the data buffer
327 * \param databuffsize Number of DWORDs to read
328 * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
331 static DSL_DEV_MeiError_t
332 IFX_MEI_DMARead (DSL_DEV_Device_t * pDev, u32 srcaddr, u32 * databuff,
339 return DSL_DEV_MEI_ERR_FAILURE;
341 // Set the read transfer address
342 IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_DX_AD, srcaddr);
344 // Read the data popped across DMA
345 while (databuffsize--) {
346 IFX_MEI_LongWordReadOffset (pDev, (u32) ME_DX_DATA, &temp);
347 if (databuff == (u32 *) DSL_DEV_PRIVATE(pDev)->CMV_RxMsg) // swap half word
348 MEI_HALF_WORD_SWAP (temp);
353 return DSL_DEV_MEI_ERR_SUCCESS;
358 * Switch the ARC control mode
359 * This function switchs the ARC control mode to JTAG mode or MEI mode
361 * \param pDev the device pointer
362 * \param mode The mode want to switch: JTAG_MASTER_MODE or MEI_MASTER_MODE.
366 IFX_MEI_ControlModeSet (DSL_DEV_Device_t * pDev, int mode)
370 IFX_MEI_LongWordReadOffset (pDev, (u32) ME_DBG_MASTER, &temp);
372 case JTAG_MASTER_MODE:
373 temp &= ~(HOST_MSTR);
375 case MEI_MASTER_MODE:
379 IFX_MEI_EMSG ("IFX_MEI_ControlModeSet: unkonwn mode [%d]\n", mode);
382 IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_DBG_MASTER, temp);
386 * Disable ARC to MEI interrupt
388 * \param pDev the device pointer
392 IFX_MEI_IRQDisable (DSL_DEV_Device_t * pDev)
394 IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_ARC2ME_MASK, 0x0);
398 * Eable ARC to MEI interrupt
400 * \param pDev the device pointer
404 IFX_MEI_IRQEnable (DSL_DEV_Device_t * pDev)
406 IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_ARC2ME_MASK, MSGAV_EN);
410 * Poll for transaction complete signal
411 * This function polls and waits for transaction complete signal.
413 * \param pDev the device pointer
417 meiPollForDbgDone (DSL_DEV_Device_t * pDev)
422 while (i < WHILE_DELAY) {
423 IFX_MEI_LongWordReadOffset (pDev, (u32) ME_ARC2ME_STAT, &query);
424 query &= (ARC_TO_MEI_DBG_DONE);
428 if (i == WHILE_DELAY) {
429 IFX_MEI_EMSG ("PollforDbg fail!\n");
432 IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_ARC2ME_STAT, ARC_TO_MEI_DBG_DONE); // to clear this interrupt
436 * ARC Debug Memory Access for a single DWORD reading.
437 * This function used for direct, address-based access to ARC memory.
439 * \param pDev the device pointer
440 * \param DEC_mode ARC memory space to used
441 * \param address Address to read
442 * \param data Pointer to data
443 * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
446 static DSL_DEV_MeiError_t
447 _IFX_MEI_DBGLongWordRead (DSL_DEV_Device_t * pDev, u32 DEC_mode,
448 u32 address, u32 * data)
450 IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_DBG_DECODE, DEC_mode);
451 IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_DBG_RD_AD, address);
452 meiPollForDbgDone (pDev);
453 IFX_MEI_LongWordReadOffset (pDev, (u32) ME_DBG_DATA, data);
454 return DSL_DEV_MEI_ERR_SUCCESS;
458 * ARC Debug Memory Access for a single DWORD writing.
459 * This function used for direct, address-based access to ARC memory.
461 * \param pDev the device pointer
462 * \param DEC_mode ARC memory space to used
463 * \param address The address to write
464 * \param data The data to write
465 * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
468 static DSL_DEV_MeiError_t
469 _IFX_MEI_DBGLongWordWrite (DSL_DEV_Device_t * pDev, u32 DEC_mode,
470 u32 address, u32 data)
472 IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_DBG_DECODE, DEC_mode);
473 IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_DBG_WR_AD, address);
474 IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_DBG_DATA, data);
475 meiPollForDbgDone (pDev);
476 return DSL_DEV_MEI_ERR_SUCCESS;
480 * ARC Debug Memory Access for writing.
481 * This function used for direct, address-based access to ARC memory.
483 * \param pDev the device pointer
484 * \param destaddr The address to read
485 * \param databuffer Pointer to data
486 * \param databuffsize The number of DWORDs to read
487 * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
491 static DSL_DEV_MeiError_t
492 IFX_MEI_DebugWrite (DSL_DEV_Device_t * pDev, u32 destaddr,
493 u32 * databuff, u32 databuffsize)
500 // Open the debug port before DMP memory write
501 IFX_MEI_ControlModeSet (pDev, MEI_MASTER_MODE);
503 // For the requested length, write the address and write the data
506 for (i = 0; i < databuffsize; i++) {
508 _IFX_MEI_DBGLongWordWrite (pDev, ME_DBG_DECODE_DMP1_MASK, address, temp);
513 // Close the debug port after DMP memory write
514 IFX_MEI_ControlModeSet (pDev, JTAG_MASTER_MODE);
516 return DSL_DEV_MEI_ERR_SUCCESS;
520 * ARC Debug Memory Access for reading.
521 * This function used for direct, address-based access to ARC memory.
523 * \param pDev the device pointer
524 * \param srcaddr The address to read
525 * \param databuffer Pointer to data
526 * \param databuffsize The number of DWORDs to read
527 * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
530 static DSL_DEV_MeiError_t
531 IFX_MEI_DebugRead (DSL_DEV_Device_t * pDev, u32 srcaddr, u32 * databuff, u32 databuffsize)
538 // Open the debug port before DMP memory read
539 IFX_MEI_ControlModeSet (pDev, MEI_MASTER_MODE);
541 // For the requested length, write the address and read the data
544 for (i = 0; i < databuffsize; i++) {
545 _IFX_MEI_DBGLongWordRead (pDev, ME_DBG_DECODE_DMP1_MASK, address, &temp);
551 // Close the debug port after DMP memory read
552 IFX_MEI_ControlModeSet (pDev, JTAG_MASTER_MODE);
554 return DSL_DEV_MEI_ERR_SUCCESS;
558 * Send a message to ARC MailBox.
559 * This function sends a message to ARC Mailbox via ARC DMA interface.
561 * \param pDev the device pointer
562 * \param msgsrcbuffer Pointer to message.
563 * \param msgsize The number of words to write.
564 * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
567 static DSL_DEV_MeiError_t
568 IFX_MEI_MailboxWrite (DSL_DEV_Device_t * pDev, u16 * msgsrcbuffer,
572 u32 arc_mailbox_status = 0x0;
574 DSL_DEV_MeiError_t meiMailboxError = DSL_DEV_MEI_ERR_SUCCESS;
578 IFX_MEI_DMAWrite (pDev, MEI_TO_ARC_MAILBOX, (u32 *) msgsrcbuffer, msgsize / 2);
580 IFX_MEI_DMAWrite (pDev, MEI_TO_ARC_MAILBOXR, (u32 *) (&temp), 1);
582 // Notify arc that mailbox write completed
583 DSL_DEV_PRIVATE(pDev)->cmv_waiting = 1;
584 IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_ME2ARC_INT, MEI_TO_ARC_MSGAV);
587 while (i < WHILE_DELAY) { // wait for ARC to clear the bit
588 IFX_MEI_LongWordReadOffset (pDev, (u32) ME_ME2ARC_INT, &arc_mailbox_status);
589 if ((arc_mailbox_status & MEI_TO_ARC_MSGAV) != MEI_TO_ARC_MSGAV)
592 if (i == WHILE_DELAY) {
593 IFX_MEI_EMSG (">>> Timeout waiting for ARC to clear MEI_TO_ARC_MSGAV!!!"
594 " MEI_TO_ARC message size = %d DWORDs <<<\n", msgsize/2);
595 meiMailboxError = DSL_DEV_MEI_ERR_FAILURE;
599 return meiMailboxError;
603 * Read a message from ARC MailBox.
604 * This function reads a message from ARC Mailbox via ARC DMA interface.
606 * \param pDev the device pointer
607 * \param msgsrcbuffer Pointer to message.
608 * \param msgsize The number of words to read
609 * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
612 static DSL_DEV_MeiError_t
613 IFX_MEI_MailboxRead (DSL_DEV_Device_t * pDev, u16 * msgdestbuffer,
616 DSL_DEV_MeiError_t meiMailboxError = DSL_DEV_MEI_ERR_SUCCESS;
619 IFX_MEI_DMARead (pDev, ARC_TO_MEI_MAILBOX, (u32 *) msgdestbuffer, msgsize / 2);
621 // Notify arc that mailbox read completed
622 IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_ARC2ME_STAT, ARC_TO_MEI_MSGAV);
624 return meiMailboxError;
628 * Download boot pages to ARC.
629 * This function downloads boot pages to ARC.
631 * \param pDev the device pointer
632 * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
635 static DSL_DEV_MeiError_t
636 IFX_MEI_DownloadBootPages (DSL_DEV_Device_t * pDev)
643 ** DMA the boot code page(s)
648 (DSL_DEV_PRIVATE(pDev)->img_hdr-> count); boot_loop++) {
649 if ((DSL_DEV_PRIVATE(pDev)-> img_hdr->page[boot_loop].p_size) & BOOT_FLAG) {
650 page_size = IFX_MEI_GetPage (pDev, boot_loop,
651 GET_PROG, MAXSWAPSIZE,
655 IFX_MEI_DMAWrite (pDev, dest_addr,
660 if ((DSL_DEV_PRIVATE(pDev)-> img_hdr->page[boot_loop].d_size) & BOOT_FLAG) {
661 page_size = IFX_MEI_GetPage (pDev, boot_loop,
662 GET_DATA, MAXSWAPSIZE,
666 IFX_MEI_DMAWrite (pDev, dest_addr,
672 return DSL_DEV_MEI_ERR_SUCCESS;
679 IFX_MEI_FuseInit (DSL_DEV_Device_t * pDev)
682 IFX_MEI_DMAWrite (pDev, IRAM0_BASE, &data, 1);
683 IFX_MEI_DMAWrite (pDev, IRAM0_BASE + 4, &data, 1);
684 IFX_MEI_DMAWrite (pDev, IRAM1_BASE, &data, 1);
685 IFX_MEI_DMAWrite (pDev, IRAM1_BASE + 4, &data, 1);
686 IFX_MEI_DMAWrite (pDev, BRAM_BASE, &data, 1);
687 IFX_MEI_DMAWrite (pDev, BRAM_BASE + 4, &data, 1);
688 IFX_MEI_DMAWrite (pDev, ADSL_DILV_BASE, &data, 1);
689 IFX_MEI_DMAWrite (pDev, ADSL_DILV_BASE + 4, &data, 1);
696 IFX_MEI_FuseProg (DSL_DEV_Device_t * pDev)
698 u32 reg_data, fuse_value;
701 IFX_MEI_LongWordRead ((u32) LTQ_RCU_RST, ®_data);
702 while ((reg_data & 0x10000000) == 0) {
703 IFX_MEI_LongWordRead ((u32) LTQ_RCU_RST, ®_data);
705 /* 0x4000 translate to about 16 ms@111M, so should be enough */
709 // STEP a: Prepare memory for external accesses
710 // Write fuse_en bit24
711 IFX_MEI_LongWordRead ((u32) LTQ_RCU_RST, ®_data);
712 IFX_MEI_LongWordWrite ((u32) LTQ_RCU_RST, reg_data | (1 << 24));
714 IFX_MEI_FuseInit (pDev);
715 for (i = 0; i < 4; i++) {
716 IFX_MEI_LongWordRead ((u32) (LTQ_FUSE_BASE) + i * 4, &fuse_value);
717 switch (fuse_value & 0xF0000) {
719 reg_data = ((fuse_value & RX_DILV_ADDR_BIT_MASK) |
720 (RX_DILV_ADDR_BIT_MASK + 0x1));
721 IFX_MEI_DMAWrite (pDev, ADSL_DILV_BASE, ®_data, 1);
724 reg_data = ((fuse_value & RX_DILV_ADDR_BIT_MASK) |
725 (RX_DILV_ADDR_BIT_MASK + 0x1));
726 IFX_MEI_DMAWrite (pDev, ADSL_DILV_BASE + 4, ®_data, 1);
729 reg_data = ((fuse_value & IRAM0_ADDR_BIT_MASK) |
730 (IRAM0_ADDR_BIT_MASK + 0x1));
731 IFX_MEI_DMAWrite (pDev, IRAM0_BASE, ®_data, 1);
734 reg_data = ((fuse_value & IRAM0_ADDR_BIT_MASK) |
735 (IRAM0_ADDR_BIT_MASK + 0x1));
736 IFX_MEI_DMAWrite (pDev, IRAM0_BASE + 4, ®_data, 1);
739 reg_data = ((fuse_value & IRAM1_ADDR_BIT_MASK) |
740 (IRAM1_ADDR_BIT_MASK + 0x1));
741 IFX_MEI_DMAWrite (pDev, IRAM1_BASE, ®_data, 1);
744 reg_data = ((fuse_value & IRAM1_ADDR_BIT_MASK) |
745 (IRAM1_ADDR_BIT_MASK + 0x1));
746 IFX_MEI_DMAWrite (pDev, IRAM1_BASE + 4, ®_data, 1);
749 reg_data = ((fuse_value & BRAM_ADDR_BIT_MASK) |
750 (BRAM_ADDR_BIT_MASK + 0x1));
751 IFX_MEI_DMAWrite (pDev, BRAM_BASE, ®_data, 1);
754 reg_data = ((fuse_value & BRAM_ADDR_BIT_MASK) |
755 (BRAM_ADDR_BIT_MASK + 0x1));
756 IFX_MEI_DMAWrite (pDev, BRAM_BASE + 4, ®_data, 1);
758 default: // PPE efuse
762 IFX_MEI_LongWordRead ((u32) LTQ_RCU_RST, ®_data);
763 IFX_MEI_LongWordWrite ((u32) LTQ_RCU_RST, reg_data & ~(1 << 24));
764 IFX_MEI_LongWordRead ((u32) LTQ_RCU_RST, ®_data);
769 * This function enables DFE Clock
771 * \param pDev the device pointer
772 * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
775 static DSL_DEV_MeiError_t
776 IFX_MEI_EnableCLK (DSL_DEV_Device_t * pDev)
778 u32 arc_debug_data = 0;
779 IFX_MEI_ControlModeSet (pDev, MEI_MASTER_MODE);
780 //enable ac_clk signal
781 _IFX_MEI_DBGLongWordRead (pDev, ME_DBG_DECODE_DMP1_MASK,
782 CRI_CCR0, &arc_debug_data);
783 arc_debug_data |= ACL_CLK_MODE_ENABLE;
784 _IFX_MEI_DBGLongWordWrite (pDev, ME_DBG_DECODE_DMP1_MASK,
785 CRI_CCR0, arc_debug_data);
786 IFX_MEI_ControlModeSet (pDev, JTAG_MASTER_MODE);
787 return DSL_DEV_MEI_ERR_SUCCESS;
792 * This function halts the ARC.
794 * \param pDev the device pointer
795 * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
798 static DSL_DEV_MeiError_t
799 IFX_MEI_HaltArc (DSL_DEV_Device_t * pDev)
801 u32 arc_debug_data = 0x0;
803 // Switch arc control from JTAG mode to MEI mode
804 IFX_MEI_ControlModeSet (pDev, MEI_MASTER_MODE);
805 _IFX_MEI_DBGLongWordRead (pDev, MEI_DEBUG_DEC_AUX_MASK,
806 ARC_DEBUG, &arc_debug_data);
807 arc_debug_data |= ARC_DEBUG_HALT;
808 _IFX_MEI_DBGLongWordWrite (pDev, MEI_DEBUG_DEC_AUX_MASK,
809 ARC_DEBUG, arc_debug_data);
810 // Switch arc control from MEI mode to JTAG mode
811 IFX_MEI_ControlModeSet (pDev, JTAG_MASTER_MODE);
815 return DSL_DEV_MEI_ERR_SUCCESS;
820 * This function runs the ARC.
822 * \param pDev the device pointer
823 * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
826 static DSL_DEV_MeiError_t
827 IFX_MEI_RunArc (DSL_DEV_Device_t * pDev)
829 u32 arc_debug_data = 0x0;
831 // Switch arc control from JTAG mode to MEI mode- write '1' to bit0
832 IFX_MEI_ControlModeSet (pDev, MEI_MASTER_MODE);
833 _IFX_MEI_DBGLongWordRead (pDev, MEI_DEBUG_DEC_AUX_MASK,
834 AUX_STATUS, &arc_debug_data);
836 // Write debug data reg with content ANDd with 0xFDFFFFFF (halt bit cleared)
837 arc_debug_data &= ~ARC_AUX_HALT;
838 _IFX_MEI_DBGLongWordWrite (pDev, MEI_DEBUG_DEC_AUX_MASK,
839 AUX_STATUS, arc_debug_data);
841 // Switch arc control from MEI mode to JTAG mode- write '0' to bit0
842 IFX_MEI_ControlModeSet (pDev, JTAG_MASTER_MODE);
843 // Enable mask for arc codeswap interrupts
844 IFX_MEI_IRQEnable (pDev);
846 return DSL_DEV_MEI_ERR_SUCCESS;
852 * This function resets the ARC.
854 * \param pDev the device pointer
855 * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
858 static DSL_DEV_MeiError_t
859 IFX_MEI_ResetARC (DSL_DEV_Device_t * pDev)
861 u32 arc_debug_data = 0;
863 IFX_MEI_HaltArc (pDev);
865 IFX_MEI_LongWordRead ((u32) LTQ_RCU_RST, &arc_debug_data);
866 IFX_MEI_LongWordWrite ((u32) LTQ_RCU_RST,
867 arc_debug_data | LTQ_RCU_RST_REQ_DFE | LTQ_RCU_RST_REQ_AFE);
870 IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_RST_CTRL, MEI_SOFT_RESET);
871 IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_RST_CTRL, 0);
873 IFX_MEI_IRQDisable (pDev);
875 IFX_MEI_EnableCLK (pDev);
879 *(unsigned long *) (BSP_PPE32_SRST) = 0xC30;
880 *(unsigned long *) (BSP_PPE32_SRST) = 0xFFF;
883 DSL_DEV_PRIVATE(pDev)->modem_ready = 0;
885 return DSL_DEV_MEI_ERR_SUCCESS;
889 DSL_BSP_Showtime (DSL_DEV_Device_t * dev, DSL_uint32_t rate_fast, DSL_uint32_t rate_intl)
891 struct port_cell_info port_cell = {0};
893 IFX_MEI_EMSG ("Datarate US intl = %d, fast = %d\n", (int)rate_intl,
897 g_tx_link_rate[0] = rate_fast / (53 * 8);
899 g_tx_link_rate[1] = rate_intl / (53 * 8);
901 if ( g_tx_link_rate[0] == 0 && g_tx_link_rate[1] == 0 ) {
902 IFX_MEI_EMSG ("Got rate fail.\n");
905 if ( ifx_mei_atm_showtime_enter )
907 port_cell.port_num = 2;
908 port_cell.tx_link_rate[0] = g_tx_link_rate[0];
909 port_cell.tx_link_rate[1] = g_tx_link_rate[1];
910 ifx_mei_atm_showtime_enter(&port_cell, g_xdata_addr);
914 IFX_MEI_EMSG("no hookup from ATM driver to set cell rate\n");
917 return DSL_DEV_MEI_ERR_SUCCESS;
921 * Reset/halt/run the DFE.
922 * This function provide operations to reset/halt/run the DFE.
924 * \param pDev the device pointer
925 * \param mode which operation want to do
926 * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
929 static DSL_DEV_MeiError_t
930 IFX_MEI_CpuModeSet (DSL_DEV_Device_t *pDev,
931 DSL_DEV_CpuMode_t mode)
933 DSL_DEV_MeiError_t err_ret = DSL_DEV_MEI_ERR_FAILURE;
936 err_ret = IFX_MEI_HaltArc (pDev);
939 err_ret = IFX_MEI_RunArc (pDev);
942 err_ret = IFX_MEI_ResetARC (pDev);
951 * Accress DFE memory.
952 * This function provide a way to access DFE memory;
954 * \param pDev the device pointer
955 * \param type read or write
956 * \param destaddr destination address
957 * \param databuff pointer to hold data
958 * \param databuffsize size want to read/write
959 * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
963 DSL_BSP_MemoryDebugAccess (DSL_DEV_Device_t * pDev,
964 DSL_BSP_MemoryAccessType_t type,
965 DSL_uint32_t destaddr, DSL_uint32_t *databuff,
966 DSL_uint32_t databuffsize)
968 DSL_DEV_MeiError_t meierr = DSL_DEV_MEI_ERR_SUCCESS;
970 case DSL_BSP_MEMORY_READ:
971 meierr = IFX_MEI_DebugRead (pDev, (u32)destaddr, (u32*)databuff, (u32)databuffsize);
973 case DSL_BSP_MEMORY_WRITE:
974 meierr = IFX_MEI_DebugWrite (pDev, (u32)destaddr, (u32*)databuff, (u32)databuffsize);
977 return DSL_DEV_MEI_ERR_SUCCESS;
981 * Download boot code to ARC.
982 * This function downloads boot code to ARC.
984 * \param pDev the device pointer
985 * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
988 static DSL_DEV_MeiError_t
989 IFX_MEI_DownloadBootCode (DSL_DEV_Device_t *pDev)
991 IFX_MEI_IRQDisable (pDev);
993 IFX_MEI_EnableCLK (pDev);
995 IFX_MEI_FuseProg (pDev); //program fuse rar
997 IFX_MEI_DownloadBootPages (pDev);
999 return DSL_DEV_MEI_ERR_SUCCESS;
1003 * Enable Jtag debugger interface
1004 * This function setups mips gpio to enable jtag debugger
1006 * \param pDev the device pointer
1007 * \param enable enable or disable
1008 * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
1011 static DSL_DEV_MeiError_t
1012 IFX_MEI_ArcJtagEnable (DSL_DEV_Device_t *dev, int enable)
1019 //reserve gpio 9, 10, 11, 14, 19 for ARC JTAG
1020 ifxmips_port_reserve_pin (0, 9);
1021 ifxmips_port_reserve_pin (0, 10);
1022 ifxmips_port_reserve_pin (0, 11);
1023 ifxmips_port_reserve_pin (0, 14);
1024 ifxmips_port_reserve_pin (1, 3);
1026 ifxmips_port_set_dir_in(0, 11);
1027 ifxmips_port_clear_altsel0(0, 11);
1028 ifxmips_port_clear_altsel1(0, 11);
1029 ifxmips_port_set_open_drain(0, 11);
1031 IFX_MEI_LongWordRead ((u32) LTQ_RCU_RST, ®_data);
1032 IFX_MEI_LongWordWrite ((u32) LTQ_RCU_RST, reg_data | LTQ_RCU_RST_REQ_ARC_JTAG);
1040 return DSL_DEV_MEI_ERR_FAILURE;
1043 return DSL_DEV_MEI_ERR_SUCCESS;
1047 * Enable DFE to MIPS interrupt
1048 * This function enable DFE to MIPS interrupt
1050 * \param pDev the device pointer
1051 * \param enable enable or disable
1052 * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
1055 static DSL_DEV_MeiError_t
1056 IFX_MEI_AdslMailboxIRQEnable (DSL_DEV_Device_t *pDev, int enable)
1058 DSL_DEV_MeiError_t meierr;
1061 meierr = DSL_DEV_MEI_ERR_SUCCESS;
1062 IFX_MEI_IRQDisable (pDev);
1065 IFX_MEI_IRQEnable (pDev);
1066 meierr = DSL_DEV_MEI_ERR_SUCCESS;
1069 meierr = DSL_DEV_MEI_ERR_FAILURE;
1077 * Get the modem status
1078 * This function return the modem status
1080 * \param pDev the device pointer
1081 * \return 1: modem ready 0: not ready
1085 IFX_MEI_IsModemReady (DSL_DEV_Device_t * pDev)
1087 return DSL_DEV_PRIVATE(pDev)->modem_ready;
1091 DSL_BSP_AdslLedInit (DSL_DEV_Device_t * dev,
1092 DSL_DEV_LedId_t led_number,
1093 DSL_DEV_LedType_t type,
1094 DSL_DEV_LedHandler_t handler)
1097 struct led_config_param param;
1098 if (led_number == DSL_LED_LINK_ID && type == DSL_LED_LINK_TYPE && handler == /*DSL_LED_HD_CPU*/DSL_LED_HD_FW) {
1099 param.operation_mask = CONFIG_OPERATION_UPDATE_SOURCE;
1101 param.source = 0x01;
1102 // bsp_led_config (¶m);
1104 } else if (led_number == DSL_LED_DATA_ID && type == DSL_LED_DATA_TYPE && (handler == DSL_LED_HD_FW)) {
1105 param.operation_mask = CONFIG_OPERATION_UPDATE_SOURCE;
1107 param.source = 0x02;
1108 // bsp_led_config (¶m);
1111 return DSL_DEV_MEI_ERR_SUCCESS;
1115 DSL_BSP_AdslLedSet (DSL_DEV_Device_t * dev, DSL_DEV_LedId_t led_number, DSL_DEV_LedMode_t mode)
1117 printk(KERN_INFO "[%s %d]: mode = %#x, led_number = %d\n", __func__, __LINE__, mode, led_number);
1120 switch (led_number) {
1121 case DSL_LED_LINK_ID:
1122 #ifdef CONFIG_BSP_LED
1123 bsp_led_set_blink (1, 0);
1124 bsp_led_set_data (1, 0);
1127 case DSL_LED_DATA_ID:
1128 #ifdef CONFIG_BSP_LED
1129 bsp_led_set_blink (0, 0);
1130 bsp_led_set_data (0, 0);
1136 switch (led_number) {
1137 case DSL_LED_LINK_ID:
1138 #ifdef CONFIG_BSP_LED
1139 bsp_led_set_blink (1, 1); // data
1142 case DSL_LED_DATA_ID:
1143 #ifdef CONFIG_BSP_LED
1144 bsp_led_set_blink (0, 1); // data
1150 switch (led_number) {
1151 case DSL_LED_LINK_ID:
1152 #ifdef CONFIG_BSP_LED
1153 bsp_led_set_blink (1, 0);
1154 bsp_led_set_data (1, 1);
1157 case DSL_LED_DATA_ID:
1158 #ifdef CONFIG_BSP_LED
1159 bsp_led_set_blink (0, 0);
1160 bsp_led_set_data (0, 1);
1166 return DSL_DEV_MEI_ERR_SUCCESS;
1172 * Compose a message.
1173 * This function compose a message from opcode, group, address, index, size, and data
1175 * \param opcode The message opcode
1176 * \param group The message group number
1177 * \param address The message address.
1178 * \param index The message index.
1179 * \param size The number of words to read/write.
1180 * \param data The pointer to data.
1181 * \param CMVMSG The pointer to message buffer.
1185 makeCMV (u8 opcode, u8 group, u16 address, u16 index, int size, u16 * data, u16 *CMVMSG)
1187 memset (CMVMSG, 0, MSG_LENGTH * 2);
1188 CMVMSG[0] = (opcode << 4) + (size & 0xf);
1189 CMVMSG[1] = (((index == 0) ? 0 : 1) << 7) + (group & 0x7f);
1190 CMVMSG[2] = address;
1192 if (opcode == H2D_CMV_WRITE)
1193 memcpy (CMVMSG + 4, data, size * 2);
1198 * Send a message to ARC and read the response
1199 * This function sends a message to arc, waits the response, and reads the responses.
1201 * \param pDev the device pointer
1202 * \param request Pointer to the request
1203 * \param reply Wait reply or not.
1204 * \param response Pointer to the response
1205 * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
1209 DSL_BSP_SendCMV (DSL_DEV_Device_t * pDev, u16 * request, int reply, u16 * response) // write cmv to arc, if reply needed, wait for reply
1211 DSL_DEV_MeiError_t meierror;
1212 #if defined(BSP_PORT_RTEMS)
1213 int delay_counter = 0;
1216 if (MEI_MUTEX_LOCK (DSL_DEV_PRIVATE(pDev)->mei_cmv_sema))
1217 return -ERESTARTSYS;
1219 DSL_DEV_PRIVATE(pDev)->cmv_reply = reply;
1220 memset (DSL_DEV_PRIVATE(pDev)->CMV_RxMsg, 0,
1221 sizeof (DSL_DEV_PRIVATE(pDev)->
1223 DSL_DEV_PRIVATE(pDev)->arcmsgav = 0;
1225 meierror = IFX_MEI_MailboxWrite (pDev, request, MSG_LENGTH);
1227 if (meierror != DSL_DEV_MEI_ERR_SUCCESS) {
1228 DSL_DEV_PRIVATE(pDev)->cmv_waiting = 0;
1229 DSL_DEV_PRIVATE(pDev)->arcmsgav = 0;
1230 IFX_MEI_EMSG ("MailboxWrite Fail!\n");
1231 IFX_MEI_EMSG ("Resetting ARC...\n");
1232 IFX_MEI_ResetARC(pDev);
1233 MEI_MUTEX_UNLOCK (DSL_DEV_PRIVATE(pDev)->mei_cmv_sema);
1237 DSL_DEV_PRIVATE(pDev)->cmv_count++;
1240 if (DSL_DEV_PRIVATE(pDev)->cmv_reply ==
1242 MEI_MUTEX_UNLOCK (DSL_DEV_PRIVATE(pDev)->mei_cmv_sema);
1243 return DSL_DEV_MEI_ERR_SUCCESS;
1246 #if !defined(BSP_PORT_RTEMS)
1247 if (DSL_DEV_PRIVATE(pDev)->arcmsgav == 0)
1248 MEI_WAIT_EVENT_TIMEOUT (DSL_DEV_PRIVATE(pDev)->wait_queue_arcmsgav, CMV_TIMEOUT);
1250 while (DSL_DEV_PRIVATE(pDev)->arcmsgav == 0 && delay_counter < CMV_TIMEOUT / 5) {
1256 DSL_DEV_PRIVATE(pDev)->cmv_waiting = 0;
1257 if (DSL_DEV_PRIVATE(pDev)->arcmsgav == 0) { //CMV_timeout
1258 DSL_DEV_PRIVATE(pDev)->arcmsgav = 0;
1259 IFX_MEI_EMSG ("\%s: DSL_DEV_MEI_ERR_MAILBOX_TIMEOUT\n",
1261 MEI_MUTEX_UNLOCK (DSL_DEV_PRIVATE(pDev)->mei_cmv_sema);
1262 return DSL_DEV_MEI_ERR_MAILBOX_TIMEOUT;
1265 DSL_DEV_PRIVATE(pDev)->arcmsgav = 0;
1266 DSL_DEV_PRIVATE(pDev)->
1268 memcpy (response, DSL_DEV_PRIVATE(pDev)->CMV_RxMsg, MSG_LENGTH * 2);
1269 MEI_MUTEX_UNLOCK (DSL_DEV_PRIVATE(pDev)->mei_cmv_sema);
1270 return DSL_DEV_MEI_ERR_SUCCESS;
1272 MEI_MUTEX_UNLOCK (DSL_DEV_PRIVATE(pDev)->mei_cmv_sema);
1273 return DSL_DEV_MEI_ERR_SUCCESS;
1277 * Reset the ARC, download boot codes, and run the ARC.
1278 * This function resets the ARC, downloads boot codes to ARC, and runs the ARC.
1280 * \param pDev the device pointer
1281 * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
1284 static DSL_DEV_MeiError_t
1285 IFX_MEI_RunAdslModem (DSL_DEV_Device_t *pDev)
1287 int nSize = 0, idx = 0;
1288 uint32_t im0_register, im2_register;
1289 // DSL_DEV_WinHost_Message_t m;
1291 if (mei_arc_swap_buff == NULL) {
1293 (u32 *) kmalloc (MAXSWAPSIZE * 4, GFP_KERNEL);
1294 if (mei_arc_swap_buff == NULL) {
1295 IFX_MEI_EMSG (">>> malloc fail for codeswap buff!!! <<<\n");
1296 return DSL_DEV_MEI_ERR_FAILURE;
1298 IFX_MEI_DMSG("allocate %dKB swap buff memory at: 0x%p\n", ksize(mei_arc_swap_buff)/1024, mei_arc_swap_buff);
1301 DSL_DEV_PRIVATE(pDev)->img_hdr =
1302 (ARC_IMG_HDR *) DSL_DEV_PRIVATE(pDev)->adsl_mem_info[0].address;
1303 if ((DSL_DEV_PRIVATE(pDev)->img_hdr->
1304 count) * sizeof (ARC_SWP_PAGE_HDR) > SDRAM_SEGMENT_SIZE) {
1305 IFX_MEI_EMSG ("firmware header size is bigger than 64K segment size\n");
1306 return DSL_DEV_MEI_ERR_FAILURE;
1309 for (idx = 0; idx < MAX_BAR_REGISTERS; idx++) {
1310 nSize += DSL_DEV_PRIVATE(pDev)->adsl_mem_info[idx].nCopy;
1313 DSL_DEV_PRIVATE(pDev)->image_size) {
1314 IFX_MEI_EMSG ("Firmware download is not completed. Please download firmware again!\n");
1315 return DSL_DEV_MEI_ERR_FAILURE;
1320 IFX_MEI_ResetARC (pDev);
1321 IFX_MEI_HaltArc (pDev);
1322 IFX_MEI_BarUpdate (pDev, DSL_DEV_PRIVATE(pDev)->nBar);
1324 //IFX_MEI_DMSG("Starting to meiDownloadBootCode\n");
1326 IFX_MEI_DownloadBootCode (pDev);
1328 im0_register = (*LTQ_ICU_IM0_IER) & (1 << 20);
1329 im2_register = (*LTQ_ICU_IM2_IER) & (1 << 20);
1331 #ifdef CONFIG_SOC_AMAZON_SE
1332 #define IFXMIPS_USB_OC_INT0 (INT_NUM_IM4_IRL0 + 23)
1333 disable_irq (IFXMIPS_USB_OC_INT0);
1334 // disable_irq (IFXMIPS_USB_OC_INT2);
1335 #elif defined(CONFIG_SOC_AR9)
1336 #define IFXMIPS_USB_OC_INT0 (INT_NUM_IM4_IRL1 + 28)
1337 disable_irq (IFXMIPS_USB_OC_INT0);
1338 // disable_irq (IFXMIPS_USB_OC_INT2);
1339 #elif defined(CONFIG_SOC_XWAY)
1340 disable_irq (LTQ_USB_OC_INT);
1344 disable_irq (pDev->nIrq[IFX_DYING_GASP]);
1346 IFX_MEI_RunArc (pDev);
1348 MEI_WAIT_EVENT_TIMEOUT (DSL_DEV_PRIVATE(pDev)->wait_queue_modemready, 1000);
1350 #ifdef CONFIG_SOC_AMAZON_SE
1351 MEI_MASK_AND_ACK_IRQ (IFXMIPS_USB_OC_INT0);
1352 // MEI_MASK_AND_ACK_IRQ (IFXMIPS_USB_OC_INT2);
1353 #elif defined(CONFIG_SOC_AR9)
1354 MEI_MASK_AND_ACK_IRQ (IFXMIPS_USB_OC_INT0);
1355 // MEI_MASK_AND_ACK_IRQ (IFXMIPS_USB_OC_INT2);
1356 #elif defined(CONFIG_SOC_XWAY)
1357 MEI_MASK_AND_ACK_IRQ (LTQ_USB_OC_INT);
1361 MEI_MASK_AND_ACK_IRQ (pDev->nIrq[IFX_DYING_GASP]);
1364 enable_irq(pDev->nIrq[IFX_DYING_GASP]);
1365 *LTQ_ICU_IM0_IER |= im0_register;
1366 *LTQ_ICU_IM2_IER |= im2_register;
1368 if (DSL_DEV_PRIVATE(pDev)->modem_ready != 1) {
1369 IFX_MEI_EMSG ("Modem failed to be ready!\n");
1370 return DSL_DEV_MEI_ERR_FAILURE;
1372 IFX_MEI_DMSG("Modem is ready.\n");
1373 return DSL_DEV_MEI_ERR_SUCCESS;
1378 * Get the page's data pointer
1379 * This function caculats the data address from the firmware header.
1381 * \param pDev the device pointer
1382 * \param Page The page number.
1383 * \param data Data page or program page.
1384 * \param MaxSize The maximum size to read.
1385 * \param Buffer Pointer to data.
1386 * \param Dest Pointer to the destination address.
1387 * \return The number of bytes to read.
1391 IFX_MEI_GetPage (DSL_DEV_Device_t * pDev, u32 Page, u32 data,
1392 u32 MaxSize, u32 * Buffer, u32 * Dest)
1397 u32 idx, offset, nBar = 0;
1399 if (Page > DSL_DEV_PRIVATE(pDev)->img_hdr->count)
1402 ** Get program or data size, depending on "data" flag
1404 size = (data == GET_DATA) ? (DSL_DEV_PRIVATE(pDev)->img_hdr->page[Page].d_size) :
1405 (DSL_DEV_PRIVATE(pDev)->img_hdr->page[Page].p_size);
1406 size &= BOOT_FLAG_MASK; // Clear boot bit!
1413 ** Get program or data offset, depending on "data" flag
1415 i = data ? (DSL_DEV_PRIVATE(pDev)->img_hdr->page[Page].d_offset) :
1416 (DSL_DEV_PRIVATE(pDev)->img_hdr->page[Page].p_offset);
1419 ** Copy data/program to buffer
1422 idx = i / SDRAM_SEGMENT_SIZE;
1423 offset = i % SDRAM_SEGMENT_SIZE;
1424 p = (u32 *) ((u8 *) DSL_DEV_PRIVATE(pDev)->adsl_mem_info[idx].address + offset);
1426 for (i = 0; i < size; i++) {
1427 if (offset + i * 4 - (nBar * SDRAM_SEGMENT_SIZE) >= SDRAM_SEGMENT_SIZE) {
1430 p = (u32 *) ((u8 *) KSEG1ADDR ((u32)DSL_DEV_PRIVATE(pDev)->adsl_mem_info[idx].address));
1436 ** Pass back data/program destination address
1438 *Dest = data ? (DSL_DEV_PRIVATE(pDev)-> img_hdr->page[Page].d_dest) :
1439 (DSL_DEV_PRIVATE(pDev)->img_hdr->page[Page].p_dest);
1445 * Free the memory for ARC firmware
1447 * \param pDev the device pointer
1448 * \param type Free all memory or free the unused memory after showtime
1451 const char *free_str[4] = {"Invalid", "Free_Reload", "Free_Showtime", "Free_All"};
1453 IFX_MEI_DFEMemoryFree (DSL_DEV_Device_t * pDev, int type)
1456 smmu_mem_info_t *adsl_mem_info =
1457 DSL_DEV_PRIVATE(pDev)->adsl_mem_info;
1459 for (idx = 0; idx < MAX_BAR_REGISTERS; idx++) {
1460 if (type == FREE_ALL ||adsl_mem_info[idx].type == type) {
1461 if (adsl_mem_info[idx].size > 0) {
1462 IFX_MEI_DMSG ("Freeing memory %p (%s)\n", adsl_mem_info[idx].org_address, free_str[adsl_mem_info[idx].type]);
1463 if ( idx == XDATA_REGISTER ) {
1464 g_xdata_addr = NULL;
1465 if ( ifx_mei_atm_showtime_exit )
1466 ifx_mei_atm_showtime_exit();
1468 kfree (adsl_mem_info[idx].org_address);
1469 adsl_mem_info[idx].org_address = 0;
1470 adsl_mem_info[idx].address = 0;
1471 adsl_mem_info[idx].size = 0;
1472 adsl_mem_info[idx].type = 0;
1473 adsl_mem_info[idx].nCopy = 0;
1478 if(mei_arc_swap_buff != NULL){
1479 IFX_MEI_DMSG("free %dKB swap buff memory at: 0x%p\n", ksize(mei_arc_swap_buff)/1024, mei_arc_swap_buff);
1480 kfree(mei_arc_swap_buff);
1481 mei_arc_swap_buff=NULL;
1487 IFX_MEI_DFEMemoryAlloc (DSL_DEV_Device_t * pDev, long size)
1489 unsigned long mem_ptr;
1490 char *org_mem_ptr = NULL;
1492 long total_size = 0;
1494 smmu_mem_info_t *adsl_mem_info =
1495 ((ifx_mei_device_private_t *) pDev->pPriv)->adsl_mem_info;
1496 // DSL_DEV_PRIVATE(pDev)->adsl_mem_info;
1497 int allocate_size = SDRAM_SEGMENT_SIZE;
1499 IFX_MEI_DMSG("image_size = %ld\n", size);
1501 for (idx = 0; size > 0 && idx < MAX_BAR_REGISTERS; idx++) {
1502 // skip bar15 for XDATA usage.
1503 if (idx == XDATA_REGISTER)
1506 if (size < SDRAM_SEGMENT_SIZE) {
1507 allocate_size = size;
1508 if (allocate_size < 1024)
1509 allocate_size = 1024;
1512 if (idx == (MAX_BAR_REGISTERS - 1))
1513 allocate_size = size;
1515 allocate_size = SDRAM_SEGMENT_SIZE;
1516 org_mem_ptr = kmalloc (allocate_size + 1024, GFP_KERNEL);
1517 if (org_mem_ptr == NULL) {
1518 IFX_MEI_EMSG ("%d: kmalloc %d bytes memory fail!\n", idx, allocate_size);
1520 goto allocate_error;
1522 mem_ptr = (unsigned long) (org_mem_ptr + 1023) & ~(1024 -1);
1523 adsl_mem_info[idx].address = (char *) mem_ptr;
1524 adsl_mem_info[idx].org_address = org_mem_ptr;
1525 adsl_mem_info[idx].size = allocate_size;
1526 size -= allocate_size;
1527 total_size += allocate_size;
1530 IFX_MEI_EMSG ("Image size is too large!\n");
1532 goto allocate_error;
1538 IFX_MEI_DFEMemoryFree (pDev, FREE_ALL);
1543 * Program the BAR registers
1545 * \param pDev the device pointer
1546 * \param nTotalBar The number of bar to program.
1550 IFX_MEI_BarUpdate (DSL_DEV_Device_t * pDev, int nTotalBar)
1553 smmu_mem_info_t *adsl_mem_info =
1554 DSL_DEV_PRIVATE(pDev)->adsl_mem_info;
1556 for (idx = 0; idx < nTotalBar; idx++) {
1557 //skip XDATA register
1558 if (idx == XDATA_REGISTER)
1560 IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_XMEM_BAR_BASE + idx * 4,
1561 (((uint32_t) adsl_mem_info[idx].address) & 0x0FFFFFFF));
1563 for (idx = nTotalBar; idx < MAX_BAR_REGISTERS; idx++) {
1564 if (idx == XDATA_REGISTER)
1566 IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_XMEM_BAR_BASE + idx * 4,
1567 (((uint32_t)adsl_mem_info[nTotalBar - 1].address) & 0x0FFFFFFF));
1568 /* These are for /proc/danube_mei/meminfo purpose */
1569 adsl_mem_info[idx].address = adsl_mem_info[nTotalBar - 1].address;
1570 adsl_mem_info[idx].org_address = adsl_mem_info[nTotalBar - 1].org_address;
1571 adsl_mem_info[idx].size = 0; /* Prevent it from being freed */
1574 g_xdata_addr = adsl_mem_info[XDATA_REGISTER].address;
1575 IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_XMEM_BAR_BASE + XDATA_REGISTER * 4,
1576 (((uint32_t) adsl_mem_info [XDATA_REGISTER].address) & 0x0FFFFFFF));
1577 // update MEI_XDATA_BASE_SH
1578 IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_XDATA_BASE_SH,
1579 ((unsigned long)adsl_mem_info[XDATA_REGISTER].address) & 0x0FFFFFFF);
1581 return DSL_DEV_MEI_ERR_SUCCESS;
1584 /* This copies the firmware from secondary storage to 64k memory segment in SDRAM */
1586 DSL_BSP_FWDownload (DSL_DEV_Device_t * pDev, const char *buf,
1587 unsigned long size, long *loff, long *current_offset)
1589 ARC_IMG_HDR img_hdr_tmp;
1590 smmu_mem_info_t *adsl_mem_info = DSL_DEV_PRIVATE(pDev)->adsl_mem_info;
1592 size_t nRead = 0, nCopy = 0;
1594 ssize_t retval = -ENOMEM;
1600 if (size < sizeof (img_hdr_tmp)) {
1601 IFX_MEI_EMSG ("Firmware size is too small!\n");
1604 copy_from_user ((char *) &img_hdr_tmp, buf, sizeof (img_hdr_tmp));
1605 // header of image_size and crc are not included.
1606 DSL_DEV_PRIVATE(pDev)->image_size = le32_to_cpu (img_hdr_tmp.size) + 8;
1608 if (DSL_DEV_PRIVATE(pDev)->image_size > 1024 * 1024) {
1609 IFX_MEI_EMSG ("Firmware size is too large!\n");
1612 // check if arc is halt
1613 IFX_MEI_ResetARC (pDev);
1614 IFX_MEI_HaltArc (pDev);
1616 IFX_MEI_DFEMemoryFree (pDev, FREE_ALL); //free all
1618 retval = IFX_MEI_DFEMemoryAlloc (pDev, DSL_DEV_PRIVATE(pDev)->image_size);
1620 IFX_MEI_EMSG ("Error: No memory space left.\n");
1623 for (idx = 0; idx < retval; idx++) {
1624 //skip XDATA register
1625 if (idx == XDATA_REGISTER)
1627 if (idx * SDRAM_SEGMENT_SIZE < le32_to_cpu (img_hdr_tmp.page[0].p_offset))
1628 adsl_mem_info[idx].type = FREE_RELOAD;
1630 adsl_mem_info[idx].type = FREE_SHOWTIME;
1632 DSL_DEV_PRIVATE(pDev)->nBar = retval;
1634 DSL_DEV_PRIVATE(pDev)->img_hdr =
1635 (ARC_IMG_HDR *) adsl_mem_info[0].address;
1637 adsl_mem_info[XDATA_REGISTER].org_address = kmalloc (SDRAM_SEGMENT_SIZE + 1024, GFP_KERNEL);
1638 adsl_mem_info[XDATA_REGISTER].address =
1639 (char *) ((unsigned long) (adsl_mem_info[XDATA_REGISTER].org_address + 1023) & 0xFFFFFC00);
1641 adsl_mem_info[XDATA_REGISTER].size = SDRAM_SEGMENT_SIZE;
1643 if (adsl_mem_info[XDATA_REGISTER].address == NULL) {
1644 IFX_MEI_EMSG ("kmalloc memory fail!\n");
1648 adsl_mem_info[XDATA_REGISTER].type = FREE_RELOAD;
1649 IFX_MEI_DMSG("-> IFX_MEI_BarUpdate()\n");
1650 IFX_MEI_BarUpdate (pDev, (DSL_DEV_PRIVATE(pDev)->nBar));
1652 else if (DSL_DEV_PRIVATE(pDev)-> image_size == 0) {
1653 IFX_MEI_EMSG ("Error: Firmware size=0! \n");
1658 while (nRead < size) {
1659 long offset = ((long) (*loff) + nRead) % SDRAM_SEGMENT_SIZE;
1660 idx = (((long) (*loff)) + nRead) / SDRAM_SEGMENT_SIZE;
1661 mem_ptr = (char *) KSEG1ADDR ((unsigned long) (adsl_mem_info[idx].address) + offset);
1662 if ((size - nRead + offset) > SDRAM_SEGMENT_SIZE)
1663 nCopy = SDRAM_SEGMENT_SIZE - offset;
1665 nCopy = size - nRead;
1666 copy_from_user (mem_ptr, buf + nRead, nCopy);
1667 for (offset = 0; offset < (nCopy / 4); offset++) {
1668 ((unsigned long *) mem_ptr)[offset] = le32_to_cpu (((unsigned long *) mem_ptr)[offset]);
1671 adsl_mem_info[idx].nCopy += nCopy;
1675 *current_offset = size;
1676 return DSL_DEV_MEI_ERR_SUCCESS;
1678 IFX_MEI_DFEMemoryFree (pDev, FREE_ALL);
1679 return DSL_DEV_MEI_ERR_FAILURE;
1682 * Register a callback event.
1684 * -1 if the event already has a callback function registered.
1687 int DSL_BSP_EventCBRegister(DSL_BSP_EventCallBack_t *p)
1690 IFX_MEI_EMSG("Invalid parameter!\n");
1693 if (p->event > DSL_BSP_CB_LAST || p->event < DSL_BSP_CB_FIRST) {
1694 IFX_MEI_EMSG("Invalid Event %d\n", p->event);
1697 if (dsl_bsp_event_callback[p->event].function) {
1698 IFX_MEI_EMSG("Event %d already has a callback function registered!\n", p->event);
1701 dsl_bsp_event_callback[p->event].function = p->function;
1702 dsl_bsp_event_callback[p->event].event = p->event;
1703 dsl_bsp_event_callback[p->event].pData = p->pData;
1707 int DSL_BSP_EventCBUnregister(DSL_BSP_EventCallBack_t *p)
1710 IFX_MEI_EMSG("Invalid parameter!\n");
1713 if (p->event > DSL_BSP_CB_LAST || p->event < DSL_BSP_CB_FIRST) {
1714 IFX_MEI_EMSG("Invalid Event %d\n", p->event);
1717 if (dsl_bsp_event_callback[p->event].function) {
1718 IFX_MEI_EMSG("Unregistering Event %d...\n", p->event);
1719 dsl_bsp_event_callback[p->event].function = NULL;
1720 dsl_bsp_event_callback[p->event].pData = NULL;
1722 IFX_MEI_EMSG("Event %d is not registered!\n", p->event);
1729 * MEI Dying Gasp interrupt handler
1733 * \param regs Pointer to the structure of danube mips registers
1736 /*static irqreturn_t IFX_MEI_Dying_Gasp_IrqHandle (int int1, void *void0)
1738 DSL_DEV_Device_t *pDev = (DSL_DEV_Device_t *) void0;
1739 DSL_BSP_CB_Type_t event;
1742 IFX_MEI_EMSG("Error: Got Interrupt but pDev is NULL!!!!\n");
1745 disable_irq (pDev->nIrq[IFX_DYING_GASP]);
1747 disable_irq_nosync(pDev->nIrq[IFX_DYING_GASP]);
1749 event = DSL_BSP_CB_DYING_GASP;
1751 if (dsl_bsp_event_callback[event].function)
1752 (*dsl_bsp_event_callback[event].function)(pDev, event, dsl_bsp_event_callback[event].pData);
1754 #ifdef CONFIG_USE_EMULATOR
1755 IFX_MEI_EMSG("Dying Gasp! Shutting Down... (Work around for Amazon-S Venus emulator)\n");
1757 IFX_MEI_EMSG("Dying Gasp! Shutting Down...\n");
1758 // kill_proc (1, SIGINT, 1);
1763 extern void ifx_usb_enable_afe_oc(void);
1766 * MEI interrupt handler
1770 * \param regs Pointer to the structure of danube mips registers
1773 static irqreturn_t IFX_MEI_IrqHandle (int int1, void *void0)
1776 DSL_DEV_Device_t *pDev = (DSL_DEV_Device_t *) void0;
1777 #if defined(CONFIG_LTQ_MEI_FW_LOOPBACK) && defined(DFE_PING_TEST)
1778 dfe_loopback_irq_handler (pDev);
1780 #endif //CONFIG_AMAZON_S_MEI_FW_LOOPBACK
1781 DSL_BSP_CB_Type_t event;
1784 IFX_MEI_EMSG("Error: Got Interrupt but pDev is NULL!!!!\n");
1786 IFX_MEI_DebugRead (pDev, ARC_MEI_MAILBOXR, &scratch, 1);
1787 if (scratch & OMB_CODESWAP_MESSAGE_MSG_TYPE_MASK) {
1788 IFX_MEI_EMSG("Receive Code Swap Request interrupt!!!\n");
1791 else if (scratch & OMB_CLEAREOC_INTERRUPT_CODE) {
1792 // clear eoc message interrupt
1793 IFX_MEI_DMSG("OMB_CLEAREOC_INTERRUPT_CODE\n");
1794 event = DSL_BSP_CB_CEOC_IRQ;
1795 IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_ARC2ME_STAT, ARC_TO_MEI_MSGAV);
1796 if (dsl_bsp_event_callback[event].function)
1797 (*dsl_bsp_event_callback[event].function)(pDev, event, dsl_bsp_event_callback[event].pData);
1798 } else if (scratch & OMB_REBOOT_INTERRUPT_CODE) {
1800 IFX_MEI_DMSG("OMB_REBOOT_INTERRUPT_CODE\n");
1801 event = DSL_BSP_CB_FIRMWARE_REBOOT;
1803 IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_ARC2ME_STAT, ARC_TO_MEI_MSGAV);
1805 if (dsl_bsp_event_callback[event].function)
1806 (*dsl_bsp_event_callback[event].function)(pDev, event, dsl_bsp_event_callback[event].pData);
1807 } else { // normal message
1808 IFX_MEI_MailboxRead (pDev, DSL_DEV_PRIVATE(pDev)->CMV_RxMsg, MSG_LENGTH);
1809 if (DSL_DEV_PRIVATE(pDev)-> cmv_waiting == 1) {
1810 DSL_DEV_PRIVATE(pDev)-> arcmsgav = 1;
1811 DSL_DEV_PRIVATE(pDev)-> cmv_waiting = 0;
1812 #if !defined(BSP_PORT_RTEMS)
1813 MEI_WAKEUP_EVENT (DSL_DEV_PRIVATE(pDev)->wait_queue_arcmsgav);
1817 DSL_DEV_PRIVATE(pDev)-> modem_ready_cnt++;
1818 memcpy ((char *) DSL_DEV_PRIVATE(pDev)->Recent_indicator,
1819 (char *) DSL_DEV_PRIVATE(pDev)->CMV_RxMsg, MSG_LENGTH * 2);
1820 if (((DSL_DEV_PRIVATE(pDev)->CMV_RxMsg[0] & 0xff0) >> 4) == D2H_AUTONOMOUS_MODEM_READY_MSG) {
1821 //check ARC ready message
1822 IFX_MEI_DMSG ("Got MODEM_READY_MSG\n");
1823 DSL_DEV_PRIVATE(pDev)->modem_ready = 1;
1824 MEI_WAKEUP_EVENT (DSL_DEV_PRIVATE(pDev)->wait_queue_modemready);
1833 DSL_BSP_ATMLedCBRegister (int (*ifx_adsl_ledcallback) (void))
1835 g_adsl_ledcallback = ifx_adsl_ledcallback;
1840 DSL_BSP_ATMLedCBUnregister (int (*ifx_adsl_ledcallback) (void))
1842 g_adsl_ledcallback = adsl_dummy_ledcallback;
1848 DSL_BSP_EventCBRegister (int (*ifx_adsl_callback)
1849 (DSL_BSP_CB_Event_t * param))
1853 if (DSL_EventCB == NULL) {
1854 DSL_EventCB = ifx_adsl_callback;
1863 DSL_BSP_EventCBUnregister (int (*ifx_adsl_callback)
1864 (DSL_BSP_CB_Event_t * param))
1868 if (DSL_EventCB == ifx_adsl_callback) {
1878 DSL_BSP_GetEventCB (int (**ifx_adsl_callback)
1879 (DSL_BSP_CB_Event_t * param))
1881 *ifx_adsl_callback = DSL_EventCB;
1886 #ifdef CONFIG_LTQ_MEI_FW_LOOPBACK
1887 #define mte_reg_base (0x4800*4+0x20000)
1889 /* Iridia Registers Address Constants */
1890 #define MTE_Reg(r) (int)(mte_reg_base + (r*4))
1892 #define IT_AMODE MTE_Reg(0x0004)
1894 #define TIMER_DELAY (1024)
1895 #define BC0_BYTES (32)
1896 #define BC1_BYTES (30)
1898 #define TIMEOUT_VALUE 2000
1904 for (i = 0; i < cycle; i++);
1908 WriteRegLong (u32 addr, u32 data)
1910 //*((volatile u32 *)(addr)) = data;
1911 IFX_MEI_WRITE_REGISTER_L (data, addr);
1915 ReadRegLong (u32 addr)
1918 //rd_val = *((volatile u32 *)(addr));
1920 return IFX_MEI_READ_REGISTER_L (addr);
1923 /* This routine writes the mailbox with the data in an input array */
1925 WriteMbox (u32 * mboxarray, u32 size)
1927 IFX_MEI_DebugWrite (&dsl_devices[0], IMBOX_BASE, mboxarray, size);
1928 IFX_MEI_DMSG("write to %X\n", IMBOX_BASE);
1929 IFX_MEI_LongWordWriteOffset (&dsl_devices[0], (u32) ME_ME2ARC_INT, MEI_TO_ARC_MSGAV);
1932 /* This routine reads the output mailbox and places the results into an array */
1934 ReadMbox (u32 * mboxarray, u32 size)
1936 IFX_MEI_DebugRead (&dsl_devices[0], OMBOX_BASE, mboxarray, size);
1937 IFX_MEI_DMSG("read from %X\n", OMBOX_BASE);
1941 MEIWriteARCValue (u32 address, u32 value)
1945 /* Write address register */
1946 IFX_MEI_WRITE_REGISTER_L (address, ME_DBG_WR_AD + LTQ_MEI_BASE_ADDR);
1948 /* Write data register */
1949 IFX_MEI_WRITE_REGISTER_L (value, ME_DBG_DATA + LTQ_MEI_BASE_ADDR);
1951 /* wait until complete - timeout at 40 */
1952 for (i = 0; i < 40; i++) {
1953 check = IFX_MEI_READ_REGISTER_L (ME_ARC2ME_STAT + LTQ_MEI_BASE_ADDR);
1955 if ((check & ARC_TO_MEI_DBG_DONE))
1958 /* clear the flag */
1959 IFX_MEI_WRITE_REGISTER_L (ARC_TO_MEI_DBG_DONE, ME_ARC2ME_STAT + LTQ_MEI_BASE_ADDR);
1963 arc_code_page_download (uint32_t arc_code_length, uint32_t * start_address)
1967 IFX_MEI_DMSG("try to download pages,size=%d\n", arc_code_length);
1968 IFX_MEI_ControlModeSet (&dsl_devices[0], MEI_MASTER_MODE);
1969 IFX_MEI_HaltArc (&dsl_devices[0]);
1970 IFX_MEI_LongWordWriteOffset (&dsl_devices[0], (u32) ME_DX_AD, 0);
1971 for (count = 0; count < arc_code_length; count++) {
1972 IFX_MEI_LongWordWriteOffset (&dsl_devices[0], (u32) ME_DX_DATA,
1973 *(start_address + count));
1975 IFX_MEI_ControlModeSet (&dsl_devices[0], JTAG_MASTER_MODE);
1978 load_jump_table (unsigned long addr)
1981 uint32_t addr_le, addr_be;
1982 uint32_t jump_table[32];
1984 for (i = 0; i < 16; i++) {
1985 addr_le = i * 8 + addr;
1986 addr_be = ((addr_le >> 16) & 0xffff);
1987 addr_be |= ((addr_le & 0xffff) << 16);
1988 jump_table[i * 2 + 0] = 0x0f802020;
1989 jump_table[i * 2 + 1] = addr_be;
1990 //printk("jt %X %08X %08X\n",i,jump_table[i*2+0],jump_table[i*2+1]);
1992 arc_code_page_download (32, &jump_table[0]);
1999 dfe_loopback_irq_handler (DSL_DEV_Device_t *pDev)
2001 uint32_t rd_mbox[10];
2003 memset (&rd_mbox[0], 0, 10 * 4);
2004 ReadMbox (&rd_mbox[0], 6);
2005 if (rd_mbox[0] == 0x0) {
2006 FX_MEI_DMSG("Get ARC_ACK\n");
2009 else if (rd_mbox[0] == 0x5) {
2010 IFX_MEI_DMSG("Get ARC_BUSY\n");
2013 else if (rd_mbox[0] == 0x3) {
2014 IFX_MEI_DMSG("Get ARC_EDONE\n");
2015 if (rd_mbox[1] == 0x0) {
2017 IFX_MEI_DMSG("Get E_MEMTEST\n");
2018 if (rd_mbox[2] != 0x1) {
2020 IFX_MEI_DMSG("Get Result %X\n", rd_mbox[2]);
2024 IFX_MEI_LongWordWriteOffset (&dsl_devices[0], (u32) ME_ARC2ME_STAT,
2025 ARC_TO_MEI_DBG_DONE);
2026 MEI_MASK_AND_ACK_IRQ (pDev->nIrq[IFX_DFEIR]);
2027 disable_irq (pDev->nIrq[IFX_DFEIR]);
2033 wait_mem_test_result (void)
2038 IFX_MEI_DMSG("Waiting Starting\n");
2039 while (mbox[0] == 0) {
2040 ReadMbox (&mbox[0], 5);
2042 IFX_MEI_DMSG("Try to get mem test result.\n");
2043 ReadMbox (&mbox[0], 5);
2044 if (mbox[0] == 0xA) {
2045 IFX_MEI_DMSG("Success.\n");
2047 else if (mbox[0] == 0xA) {
2048 IFX_MEI_EMSG("Fail,address %X,except data %X,receive data %X\n",
2049 mbox[1], mbox[2], mbox[3]);
2052 IFX_MEI_EMSG("Fail\n");
2057 arc_ping_testing (DSL_DEV_Device_t *pDev)
2059 #define MEI_PING 0x00000001
2060 uint32_t wr_mbox[10], rd_mbox[10];
2063 for (i = 0; i < 10; i++) {
2068 FX_MEI_DMSG("send ping msg\n");
2069 wr_mbox[0] = MEI_PING;
2070 WriteMbox (&wr_mbox[0], 10);
2072 while (got_int == 0) {
2076 IFX_MEI_DMSG("send start event\n");
2082 wr_mbox[3] = (uint32_t) 0xf5acc307e;
2085 wr_mbox[6] = 0x1c000;
2089 WriteMbox (&wr_mbox[0], 10);
2090 DSL_ENABLE_IRQ (pDev->nIrq[IFX_DFEIR]);
2091 //printk("IFX_MEI_MailboxWrite ret=%d\n",i);
2092 IFX_MEI_LongWordWriteOffset (&dsl_devices[0],
2093 (u32) ME_ME2ARC_INT,
2095 IFX_MEI_DMSG("sleeping\n");
2100 IFX_MEI_DMSG("got_int >>>> 3\n");
2102 IFX_MEI_DMSG("got int = %d\n", got_int);
2105 DSL_ENABLE_IRQ (pDev->nIrq[IFX_DFEIR]);
2107 //mbox_read(&rd_mbox[0],6);
2113 static DSL_DEV_MeiError_t
2114 DFE_Loopback_Test (void)
2117 u32 arc_debug_data = 0, temp;
2118 DSL_DEV_Device_t *pDev = &dsl_devices[0];
2119 uint32_t wr_mbox[10];
2121 IFX_MEI_ResetARC (pDev);
2123 arc_debug_data = ACL_CLK_MODE_ENABLE;
2124 IFX_MEI_DebugWrite (pDev, CRI_CCR0, &arc_debug_data, 1);
2126 #if defined( DFE_PING_TEST )|| defined( DFE_ATM_LOOPBACK)
2127 // WriteARCreg(AUX_XMEM_LTEST,0);
2128 IFX_MEI_ControlModeSet (pDev, MEI_MASTER_MODE);
2129 #define AUX_XMEM_LTEST 0x128
2130 _IFX_MEI_DBGLongWordWrite (pDev, MEI_DEBUG_DEC_AUX_MASK, AUX_XMEM_LTEST, 0);
2131 IFX_MEI_ControlModeSet (pDev, JTAG_MASTER_MODE);
2133 // WriteARCreg(AUX_XDMA_GAP,0);
2134 IFX_MEI_ControlModeSet (pDev, MEI_MASTER_MODE);
2135 #define AUX_XDMA_GAP 0x114
2136 _IFX_MEI_DBGLongWordWrite (pDev, MEI_DEBUG_DEC_AUX_MASK, AUX_XDMA_GAP, 0);
2137 IFX_MEI_ControlModeSet (pDev, JTAG_MASTER_MODE);
2139 IFX_MEI_ControlModeSet (pDev, MEI_MASTER_MODE);
2141 _IFX_MEI_DBGLongWordWrite (pDev, MEI_DEBUG_DEC_AUX_MASK,
2142 (u32) ME_XDATA_BASE_SH + LTQ_MEI_BASE_ADDR, temp);
2143 IFX_MEI_ControlModeSet (pDev, JTAG_MASTER_MODE);
2145 i = IFX_MEI_DFEMemoryAlloc (pDev, SDRAM_SEGMENT_SIZE * 16);
2149 for (idx = 0; idx < i; idx++) {
2150 DSL_DEV_PRIVATE(pDev)->adsl_mem_info[idx].type = FREE_RELOAD;
2151 IFX_MEI_WRITE_REGISTER_L ((((uint32_t) DSL_DEV_PRIVATE(pDev)->adsl_mem_info[idx].address) & 0x0fffffff),
2152 LTQ_MEI_BASE_ADDR + ME_XMEM_BAR_BASE + idx * 4);
2153 IFX_MEI_DMSG("bar%d(%X)=%X\n", idx,
2154 LTQ_MEI_BASE_ADDR + ME_XMEM_BAR_BASE +
2155 idx * 4, (((uint32_t)
2156 ((ifx_mei_device_private_t *)
2157 pDev->pPriv)->adsl_mem_info[idx].
2158 address) & 0x0fffffff));
2159 memset ((u8 *) DSL_DEV_PRIVATE(pDev)->adsl_mem_info[idx].address, 0, SDRAM_SEGMENT_SIZE);
2162 IFX_MEI_LongWordWriteOffset (pDev, (u32) ME_XDATA_BASE_SH,
2163 ((unsigned long) DSL_DEV_PRIVATE(pDev)->adsl_mem_info[XDATA_REGISTER].address) & 0x0FFFFFFF);
2166 IFX_MEI_EMSG ("cannot load image: no memory\n");
2167 return DSL_DEV_MEI_ERR_FAILURE;
2169 //WriteARCreg(AUX_IC_CTRL,2);
2170 IFX_MEI_DMSG("Setting MEI_MASTER_MODE..\n");
2171 IFX_MEI_ControlModeSet (pDev, MEI_MASTER_MODE);
2172 #define AUX_IC_CTRL 0x11
2173 _IFX_MEI_DBGLongWordWrite (pDev, MEI_DEBUG_DEC_AUX_MASK,
2175 IFX_MEI_DMSG("Setting JTAG_MASTER_MODE..\n");
2176 IFX_MEI_ControlModeSet (pDev, JTAG_MASTER_MODE);
2178 IFX_MEI_DMSG("Halting ARC...\n");
2179 IFX_MEI_HaltArc (&dsl_devices[0]);
2181 #ifdef DFE_PING_TEST
2183 IFX_MEI_DMSG("ping test image size=%d\n", sizeof (arc_ahb_access_code));
2184 memcpy ((u8 *) (DSL_DEV_PRIVATE(pDev)->
2185 adsl_mem_info[0].address + 0x1004),
2186 &arc_ahb_access_code[0], sizeof (arc_ahb_access_code));
2187 load_jump_table (0x80000 + 0x1004);
2189 #endif //DFE_PING_TEST
2191 IFX_MEI_DMSG("ARC ping test code download complete\n");
2192 #endif //defined( DFE_PING_TEST )|| defined( DFE_ATM_LOOPBACK)
2194 IFX_MEI_LongWordWriteOffset (&dsl_devices[0], (u32) ME_ARC2ME_MASK, MSGAV_EN);
2196 arc_code_page_download (1537, &code_array[0]);
2197 IFX_MEI_DMSG("ARC mem test code download complete\n");
2198 #endif //DFE_MEM_TEST
2199 #ifdef DFE_ATM_LOOPBACK
2200 arc_debug_data = 0xf;
2201 arc_code_page_download (sizeof(code_array) / sizeof(*code_array), &code_array[0]);
2202 wr_mbox[0] = 0; //TIMER_DELAY - org: 1024
2203 wr_mbox[1] = 0; //TXFB_START0
2204 wr_mbox[2] = 0x7f; //TXFB_END0 - org: 49
2205 wr_mbox[3] = 0x80; //TXFB_START1 - org: 80
2206 wr_mbox[4] = 0xff; //TXFB_END1 - org: 109
2207 wr_mbox[5] = 0x100; //RXFB_START0 - org: 0
2208 wr_mbox[6] = 0x17f; //RXFB_END0 - org: 49
2209 wr_mbox[7] = 0x180; //RXFB_START1 - org: 256
2210 wr_mbox[8] = 0x1ff; //RXFB_END1 - org: 315
2211 WriteMbox (&wr_mbox[0], 9);
2212 // Start Iridia IT_AMODE (in dmp access) why is it required?
2213 IFX_MEI_DebugWrite (&dsl_devices[0], 0x32010, &arc_debug_data, 1);
2214 #endif //DFE_ATM_LOOPBACK
2215 IFX_MEI_IRQEnable (pDev);
2216 IFX_MEI_DMSG("run ARC...\n");
2217 IFX_MEI_RunArc (&dsl_devices[0]);
2219 #ifdef DFE_PING_TEST
2220 arc_ping_testing (pDev);
2221 #endif //DFE_PING_TEST
2223 wait_mem_test_result ();
2224 #endif //DFE_MEM_TEST
2226 IFX_MEI_DFEMemoryFree (pDev, FREE_ALL);
2227 return DSL_DEV_MEI_ERR_SUCCESS;
2230 #endif //CONFIG_AMAZON_S_MEI_FW_LOOPBACK
2233 IFX_MEI_InitDevNode (int num)
2236 if ((dev_major = register_chrdev (dev_major, IFX_MEI_DEVNAME, &bsp_mei_operations)) < 0) {
2237 IFX_MEI_EMSG ("register_chrdev(%d %s) failed!\n", dev_major, IFX_MEI_DEVNAME);
2245 IFX_MEI_CleanUpDevNode (int num)
2248 unregister_chrdev (dev_major, MEI_DIRNAME);
2253 IFX_MEI_InitDevice (int num)
2255 DSL_DEV_Device_t *pDev;
2257 pDev = &dsl_devices[num];
2260 pDev->pPriv = &sDanube_Mei_Private[num];
2261 memset (pDev->pPriv, 0, sizeof (ifx_mei_device_private_t));
2263 memset (&DSL_DEV_PRIVATE(pDev)->
2264 adsl_mem_info[0], 0,
2265 sizeof (smmu_mem_info_t) * MAX_BAR_REGISTERS);
2268 pDev->nIrq[IFX_DFEIR] = LTQ_MEI_INT;
2269 pDev->nIrq[IFX_DYING_GASP] = LTQ_MEI_DYING_GASP_INT;
2270 pDev->base_address = KSEG1 + LTQ_MEI_BASE_ADDR;
2273 #ifdef CONFIG_LANTIQ_AMAZON_SE
2274 *LTQ_PMU_PWDCR &= ~(1 << 9); // enable dsl
2275 *LTQ_PMU_PWDCR &= ~(1 << 15); // enable AHB base
2277 temp = ltq_r32(LTQ_PMU_PWDCR);
2279 ltq_w32(temp, LTQ_PMU_PWDCR);
2283 DSL_DEV_PRIVATE(pDev)->modem_ready = 0;
2284 DSL_DEV_PRIVATE(pDev)->arcmsgav = 0;
2286 MEI_INIT_WAKELIST ("arcq", DSL_DEV_PRIVATE(pDev)->wait_queue_arcmsgav); // for ARCMSGAV
2287 MEI_INIT_WAKELIST ("arcr", DSL_DEV_PRIVATE(pDev)->wait_queue_modemready); // for arc modem ready
2289 MEI_MUTEX_INIT (DSL_DEV_PRIVATE(pDev)->mei_cmv_sema, 1); // semaphore initialization, mutex
2291 MEI_MASK_AND_ACK_IRQ (pDev->nIrq[IFX_DFEIR]);
2292 MEI_MASK_AND_ACK_IRQ (pDev->nIrq[IFX_DYING_GASP]);
2294 if (request_irq (pDev->nIrq[IFX_DFEIR], IFX_MEI_IrqHandle, 0, "DFEIR", pDev) != 0) {
2295 IFX_MEI_EMSG ("request_irq %d failed!\n", pDev->nIrq[IFX_DFEIR]);
2298 /*if (request_irq (pDev->nIrq[IFX_DYING_GASP], IFX_MEI_Dying_Gasp_IrqHandle, 0, "DYING_GASP", pDev) != 0) {
2299 IFX_MEI_EMSG ("request_irq %d failed!\n", pDev->nIrq[IFX_DYING_GASP]);
2302 // IFX_MEI_DMSG("Device %d initialized. IER %#x\n", num, bsp_get_irq_ier(pDev->nIrq[IFX_DYING_GASP]));
2307 IFX_MEI_ExitDevice (int num)
2309 DSL_DEV_Device_t *pDev;
2310 pDev = &dsl_devices[num];
2315 disable_irq (pDev->nIrq[IFX_DFEIR]);
2316 disable_irq (pDev->nIrq[IFX_DYING_GASP]);
2318 free_irq(pDev->nIrq[IFX_DFEIR], pDev);
2319 free_irq(pDev->nIrq[IFX_DYING_GASP], pDev);
2324 static DSL_DEV_Device_t *
2325 IFX_BSP_HandleGet (int maj, int num)
2327 if (num > BSP_MAX_DEVICES)
2329 return &dsl_devices[num];
2333 DSL_BSP_DriverHandleGet (int maj, int num)
2335 DSL_DEV_Device_t *pDev;
2337 if (num > BSP_MAX_DEVICES)
2340 pDev = &dsl_devices[num];
2341 if (!try_module_get(pDev->owner))
2349 DSL_BSP_DriverHandleDelete (DSL_DEV_Device_t * nHandle)
2351 DSL_DEV_Device_t *pDev = (DSL_DEV_Device_t *) nHandle;
2354 module_put(pDev->owner);
2359 IFX_MEI_Open (DSL_DRV_inode_t * ino, DSL_DRV_file_t * fil)
2361 int maj = MAJOR (ino->i_rdev);
2362 int num = MINOR (ino->i_rdev);
2364 DSL_DEV_Device_t *pDev = NULL;
2365 if ((pDev = DSL_BSP_DriverHandleGet (maj, num)) == NULL) {
2366 IFX_MEI_EMSG("open(%d:%d) fail!\n", maj, num);
2369 fil->private_data = pDev;
2374 IFX_MEI_Release (DSL_DRV_inode_t * ino, DSL_DRV_file_t * fil)
2376 //int maj = MAJOR(ino->i_rdev);
2377 int num = MINOR (ino->i_rdev);
2378 DSL_DEV_Device_t *pDev;
2380 pDev = &dsl_devices[num];
2383 DSL_BSP_DriverHandleDelete (pDev);
2388 * Callback function for linux userspace program writing
2391 IFX_MEI_Write (DSL_DRV_file_t * filp, const char *buf, size_t size, loff_t * loff)
2393 DSL_DEV_MeiError_t mei_error = DSL_DEV_MEI_ERR_FAILURE;
2395 DSL_DEV_Device_t *pDev = (DSL_DEV_Device_t *) filp->private_data;
2401 DSL_BSP_FWDownload (pDev, buf, size, (long *) loff, &offset);
2403 if (mei_error == DSL_DEV_MEI_ERR_FAILURE)
2405 return (ssize_t) offset;
2409 * Callback function for linux userspace program ioctling
2412 IFX_MEI_IoctlCopyFrom (int from_kernel, char *dest, char *from, int size)
2417 ret = copy_from_user ((char *) dest, (char *) from, size);
2419 ret = (int)memcpy ((char *) dest, (char *) from, size);
2424 IFX_MEI_IoctlCopyTo (int from_kernel, char *dest, char *from, int size)
2429 ret = copy_to_user ((char *) dest, (char *) from, size);
2431 ret = (int)memcpy ((char *) dest, (char *) from, size);
2436 IFX_MEI_Ioctls (DSL_DEV_Device_t * pDev, int from_kernel, unsigned int command, unsigned long lon)
2439 int meierr = DSL_DEV_MEI_ERR_SUCCESS;
2440 u32 base_address = LTQ_MEI_BASE_ADDR;
2441 DSL_DEV_WinHost_Message_t winhost_msg, m;
2442 // DSL_DEV_MeiDebug_t debugrdwr;
2443 DSL_DEV_MeiReg_t regrdwr;
2447 case DSL_FIO_BSP_CMV_WINHOST:
2448 IFX_MEI_IoctlCopyFrom (from_kernel, (char *) winhost_msg.msg.TxMessage,
2449 (char *) lon, MSG_LENGTH * 2);
2451 if ((meierr = DSL_BSP_SendCMV (pDev, winhost_msg.msg.TxMessage, YES_REPLY,
2452 winhost_msg.msg.RxMessage)) != DSL_DEV_MEI_ERR_SUCCESS) {
2453 IFX_MEI_EMSG ("WINHOST CMV fail :TxMessage:%X %X %X %X, RxMessage:%X %X %X %X %X\n",
2454 winhost_msg.msg.TxMessage[0], winhost_msg.msg.TxMessage[1], winhost_msg.msg.TxMessage[2], winhost_msg.msg.TxMessage[3],
2455 winhost_msg.msg.RxMessage[0], winhost_msg.msg.RxMessage[1], winhost_msg.msg.RxMessage[2], winhost_msg.msg.RxMessage[3],
2456 winhost_msg.msg.RxMessage[4]);
2457 meierr = DSL_DEV_MEI_ERR_FAILURE;
2460 IFX_MEI_IoctlCopyTo (from_kernel, (char *) lon,
2461 (char *) winhost_msg.msg.RxMessage,
2466 case DSL_FIO_BSP_CMV_READ:
2467 IFX_MEI_IoctlCopyFrom (from_kernel, (char *) (®rdwr),
2468 (char *) lon, sizeof (DSL_DEV_MeiReg_t));
2470 IFX_MEI_LongWordRead ((u32) regrdwr.iAddress,
2471 (u32 *) & (regrdwr.iData));
2473 IFX_MEI_IoctlCopyTo (from_kernel, (char *) lon,
2474 (char *) (®rdwr),
2475 sizeof (DSL_DEV_MeiReg_t));
2479 case DSL_FIO_BSP_CMV_WRITE:
2480 IFX_MEI_IoctlCopyFrom (from_kernel, (char *) (®rdwr),
2481 (char *) lon, sizeof (DSL_DEV_MeiReg_t));
2483 IFX_MEI_LongWordWrite ((u32) regrdwr.iAddress,
2487 case DSL_FIO_BSP_GET_BASE_ADDRESS:
2488 IFX_MEI_IoctlCopyTo (from_kernel, (char *) lon,
2489 (char *) (&base_address),
2490 sizeof (base_address));
2493 case DSL_FIO_BSP_IS_MODEM_READY:
2494 i = IFX_MEI_IsModemReady (pDev);
2495 IFX_MEI_IoctlCopyTo (from_kernel, (char *) lon,
2496 (char *) (&i), sizeof (int));
2497 meierr = DSL_DEV_MEI_ERR_SUCCESS;
2499 case DSL_FIO_BSP_RESET:
2500 case DSL_FIO_BSP_REBOOT:
2501 meierr = IFX_MEI_CpuModeSet (pDev, DSL_CPU_RESET);
2502 meierr = IFX_MEI_CpuModeSet (pDev, DSL_CPU_HALT);
2505 case DSL_FIO_BSP_HALT:
2506 meierr = IFX_MEI_CpuModeSet (pDev, DSL_CPU_HALT);
2509 case DSL_FIO_BSP_RUN:
2510 meierr = IFX_MEI_CpuModeSet (pDev, DSL_CPU_RUN);
2512 case DSL_FIO_BSP_BOOTDOWNLOAD:
2513 meierr = IFX_MEI_DownloadBootCode (pDev);
2515 case DSL_FIO_BSP_JTAG_ENABLE:
2516 meierr = IFX_MEI_ArcJtagEnable (pDev, 1);
2519 case DSL_FIO_BSP_REMOTE:
2520 IFX_MEI_IoctlCopyFrom (from_kernel, (char *) (&i),
2521 (char *) lon, sizeof (int));
2523 meierr = IFX_MEI_AdslMailboxIRQEnable (pDev, i);
2526 case DSL_FIO_BSP_DSL_START:
2527 IFX_MEI_DMSG("DSL_FIO_BSP_DSL_START\n");
2528 if ((meierr = IFX_MEI_RunAdslModem (pDev)) != DSL_DEV_MEI_ERR_SUCCESS) {
2529 IFX_MEI_EMSG ("IFX_MEI_RunAdslModem() error...");
2530 meierr = DSL_DEV_MEI_ERR_FAILURE;
2534 /* case DSL_FIO_BSP_DEBUG_READ:
2535 case DSL_FIO_BSP_DEBUG_WRITE:
2536 IFX_MEI_IoctlCopyFrom (from_kernel,
2537 (char *) (&debugrdwr),
2539 sizeof (debugrdwr));
2541 if (command == DSL_FIO_BSP_DEBUG_READ)
2542 meierr = DSL_BSP_MemoryDebugAccess (pDev,
2543 DSL_BSP_MEMORY_READ,
2551 meierr = DSL_BSP_MemoryDebugAccess (pDev,
2552 DSL_BSP_MEMORY_WRITE,
2560 IFX_MEI_IoctlCopyTo (from_kernel, (char *) lon, (char *) (&debugrdwr), sizeof (debugrdwr));
2562 case DSL_FIO_BSP_GET_VERSION:
2563 IFX_MEI_IoctlCopyTo (from_kernel, (char *) lon, (char *) (&bsp_mei_version), sizeof (DSL_DEV_Version_t));
2566 #define LTQ_MPS_CHIPID_VERSION_GET(value) (((value) >> 28) & ((1 << 4) - 1))
2567 case DSL_FIO_BSP_GET_CHIP_INFO:
2568 bsp_chip_info.major = 1;
2569 bsp_chip_info.minor = LTQ_MPS_CHIPID_VERSION_GET(*LTQ_MPS_CHIPID);
2570 IFX_MEI_IoctlCopyTo (from_kernel, (char *) lon, (char *) (&bsp_chip_info), sizeof (DSL_DEV_HwVersion_t));
2571 meierr = DSL_DEV_MEI_ERR_SUCCESS;
2574 case DSL_FIO_BSP_FREE_RESOURCE:
2575 makeCMV (H2D_CMV_READ, DSL_CMV_GROUP_STAT, 4, 0, 1, NULL, m.msg.TxMessage);
2576 if (DSL_BSP_SendCMV (pDev, m.msg.TxMessage, YES_REPLY, m.msg.RxMessage) != DSL_DEV_MEI_ERR_SUCCESS) {
2577 meierr = DSL_DEV_MEI_ERR_FAILURE;
2580 IFX_MEI_DMSG("RxMessage[4] = %#x\n", m.msg.RxMessage[4]);
2581 if (!(m.msg.RxMessage[4] & DSL_DEV_STAT_CODESWAP_COMPLETE)) {
2582 meierr = DSL_DEV_MEI_ERR_FAILURE;
2585 IFX_MEI_DMSG("Freeing all memories marked FREE_SHOWTIME\n");
2586 IFX_MEI_DFEMemoryFree (pDev, FREE_SHOWTIME);
2587 meierr = DSL_DEV_MEI_ERR_SUCCESS;
2589 #ifdef CONFIG_IFXMIPS_AMAZON_SE
2590 case DSL_FIO_ARC_MUX_TEST:
2591 AMAZON_SE_MEI_ARC_MUX_Test();
2595 // IFX_MEI_EMSG("Invalid IOCTL command: %d\n");
2601 #ifdef CONFIG_IFXMIPS_AMAZON_SE
2602 void AMAZON_SE_MEI_ARC_MUX_Test(void)
2605 *LTQ_RCU_RST |= LTQ_RCU_RST_REQ_MUX_ARC;
2607 p = (u32*)(DFE_LDST_BASE_ADDR + IRAM0_BASE);
2608 IFX_MEI_EMSG("Writing to IRAM0(%p)...\n", p);
2609 for (i = 0; i < IRAM0_SIZE/sizeof(u32); i++, p++) {
2611 if (*p != 0xdeadbeef)
2612 IFX_MEI_EMSG("%p: %#x\n", p, *p);
2615 p = (u32*)(DFE_LDST_BASE_ADDR + IRAM1_BASE);
2616 IFX_MEI_EMSG("Writing to IRAM1(%p)...\n", p);
2617 for (i = 0; i < IRAM1_SIZE/sizeof(u32); i++, p++) {
2619 if (*p != 0xdeadbeef)
2620 IFX_MEI_EMSG("%p: %#x\n", p, *p);
2623 p = (u32*)(DFE_LDST_BASE_ADDR + BRAM_BASE);
2624 IFX_MEI_EMSG("Writing to BRAM(%p)...\n", p);
2625 for (i = 0; i < BRAM_SIZE/sizeof(u32); i++, p++) {
2627 if (*p != 0xdeadbeef)
2628 IFX_MEI_EMSG("%p: %#x\n", p, *p);
2631 p = (u32*)(DFE_LDST_BASE_ADDR + XRAM_BASE);
2632 IFX_MEI_EMSG("Writing to XRAM(%p)...\n", p);
2633 for (i = 0; i < XRAM_SIZE/sizeof(u32); i++, p++) {
2635 if (*p != 0xdeadbeef)
2636 IFX_MEI_EMSG("%p: %#x\n", p, *p);
2639 p = (u32*)(DFE_LDST_BASE_ADDR + YRAM_BASE);
2640 IFX_MEI_EMSG("Writing to YRAM(%p)...\n", p);
2641 for (i = 0; i < YRAM_SIZE/sizeof(u32); i++, p++) {
2643 if (*p != 0xdeadbeef)
2644 IFX_MEI_EMSG("%p: %#x\n", p, *p);
2647 p = (u32*)(DFE_LDST_BASE_ADDR + EXT_MEM_BASE);
2648 IFX_MEI_EMSG("Writing to EXT_MEM(%p)...\n", p);
2649 for (i = 0; i < EXT_MEM_SIZE/sizeof(u32); i++, p++) {
2651 if (*p != 0xdeadbeef)
2652 IFX_MEI_EMSG("%p: %#x\n", p, *p);
2654 *LTQ_RCU_RST &= ~LTQ_RCU_RST_REQ_MUX_ARC;
2658 DSL_BSP_KernelIoctls (DSL_DEV_Device_t * pDev, unsigned int command,
2663 error = IFX_MEI_Ioctls (pDev, 1, command, lon);
2668 IFX_MEI_UserIoctls (DSL_DRV_file_t * fil,
2669 unsigned int command, unsigned long lon)
2672 DSL_DEV_Device_t *pDev;
2674 pDev = IFX_BSP_HandleGet (0, 0);
2678 error = IFX_MEI_Ioctls (pDev, 0, command, lon);
2682 static int adsl_dummy_ledcallback(void)
2687 int ifx_mei_atm_led_blink(void)
2689 return g_adsl_ledcallback();
2691 EXPORT_SYMBOL(ifx_mei_atm_led_blink);
2693 int ifx_mei_atm_showtime_check(int *is_showtime, struct port_cell_info *port_cell, void **xdata_addr)
2697 if ( is_showtime ) {
2698 *is_showtime = g_tx_link_rate[0] == 0 && g_tx_link_rate[1] == 0 ? 0 : 1;
2702 for ( i = 0; i < port_cell->port_num && i < 2; i++ )
2703 port_cell->tx_link_rate[i] = g_tx_link_rate[i];
2707 if ( g_tx_link_rate[0] == 0 && g_tx_link_rate[1] == 0 )
2710 *xdata_addr = g_xdata_addr;
2715 EXPORT_SYMBOL(ifx_mei_atm_showtime_check);
2718 * Writing function for linux proc filesystem
2720 static int ltq_mei_probe(struct platform_device *pdev)
2723 static struct class *dsl_class;
2725 pr_info("IFX MEI Version %ld.%02ld.%02ld\n", bsp_mei_version.major, bsp_mei_version.minor, bsp_mei_version.revision);
2727 for (i = 0; i < BSP_MAX_DEVICES; i++) {
2728 if (IFX_MEI_InitDevice (i) != 0) {
2729 IFX_MEI_EMSG("Init device fail!\n");
2732 IFX_MEI_InitDevNode (i);
2734 for (i = 0; i <= DSL_BSP_CB_LAST ; i++)
2735 dsl_bsp_event_callback[i].function = NULL;
2737 #ifdef CONFIG_LTQ_MEI_FW_LOOPBACK
2738 IFX_MEI_DMSG("Start loopback test...\n");
2739 DFE_Loopback_Test ();
2741 dsl_class = class_create(THIS_MODULE, "ifx_mei");
2742 device_create(dsl_class, NULL, MKDEV(MEI_MAJOR, 0), NULL, "ifx_mei");
2746 static int ltq_mei_remove(struct platform_device *pdev)
2751 for (num = 0; num < BSP_MAX_DEVICES; num++) {
2752 IFX_MEI_CleanUpDevNode (num);
2755 for (i = 0; i < BSP_MAX_DEVICES; i++) {
2756 for (i = 0; i < BSP_MAX_DEVICES; i++) {
2757 IFX_MEI_ExitDevice (i);
2763 static const struct of_device_id ltq_mei_match[] = {
2764 { .compatible = "lantiq,mei-xway"},
2768 static struct platform_driver ltq_mei_driver = {
2769 .probe = ltq_mei_probe,
2770 .remove = ltq_mei_remove,
2772 .name = "lantiq,mei-xway",
2773 .owner = THIS_MODULE,
2774 .of_match_table = ltq_mei_match,
2778 module_platform_driver(ltq_mei_driver);
2780 /* export function for DSL Driver */
2782 /* The functions of MEI_DriverHandleGet and MEI_DriverHandleDelete are
2783 something like open/close in kernel space , where the open could be used
2784 to register a callback for autonomous messages and returns a mei driver context pointer (comparable to the file descriptor in user space)
2785 The context will be required for the multi line chips future! */
2787 EXPORT_SYMBOL (DSL_BSP_DriverHandleGet);
2788 EXPORT_SYMBOL (DSL_BSP_DriverHandleDelete);
2790 EXPORT_SYMBOL (DSL_BSP_ATMLedCBRegister);
2791 EXPORT_SYMBOL (DSL_BSP_ATMLedCBUnregister);
2792 EXPORT_SYMBOL (DSL_BSP_KernelIoctls);
2793 EXPORT_SYMBOL (DSL_BSP_AdslLedInit);
2794 //EXPORT_SYMBOL (DSL_BSP_AdslLedSet);
2795 EXPORT_SYMBOL (DSL_BSP_FWDownload);
2796 EXPORT_SYMBOL (DSL_BSP_Showtime);
2798 EXPORT_SYMBOL (DSL_BSP_MemoryDebugAccess);
2799 EXPORT_SYMBOL (DSL_BSP_SendCMV);
2801 // provide a register/unregister function for DSL driver to register a event callback function
2802 EXPORT_SYMBOL (DSL_BSP_EventCBRegister);
2803 EXPORT_SYMBOL (DSL_BSP_EventCBUnregister);
2805 MODULE_LICENSE("Dual BSD/GPL");