Measure SPI transactions time. This enables profiling the current performance of the driver and assess future enhancements. Change-Id: I5d0ff6ad18061862c0fff9097a03ddabe60e22e4 Signed-off-by: Gidon Studinski <gidons@codeaurora.org>
234 lines
5.6 KiB
C
234 lines
5.6 KiB
C
/* SPDX-License-Identifier: GPL-2.0-only */
|
|
/*
|
|
* Copyright (c) 2019-2020, The Linux foundation. All rights reserved.
|
|
*/
|
|
|
|
#ifndef __WIGIG_SENSING_H__
|
|
#define __WIGIG_SENSING_H__
|
|
#include <linux/cdev.h>
|
|
#include <linux/circ_buf.h>
|
|
#include <linux/kfifo.h>
|
|
#include <linux/ktime.h>
|
|
#include <linux/slab.h>
|
|
#include <uapi/misc/wigig_sensing_uapi.h>
|
|
|
|
#ifdef pr_fmt
|
|
#undef pr_fmt
|
|
#endif
|
|
|
|
#define pr_fmt(fmt) "[wigig_sensing]: " fmt
|
|
|
|
/* Registers */
|
|
#define RGF_USER_SPI_SPI_MBOX_FILL_STATUS (0x880080)
|
|
#define RGF_USER_SPI_SPI_EXT_MBOX_OUTB (0x880084)
|
|
#define RGF_USER_SPI_SPI_MBOX_INB (0x880088)
|
|
#define RGF_SPI_FIFO_CONTROL_ADDR (0x8800A0)
|
|
#define RGF_SPI_FIFO_WR_PTR_ADDR (0x88009C)
|
|
#define RGF_SPI_FIFO_RD_PTR_ADDR (0x880098)
|
|
#define RGF_SPI_FIFO_BASE_ADDR_ADDR (0x880094)
|
|
#define RGF_SPI_CONTROL_ADDR (0x880090)
|
|
#define RGF_SPI_CONFIG_ADDR (0x88008C)
|
|
|
|
#define SPIS_TRNS_LEN_REG_ADDR (0x50)
|
|
#define ADDR_WIDTH (3)
|
|
#define DUMMY_BYTES_WIDTH (4)
|
|
#define OPCODE_WIDTH (1)
|
|
#define SPIS_SANITY_REG_ADDR (0x0)
|
|
#define SPIS_SANITY_REG_VAL (0xDEADBEEF)
|
|
#define SPIS_CFG_REG_ADDR (0xC)
|
|
#define JTAG_ID_REG_ADDR (0x880000)
|
|
#define JTAG_ID (0x1007E0E1)
|
|
/* optimized configuration with 4 dummy bytes */
|
|
#define SPIS_CONFIG_REG_OPT_VAL (0x44200800)
|
|
#define SPIS_EXTENDED_RESET_COMMAND_LEN (225)
|
|
|
|
#define MAX_SPI_READ_CHUNKS (10)
|
|
#define SPI_MIN_TRANSACTION_SIZE (512)
|
|
#define SPI_MAX_TRANSACTION_SIZE (8*1024)
|
|
#define SPI_CMD_TRANSACTION_SIZE (512)
|
|
#define SPI_BUFFER_SIZE (SPI_MAX_TRANSACTION_SIZE + OPCODE_WIDTH + \
|
|
ADDR_WIDTH + DUMMY_BYTES_WIDTH)
|
|
#define SPI_CMD_BUFFER_SIZE (SPI_CMD_TRANSACTION_SIZE + OPCODE_WIDTH + \
|
|
ADDR_WIDTH + DUMMY_BYTES_WIDTH)
|
|
|
|
#define INT_FW_READY BIT(24)
|
|
#define INT_DATA_READY BIT(25)
|
|
#define INT_FIFO_READY BIT(26)
|
|
#define INT_DONT_DEASSERT BIT(27)
|
|
#define INT_SYSASSERT BIT(29)
|
|
#define INT_DEEP_SLEEP_EXIT BIT(30)
|
|
union user_rgf_spi_status {
|
|
struct {
|
|
u16 fill_level:16;
|
|
int reserved1:3;
|
|
u8 spi_fifo_thr_status:1;
|
|
u8 spi_fifo_empty_status:1;
|
|
u8 spi_fifo_full_status:1;
|
|
u8 spi_fifo_underrun_status:1;
|
|
u8 spi_fifo_overrun_status:1;
|
|
|
|
/* mbox_outb */
|
|
u8 int_fw_ready:1; /* FW MBOX ready */
|
|
u8 int_data_ready:1; /* data available on FIFO */
|
|
u8 int_fifo_ready:1; /* FIFO status update */
|
|
u8 int_dont_deassert:1; /* Don't deassert DRI */
|
|
u8 reserved3:1;
|
|
u8 int_sysassert:1; /* SYSASSERT occurred */
|
|
u8 int_deep_sleep_exit:1;
|
|
u8 reserved4:1;
|
|
} __packed b;
|
|
u32 v;
|
|
} __packed;
|
|
|
|
union user_rgf_spi_mbox_inb {
|
|
struct {
|
|
u8 mode:4;
|
|
u8 channel_request:4;
|
|
u32 reserved:23;
|
|
u8 deassert_dri:1;
|
|
} __packed b;
|
|
u32 v;
|
|
} __packed;
|
|
|
|
union rgf_spi_config {
|
|
struct {
|
|
u16 size:16;
|
|
u8 reserved1:8;
|
|
u8 mbox_auto_clear_disable:1;
|
|
u8 status_auto_clear_disable:1;
|
|
u8 reserved2:5;
|
|
u8 enable:1;
|
|
} __packed b;
|
|
u32 v;
|
|
} __packed;
|
|
|
|
union rgf_spi_control {
|
|
struct {
|
|
u8 read_ptr_clear:1;
|
|
u8 fill_level_clear:1;
|
|
u8 thresh_reach_clear:1;
|
|
u8 status_field_clear:1;
|
|
u8 mbox_field_clear:1;
|
|
u32 reserved:27;
|
|
} __packed b;
|
|
u32 v;
|
|
} __packed;
|
|
|
|
struct cir_data {
|
|
struct circ_buf b;
|
|
u32 size_bytes;
|
|
struct mutex lock;
|
|
};
|
|
|
|
struct spi_fifo {
|
|
u32 wr_ptr;
|
|
u32 rd_ptr;
|
|
u32 base_addr;
|
|
union rgf_spi_config config;
|
|
union rgf_spi_control control;
|
|
};
|
|
|
|
/**
|
|
* State machine states
|
|
* TODO: Document states
|
|
*/
|
|
enum wigig_sensing_stm_e {
|
|
WIGIG_SENSING_STATE_MIN = 0,
|
|
WIGIG_SENSING_STATE_INITIALIZED,
|
|
WIGIG_SENSING_STATE_READY_STOPPED,
|
|
WIGIG_SENSING_STATE_SEARCH,
|
|
WIGIG_SENSING_STATE_FACIAL,
|
|
WIGIG_SENSING_STATE_GESTURE,
|
|
WIGIG_SENSING_STATE_CUSTOM,
|
|
WIGIG_SENSING_STATE_GET_PARAMS,
|
|
WIGIG_SENSING_STATE_SYS_ASSERT,
|
|
WIGIG_SENSING_STATE_MAX,
|
|
};
|
|
|
|
struct wigig_sensing_stm {
|
|
bool auto_recovery;
|
|
bool fw_is_ready;
|
|
bool spi_malfunction;
|
|
bool spi_ready;
|
|
bool waiting_for_deep_sleep_exit;
|
|
bool waiting_for_deep_sleep_exit_first_pass;
|
|
bool burst_size_ready;
|
|
bool change_mode_in_progress;
|
|
enum wigig_sensing_stm_e state;
|
|
enum wigig_sensing_mode mode;
|
|
u32 burst_size;
|
|
u32 channel;
|
|
u32 channel_request;
|
|
enum wigig_sensing_stm_e state_request;
|
|
enum wigig_sensing_mode mode_request;
|
|
};
|
|
|
|
enum spi_stats_meas {
|
|
SPI_STATS_MEAS_MIN,
|
|
SPI_STATS_MEAS_SANITY = SPI_STATS_MEAS_MIN,
|
|
SPI_STATS_MEAS_DEASSERT,
|
|
SPI_STATS_MEAS_DRI_PROC,
|
|
SPI_STATS_MEAS_MBOX_FILL_STATUS,
|
|
SPI_STATS_MEAS_CHANGE_MODE,
|
|
SPI_STATS_MEAS_DATA_READY,
|
|
SPI_STATS_MEAS_MAX,
|
|
};
|
|
|
|
#define SPI_STATS_MAX_NAME_LEN (20)
|
|
struct spi_stats {
|
|
char name[SPI_STATS_MAX_NAME_LEN];
|
|
atomic64_t min;
|
|
atomic64_t max;
|
|
atomic64_t acc;
|
|
atomic_t num_meas;
|
|
ktime_t start, delta;
|
|
};
|
|
|
|
struct wigig_sensing_ctx {
|
|
dev_t wigig_sensing_dev;
|
|
struct cdev cdev;
|
|
struct class *class;
|
|
struct device *dev;
|
|
struct spi_device *spi_dev;
|
|
struct dentry *debugfs_dent;
|
|
|
|
/* Locks */
|
|
struct mutex ioctl_lock;
|
|
struct mutex file_lock;
|
|
struct mutex spi_lock;
|
|
struct mutex dri_lock;
|
|
wait_queue_head_t cmd_wait_q;
|
|
wait_queue_head_t data_wait_q;
|
|
|
|
/* DRI */
|
|
struct gpio_desc *dri_gpio;
|
|
int dri_irq;
|
|
bool opened;
|
|
|
|
/* Memory buffers for SPI transactions */
|
|
u8 *tx_buf;
|
|
u8 *rx_buf;
|
|
u8 *cmd_buf;
|
|
u8 *cmd_reply_buf;
|
|
|
|
/* SPI FIFO parameters */
|
|
struct spi_fifo spi_fifo;
|
|
struct wigig_sensing_stm stm;
|
|
u32 last_read_length;
|
|
union user_rgf_spi_mbox_inb inb_cmd;
|
|
u32 spi_transaction_size;
|
|
|
|
/* CIR buffer */
|
|
struct cir_data cir_data;
|
|
u8 *temp_buffer;
|
|
bool event_pending;
|
|
DECLARE_KFIFO(events_fifo, enum wigig_sensing_event, 8);
|
|
u32 dropped_bursts;
|
|
|
|
/* Statistics */
|
|
struct spi_stats spi_stats[SPI_STATS_MEAS_MAX];
|
|
};
|
|
|
|
#endif /* __WIGIG_SENSING_H__ */
|
|
|