Skip to content

Commit 20d3bb9

Browse files
birkelundChristoph Hellwig
authored andcommitted
nvme-pci: allow use of cmb on v1.4 controllers
Since NVMe v1.4 the Controller Memory Buffer must be explicitly enabled by the host. Signed-off-by: Klaus Jensen <[email protected]> [hch: avoid a local variable and add a comment] Signed-off-by: Christoph Hellwig <[email protected]>
1 parent 9ebbfe4 commit 20d3bb9

File tree

2 files changed

+20
-0
lines changed

2 files changed

+20
-0
lines changed

drivers/nvme/host/pci.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include <linux/t10-pi.h>
2424
#include <linux/types.h>
2525
#include <linux/io-64-nonatomic-lo-hi.h>
26+
#include <linux/io-64-nonatomic-hi-lo.h>
2627
#include <linux/sed-opal.h>
2728
#include <linux/pci-p2pdma.h>
2829

@@ -1795,6 +1796,9 @@ static void nvme_map_cmb(struct nvme_dev *dev)
17951796
if (dev->cmb_size)
17961797
return;
17971798

1799+
if (NVME_CAP_CMBS(dev->ctrl.cap))
1800+
writel(NVME_CMBMSC_CRE, dev->bar + NVME_REG_CMBMSC);
1801+
17981802
dev->cmbsz = readl(dev->bar + NVME_REG_CMBSZ);
17991803
if (!dev->cmbsz)
18001804
return;
@@ -1808,6 +1812,16 @@ static void nvme_map_cmb(struct nvme_dev *dev)
18081812
if (offset > bar_size)
18091813
return;
18101814

1815+
/*
1816+
* Tell the controller about the host side address mapping the CMB,
1817+
* and enable CMB decoding for the NVMe 1.4+ scheme:
1818+
*/
1819+
if (NVME_CAP_CMBS(dev->ctrl.cap)) {
1820+
hi_lo_writeq(NVME_CMBMSC_CRE | NVME_CMBMSC_CMSE |
1821+
(pci_bus_address(pdev, bar) + offset),
1822+
dev->bar + NVME_REG_CMBMSC);
1823+
}
1824+
18111825
/*
18121826
* Controllers may support a CMB size larger than their BAR,
18131827
* for example, due to being behind a bridge. Reduce the CMB to

include/linux/nvme.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,9 @@ enum {
116116
NVME_REG_BPMBL = 0x0048, /* Boot Partition Memory Buffer
117117
* Location
118118
*/
119+
NVME_REG_CMBMSC = 0x0050, /* Controller Memory Buffer Memory
120+
* Space Control
121+
*/
119122
NVME_REG_PMRCAP = 0x0e00, /* Persistent Memory Capabilities */
120123
NVME_REG_PMRCTL = 0x0e04, /* Persistent Memory Region Control */
121124
NVME_REG_PMRSTS = 0x0e08, /* Persistent Memory Region Status */
@@ -135,6 +138,7 @@ enum {
135138
#define NVME_CAP_CSS(cap) (((cap) >> 37) & 0xff)
136139
#define NVME_CAP_MPSMIN(cap) (((cap) >> 48) & 0xf)
137140
#define NVME_CAP_MPSMAX(cap) (((cap) >> 52) & 0xf)
141+
#define NVME_CAP_CMBS(cap) (((cap) >> 57) & 0x1)
138142

139143
#define NVME_CMB_BIR(cmbloc) ((cmbloc) & 0x7)
140144
#define NVME_CMB_OFST(cmbloc) (((cmbloc) >> 12) & 0xfffff)
@@ -192,6 +196,8 @@ enum {
192196
NVME_CSTS_SHST_OCCUR = 1 << 2,
193197
NVME_CSTS_SHST_CMPLT = 2 << 2,
194198
NVME_CSTS_SHST_MASK = 3 << 2,
199+
NVME_CMBMSC_CRE = 1 << 0,
200+
NVME_CMBMSC_CMSE = 1 << 1,
195201
};
196202

197203
struct nvme_id_power_state {

0 commit comments

Comments
 (0)