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

Reply via email to