Further to discussions earlier this week, I've just been digging through the Loon 3 VHDL and kernel source with a view to tweaking the register layout to accommodate some new functions and turn some write-only registers into set/clear ones. Note that all these changes are independent of the eventual move to variable latency I/O. The programmable logic (CPLD or FPGA) occupies the physical addresses 0x1000000-0x13fffffc, enabled by nCS4. We divide this space into up to 256 'modules' of 64K each, decoded using the eight address lines A23..A16. However, the CPLD is short of pins and of these eight lines it only has access to A23, A22 and A21. This means that the CPLD can really only support 8 modules, but this is of little concern since it can accommodate far less logic than the FPGA. However, it means that in the CPLD's world, only the top 3 bits of the module number are significant. Within each module, only the bottom 12 bits of the address (A11..A0) are currently decoded. Of these bits, the CPLD can only see A10..A0. The only other address bit available to the CPLD is A12. There are at the moment two modules implemented in the logic. I'll refer to them by their module number, which is bits A23..A16. Module 0xc0 is the Samosa bus, and needs no change at this time. Module 0xe0 is the internal registers, currently laid out as follows, listed by address: 0x000 bidirectional: NAND Data bus 0x008 write: CF Control read: CF status 0x00c write: Interrupt mask read: interrupt status 0x010 write: NAND control 2 0x014 write: NAND control 0x01c write: general control read: version number Of these six registers, five of them (0x008, 0x00c, 0x010, 0x014 and 0x01c) can have values written to them but the values cannot be read back. This creates a problem when updating those registers: the only way to change single bits within them is to maintain a copy of the register in RAM, modify that, then copy it in to the hardware register. This is what the kernel currently does. This local-copy technique works but becomes hairy when the same register needs to be accessed from different parts of the kernel. For example, the general control register contains power management bits to do with both Samosa and NAND. The code dealing with these functions is in entirely different places in the kernel, and sharing a copy of a register between them is messy and potentially creates a concurrency problem. There are things we avoid doing, such as Samosa bus power management, which can at least partly be attributed to this. Making these registers directly readable is fairly expensive in terms of logic, and would also require the registers' existing 'read' functions to be remapped somewhere else. Commonly hardware registers use a set/clear approach, in which writing '1's to one address sets bits in a register, and writing '1's to another address clears bits. In this way bits can be changed either way in an atomic operation without affecting unwanted bits or needing any knowledge of them. The hardware also requires little logic. As luck would have it, there's an address line, A12, which is not currently decoded by the internal registers module, but is available in both the CPLD and FPGA. I propose to use this as a set/clear signal for the relevant registers, as I believe it requires the minimum amount of change. The resulting memory map would look like: 0x0000 bidirectional: NAND Data bus 0x0008 write: clear CF Control read: CF status 0x000c write: clear Interrupt mask read: interrupt status 0x0010 write: clear NAND control 2 0x0014 write: clear NAND control 0x001c write: clear general control read: version number 0x1000 bidirectional: NAND Data bus 0x1008 write: set CF Control read: CF status 0x100c write: set Interrupt mask read: interrupt status 0x1010 write: set NAND control 2 0x1014 write: set NAND control 0x101c write: set general control read: version number This has the useful property of maintaining the address of things like the version number, thus creating the minimum amount of confusion when software tries to talk to the wrong version of hardware. In addition, I propose giving the NAND control register at 0x0014/0x1014 a read function so that we can read various miscellaneous bits, most importantly NAND_RNB. These changes will affect the VHDL, kernel and bootldr, but will mean that: - Samosa power management becomes possible, which is critical for TCL - NAND power management can be improved, reducing standby power consumption - NAND access can be optimised hugely, because it will be possible to read the NAND_RNB bit rather than semi-relying on slow bus timings. - future changes and enhancements will also be easier to integrate into the logic. Chris -- Chris Jones - chris@martin-jones.com Martin-Jones Technology Ltd, makers of Solidlights 148 Catharine Street, Cambridge, CB1 3AR, UK Phone +44 (0) 1223 655611 Fax +44 (0) 870 112 3908 http://www.solidlights.co.uk/