1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
|
/* 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], hw 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 sg 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;
};
/*
* THC DMA context
* Store all THC Channel configures
*/
struct thc_dma_context {
struct thc_dma_configuration dma_config[MAX_THC_DMA_CHANNEL];
u8 use_write_interrupts;
};
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_ */
|