mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson
synced 2025-08-29 11:42:36 +00:00

This patch adds support for a new feature, named "Interrupt Delay", allowing driver to set a specific delay time for next interrupt detection. It gives driver a capability to control THC waiting time for the next interrupt, to reduce the likelihood of spurious readings. APIs added: - thc_i2c_set_rx_int_delay(): Set I2C Rx input interrupt delay value - thc_i2c_rx_int_delay_enable(): Enable or disable I2C Rx interrupt delay As this interrupt delay feature is only applicable to RxDMA and must remain disabled during SWDMA operations, it also involves a change in SWDMA code to record the max input size control feature state before SWDMA and restore the state after SWDMA. Signed-off-by: Even Xu <even.xu@intel.com> Tested-by: Chong Han <chong.han@intel.com> Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Signed-off-by: Jiri Kosina <jkosina@suse.com>
155 lines
5.0 KiB
C
155 lines
5.0 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
/* Copyright (c) 2024 Intel Corporation */
|
|
|
|
#ifndef _INTEL_THC_DMA_H_
|
|
#define _INTEL_THC_DMA_H_
|
|
|
|
#include <linux/bits.h>
|
|
#include <linux/dma-mapping.h>
|
|
#include <linux/sizes.h>
|
|
#include <linux/time64.h>
|
|
#include <linux/types.h>
|
|
|
|
#define THC_POINTER_MASK GENMASK(6, 0)
|
|
#define THC_POINTER_WRAPAROUND 0x80
|
|
#define THC_WRAPAROUND_VALUE_ODD 0x10
|
|
#define THC_WRAPAROUND_VALUE_EVEN 0x90
|
|
#define THC_MIN_BYTES_PER_SG_LIST_ENTRY SZ_4K
|
|
|
|
#define THC_DEFAULT_RXDMA_POLLING_US_INTERVAL 100
|
|
#define THC_DEFAULT_RXDMA_POLLING_US_TIMEOUT (10 * USEC_PER_MSEC)
|
|
|
|
/*
|
|
* THC needs 1KB aligned address, dest_addr is 54 bits, not 64,
|
|
* so don't need to send the lower 10-bits of address.
|
|
*/
|
|
#define THC_ADDRESS_SHIFT 10
|
|
|
|
/**
|
|
* THC DMA channels:
|
|
* @THC_RXDMA1: Legacy channel, reserved for raw data reading
|
|
* @THC_RXDMA2: DMA to read HID data from touch device
|
|
* @THC_TXDMA: DMA to write to touch device
|
|
* @THC_SWDMA: SW triggered DMA to write and read from touch device
|
|
*/
|
|
enum thc_dma_channel {
|
|
THC_RXDMA1 = 0,
|
|
THC_RXDMA2 = 1,
|
|
THC_TXDMA = 2,
|
|
THC_SWDMA = 3,
|
|
MAX_THC_DMA_CHANNEL
|
|
};
|
|
|
|
/**
|
|
* THC DMA Physical Memory Descriptor (PRD)
|
|
* @dest_addr: Bit[53:0], destination address in system memory
|
|
* @int_on_completion: Bit[63], if set, thc will trigger interrupt to driver
|
|
* @len: Bit[87:64], length of this entry
|
|
* @end_of_prd: Bit[88], if set, this entry is last one of current PRD table
|
|
* @hw_status: Bit[90:89], hardware status bits
|
|
*/
|
|
struct thc_prd_entry {
|
|
u64 dest_addr : 54;
|
|
u64 reserved1 : 9;
|
|
u64 int_on_completion : 1;
|
|
u64 len : 24;
|
|
u64 end_of_prd : 1;
|
|
u64 hw_status : 2;
|
|
u64 reserved2 : 37;
|
|
};
|
|
|
|
/*
|
|
* Max OS memory fragmentation will be at a 4KB boundary, thus to address 1MB
|
|
* of virtually contiguous memory 256 PRD entries are required for a single
|
|
* PRD Table. SW writes the number of PRD Entries for each PRD table in the
|
|
* THC_M_PRT_RPRD_CNTRL.PTEC register field. The PRD entry's length must be
|
|
* multiple of 4KB except for the last entry in a PRD table.
|
|
* This is the max possible number of etries supported by HW, in practise we
|
|
* there will be less entries in each prd table(the actual number will be
|
|
* given by scatter-gather list allocation).
|
|
*/
|
|
#define PRD_ENTRIES_NUM 16
|
|
|
|
/*
|
|
* Number of PRD tables equals to number of data buffers.
|
|
* The max number of PRD tables supported by the HW is 128,
|
|
* but we allocate only 16.
|
|
*/
|
|
#define PRD_TABLES_NUM 16
|
|
|
|
/* THC DMA Physical Memory Descriptor Table */
|
|
struct thc_prd_table {
|
|
struct thc_prd_entry entries[PRD_ENTRIES_NUM];
|
|
};
|
|
|
|
#define PRD_TABLE_SIZE sizeof(struct thc_prd_table)
|
|
|
|
/**
|
|
* struct thc_dma_configuration - THC DMA configure
|
|
* @dma_channel: DMA channel for current DMA configuration
|
|
* @prd_tbls_dma_handle: DMA buffer handle
|
|
* @dir: Direction of DMA for this config
|
|
* @prd_tbls: PRD tables for current DMA
|
|
* @sgls: Array of pointers to scatter-gather lists
|
|
* @sgls_nent: Actual number of entries per scatter-gather list
|
|
* @prd_tbl_num: Actual number of PRD tables
|
|
* @max_packet_size: Size of the buffer needed for 1 DMA message (1 PRD table)
|
|
* @prd_base_addr_high: High 32bits memory address where stores PRD table
|
|
* @prd_base_addr_low: Low 32bits memory address where stores PRD table
|
|
* @prd_cntrl: PRD control register value
|
|
* @dma_cntrl: DMA control register value
|
|
*/
|
|
struct thc_dma_configuration {
|
|
enum thc_dma_channel dma_channel;
|
|
dma_addr_t prd_tbls_dma_handle;
|
|
enum dma_data_direction dir;
|
|
bool is_enabled;
|
|
|
|
struct thc_prd_table *prd_tbls;
|
|
struct scatterlist *sgls[PRD_TABLES_NUM];
|
|
u8 sgls_nent[PRD_TABLES_NUM];
|
|
u8 prd_tbl_num;
|
|
|
|
size_t max_packet_size;
|
|
u32 prd_base_addr_high;
|
|
u32 prd_base_addr_low;
|
|
u32 prd_cntrl;
|
|
u32 dma_cntrl;
|
|
};
|
|
|
|
/**
|
|
* struct thc_dma_context - THC DMA context
|
|
* @thc_dma_configuration: Array of all THC Channel configures
|
|
* @use_write_interrupts: Indicate TxDMA using interrupt or polling
|
|
* @rx_max_size_en: Temp flag to indicate THC I2C Rx max input size control feature
|
|
* enabled or not, only be used during SWDMA operation.
|
|
* @rx_int_delay_en: Temp flag to indicate THC I2C Rx interrupt delay feature
|
|
* enabled or not, only be used during SWDMA operation.
|
|
*/
|
|
struct thc_dma_context {
|
|
struct thc_dma_configuration dma_config[MAX_THC_DMA_CHANNEL];
|
|
u8 use_write_interrupts;
|
|
|
|
bool rx_max_size_en;
|
|
bool rx_int_delay_en;
|
|
};
|
|
|
|
struct thc_device;
|
|
|
|
int thc_dma_set_max_packet_sizes(struct thc_device *dev,
|
|
size_t mps_read1, size_t mps_read2,
|
|
size_t mps_write, size_t mps_swdma);
|
|
int thc_dma_allocate(struct thc_device *dev);
|
|
int thc_dma_configure(struct thc_device *dev);
|
|
void thc_dma_unconfigure(struct thc_device *dev);
|
|
void thc_dma_release(struct thc_device *dev);
|
|
int thc_rxdma_read(struct thc_device *dev, enum thc_dma_channel dma_channel,
|
|
void *read_buff, size_t *read_len, int *read_finished);
|
|
int thc_swdma_read(struct thc_device *dev, void *write_buff, size_t write_len,
|
|
u32 *prd_tbl_len, void *read_buff, size_t *read_len);
|
|
int thc_dma_write(struct thc_device *dev, void *buffer, size_t buf_len);
|
|
|
|
struct thc_dma_context *thc_dma_init(struct thc_device *dev);
|
|
|
|
#endif /* _INTEL_THC_DMA_H_ */
|