Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: BSD-3-Clause
0002 /*
0003  * Copyright (c) 2020, MIPI Alliance, Inc.
0004  *
0005  * Author: Nicolas Pitre <npitre@baylibre.com>
0006  *
0007  * I3C HCI v1.0/v1.1 Command Descriptor Handling
0008  */
0009 
0010 #include <linux/bitfield.h>
0011 #include <linux/i3c/master.h>
0012 
0013 #include "hci.h"
0014 #include "cmd.h"
0015 #include "dat.h"
0016 #include "dct.h"
0017 
0018 
0019 /*
0020  * Address Assignment Command
0021  */
0022 
0023 #define CMD_0_ATTR_A            FIELD_PREP(CMD_0_ATTR, 0x2)
0024 
0025 #define CMD_A0_TOC                 W0_BIT_(31)
0026 #define CMD_A0_ROC                 W0_BIT_(30)
0027 #define CMD_A0_DEV_COUNT(v)     FIELD_PREP(W0_MASK(29, 26), v)
0028 #define CMD_A0_DEV_INDEX(v)     FIELD_PREP(W0_MASK(20, 16), v)
0029 #define CMD_A0_CMD(v)           FIELD_PREP(W0_MASK(14,  7), v)
0030 #define CMD_A0_TID(v)           FIELD_PREP(W0_MASK( 6,  3), v)
0031 
0032 /*
0033  * Immediate Data Transfer Command
0034  */
0035 
0036 #define CMD_0_ATTR_I            FIELD_PREP(CMD_0_ATTR, 0x1)
0037 
0038 #define CMD_I1_DATA_BYTE_4(v)       FIELD_PREP(W1_MASK(63, 56), v)
0039 #define CMD_I1_DATA_BYTE_3(v)       FIELD_PREP(W1_MASK(55, 48), v)
0040 #define CMD_I1_DATA_BYTE_2(v)       FIELD_PREP(W1_MASK(47, 40), v)
0041 #define CMD_I1_DATA_BYTE_1(v)       FIELD_PREP(W1_MASK(39, 32), v)
0042 #define CMD_I1_DEF_BYTE(v)      FIELD_PREP(W1_MASK(39, 32), v)
0043 #define CMD_I0_TOC                 W0_BIT_(31)
0044 #define CMD_I0_ROC                 W0_BIT_(30)
0045 #define CMD_I0_RNW                 W0_BIT_(29)
0046 #define CMD_I0_MODE(v)          FIELD_PREP(W0_MASK(28, 26), v)
0047 #define CMD_I0_DTT(v)           FIELD_PREP(W0_MASK(25, 23), v)
0048 #define CMD_I0_DEV_INDEX(v)     FIELD_PREP(W0_MASK(20, 16), v)
0049 #define CMD_I0_CP                  W0_BIT_(15)
0050 #define CMD_I0_CMD(v)           FIELD_PREP(W0_MASK(14,  7), v)
0051 #define CMD_I0_TID(v)           FIELD_PREP(W0_MASK( 6,  3), v)
0052 
0053 /*
0054  * Regular Data Transfer Command
0055  */
0056 
0057 #define CMD_0_ATTR_R            FIELD_PREP(CMD_0_ATTR, 0x0)
0058 
0059 #define CMD_R1_DATA_LENGTH(v)       FIELD_PREP(W1_MASK(63, 48), v)
0060 #define CMD_R1_DEF_BYTE(v)      FIELD_PREP(W1_MASK(39, 32), v)
0061 #define CMD_R0_TOC                 W0_BIT_(31)
0062 #define CMD_R0_ROC                 W0_BIT_(30)
0063 #define CMD_R0_RNW                 W0_BIT_(29)
0064 #define CMD_R0_MODE(v)          FIELD_PREP(W0_MASK(28, 26), v)
0065 #define CMD_R0_DBP                 W0_BIT_(25)
0066 #define CMD_R0_DEV_INDEX(v)     FIELD_PREP(W0_MASK(20, 16), v)
0067 #define CMD_R0_CP                  W0_BIT_(15)
0068 #define CMD_R0_CMD(v)           FIELD_PREP(W0_MASK(14,  7), v)
0069 #define CMD_R0_TID(v)           FIELD_PREP(W0_MASK( 6,  3), v)
0070 
0071 /*
0072  * Combo Transfer (Write + Write/Read) Command
0073  */
0074 
0075 #define CMD_0_ATTR_C            FIELD_PREP(CMD_0_ATTR, 0x3)
0076 
0077 #define CMD_C1_DATA_LENGTH(v)       FIELD_PREP(W1_MASK(63, 48), v)
0078 #define CMD_C1_OFFSET(v)        FIELD_PREP(W1_MASK(47, 32), v)
0079 #define CMD_C0_TOC                 W0_BIT_(31)
0080 #define CMD_C0_ROC                 W0_BIT_(30)
0081 #define CMD_C0_RNW                 W0_BIT_(29)
0082 #define CMD_C0_MODE(v)          FIELD_PREP(W0_MASK(28, 26), v)
0083 #define CMD_C0_16_BIT_SUBOFFSET            W0_BIT_(25)
0084 #define CMD_C0_FIRST_PHASE_MODE            W0_BIT_(24)
0085 #define CMD_C0_DATA_LENGTH_POSITION(v)  FIELD_PREP(W0_MASK(23, 22), v)
0086 #define CMD_C0_DEV_INDEX(v)     FIELD_PREP(W0_MASK(20, 16), v)
0087 #define CMD_C0_CP                  W0_BIT_(15)
0088 #define CMD_C0_CMD(v)           FIELD_PREP(W0_MASK(14,  7), v)
0089 #define CMD_C0_TID(v)           FIELD_PREP(W0_MASK( 6,  3), v)
0090 
0091 /*
0092  * Internal Control Command
0093  */
0094 
0095 #define CMD_0_ATTR_M            FIELD_PREP(CMD_0_ATTR, 0x7)
0096 
0097 #define CMD_M1_VENDOR_SPECIFIC             W1_MASK(63, 32)
0098 #define CMD_M0_MIPI_RESERVED               W0_MASK(31, 12)
0099 #define CMD_M0_MIPI_CMD                W0_MASK(11,  8)
0100 #define CMD_M0_VENDOR_INFO_PRESENT         W0_BIT_( 7)
0101 #define CMD_M0_TID(v)           FIELD_PREP(W0_MASK( 6,  3), v)
0102 
0103 
0104 /* Data Transfer Speed and Mode */
0105 enum hci_cmd_mode {
0106     MODE_I3C_SDR0       = 0x0,
0107     MODE_I3C_SDR1       = 0x1,
0108     MODE_I3C_SDR2       = 0x2,
0109     MODE_I3C_SDR3       = 0x3,
0110     MODE_I3C_SDR4       = 0x4,
0111     MODE_I3C_HDR_TSx    = 0x5,
0112     MODE_I3C_HDR_DDR    = 0x6,
0113     MODE_I3C_HDR_BT     = 0x7,
0114     MODE_I3C_Fm_FmP     = 0x8,
0115     MODE_I2C_Fm     = 0x0,
0116     MODE_I2C_FmP        = 0x1,
0117     MODE_I2C_UD1        = 0x2,
0118     MODE_I2C_UD2        = 0x3,
0119     MODE_I2C_UD3        = 0x4,
0120 };
0121 
0122 static enum hci_cmd_mode get_i3c_mode(struct i3c_hci *hci)
0123 {
0124     struct i3c_bus *bus = i3c_master_get_bus(&hci->master);
0125 
0126     if (bus->scl_rate.i3c >= 12500000)
0127         return MODE_I3C_SDR0;
0128     if (bus->scl_rate.i3c > 8000000)
0129         return MODE_I3C_SDR1;
0130     if (bus->scl_rate.i3c > 6000000)
0131         return MODE_I3C_SDR2;
0132     if (bus->scl_rate.i3c > 4000000)
0133         return MODE_I3C_SDR3;
0134     if (bus->scl_rate.i3c > 2000000)
0135         return MODE_I3C_SDR4;
0136     return MODE_I3C_Fm_FmP;
0137 }
0138 
0139 static enum hci_cmd_mode get_i2c_mode(struct i3c_hci *hci)
0140 {
0141     struct i3c_bus *bus = i3c_master_get_bus(&hci->master);
0142 
0143     if (bus->scl_rate.i2c >= 1000000)
0144         return MODE_I2C_FmP;
0145     return MODE_I2C_Fm;
0146 }
0147 
0148 static void fill_data_bytes(struct hci_xfer *xfer, u8 *data,
0149                 unsigned int data_len)
0150 {
0151     xfer->cmd_desc[1] = 0;
0152     switch (data_len) {
0153     case 4:
0154         xfer->cmd_desc[1] |= CMD_I1_DATA_BYTE_4(data[3]);
0155         fallthrough;
0156     case 3:
0157         xfer->cmd_desc[1] |= CMD_I1_DATA_BYTE_3(data[2]);
0158         fallthrough;
0159     case 2:
0160         xfer->cmd_desc[1] |= CMD_I1_DATA_BYTE_2(data[1]);
0161         fallthrough;
0162     case 1:
0163         xfer->cmd_desc[1] |= CMD_I1_DATA_BYTE_1(data[0]);
0164         fallthrough;
0165     case 0:
0166         break;
0167     }
0168     /* we consumed all the data with the cmd descriptor */
0169     xfer->data = NULL;
0170 }
0171 
0172 static int hci_cmd_v1_prep_ccc(struct i3c_hci *hci,
0173                    struct hci_xfer *xfer,
0174                    u8 ccc_addr, u8 ccc_cmd, bool raw)
0175 {
0176     unsigned int dat_idx = 0;
0177     enum hci_cmd_mode mode = get_i3c_mode(hci);
0178     u8 *data = xfer->data;
0179     unsigned int data_len = xfer->data_len;
0180     bool rnw = xfer->rnw;
0181     int ret;
0182 
0183     /* this should never happen */
0184     if (WARN_ON(raw))
0185         return -EINVAL;
0186 
0187     if (ccc_addr != I3C_BROADCAST_ADDR) {
0188         ret = mipi_i3c_hci_dat_v1.get_index(hci, ccc_addr);
0189         if (ret < 0)
0190             return ret;
0191         dat_idx = ret;
0192     }
0193 
0194     xfer->cmd_tid = hci_get_tid();
0195 
0196     if (!rnw && data_len <= 4) {
0197         /* we use an Immediate Data Transfer Command */
0198         xfer->cmd_desc[0] =
0199             CMD_0_ATTR_I |
0200             CMD_I0_TID(xfer->cmd_tid) |
0201             CMD_I0_CMD(ccc_cmd) | CMD_I0_CP |
0202             CMD_I0_DEV_INDEX(dat_idx) |
0203             CMD_I0_DTT(data_len) |
0204             CMD_I0_MODE(mode);
0205         fill_data_bytes(xfer, data, data_len);
0206     } else {
0207         /* we use a Regular Data Transfer Command */
0208         xfer->cmd_desc[0] =
0209             CMD_0_ATTR_R |
0210             CMD_R0_TID(xfer->cmd_tid) |
0211             CMD_R0_CMD(ccc_cmd) | CMD_R0_CP |
0212             CMD_R0_DEV_INDEX(dat_idx) |
0213             CMD_R0_MODE(mode) |
0214             (rnw ? CMD_R0_RNW : 0);
0215         xfer->cmd_desc[1] =
0216             CMD_R1_DATA_LENGTH(data_len);
0217     }
0218 
0219     return 0;
0220 }
0221 
0222 static void hci_cmd_v1_prep_i3c_xfer(struct i3c_hci *hci,
0223                      struct i3c_dev_desc *dev,
0224                      struct hci_xfer *xfer)
0225 {
0226     struct i3c_hci_dev_data *dev_data = i3c_dev_get_master_data(dev);
0227     unsigned int dat_idx = dev_data->dat_idx;
0228     enum hci_cmd_mode mode = get_i3c_mode(hci);
0229     u8 *data = xfer->data;
0230     unsigned int data_len = xfer->data_len;
0231     bool rnw = xfer->rnw;
0232 
0233     xfer->cmd_tid = hci_get_tid();
0234 
0235     if (!rnw && data_len <= 4) {
0236         /* we use an Immediate Data Transfer Command */
0237         xfer->cmd_desc[0] =
0238             CMD_0_ATTR_I |
0239             CMD_I0_TID(xfer->cmd_tid) |
0240             CMD_I0_DEV_INDEX(dat_idx) |
0241             CMD_I0_DTT(data_len) |
0242             CMD_I0_MODE(mode);
0243         fill_data_bytes(xfer, data, data_len);
0244     } else {
0245         /* we use a Regular Data Transfer Command */
0246         xfer->cmd_desc[0] =
0247             CMD_0_ATTR_R |
0248             CMD_R0_TID(xfer->cmd_tid) |
0249             CMD_R0_DEV_INDEX(dat_idx) |
0250             CMD_R0_MODE(mode) |
0251             (rnw ? CMD_R0_RNW : 0);
0252         xfer->cmd_desc[1] =
0253             CMD_R1_DATA_LENGTH(data_len);
0254     }
0255 }
0256 
0257 static void hci_cmd_v1_prep_i2c_xfer(struct i3c_hci *hci,
0258                      struct i2c_dev_desc *dev,
0259                      struct hci_xfer *xfer)
0260 {
0261     struct i3c_hci_dev_data *dev_data = i2c_dev_get_master_data(dev);
0262     unsigned int dat_idx = dev_data->dat_idx;
0263     enum hci_cmd_mode mode = get_i2c_mode(hci);
0264     u8 *data = xfer->data;
0265     unsigned int data_len = xfer->data_len;
0266     bool rnw = xfer->rnw;
0267 
0268     xfer->cmd_tid = hci_get_tid();
0269 
0270     if (!rnw && data_len <= 4) {
0271         /* we use an Immediate Data Transfer Command */
0272         xfer->cmd_desc[0] =
0273             CMD_0_ATTR_I |
0274             CMD_I0_TID(xfer->cmd_tid) |
0275             CMD_I0_DEV_INDEX(dat_idx) |
0276             CMD_I0_DTT(data_len) |
0277             CMD_I0_MODE(mode);
0278         fill_data_bytes(xfer, data, data_len);
0279     } else {
0280         /* we use a Regular Data Transfer Command */
0281         xfer->cmd_desc[0] =
0282             CMD_0_ATTR_R |
0283             CMD_R0_TID(xfer->cmd_tid) |
0284             CMD_R0_DEV_INDEX(dat_idx) |
0285             CMD_R0_MODE(mode) |
0286             (rnw ? CMD_R0_RNW : 0);
0287         xfer->cmd_desc[1] =
0288             CMD_R1_DATA_LENGTH(data_len);
0289     }
0290 }
0291 
0292 static int hci_cmd_v1_daa(struct i3c_hci *hci)
0293 {
0294     struct hci_xfer *xfer;
0295     int ret, dat_idx = -1;
0296     u8 next_addr = 0;
0297     u64 pid;
0298     unsigned int dcr, bcr;
0299     DECLARE_COMPLETION_ONSTACK(done);
0300 
0301     xfer = hci_alloc_xfer(2);
0302     if (!xfer)
0303         return -ENOMEM;
0304 
0305     /*
0306      * Simple for now: we allocate a temporary DAT entry, do a single
0307      * DAA, register the device which will allocate its own DAT entry
0308      * via the core callback, then free the temporary DAT entry.
0309      * Loop until there is no more devices to assign an address to.
0310      * Yes, there is room for improvements.
0311      */
0312     for (;;) {
0313         ret = mipi_i3c_hci_dat_v1.alloc_entry(hci);
0314         if (ret < 0)
0315             break;
0316         dat_idx = ret;
0317         ret = i3c_master_get_free_addr(&hci->master, next_addr);
0318         if (ret < 0)
0319             break;
0320         next_addr = ret;
0321 
0322         DBG("next_addr = 0x%02x, DAA using DAT %d", next_addr, dat_idx);
0323         mipi_i3c_hci_dat_v1.set_dynamic_addr(hci, dat_idx, next_addr);
0324         mipi_i3c_hci_dct_index_reset(hci);
0325 
0326         xfer->cmd_tid = hci_get_tid();
0327         xfer->cmd_desc[0] =
0328             CMD_0_ATTR_A |
0329             CMD_A0_TID(xfer->cmd_tid) |
0330             CMD_A0_CMD(I3C_CCC_ENTDAA) |
0331             CMD_A0_DEV_INDEX(dat_idx) |
0332             CMD_A0_DEV_COUNT(1) |
0333             CMD_A0_ROC | CMD_A0_TOC;
0334         xfer->cmd_desc[1] = 0;
0335         hci->io->queue_xfer(hci, xfer, 1);
0336         if (!wait_for_completion_timeout(&done, HZ) &&
0337             hci->io->dequeue_xfer(hci, xfer, 1)) {
0338             ret = -ETIME;
0339             break;
0340         }
0341         if (RESP_STATUS(xfer[0].response) == RESP_ERR_NACK &&
0342             RESP_STATUS(xfer[0].response) == 1) {
0343             ret = 0;  /* no more devices to be assigned */
0344             break;
0345         }
0346         if (RESP_STATUS(xfer[0].response) != RESP_SUCCESS) {
0347             ret = -EIO;
0348             break;
0349         }
0350 
0351         i3c_hci_dct_get_val(hci, 0, &pid, &dcr, &bcr);
0352         DBG("assigned address %#x to device PID=0x%llx DCR=%#x BCR=%#x",
0353             next_addr, pid, dcr, bcr);
0354 
0355         mipi_i3c_hci_dat_v1.free_entry(hci, dat_idx);
0356         dat_idx = -1;
0357 
0358         /*
0359          * TODO: Extend the subsystem layer to allow for registering
0360          * new device and provide BCR/DCR/PID at the same time.
0361          */
0362         ret = i3c_master_add_i3c_dev_locked(&hci->master, next_addr);
0363         if (ret)
0364             break;
0365     }
0366 
0367     if (dat_idx >= 0)
0368         mipi_i3c_hci_dat_v1.free_entry(hci, dat_idx);
0369     hci_free_xfer(xfer, 1);
0370     return ret;
0371 }
0372 
0373 const struct hci_cmd_ops mipi_i3c_hci_cmd_v1 = {
0374     .prep_ccc       = hci_cmd_v1_prep_ccc,
0375     .prep_i3c_xfer      = hci_cmd_v1_prep_i3c_xfer,
0376     .prep_i2c_xfer      = hci_cmd_v1_prep_i2c_xfer,
0377     .perform_daa        = hci_cmd_v1_daa,
0378 };