|
@@ -419,3 +419,196 @@ extern inline void t2_outl(u32 b, unsigned long addr)
|
|
|
* 9876543210987654321098765432109876543210
|
|
|
* 1ZZZZ0.PCI.QW.Address............BBLL
|
|
|
*
|
|
|
+ * ZZ = SBZ
|
|
|
+ * BB = Byte offset
|
|
|
+ * LL = Transfer length
|
|
|
+ *
|
|
|
+ * PCI Address:
|
|
|
+ *
|
|
|
+ * 3 2 1
|
|
|
+ * 10987654321098765432109876543210
|
|
|
+ * HHH....PCI.QW.Address........ 00
|
|
|
+ *
|
|
|
+ * HHH = 31:29 HAE_MEM CSR
|
|
|
+ *
|
|
|
+ */
|
|
|
+
|
|
|
+#ifdef T2_ONE_HAE_WINDOW
|
|
|
+#define t2_set_hae
|
|
|
+#else
|
|
|
+#define t2_set_hae { \
|
|
|
+ unsigned long msb = addr >> 27; \
|
|
|
+ addr &= T2_MEM_R1_MASK; \
|
|
|
+ set_hae(msb); \
|
|
|
+}
|
|
|
+#endif
|
|
|
+
|
|
|
+/*
|
|
|
+ * NOTE: take T2_DENSE_MEM off in each readX/writeX routine, since
|
|
|
+ * they may be called directly, rather than through the
|
|
|
+ * ioreadNN/iowriteNN routines.
|
|
|
+ */
|
|
|
+
|
|
|
+__EXTERN_INLINE u8 t2_readb(const volatile void __iomem *xaddr)
|
|
|
+{
|
|
|
+ unsigned long addr = (unsigned long) xaddr - T2_DENSE_MEM;
|
|
|
+ unsigned long result;
|
|
|
+
|
|
|
+ t2_set_hae;
|
|
|
+
|
|
|
+ result = *(vip) ((addr << 5) + T2_SPARSE_MEM + 0x00);
|
|
|
+ return __kernel_extbl(result, addr & 3);
|
|
|
+}
|
|
|
+
|
|
|
+__EXTERN_INLINE u16 t2_readw(const volatile void __iomem *xaddr)
|
|
|
+{
|
|
|
+ unsigned long addr = (unsigned long) xaddr - T2_DENSE_MEM;
|
|
|
+ unsigned long result;
|
|
|
+
|
|
|
+ t2_set_hae;
|
|
|
+
|
|
|
+ result = *(vuip) ((addr << 5) + T2_SPARSE_MEM + 0x08);
|
|
|
+ return __kernel_extwl(result, addr & 3);
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+ * On SABLE with T2, we must use SPARSE memory even for 32-bit access,
|
|
|
+ * because we cannot access all of DENSE without changing its HAE.
|
|
|
+ */
|
|
|
+__EXTERN_INLINE u32 t2_readl(const volatile void __iomem *xaddr)
|
|
|
+{
|
|
|
+ unsigned long addr = (unsigned long) xaddr - T2_DENSE_MEM;
|
|
|
+ unsigned long result;
|
|
|
+
|
|
|
+ t2_set_hae;
|
|
|
+
|
|
|
+ result = *(vuip) ((addr << 5) + T2_SPARSE_MEM + 0x18);
|
|
|
+ return result & 0xffffffffUL;
|
|
|
+}
|
|
|
+
|
|
|
+__EXTERN_INLINE u64 t2_readq(const volatile void __iomem *xaddr)
|
|
|
+{
|
|
|
+ unsigned long addr = (unsigned long) xaddr - T2_DENSE_MEM;
|
|
|
+ unsigned long r0, r1, work;
|
|
|
+
|
|
|
+ t2_set_hae;
|
|
|
+
|
|
|
+ work = (addr << 5) + T2_SPARSE_MEM + 0x18;
|
|
|
+ r0 = *(vuip)(work);
|
|
|
+ r1 = *(vuip)(work + (4 << 5));
|
|
|
+ return r1 << 32 | r0;
|
|
|
+}
|
|
|
+
|
|
|
+__EXTERN_INLINE void t2_writeb(u8 b, volatile void __iomem *xaddr)
|
|
|
+{
|
|
|
+ unsigned long addr = (unsigned long) xaddr - T2_DENSE_MEM;
|
|
|
+ unsigned long w;
|
|
|
+
|
|
|
+ t2_set_hae;
|
|
|
+
|
|
|
+ w = __kernel_insbl(b, addr & 3);
|
|
|
+ *(vuip) ((addr << 5) + T2_SPARSE_MEM + 0x00) = w;
|
|
|
+}
|
|
|
+
|
|
|
+__EXTERN_INLINE void t2_writew(u16 b, volatile void __iomem *xaddr)
|
|
|
+{
|
|
|
+ unsigned long addr = (unsigned long) xaddr - T2_DENSE_MEM;
|
|
|
+ unsigned long w;
|
|
|
+
|
|
|
+ t2_set_hae;
|
|
|
+
|
|
|
+ w = __kernel_inswl(b, addr & 3);
|
|
|
+ *(vuip) ((addr << 5) + T2_SPARSE_MEM + 0x08) = w;
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+ * On SABLE with T2, we must use SPARSE memory even for 32-bit access,
|
|
|
+ * because we cannot access all of DENSE without changing its HAE.
|
|
|
+ */
|
|
|
+__EXTERN_INLINE void t2_writel(u32 b, volatile void __iomem *xaddr)
|
|
|
+{
|
|
|
+ unsigned long addr = (unsigned long) xaddr - T2_DENSE_MEM;
|
|
|
+
|
|
|
+ t2_set_hae;
|
|
|
+
|
|
|
+ *(vuip) ((addr << 5) + T2_SPARSE_MEM + 0x18) = b;
|
|
|
+}
|
|
|
+
|
|
|
+__EXTERN_INLINE void t2_writeq(u64 b, volatile void __iomem *xaddr)
|
|
|
+{
|
|
|
+ unsigned long addr = (unsigned long) xaddr - T2_DENSE_MEM;
|
|
|
+ unsigned long work;
|
|
|
+
|
|
|
+ t2_set_hae;
|
|
|
+
|
|
|
+ work = (addr << 5) + T2_SPARSE_MEM + 0x18;
|
|
|
+ *(vuip)work = b;
|
|
|
+ *(vuip)(work + (4 << 5)) = b >> 32;
|
|
|
+}
|
|
|
+
|
|
|
+__EXTERN_INLINE void __iomem *t2_ioportmap(unsigned long addr)
|
|
|
+{
|
|
|
+ return (void __iomem *)(addr + T2_IO);
|
|
|
+}
|
|
|
+
|
|
|
+__EXTERN_INLINE void __iomem *t2_ioremap(unsigned long addr,
|
|
|
+ unsigned long size)
|
|
|
+{
|
|
|
+ return (void __iomem *)(addr + T2_DENSE_MEM);
|
|
|
+}
|
|
|
+
|
|
|
+__EXTERN_INLINE int t2_is_ioaddr(unsigned long addr)
|
|
|
+{
|
|
|
+ return (long)addr >= 0;
|
|
|
+}
|
|
|
+
|
|
|
+__EXTERN_INLINE int t2_is_mmio(const volatile void __iomem *addr)
|
|
|
+{
|
|
|
+ return (unsigned long)addr >= T2_DENSE_MEM;
|
|
|
+}
|
|
|
+
|
|
|
+/* New-style ioread interface. The mmio routines are so ugly for T2 that
|
|
|
+ it doesn't make sense to merge the pio and mmio routines. */
|
|
|
+
|
|
|
+#define IOPORT(OS, NS) \
|
|
|
+__EXTERN_INLINE unsigned int t2_ioread##NS(void __iomem *xaddr) \
|
|
|
+{ \
|
|
|
+ if (t2_is_mmio(xaddr)) \
|
|
|
+ return t2_read##OS(xaddr); \
|
|
|
+ else \
|
|
|
+ return t2_in##OS((unsigned long)xaddr - T2_IO); \
|
|
|
+} \
|
|
|
+__EXTERN_INLINE void t2_iowrite##NS(u##NS b, void __iomem *xaddr) \
|
|
|
+{ \
|
|
|
+ if (t2_is_mmio(xaddr)) \
|
|
|
+ t2_write##OS(b, xaddr); \
|
|
|
+ else \
|
|
|
+ t2_out##OS(b, (unsigned long)xaddr - T2_IO); \
|
|
|
+}
|
|
|
+
|
|
|
+IOPORT(b, 8)
|
|
|
+IOPORT(w, 16)
|
|
|
+IOPORT(l, 32)
|
|
|
+
|
|
|
+#undef IOPORT
|
|
|
+
|
|
|
+#undef vip
|
|
|
+#undef vuip
|
|
|
+
|
|
|
+#undef __IO_PREFIX
|
|
|
+#define __IO_PREFIX t2
|
|
|
+#define t2_trivial_rw_bw 0
|
|
|
+#define t2_trivial_rw_lq 0
|
|
|
+#define t2_trivial_io_bw 0
|
|
|
+#define t2_trivial_io_lq 0
|
|
|
+#define t2_trivial_iounmap 1
|
|
|
+#include <asm/io_trivial.h>
|
|
|
+
|
|
|
+#ifdef __IO_EXTERN_INLINE
|
|
|
+#undef __EXTERN_INLINE
|
|
|
+#undef __IO_EXTERN_INLINE
|
|
|
+#endif
|
|
|
+
|
|
|
+#endif /* __KERNEL__ */
|
|
|
+
|
|
|
+#endif /* __ALPHA_T2__H__ */
|