android13/kernel-5.10/drivers/sprd_pcie/sipc/sblock.h

174 lines
4.0 KiB
C
Executable File

/*
* Copyright (C) 2019 Spreadtrum Communications Inc.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* 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 __SBLOCK_H
#define __SBLOCK_H
/* flag for CMD/DONE msg type */
#define SMSG_CMD_SBLOCK_INIT 0x1
#define SMSG_DONE_SBLOCK_INIT 0x2
/* flag for EVENT msg type */
#define SMSG_EVENT_SBLOCK_SEND 0x1
#define SMSG_EVENT_SBLOCK_RELEASE 0x2
#define SBLOCK_STATE_IDLE 0
#define SBLOCK_STATE_READY 1
#define SBLOCK_BLK_STATE_DONE 0
#define SBLOCK_BLK_STATE_PENDING 1
struct sblock_blks {
u32 addr; /*phy address*/
u32 length;
};
/* ring block header */
struct sblock_ring_header {
/* get|send-block info */
u32 txblk_addr; /* tx blocks start addr */
u32 txblk_count; /* tx blocks num */
u32 txblk_size; /* one tx block size */
u32 txblk_blks; /* tx_ring or tx_pool start addr */
u32 txblk_rdptr; /* tx_ring or tx_pool read point */
u32 txblk_wrptr; /* tx_ring or tx_pool write point */
/* release|recv-block info */
u32 rxblk_addr;
u32 rxblk_count;
u32 rxblk_size;
u32 rxblk_blks;
u32 rxblk_rdptr;
u32 rxblk_wrptr;
};
struct sblock_header {
struct sblock_ring_header ring;
struct sblock_ring_header pool;
};
struct sblock_ring_header_op {
/*
* this points point to share memory
* for update rdptr and wtptr on share memory
*/
volatile u32 *tx_rd_p;
volatile u32 *tx_wt_p;
volatile u32 *rx_rd_p;
volatile u32 *rx_wt_p;
/*
* this member copy from share memory,
* because this contents will not change on share memory
*/
u32 tx_addr; /* txblk_addr */
u32 tx_count; /* txblk_count */
u32 tx_size; /* txblk_size */
u32 tx_blks; /* txblk_blks */
u32 rx_addr;
u32 rx_count;
u32 rx_size;
u32 rx_blks;
};
struct sblock_header_op {
struct sblock_ring_header_op ringhd_op;
struct sblock_ring_header_op poolhd_op;
};
struct sblock_ring {
struct sblock_header *header;
struct sblock_header_op header_op;
struct sprd_pms *tx_pms;
struct sprd_pms *rx_pms;
char tx_pms_name[20];
char rx_pms_name[20];
void *txblk_virt; /* virt of header->txblk_addr */
void *rxblk_virt; /* virt of header->rxblk_addr */
/* virt of header->ring->txblk_blks */
struct sblock_blks *r_txblks;
/* virt of header->ring->rxblk_blks */
struct sblock_blks *r_rxblks;
/* virt of header->pool->txblk_blks */
struct sblock_blks *p_txblks;
/* virt of header->pool->rxblk_blks */
struct sblock_blks *p_rxblks;
unsigned int poll_mask;
/* protect the poll_mask menber */
spinlock_t poll_lock;
int *txrecord; /* record the state of every txblk */
int *rxrecord; /* record the state of every rxblk */
int yell; /* need to notify cp */
spinlock_t r_txlock; /* send */
spinlock_t r_rxlock; /* recv */
spinlock_t p_txlock; /* get */
spinlock_t p_rxlock; /* release */
wait_queue_head_t getwait;
wait_queue_head_t recvwait;
};
struct sblock_mgr {
u8 dst;
u8 channel;
int pre_cfg; /*support in host mode only */
u32 state;
void *smem_virt;
u32 smem_addr;
u32 smem_addr_debug;
u32 smem_size;
u32 dst_smem_addr;
/*
* this address stored in share memory,
* be used to calculte the block virt address.
* in host mode, it is client physial address(dst_smem_addr),
* in client mode, it is own physial address(smem_addr).
*/
u32 stored_smem_addr;
u32 txblksz;
u32 rxblksz;
u32 txblknum;
u32 rxblknum;
struct sblock_ring *ring;
struct task_struct *thread;
void (*handler)(int event, void *data);
void *data;
};
#ifdef CONFIG_64BIT
#define SBLOCK_ALIGN_BYTES (8)
#else
#define SBLOCK_ALIGN_BYTES (4)
#endif
static inline u32 sblock_get_index(u32 x, u32 y)
{
return (x / y);
}
static inline u32 sblock_get_ringpos(u32 x, u32 y)
{
return is_power_of_2(y) ? (x & (y - 1)) : (x % y);
}
#endif