forked from Minki/linux
30af97296f
The information required to map registers based on capabilities is contained within the bars themselves. This means the bar must be mapped to read the information needed and then unmapped to map the individual parts of the BAR based on capabilities. Change cxl_setup_device_regs() to return a new cxl_register_map, change the name to cxl_probe_device_regs(). Allocate and place cxl_register_maps on a list while processing all of the specified register blocks. After probing all the register blocks go back and map smaller registers blocks based on their capabilities and dispose of the cxl_register_maps. NOTE: pci_iomap() is not managed automatically via pcim_enable_device() so be careful to call pci_iounmap() correctly. Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> Signed-off-by: Ira Weiny <ira.weiny@intel.com> Link: https://lore.kernel.org/r/20210604005036.4187184-1-ira.weiny@intel.com Signed-off-by: Dan Williams <dan.j.williams@intel.com>
97 lines
2.7 KiB
C
97 lines
2.7 KiB
C
/* SPDX-License-Identifier: GPL-2.0-only */
|
|
/* Copyright(c) 2020 Intel Corporation. */
|
|
|
|
#ifndef __CXL_H__
|
|
#define __CXL_H__
|
|
|
|
#include <linux/bitfield.h>
|
|
#include <linux/bitops.h>
|
|
#include <linux/io.h>
|
|
|
|
/* CXL 2.0 8.2.8.1 Device Capabilities Array Register */
|
|
#define CXLDEV_CAP_ARRAY_OFFSET 0x0
|
|
#define CXLDEV_CAP_ARRAY_CAP_ID 0
|
|
#define CXLDEV_CAP_ARRAY_ID_MASK GENMASK_ULL(15, 0)
|
|
#define CXLDEV_CAP_ARRAY_COUNT_MASK GENMASK_ULL(47, 32)
|
|
/* CXL 2.0 8.2.8.2 CXL Device Capability Header Register */
|
|
#define CXLDEV_CAP_HDR_CAP_ID_MASK GENMASK(15, 0)
|
|
/* CXL 2.0 8.2.8.2.1 CXL Device Capabilities */
|
|
#define CXLDEV_CAP_CAP_ID_DEVICE_STATUS 0x1
|
|
#define CXLDEV_CAP_CAP_ID_PRIMARY_MAILBOX 0x2
|
|
#define CXLDEV_CAP_CAP_ID_SECONDARY_MAILBOX 0x3
|
|
#define CXLDEV_CAP_CAP_ID_MEMDEV 0x4000
|
|
|
|
/* CXL 2.0 8.2.8.4 Mailbox Registers */
|
|
#define CXLDEV_MBOX_CAPS_OFFSET 0x00
|
|
#define CXLDEV_MBOX_CAP_PAYLOAD_SIZE_MASK GENMASK(4, 0)
|
|
#define CXLDEV_MBOX_CTRL_OFFSET 0x04
|
|
#define CXLDEV_MBOX_CTRL_DOORBELL BIT(0)
|
|
#define CXLDEV_MBOX_CMD_OFFSET 0x08
|
|
#define CXLDEV_MBOX_CMD_COMMAND_OPCODE_MASK GENMASK_ULL(15, 0)
|
|
#define CXLDEV_MBOX_CMD_PAYLOAD_LENGTH_MASK GENMASK_ULL(36, 16)
|
|
#define CXLDEV_MBOX_STATUS_OFFSET 0x10
|
|
#define CXLDEV_MBOX_STATUS_RET_CODE_MASK GENMASK_ULL(47, 32)
|
|
#define CXLDEV_MBOX_BG_CMD_STATUS_OFFSET 0x18
|
|
#define CXLDEV_MBOX_PAYLOAD_OFFSET 0x20
|
|
|
|
/*
|
|
* CXL_DEVICE_REGS - Common set of CXL Device register block base pointers
|
|
* @status: CXL 2.0 8.2.8.3 Device Status Registers
|
|
* @mbox: CXL 2.0 8.2.8.4 Mailbox Registers
|
|
* @memdev: CXL 2.0 8.2.8.5 Memory Device Registers
|
|
*/
|
|
#define CXL_DEVICE_REGS() \
|
|
void __iomem *status; \
|
|
void __iomem *mbox; \
|
|
void __iomem *memdev
|
|
|
|
/* See note for 'struct cxl_regs' for the rationale of this organization */
|
|
struct cxl_device_regs {
|
|
CXL_DEVICE_REGS();
|
|
};
|
|
|
|
/*
|
|
* Note, the anonymous union organization allows for per
|
|
* register-block-type helper routines, without requiring block-type
|
|
* agnostic code to include the prefix.
|
|
*/
|
|
struct cxl_regs {
|
|
union {
|
|
struct {
|
|
CXL_DEVICE_REGS();
|
|
};
|
|
struct cxl_device_regs device_regs;
|
|
};
|
|
};
|
|
|
|
struct cxl_reg_map {
|
|
bool valid;
|
|
unsigned long offset;
|
|
unsigned long size;
|
|
};
|
|
|
|
struct cxl_device_reg_map {
|
|
struct cxl_reg_map status;
|
|
struct cxl_reg_map mbox;
|
|
struct cxl_reg_map memdev;
|
|
};
|
|
|
|
struct cxl_register_map {
|
|
struct list_head list;
|
|
u64 block_offset;
|
|
u8 reg_type;
|
|
u8 barno;
|
|
union {
|
|
struct cxl_device_reg_map device_map;
|
|
};
|
|
};
|
|
|
|
void cxl_probe_device_regs(struct device *dev, void __iomem *base,
|
|
struct cxl_device_reg_map *map);
|
|
int cxl_map_device_regs(struct pci_dev *pdev,
|
|
struct cxl_device_regs *regs,
|
|
struct cxl_register_map *map);
|
|
|
|
extern struct bus_type cxl_bus_type;
|
|
#endif /* __CXL_H__ */
|