0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/bitfield.h>
0009 #include <linux/bitmap.h>
0010 #include <linux/device.h>
0011 #include <linux/errno.h>
0012 #include <linux/i3c/master.h>
0013 #include <linux/io.h>
0014
0015 #include "hci.h"
0016 #include "dat.h"
0017
0018
0019
0020
0021
0022
0023 #define DAT_1_AUTOCMD_HDR_CODE W1_MASK(58, 51)
0024 #define DAT_1_AUTOCMD_MODE W1_MASK(50, 48)
0025 #define DAT_1_AUTOCMD_VALUE W1_MASK(47, 40)
0026 #define DAT_1_AUTOCMD_MASK W1_MASK(39, 32)
0027
0028 #define DAT_0_DEV_NACK_RETRY_CNT W0_MASK(30, 29)
0029 #define DAT_0_RING_ID W0_MASK(28, 26)
0030 #define DAT_0_DYNADDR_PARITY W0_BIT_(23)
0031 #define DAT_0_DYNAMIC_ADDRESS W0_MASK(22, 16)
0032 #define DAT_0_TS W0_BIT_(15)
0033 #define DAT_0_MR_REJECT W0_BIT_(14)
0034
0035
0036 #define DAT_0_STATIC_ADDRESS W0_MASK(6, 0)
0037
0038 #define dat_w0_read(i) readl(hci->DAT_regs + (i) * 8)
0039 #define dat_w1_read(i) readl(hci->DAT_regs + (i) * 8 + 4)
0040 #define dat_w0_write(i, v) writel(v, hci->DAT_regs + (i) * 8)
0041 #define dat_w1_write(i, v) writel(v, hci->DAT_regs + (i) * 8 + 4)
0042
0043 static inline bool dynaddr_parity(unsigned int addr)
0044 {
0045 addr |= 1 << 7;
0046 addr += addr >> 4;
0047 addr += addr >> 2;
0048 addr += addr >> 1;
0049 return (addr & 1);
0050 }
0051
0052 static int hci_dat_v1_init(struct i3c_hci *hci)
0053 {
0054 unsigned int dat_idx;
0055
0056 if (!hci->DAT_regs) {
0057 dev_err(&hci->master.dev,
0058 "only DAT in register space is supported at the moment\n");
0059 return -EOPNOTSUPP;
0060 }
0061 if (hci->DAT_entry_size != 8) {
0062 dev_err(&hci->master.dev,
0063 "only 8-bytes DAT entries are supported at the moment\n");
0064 return -EOPNOTSUPP;
0065 }
0066
0067
0068 hci->DAT_data = bitmap_zalloc(hci->DAT_entries, GFP_KERNEL);
0069 if (!hci->DAT_data)
0070 return -ENOMEM;
0071
0072
0073 for (dat_idx = 0; dat_idx < hci->DAT_entries; dat_idx++) {
0074 dat_w0_write(dat_idx, 0);
0075 dat_w1_write(dat_idx, 0);
0076 }
0077
0078 return 0;
0079 }
0080
0081 static void hci_dat_v1_cleanup(struct i3c_hci *hci)
0082 {
0083 bitmap_free(hci->DAT_data);
0084 hci->DAT_data = NULL;
0085 }
0086
0087 static int hci_dat_v1_alloc_entry(struct i3c_hci *hci)
0088 {
0089 unsigned int dat_idx;
0090
0091 dat_idx = find_first_zero_bit(hci->DAT_data, hci->DAT_entries);
0092 if (dat_idx >= hci->DAT_entries)
0093 return -ENOENT;
0094 __set_bit(dat_idx, hci->DAT_data);
0095
0096
0097 dat_w0_write(dat_idx, DAT_0_SIR_REJECT | DAT_0_MR_REJECT);
0098
0099 return dat_idx;
0100 }
0101
0102 static void hci_dat_v1_free_entry(struct i3c_hci *hci, unsigned int dat_idx)
0103 {
0104 dat_w0_write(dat_idx, 0);
0105 dat_w1_write(dat_idx, 0);
0106 __clear_bit(dat_idx, hci->DAT_data);
0107 }
0108
0109 static void hci_dat_v1_set_dynamic_addr(struct i3c_hci *hci,
0110 unsigned int dat_idx, u8 address)
0111 {
0112 u32 dat_w0;
0113
0114 dat_w0 = dat_w0_read(dat_idx);
0115 dat_w0 &= ~(DAT_0_DYNAMIC_ADDRESS | DAT_0_DYNADDR_PARITY);
0116 dat_w0 |= FIELD_PREP(DAT_0_DYNAMIC_ADDRESS, address) |
0117 (dynaddr_parity(address) ? DAT_0_DYNADDR_PARITY : 0);
0118 dat_w0_write(dat_idx, dat_w0);
0119 }
0120
0121 static void hci_dat_v1_set_static_addr(struct i3c_hci *hci,
0122 unsigned int dat_idx, u8 address)
0123 {
0124 u32 dat_w0;
0125
0126 dat_w0 = dat_w0_read(dat_idx);
0127 dat_w0 &= ~DAT_0_STATIC_ADDRESS;
0128 dat_w0 |= FIELD_PREP(DAT_0_STATIC_ADDRESS, address);
0129 dat_w0_write(dat_idx, dat_w0);
0130 }
0131
0132 static void hci_dat_v1_set_flags(struct i3c_hci *hci, unsigned int dat_idx,
0133 u32 w0_flags, u32 w1_flags)
0134 {
0135 u32 dat_w0, dat_w1;
0136
0137 dat_w0 = dat_w0_read(dat_idx);
0138 dat_w1 = dat_w1_read(dat_idx);
0139 dat_w0 |= w0_flags;
0140 dat_w1 |= w1_flags;
0141 dat_w0_write(dat_idx, dat_w0);
0142 dat_w1_write(dat_idx, dat_w1);
0143 }
0144
0145 static void hci_dat_v1_clear_flags(struct i3c_hci *hci, unsigned int dat_idx,
0146 u32 w0_flags, u32 w1_flags)
0147 {
0148 u32 dat_w0, dat_w1;
0149
0150 dat_w0 = dat_w0_read(dat_idx);
0151 dat_w1 = dat_w1_read(dat_idx);
0152 dat_w0 &= ~w0_flags;
0153 dat_w1 &= ~w1_flags;
0154 dat_w0_write(dat_idx, dat_w0);
0155 dat_w1_write(dat_idx, dat_w1);
0156 }
0157
0158 static int hci_dat_v1_get_index(struct i3c_hci *hci, u8 dev_addr)
0159 {
0160 unsigned int dat_idx;
0161 u32 dat_w0;
0162
0163 for_each_set_bit(dat_idx, hci->DAT_data, hci->DAT_entries) {
0164 dat_w0 = dat_w0_read(dat_idx);
0165 if (FIELD_GET(DAT_0_DYNAMIC_ADDRESS, dat_w0) == dev_addr)
0166 return dat_idx;
0167 }
0168
0169 return -ENODEV;
0170 }
0171
0172 const struct hci_dat_ops mipi_i3c_hci_dat_v1 = {
0173 .init = hci_dat_v1_init,
0174 .cleanup = hci_dat_v1_cleanup,
0175 .alloc_entry = hci_dat_v1_alloc_entry,
0176 .free_entry = hci_dat_v1_free_entry,
0177 .set_dynamic_addr = hci_dat_v1_set_dynamic_addr,
0178 .set_static_addr = hci_dat_v1_set_static_addr,
0179 .set_flags = hci_dat_v1_set_flags,
0180 .clear_flags = hci_dat_v1_clear_flags,
0181 .get_index = hci_dat_v1_get_index,
0182 };