path: root/Documentation/arm/Sharp-LH
diff options
Diffstat (limited to 'Documentation/arm/Sharp-LH')
7 files changed, 247 insertions, 0 deletions
diff --git a/Documentation/arm/Sharp-LH/CompactFlash b/Documentation/arm/Sharp-LH/CompactFlash
new file mode 100644
index 000000000000..8616d877df9e
--- /dev/null
+++ b/Documentation/arm/Sharp-LH/CompactFlash
@@ -0,0 +1,32 @@
+README on the Compact Flash for Card Engines
+There are three challenges in supporting the CF interface of the Card
+Engines. First, every IO operation must be followed with IO to
+another memory region. Second, the slot is wired for one-to-one
+address mapping *and* it is wired for 16 bit access only. Second, the
+interrupt request line from the CF device isn't wired.
+The IOBARRIER issue is covered in README.IOBARRIER. This isn't an
+onerous problem. Enough said here.
+The addressing issue is solved in the
+arch/arm/mach-lh7a40x/ide-lpd7a40x.c file with some awkward
+work-arounds. We implement a special SELECT_DRIVE routine that is
+called before the IDE driver performs its own SELECT_DRIVE. Our code
+recognizes that the SELECT register cannot be modified without also
+writing a command. It send an IDLE_IMMEDIATE command on selecting a
+drive. The function also prevents drive select to the slave drive
+since there can be only one. The awkward part is that the IDE driver,
+even though we have a select procedure, also attempts to change the
+drive by writing directly the SELECT register. This attempt is
+explicitly blocked by the OUTB function--not pretty, but effective.
+The lack of interrupts is a more serious problem. Even though the CF
+card is fast when compared to a normal IDE device, we don't know that
+the CF is really flash. A user could use one of the very small hard
+drives being shipped with a CF interface. The IDE code includes a
+check for interfaces that lack an IRQ. In these cases, submitting a
+command to the IDE controller is followed by a call to poll for
+completion. If the device isn't immediately ready, it schedules a
+timer to poll again later.
diff --git a/Documentation/arm/Sharp-LH/IOBarrier b/Documentation/arm/Sharp-LH/IOBarrier
new file mode 100644
index 000000000000..c0d8853672dc
--- /dev/null
+++ b/Documentation/arm/Sharp-LH/IOBarrier
@@ -0,0 +1,45 @@
+README on the IOBARRIER for CardEngine IO
+Due to an unfortunate oversight when the Card Engines were designed,
+the signals that control access to some peripherals, most notably the
+SMC91C9111 ethernet controller, are not properly handled.
+The symptom is that some back to back IO with the peripheral returns
+unreliable data. With the SMC chip, you'll see errors about the bank
+register being 'screwed'.
+The cause is that the AEN signal to the SMC chip does not transition
+for every memory access. It is driven through the CPLD from the CS7
+line of the CPU's static memory controller which is optimized to
+eliminate unnecessary transitions. Yet, the SMC requires a transition
+for every write access. The Sharp website has more information about
+the effect this power-conserving feature has on peripheral
+The solution is to follow every write access to the SMC chip with an
+access to another memory region that will force the CPU to release the
+chip select line. It is important to guarantee that this access
+forces the CPU off-chip. We map a page of SDRAM as if it were an
+uncacheable IO device and read from it after every SMC IO write
+Only this sequence is important. It does not matter that there is no
+BARRIER IO before the access to the SMC chip because the AEN latch
+only needs occurs after the SMC IO write cycle. The routines that
+implement this work-around make an additional concession which is to
+disable interrupts during the IO sequence. Other hardware devices
+(the LogicPD CPLD) have registers in the same the physical memory
+region as the SMC chip. An interrupt might allow an access to one of
+those registers while SMC IO is being performed.
+You might be tempted to think that we have to access another device
+attached to the static memory controller, but the empirical evidence
+indicates that this is not so. Mapping 0x00000000 (flash) and
+0xc0000000 (SDRAM) appear to have the same effect. Using SDRAM seems
+to be faster. Choosing to access an undecoded memory region is not
+desirable as there is no way to know how that chip select will be used
+in the future.
diff --git a/Documentation/arm/Sharp-LH/KEV7A400 b/Documentation/arm/Sharp-LH/KEV7A400
new file mode 100644
index 000000000000..be32b14cd535
--- /dev/null
+++ b/Documentation/arm/Sharp-LH/KEV7A400
@@ -0,0 +1,8 @@
+README on Implementing Linux for Sharp's KEV7a400
+This product has been discontinued by Sharp. For the time being, the
+partially implemented code remains in the kernel. At some point in
+the future, either the code will be finished or it will be removed
+completely. This depends primarily on how many of the development
+boards are in the field.
diff --git a/Documentation/arm/Sharp-LH/LPD7A400 b/Documentation/arm/Sharp-LH/LPD7A400
new file mode 100644
index 000000000000..3275b453bfdf
--- /dev/null
+++ b/Documentation/arm/Sharp-LH/LPD7A400
@@ -0,0 +1,15 @@
+README on Implementing Linux for the Logic PD LPD7A400-10
+- CPLD memory mapping
+ The board designers chose to use high address lines for controlling
+ access to the CPLD registers. It turns out to be a big waste
+ because we're using an MMU and must map IO space into virtual
+ memory. The result is that we have to make a mapping for every
+ register.
+- Serial Console
+ It may be OK not to use the serial console option if the user passes
+ the console device name to the kernel. This deserves some exploration.
diff --git a/Documentation/arm/Sharp-LH/LPD7A40X b/Documentation/arm/Sharp-LH/LPD7A40X
new file mode 100644
index 000000000000..8c29a27e208f
--- /dev/null
+++ b/Documentation/arm/Sharp-LH/LPD7A40X
@@ -0,0 +1,16 @@
+README on Implementing Linux for the Logic PD LPD7A40X-10
+- CPLD memory mapping
+ The board designers chose to use high address lines for controlling
+ access to the CPLD registers. It turns out to be a big waste
+ because we're using an MMU and must map IO space into virtual
+ memory. The result is that we have to make a mapping for every
+ register.
+- Serial Console
+ It may be OK not to use the serial console option if the user passes
+ the console device name to the kernel. This deserves some exploration.
diff --git a/Documentation/arm/Sharp-LH/SDRAM b/Documentation/arm/Sharp-LH/SDRAM
new file mode 100644
index 000000000000..93ddc23c2faa
--- /dev/null
+++ b/Documentation/arm/Sharp-LH/SDRAM
@@ -0,0 +1,51 @@
+README on the SDRAM Controller for the LH7a40X
+The standard configuration for the SDRAM controller generates a sparse
+memory array. The precise layout is determined by the SDRAM chips. A
+default kernel configuration assembles the discontiguous memory
+regions into separate memory nodes via the NUMA (Non-Uniform Memory
+Architecture) facilities. In this default configuration, the kernel
+is forgiving about the precise layout. As long as it is given an
+accurate picture of available memory by the bootloader the kernel will
+execute correctly.
+The SDRC supports a mode where some of the chip select lines are
+swapped in order to make SDRAM look like a synchronous ROM. Setting
+this bit means that the RAM will present as a contiguous array. Some
+programmers prefer this to the discontiguous layout. Be aware that
+may be a penalty for this feature where some some configurations of
+memory are significantly reduced; i.e. 64MiB of RAM appears as only 32
+There are a couple of configuration options to override the default
+behavior. When the SROMLL bit is set and memory appears as a
+contiguous array, there is no reason to support NUMA.
+CONFIG_LH7A40X_CONTIGMEM disables NUMA support. When physical memory
+is discontiguous, the memory tables are organized such that there are
+two banks per nodes with a small gap between them. This layout wastes
+some kernel memory for page tables representing non-existent memory.
+CONFIG_LH7A40X_ONE_BANK_PER_NODE optimizes the node tables such that
+there are no gaps. These options control the low level organization
+of the memory management tables in ways that may prevent the kernel
+from booting or may cause the kernel to allocated excessively large
+page tables. Be warned. Only change these options if you know what
+you are doing. The default behavior is a reasonable compromise that
+will suit all users.
+A typical 32MiB system with the default configuration options will
+find physical memory managed as follows.
+ node 0: 0xc0000000 4MiB
+ 0xc1000000 4MiB
+ node 1: 0xc4000000 4MiB
+ 0xc5000000 4MiB
+ node 2: 0xc8000000 4MiB
+ 0xc9000000 4MiB
+ node 3: 0xcc000000 4MiB
+ 0xcd000000 4MiB
+Setting CONFIG_LH7A40X_ONE_BANK_PER_NODE will put each bank into a
+separate node.
diff --git a/Documentation/arm/Sharp-LH/VectoredInterruptController b/Documentation/arm/Sharp-LH/VectoredInterruptController
new file mode 100644
index 000000000000..23047e9861ee
--- /dev/null
+++ b/Documentation/arm/Sharp-LH/VectoredInterruptController
@@ -0,0 +1,80 @@
+README on the Vectored Interrupt Controller of the LH7A404
+The 404 revision of the LH7A40X series comes with two vectored
+interrupts controllers. While the kernel does use some of the
+features of these devices, it is far from the purpose for which they
+were designed.
+When this README was written, the implementation of the VICs was in
+flux. It is possible that some details, especially with priorities,
+will change.
+The VIC support code is inspired by routines written by Sharp.
+Priority Control
+The significant reason for using the VIC's vectoring is to control
+interrupt priorities. There are two tables in
+arch/arm/mach-lh7a40x/irq-lh7a404.c that look something like this.
+ static unsigned char irq_pri_vic1[] = { IRQ_GPIO3INTR, };
+ static unsigned char irq_pri_vic2[] = {
+The initialization code reads these tables and inserts a vector
+address and enable for each indicated IRQ. Vectored interrupts have
+higher priority than non-vectored interrupts. So, on VIC1,
+IRQ_GPIO3INTR will be served before any other non-FIQ interrupt. Due
+to the way that the vectoring works, IRQ_T3UI is the next highest
+priority followed by the other vectored interrupts on VIC2. After
+that, the non-vectored interrupts are scanned in VIC1 then in VIC2.
+The interrupt service routine macro get_irqnr() in
+arch/arm/kernel/entry-armv.S scans the VICs for the next active
+interrupt. The vectoring makes this code somewhat larger than it was
+before using vectoring (refer to the LH7A400 implementation). In the
+case where an interrupt is vectored, the implementation will tend to
+be faster than the non-vectored version. However, the worst-case path
+is longer.
+It is worth noting that at present, there is no need to read
+VIC2_VECTADDR because the register appears to be shared between the
+controllers. The code is written such that if this changes, it ought
+to still work properly.
+Vector Addresses
+The proper use of the vectoring hardware would jump to the ISR
+specified by the vectoring address. Linux isn't structured to take
+advantage of this feature, though it might be possible to change
+things to support it.
+In this implementation, the vectoring address is used to speed the
+search for the active IRQ. The address is coded such that the lowest
+6 bits store the IRQ number for vectored interrupts. These numbers
+correspond to the bits in the interrupt status registers. IRQ zero is
+the lowest interrupt bit in VIC1. IRQ 32 is the lowest interrupt bit
+in VIC2. Because zero is a valid IRQ number and because we cannot
+detect whether or not there is a valid vectoring address if that
+address is zero, the eigth bit (0x100) is set for vectored interrupts.
+The address for IRQ 0x18 (VIC2) is 0x118. Only the ninth bit is set
+for the default handler on VIC1 and only the tenth bit is set for the
+default handler on VIC2.
+In other words.
+ 0x000 - no active interrupt
+ 0x1ii - vectored interrupt 0xii
+ 0x2xx - unvectored interrupt on VIC1 (xx is don't care)
+ 0x4xx - unvectored interrupt on VIC2 (xx is don't care)