Commit b02002cc authored by Niklas Schnelle's avatar Niklas Schnelle Committed by Vasily Gorbik
Browse files

s390/pci: Implement ioremap_wc/prot() with MIO



With our current support for the new MIO PCI instructions, write
combining/write back MMIO memory can be obtained via the pci_iomap_wc()
and pci_iomap_wc_range() functions.
This is achieved by using the write back address for a specific bar
as provided in clp_store_query_pci_fn()

These functions are however not widely used and instead drivers often
rely on ioremap_wc() and ioremap_prot(), which on other platforms enable
write combining using a PTE flag set through the pgrprot value.

While we do not have a write combining flag in the low order flag bits
of the PTE like x86_64 does, with MIO support, there is a write back bit
in the physical address (bit 1 on z15) and thus also the PTE.
Which bit is used to toggle write back and whether it is available at
all, is however not fixed in the architecture. Instead we get this
information from the CLP Store Logical Processor Characteristics for PCI
command. When the write back bit is not provided we fall back to the
existing behavior.

Signed-off-by: default avatarNiklas Schnelle <schnelle@linux.ibm.com>
Reviewed-by: default avatarPierre Morel <pmorel@linux.ibm.com>
Reviewed-by: default avatarGerald Schaefer <gerald.schaefer@linux.ibm.com>
Signed-off-by: default avatarVasily Gorbik <gor@linux.ibm.com>
parent 4d4a3caa
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -24,7 +24,7 @@
    |      parisc: | TODO |
    |     powerpc: |  ok  |
    |       riscv: | TODO |
    |        s390: | TODO |
    |        s390: |  ok  |
    |          sh: |  ok  |
    |       sparc: | TODO |
    |          um: | TODO |
+3 −0
Original line number Diff line number Diff line
@@ -5,6 +5,9 @@
/* CLP common request & response block size */
#define CLP_BLK_SIZE			PAGE_SIZE

/* Call Logical Processor - Command Code */
#define CLP_SLPC		0x0001

#define CLP_LPS_BASE	0
#define CLP_LPS_PCI	2

+8 −0
Original line number Diff line number Diff line
@@ -12,6 +12,7 @@

#include <linux/kernel.h>
#include <asm/page.h>
#include <asm/pgtable.h>
#include <asm/pci_io.h>

#define xlate_dev_mem_ptr xlate_dev_mem_ptr
@@ -26,7 +27,10 @@ void unxlate_dev_mem_ptr(phys_addr_t phys, void *addr);

#define IO_SPACE_LIMIT 0

void __iomem *ioremap_prot(phys_addr_t addr, size_t size, unsigned long prot);
void __iomem *ioremap(phys_addr_t addr, size_t size);
void __iomem *ioremap_wc(phys_addr_t addr, size_t size);
void __iomem *ioremap_wt(phys_addr_t addr, size_t size);
void iounmap(volatile void __iomem *addr);

static inline void __iomem *ioport_map(unsigned long port, unsigned int nr)
@@ -52,6 +56,10 @@ static inline void ioport_unmap(void __iomem *p)
#define pci_iomap_wc pci_iomap_wc
#define pci_iomap_wc_range pci_iomap_wc_range

#define ioremap ioremap
#define ioremap_wt ioremap_wt
#define ioremap_wc ioremap_wc

#define memcpy_fromio(dst, src, count)	zpci_memcpy_fromio(dst, src, count)
#define memcpy_toio(dst, src, count)	zpci_memcpy_toio(dst, src, count)
#define memset_io(dst, val, count)	zpci_memset_io(dst, val, count)
+1 −0
Original line number Diff line number Diff line
@@ -208,6 +208,7 @@ int zpci_unregister_ioat(struct zpci_dev *, u8);
void zpci_remove_reserved_devices(void);

/* CLP */
int clp_setup_writeback_mio(void);
int clp_scan_pci_devices(void);
int clp_rescan_pci_devices(void);
int clp_rescan_pci_devices_simple(u32 *fid);
+19 −0
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@
/*
 * Call Logical Processor - Command Codes
 */
#define CLP_SLPC		0x0001
#define CLP_LIST_PCI		0x0002
#define CLP_QUERY_PCI_FN	0x0003
#define CLP_QUERY_PCI_FNGRP	0x0004
@@ -51,6 +52,19 @@ struct clp_fh_list_entry {

extern bool zpci_unique_uid;

struct clp_rsp_slpc_pci {
	struct clp_rsp_hdr hdr;
	u32 reserved2[4];
	u32 lpif[8];
	u32 reserved3[4];
	u32 vwb		:  1;
	u32		:  1;
	u32 mio_wb	:  6;
	u32		: 24;
	u32 reserved5[3];
	u32 lpic[8];
} __packed;

/* List PCI functions request */
struct clp_req_list_pci {
	struct clp_req_hdr hdr;
@@ -172,6 +186,11 @@ struct clp_rsp_set_pci {
} __packed;

/* Combined request/response block structures used by clp insn */
struct clp_req_rsp_slpc_pci {
	struct clp_req_slpc request;
	struct clp_rsp_slpc_pci response;
} __packed;

struct clp_req_rsp_list_pci {
	struct clp_req_list_pci request;
	struct clp_rsp_list_pci response;
Loading