Subject: Suspected 21285 deadlock?

From: Russell King - ARM Linux Admin <[email-masked]>
Date: Sat, 24 Apr 1999 18:54:51 +0100 (BST)

Hi,

Gotta small problem, which I'm hoping that people involved with building
systems around the DC21285 can shed some light on.

I've got a card with a CY82C693UB (South bridge) in my EBSA285, with an
ESS1879 sound chip on the 82C693's ISA bus.  The sound chip uses ISA DMA.
There is also a 3c592 net card on the PCI bus, Promise Ultra33 UDMA IDE
card, and an S3 Trio64V2 video card.

The problem I'm seeing is total deadlock of the SA110 when, eg, the
Ethernet is accessed while an ISA DMA is in progress to the sound chip.
I haven't tried DMAs to other devices yet.

When it deadlocks, the following always seems to be true:

1. SA110 address bus contains an address in the PCI I/O
   space of the DC21285.

2. The SA110 MCLK is held high.

3. ABE is high (address bus enabled).

4. DBE toggles.

5. The ISA DMA is still running, playing the same snippet of audio
   over and over again (since the SA110 can't update the SDRAM with the
   next block).  Hence, ISA -> PCI -> SA110 bus is still functional.

6. The PCI request and grant signals for the 82C693 are toggling.

7. The PCI request and grant signals for the DC21285 are also toggling.

8. Comparing these two grant signals, they appear to be anti-phase.

Note: other PCI masters appear to be ok.

The only way out of this state is a hardware reset.  I've tried swapping
the slot that the Promise and the Southbridge use, but that doesn't affect
it - it still deadlocks when doing ISA DMA.  I haven't yet checked to see
if this PCI I/O transaction that the SA110 is asking for is a read or a
write, but I should know that later tonight...

I suspect that this could be related to the Outbound write flush problem
(ie, issuing an outbound write flush to the DC21285 causes deadlock).
   _____
  |_____| ------------------------------------------------- ---+---+-
  |   |        Russell King       [email-masked]      --- ---
  | | | |  http://www.arm.linux.org.uk/~rmk/armlinux.html    /  /  |
  | +-+-+                                                     --- -+-
  /   |               THE developer of ARM Linux              |+| /|\
 /  | | |                                                     ---  |
    +-+-+ -------------------------------------------------  /\\\  |
unsubscribe: body of `unsubscribe linux-arm' to [email-masked]

---

From: Philip Blundell <[email-masked]>
Date: Sat, 24 Apr 1999 19:29:41 +0100

>(ie, issuing an outbound write flush to the DC21285 causes deadlock).

Wasn't the problem with outbound flush just that that functionality didn't 
actually get implemented?

It sounds like the 21285 is trying to perform some transaction on the bus 
either to satisfy a read or to unload its write FIFO (and it's stalled the 
SA110 while it does so) but it keeps getting a retry response.  Can you 
examine the PCI bus and see what's going on in terms of the address that the 
Footbridge asserts and the response it gets from the target?

I've never seen this on any of the machines I've worked on, but none of those 
have used the same southbridge that you've got.

p.

---

From: Russell King - ARM Linux Admin <[email-masked]>
Date: Sat, 24 Apr 1999 19:50:06 +0100 (BST)

>From what I remember reading, and from what Dave Gilberts' description
of what happened when he tried it with the tulip driver, I think it
does deadlock if attempted on rev. 01 21285s...

> Footbridge asserts and the response it gets from the target?

I'll try, but all my slots are full, and I can only get to the 'B' side
of the PCI connectors safely.  This means that I can get to all but 
CBE0, STOP, SDONE and TRDY signals.  I'll also reduce the bus speed
to make it easier on the poor 60MHz scope...
   _____
  |_____| ------------------------------------------------- ---+---+-
  |   |        Russell King       [email-masked]      --- ---
  | | | |  http://www.arm.linux.org.uk/~rmk/armlinux.html    /  /  |
  | +-+-+                                                     --- -+-
  /   |               THE developer of ARM Linux              |+| /|\
 /  | | |                                                     ---  |
    +-+-+ -------------------------------------------------  /\\\  |
unsubscribe: body of `unsubscribe linux-arm' to [email-masked]

---

From: Dave Baukus <[email-masked]>
Date: Mon, 26 Apr 1999 18:32:41 -0500

The definition of virt_to_bus() and bus_to_virt() for ebas285 on the
arm 2.2.2 ARM kernel are rather curious to me; The macros are as follows (from
linux/include/asm-arm/arch-ebsa285/mmu.h):

------------
/* On DEC21285-based machines, the dram is contiguous
 */
#define __virt_to_phys__is_a_macro
#define __virt_to_phys(vpage) ((unsigned long)(vpage) - PAGE_OFFSET)
#define __phys_to_virt__is_a_macro
#define __phys_to_virt(ppage) ((unsigned long)(ppage) + PAGE_OFFSET)
 
#define __virt_to_bus__is_a_macro
#define         ((x) - 0xe0000000)
#define __bus_to_virt__is_a_macro
#define __bus_to_virt(x)        ((x) + 0xe0000000)
------------

PAGE_OFFSET from some place else is 0xc0000000

__virt_to_phys() et.al. make sense; however, I loose it on __virt_to_bus()
et.al.  
I can't see anything mapped in at 0xe0000000.

Can somebody explain the difference between these 2 sets of macros.
I have an AMD driver that is using  __virt_to_bus on addresses returned from
kmalloc(). Thus, I get address manipulation such as:
		0xc000fxxx - 0xe0000000
This is either broken or way too slick for me.
Which is it ?

Thanks,
--
Dave Baukus
	Inet Technologies Inc.
	[email-masked]

---

From: Russell King - ARM Linux Admin <[email-masked]>
Date: Tue, 27 Apr 1999 10:01:30 +0100 (BST)

Dave Baukus writes:
> et.al.  I can't see anything mapped in at 0xe0000000.

Read on...

> Can somebody explain the difference between these 2 sets of macros.

You may want to read Documentation/IO-mapping.txt.  Basically:
  virt_to_phys converts an address as seen from the CPU
      (ie, 0xc0004000 - the address of the kernel page directory)
     to an address that is seen 'the other side of the page tables'
      (ie, 0x00004000 - the address that the CPU has to put on it's
       address pins to get the contents of that location.
  virt_to_bus converts an address as seen from the CPI
     to an address that is seen on the machine's IO bus

 Note: All of these translation functions are only valid on the
  kernel's mapping of the SDRAM.

> I have an AMD driver that is using  __virt_to_bus on addresses
> returned from kmalloc(). Thus, I get address manipulation such as:
> 		0xc000fxxx - 0xe0000000

It's slick.

The situation currently is:
  1. The SDRAM is mapped into PCI memory space at 0xe0000000
     This means that virtual address 0xc0000000 = PCI address 0xe0000000.
     Adding 0x20000000 or subtracting 0xe0000000 performs this
     translation.

  2. The PCI memory space is mapped into virtual address space at
     0xe0000000.  This is merely for compatability with some currently
     broken drivers, however, the same translation is true:
     PCI address 0 == virtual address space 0xe0000000.
     But note!  This should *not* be used!
   _____
  |_____| ------------------------------------------------- ---+---+-
  |   |        Russell King       [email-masked]      --- ---
  | | | |  http://www.arm.linux.org.uk/~rmk/armlinux.html    /  /  |
  | +-+-+                                                     --- -+-
  /   |               THE developer of ARM Linux              |+| /|\
 /  | | |                                                     ---  |
    +-+-+ -------------------------------------------------  /\\\  |
unsubscribe: body of `unsubscribe linux-arm' to [email-masked]