| /* 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_pages: Number of pages per scatter-gather list |
| * @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_pages[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_ */ |