aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoerg Roedel <joerg.roedel@amd.com>2008-08-14 13:55:15 -0400
committerIngo Molnar <mingo@elte.hu>2008-08-15 07:56:46 -0400
commit519c31bacf78a969efa8d2e55ed8862848f28590 (patch)
treebbeb4cd9f810536beb3bb1c5e6a827fa35a37633
parentb635acec48bcaa9183fcbf4e3955616b0d4119b5 (diff)
x86, AMD IOMMU: use status bit instead of memory write-back for completion wait
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r--arch/x86/kernel/amd_iommu.c17
-rw-r--r--include/asm-x86/amd_iommu_types.h4
2 files changed, 14 insertions, 7 deletions
diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c
index 22d7d050905d..028e945c68ad 100644
--- a/arch/x86/kernel/amd_iommu.c
+++ b/arch/x86/kernel/amd_iommu.c
@@ -101,16 +101,13 @@ static int iommu_queue_command(struct amd_iommu *iommu, struct iommu_cmd *cmd)
101 */ 101 */
102static int iommu_completion_wait(struct amd_iommu *iommu) 102static int iommu_completion_wait(struct amd_iommu *iommu)
103{ 103{
104 int ret; 104 int ret, ready = 0;
105 unsigned status = 0;
105 struct iommu_cmd cmd; 106 struct iommu_cmd cmd;
106 volatile u64 ready = 0;
107 unsigned long ready_phys = virt_to_phys(&ready);
108 unsigned long i = 0; 107 unsigned long i = 0;
109 108
110 memset(&cmd, 0, sizeof(cmd)); 109 memset(&cmd, 0, sizeof(cmd));
111 cmd.data[0] = LOW_U32(ready_phys) | CMD_COMPL_WAIT_STORE_MASK; 110 cmd.data[0] = CMD_COMPL_WAIT_INT_MASK;
112 cmd.data[1] = upper_32_bits(ready_phys);
113 cmd.data[2] = 1; /* value written to 'ready' */
114 CMD_SET_TYPE(&cmd, CMD_COMPL_WAIT); 111 CMD_SET_TYPE(&cmd, CMD_COMPL_WAIT);
115 112
116 iommu->need_sync = 0; 113 iommu->need_sync = 0;
@@ -122,9 +119,15 @@ static int iommu_completion_wait(struct amd_iommu *iommu)
122 119
123 while (!ready && (i < EXIT_LOOP_COUNT)) { 120 while (!ready && (i < EXIT_LOOP_COUNT)) {
124 ++i; 121 ++i;
125 cpu_relax(); 122 /* wait for the bit to become one */
123 status = readl(iommu->mmio_base + MMIO_STATUS_OFFSET);
124 ready = status & MMIO_STATUS_COM_WAIT_INT_MASK;
126 } 125 }
127 126
127 /* set bit back to zero */
128 status &= ~MMIO_STATUS_COM_WAIT_INT_MASK;
129 writel(status, iommu->mmio_base + MMIO_STATUS_OFFSET);
130
128 if (unlikely((i == EXIT_LOOP_COUNT) && printk_ratelimit())) 131 if (unlikely((i == EXIT_LOOP_COUNT) && printk_ratelimit()))
129 printk(KERN_WARNING "AMD IOMMU: Completion wait loop failed\n"); 132 printk(KERN_WARNING "AMD IOMMU: Completion wait loop failed\n");
130 133
diff --git a/include/asm-x86/amd_iommu_types.h b/include/asm-x86/amd_iommu_types.h
index 22aa58ca1991..32543229db76 100644
--- a/include/asm-x86/amd_iommu_types.h
+++ b/include/asm-x86/amd_iommu_types.h
@@ -69,6 +69,9 @@
69#define MMIO_EVT_TAIL_OFFSET 0x2018 69#define MMIO_EVT_TAIL_OFFSET 0x2018
70#define MMIO_STATUS_OFFSET 0x2020 70#define MMIO_STATUS_OFFSET 0x2020
71 71
72/* MMIO status bits */
73#define MMIO_STATUS_COM_WAIT_INT_MASK 0x04
74
72/* feature control bits */ 75/* feature control bits */
73#define CONTROL_IOMMU_EN 0x00ULL 76#define CONTROL_IOMMU_EN 0x00ULL
74#define CONTROL_HT_TUN_EN 0x01ULL 77#define CONTROL_HT_TUN_EN 0x01ULL
@@ -89,6 +92,7 @@
89#define CMD_INV_IOMMU_PAGES 0x03 92#define CMD_INV_IOMMU_PAGES 0x03
90 93
91#define CMD_COMPL_WAIT_STORE_MASK 0x01 94#define CMD_COMPL_WAIT_STORE_MASK 0x01
95#define CMD_COMPL_WAIT_INT_MASK 0x02
92#define CMD_INV_IOMMU_PAGES_SIZE_MASK 0x01 96#define CMD_INV_IOMMU_PAGES_SIZE_MASK 0x01
93#define CMD_INV_IOMMU_PAGES_PDE_MASK 0x02 97#define CMD_INV_IOMMU_PAGES_PDE_MASK 0x02
94 98