Commit a372cfac authored by Adrian Hunter's avatar Adrian Hunter Committed by Alexandre Belloni
Browse files

i3c: mipi-i3c-hci: Cache DAT in memory for Runtime PM restore



Prepare for Runtime PM support, which requires restoring the Device Address
Table (DAT) registers after resume.  Maintain a copy of DAT in memory so it
can be reprogrammed when the controller is powered back up.

Signed-off-by: default avatarAdrian Hunter <adrian.hunter@intel.com>
Reviewed-by: default avatarFrank Li <Frank.Li@nxp.com>
Link: https://patch.msgid.link/20260113072702.16268-9-adrian.hunter@intel.com


Signed-off-by: default avatarAlexandre Belloni <alexandre.belloni@bootlin.com>
parent 29bf98a6
Loading
Loading
Loading
Loading
+23 −6
Original line number Diff line number Diff line
@@ -34,13 +34,26 @@
/*	DAT_0_IBI_PAYLOAD		W0_BIT_(12) */
#define DAT_0_STATIC_ADDRESS		W0_MASK(6, 0)

#define dat_w0_read(i)		readl(hci->DAT_regs + (i) * 8)
#define dat_w1_read(i)		readl(hci->DAT_regs + (i) * 8 + 4)
#define dat_w0_write(i, v)	writel(v, hci->DAT_regs + (i) * 8)
#define dat_w1_write(i, v)	writel(v, hci->DAT_regs + (i) * 8 + 4)
#define dat_w0_read(i)		hci->DAT[i].w0
#define dat_w1_read(i)		hci->DAT[i].w1
#define dat_w0_write(i, v)	hci_dat_w0_write(hci, i, v)
#define dat_w1_write(i, v)	hci_dat_w1_write(hci, i, v)

static inline void hci_dat_w0_write(struct i3c_hci *hci, int i, u32 v)
{
	hci->DAT[i].w0 = v;
	writel(v, hci->DAT_regs + i * 8);
}

static inline void hci_dat_w1_write(struct i3c_hci *hci, int i, u32 v)
{
	hci->DAT[i].w1 = v;
	writel(v, hci->DAT_regs + i * 8 + 4);
}

static int hci_dat_v1_init(struct i3c_hci *hci)
{
	struct device *dev = hci->master.dev.parent;
	unsigned int dat_idx;

	if (!hci->DAT_regs) {
@@ -54,9 +67,13 @@ static int hci_dat_v1_init(struct i3c_hci *hci)
		return -EOPNOTSUPP;
	}

	if (!hci->DAT_data) {
		struct device *dev = hci->master.dev.parent;
	if (!hci->DAT) {
		hci->DAT = devm_kcalloc(dev, hci->DAT_entries, hci->DAT_entry_size, GFP_KERNEL);
		if (!hci->DAT)
			return -ENOMEM;
	}

	if (!hci->DAT_data) {
		/* use a bitmap for faster free slot search */
		hci->DAT_data = devm_bitmap_zalloc(dev, hci->DAT_entries, GFP_KERNEL);
		if (!hci->DAT_data)
+6 −0
Original line number Diff line number Diff line
@@ -31,6 +31,11 @@

struct hci_cmd_ops;

struct dat_words {
	u32 w0;
	u32 w1;
};

/* Our main structure */
struct i3c_hci {
	struct i3c_master_controller master;
@@ -51,6 +56,7 @@ struct i3c_hci {
	unsigned int DAT_entries;
	unsigned int DAT_entry_size;
	void *DAT_data;
	struct dat_words *DAT;
	unsigned int DCT_entries;
	unsigned int DCT_entry_size;
	u8 version_major;