Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 /*
0003  * Copyright (c) 2022, Linaro Ltd.
0004  *
0005  */
0006 
0007 #ifndef _MHI_EP_INTERNAL_
0008 #define _MHI_EP_INTERNAL_
0009 
0010 #include <linux/bitfield.h>
0011 
0012 #include "../common.h"
0013 
0014 extern struct bus_type mhi_ep_bus_type;
0015 
0016 #define MHI_REG_OFFSET              0x100
0017 #define BHI_REG_OFFSET              0x200
0018 
0019 /* MHI registers */
0020 #define EP_MHIREGLEN                (MHI_REG_OFFSET + MHIREGLEN)
0021 #define EP_MHIVER               (MHI_REG_OFFSET + MHIVER)
0022 #define EP_MHICFG               (MHI_REG_OFFSET + MHICFG)
0023 #define EP_CHDBOFF              (MHI_REG_OFFSET + CHDBOFF)
0024 #define EP_ERDBOFF              (MHI_REG_OFFSET + ERDBOFF)
0025 #define EP_BHIOFF               (MHI_REG_OFFSET + BHIOFF)
0026 #define EP_BHIEOFF              (MHI_REG_OFFSET + BHIEOFF)
0027 #define EP_DEBUGOFF             (MHI_REG_OFFSET + DEBUGOFF)
0028 #define EP_MHICTRL              (MHI_REG_OFFSET + MHICTRL)
0029 #define EP_MHISTATUS                (MHI_REG_OFFSET + MHISTATUS)
0030 #define EP_CCABAP_LOWER             (MHI_REG_OFFSET + CCABAP_LOWER)
0031 #define EP_CCABAP_HIGHER            (MHI_REG_OFFSET + CCABAP_HIGHER)
0032 #define EP_ECABAP_LOWER             (MHI_REG_OFFSET + ECABAP_LOWER)
0033 #define EP_ECABAP_HIGHER            (MHI_REG_OFFSET + ECABAP_HIGHER)
0034 #define EP_CRCBAP_LOWER             (MHI_REG_OFFSET + CRCBAP_LOWER)
0035 #define EP_CRCBAP_HIGHER            (MHI_REG_OFFSET + CRCBAP_HIGHER)
0036 #define EP_CRDB_LOWER               (MHI_REG_OFFSET + CRDB_LOWER)
0037 #define EP_CRDB_HIGHER              (MHI_REG_OFFSET + CRDB_HIGHER)
0038 #define EP_MHICTRLBASE_LOWER            (MHI_REG_OFFSET + MHICTRLBASE_LOWER)
0039 #define EP_MHICTRLBASE_HIGHER           (MHI_REG_OFFSET + MHICTRLBASE_HIGHER)
0040 #define EP_MHICTRLLIMIT_LOWER           (MHI_REG_OFFSET + MHICTRLLIMIT_LOWER)
0041 #define EP_MHICTRLLIMIT_HIGHER          (MHI_REG_OFFSET + MHICTRLLIMIT_HIGHER)
0042 #define EP_MHIDATABASE_LOWER            (MHI_REG_OFFSET + MHIDATABASE_LOWER)
0043 #define EP_MHIDATABASE_HIGHER           (MHI_REG_OFFSET + MHIDATABASE_HIGHER)
0044 #define EP_MHIDATALIMIT_LOWER           (MHI_REG_OFFSET + MHIDATALIMIT_LOWER)
0045 #define EP_MHIDATALIMIT_HIGHER          (MHI_REG_OFFSET + MHIDATALIMIT_HIGHER)
0046 
0047 /* MHI BHI registers */
0048 #define EP_BHI_INTVEC               (BHI_REG_OFFSET + BHI_INTVEC)
0049 #define EP_BHI_EXECENV              (BHI_REG_OFFSET + BHI_EXECENV)
0050 
0051 /* MHI Doorbell registers */
0052 #define CHDB_LOWER_n(n)             (0x400 + 0x8 * (n))
0053 #define CHDB_HIGHER_n(n)            (0x404 + 0x8 * (n))
0054 #define ERDB_LOWER_n(n)             (0x800 + 0x8 * (n))
0055 #define ERDB_HIGHER_n(n)            (0x804 + 0x8 * (n))
0056 
0057 #define MHI_CTRL_INT_STATUS         0x4
0058 #define MHI_CTRL_INT_STATUS_MSK         BIT(0)
0059 #define MHI_CTRL_INT_STATUS_CRDB_MSK        BIT(1)
0060 #define MHI_CHDB_INT_STATUS_n(n)        (0x28 + 0x4 * (n))
0061 #define MHI_ERDB_INT_STATUS_n(n)        (0x38 + 0x4 * (n))
0062 
0063 #define MHI_CTRL_INT_CLEAR          0x4c
0064 #define MHI_CTRL_INT_MMIO_WR_CLEAR      BIT(2)
0065 #define MHI_CTRL_INT_CRDB_CLEAR         BIT(1)
0066 #define MHI_CTRL_INT_CRDB_MHICTRL_CLEAR     BIT(0)
0067 
0068 #define MHI_CHDB_INT_CLEAR_n(n)         (0x70 + 0x4 * (n))
0069 #define MHI_CHDB_INT_CLEAR_n_CLEAR_ALL      GENMASK(31, 0)
0070 #define MHI_ERDB_INT_CLEAR_n(n)         (0x80 + 0x4 * (n))
0071 #define MHI_ERDB_INT_CLEAR_n_CLEAR_ALL      GENMASK(31, 0)
0072 
0073 /*
0074  * Unlike the usual "masking" convention, writing "1" to a bit in this register
0075  * enables the interrupt and writing "0" will disable it..
0076  */
0077 #define MHI_CTRL_INT_MASK           0x94
0078 #define MHI_CTRL_INT_MASK_MASK          GENMASK(1, 0)
0079 #define MHI_CTRL_MHICTRL_MASK           BIT(0)
0080 #define MHI_CTRL_CRDB_MASK          BIT(1)
0081 
0082 #define MHI_CHDB_INT_MASK_n(n)          (0xb8 + 0x4 * (n))
0083 #define MHI_CHDB_INT_MASK_n_EN_ALL      GENMASK(31, 0)
0084 #define MHI_ERDB_INT_MASK_n(n)          (0xc8 + 0x4 * (n))
0085 #define MHI_ERDB_INT_MASK_n_EN_ALL      GENMASK(31, 0)
0086 
0087 #define NR_OF_CMD_RINGS             1
0088 #define MHI_MASK_ROWS_CH_DB         4
0089 #define MHI_MASK_ROWS_EV_DB         4
0090 #define MHI_MASK_CH_LEN             32
0091 #define MHI_MASK_EV_LEN             32
0092 
0093 /* Generic context */
0094 struct mhi_generic_ctx {
0095     __le32 reserved0;
0096     __le32 reserved1;
0097     __le32 reserved2;
0098 
0099     __le64 rbase __packed __aligned(4);
0100     __le64 rlen __packed __aligned(4);
0101     __le64 rp __packed __aligned(4);
0102     __le64 wp __packed __aligned(4);
0103 };
0104 
0105 enum mhi_ep_ring_type {
0106     RING_TYPE_CMD,
0107     RING_TYPE_ER,
0108     RING_TYPE_CH,
0109 };
0110 
0111 /* Ring element */
0112 union mhi_ep_ring_ctx {
0113     struct mhi_cmd_ctxt cmd;
0114     struct mhi_event_ctxt ev;
0115     struct mhi_chan_ctxt ch;
0116     struct mhi_generic_ctx generic;
0117 };
0118 
0119 struct mhi_ep_ring_item {
0120     struct list_head node;
0121     struct mhi_ep_ring *ring;
0122 };
0123 
0124 struct mhi_ep_ring {
0125     struct mhi_ep_cntrl *mhi_cntrl;
0126     union mhi_ep_ring_ctx *ring_ctx;
0127     struct mhi_ring_element *ring_cache;
0128     enum mhi_ep_ring_type type;
0129     u64 rbase;
0130     size_t rd_offset;
0131     size_t wr_offset;
0132     size_t ring_size;
0133     u32 db_offset_h;
0134     u32 db_offset_l;
0135     u32 ch_id;
0136     u32 er_index;
0137     u32 irq_vector;
0138     bool started;
0139 };
0140 
0141 struct mhi_ep_cmd {
0142     struct mhi_ep_ring ring;
0143 };
0144 
0145 struct mhi_ep_event {
0146     struct mhi_ep_ring ring;
0147 };
0148 
0149 struct mhi_ep_state_transition {
0150     struct list_head node;
0151     enum mhi_state state;
0152 };
0153 
0154 struct mhi_ep_chan {
0155     char *name;
0156     struct mhi_ep_device *mhi_dev;
0157     struct mhi_ep_ring ring;
0158     struct mutex lock;
0159     void (*xfer_cb)(struct mhi_ep_device *mhi_dev, struct mhi_result *result);
0160     enum mhi_ch_state state;
0161     enum dma_data_direction dir;
0162     u64 tre_loc;
0163     u32 tre_size;
0164     u32 tre_bytes_left;
0165     u32 chan;
0166     bool skip_td;
0167 };
0168 
0169 /* MHI Ring related functions */
0170 void mhi_ep_ring_init(struct mhi_ep_ring *ring, enum mhi_ep_ring_type type, u32 id);
0171 void mhi_ep_ring_reset(struct mhi_ep_cntrl *mhi_cntrl, struct mhi_ep_ring *ring);
0172 int mhi_ep_ring_start(struct mhi_ep_cntrl *mhi_cntrl, struct mhi_ep_ring *ring,
0173               union mhi_ep_ring_ctx *ctx);
0174 size_t mhi_ep_ring_addr2offset(struct mhi_ep_ring *ring, u64 ptr);
0175 int mhi_ep_ring_add_element(struct mhi_ep_ring *ring, struct mhi_ring_element *element);
0176 void mhi_ep_ring_inc_index(struct mhi_ep_ring *ring);
0177 int mhi_ep_update_wr_offset(struct mhi_ep_ring *ring);
0178 
0179 /* MMIO related functions */
0180 u32 mhi_ep_mmio_read(struct mhi_ep_cntrl *mhi_cntrl, u32 offset);
0181 void mhi_ep_mmio_write(struct mhi_ep_cntrl *mhi_cntrl, u32 offset, u32 val);
0182 void mhi_ep_mmio_masked_write(struct mhi_ep_cntrl *mhi_cntrl, u32 offset, u32 mask, u32 val);
0183 u32 mhi_ep_mmio_masked_read(struct mhi_ep_cntrl *dev, u32 offset, u32 mask);
0184 void mhi_ep_mmio_enable_ctrl_interrupt(struct mhi_ep_cntrl *mhi_cntrl);
0185 void mhi_ep_mmio_disable_ctrl_interrupt(struct mhi_ep_cntrl *mhi_cntrl);
0186 void mhi_ep_mmio_enable_cmdb_interrupt(struct mhi_ep_cntrl *mhi_cntrl);
0187 void mhi_ep_mmio_disable_cmdb_interrupt(struct mhi_ep_cntrl *mhi_cntrl);
0188 void mhi_ep_mmio_enable_chdb(struct mhi_ep_cntrl *mhi_cntrl, u32 ch_id);
0189 void mhi_ep_mmio_disable_chdb(struct mhi_ep_cntrl *mhi_cntrl, u32 ch_id);
0190 void mhi_ep_mmio_enable_chdb_interrupts(struct mhi_ep_cntrl *mhi_cntrl);
0191 bool mhi_ep_mmio_read_chdb_status_interrupts(struct mhi_ep_cntrl *mhi_cntrl);
0192 void mhi_ep_mmio_mask_interrupts(struct mhi_ep_cntrl *mhi_cntrl);
0193 void mhi_ep_mmio_get_chc_base(struct mhi_ep_cntrl *mhi_cntrl);
0194 void mhi_ep_mmio_get_erc_base(struct mhi_ep_cntrl *mhi_cntrl);
0195 void mhi_ep_mmio_get_crc_base(struct mhi_ep_cntrl *mhi_cntrl);
0196 u64 mhi_ep_mmio_get_db(struct mhi_ep_ring *ring);
0197 void mhi_ep_mmio_set_env(struct mhi_ep_cntrl *mhi_cntrl, u32 value);
0198 void mhi_ep_mmio_clear_reset(struct mhi_ep_cntrl *mhi_cntrl);
0199 void mhi_ep_mmio_reset(struct mhi_ep_cntrl *mhi_cntrl);
0200 void mhi_ep_mmio_get_mhi_state(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_state *state,
0201                    bool *mhi_reset);
0202 void mhi_ep_mmio_init(struct mhi_ep_cntrl *mhi_cntrl);
0203 void mhi_ep_mmio_update_ner(struct mhi_ep_cntrl *mhi_cntrl);
0204 
0205 /* MHI EP core functions */
0206 int mhi_ep_send_state_change_event(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_state state);
0207 int mhi_ep_send_ee_event(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_ee_type exec_env);
0208 bool mhi_ep_check_mhi_state(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_state cur_mhi_state,
0209                 enum mhi_state mhi_state);
0210 int mhi_ep_set_mhi_state(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_state mhi_state);
0211 int mhi_ep_set_m0_state(struct mhi_ep_cntrl *mhi_cntrl);
0212 int mhi_ep_set_m3_state(struct mhi_ep_cntrl *mhi_cntrl);
0213 int mhi_ep_set_ready_state(struct mhi_ep_cntrl *mhi_cntrl);
0214 void mhi_ep_handle_syserr(struct mhi_ep_cntrl *mhi_cntrl);
0215 void mhi_ep_resume_channels(struct mhi_ep_cntrl *mhi_cntrl);
0216 void mhi_ep_suspend_channels(struct mhi_ep_cntrl *mhi_cntrl);
0217 
0218 #endif