[linux-cirrus] Memory mapping (virtual to physical) __virt_to_phys()

  • From: "Wagner Scott (ST-IN/ENG1.1)" <Scott.Wagner@xxxxxxxxxxxx>
  • To: <linux-cirrus@xxxxxxxxxxxxx>
  • Date: Mon, 18 Jun 2007 09:08:54 -0400

Hello all,

I have an EP9302 running Linux 2.6.14 and using the following memory
mapping:
 * 0xF200_0000 - 0xF2FF_FFFF      16 MB   0xfebfc000  nCS0     NAND
Flash Address 
 * 0xF100_0000 - 0xF1FF_FFFF      16 MB   0xfebfb000  nCS0     NAND
Flash Command 
 * 0xF000_0000 - 0xF0FF_FFFF      16 MB   0xfebfa000  nCS0     NAND
Flash Data 
 * 0xE000_0000 - 0xEFFF_FFFF      256 MB  0xc8000000  nSDCS2   SDRAM #2
 * 0xD000_0000 - 0xDFFF_FFFF      256 MB       -      nSDCS1   Unused
 * 0xC000_0000 - 0xCFFF_FFFF      256 MB       -      nSDCS0   Unused
 * 0x8080_0000 - 0x8FFF_FFFF      248 MB  0xE0800000  APB      EP9302
Peripherals
 * 0x8000_0000 - 0x800F_FFFF      1 MB    0xE0000000  AHB      EP9302
Peripherals
 * 0x7000_0000 - 0x7FFF_FFFF      256 MB       -      nCS7     Unused
 * 0x6000_0000 - 0x6FFF_FFFF      256 MB       -      nCS6     Unused
 * 0x4000_0000 - 0x4FFF_FFFF                                   Unused
 * 0x3000_0000 - 0x3000_00FF      256 B   0xfebf3000  nCS3
Peripheral 3
 * 0x2000_0000 - 0x2000_00FF      256 B   0xfebf2000  nCS2
Peripheral 2
 * 0x1000_0000 - 0x1000_00FF      256 B   0xfebf0000  nCS1
Peripheral 1
 * 0x0000_0000 - 0x0FFF_FFFF      256 MB  0xc0000000  nSDCS3   SDRAM #1

My problem is with the __virt_to_phys() macro in
./include/arch/arm/memory.h.  I have __phys_to_virt() mapping SDRAM
physical addresses 0x00nn_nnnn to vrtual 0xC0nn_nnnn for the low block;
0xE0nn_nnnn to 0xC8nn_nnnn for the low block.  I would expect that
__virt_to_phys() should map addresses 0xC0nn_nnnn to 0x00nn_nnnn for the
low block; 0xC8nn_nnnn to 0xE0nn_nnnn for the low block.

This does not do what I expect.  When I use this __virt_to_phys()
mapping, the EP9302 peripherals do not work (note that they are mapped
at virtual address 0xE0nn_nnnn).  If I have __virt_to_phys() map the
high block at C800_0000 to 4000_0000 (where there is nothing in either
virtual or physical space), everything seems to work OK.

I don't understand this.  First, why can't I do a V to P mapping back to
E0x?  The peripherals are at _virtual_ E0, not _physical_ E0.  Second,
why does lying and mapping the high SDRAM block back to 40x (where there
is absolutely nothing) work?

Thanks in advance.

Scott Wagner
 

Other related posts: