~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/mips/include/asm/mach-powertv/ioremap.h

Version: ~ [ linux-5.5-rc6 ] ~ [ linux-5.4.11 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.95 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.164 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.209 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.209 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.81 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.102 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  *      This program is free software; you can redistribute it and/or
  3  *      modify it under the terms of the GNU General Public License
  4  *      as published by the Free Software Foundation; either version
  5  *      2 of the License, or (at your option) any later version.
  6  *
  7  * Portions Copyright (C)  Cisco Systems, Inc.
  8  */
  9 #ifndef __ASM_MACH_POWERTV_IOREMAP_H
 10 #define __ASM_MACH_POWERTV_IOREMAP_H
 11 
 12 #include <linux/types.h>
 13 #include <linux/log2.h>
 14 #include <linux/compiler.h>
 15 
 16 #include <asm/pgtable-bits.h>
 17 #include <asm/addrspace.h>
 18 
 19 /* We're going to mess with bits, so get sizes */
 20 #define IOR_BPC                 8                       /* Bits per char */
 21 #define IOR_PHYS_BITS           (IOR_BPC * sizeof(phys_addr_t))
 22 #define IOR_DMA_BITS            (IOR_BPC * sizeof(dma_addr_t))
 23 
 24 /*
 25  * Define the granularity of physical/DMA mapping in terms of the number
 26  * of bits that defines the offset within a grain. These will be the
 27  * least significant bits of the address. The rest of a physical or DMA
 28  * address will be used to index into an appropriate table to find the
 29  * offset to add to the address to yield the corresponding DMA or physical
 30  * address, respectively.
 31  */
 32 #define IOR_LSBITS              22                      /* Bits in a grain */
 33 
 34 /*
 35  * Compute the number of most significant address bits after removing those
 36  * used for the offset within a grain and then compute the number of table
 37  * entries for the conversion.
 38  */
 39 #define IOR_PHYS_MSBITS         (IOR_PHYS_BITS - IOR_LSBITS)
 40 #define IOR_NUM_PHYS_TO_DMA     ((phys_addr_t) 1 << IOR_PHYS_MSBITS)
 41 
 42 #define IOR_DMA_MSBITS          (IOR_DMA_BITS - IOR_LSBITS)
 43 #define IOR_NUM_DMA_TO_PHYS     ((dma_addr_t) 1 << IOR_DMA_MSBITS)
 44 
 45 /*
 46  * Define data structures used as elements in the arrays for the conversion
 47  * between physical and DMA addresses. We do some slightly fancy math to
 48  * compute the width of the offset element of the conversion tables so
 49  * that we can have the smallest conversion tables. Next, round up the
 50  * sizes to the next higher power of two, i.e. the offset element will have
 51  * 8, 16, 32, 64, etc. bits. This eliminates the need to mask off any
 52  * bits.  Finally, we compute a shift value that puts the most significant
 53  * bits of the offset into the most significant bits of the offset element.
 54  * This makes it more efficient on processors without barrel shifters and
 55  * easier to see the values if the conversion table is dumped in binary.
 56  */
 57 #define _IOR_OFFSET_WIDTH(n)    (1 << order_base_2(n))
 58 #define IOR_OFFSET_WIDTH(n) \
 59         (_IOR_OFFSET_WIDTH(n) < 8 ? 8 : _IOR_OFFSET_WIDTH(n))
 60 
 61 #define IOR_PHYS_OFFSET_BITS    IOR_OFFSET_WIDTH(IOR_PHYS_MSBITS)
 62 #define IOR_PHYS_SHIFT          (IOR_PHYS_BITS - IOR_PHYS_OFFSET_BITS)
 63 
 64 #define IOR_DMA_OFFSET_BITS     IOR_OFFSET_WIDTH(IOR_DMA_MSBITS)
 65 #define IOR_DMA_SHIFT           (IOR_DMA_BITS - IOR_DMA_OFFSET_BITS)
 66 
 67 struct ior_phys_to_dma {
 68         dma_addr_t offset:IOR_DMA_OFFSET_BITS __packed
 69                 __aligned((IOR_DMA_OFFSET_BITS / IOR_BPC));
 70 };
 71 
 72 struct ior_dma_to_phys {
 73         dma_addr_t offset:IOR_PHYS_OFFSET_BITS __packed
 74                 __aligned((IOR_PHYS_OFFSET_BITS / IOR_BPC));
 75 };
 76 
 77 extern struct ior_phys_to_dma _ior_phys_to_dma[IOR_NUM_PHYS_TO_DMA];
 78 extern struct ior_dma_to_phys _ior_dma_to_phys[IOR_NUM_DMA_TO_PHYS];
 79 
 80 static inline dma_addr_t _phys_to_dma_offset_raw(phys_addr_t phys)
 81 {
 82         return (dma_addr_t)_ior_phys_to_dma[phys >> IOR_LSBITS].offset;
 83 }
 84 
 85 static inline dma_addr_t _dma_to_phys_offset_raw(dma_addr_t dma)
 86 {
 87         return (dma_addr_t)_ior_dma_to_phys[dma >> IOR_LSBITS].offset;
 88 }
 89 
 90 /* These are not portable and should not be used in drivers. Drivers should
 91  * be using ioremap() and friends to map physical addresses to virtual
 92  * addresses and dma_map*() and friends to map virtual addresses into DMA
 93  * addresses and back.
 94  */
 95 static inline dma_addr_t phys_to_dma(phys_addr_t phys)
 96 {
 97         return phys + (_phys_to_dma_offset_raw(phys) << IOR_PHYS_SHIFT);
 98 }
 99 
100 static inline phys_addr_t dma_to_phys(dma_addr_t dma)
101 {
102         return dma + (_dma_to_phys_offset_raw(dma) << IOR_DMA_SHIFT);
103 }
104 
105 extern void ioremap_add_map(dma_addr_t phys, phys_addr_t alias,
106         dma_addr_t size);
107 
108 /*
109  * Allow physical addresses to be fixed up to help peripherals located
110  * outside the low 32-bit range -- generic pass-through version.
111  */
112 static inline phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size)
113 {
114         return phys_addr;
115 }
116 
117 /*
118  * Handle the special case of addresses the area aliased into the first
119  * 512 MiB of the processor's physical address space. These turn into either
120  * kseg0 or kseg1 addresses, depending on flags.
121  */
122 static inline void __iomem *plat_ioremap(phys_t start, unsigned long size,
123         unsigned long flags)
124 {
125         phys_addr_t start_offset;
126         void __iomem *result = NULL;
127 
128         /* Start by checking to see whether this is an aliased address */
129         start_offset = _dma_to_phys_offset_raw(start);
130 
131         /*
132          * If:
133          * o    the memory is aliased into the first 512 MiB, and
134          * o    the start and end are in the same RAM bank, and
135          * o    we don't have a zero size or wrap around, and
136          * o    we are supposed to create an uncached mapping,
137          *      handle this is a kseg0 or kseg1 address
138          */
139         if (start_offset != 0) {
140                 phys_addr_t last;
141                 dma_addr_t dma_to_phys_offset;
142 
143                 last = start + size - 1;
144                 dma_to_phys_offset =
145                         _dma_to_phys_offset_raw(last) << IOR_DMA_SHIFT;
146 
147                 if (dma_to_phys_offset == start_offset &&
148                         size != 0 && start <= last) {
149                         phys_t adjusted_start;
150                         adjusted_start = start + start_offset;
151                         if (flags == _CACHE_UNCACHED)
152                                 result = (void __iomem *) (unsigned long)
153                                         CKSEG1ADDR(adjusted_start);
154                         else
155                                 result = (void __iomem *) (unsigned long)
156                                         CKSEG0ADDR(adjusted_start);
157                 }
158         }
159 
160         return result;
161 }
162 
163 static inline int plat_iounmap(const volatile void __iomem *addr)
164 {
165         return 0;
166 }
167 #endif /* __ASM_MACH_POWERTV_IOREMAP_H */
168 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp