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/mod_devicetable.h>
32 #include <linux/version.h>
33 #include <generated/utsrelease.h>
34 #include <linux/types.h>
37 #include <linux/errno.h>
38 #include <linux/interrupt.h>
39 #include <linux/netdevice.h>
40 #include <linux/etherdevice.h>
41 #include <linux/proc_fs.h>
42 #include <linux/init.h>
43 #include <linux/ioport.h>
44 #include <linux/delay.h>
45 #include <linux/device.h>
46 #include <linux/sched.h>
47 #include <linux/platform_device.h>
48 #include <asm/uaccess.h>
49 #include <asm/hardirq.h>
51 #include "lantiq_atm.h"
52 #include <lantiq_soc.h>
53 //#include "ifxmips_atm.h"
55 #include "ifxmips_mei_interface.h"
57 /*#define LTQ_RCU_RST IFX_RCU_RST_REQ
58 #define LTQ_RCU_RST_REQ_ARC_JTAG IFX_RCU_RST_REQ_ARC_JTAG
59 #define LTQ_RCU_RST_REQ_DFE IFX_RCU_RST_REQ_DFE
60 #define LTQ_RCU_RST_REQ_AFE IFX_RCU_RST_REQ_AFE
61 #define IFXMIPS_FUSE_BASE_ADDR IFX_FUSE_BASE_ADDR
62 #define IFXMIPS_ICU_IM0_IER IFX_ICU_IM0_IER
63 #define IFXMIPS_ICU_IM2_IER IFX_ICU_IM2_IER
64 #define LTQ_MEI_INT IFX_MEI_INT
65 #define LTQ_MEI_DYING_GASP_INT IFX_MEI_DYING_GASP_INT
66 #define LTQ_MEI_BASE_ADDR IFX_MEI_SPACE_ACCESS
67 #define IFXMIPS_PMU_PWDCR IFX_PMU_PWDCR
68 #define IFXMIPS_MPS_CHIPID IFX_MPS_CHIPID
70 #define ifxmips_port_reserve_pin ifx_gpio_pin_reserve
71 #define ifxmips_port_set_dir_in ifx_gpio_dir_in_set
72 #define ifxmips_port_clear_altsel0 ifx_gpio_altsel0_set
73 #define ifxmips_port_clear_altsel1 ifx_gpio_altsel1_clear
74 #define ifxmips_port_set_open_drain ifx_gpio_open_drain_clear
75 #define ifxmips_port_free_pin ifx_gpio_pin_free
76 #define ifxmips_mask_and_ack_irq bsp_mask_and_ack_irq
77 #define IFXMIPS_MPS_CHIPID_VERSION_GET IFX_MCD_CHIPID_VERSION_GET
78 #define ltq_r32(reg) __raw_readl(reg)
79 #define ltq_w32(val, reg) __raw_writel(val, reg)
80 #define ltq_w32_mask(clear, set, reg) ltq_w32((ltq_r32(reg) & ~clear) | set, reg)
83 #define LTQ_RCU_BASE_ADDR 0x1F203000
84 #define LTQ_ICU_BASE_ADDR 0x1F880200
85 #define LTQ_MEI_BASE_ADDR 0x1E116000
86 #define LTQ_PMU_BASE_ADDR 0x1F102000
90 # define LTQ_MEI_INT (INT_NUM_IM1_IRL0 + 23)
91 # define LTQ_MEI_DYING_GASP_INT (INT_NUM_IM1_IRL0 + 21)
92 # define LTQ_USB_OC_INT (INT_NUM_IM4_IRL0 + 23)
95 #ifdef CONFIG_AMAZON_SE
96 # define LTQ_MEI_INT (INT_NUM_IM2_IRL0 + 9)
97 # define LTQ_MEI_DYING_GASP_INT (INT_NUM_IM2_IRL0 + 11)
98 # define LTQ_USB_OC_INT (INT_NUM_IM2_IRL0 + 20)
102 # define LTQ_MEI_INT (INT_NUM_IM1_IRL0 + 23)
103 # define LTQ_MEI_DYING_GASP_INT (INT_NUM_IM1_IRL0 + 21)
104 # define LTQ_USB_OC_INT (INT_NUM_IM1_IRL0 + 28)
108 #error "Unknown Lantiq ARCH!"
111 #define LTQ_RCU_RST_REQ_DFE (1 << 7)
112 #define LTQ_RCU_RST_REQ_AFE (1 << 11)
114 #define LTQ_PMU_BASE (KSEG1 + LTQ_PMU_BASE_ADDR)
115 #define LTQ_RCU_BASE (KSEG1 + LTQ_RCU_BASE_ADDR)
116 #define LTQ_ICU_BASE (KSEG1 + LTQ_ICU_BASE_ADDR)
118 #define LTQ_PMU_PWDCR ((u32 *)(LTQ_PMU_BASE + 0x001C))
119 #define LTQ_PMU_PWDSR ((u32 *)(LTQ_PMU_BASE + 0x0020))
120 #define LTQ_RCU_RST ((u32 *)(LTQ_RCU_BASE + 0x0010))
121 #define LTQ_RCU_RST_ALL 0x40000000
123 #define LTQ_ICU_IM0_ISR ((u32 *)(LTQ_ICU_BASE + 0x0000))
124 #define LTQ_ICU_IM0_IER ((u32 *)(LTQ_ICU_BASE + 0x0008))
125 #define LTQ_ICU_IM0_IOSR ((u32 *)(LTQ_ICU_BASE + 0x0010))
126 #define LTQ_ICU_IM0_IRSR ((u32 *)(LTQ_ICU_BASE + 0x0018))
127 #define LTQ_ICU_IM0_IMR ((u32 *)(LTQ_ICU_BASE + 0x0020))
130 #define LTQ_ICU_IM1_ISR ((u32 *)(LTQ_ICU_BASE + 0x0028))
131 #define LTQ_ICU_IM2_ISR ((u32 *)(LTQ_ICU_BASE + 0x0050))
132 #define LTQ_ICU_IM3_ISR ((u32 *)(LTQ_ICU_BASE + 0x0078))
133 #define LTQ_ICU_IM4_ISR ((u32 *)(LTQ_ICU_BASE + 0x00A0))
135 #define LTQ_ICU_OFFSET (LTQ_ICU_IM1_ISR - LTQ_ICU_IM0_ISR)
136 #define LTQ_ICU_IM2_IER (LTQ_ICU_IM0_IER + LTQ_ICU_OFFSET)
138 #define IFX_MEI_EMSG(fmt, args...) pr_err("[%s %d]: " fmt,__FUNCTION__, __LINE__, ## args)
139 #define IFX_MEI_DMSG(fmt, args...) pr_debug("[%s %d]: " fmt,__FUNCTION__, __LINE__, ## args)
141 #define LTQ_FUSE_BASE (KSEG1 + 0x1F107354)
143 #ifdef CONFIG_LTQ_MEI_FW_LOOPBACK
144 //#define DFE_MEM_TEST
145 //#define DFE_PING_TEST
146 #define DFE_ATM_LOOPBACK
149 #ifdef DFE_ATM_LOOPBACK
150 #include <asm/ifxmips/ifxmips_mei_fw_loopback.h>
153 void dfe_loopback_irq_handler (DSL_DEV_Device_t
*pDev
);
155 #endif //CONFIG_AMAZON_S_MEI_FW_LOOPBACK
157 DSL_DEV_Version_t bsp_mei_version
= {
162 DSL_DEV_HwVersion_t bsp_chip_info
;
164 #define IFX_MEI_DEVNAME "ifx_mei"
165 #define BSP_MAX_DEVICES 1
166 #define MEI_DIRNAME "ifxmips_mei"
168 DSL_DEV_MeiError_t
DSL_BSP_FWDownload (DSL_DEV_Device_t
*, const char *, unsigned long, long *, long *);
169 DSL_DEV_MeiError_t
DSL_BSP_Showtime (DSL_DEV_Device_t
*, DSL_uint32_t
, DSL_uint32_t
);
170 DSL_DEV_MeiError_t
DSL_BSP_AdslLedInit (DSL_DEV_Device_t
*, DSL_DEV_LedId_t
, DSL_DEV_LedType_t
, DSL_DEV_LedHandler_t
);
171 //DSL_DEV_MeiError_t DSL_BSP_AdslLedSet (DSL_DEV_Device_t *, DSL_DEV_LedId_t, DSL_DEV_LedMode_t);
172 DSL_DEV_MeiError_t
DSL_BSP_MemoryDebugAccess (DSL_DEV_Device_t
*, DSL_BSP_MemoryAccessType_t
, DSL_uint32_t
, DSL_uint32_t
*, DSL_uint32_t
);
173 DSL_DEV_MeiError_t
DSL_BSP_SendCMV (DSL_DEV_Device_t
*, u16
*, int, u16
*);
175 int DSL_BSP_KernelIoctls (DSL_DEV_Device_t
*, unsigned int, unsigned long);
177 static DSL_DEV_MeiError_t
IFX_MEI_RunAdslModem (DSL_DEV_Device_t
*);
178 static DSL_DEV_MeiError_t
IFX_MEI_CpuModeSet (DSL_DEV_Device_t
*, DSL_DEV_CpuMode_t
);
179 static DSL_DEV_MeiError_t
IFX_MEI_DownloadBootCode (DSL_DEV_Device_t
*);
180 static DSL_DEV_MeiError_t
IFX_MEI_ArcJtagEnable (DSL_DEV_Device_t
*, int);
181 static DSL_DEV_MeiError_t
IFX_MEI_AdslMailboxIRQEnable (DSL_DEV_Device_t
*, int);
183 static int IFX_MEI_GetPage (DSL_DEV_Device_t
*, u32
, u32
, u32
, u32
*, u32
*);
184 static int IFX_MEI_BarUpdate (DSL_DEV_Device_t
*, int);
186 static ssize_t
IFX_MEI_Write (DSL_DRV_file_t
*, const char *, size_t, loff_t
*);
187 static long IFX_MEI_UserIoctls (DSL_DRV_file_t
*, unsigned int, unsigned long);
188 static int IFX_MEI_Open (DSL_DRV_inode_t
*, DSL_DRV_file_t
*);
189 static int IFX_MEI_Release (DSL_DRV_inode_t
*, DSL_DRV_file_t
*);
191 void AMAZON_SE_MEI_ARC_MUX_Test(void);
193 void IFX_MEI_ARC_MUX_Test(void);
195 static int adsl_dummy_ledcallback(void);
197 int (*ifx_mei_atm_showtime_enter
)(struct port_cell_info
*, void *) = NULL
;
198 EXPORT_SYMBOL(ifx_mei_atm_showtime_enter
);
200 int (*ifx_mei_atm_showtime_exit
)(void) = NULL
;
201 EXPORT_SYMBOL(ifx_mei_atm_showtime_exit
);
203 static int (*g_adsl_ledcallback
)(void) = adsl_dummy_ledcallback
;
205 static unsigned int g_tx_link_rate
[2] = {0};
207 static void *g_xdata_addr
= NULL
;
209 static u32
*mei_arc_swap_buff
= NULL
; // holding swap pages
211 extern void ltq_mask_and_ack_irq(struct irq_data
*d
);
212 static void inline MEI_MASK_AND_ACK_IRQ(int x
)
216 ltq_mask_and_ack_irq(&d
);
218 #define MEI_MAJOR 105
219 static int dev_major
= MEI_MAJOR
;
221 static struct file_operations bsp_mei_operations
= {
224 release
:IFX_MEI_Release
,
226 unlocked_ioctl
:IFX_MEI_UserIoctls
,
229 static DSL_DEV_Device_t dsl_devices
[BSP_MAX_DEVICES
];
231 static ifx_mei_device_private_t
232 sDanube_Mei_Private
[BSP_MAX_DEVICES
];
234 static DSL_BSP_EventCallBack_t dsl_bsp_event_callback
[DSL_BSP_CB_LAST
+ 1];
237 * Write a value to register
238 * This function writes a value to danube register
240 * \param ul_address The address to write
241 * \param ul_data The value to write
245 IFX_MEI_LongWordWrite (u32 ul_address
, u32 ul_data
)
247 IFX_MEI_WRITE_REGISTER_L (ul_data
, ul_address
);
253 * Write a value to register
254 * This function writes a value to danube register
256 * \param pDev the device pointer
257 * \param ul_address The address to write
258 * \param ul_data The value to write
262 IFX_MEI_LongWordWriteOffset (DSL_DEV_Device_t
* pDev
, u32 ul_address
,
265 IFX_MEI_WRITE_REGISTER_L (ul_data
, pDev
->base_address
+ ul_address
);
271 * Read the danube register
272 * This function read the value from danube register
274 * \param ul_address The address to write
275 * \param pul_data Pointer to the data
279 IFX_MEI_LongWordRead (u32 ul_address
, u32
* pul_data
)
281 *pul_data
= IFX_MEI_READ_REGISTER_L (ul_address
);
287 * Read the danube register
288 * This function read the value from danube register
290 * \param pDev the device pointer
291 * \param ul_address The address to write
292 * \param pul_data Pointer to the data
296 IFX_MEI_LongWordReadOffset (DSL_DEV_Device_t
* pDev
, u32 ul_address
,
299 *pul_data
= IFX_MEI_READ_REGISTER_L (pDev
->base_address
+ ul_address
);
305 * Write several DWORD datas to ARC memory via ARC DMA interface
306 * This function writes several DWORD datas to ARC memory via DMA interface.
308 * \param pDev the device pointer
309 * \param destaddr The address to write
310 * \param databuff Pointer to the data buffer
311 * \param databuffsize Number of DWORDs to write
312 * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
315 static DSL_DEV_MeiError_t
316 IFX_MEI_DMAWrite (DSL_DEV_Device_t
* pDev
, u32 destaddr
,
317 u32
* databuff
, u32 databuffsize
)
323 return DSL_DEV_MEI_ERR_FAILURE
;
325 // Set the write transfer address
326 IFX_MEI_LongWordWriteOffset (pDev
, ME_DX_AD
, destaddr
);
328 // Write the data pushed across DMA
329 while (databuffsize
--) {
331 if (destaddr
== MEI_TO_ARC_MAILBOX
)
332 MEI_HALF_WORD_SWAP (temp
);
333 IFX_MEI_LongWordWriteOffset (pDev
, (u32
) ME_DX_DATA
, temp
);
337 return DSL_DEV_MEI_ERR_SUCCESS
;
342 * Read several DWORD datas from ARC memory via ARC DMA interface
343 * This function reads several DWORD datas from ARC memory via DMA interface.
345 * \param pDev the device pointer
346 * \param srcaddr The address to read
347 * \param databuff Pointer to the data buffer
348 * \param databuffsize Number of DWORDs to read
349 * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
352 static DSL_DEV_MeiError_t
353 IFX_MEI_DMARead (DSL_DEV_Device_t
* pDev
, u32 srcaddr
, u32
* databuff
,
360 return DSL_DEV_MEI_ERR_FAILURE
;
362 // Set the read transfer address
363 IFX_MEI_LongWordWriteOffset (pDev
, (u32
) ME_DX_AD
, srcaddr
);
365 // Read the data popped across DMA
366 while (databuffsize
--) {
367 IFX_MEI_LongWordReadOffset (pDev
, (u32
) ME_DX_DATA
, &temp
);
368 if (databuff
== (u32
*) DSL_DEV_PRIVATE(pDev
)->CMV_RxMsg
) // swap half word
369 MEI_HALF_WORD_SWAP (temp
);
374 return DSL_DEV_MEI_ERR_SUCCESS
;
379 * Switch the ARC control mode
380 * This function switchs the ARC control mode to JTAG mode or MEI mode
382 * \param pDev the device pointer
383 * \param mode The mode want to switch: JTAG_MASTER_MODE or MEI_MASTER_MODE.
387 IFX_MEI_ControlModeSet (DSL_DEV_Device_t
* pDev
, int mode
)
391 IFX_MEI_LongWordReadOffset (pDev
, (u32
) ME_DBG_MASTER
, &temp
);
393 case JTAG_MASTER_MODE
:
394 temp
&= ~(HOST_MSTR
);
396 case MEI_MASTER_MODE
:
400 IFX_MEI_EMSG ("IFX_MEI_ControlModeSet: unkonwn mode [%d]\n", mode
);
403 IFX_MEI_LongWordWriteOffset (pDev
, (u32
) ME_DBG_MASTER
, temp
);
407 * Disable ARC to MEI interrupt
409 * \param pDev the device pointer
413 IFX_MEI_IRQDisable (DSL_DEV_Device_t
* pDev
)
415 IFX_MEI_LongWordWriteOffset (pDev
, (u32
) ME_ARC2ME_MASK
, 0x0);
419 * Eable ARC to MEI interrupt
421 * \param pDev the device pointer
425 IFX_MEI_IRQEnable (DSL_DEV_Device_t
* pDev
)
427 IFX_MEI_LongWordWriteOffset (pDev
, (u32
) ME_ARC2ME_MASK
, MSGAV_EN
);
431 * Poll for transaction complete signal
432 * This function polls and waits for transaction complete signal.
434 * \param pDev the device pointer
438 meiPollForDbgDone (DSL_DEV_Device_t
* pDev
)
443 while (i
< WHILE_DELAY
) {
444 IFX_MEI_LongWordReadOffset (pDev
, (u32
) ME_ARC2ME_STAT
, &query
);
445 query
&= (ARC_TO_MEI_DBG_DONE
);
449 if (i
== WHILE_DELAY
) {
450 IFX_MEI_EMSG ("PollforDbg fail!\n");
453 IFX_MEI_LongWordWriteOffset (pDev
, (u32
) ME_ARC2ME_STAT
, ARC_TO_MEI_DBG_DONE
); // to clear this interrupt
457 * ARC Debug Memory Access for a single DWORD reading.
458 * This function used for direct, address-based access to ARC memory.
460 * \param pDev the device pointer
461 * \param DEC_mode ARC memory space to used
462 * \param address Address to read
463 * \param data Pointer to data
464 * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
467 static DSL_DEV_MeiError_t
468 _IFX_MEI_DBGLongWordRead (DSL_DEV_Device_t
* pDev
, u32 DEC_mode
,
469 u32 address
, u32
* data
)
471 IFX_MEI_LongWordWriteOffset (pDev
, (u32
) ME_DBG_DECODE
, DEC_mode
);
472 IFX_MEI_LongWordWriteOffset (pDev
, (u32
) ME_DBG_RD_AD
, address
);
473 meiPollForDbgDone (pDev
);
474 IFX_MEI_LongWordReadOffset (pDev
, (u32
) ME_DBG_DATA
, data
);
475 return DSL_DEV_MEI_ERR_SUCCESS
;
479 * ARC Debug Memory Access for a single DWORD writing.
480 * This function used for direct, address-based access to ARC memory.
482 * \param pDev the device pointer
483 * \param DEC_mode ARC memory space to used
484 * \param address The address to write
485 * \param data The data to write
486 * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
489 static DSL_DEV_MeiError_t
490 _IFX_MEI_DBGLongWordWrite (DSL_DEV_Device_t
* pDev
, u32 DEC_mode
,
491 u32 address
, u32 data
)
493 IFX_MEI_LongWordWriteOffset (pDev
, (u32
) ME_DBG_DECODE
, DEC_mode
);
494 IFX_MEI_LongWordWriteOffset (pDev
, (u32
) ME_DBG_WR_AD
, address
);
495 IFX_MEI_LongWordWriteOffset (pDev
, (u32
) ME_DBG_DATA
, data
);
496 meiPollForDbgDone (pDev
);
497 return DSL_DEV_MEI_ERR_SUCCESS
;
501 * ARC Debug Memory Access for writing.
502 * This function used for direct, address-based access to ARC memory.
504 * \param pDev the device pointer
505 * \param destaddr The address to read
506 * \param databuffer Pointer to data
507 * \param databuffsize The number of DWORDs to read
508 * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
512 static DSL_DEV_MeiError_t
513 IFX_MEI_DebugWrite (DSL_DEV_Device_t
* pDev
, u32 destaddr
,
514 u32
* databuff
, u32 databuffsize
)
521 // Open the debug port before DMP memory write
522 IFX_MEI_ControlModeSet (pDev
, MEI_MASTER_MODE
);
524 // For the requested length, write the address and write the data
527 for (i
= 0; i
< databuffsize
; i
++) {
529 _IFX_MEI_DBGLongWordWrite (pDev
, ME_DBG_DECODE_DMP1_MASK
, address
, temp
);
534 // Close the debug port after DMP memory write
535 IFX_MEI_ControlModeSet (pDev
, JTAG_MASTER_MODE
);
537 return DSL_DEV_MEI_ERR_SUCCESS
;
541 * ARC Debug Memory Access for reading.
542 * This function used for direct, address-based access to ARC memory.
544 * \param pDev the device pointer
545 * \param srcaddr The address to read
546 * \param databuffer Pointer to data
547 * \param databuffsize The number of DWORDs to read
548 * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
551 static DSL_DEV_MeiError_t
552 IFX_MEI_DebugRead (DSL_DEV_Device_t
* pDev
, u32 srcaddr
, u32
* databuff
, u32 databuffsize
)
559 // Open the debug port before DMP memory read
560 IFX_MEI_ControlModeSet (pDev
, MEI_MASTER_MODE
);
562 // For the requested length, write the address and read the data
565 for (i
= 0; i
< databuffsize
; i
++) {
566 _IFX_MEI_DBGLongWordRead (pDev
, ME_DBG_DECODE_DMP1_MASK
, address
, &temp
);
572 // Close the debug port after DMP memory read
573 IFX_MEI_ControlModeSet (pDev
, JTAG_MASTER_MODE
);
575 return DSL_DEV_MEI_ERR_SUCCESS
;
579 * Send a message to ARC MailBox.
580 * This function sends a message to ARC Mailbox via ARC DMA interface.
582 * \param pDev the device pointer
583 * \param msgsrcbuffer Pointer to message.
584 * \param msgsize The number of words to write.
585 * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
588 static DSL_DEV_MeiError_t
589 IFX_MEI_MailboxWrite (DSL_DEV_Device_t
* pDev
, u16
* msgsrcbuffer
,
593 u32 arc_mailbox_status
= 0x0;
595 DSL_DEV_MeiError_t meiMailboxError
= DSL_DEV_MEI_ERR_SUCCESS
;
599 IFX_MEI_DMAWrite (pDev
, MEI_TO_ARC_MAILBOX
, (u32
*) msgsrcbuffer
, msgsize
/ 2);
601 IFX_MEI_DMAWrite (pDev
, MEI_TO_ARC_MAILBOXR
, (u32
*) (&temp
), 1);
603 // Notify arc that mailbox write completed
604 DSL_DEV_PRIVATE(pDev
)->cmv_waiting
= 1;
605 IFX_MEI_LongWordWriteOffset (pDev
, (u32
) ME_ME2ARC_INT
, MEI_TO_ARC_MSGAV
);
608 while (i
< WHILE_DELAY
) { // wait for ARC to clear the bit
609 IFX_MEI_LongWordReadOffset (pDev
, (u32
) ME_ME2ARC_INT
, &arc_mailbox_status
);
610 if ((arc_mailbox_status
& MEI_TO_ARC_MSGAV
) != MEI_TO_ARC_MSGAV
)
613 if (i
== WHILE_DELAY
) {
614 IFX_MEI_EMSG (">>> Timeout waiting for ARC to clear MEI_TO_ARC_MSGAV!!!"
615 " MEI_TO_ARC message size = %d DWORDs <<<\n", msgsize
/2);
616 meiMailboxError
= DSL_DEV_MEI_ERR_FAILURE
;
620 return meiMailboxError
;
624 * Read a message from ARC MailBox.
625 * This function reads a message from ARC Mailbox via ARC DMA interface.
627 * \param pDev the device pointer
628 * \param msgsrcbuffer Pointer to message.
629 * \param msgsize The number of words to read
630 * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
633 static DSL_DEV_MeiError_t
634 IFX_MEI_MailboxRead (DSL_DEV_Device_t
* pDev
, u16
* msgdestbuffer
,
637 DSL_DEV_MeiError_t meiMailboxError
= DSL_DEV_MEI_ERR_SUCCESS
;
640 IFX_MEI_DMARead (pDev
, ARC_TO_MEI_MAILBOX
, (u32
*) msgdestbuffer
, msgsize
/ 2);
642 // Notify arc that mailbox read completed
643 IFX_MEI_LongWordWriteOffset (pDev
, (u32
) ME_ARC2ME_STAT
, ARC_TO_MEI_MSGAV
);
645 return meiMailboxError
;
649 * Download boot pages to ARC.
650 * This function downloads boot pages to ARC.
652 * \param pDev the device pointer
653 * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
656 static DSL_DEV_MeiError_t
657 IFX_MEI_DownloadBootPages (DSL_DEV_Device_t
* pDev
)
664 ** DMA the boot code page(s)
669 (DSL_DEV_PRIVATE(pDev
)->img_hdr
-> count
); boot_loop
++) {
670 if ((DSL_DEV_PRIVATE(pDev
)-> img_hdr
->page
[boot_loop
].p_size
) & BOOT_FLAG
) {
671 page_size
= IFX_MEI_GetPage (pDev
, boot_loop
,
672 GET_PROG
, MAXSWAPSIZE
,
676 IFX_MEI_DMAWrite (pDev
, dest_addr
,
681 if ((DSL_DEV_PRIVATE(pDev
)-> img_hdr
->page
[boot_loop
].d_size
) & BOOT_FLAG
) {
682 page_size
= IFX_MEI_GetPage (pDev
, boot_loop
,
683 GET_DATA
, MAXSWAPSIZE
,
687 IFX_MEI_DMAWrite (pDev
, dest_addr
,
693 return DSL_DEV_MEI_ERR_SUCCESS
;
700 IFX_MEI_FuseInit (DSL_DEV_Device_t
* pDev
)
703 IFX_MEI_DMAWrite (pDev
, IRAM0_BASE
, &data
, 1);
704 IFX_MEI_DMAWrite (pDev
, IRAM0_BASE
+ 4, &data
, 1);
705 IFX_MEI_DMAWrite (pDev
, IRAM1_BASE
, &data
, 1);
706 IFX_MEI_DMAWrite (pDev
, IRAM1_BASE
+ 4, &data
, 1);
707 IFX_MEI_DMAWrite (pDev
, BRAM_BASE
, &data
, 1);
708 IFX_MEI_DMAWrite (pDev
, BRAM_BASE
+ 4, &data
, 1);
709 IFX_MEI_DMAWrite (pDev
, ADSL_DILV_BASE
, &data
, 1);
710 IFX_MEI_DMAWrite (pDev
, ADSL_DILV_BASE
+ 4, &data
, 1);
717 IFX_MEI_FuseProg (DSL_DEV_Device_t
* pDev
)
719 u32 reg_data
, fuse_value
;
722 IFX_MEI_LongWordRead ((u32
) LTQ_RCU_RST
, ®_data
);
723 while ((reg_data
& 0x10000000) == 0) {
724 IFX_MEI_LongWordRead ((u32
) LTQ_RCU_RST
, ®_data
);
726 /* 0x4000 translate to about 16 ms@111M, so should be enough */
730 // STEP a: Prepare memory for external accesses
731 // Write fuse_en bit24
732 IFX_MEI_LongWordRead ((u32
) LTQ_RCU_RST
, ®_data
);
733 IFX_MEI_LongWordWrite ((u32
) LTQ_RCU_RST
, reg_data
| (1 << 24));
735 IFX_MEI_FuseInit (pDev
);
736 for (i
= 0; i
< 4; i
++) {
737 IFX_MEI_LongWordRead ((u32
) (LTQ_FUSE_BASE
) + i
* 4, &fuse_value
);
738 switch (fuse_value
& 0xF0000) {
740 reg_data
= ((fuse_value
& RX_DILV_ADDR_BIT_MASK
) |
741 (RX_DILV_ADDR_BIT_MASK
+ 0x1));
742 IFX_MEI_DMAWrite (pDev
, ADSL_DILV_BASE
, ®_data
, 1);
745 reg_data
= ((fuse_value
& RX_DILV_ADDR_BIT_MASK
) |
746 (RX_DILV_ADDR_BIT_MASK
+ 0x1));
747 IFX_MEI_DMAWrite (pDev
, ADSL_DILV_BASE
+ 4, ®_data
, 1);
750 reg_data
= ((fuse_value
& IRAM0_ADDR_BIT_MASK
) |
751 (IRAM0_ADDR_BIT_MASK
+ 0x1));
752 IFX_MEI_DMAWrite (pDev
, IRAM0_BASE
, ®_data
, 1);
755 reg_data
= ((fuse_value
& IRAM0_ADDR_BIT_MASK
) |
756 (IRAM0_ADDR_BIT_MASK
+ 0x1));
757 IFX_MEI_DMAWrite (pDev
, IRAM0_BASE
+ 4, ®_data
, 1);
760 reg_data
= ((fuse_value
& IRAM1_ADDR_BIT_MASK
) |
761 (IRAM1_ADDR_BIT_MASK
+ 0x1));
762 IFX_MEI_DMAWrite (pDev
, IRAM1_BASE
, ®_data
, 1);
765 reg_data
= ((fuse_value
& IRAM1_ADDR_BIT_MASK
) |
766 (IRAM1_ADDR_BIT_MASK
+ 0x1));
767 IFX_MEI_DMAWrite (pDev
, IRAM1_BASE
+ 4, ®_data
, 1);
770 reg_data
= ((fuse_value
& BRAM_ADDR_BIT_MASK
) |
771 (BRAM_ADDR_BIT_MASK
+ 0x1));
772 IFX_MEI_DMAWrite (pDev
, BRAM_BASE
, ®_data
, 1);
775 reg_data
= ((fuse_value
& BRAM_ADDR_BIT_MASK
) |
776 (BRAM_ADDR_BIT_MASK
+ 0x1));
777 IFX_MEI_DMAWrite (pDev
, BRAM_BASE
+ 4, ®_data
, 1);
779 default: // PPE efuse
783 IFX_MEI_LongWordRead ((u32
) LTQ_RCU_RST
, ®_data
);
784 IFX_MEI_LongWordWrite ((u32
) LTQ_RCU_RST
, reg_data
& ~(1 << 24));
785 IFX_MEI_LongWordRead ((u32
) LTQ_RCU_RST
, ®_data
);
790 * This function enables DFE Clock
792 * \param pDev the device pointer
793 * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
796 static DSL_DEV_MeiError_t
797 IFX_MEI_EnableCLK (DSL_DEV_Device_t
* pDev
)
799 u32 arc_debug_data
= 0;
800 IFX_MEI_ControlModeSet (pDev
, MEI_MASTER_MODE
);
801 //enable ac_clk signal
802 _IFX_MEI_DBGLongWordRead (pDev
, ME_DBG_DECODE_DMP1_MASK
,
803 CRI_CCR0
, &arc_debug_data
);
804 arc_debug_data
|= ACL_CLK_MODE_ENABLE
;
805 _IFX_MEI_DBGLongWordWrite (pDev
, ME_DBG_DECODE_DMP1_MASK
,
806 CRI_CCR0
, arc_debug_data
);
807 IFX_MEI_ControlModeSet (pDev
, JTAG_MASTER_MODE
);
808 return DSL_DEV_MEI_ERR_SUCCESS
;
813 * This function halts the ARC.
815 * \param pDev the device pointer
816 * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
819 static DSL_DEV_MeiError_t
820 IFX_MEI_HaltArc (DSL_DEV_Device_t
* pDev
)
822 u32 arc_debug_data
= 0x0;
824 // Switch arc control from JTAG mode to MEI mode
825 IFX_MEI_ControlModeSet (pDev
, MEI_MASTER_MODE
);
826 _IFX_MEI_DBGLongWordRead (pDev
, MEI_DEBUG_DEC_AUX_MASK
,
827 ARC_DEBUG
, &arc_debug_data
);
828 arc_debug_data
|= ARC_DEBUG_HALT
;
829 _IFX_MEI_DBGLongWordWrite (pDev
, MEI_DEBUG_DEC_AUX_MASK
,
830 ARC_DEBUG
, arc_debug_data
);
831 // Switch arc control from MEI mode to JTAG mode
832 IFX_MEI_ControlModeSet (pDev
, JTAG_MASTER_MODE
);
836 return DSL_DEV_MEI_ERR_SUCCESS
;
841 * This function runs the ARC.
843 * \param pDev the device pointer
844 * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
847 static DSL_DEV_MeiError_t
848 IFX_MEI_RunArc (DSL_DEV_Device_t
* pDev
)
850 u32 arc_debug_data
= 0x0;
852 // Switch arc control from JTAG mode to MEI mode- write '1' to bit0
853 IFX_MEI_ControlModeSet (pDev
, MEI_MASTER_MODE
);
854 _IFX_MEI_DBGLongWordRead (pDev
, MEI_DEBUG_DEC_AUX_MASK
,
855 AUX_STATUS
, &arc_debug_data
);
857 // Write debug data reg with content ANDd with 0xFDFFFFFF (halt bit cleared)
858 arc_debug_data
&= ~ARC_AUX_HALT
;
859 _IFX_MEI_DBGLongWordWrite (pDev
, MEI_DEBUG_DEC_AUX_MASK
,
860 AUX_STATUS
, arc_debug_data
);
862 // Switch arc control from MEI mode to JTAG mode- write '0' to bit0
863 IFX_MEI_ControlModeSet (pDev
, JTAG_MASTER_MODE
);
864 // Enable mask for arc codeswap interrupts
865 IFX_MEI_IRQEnable (pDev
);
867 return DSL_DEV_MEI_ERR_SUCCESS
;
873 * This function resets the ARC.
875 * \param pDev the device pointer
876 * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
879 static DSL_DEV_MeiError_t
880 IFX_MEI_ResetARC (DSL_DEV_Device_t
* pDev
)
882 u32 arc_debug_data
= 0;
884 IFX_MEI_HaltArc (pDev
);
886 IFX_MEI_LongWordRead ((u32
) LTQ_RCU_RST
, &arc_debug_data
);
887 IFX_MEI_LongWordWrite ((u32
) LTQ_RCU_RST
,
888 arc_debug_data
| LTQ_RCU_RST_REQ_DFE
| LTQ_RCU_RST_REQ_AFE
);
891 IFX_MEI_LongWordWriteOffset (pDev
, (u32
) ME_RST_CTRL
, MEI_SOFT_RESET
);
892 IFX_MEI_LongWordWriteOffset (pDev
, (u32
) ME_RST_CTRL
, 0);
894 IFX_MEI_IRQDisable (pDev
);
896 IFX_MEI_EnableCLK (pDev
);
900 *(unsigned long *) (BSP_PPE32_SRST
) = 0xC30;
901 *(unsigned long *) (BSP_PPE32_SRST
) = 0xFFF;
904 DSL_DEV_PRIVATE(pDev
)->modem_ready
= 0;
906 return DSL_DEV_MEI_ERR_SUCCESS
;
910 DSL_BSP_Showtime (DSL_DEV_Device_t
* dev
, DSL_uint32_t rate_fast
, DSL_uint32_t rate_intl
)
912 struct port_cell_info port_cell
= {0};
914 IFX_MEI_EMSG ("Datarate US intl = %d, fast = %d\n", (int)rate_intl
,
918 g_tx_link_rate
[0] = rate_fast
/ (53 * 8);
920 g_tx_link_rate
[1] = rate_intl
/ (53 * 8);
922 if ( g_tx_link_rate
[0] == 0 && g_tx_link_rate
[1] == 0 ) {
923 IFX_MEI_EMSG ("Got rate fail.\n");
926 if ( ifx_mei_atm_showtime_enter
)
928 port_cell
.port_num
= 2;
929 port_cell
.tx_link_rate
[0] = g_tx_link_rate
[0];
930 port_cell
.tx_link_rate
[1] = g_tx_link_rate
[1];
931 ifx_mei_atm_showtime_enter(&port_cell
, g_xdata_addr
);
935 IFX_MEI_EMSG("no hookup from ATM driver to set cell rate\n");
938 return DSL_DEV_MEI_ERR_SUCCESS
;
942 * Reset/halt/run the DFE.
943 * This function provide operations to reset/halt/run the DFE.
945 * \param pDev the device pointer
946 * \param mode which operation want to do
947 * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
950 static DSL_DEV_MeiError_t
951 IFX_MEI_CpuModeSet (DSL_DEV_Device_t
*pDev
,
952 DSL_DEV_CpuMode_t mode
)
954 DSL_DEV_MeiError_t err_ret
= DSL_DEV_MEI_ERR_FAILURE
;
957 err_ret
= IFX_MEI_HaltArc (pDev
);
960 err_ret
= IFX_MEI_RunArc (pDev
);
963 err_ret
= IFX_MEI_ResetARC (pDev
);
972 * Accress DFE memory.
973 * This function provide a way to access DFE memory;
975 * \param pDev the device pointer
976 * \param type read or write
977 * \param destaddr destination address
978 * \param databuff pointer to hold data
979 * \param databuffsize size want to read/write
980 * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
984 DSL_BSP_MemoryDebugAccess (DSL_DEV_Device_t
* pDev
,
985 DSL_BSP_MemoryAccessType_t type
,
986 DSL_uint32_t destaddr
, DSL_uint32_t
*databuff
,
987 DSL_uint32_t databuffsize
)
989 DSL_DEV_MeiError_t meierr
= DSL_DEV_MEI_ERR_SUCCESS
;
991 case DSL_BSP_MEMORY_READ
:
992 meierr
= IFX_MEI_DebugRead (pDev
, (u32
)destaddr
, (u32
*)databuff
, (u32
)databuffsize
);
994 case DSL_BSP_MEMORY_WRITE
:
995 meierr
= IFX_MEI_DebugWrite (pDev
, (u32
)destaddr
, (u32
*)databuff
, (u32
)databuffsize
);
998 return DSL_DEV_MEI_ERR_SUCCESS
;
1002 * Download boot code to ARC.
1003 * This function downloads boot code to ARC.
1005 * \param pDev the device pointer
1006 * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
1009 static DSL_DEV_MeiError_t
1010 IFX_MEI_DownloadBootCode (DSL_DEV_Device_t
*pDev
)
1012 IFX_MEI_IRQDisable (pDev
);
1014 IFX_MEI_EnableCLK (pDev
);
1016 IFX_MEI_FuseProg (pDev
); //program fuse rar
1018 IFX_MEI_DownloadBootPages (pDev
);
1020 return DSL_DEV_MEI_ERR_SUCCESS
;
1024 * Enable Jtag debugger interface
1025 * This function setups mips gpio to enable jtag debugger
1027 * \param pDev the device pointer
1028 * \param enable enable or disable
1029 * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
1032 static DSL_DEV_MeiError_t
1033 IFX_MEI_ArcJtagEnable (DSL_DEV_Device_t
*dev
, int enable
)
1040 //reserve gpio 9, 10, 11, 14, 19 for ARC JTAG
1041 ifxmips_port_reserve_pin (0, 9);
1042 ifxmips_port_reserve_pin (0, 10);
1043 ifxmips_port_reserve_pin (0, 11);
1044 ifxmips_port_reserve_pin (0, 14);
1045 ifxmips_port_reserve_pin (1, 3);
1047 ifxmips_port_set_dir_in(0, 11);
1048 ifxmips_port_clear_altsel0(0, 11);
1049 ifxmips_port_clear_altsel1(0, 11);
1050 ifxmips_port_set_open_drain(0, 11);
1052 IFX_MEI_LongWordRead ((u32) LTQ_RCU_RST, ®_data);
1053 IFX_MEI_LongWordWrite ((u32) LTQ_RCU_RST, reg_data | LTQ_RCU_RST_REQ_ARC_JTAG);
1061 return DSL_DEV_MEI_ERR_FAILURE;
1064 return DSL_DEV_MEI_ERR_SUCCESS
;
1068 * Enable DFE to MIPS interrupt
1069 * This function enable DFE to MIPS interrupt
1071 * \param pDev the device pointer
1072 * \param enable enable or disable
1073 * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
1076 static DSL_DEV_MeiError_t
1077 IFX_MEI_AdslMailboxIRQEnable (DSL_DEV_Device_t
*pDev
, int enable
)
1079 DSL_DEV_MeiError_t meierr
;
1082 meierr
= DSL_DEV_MEI_ERR_SUCCESS
;
1083 IFX_MEI_IRQDisable (pDev
);
1086 IFX_MEI_IRQEnable (pDev
);
1087 meierr
= DSL_DEV_MEI_ERR_SUCCESS
;
1090 meierr
= DSL_DEV_MEI_ERR_FAILURE
;
1098 * Get the modem status
1099 * This function return the modem status
1101 * \param pDev the device pointer
1102 * \return 1: modem ready 0: not ready
1106 IFX_MEI_IsModemReady (DSL_DEV_Device_t
* pDev
)
1108 return DSL_DEV_PRIVATE(pDev
)->modem_ready
;
1112 DSL_BSP_AdslLedInit (DSL_DEV_Device_t
* dev
,
1113 DSL_DEV_LedId_t led_number
,
1114 DSL_DEV_LedType_t type
,
1115 DSL_DEV_LedHandler_t handler
)
1118 struct led_config_param param
;
1119 if (led_number
== DSL_LED_LINK_ID
&& type
== DSL_LED_LINK_TYPE
&& handler
== /*DSL_LED_HD_CPU*/DSL_LED_HD_FW
) {
1120 param
.operation_mask
= CONFIG_OPERATION_UPDATE_SOURCE
;
1122 param
.source
= 0x01;
1123 // bsp_led_config (¶m);
1125 } else if (led_number
== DSL_LED_DATA_ID
&& type
== DSL_LED_DATA_TYPE
&& (handler
== DSL_LED_HD_FW
)) {
1126 param
.operation_mask
= CONFIG_OPERATION_UPDATE_SOURCE
;
1128 param
.source
= 0x02;
1129 // bsp_led_config (¶m);
1132 return DSL_DEV_MEI_ERR_SUCCESS
;
1136 DSL_BSP_AdslLedSet (DSL_DEV_Device_t
* dev
, DSL_DEV_LedId_t led_number
, DSL_DEV_LedMode_t mode
)
1138 printk(KERN_INFO
"[%s %d]: mode = %#x, led_number = %d\n", __func__
, __LINE__
, mode
, led_number
);
1141 switch (led_number
) {
1142 case DSL_LED_LINK_ID
:
1143 #ifdef CONFIG_BSP_LED
1144 bsp_led_set_blink (1, 0);
1145 bsp_led_set_data (1, 0);
1148 case DSL_LED_DATA_ID
:
1149 #ifdef CONFIG_BSP_LED
1150 bsp_led_set_blink (0, 0);
1151 bsp_led_set_data (0, 0);
1157 switch (led_number
) {
1158 case DSL_LED_LINK_ID
:
1159 #ifdef CONFIG_BSP_LED
1160 bsp_led_set_blink (1, 1); // data
1163 case DSL_LED_DATA_ID
:
1164 #ifdef CONFIG_BSP_LED
1165 bsp_led_set_blink (0, 1); // data
1171 switch (led_number
) {
1172 case DSL_LED_LINK_ID
:
1173 #ifdef CONFIG_BSP_LED
1174 bsp_led_set_blink (1, 0);
1175 bsp_led_set_data (1, 1);
1178 case DSL_LED_DATA_ID
:
1179 #ifdef CONFIG_BSP_LED
1180 bsp_led_set_blink (0, 0);
1181 bsp_led_set_data (0, 1);
1187 return DSL_DEV_MEI_ERR_SUCCESS
;
1193 * Compose a message.
1194 * This function compose a message from opcode, group, address, index, size, and data
1196 * \param opcode The message opcode
1197 * \param group The message group number
1198 * \param address The message address.
1199 * \param index The message index.
1200 * \param size The number of words to read/write.
1201 * \param data The pointer to data.
1202 * \param CMVMSG The pointer to message buffer.
1206 makeCMV (u8 opcode
, u8 group
, u16 address
, u16 index
, int size
, u16
* data
, u16
*CMVMSG
)
1208 memset (CMVMSG
, 0, MSG_LENGTH
* 2);
1209 CMVMSG
[0] = (opcode
<< 4) + (size
& 0xf);
1210 CMVMSG
[1] = (((index
== 0) ? 0 : 1) << 7) + (group
& 0x7f);
1211 CMVMSG
[2] = address
;
1213 if (opcode
== H2D_CMV_WRITE
)
1214 memcpy (CMVMSG
+ 4, data
, size
* 2);
1219 * Send a message to ARC and read the response
1220 * This function sends a message to arc, waits the response, and reads the responses.
1222 * \param pDev the device pointer
1223 * \param request Pointer to the request
1224 * \param reply Wait reply or not.
1225 * \param response Pointer to the response
1226 * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
1230 DSL_BSP_SendCMV (DSL_DEV_Device_t
* pDev
, u16
* request
, int reply
, u16
* response
) // write cmv to arc, if reply needed, wait for reply
1232 DSL_DEV_MeiError_t meierror
;
1233 #if defined(BSP_PORT_RTEMS)
1234 int delay_counter
= 0;
1237 if (MEI_MUTEX_LOCK (DSL_DEV_PRIVATE(pDev
)->mei_cmv_sema
))
1238 return -ERESTARTSYS
;
1240 DSL_DEV_PRIVATE(pDev
)->cmv_reply
= reply
;
1241 memset (DSL_DEV_PRIVATE(pDev
)->CMV_RxMsg
, 0,
1242 sizeof (DSL_DEV_PRIVATE(pDev
)->
1244 DSL_DEV_PRIVATE(pDev
)->arcmsgav
= 0;
1246 meierror
= IFX_MEI_MailboxWrite (pDev
, request
, MSG_LENGTH
);
1248 if (meierror
!= DSL_DEV_MEI_ERR_SUCCESS
) {
1249 DSL_DEV_PRIVATE(pDev
)->cmv_waiting
= 0;
1250 DSL_DEV_PRIVATE(pDev
)->arcmsgav
= 0;
1251 IFX_MEI_EMSG ("MailboxWrite Fail!\n");
1252 IFX_MEI_EMSG ("Resetting ARC...\n");
1253 IFX_MEI_ResetARC(pDev
);
1254 MEI_MUTEX_UNLOCK (DSL_DEV_PRIVATE(pDev
)->mei_cmv_sema
);
1258 DSL_DEV_PRIVATE(pDev
)->cmv_count
++;
1261 if (DSL_DEV_PRIVATE(pDev
)->cmv_reply
==
1263 MEI_MUTEX_UNLOCK (DSL_DEV_PRIVATE(pDev
)->mei_cmv_sema
);
1264 return DSL_DEV_MEI_ERR_SUCCESS
;
1267 #if !defined(BSP_PORT_RTEMS)
1268 if (DSL_DEV_PRIVATE(pDev
)->arcmsgav
== 0)
1269 MEI_WAIT_EVENT_TIMEOUT (DSL_DEV_PRIVATE(pDev
)->wait_queue_arcmsgav
, CMV_TIMEOUT
);
1271 while (DSL_DEV_PRIVATE(pDev
)->arcmsgav
== 0 && delay_counter
< CMV_TIMEOUT
/ 5) {
1277 DSL_DEV_PRIVATE(pDev
)->cmv_waiting
= 0;
1278 if (DSL_DEV_PRIVATE(pDev
)->arcmsgav
== 0) { //CMV_timeout
1279 DSL_DEV_PRIVATE(pDev
)->arcmsgav
= 0;
1280 IFX_MEI_EMSG ("\%s: DSL_DEV_MEI_ERR_MAILBOX_TIMEOUT\n",
1282 MEI_MUTEX_UNLOCK (DSL_DEV_PRIVATE(pDev
)->mei_cmv_sema
);
1283 return DSL_DEV_MEI_ERR_MAILBOX_TIMEOUT
;
1286 DSL_DEV_PRIVATE(pDev
)->arcmsgav
= 0;
1287 DSL_DEV_PRIVATE(pDev
)->
1289 memcpy (response
, DSL_DEV_PRIVATE(pDev
)->CMV_RxMsg
, MSG_LENGTH
* 2);
1290 MEI_MUTEX_UNLOCK (DSL_DEV_PRIVATE(pDev
)->mei_cmv_sema
);
1291 return DSL_DEV_MEI_ERR_SUCCESS
;
1293 MEI_MUTEX_UNLOCK (DSL_DEV_PRIVATE(pDev
)->mei_cmv_sema
);
1294 return DSL_DEV_MEI_ERR_SUCCESS
;
1298 * Reset the ARC, download boot codes, and run the ARC.
1299 * This function resets the ARC, downloads boot codes to ARC, and runs the ARC.
1301 * \param pDev the device pointer
1302 * \return DSL_DEV_MEI_ERR_SUCCESS or DSL_DEV_MEI_ERR_FAILURE
1305 static DSL_DEV_MeiError_t
1306 IFX_MEI_RunAdslModem (DSL_DEV_Device_t
*pDev
)
1308 int nSize
= 0, idx
= 0;
1309 uint32_t im0_register
, im2_register
;
1310 // DSL_DEV_WinHost_Message_t m;
1312 if (mei_arc_swap_buff
== NULL
) {
1314 (u32
*) kmalloc (MAXSWAPSIZE
* 4, GFP_KERNEL
);
1315 if (mei_arc_swap_buff
== NULL
) {
1316 IFX_MEI_EMSG (">>> malloc fail for codeswap buff!!! <<<\n");
1317 return DSL_DEV_MEI_ERR_FAILURE
;
1319 IFX_MEI_DMSG("allocate %dKB swap buff memory at: 0x%p\n", ksize(mei_arc_swap_buff
)/1024, mei_arc_swap_buff
);
1322 DSL_DEV_PRIVATE(pDev
)->img_hdr
=
1323 (ARC_IMG_HDR
*) DSL_DEV_PRIVATE(pDev
)->adsl_mem_info
[0].address
;
1324 if ((DSL_DEV_PRIVATE(pDev
)->img_hdr
->
1325 count
) * sizeof (ARC_SWP_PAGE_HDR
) > SDRAM_SEGMENT_SIZE
) {
1326 IFX_MEI_EMSG ("firmware header size is bigger than 64K segment size\n");
1327 return DSL_DEV_MEI_ERR_FAILURE
;
1330 for (idx
= 0; idx
< MAX_BAR_REGISTERS
; idx
++) {
1331 nSize
+= DSL_DEV_PRIVATE(pDev
)->adsl_mem_info
[idx
].nCopy
;
1334 DSL_DEV_PRIVATE(pDev
)->image_size
) {
1335 IFX_MEI_EMSG ("Firmware download is not completed. Please download firmware again!\n");
1336 return DSL_DEV_MEI_ERR_FAILURE
;
1341 IFX_MEI_ResetARC (pDev
);
1342 IFX_MEI_HaltArc (pDev
);
1343 IFX_MEI_BarUpdate (pDev
, DSL_DEV_PRIVATE(pDev
)->nBar
);
1345 //IFX_MEI_DMSG("Starting to meiDownloadBootCode\n");
1347 IFX_MEI_DownloadBootCode (pDev
);
1349 im0_register
= (*LTQ_ICU_IM0_IER
) & (1 << 20);
1350 im2_register
= (*LTQ_ICU_IM2_IER
) & (1 << 20);
1353 disable_irq (LTQ_USB_OC_INT
);
1354 disable_irq (pDev
->nIrq
[IFX_DYING_GASP
]);
1356 IFX_MEI_RunArc (pDev
);
1358 MEI_WAIT_EVENT_TIMEOUT (DSL_DEV_PRIVATE(pDev
)->wait_queue_modemready
, 1000);
1360 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
;
1517 org_mem_ptr
= kmalloc (allocate_size
, GFP_KERNEL
);
1518 if (org_mem_ptr
== NULL
) {
1519 IFX_MEI_EMSG ("%d: kmalloc %d bytes memory fail!\n", idx
, allocate_size
);
1521 goto allocate_error
;
1524 if (((unsigned long)org_mem_ptr
) & (1023)) {
1525 /* Pointer not 1k aligned, so free it and allocate a larger chunk
1526 * for further alignment.
1529 org_mem_ptr
= kmalloc (allocate_size
+ 1024, GFP_KERNEL
);
1530 if (org_mem_ptr
== NULL
) {
1531 IFX_MEI_EMSG ("%d: kmalloc %d bytes memory fail!\n",
1532 idx
, allocate_size
+ 1024);
1534 goto allocate_error
;
1536 mem_ptr
= (unsigned long) (org_mem_ptr
+ 1023) & ~(1024 -1);
1538 mem_ptr
= (unsigned long) org_mem_ptr
;
1541 adsl_mem_info
[idx
].address
= (char *) mem_ptr
;
1542 adsl_mem_info
[idx
].org_address
= org_mem_ptr
;
1543 adsl_mem_info
[idx
].size
= allocate_size
;
1544 size
-= allocate_size
;
1545 total_size
+= allocate_size
;
1548 IFX_MEI_EMSG ("Image size is too large!\n");
1550 goto allocate_error
;
1556 IFX_MEI_DFEMemoryFree (pDev
, FREE_ALL
);
1561 * Program the BAR registers
1563 * \param pDev the device pointer
1564 * \param nTotalBar The number of bar to program.
1568 IFX_MEI_BarUpdate (DSL_DEV_Device_t
* pDev
, int nTotalBar
)
1571 smmu_mem_info_t
*adsl_mem_info
=
1572 DSL_DEV_PRIVATE(pDev
)->adsl_mem_info
;
1574 for (idx
= 0; idx
< nTotalBar
; idx
++) {
1575 //skip XDATA register
1576 if (idx
== XDATA_REGISTER
)
1578 IFX_MEI_LongWordWriteOffset (pDev
, (u32
) ME_XMEM_BAR_BASE
+ idx
* 4,
1579 (((uint32_t) adsl_mem_info
[idx
].address
) & 0x0FFFFFFF));
1581 for (idx
= nTotalBar
; idx
< MAX_BAR_REGISTERS
; idx
++) {
1582 if (idx
== XDATA_REGISTER
)
1584 IFX_MEI_LongWordWriteOffset (pDev
, (u32
) ME_XMEM_BAR_BASE
+ idx
* 4,
1585 (((uint32_t)adsl_mem_info
[nTotalBar
- 1].address
) & 0x0FFFFFFF));
1586 /* These are for /proc/danube_mei/meminfo purpose */
1587 adsl_mem_info
[idx
].address
= adsl_mem_info
[nTotalBar
- 1].address
;
1588 adsl_mem_info
[idx
].org_address
= adsl_mem_info
[nTotalBar
- 1].org_address
;
1589 adsl_mem_info
[idx
].size
= 0; /* Prevent it from being freed */
1592 g_xdata_addr
= adsl_mem_info
[XDATA_REGISTER
].address
;
1593 IFX_MEI_LongWordWriteOffset (pDev
, (u32
) ME_XMEM_BAR_BASE
+ XDATA_REGISTER
* 4,
1594 (((uint32_t) adsl_mem_info
[XDATA_REGISTER
].address
) & 0x0FFFFFFF));
1595 // update MEI_XDATA_BASE_SH
1596 IFX_MEI_LongWordWriteOffset (pDev
, (u32
) ME_XDATA_BASE_SH
,
1597 ((unsigned long)adsl_mem_info
[XDATA_REGISTER
].address
) & 0x0FFFFFFF);
1599 return DSL_DEV_MEI_ERR_SUCCESS
;
1602 /* This copies the firmware from secondary storage to 64k memory segment in SDRAM */
1604 DSL_BSP_FWDownload (DSL_DEV_Device_t
* pDev
, const char *buf
,
1605 unsigned long size
, long *loff
, long *current_offset
)
1607 ARC_IMG_HDR img_hdr_tmp
;
1608 smmu_mem_info_t
*adsl_mem_info
= DSL_DEV_PRIVATE(pDev
)->adsl_mem_info
;
1610 size_t nRead
= 0, nCopy
= 0;
1612 char *org_mem_ptr
= NULL
;
1613 ssize_t retval
= -ENOMEM
;
1619 if (size
< sizeof (img_hdr_tmp
)) {
1620 IFX_MEI_EMSG ("Firmware size is too small!\n");
1623 copy_from_user ((char *) &img_hdr_tmp
, buf
, sizeof (img_hdr_tmp
));
1624 // header of image_size and crc are not included.
1625 DSL_DEV_PRIVATE(pDev
)->image_size
= le32_to_cpu (img_hdr_tmp
.size
) + 8;
1627 if (DSL_DEV_PRIVATE(pDev
)->image_size
> 1024 * 1024) {
1628 IFX_MEI_EMSG ("Firmware size is too large!\n");
1631 // check if arc is halt
1632 IFX_MEI_ResetARC (pDev
);
1633 IFX_MEI_HaltArc (pDev
);
1635 IFX_MEI_DFEMemoryFree (pDev
, FREE_ALL
); //free all
1637 retval
= IFX_MEI_DFEMemoryAlloc (pDev
, DSL_DEV_PRIVATE(pDev
)->image_size
);
1639 IFX_MEI_EMSG ("Error: No memory space left.\n");
1642 for (idx
= 0; idx
< retval
; idx
++) {
1643 //skip XDATA register
1644 if (idx
== XDATA_REGISTER
)
1646 if (idx
* SDRAM_SEGMENT_SIZE
< le32_to_cpu (img_hdr_tmp
.page
[0].p_offset
))
1647 adsl_mem_info
[idx
].type
= FREE_RELOAD
;
1649 adsl_mem_info
[idx
].type
= FREE_SHOWTIME
;
1651 DSL_DEV_PRIVATE(pDev
)->nBar
= retval
;
1653 DSL_DEV_PRIVATE(pDev
)->img_hdr
=
1654 (ARC_IMG_HDR
*) adsl_mem_info
[0].address
;
1656 org_mem_ptr
= kmalloc (SDRAM_SEGMENT_SIZE
, GFP_KERNEL
);
1657 if (org_mem_ptr
== NULL
) {
1658 IFX_MEI_EMSG ("kmalloc memory fail!\n");
1663 if (((unsigned long)org_mem_ptr
) & (1023)) {
1664 /* Pointer not 1k aligned, so free it and allocate a larger chunk
1665 * for further alignment.
1668 org_mem_ptr
= kmalloc (SDRAM_SEGMENT_SIZE
+ 1024, GFP_KERNEL
);
1669 if (org_mem_ptr
== NULL
) {
1670 IFX_MEI_EMSG ("kmalloc memory fail!\n");
1674 adsl_mem_info
[XDATA_REGISTER
].address
=
1675 (char *) ((unsigned long) (org_mem_ptr
+ 1023) & ~(1024 -1));
1677 adsl_mem_info
[XDATA_REGISTER
].address
= org_mem_ptr
;
1680 adsl_mem_info
[XDATA_REGISTER
].org_address
= org_mem_ptr
;
1681 adsl_mem_info
[XDATA_REGISTER
].size
= SDRAM_SEGMENT_SIZE
;
1683 adsl_mem_info
[XDATA_REGISTER
].type
= FREE_RELOAD
;
1684 IFX_MEI_DMSG("-> IFX_MEI_BarUpdate()\n");
1685 IFX_MEI_BarUpdate (pDev
, (DSL_DEV_PRIVATE(pDev
)->nBar
));
1687 else if (DSL_DEV_PRIVATE(pDev
)-> image_size
== 0) {
1688 IFX_MEI_EMSG ("Error: Firmware size=0! \n");
1693 while (nRead
< size
) {
1694 long offset
= ((long) (*loff
) + nRead
) % SDRAM_SEGMENT_SIZE
;
1695 idx
= (((long) (*loff
)) + nRead
) / SDRAM_SEGMENT_SIZE
;
1696 mem_ptr
= (char *) KSEG1ADDR ((unsigned long) (adsl_mem_info
[idx
].address
) + offset
);
1697 if ((size
- nRead
+ offset
) > SDRAM_SEGMENT_SIZE
)
1698 nCopy
= SDRAM_SEGMENT_SIZE
- offset
;
1700 nCopy
= size
- nRead
;
1701 copy_from_user (mem_ptr
, buf
+ nRead
, nCopy
);
1702 for (offset
= 0; offset
< (nCopy
/ 4); offset
++) {
1703 ((unsigned long *) mem_ptr
)[offset
] = le32_to_cpu (((unsigned long *) mem_ptr
)[offset
]);
1706 adsl_mem_info
[idx
].nCopy
+= nCopy
;
1710 *current_offset
= size
;
1711 return DSL_DEV_MEI_ERR_SUCCESS
;
1713 IFX_MEI_DFEMemoryFree (pDev
, FREE_ALL
);
1714 return DSL_DEV_MEI_ERR_FAILURE
;
1717 * Register a callback event.
1719 * -1 if the event already has a callback function registered.
1722 int DSL_BSP_EventCBRegister(DSL_BSP_EventCallBack_t
*p
)
1725 IFX_MEI_EMSG("Invalid parameter!\n");
1728 if (p
->event
> DSL_BSP_CB_LAST
|| p
->event
< DSL_BSP_CB_FIRST
) {
1729 IFX_MEI_EMSG("Invalid Event %d\n", p
->event
);
1732 if (dsl_bsp_event_callback
[p
->event
].function
) {
1733 IFX_MEI_EMSG("Event %d already has a callback function registered!\n", p
->event
);
1736 dsl_bsp_event_callback
[p
->event
].function
= p
->function
;
1737 dsl_bsp_event_callback
[p
->event
].event
= p
->event
;
1738 dsl_bsp_event_callback
[p
->event
].pData
= p
->pData
;
1742 int DSL_BSP_EventCBUnregister(DSL_BSP_EventCallBack_t
*p
)
1745 IFX_MEI_EMSG("Invalid parameter!\n");
1748 if (p
->event
> DSL_BSP_CB_LAST
|| p
->event
< DSL_BSP_CB_FIRST
) {
1749 IFX_MEI_EMSG("Invalid Event %d\n", p
->event
);
1752 if (dsl_bsp_event_callback
[p
->event
].function
) {
1753 IFX_MEI_EMSG("Unregistering Event %d...\n", p
->event
);
1754 dsl_bsp_event_callback
[p
->event
].function
= NULL
;
1755 dsl_bsp_event_callback
[p
->event
].pData
= NULL
;
1757 IFX_MEI_EMSG("Event %d is not registered!\n", p
->event
);
1764 * MEI Dying Gasp interrupt handler
1768 * \param regs Pointer to the structure of danube mips registers
1771 /*static irqreturn_t IFX_MEI_Dying_Gasp_IrqHandle (int int1, void *void0)
1773 DSL_DEV_Device_t *pDev = (DSL_DEV_Device_t *) void0;
1774 DSL_BSP_CB_Type_t event;
1777 IFX_MEI_EMSG("Error: Got Interrupt but pDev is NULL!!!!\n");
1780 disable_irq (pDev->nIrq[IFX_DYING_GASP]);
1782 disable_irq_nosync(pDev->nIrq[IFX_DYING_GASP]);
1784 event = DSL_BSP_CB_DYING_GASP;
1786 if (dsl_bsp_event_callback[event].function)
1787 (*dsl_bsp_event_callback[event].function)(pDev, event, dsl_bsp_event_callback[event].pData);
1789 #ifdef CONFIG_USE_EMULATOR
1790 IFX_MEI_EMSG("Dying Gasp! Shutting Down... (Work around for Amazon-S Venus emulator)\n");
1792 IFX_MEI_EMSG("Dying Gasp! Shutting Down...\n");
1793 // kill_proc (1, SIGINT, 1);
1798 extern void ifx_usb_enable_afe_oc(void);
1801 * MEI interrupt handler
1805 * \param regs Pointer to the structure of danube mips registers
1808 static irqreturn_t
IFX_MEI_IrqHandle (int int1
, void *void0
)
1811 DSL_DEV_Device_t
*pDev
= (DSL_DEV_Device_t
*) void0
;
1812 #if defined(CONFIG_LTQ_MEI_FW_LOOPBACK) && defined(DFE_PING_TEST)
1813 dfe_loopback_irq_handler (pDev
);
1815 #endif //CONFIG_AMAZON_S_MEI_FW_LOOPBACK
1816 DSL_BSP_CB_Type_t event
;
1819 IFX_MEI_EMSG("Error: Got Interrupt but pDev is NULL!!!!\n");
1821 IFX_MEI_DebugRead (pDev
, ARC_MEI_MAILBOXR
, &scratch
, 1);
1822 if (scratch
& OMB_CODESWAP_MESSAGE_MSG_TYPE_MASK
) {
1823 IFX_MEI_EMSG("Receive Code Swap Request interrupt!!!\n");
1826 else if (scratch
& OMB_CLEAREOC_INTERRUPT_CODE
) {
1827 // clear eoc message interrupt
1828 IFX_MEI_DMSG("OMB_CLEAREOC_INTERRUPT_CODE\n");
1829 event
= DSL_BSP_CB_CEOC_IRQ
;
1830 IFX_MEI_LongWordWriteOffset (pDev
, (u32
) ME_ARC2ME_STAT
, ARC_TO_MEI_MSGAV
);
1831 if (dsl_bsp_event_callback
[event
].function
)
1832 (*dsl_bsp_event_callback
[event
].function
)(pDev
, event
, dsl_bsp_event_callback
[event
].pData
);
1833 } else if (scratch
& OMB_REBOOT_INTERRUPT_CODE
) {
1835 IFX_MEI_DMSG("OMB_REBOOT_INTERRUPT_CODE\n");
1836 event
= DSL_BSP_CB_FIRMWARE_REBOOT
;
1838 IFX_MEI_LongWordWriteOffset (pDev
, (u32
) ME_ARC2ME_STAT
, ARC_TO_MEI_MSGAV
);
1840 if (dsl_bsp_event_callback
[event
].function
)
1841 (*dsl_bsp_event_callback
[event
].function
)(pDev
, event
, dsl_bsp_event_callback
[event
].pData
);
1842 } else { // normal message
1843 IFX_MEI_MailboxRead (pDev
, DSL_DEV_PRIVATE(pDev
)->CMV_RxMsg
, MSG_LENGTH
);
1844 if (DSL_DEV_PRIVATE(pDev
)-> cmv_waiting
== 1) {
1845 DSL_DEV_PRIVATE(pDev
)-> arcmsgav
= 1;
1846 DSL_DEV_PRIVATE(pDev
)-> cmv_waiting
= 0;
1847 #if !defined(BSP_PORT_RTEMS)
1848 MEI_WAKEUP_EVENT (DSL_DEV_PRIVATE(pDev
)->wait_queue_arcmsgav
);
1852 DSL_DEV_PRIVATE(pDev
)-> modem_ready_cnt
++;
1853 memcpy ((char *) DSL_DEV_PRIVATE(pDev
)->Recent_indicator
,
1854 (char *) DSL_DEV_PRIVATE(pDev
)->CMV_RxMsg
, MSG_LENGTH
* 2);
1855 if (((DSL_DEV_PRIVATE(pDev
)->CMV_RxMsg
[0] & 0xff0) >> 4) == D2H_AUTONOMOUS_MODEM_READY_MSG
) {
1856 //check ARC ready message
1857 IFX_MEI_DMSG ("Got MODEM_READY_MSG\n");
1858 DSL_DEV_PRIVATE(pDev
)->modem_ready
= 1;
1859 MEI_WAKEUP_EVENT (DSL_DEV_PRIVATE(pDev
)->wait_queue_modemready
);
1868 DSL_BSP_ATMLedCBRegister (int (*ifx_adsl_ledcallback
) (void))
1870 g_adsl_ledcallback
= ifx_adsl_ledcallback
;
1875 DSL_BSP_ATMLedCBUnregister (int (*ifx_adsl_ledcallback
) (void))
1877 g_adsl_ledcallback
= adsl_dummy_ledcallback
;
1883 DSL_BSP_EventCBRegister (int (*ifx_adsl_callback
)
1884 (DSL_BSP_CB_Event_t
* param
))
1888 if (DSL_EventCB
== NULL
) {
1889 DSL_EventCB
= ifx_adsl_callback
;
1898 DSL_BSP_EventCBUnregister (int (*ifx_adsl_callback
)
1899 (DSL_BSP_CB_Event_t
* param
))
1903 if (DSL_EventCB
== ifx_adsl_callback
) {
1913 DSL_BSP_GetEventCB (int (**ifx_adsl_callback
)
1914 (DSL_BSP_CB_Event_t
* param
))
1916 *ifx_adsl_callback
= DSL_EventCB
;
1921 #ifdef CONFIG_LTQ_MEI_FW_LOOPBACK
1922 #define mte_reg_base (0x4800*4+0x20000)
1924 /* Iridia Registers Address Constants */
1925 #define MTE_Reg(r) (int)(mte_reg_base + (r*4))
1927 #define IT_AMODE MTE_Reg(0x0004)
1929 #define TIMER_DELAY (1024)
1930 #define BC0_BYTES (32)
1931 #define BC1_BYTES (30)
1933 #define TIMEOUT_VALUE 2000
1939 for (i
= 0; i
< cycle
; i
++);
1943 WriteRegLong (u32 addr
, u32 data
)
1945 //*((volatile u32 *)(addr)) = data;
1946 IFX_MEI_WRITE_REGISTER_L (data
, addr
);
1950 ReadRegLong (u32 addr
)
1953 //rd_val = *((volatile u32 *)(addr));
1955 return IFX_MEI_READ_REGISTER_L (addr
);
1958 /* This routine writes the mailbox with the data in an input array */
1960 WriteMbox (u32
* mboxarray
, u32 size
)
1962 IFX_MEI_DebugWrite (&dsl_devices
[0], IMBOX_BASE
, mboxarray
, size
);
1963 IFX_MEI_DMSG("write to %X\n", IMBOX_BASE
);
1964 IFX_MEI_LongWordWriteOffset (&dsl_devices
[0], (u32
) ME_ME2ARC_INT
, MEI_TO_ARC_MSGAV
);
1967 /* This routine reads the output mailbox and places the results into an array */
1969 ReadMbox (u32
* mboxarray
, u32 size
)
1971 IFX_MEI_DebugRead (&dsl_devices
[0], OMBOX_BASE
, mboxarray
, size
);
1972 IFX_MEI_DMSG("read from %X\n", OMBOX_BASE
);
1976 MEIWriteARCValue (u32 address
, u32 value
)
1980 /* Write address register */
1981 IFX_MEI_WRITE_REGISTER_L (address
, ME_DBG_WR_AD
+ LTQ_MEI_BASE_ADDR
);
1983 /* Write data register */
1984 IFX_MEI_WRITE_REGISTER_L (value
, ME_DBG_DATA
+ LTQ_MEI_BASE_ADDR
);
1986 /* wait until complete - timeout at 40 */
1987 for (i
= 0; i
< 40; i
++) {
1988 check
= IFX_MEI_READ_REGISTER_L (ME_ARC2ME_STAT
+ LTQ_MEI_BASE_ADDR
);
1990 if ((check
& ARC_TO_MEI_DBG_DONE
))
1993 /* clear the flag */
1994 IFX_MEI_WRITE_REGISTER_L (ARC_TO_MEI_DBG_DONE
, ME_ARC2ME_STAT
+ LTQ_MEI_BASE_ADDR
);
1998 arc_code_page_download (uint32_t arc_code_length
, uint32_t * start_address
)
2002 IFX_MEI_DMSG("try to download pages,size=%d\n", arc_code_length
);
2003 IFX_MEI_ControlModeSet (&dsl_devices
[0], MEI_MASTER_MODE
);
2004 IFX_MEI_HaltArc (&dsl_devices
[0]);
2005 IFX_MEI_LongWordWriteOffset (&dsl_devices
[0], (u32
) ME_DX_AD
, 0);
2006 for (count
= 0; count
< arc_code_length
; count
++) {
2007 IFX_MEI_LongWordWriteOffset (&dsl_devices
[0], (u32
) ME_DX_DATA
,
2008 *(start_address
+ count
));
2010 IFX_MEI_ControlModeSet (&dsl_devices
[0], JTAG_MASTER_MODE
);
2013 load_jump_table (unsigned long addr
)
2016 uint32_t addr_le
, addr_be
;
2017 uint32_t jump_table
[32];
2019 for (i
= 0; i
< 16; i
++) {
2020 addr_le
= i
* 8 + addr
;
2021 addr_be
= ((addr_le
>> 16) & 0xffff);
2022 addr_be
|= ((addr_le
& 0xffff) << 16);
2023 jump_table
[i
* 2 + 0] = 0x0f802020;
2024 jump_table
[i
* 2 + 1] = addr_be
;
2025 //printk("jt %X %08X %08X\n",i,jump_table[i*2+0],jump_table[i*2+1]);
2027 arc_code_page_download (32, &jump_table
[0]);
2034 dfe_loopback_irq_handler (DSL_DEV_Device_t
*pDev
)
2036 uint32_t rd_mbox
[10];
2038 memset (&rd_mbox
[0], 0, 10 * 4);
2039 ReadMbox (&rd_mbox
[0], 6);
2040 if (rd_mbox
[0] == 0x0) {
2041 FX_MEI_DMSG("Get ARC_ACK\n");
2044 else if (rd_mbox
[0] == 0x5) {
2045 IFX_MEI_DMSG("Get ARC_BUSY\n");
2048 else if (rd_mbox
[0] == 0x3) {
2049 IFX_MEI_DMSG("Get ARC_EDONE\n");
2050 if (rd_mbox
[1] == 0x0) {
2052 IFX_MEI_DMSG("Get E_MEMTEST\n");
2053 if (rd_mbox
[2] != 0x1) {
2055 IFX_MEI_DMSG("Get Result %X\n", rd_mbox
[2]);
2059 IFX_MEI_LongWordWriteOffset (&dsl_devices
[0], (u32
) ME_ARC2ME_STAT
,
2060 ARC_TO_MEI_DBG_DONE
);
2061 MEI_MASK_AND_ACK_IRQ (pDev
->nIrq
[IFX_DFEIR
]);
2062 disable_irq (pDev
->nIrq
[IFX_DFEIR
]);
2068 wait_mem_test_result (void)
2073 IFX_MEI_DMSG("Waiting Starting\n");
2074 while (mbox
[0] == 0) {
2075 ReadMbox (&mbox
[0], 5);
2077 IFX_MEI_DMSG("Try to get mem test result.\n");
2078 ReadMbox (&mbox
[0], 5);
2079 if (mbox
[0] == 0xA) {
2080 IFX_MEI_DMSG("Success.\n");
2082 else if (mbox
[0] == 0xA) {
2083 IFX_MEI_EMSG("Fail,address %X,except data %X,receive data %X\n",
2084 mbox
[1], mbox
[2], mbox
[3]);
2087 IFX_MEI_EMSG("Fail\n");
2092 arc_ping_testing (DSL_DEV_Device_t
*pDev
)
2094 #define MEI_PING 0x00000001
2095 uint32_t wr_mbox
[10], rd_mbox
[10];
2098 for (i
= 0; i
< 10; i
++) {
2103 FX_MEI_DMSG("send ping msg\n");
2104 wr_mbox
[0] = MEI_PING
;
2105 WriteMbox (&wr_mbox
[0], 10);
2107 while (got_int
== 0) {
2111 IFX_MEI_DMSG("send start event\n");
2117 wr_mbox
[3] = (uint32_t) 0xf5acc307e;
2120 wr_mbox
[6] = 0x1c000;
2124 WriteMbox (&wr_mbox
[0], 10);
2125 DSL_ENABLE_IRQ (pDev
->nIrq
[IFX_DFEIR
]);
2126 //printk("IFX_MEI_MailboxWrite ret=%d\n",i);
2127 IFX_MEI_LongWordWriteOffset (&dsl_devices
[0],
2128 (u32
) ME_ME2ARC_INT
,
2130 IFX_MEI_DMSG("sleeping\n");
2135 IFX_MEI_DMSG("got_int >>>> 3\n");
2137 IFX_MEI_DMSG("got int = %d\n", got_int
);
2140 DSL_ENABLE_IRQ (pDev
->nIrq
[IFX_DFEIR
]);
2142 //mbox_read(&rd_mbox[0],6);
2148 static DSL_DEV_MeiError_t
2149 DFE_Loopback_Test (void)
2152 u32 arc_debug_data
= 0, temp
;
2153 DSL_DEV_Device_t
*pDev
= &dsl_devices
[0];
2154 uint32_t wr_mbox
[10];
2156 IFX_MEI_ResetARC (pDev
);
2158 arc_debug_data
= ACL_CLK_MODE_ENABLE
;
2159 IFX_MEI_DebugWrite (pDev
, CRI_CCR0
, &arc_debug_data
, 1);
2161 #if defined( DFE_PING_TEST )|| defined( DFE_ATM_LOOPBACK)
2162 // WriteARCreg(AUX_XMEM_LTEST,0);
2163 IFX_MEI_ControlModeSet (pDev
, MEI_MASTER_MODE
);
2164 #define AUX_XMEM_LTEST 0x128
2165 _IFX_MEI_DBGLongWordWrite (pDev
, MEI_DEBUG_DEC_AUX_MASK
, AUX_XMEM_LTEST
, 0);
2166 IFX_MEI_ControlModeSet (pDev
, JTAG_MASTER_MODE
);
2168 // WriteARCreg(AUX_XDMA_GAP,0);
2169 IFX_MEI_ControlModeSet (pDev
, MEI_MASTER_MODE
);
2170 #define AUX_XDMA_GAP 0x114
2171 _IFX_MEI_DBGLongWordWrite (pDev
, MEI_DEBUG_DEC_AUX_MASK
, AUX_XDMA_GAP
, 0);
2172 IFX_MEI_ControlModeSet (pDev
, JTAG_MASTER_MODE
);
2174 IFX_MEI_ControlModeSet (pDev
, MEI_MASTER_MODE
);
2176 _IFX_MEI_DBGLongWordWrite (pDev
, MEI_DEBUG_DEC_AUX_MASK
,
2177 (u32
) ME_XDATA_BASE_SH
+ LTQ_MEI_BASE_ADDR
, temp
);
2178 IFX_MEI_ControlModeSet (pDev
, JTAG_MASTER_MODE
);
2180 i
= IFX_MEI_DFEMemoryAlloc (pDev
, SDRAM_SEGMENT_SIZE
* 16);
2184 for (idx
= 0; idx
< i
; idx
++) {
2185 DSL_DEV_PRIVATE(pDev
)->adsl_mem_info
[idx
].type
= FREE_RELOAD
;
2186 IFX_MEI_WRITE_REGISTER_L ((((uint32_t) DSL_DEV_PRIVATE(pDev
)->adsl_mem_info
[idx
].address
) & 0x0fffffff),
2187 LTQ_MEI_BASE_ADDR
+ ME_XMEM_BAR_BASE
+ idx
* 4);
2188 IFX_MEI_DMSG("bar%d(%X)=%X\n", idx
,
2189 LTQ_MEI_BASE_ADDR
+ ME_XMEM_BAR_BASE
+
2190 idx
* 4, (((uint32_t)
2191 ((ifx_mei_device_private_t
*)
2192 pDev
->pPriv
)->adsl_mem_info
[idx
].
2193 address
) & 0x0fffffff));
2194 memset ((u8
*) DSL_DEV_PRIVATE(pDev
)->adsl_mem_info
[idx
].address
, 0, SDRAM_SEGMENT_SIZE
);
2197 IFX_MEI_LongWordWriteOffset (pDev
, (u32
) ME_XDATA_BASE_SH
,
2198 ((unsigned long) DSL_DEV_PRIVATE(pDev
)->adsl_mem_info
[XDATA_REGISTER
].address
) & 0x0FFFFFFF);
2201 IFX_MEI_EMSG ("cannot load image: no memory\n");
2202 return DSL_DEV_MEI_ERR_FAILURE
;
2204 //WriteARCreg(AUX_IC_CTRL,2);
2205 IFX_MEI_DMSG("Setting MEI_MASTER_MODE..\n");
2206 IFX_MEI_ControlModeSet (pDev
, MEI_MASTER_MODE
);
2207 #define AUX_IC_CTRL 0x11
2208 _IFX_MEI_DBGLongWordWrite (pDev
, MEI_DEBUG_DEC_AUX_MASK
,
2210 IFX_MEI_DMSG("Setting JTAG_MASTER_MODE..\n");
2211 IFX_MEI_ControlModeSet (pDev
, JTAG_MASTER_MODE
);
2213 IFX_MEI_DMSG("Halting ARC...\n");
2214 IFX_MEI_HaltArc (&dsl_devices
[0]);
2216 #ifdef DFE_PING_TEST
2218 IFX_MEI_DMSG("ping test image size=%d\n", sizeof (arc_ahb_access_code
));
2219 memcpy ((u8
*) (DSL_DEV_PRIVATE(pDev
)->
2220 adsl_mem_info
[0].address
+ 0x1004),
2221 &arc_ahb_access_code
[0], sizeof (arc_ahb_access_code
));
2222 load_jump_table (0x80000 + 0x1004);
2224 #endif //DFE_PING_TEST
2226 IFX_MEI_DMSG("ARC ping test code download complete\n");
2227 #endif //defined( DFE_PING_TEST )|| defined( DFE_ATM_LOOPBACK)
2229 IFX_MEI_LongWordWriteOffset (&dsl_devices
[0], (u32
) ME_ARC2ME_MASK
, MSGAV_EN
);
2231 arc_code_page_download (1537, &code_array
[0]);
2232 IFX_MEI_DMSG("ARC mem test code download complete\n");
2233 #endif //DFE_MEM_TEST
2234 #ifdef DFE_ATM_LOOPBACK
2235 arc_debug_data
= 0xf;
2236 arc_code_page_download (sizeof(code_array
) / sizeof(*code_array
), &code_array
[0]);
2237 wr_mbox
[0] = 0; //TIMER_DELAY - org: 1024
2238 wr_mbox
[1] = 0; //TXFB_START0
2239 wr_mbox
[2] = 0x7f; //TXFB_END0 - org: 49
2240 wr_mbox
[3] = 0x80; //TXFB_START1 - org: 80
2241 wr_mbox
[4] = 0xff; //TXFB_END1 - org: 109
2242 wr_mbox
[5] = 0x100; //RXFB_START0 - org: 0
2243 wr_mbox
[6] = 0x17f; //RXFB_END0 - org: 49
2244 wr_mbox
[7] = 0x180; //RXFB_START1 - org: 256
2245 wr_mbox
[8] = 0x1ff; //RXFB_END1 - org: 315
2246 WriteMbox (&wr_mbox
[0], 9);
2247 // Start Iridia IT_AMODE (in dmp access) why is it required?
2248 IFX_MEI_DebugWrite (&dsl_devices
[0], 0x32010, &arc_debug_data
, 1);
2249 #endif //DFE_ATM_LOOPBACK
2250 IFX_MEI_IRQEnable (pDev
);
2251 IFX_MEI_DMSG("run ARC...\n");
2252 IFX_MEI_RunArc (&dsl_devices
[0]);
2254 #ifdef DFE_PING_TEST
2255 arc_ping_testing (pDev
);
2256 #endif //DFE_PING_TEST
2258 wait_mem_test_result ();
2259 #endif //DFE_MEM_TEST
2261 IFX_MEI_DFEMemoryFree (pDev
, FREE_ALL
);
2262 return DSL_DEV_MEI_ERR_SUCCESS
;
2265 #endif //CONFIG_AMAZON_S_MEI_FW_LOOPBACK
2268 IFX_MEI_InitDevNode (int num
)
2271 if ((dev_major
= register_chrdev (dev_major
, IFX_MEI_DEVNAME
, &bsp_mei_operations
)) < 0) {
2272 IFX_MEI_EMSG ("register_chrdev(%d %s) failed!\n", dev_major
, IFX_MEI_DEVNAME
);
2280 IFX_MEI_CleanUpDevNode (int num
)
2283 unregister_chrdev (dev_major
, MEI_DIRNAME
);
2288 IFX_MEI_InitDevice (int num
)
2290 DSL_DEV_Device_t
*pDev
;
2292 pDev
= &dsl_devices
[num
];
2295 pDev
->pPriv
= &sDanube_Mei_Private
[num
];
2296 memset (pDev
->pPriv
, 0, sizeof (ifx_mei_device_private_t
));
2298 memset (&DSL_DEV_PRIVATE(pDev
)->
2299 adsl_mem_info
[0], 0,
2300 sizeof (smmu_mem_info_t
) * MAX_BAR_REGISTERS
);
2303 pDev
->nIrq
[IFX_DFEIR
] = LTQ_MEI_INT
;
2304 pDev
->nIrq
[IFX_DYING_GASP
] = LTQ_MEI_DYING_GASP_INT
;
2305 pDev
->base_address
= KSEG1
+ LTQ_MEI_BASE_ADDR
;
2308 #ifdef CONFIG_LANTIQ_AMAZON_SE
2309 *LTQ_PMU_PWDCR
&= ~(1 << 9); // enable dsl
2310 *LTQ_PMU_PWDCR
&= ~(1 << 15); // enable AHB base
2312 temp
= ltq_r32(LTQ_PMU_PWDCR
);
2314 ltq_w32(temp
, LTQ_PMU_PWDCR
);
2317 DSL_DEV_PRIVATE(pDev
)->modem_ready
= 0;
2318 DSL_DEV_PRIVATE(pDev
)->arcmsgav
= 0;
2320 MEI_INIT_WAKELIST ("arcq", DSL_DEV_PRIVATE(pDev
)->wait_queue_arcmsgav
); // for ARCMSGAV
2321 MEI_INIT_WAKELIST ("arcr", DSL_DEV_PRIVATE(pDev
)->wait_queue_modemready
); // for arc modem ready
2323 MEI_MUTEX_INIT (DSL_DEV_PRIVATE(pDev
)->mei_cmv_sema
, 1); // semaphore initialization, mutex
2325 MEI_MASK_AND_ACK_IRQ (pDev
->nIrq
[IFX_DFEIR
]);
2326 MEI_MASK_AND_ACK_IRQ (pDev
->nIrq
[IFX_DYING_GASP
]);
2328 if (request_irq (pDev
->nIrq
[IFX_DFEIR
], IFX_MEI_IrqHandle
, 0, "DFEIR", pDev
) != 0) {
2329 IFX_MEI_EMSG ("request_irq %d failed!\n", pDev
->nIrq
[IFX_DFEIR
]);
2332 /*if (request_irq (pDev->nIrq[IFX_DYING_GASP], IFX_MEI_Dying_Gasp_IrqHandle, 0, "DYING_GASP", pDev) != 0) {
2333 IFX_MEI_EMSG ("request_irq %d failed!\n", pDev->nIrq[IFX_DYING_GASP]);
2336 // IFX_MEI_DMSG("Device %d initialized. IER %#x\n", num, bsp_get_irq_ier(pDev->nIrq[IFX_DYING_GASP]));
2341 IFX_MEI_ExitDevice (int num
)
2343 DSL_DEV_Device_t
*pDev
;
2344 pDev
= &dsl_devices
[num
];
2349 disable_irq (pDev
->nIrq
[IFX_DFEIR
]);
2350 disable_irq (pDev
->nIrq
[IFX_DYING_GASP
]);
2352 free_irq(pDev
->nIrq
[IFX_DFEIR
], pDev
);
2353 free_irq(pDev
->nIrq
[IFX_DYING_GASP
], pDev
);
2358 static DSL_DEV_Device_t
*
2359 IFX_BSP_HandleGet (int maj
, int num
)
2361 if (num
> BSP_MAX_DEVICES
)
2363 return &dsl_devices
[num
];
2367 DSL_BSP_DriverHandleGet (int maj
, int num
)
2369 DSL_DEV_Device_t
*pDev
;
2371 if (num
> BSP_MAX_DEVICES
)
2374 pDev
= &dsl_devices
[num
];
2375 if (!try_module_get(pDev
->owner
))
2383 DSL_BSP_DriverHandleDelete (DSL_DEV_Device_t
* nHandle
)
2385 DSL_DEV_Device_t
*pDev
= (DSL_DEV_Device_t
*) nHandle
;
2388 module_put(pDev
->owner
);
2393 IFX_MEI_Open (DSL_DRV_inode_t
* ino
, DSL_DRV_file_t
* fil
)
2395 int maj
= MAJOR (ino
->i_rdev
);
2396 int num
= MINOR (ino
->i_rdev
);
2398 DSL_DEV_Device_t
*pDev
= NULL
;
2399 if ((pDev
= DSL_BSP_DriverHandleGet (maj
, num
)) == NULL
) {
2400 IFX_MEI_EMSG("open(%d:%d) fail!\n", maj
, num
);
2403 fil
->private_data
= pDev
;
2408 IFX_MEI_Release (DSL_DRV_inode_t
* ino
, DSL_DRV_file_t
* fil
)
2410 //int maj = MAJOR(ino->i_rdev);
2411 int num
= MINOR (ino
->i_rdev
);
2412 DSL_DEV_Device_t
*pDev
;
2414 pDev
= &dsl_devices
[num
];
2417 DSL_BSP_DriverHandleDelete (pDev
);
2422 * Callback function for linux userspace program writing
2425 IFX_MEI_Write (DSL_DRV_file_t
* filp
, const char *buf
, size_t size
, loff_t
* loff
)
2427 DSL_DEV_MeiError_t mei_error
= DSL_DEV_MEI_ERR_FAILURE
;
2429 DSL_DEV_Device_t
*pDev
= (DSL_DEV_Device_t
*) filp
->private_data
;
2435 DSL_BSP_FWDownload (pDev
, buf
, size
, (long *) loff
, &offset
);
2437 if (mei_error
== DSL_DEV_MEI_ERR_FAILURE
)
2439 return (ssize_t
) offset
;
2443 * Callback function for linux userspace program ioctling
2446 IFX_MEI_IoctlCopyFrom (int from_kernel
, char *dest
, char *from
, int size
)
2451 ret
= copy_from_user ((char *) dest
, (char *) from
, size
);
2453 ret
= (int)memcpy ((char *) dest
, (char *) from
, size
);
2458 IFX_MEI_IoctlCopyTo (int from_kernel
, char *dest
, char *from
, int size
)
2463 ret
= copy_to_user ((char *) dest
, (char *) from
, size
);
2465 ret
= (int)memcpy ((char *) dest
, (char *) from
, size
);
2470 IFX_MEI_Ioctls (DSL_DEV_Device_t
* pDev
, int from_kernel
, unsigned int command
, unsigned long lon
)
2473 int meierr
= DSL_DEV_MEI_ERR_SUCCESS
;
2474 u32 base_address
= LTQ_MEI_BASE_ADDR
;
2475 DSL_DEV_WinHost_Message_t winhost_msg
, m
;
2476 // DSL_DEV_MeiDebug_t debugrdwr;
2477 DSL_DEV_MeiReg_t regrdwr
;
2481 case DSL_FIO_BSP_CMV_WINHOST
:
2482 IFX_MEI_IoctlCopyFrom (from_kernel
, (char *) winhost_msg
.msg
.TxMessage
,
2483 (char *) lon
, MSG_LENGTH
* 2);
2485 if ((meierr
= DSL_BSP_SendCMV (pDev
, winhost_msg
.msg
.TxMessage
, YES_REPLY
,
2486 winhost_msg
.msg
.RxMessage
)) != DSL_DEV_MEI_ERR_SUCCESS
) {
2487 IFX_MEI_EMSG ("WINHOST CMV fail :TxMessage:%X %X %X %X, RxMessage:%X %X %X %X %X\n",
2488 winhost_msg
.msg
.TxMessage
[0], winhost_msg
.msg
.TxMessage
[1], winhost_msg
.msg
.TxMessage
[2], winhost_msg
.msg
.TxMessage
[3],
2489 winhost_msg
.msg
.RxMessage
[0], winhost_msg
.msg
.RxMessage
[1], winhost_msg
.msg
.RxMessage
[2], winhost_msg
.msg
.RxMessage
[3],
2490 winhost_msg
.msg
.RxMessage
[4]);
2491 meierr
= DSL_DEV_MEI_ERR_FAILURE
;
2494 IFX_MEI_IoctlCopyTo (from_kernel
, (char *) lon
,
2495 (char *) winhost_msg
.msg
.RxMessage
,
2500 case DSL_FIO_BSP_CMV_READ
:
2501 IFX_MEI_IoctlCopyFrom (from_kernel
, (char *) (®rdwr
),
2502 (char *) lon
, sizeof (DSL_DEV_MeiReg_t
));
2504 IFX_MEI_LongWordRead ((u32
) regrdwr
.iAddress
,
2505 (u32
*) & (regrdwr
.iData
));
2507 IFX_MEI_IoctlCopyTo (from_kernel
, (char *) lon
,
2508 (char *) (®rdwr
),
2509 sizeof (DSL_DEV_MeiReg_t
));
2513 case DSL_FIO_BSP_CMV_WRITE
:
2514 IFX_MEI_IoctlCopyFrom (from_kernel
, (char *) (®rdwr
),
2515 (char *) lon
, sizeof (DSL_DEV_MeiReg_t
));
2517 IFX_MEI_LongWordWrite ((u32
) regrdwr
.iAddress
,
2521 case DSL_FIO_BSP_GET_BASE_ADDRESS
:
2522 IFX_MEI_IoctlCopyTo (from_kernel
, (char *) lon
,
2523 (char *) (&base_address
),
2524 sizeof (base_address
));
2527 case DSL_FIO_BSP_IS_MODEM_READY
:
2528 i
= IFX_MEI_IsModemReady (pDev
);
2529 IFX_MEI_IoctlCopyTo (from_kernel
, (char *) lon
,
2530 (char *) (&i
), sizeof (int));
2531 meierr
= DSL_DEV_MEI_ERR_SUCCESS
;
2533 case DSL_FIO_BSP_RESET
:
2534 case DSL_FIO_BSP_REBOOT
:
2535 meierr
= IFX_MEI_CpuModeSet (pDev
, DSL_CPU_RESET
);
2536 meierr
= IFX_MEI_CpuModeSet (pDev
, DSL_CPU_HALT
);
2539 case DSL_FIO_BSP_HALT
:
2540 meierr
= IFX_MEI_CpuModeSet (pDev
, DSL_CPU_HALT
);
2543 case DSL_FIO_BSP_RUN
:
2544 meierr
= IFX_MEI_CpuModeSet (pDev
, DSL_CPU_RUN
);
2546 case DSL_FIO_BSP_BOOTDOWNLOAD
:
2547 meierr
= IFX_MEI_DownloadBootCode (pDev
);
2549 case DSL_FIO_BSP_JTAG_ENABLE
:
2550 meierr
= IFX_MEI_ArcJtagEnable (pDev
, 1);
2553 case DSL_FIO_BSP_REMOTE
:
2554 IFX_MEI_IoctlCopyFrom (from_kernel
, (char *) (&i
),
2555 (char *) lon
, sizeof (int));
2557 meierr
= IFX_MEI_AdslMailboxIRQEnable (pDev
, i
);
2560 case DSL_FIO_BSP_DSL_START
:
2561 IFX_MEI_DMSG("DSL_FIO_BSP_DSL_START\n");
2562 if ((meierr
= IFX_MEI_RunAdslModem (pDev
)) != DSL_DEV_MEI_ERR_SUCCESS
) {
2563 IFX_MEI_EMSG ("IFX_MEI_RunAdslModem() error...");
2564 meierr
= DSL_DEV_MEI_ERR_FAILURE
;
2568 /* case DSL_FIO_BSP_DEBUG_READ:
2569 case DSL_FIO_BSP_DEBUG_WRITE:
2570 IFX_MEI_IoctlCopyFrom (from_kernel,
2571 (char *) (&debugrdwr),
2573 sizeof (debugrdwr));
2575 if (command == DSL_FIO_BSP_DEBUG_READ)
2576 meierr = DSL_BSP_MemoryDebugAccess (pDev,
2577 DSL_BSP_MEMORY_READ,
2585 meierr = DSL_BSP_MemoryDebugAccess (pDev,
2586 DSL_BSP_MEMORY_WRITE,
2594 IFX_MEI_IoctlCopyTo (from_kernel, (char *) lon, (char *) (&debugrdwr), sizeof (debugrdwr));
2596 case DSL_FIO_BSP_GET_VERSION
:
2597 IFX_MEI_IoctlCopyTo (from_kernel
, (char *) lon
, (char *) (&bsp_mei_version
), sizeof (DSL_DEV_Version_t
));
2600 #define LTQ_MPS_CHIPID_VERSION_GET(value) (((value) >> 28) & ((1 << 4) - 1))
2601 case DSL_FIO_BSP_GET_CHIP_INFO
:
2602 bsp_chip_info
.major
= 1;
2603 bsp_chip_info
.minor
= LTQ_MPS_CHIPID_VERSION_GET(*LTQ_MPS_CHIPID
);
2604 IFX_MEI_IoctlCopyTo (from_kernel
, (char *) lon
, (char *) (&bsp_chip_info
), sizeof (DSL_DEV_HwVersion_t
));
2605 meierr
= DSL_DEV_MEI_ERR_SUCCESS
;
2608 case DSL_FIO_BSP_FREE_RESOURCE
:
2609 makeCMV (H2D_CMV_READ
, DSL_CMV_GROUP_STAT
, 4, 0, 1, NULL
, m
.msg
.TxMessage
);
2610 if (DSL_BSP_SendCMV (pDev
, m
.msg
.TxMessage
, YES_REPLY
, m
.msg
.RxMessage
) != DSL_DEV_MEI_ERR_SUCCESS
) {
2611 meierr
= DSL_DEV_MEI_ERR_FAILURE
;
2614 IFX_MEI_DMSG("RxMessage[4] = %#x\n", m
.msg
.RxMessage
[4]);
2615 if (!(m
.msg
.RxMessage
[4] & DSL_DEV_STAT_CODESWAP_COMPLETE
)) {
2616 meierr
= DSL_DEV_MEI_ERR_FAILURE
;
2619 IFX_MEI_DMSG("Freeing all memories marked FREE_SHOWTIME\n");
2620 IFX_MEI_DFEMemoryFree (pDev
, FREE_SHOWTIME
);
2621 meierr
= DSL_DEV_MEI_ERR_SUCCESS
;
2623 #ifdef CONFIG_IFXMIPS_AMAZON_SE
2624 case DSL_FIO_ARC_MUX_TEST
:
2625 AMAZON_SE_MEI_ARC_MUX_Test();
2629 // IFX_MEI_EMSG("Invalid IOCTL command: %d\n");
2635 #ifdef CONFIG_IFXMIPS_AMAZON_SE
2636 void AMAZON_SE_MEI_ARC_MUX_Test(void)
2639 *LTQ_RCU_RST
|= LTQ_RCU_RST_REQ_MUX_ARC
;
2641 p
= (u32
*)(DFE_LDST_BASE_ADDR
+ IRAM0_BASE
);
2642 IFX_MEI_EMSG("Writing to IRAM0(%p)...\n", p
);
2643 for (i
= 0; i
< IRAM0_SIZE
/sizeof(u32
); i
++, p
++) {
2645 if (*p
!= 0xdeadbeef)
2646 IFX_MEI_EMSG("%p: %#x\n", p
, *p
);
2649 p
= (u32
*)(DFE_LDST_BASE_ADDR
+ IRAM1_BASE
);
2650 IFX_MEI_EMSG("Writing to IRAM1(%p)...\n", p
);
2651 for (i
= 0; i
< IRAM1_SIZE
/sizeof(u32
); i
++, p
++) {
2653 if (*p
!= 0xdeadbeef)
2654 IFX_MEI_EMSG("%p: %#x\n", p
, *p
);
2657 p
= (u32
*)(DFE_LDST_BASE_ADDR
+ BRAM_BASE
);
2658 IFX_MEI_EMSG("Writing to BRAM(%p)...\n", p
);
2659 for (i
= 0; i
< BRAM_SIZE
/sizeof(u32
); i
++, p
++) {
2661 if (*p
!= 0xdeadbeef)
2662 IFX_MEI_EMSG("%p: %#x\n", p
, *p
);
2665 p
= (u32
*)(DFE_LDST_BASE_ADDR
+ XRAM_BASE
);
2666 IFX_MEI_EMSG("Writing to XRAM(%p)...\n", p
);
2667 for (i
= 0; i
< XRAM_SIZE
/sizeof(u32
); i
++, p
++) {
2669 if (*p
!= 0xdeadbeef)
2670 IFX_MEI_EMSG("%p: %#x\n", p
, *p
);
2673 p
= (u32
*)(DFE_LDST_BASE_ADDR
+ YRAM_BASE
);
2674 IFX_MEI_EMSG("Writing to YRAM(%p)...\n", p
);
2675 for (i
= 0; i
< YRAM_SIZE
/sizeof(u32
); i
++, p
++) {
2677 if (*p
!= 0xdeadbeef)
2678 IFX_MEI_EMSG("%p: %#x\n", p
, *p
);
2681 p
= (u32
*)(DFE_LDST_BASE_ADDR
+ EXT_MEM_BASE
);
2682 IFX_MEI_EMSG("Writing to EXT_MEM(%p)...\n", p
);
2683 for (i
= 0; i
< EXT_MEM_SIZE
/sizeof(u32
); i
++, p
++) {
2685 if (*p
!= 0xdeadbeef)
2686 IFX_MEI_EMSG("%p: %#x\n", p
, *p
);
2688 *LTQ_RCU_RST
&= ~LTQ_RCU_RST_REQ_MUX_ARC
;
2692 DSL_BSP_KernelIoctls (DSL_DEV_Device_t
* pDev
, unsigned int command
,
2697 error
= IFX_MEI_Ioctls (pDev
, 1, command
, lon
);
2702 IFX_MEI_UserIoctls (DSL_DRV_file_t
* fil
,
2703 unsigned int command
, unsigned long lon
)
2706 DSL_DEV_Device_t
*pDev
;
2708 pDev
= IFX_BSP_HandleGet (0, 0);
2712 error
= IFX_MEI_Ioctls (pDev
, 0, command
, lon
);
2716 static int adsl_dummy_ledcallback(void)
2721 int ifx_mei_atm_led_blink(void)
2723 return g_adsl_ledcallback();
2725 EXPORT_SYMBOL(ifx_mei_atm_led_blink
);
2727 int ifx_mei_atm_showtime_check(int *is_showtime
, struct port_cell_info
*port_cell
, void **xdata_addr
)
2731 if ( is_showtime
) {
2732 *is_showtime
= g_tx_link_rate
[0] == 0 && g_tx_link_rate
[1] == 0 ? 0 : 1;
2736 for ( i
= 0; i
< port_cell
->port_num
&& i
< 2; i
++ )
2737 port_cell
->tx_link_rate
[i
] = g_tx_link_rate
[i
];
2741 if ( g_tx_link_rate
[0] == 0 && g_tx_link_rate
[1] == 0 )
2744 *xdata_addr
= g_xdata_addr
;
2749 EXPORT_SYMBOL(ifx_mei_atm_showtime_check
);
2752 * Writing function for linux proc filesystem
2754 static int ltq_mei_probe(struct platform_device
*pdev
)
2757 static struct class *dsl_class
;
2759 pr_info("IFX MEI Version %ld.%02ld.%02ld\n", bsp_mei_version
.major
, bsp_mei_version
.minor
, bsp_mei_version
.revision
);
2761 for (i
= 0; i
< BSP_MAX_DEVICES
; i
++) {
2762 if (IFX_MEI_InitDevice (i
) != 0) {
2763 IFX_MEI_EMSG("Init device fail!\n");
2766 IFX_MEI_InitDevNode (i
);
2768 for (i
= 0; i
<= DSL_BSP_CB_LAST
; i
++)
2769 dsl_bsp_event_callback
[i
].function
= NULL
;
2771 #ifdef CONFIG_LTQ_MEI_FW_LOOPBACK
2772 IFX_MEI_DMSG("Start loopback test...\n");
2773 DFE_Loopback_Test ();
2775 dsl_class
= class_create(THIS_MODULE
, "ifx_mei");
2776 device_create(dsl_class
, NULL
, MKDEV(MEI_MAJOR
, 0), NULL
, "ifx_mei");
2780 static int ltq_mei_remove(struct platform_device
*pdev
)
2785 for (num
= 0; num
< BSP_MAX_DEVICES
; num
++) {
2786 IFX_MEI_CleanUpDevNode (num
);
2789 for (i
= 0; i
< BSP_MAX_DEVICES
; i
++) {
2790 for (i
= 0; i
< BSP_MAX_DEVICES
; i
++) {
2791 IFX_MEI_ExitDevice (i
);
2797 static const struct of_device_id ltq_mei_match
[] = {
2798 { .compatible
= "lantiq,mei-xway"},
2802 static struct platform_driver ltq_mei_driver
= {
2803 .probe
= ltq_mei_probe
,
2804 .remove
= ltq_mei_remove
,
2806 .name
= "lantiq,mei-xway",
2807 .owner
= THIS_MODULE
,
2808 .of_match_table
= ltq_mei_match
,
2812 module_platform_driver(ltq_mei_driver
);
2814 /* export function for DSL Driver */
2816 /* The functions of MEI_DriverHandleGet and MEI_DriverHandleDelete are
2817 something like open/close in kernel space , where the open could be used
2818 to register a callback for autonomous messages and returns a mei driver context pointer (comparable to the file descriptor in user space)
2819 The context will be required for the multi line chips future! */
2821 EXPORT_SYMBOL (DSL_BSP_DriverHandleGet
);
2822 EXPORT_SYMBOL (DSL_BSP_DriverHandleDelete
);
2824 EXPORT_SYMBOL (DSL_BSP_ATMLedCBRegister
);
2825 EXPORT_SYMBOL (DSL_BSP_ATMLedCBUnregister
);
2826 EXPORT_SYMBOL (DSL_BSP_KernelIoctls
);
2827 EXPORT_SYMBOL (DSL_BSP_AdslLedInit
);
2828 //EXPORT_SYMBOL (DSL_BSP_AdslLedSet);
2829 EXPORT_SYMBOL (DSL_BSP_FWDownload
);
2830 EXPORT_SYMBOL (DSL_BSP_Showtime
);
2832 EXPORT_SYMBOL (DSL_BSP_MemoryDebugAccess
);
2833 EXPORT_SYMBOL (DSL_BSP_SendCMV
);
2835 // provide a register/unregister function for DSL driver to register a event callback function
2836 EXPORT_SYMBOL (DSL_BSP_EventCBRegister
);
2837 EXPORT_SYMBOL (DSL_BSP_EventCBUnregister
);
2839 MODULE_LICENSE("Dual BSD/GPL");