Hi all, Some background: I'm trying to use the mcf_qspi driver on an MCF5275 with 2.6.x. Originally, I had some problems compiling it, but after a bit of hacking, it's compiling and initializing at boot. I've created a /dev/qspi node in the ROMFS, and open() and ioctl() seem to be working. While testing the driver, however, I'm running into some problems. Namely:
1) When qspi_internal_write() is called, things proceed as they should (for a while), but I can't get a blessed thing to show on an oscope. Through the use of printk I can see the SPE bit being set in the QDLYR register (by the driver), and two lines later, it has been cleared by the QSPI module, which signals that the transfer is finished. During that time, nothing shows up on SCK or QSDO. 2) A couple lines later, sleep_on(&wqueue) puts the process to sleep (to wait for the qspi transfer to finish), and it never gets woken again. It seems that either the interrupt isn't reaching the driver, or that the interrupt never goes because the transfer doesn't finish (which doesn't make sense, seeing as how the SPE bit is cleared). This also happens in qspi_internal_read. Frankly, the best idea of I've got at the moment (and it's not a very good one, I know) is: 1) my scope is on the fritz 2) I've set the interrupt priority and level wrong. I wasn't sure what the level and priority should be, so I used level 5, priority 3 (which is used with the 5282). Can anyone clear that up? Should it be different? Also, request_irq uses SA_INTERRUPT... which doesn't seem to be defined in 2.6.x. I added my own define for what it was in 2.4.x, but should I be using something else? Since the driver was originally written for the 5272, not the 5275, I've of course made some changes. The QSPI write sequence for the 5275 detailed in the manual is exactly the same as the 5272, with the exception of setting up the CS pins (see below for my resultant change). It's very possible that I'm missing something though. I've tried to make a list of changes that I've made to the driver below for anyone's perusal. Eventually I could make an actual patch, but I would like to see it working first :-). In summary: 1) What should the priority and level be set to? 2) Should request_irq use something other than SA_INTERRUPT? 3) Any other ideas on why an interrupt doesn't wake the process after sleep_on(&wqueue)? 4) Any ideas on the non-activity on SCK and QSDO? I can give more details as needed. Thanks! -David Here's a breakdown of changes that I've made. If it doesn't shed any light, maybe it will help someone else down the road: ----------------------------------------------------------------------------------- In mcf_qspi.c: In qspi_internal_read: Changed two lines to make them generic: - *sp = *(volatile unsigned short *)(MCF_MBAR + MCFSIM_QDR); +*sp = QDR; - *cp = *(volatile unsigned short *)(MCF_MBAR + MCFSIM_QDR); + *cp = QDR; In static int init(void), added: #elif (defined(CONFIG_M5275)) /* set our IPL in ICR18 as level 5, priority 3 */ lp = (volatile u32 *)(MCF_IPSBAR + 0x00000C50); *lp = (*lp & 0xFFFF00FF) | 0x00005300; (Based on the M5272, but with different addresses, and without the unnecessary CS pin setup. Similar clearing of IPL in qspi_exit ) ----------------------------------------------------------------------------------- In linux-2.6.x/include/asm/mcf_qspi.h Added: #elif defined(CONFIG_M5275) #define MCFQSPI_IRQ_VECTOR 82 #define QSPIMOD_OFFSET 0x340 ....... #if defined(CONFIG_M5275) #define QMR *(volatile u16 *)(MCF_IPSBAR + MCFSIM_QMR) #define QAR *(volatile u16 *)(MCF_IPSBAR + MCFSIM_QAR) etc. (all the other processors seem to have QSPI addresses based on MCF_MBAR, the MCFSIM_ offsets are fine though) ------------------------------------------------------------------------------------- In ../include/asm/mcfqspi.h: Added a typedef for qspi_read_data, which should be there, but was inexplicably missing: typedef struct qspi_read_data { __u32 length; __u8 *buf; /* data to send during read */ unsigned int loop : 1; } qspi_read_data; Added some defines: #define SA_INTERRUPT 0x20000000 #define DEFAULT_BIT_RATE 0x00000002 and then copied a whole bunch more from the 2.4.x mcfqspi.h: #define DEFAULT_BIT_RATE 0x00000002 #define QSPIIOCS_DOUT_HIZ 1 /* QMR[DOHIE] set hi-z dout between transfers */ #define QSPIIOCS_BITS 2 /* QMR[BITS] set transfer size */ #define QSPIIOCG_BITS 3 /* QMR[BITS] get transfer size */ #define QSPIIOCS_CPOL 4 /* QMR[CPOL] set SCK inactive state */ #define QSPIIOCS_CPHA 5 /* QMR[CPHA] set SCK phase, 1=rising edge */ #define QSPIIOCS_BAUD 6 /* QMR[BAUD] set SCK baud rate divider */ #define QSPIIOCS_QCD 7 /* QDLYR[QCD] set start delay */ #define QSPIIOCS_DTL 8 /* QDLYR[DTL] set after delay */ #define QSPIIOCS_CONT 9 /* continuous CS asserted during transfer */ #define QSPIIOCS_READDATA 10 /* set data send during read */ #define QSPIIOCS_ODD_MOD 11 /* if length of buffer is a odd number, 16-bit transfers */ /* are finalized with a 8-bit transfer */ #define QSPIIOCS_DSP_MOD 12 /* transfers are bounded to 15/30 bytes (a multiple of 3 bytes = 1 DSP word) */ #define QSPIIOCS_POLL_MOD 13 /* driver uses polling instead of interrupts */ _______________________________________________ uClinux-dev mailing list uClinux-dev@uclinux.org http://mailman.uclinux.org/mailman/listinfo/uclinux-dev This message was resent by uclinux-dev@uclinux.org To unsubscribe see: http://mailman.uclinux.org/mailman/options/uclinux-dev