/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and * only version 2 as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ #ifndef _H_MHI_MACROS #define _H_MHI_MACROS #define MHI_IPC_LOG_PAGES (100) #define MAX_BOUNCE_BUF_SIZE 0x2000 #define MHI_LOG_SIZE 0x1000 #define MHI_LINK_STABILITY_WAIT_MS 100 #define MHI_DEVICE_WAKE_DBOUNCE_TIMEOUT_MS 10 #define MHI_MAX_LINK_RETRIES 9 #define DT_WAIT_RETRIES 30 #define MHI_MAX_SUSPEND_RETRIES 1000 #define MHI_VERSION 0x01000000 #define ALIGNMENT_OFFSET 0xFFF #define NR_OF_CMD_RINGS 1 #define EV_EL_PER_RING (256 + 16) #define CMD_EL_PER_RING 128 #define ELEMENT_GAP 1 #define MHI_EPID 4 #define MHI_MAX_STATE_TRANSITION_TIMEOUT 5000 #define MHI_MAX_CMD_TIMEOUT 500 #define MHI_RPM_AUTOSUSPEND_TMR_VAL_MS 1000 #define MAX_BUF_SIZE 32 #define HW_EVENT_RINGS_ALLOCATED 2 #define PRIMARY_CMD_RING 0 #define MHI_WORK_Q_MAX_SIZE 128 #define MAX_XFER_WORK_ITEMS 100 #define MHI_PCIE_VENDOR_ID 0x17CB #define MHI_PCIE_DEVICE_ID_9x35 0x0300 #define MHI_PCIE_DEVICE_ID_ZIRC 0x0301 #define MHI_PCIE_DEVICE_ID_9x55 0x0302 #define MHI_M2_DEBOUNCE_TMR_US 10000 #define MHI_EV_DB_INTERVAL 1 #define MHI_DEV_WAKE_DB 127 #define MHI_HANDLE_MAGIC 0x12344321 /* PCIe Device Info */ #define MHI_PCIE_DEVICE_BAR0_OFFSET_LOW (16) #define MHI_PCIE_DEVICE_BAR0_OFFSET_HIGH (20) #define MHI_PCIE_DEVICE_MANUFACT_ID_OFFSET (0) #define MHI_PCIE_DEVICE_ID_OFFSET (2) #define IS_HARDWARE_CHANNEL(_CHAN_NR) \ (((enum MHI_CLIENT_CHANNEL)(_CHAN_NR) > \ MHI_CLIENT_RESERVED_1_UPPER) && \ ((enum MHI_CLIENT_CHANNEL)(_CHAN_NR) < MHI_CLIENT_RESERVED_2_LOWER)) #define IS_SOFTWARE_CHANNEL(_CHAN_NR) \ (((enum MHI_CLIENT_CHANNEL)(_CHAN_NR) >= 0) && \ ((enum MHI_CLIENT_CHANNEL)(_CHAN_NR) < MHI_CLIENT_RESERVED_1_LOWER)) #define IRQ_TO_MSI(_MHI_DEV_CTXT, _IRQ_NR) \ ((_IRQ_NR) - (_MHI_DEV_CTXT)->core.irq_base) #define MSI_TO_IRQ(_MHI_DEV_CTXT, _MSI_NR) \ ((_MHI_DEV_CTXT)->core.irq_base + (_MSI_NR)) #define VALID_CHAN_NR(_CHAN_NR) (IS_HARDWARE_CHANNEL(_CHAN_NR) || \ IS_SOFTWARE_CHANNEL(_CHAN_NR)) #define VALID_BUF(_BUF_ADDR, _BUF_LEN, _MHI_DEV_CTXT) \ (((uintptr_t)(_BUF_ADDR) >= \ mhi_dev_ctxt->dev_space.start_win_addr) && \ (((uintptr_t)(_BUF_ADDR) + (uintptr_t)(_BUF_LEN) < \ mhi_dev_ctxt->dev_space.end_win_addr))) #define MHI_HW_INTMOD_VAL_MS 2 /* Timeout Values */ #define MHI_READY_STATUS_TIMEOUT_MS 500 #define MHI_THREAD_SLEEP_TIMEOUT_MS 100 #define MHI_RESUME_WAKE_RETRIES 20 #define IS_HW_EV_RING(_mhi_dev_ctxt, _EV_INDEX) (_EV_INDEX >= \ ((_mhi_dev_ctxt)->mmio_info.nr_event_rings - \ ((_mhi_dev_ctxt)->mmio_info.nr_hw_event_rings))) #define IS_SW_EV_RING(_mhi_dev_ctxt, _EV_INDEX) (_EV_INDEX < \ ((_mhi_dev_ctxt)->mmio_info.nr_event_rings - \ ((_mhi_dev_ctxt)->mmio_info.nr_hw_event_rings))) /* MHI Transfer Ring Elements 7.4.1*/ #define TX_TRB_LEN #define MHI_TX_TRB_LEN__SHIFT (0) #define MHI_TX_TRB_LEN__MASK (0xFFFF) #define MHI_TX_TRB_SET_LEN(_FIELD, _PKT, _VAL) \ { \ u32 new_val = ((_PKT)->data_tx_pkt).buf_len; \ new_val &= (~((MHI_##_FIELD ## __MASK) << MHI_##_FIELD ## __SHIFT)); \ new_val |= (_VAL) << MHI_##_FIELD ## __SHIFT; \ new_val &= (((MHI_##_FIELD ## __MASK) << MHI_##_FIELD ## __SHIFT)); \ ((_PKT)->data_tx_pkt).buf_len = new_val; \ } #define MHI_TX_TRB_GET_LEN(_FIELD, _PKT) \ (((_PKT)->data_tx_pkt).buf_len & (((MHI_##_FIELD ## __MASK) << \ MHI_##_FIELD ## __SHIFT))) \ /* MHI Event Ring Elements 7.4.1*/ #define EV_TRB_CODE #define MHI_EV_TRB_CODE__MASK (0xFF) #define MHI_EV_TRB_CODE__SHIFT (24) #define MHI_EV_READ_CODE(_FIELD, _PKT) (((_PKT->type).xfer_details >> \ MHI_##_FIELD ## __SHIFT) & \ MHI_ ##_FIELD ## __MASK) #define EV_LEN #define MHI_EV_LEN__MASK (0xFFFF) #define MHI_EV_LEN__SHIFT (0) #define MHI_EV_READ_LEN(_FIELD, _PKT) (((_PKT->xfer_event_pkt).xfer_details >> \ MHI_##_FIELD ## __SHIFT) & \ MHI_ ##_FIELD ## __MASK) #define EV_CHID #define MHI_EV_CHID__MASK (0xFF) #define MHI_EV_CHID__SHIFT (24) #define MHI_EV_READ_CHID(_FIELD, _PKT) ((((_PKT)->xfer_event_pkt).info >> \ MHI_##_FIELD ## __SHIFT) & \ MHI_ ##_FIELD ## __MASK) #define EV_PTR #define MHI_EV_PTR__MASK (0xFFFFFFFFFFFFFFFFULL) #define MHI_EV_PTR__SHIFT (0) #define MHI_EV_READ_PTR(_FIELD, _PKT) ((((_PKT)->xfer_event_pkt).xfer_ptr >> \ MHI_##_FIELD ## __SHIFT) & \ MHI_ ##_FIELD ## __MASK) #define EV_STATE #define MHI_EV_STATE__MASK (0xFF) #define MHI_EV_STATE__SHIFT (24) #define MHI_READ_STATE(_PKT) ((((_PKT)->state_change_event_pkt).state >> \ MHI_EV_STATE__SHIFT) & \ MHI_EV_STATE__MASK) #define EXEC_ENV #define MHI_EXEC_ENV__MASK (0xFF) #define MHI_EXEC_ENV__SHIFT (24) #define MHI_READ_EXEC_ENV(_PKT) ((((_PKT)->ee_event_pkt).exec_env>> \ MHI_EXEC_ENV__SHIFT) & \ MHI_EXEC_ENV__MASK) /* MacroS for reading common "info" field for TRBs*/ #define TX_TRB_CHAIN #define MHI_TX_TRB_CHAIN__SHIFT (0) #define MHI_TX_TRB_CHAIN__MASK (0x1) #define TX_TRB_IEOB #define MHI_TX_TRB_IEOB__MASK (0x1) #define MHI_TX_TRB_IEOB__SHIFT (8) #define TX_TRB_IEOT #define MHI_TX_TRB_IEOT__MASK (0x1) #define MHI_TX_TRB_IEOT__SHIFT (9) #define TX_TRB_BEI #define MHI_TX_TRB_BEI__MASK (0x1) #define MHI_TX_TRB_BEI__SHIFT (10) #define TX_TRB_TYPE #define MHI_TX_TRB_TYPE__MASK (0xFF) #define MHI_TX_TRB_TYPE__SHIFT (16) #define EV_TRB_TYPE #define MHI_EV_TRB_TYPE__MASK (0xFF) #define MHI_EV_TRB_TYPE__SHIFT (16) #define CMD_TRB_TYPE #define MHI_CMD_TRB_TYPE__MASK (0xFF) #define MHI_CMD_TRB_TYPE__SHIFT (16) #define CMD_TRB_CHID #define MHI_CMD_TRB_CHID__MASK (0xFF) #define MHI_CMD_TRB_CHID__SHIFT (24) #define MHI_TRB_SET_INFO(_FIELD, _PKT, _VAL) \ do { \ u32 new_val = ((_PKT)->type).info; \ new_val &= (~((MHI_##_FIELD ## __MASK) << \ MHI_##_FIELD ## __SHIFT)); \ new_val |= _VAL << MHI_##_FIELD ## __SHIFT; \ (_PKT->type).info = new_val; \ } while (0) #define MHI_TRB_GET_INFO(_FIELD, _PKT, _DEST) \ do { \ _DEST = ((_PKT)->type).info; \ _DEST &= (((MHI_##_FIELD ## __MASK) << \ MHI_##_FIELD ## __SHIFT)); \ _DEST >>= MHI_##_FIELD ## __SHIFT; \ } while (0) #define MHI_TRB_READ_INFO(_FIELD, _PKT) \ ((((_PKT)->type).info >> MHI_##_FIELD ## __SHIFT) & \ MHI_##_FIELD ## __MASK) #define HIGH_WORD(_x) ((u32)((((u64)(_x)) >> 32) & 0xFFFFFFFF)) #define LOW_WORD(_x) ((u32)(((u64)(_x)) & 0xFFFFFFFF)) #define EVENT_CTXT_INTMODT #define MHI_EVENT_CTXT_INTMODT__MASK (0xFFFF) #define MHI_EVENT_CTXT_INTMODT__SHIFT (16) #define MHI_SET_EV_CTXT(_FIELD, _CTXT, _VAL) \ { \ u32 new_val = (_VAL << MHI_##_FIELD ## __SHIFT); \ new_val &= (MHI_##_FIELD ## __MASK << MHI_##_FIELD ## __SHIFT); \ (_CTXT)->mhi_intmodt &= (~((MHI_##_FIELD ## __MASK) << \ MHI_##_FIELD ## __SHIFT)); \ (_CTXT)->mhi_intmodt |= new_val; \ } #define MHI_GET_EV_CTXT(_FIELD, _CTXT) \ (((_CTXT)->mhi_intmodt >> MHI_##_FIELD ## __SHIFT) & \ MHI_##_FIELD ## __MASK) #define MHI_READ_FIELD(_val, _mask, _shift) \ do { \ _val &= (u32)(_mask); \ _val >>= (u32)(_shift); \ } while (0) #define CHAN_BRINGUP_STAGE #define MHI_CHAN_BRINGUP_STAGE__MASK (3) #define MHI_CHAN_BRINGUP_STAGE__SHIFT (0) #define CHAN_DIR #define MHI_CHAN_DIR__MASK (3) #define MHI_CHAN_DIR__SHIFT (4) #define CHAN_TYPE #define MHI_CHAN_TYPE__MASK (3) #define MHI_CHAN_TYPE__SHIFT (6) #define PRESERVE_DB_STATE #define MHI_PRESERVE_DB_STATE__MASK (1) #define MHI_PRESERVE_DB_STATE__SHIFT (8) #define BRSTMODE #define MHI_BRSTMODE__MASK (3) #define MHI_BRSTMODE__SHIFT (9) #define GET_CHAN_PROPS(_FIELD, _VAL) \ (((_VAL) >> MHI_##_FIELD ## __SHIFT) & MHI_##_FIELD ## __MASK) #define EV_BRSTMODE #define MHI_EV_BRSTMODE__MASK (3) #define MHI_EV_BRSTMODE__SHIFT (5) #define EV_TYPE #define MHI_EV_TYPE__MASK (3) #define MHI_EV_TYPE__SHIFT (3) #define EV_MANAGED #define MHI_EV_MANAGED__MASK (3) #define MHI_EV_MANAGED__SHIFT (0) #define GET_EV_PROPS(_FIELD, _VAL) \ (((_VAL) >> MHI_##_FIELD ## __SHIFT) & MHI_##_FIELD ## __MASK) #endif