"slow" ports on MPC8255 ?
Wolfgang Denk
wd at denx.de
Wed Jun 18 06:47:03 EST 2003
Hi,
has anybody of you experienced problems with accesses to port data
registers on a MPC8255 yet?
The environment:
- CPU: MPC8255 Rev 14, Mask B.1 4K25A
- happens independend of CPU and CPM clock
(tried 300/200 Mhz and 166/133 MHz)
- happens in U-Boot and in Linux
The problem:
- writing port A data register (as 32 bit word) and then looping
reading it back will show that it takes some time for the write to
take effect, i. e. we can read the old value for some time and
then, bit for bit, the new value becomes visible.
Example code:
void foo (unsigned char data, int pos)
{
volatile unsigned int *datp =
&((immap_t *) CFG_IMMR)->im_ioport.iop_pdata;
unsigned int reg, tmp;
unsigned long cnt;
unsigned long buf[256];
cnt = 0;
reg = *datp;
buf[cnt] = reg;
reg &= ~(0xFF << (pos ? 0 : 8));
reg |= (data << (pos ? 0 : 8));
*datp = reg;
buf[++cnt] = reg;
__asm__ ("eieio;sync;isync");
while ((tmp = *datp) != reg) {
if (++cnt < 256)
buf[cnt] = tmp;
}
printf ("## %ld: %08lX -> %08lX:", cnt, buf[0], buf[1]);
for (tmp = 2; tmp <= cnt; ++tmp)
printf ("%08lX ", buf[tmp]);
printf ("##\n");
}
What I get is this:
## 7: FFDE039F -> FFDE0325:FFDE0305 FFDE0305 FFDE0305 FFDE0305 FFDE0305 FFDE0305 ##
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
## 6: FFDE0325 -> FFDE030D:FFDE0305 FFDE0305 FFDE0305 FFDE0305 FFDE0305 ##
## 7: FFDE030D -> FFDE0399:FFDE0309 FFDE0309 FFDE0309 FFDE0309 FFDE0389 FFDE0389 ##
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
## 7: FFDE0399 -> FFDE0349:FFDE0309 FFDE0309 FFDE0309 FFDE0309 FFDE0309 FFDE0309 ##
## 7: FFDE0341 -> FFDE031F:FFDE0301 FFDE0301 FFDE0301 FFDE0301 FFDE0301 FFDE030F ##
## 7: FFDE0301 -> FFDE0309:FFDE0301 FFDE0301 FFDE0301 FFDE0301 FFDE0301 FFDE0301 ##
## 7: FFDE0309 -> FFDE0311:FFDE0301 FFDE0301 FFDE0301 FFDE0301 FFDE0301 FFDE0301 ##
## 8: FFDE0311 -> FFDE03C1:FFDE0301 FFDE0301 FFDE0301 FFDE0301 FFDE0381 FFDE0381 FFDE0381 ##
## 8: FFDE03C1 -> FFDE0363:FFDE0341 FFDE0341 FFDE0341 FFDE0341 FFDE0341 FFDE0341 FFDE0361 ##
## 7: FFDE0363 -> FFDE0385:FFDE0301 FFDE0301 FFDE0301 FFDE0301 FFDE0381 FFDE0381 ##
## 7: FFDE0385 -> FFDE0361:FFDE0301 FFDE0301 FFDE0301 FFDE0301 FFDE0301 FFDE0321 ##
## 7: FFDE0361 -> FFDE0371:FFDE0361 FFDE0361 FFDE0361 FFDE0361 FFDE0361 FFDE0361 ##
## 6: FFDE0371 -> FFDE9F71:FFDE0371 FFDE0371 FFDE0371 FFDE0371 FFDE8371 ##
# 7: FFDE9F71 -> FFDE9F03:FFDE9F01 FFDE9F01 FFDE9F01 FFDE9F01 FFDE9F01 FFDE9F01 ##
## 7: FFDE9F03 -> FFDE9F9F:FFDE9F03 FFDE9F03 FFDE9F03 FFDE9F03 FFDE9F83 FFDE9F83 ##
## 7: FFDE9F9F -> FFDE9F25:FFDE9F05 FFDE9F05 FFDE9F05 FFDE9F05 FFDE9F05 FFDE9F05 ##
## 6: FFDE9F25 -> FFDE9F0D:FFDE9F05 FFDE9F05 FFDE9F05 FFDE9F05 FFDE9F05 ##
## 7: FFDE9F0D -> FFDE9F99:FFDE9F09 FFDE9F09 FFDE9F09 FFDE9F09 FFDE9F89 FFDE9F89 ##
## 7: FFDE9F99 -> FFDE9F49:FFDE9F09 FFDE9F09 FFDE9F09 FFDE9F09 FFDE9F09 FFDE9F09 ##
## 7: FFDE9F41 -> FFDE9F1F:FFDE9F01 FFDE9F01 FFDE9F01 FFDE9F01 FFDE9F01 FFDE9F05 ##
## 6: FFDE9F01 -> FFDE9F09:FFDE9F01 FFDE9F01 FFDE9F01 FFDE9F01 FFDE9F01 ##
## 6: FFDE9F09 -> FFDE9F11:FFDE9F01 FFDE9F01 FFDE9F01 FFDE9F01 FFDE9F01 ##
## 7: FFDE9F11 -> FFDE9FC1:FFDE9F01 FFDE9F01 FFDE9F01 FFDE9F01 FFDE9F01 FFDE9F81
If you look at the first marked (^^^) line the problem becomes obvious:
Port A data register contains FFDE039F and I'm writing a FFDE0325 to it.
The low 8 bits change from 9F -> 05 -> 25.
The second marked line is even more interesting: Here the register is
changing 0D -> 09 -> 89 -> 99.
eieio, sync and isync don't seem to have any effect. Also, I cannot
think of any cache effect that works like this.
To me it looks as if setting the register was implemented in the CPM
in microcode, and in a non-atomic way, and not synchronized against
accesses by the CPU.
Ummm... by the way: the same code runs perfectly fine on identical
hardware with a MPC8260 CPU.
Any ideas?
Wolfgang Denk
--
Software Engineering: Embedded and Realtime Systems, Embedded Linux
Phone: (+49)-8142-4596-87 Fax: (+49)-8142-4596-88 Email: wd at denx.de
One difference between a man and a machine is that a machine is quiet
when well oiled.
** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/
More information about the Linuxppc-dev
mailing list