summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKarthikeyan Ramasubramanian <kramasub@codeaurora.org>2018-03-30 13:08:17 -0400
committerAndy Gross <andy.gross@linaro.org>2018-04-25 01:12:05 -0400
commiteddac5af06546d2e7a0730e3dc02dde3dc91098a (patch)
tree53954aa55955569e563df1c173bd2ee73a0d3156
parent64bf6b260e86e778c3d95290d60f5b25e641b08e (diff)
soc: qcom: Add GENI based QUP Wrapper driver
This driver manages the Generic Interface (GENI) firmware based Qualcomm Universal Peripheral (QUP) Wrapper. GENI based QUP is the next generation programmable module composed of multiple Serial Engines (SE) and supports a wide range of serial interfaces like UART, SPI, I2C, I3C, etc. This driver also enables managing the serial interface independent aspects of Serial Engines. Signed-off-by: Karthikeyan Ramasubramanian <kramasub@codeaurora.org> Signed-off-by: Sagar Dharia <sdharia@codeaurora.org> Signed-off-by: Girish Mahadevan <girishm@codeaurora.org> Reviewed-by: Evan Green <evgreen@chromium.org> Signed-off-by: Andy Gross <andy.gross@linaro.org>
-rw-r--r--drivers/soc/qcom/Kconfig9
-rw-r--r--drivers/soc/qcom/Makefile1
-rw-r--r--drivers/soc/qcom/qcom-geni-se.c748
-rw-r--r--include/linux/qcom-geni-se.h425
4 files changed, 1183 insertions, 0 deletions
diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig
index 5c4535b545cc..d0372de29834 100644
--- a/drivers/soc/qcom/Kconfig
+++ b/drivers/soc/qcom/Kconfig
@@ -3,6 +3,15 @@
3# 3#
4menu "Qualcomm SoC drivers" 4menu "Qualcomm SoC drivers"
5 5
6config QCOM_GENI_SE
7 tristate "QCOM GENI Serial Engine Driver"
8 depends on ARCH_QCOM || COMPILE_TEST
9 help
10 This driver is used to manage Generic Interface (GENI) firmware based
11 Qualcomm Technologies, Inc. Universal Peripheral (QUP) Wrapper. This
12 driver is also used to manage the common aspects of multiple Serial
13 Engines present in the QUP.
14
6config QCOM_GLINK_SSR 15config QCOM_GLINK_SSR
7 tristate "Qualcomm Glink SSR driver" 16 tristate "Qualcomm Glink SSR driver"
8 depends on RPMSG 17 depends on RPMSG
diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile
index dcebf2814e6d..959aa748f5ac 100644
--- a/drivers/soc/qcom/Makefile
+++ b/drivers/soc/qcom/Makefile
@@ -1,4 +1,5 @@
1# SPDX-License-Identifier: GPL-2.0 1# SPDX-License-Identifier: GPL-2.0
2obj-$(CONFIG_QCOM_GENI_SE) += qcom-geni-se.o
2obj-$(CONFIG_QCOM_GLINK_SSR) += glink_ssr.o 3obj-$(CONFIG_QCOM_GLINK_SSR) += glink_ssr.o
3obj-$(CONFIG_QCOM_GSBI) += qcom_gsbi.o 4obj-$(CONFIG_QCOM_GSBI) += qcom_gsbi.o
4obj-$(CONFIG_QCOM_MDT_LOADER) += mdt_loader.o 5obj-$(CONFIG_QCOM_MDT_LOADER) += mdt_loader.o
diff --git a/drivers/soc/qcom/qcom-geni-se.c b/drivers/soc/qcom/qcom-geni-se.c
new file mode 100644
index 000000000000..feed3db21c10
--- /dev/null
+++ b/drivers/soc/qcom/qcom-geni-se.c
@@ -0,0 +1,748 @@
1// SPDX-License-Identifier: GPL-2.0
2// Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
3
4#include <linux/clk.h>
5#include <linux/slab.h>
6#include <linux/dma-mapping.h>
7#include <linux/io.h>
8#include <linux/module.h>
9#include <linux/of.h>
10#include <linux/of_platform.h>
11#include <linux/pinctrl/consumer.h>
12#include <linux/platform_device.h>
13#include <linux/qcom-geni-se.h>
14
15/**
16 * DOC: Overview
17 *
18 * Generic Interface (GENI) Serial Engine (SE) Wrapper driver is introduced
19 * to manage GENI firmware based Qualcomm Universal Peripheral (QUP) Wrapper
20 * controller. QUP Wrapper is designed to support various serial bus protocols
21 * like UART, SPI, I2C, I3C, etc.
22 */
23
24/**
25 * DOC: Hardware description
26 *
27 * GENI based QUP is a highly-flexible and programmable module for supporting
28 * a wide range of serial interfaces like UART, SPI, I2C, I3C, etc. A single
29 * QUP module can provide upto 8 serial interfaces, using its internal
30 * serial engines. The actual configuration is determined by the target
31 * platform configuration. The protocol supported by each interface is
32 * determined by the firmware loaded to the serial engine. Each SE consists
33 * of a DMA Engine and GENI sub modules which enable serial engines to
34 * support FIFO and DMA modes of operation.
35 *
36 *
37 * +-----------------------------------------+
38 * |QUP Wrapper |
39 * | +----------------------------+ |
40 * --QUP & SE Clocks--> | Serial Engine N | +-IO------>
41 * | | ... | | Interface
42 * <---Clock Perf.----+ +----+-----------------------+ | |
43 * State Interface | | Serial Engine 1 | | |
44 * | | | | |
45 * | | | | |
46 * <--------AHB-------> | | | |
47 * | | +----+ |
48 * | | | |
49 * | | | |
50 * <------SE IRQ------+ +----------------------------+ |
51 * | |
52 * +-----------------------------------------+
53 *
54 * Figure 1: GENI based QUP Wrapper
55 *
56 * The GENI submodules include primary and secondary sequencers which are
57 * used to drive TX & RX operations. On serial interfaces that operate using
58 * master-slave model, primary sequencer drives both TX & RX operations. On
59 * serial interfaces that operate using peer-to-peer model, primary sequencer
60 * drives TX operation and secondary sequencer drives RX operation.
61 */
62
63/**
64 * DOC: Software description
65 *
66 * GENI SE Wrapper driver is structured into 2 parts:
67 *
68 * geni_wrapper represents QUP Wrapper controller. This part of the driver
69 * manages QUP Wrapper information such as hardware version, clock
70 * performance table that is common to all the internal serial engines.
71 *
72 * geni_se represents serial engine. This part of the driver manages serial
73 * engine information such as clocks, containing QUP Wrapper, etc. This part
74 * of driver also supports operations (eg. initialize the concerned serial
75 * engine, select between FIFO and DMA mode of operation etc.) that are
76 * common to all the serial engines and are independent of serial interfaces.
77 */
78
79#define MAX_CLK_PERF_LEVEL 32
80#define NUM_AHB_CLKS 2
81
82/**
83 * @struct geni_wrapper - Data structure to represent the QUP Wrapper Core
84 * @dev: Device pointer of the QUP wrapper core
85 * @base: Base address of this instance of QUP wrapper core
86 * @ahb_clks: Handle to the primary & secondary AHB clocks
87 */
88struct geni_wrapper {
89 struct device *dev;
90 void __iomem *base;
91 struct clk_bulk_data ahb_clks[NUM_AHB_CLKS];
92};
93
94#define QUP_HW_VER_REG 0x4
95
96/* Common SE registers */
97#define GENI_INIT_CFG_REVISION 0x0
98#define GENI_S_INIT_CFG_REVISION 0x4
99#define GENI_OUTPUT_CTRL 0x24
100#define GENI_CGC_CTRL 0x28
101#define GENI_CLK_CTRL_RO 0x60
102#define GENI_IF_DISABLE_RO 0x64
103#define GENI_FW_S_REVISION_RO 0x6c
104#define SE_GENI_BYTE_GRAN 0x254
105#define SE_GENI_TX_PACKING_CFG0 0x260
106#define SE_GENI_TX_PACKING_CFG1 0x264
107#define SE_GENI_RX_PACKING_CFG0 0x284
108#define SE_GENI_RX_PACKING_CFG1 0x288
109#define SE_GENI_M_GP_LENGTH 0x910
110#define SE_GENI_S_GP_LENGTH 0x914
111#define SE_DMA_TX_PTR_L 0xc30
112#define SE_DMA_TX_PTR_H 0xc34
113#define SE_DMA_TX_ATTR 0xc38
114#define SE_DMA_TX_LEN 0xc3c
115#define SE_DMA_TX_IRQ_EN 0xc48
116#define SE_DMA_TX_IRQ_EN_SET 0xc4c
117#define SE_DMA_TX_IRQ_EN_CLR 0xc50
118#define SE_DMA_TX_LEN_IN 0xc54
119#define SE_DMA_TX_MAX_BURST 0xc5c
120#define SE_DMA_RX_PTR_L 0xd30
121#define SE_DMA_RX_PTR_H 0xd34
122#define SE_DMA_RX_ATTR 0xd38
123#define SE_DMA_RX_LEN 0xd3c
124#define SE_DMA_RX_IRQ_EN 0xd48
125#define SE_DMA_RX_IRQ_EN_SET 0xd4c
126#define SE_DMA_RX_IRQ_EN_CLR 0xd50
127#define SE_DMA_RX_LEN_IN 0xd54
128#define SE_DMA_RX_MAX_BURST 0xd5c
129#define SE_DMA_RX_FLUSH 0xd60
130#define SE_GSI_EVENT_EN 0xe18
131#define SE_IRQ_EN 0xe1c
132#define SE_DMA_GENERAL_CFG 0xe30
133
134/* GENI_OUTPUT_CTRL fields */
135#define DEFAULT_IO_OUTPUT_CTRL_MSK GENMASK(6, 0)
136
137/* GENI_CGC_CTRL fields */
138#define CFG_AHB_CLK_CGC_ON BIT(0)
139#define CFG_AHB_WR_ACLK_CGC_ON BIT(1)
140#define DATA_AHB_CLK_CGC_ON BIT(2)
141#define SCLK_CGC_ON BIT(3)
142#define TX_CLK_CGC_ON BIT(4)
143#define RX_CLK_CGC_ON BIT(5)
144#define EXT_CLK_CGC_ON BIT(6)
145#define PROG_RAM_HCLK_OFF BIT(8)
146#define PROG_RAM_SCLK_OFF BIT(9)
147#define DEFAULT_CGC_EN GENMASK(6, 0)
148
149/* SE_GSI_EVENT_EN fields */
150#define DMA_RX_EVENT_EN BIT(0)
151#define DMA_TX_EVENT_EN BIT(1)
152#define GENI_M_EVENT_EN BIT(2)
153#define GENI_S_EVENT_EN BIT(3)
154
155/* SE_IRQ_EN fields */
156#define DMA_RX_IRQ_EN BIT(0)
157#define DMA_TX_IRQ_EN BIT(1)
158#define GENI_M_IRQ_EN BIT(2)
159#define GENI_S_IRQ_EN BIT(3)
160
161/* SE_DMA_GENERAL_CFG */
162#define DMA_RX_CLK_CGC_ON BIT(0)
163#define DMA_TX_CLK_CGC_ON BIT(1)
164#define DMA_AHB_SLV_CFG_ON BIT(2)
165#define AHB_SEC_SLV_CLK_CGC_ON BIT(3)
166#define DUMMY_RX_NON_BUFFERABLE BIT(4)
167#define RX_DMA_ZERO_PADDING_EN BIT(5)
168#define RX_DMA_IRQ_DELAY_MSK GENMASK(8, 6)
169#define RX_DMA_IRQ_DELAY_SHFT 6
170
171/**
172 * geni_se_get_qup_hw_version() - Read the QUP wrapper Hardware version
173 * @se: Pointer to the corresponding serial engine.
174 *
175 * Return: Hardware Version of the wrapper.
176 */
177u32 geni_se_get_qup_hw_version(struct geni_se *se)
178{
179 struct geni_wrapper *wrapper = se->wrapper;
180
181 return readl_relaxed(wrapper->base + QUP_HW_VER_REG);
182}
183EXPORT_SYMBOL(geni_se_get_qup_hw_version);
184
185static void geni_se_io_set_mode(void __iomem *base)
186{
187 u32 val;
188
189 val = readl_relaxed(base + SE_IRQ_EN);
190 val |= GENI_M_IRQ_EN | GENI_S_IRQ_EN;
191 val |= DMA_TX_IRQ_EN | DMA_RX_IRQ_EN;
192 writel_relaxed(val, base + SE_IRQ_EN);
193
194 val = readl_relaxed(base + SE_GENI_DMA_MODE_EN);
195 val &= ~GENI_DMA_MODE_EN;
196 writel_relaxed(val, base + SE_GENI_DMA_MODE_EN);
197
198 writel_relaxed(0, base + SE_GSI_EVENT_EN);
199}
200
201static void geni_se_io_init(void __iomem *base)
202{
203 u32 val;
204
205 val = readl_relaxed(base + GENI_CGC_CTRL);
206 val |= DEFAULT_CGC_EN;
207 writel_relaxed(val, base + GENI_CGC_CTRL);
208
209 val = readl_relaxed(base + SE_DMA_GENERAL_CFG);
210 val |= AHB_SEC_SLV_CLK_CGC_ON | DMA_AHB_SLV_CFG_ON;
211 val |= DMA_TX_CLK_CGC_ON | DMA_RX_CLK_CGC_ON;
212 writel_relaxed(val, base + SE_DMA_GENERAL_CFG);
213
214 writel_relaxed(DEFAULT_IO_OUTPUT_CTRL_MSK, base + GENI_OUTPUT_CTRL);
215 writel_relaxed(FORCE_DEFAULT, base + GENI_FORCE_DEFAULT_REG);
216}
217
218/**
219 * geni_se_init() - Initialize the GENI serial engine
220 * @se: Pointer to the concerned serial engine.
221 * @rx_wm: Receive watermark, in units of FIFO words.
222 * @rx_rfr_wm: Ready-for-receive watermark, in units of FIFO words.
223 *
224 * This function is used to initialize the GENI serial engine, configure
225 * receive watermark and ready-for-receive watermarks.
226 */
227void geni_se_init(struct geni_se *se, u32 rx_wm, u32 rx_rfr)
228{
229 u32 val;
230
231 geni_se_io_init(se->base);
232 geni_se_io_set_mode(se->base);
233
234 writel_relaxed(rx_wm, se->base + SE_GENI_RX_WATERMARK_REG);
235 writel_relaxed(rx_rfr, se->base + SE_GENI_RX_RFR_WATERMARK_REG);
236
237 val = readl_relaxed(se->base + SE_GENI_M_IRQ_EN);
238 val |= M_COMMON_GENI_M_IRQ_EN;
239 writel_relaxed(val, se->base + SE_GENI_M_IRQ_EN);
240
241 val = readl_relaxed(se->base + SE_GENI_S_IRQ_EN);
242 val |= S_COMMON_GENI_S_IRQ_EN;
243 writel_relaxed(val, se->base + SE_GENI_S_IRQ_EN);
244}
245EXPORT_SYMBOL(geni_se_init);
246
247static void geni_se_select_fifo_mode(struct geni_se *se)
248{
249 u32 proto = geni_se_read_proto(se);
250 u32 val;
251
252 writel_relaxed(0, se->base + SE_GSI_EVENT_EN);
253 writel_relaxed(0xffffffff, se->base + SE_GENI_M_IRQ_CLEAR);
254 writel_relaxed(0xffffffff, se->base + SE_GENI_S_IRQ_CLEAR);
255 writel_relaxed(0xffffffff, se->base + SE_DMA_TX_IRQ_CLR);
256 writel_relaxed(0xffffffff, se->base + SE_DMA_RX_IRQ_CLR);
257 writel_relaxed(0xffffffff, se->base + SE_IRQ_EN);
258
259 val = readl_relaxed(se->base + SE_GENI_M_IRQ_EN);
260 if (proto != GENI_SE_UART) {
261 val |= M_CMD_DONE_EN | M_TX_FIFO_WATERMARK_EN;
262 val |= M_RX_FIFO_WATERMARK_EN | M_RX_FIFO_LAST_EN;
263 }
264 writel_relaxed(val, se->base + SE_GENI_M_IRQ_EN);
265
266 val = readl_relaxed(se->base + SE_GENI_S_IRQ_EN);
267 if (proto != GENI_SE_UART)
268 val |= S_CMD_DONE_EN;
269 writel_relaxed(val, se->base + SE_GENI_S_IRQ_EN);
270
271 val = readl_relaxed(se->base + SE_GENI_DMA_MODE_EN);
272 val &= ~GENI_DMA_MODE_EN;
273 writel_relaxed(val, se->base + SE_GENI_DMA_MODE_EN);
274}
275
276static void geni_se_select_dma_mode(struct geni_se *se)
277{
278 u32 val;
279
280 writel_relaxed(0, se->base + SE_GSI_EVENT_EN);
281 writel_relaxed(0xffffffff, se->base + SE_GENI_M_IRQ_CLEAR);
282 writel_relaxed(0xffffffff, se->base + SE_GENI_S_IRQ_CLEAR);
283 writel_relaxed(0xffffffff, se->base + SE_DMA_TX_IRQ_CLR);
284 writel_relaxed(0xffffffff, se->base + SE_DMA_RX_IRQ_CLR);
285 writel_relaxed(0xffffffff, se->base + SE_IRQ_EN);
286
287 val = readl_relaxed(se->base + SE_GENI_DMA_MODE_EN);
288 val |= GENI_DMA_MODE_EN;
289 writel_relaxed(val, se->base + SE_GENI_DMA_MODE_EN);
290}
291
292/**
293 * geni_se_select_mode() - Select the serial engine transfer mode
294 * @se: Pointer to the concerned serial engine.
295 * @mode: Transfer mode to be selected.
296 */
297void geni_se_select_mode(struct geni_se *se, enum geni_se_xfer_mode mode)
298{
299 WARN_ON(mode != GENI_SE_FIFO && mode != GENI_SE_DMA);
300
301 switch (mode) {
302 case GENI_SE_FIFO:
303 geni_se_select_fifo_mode(se);
304 break;
305 case GENI_SE_DMA:
306 geni_se_select_dma_mode(se);
307 break;
308 case GENI_SE_INVALID:
309 default:
310 break;
311 }
312}
313EXPORT_SYMBOL(geni_se_select_mode);
314
315/**
316 * DOC: Overview
317 *
318 * GENI FIFO packing is highly configurable. TX/RX packing/unpacking consist
319 * of up to 4 operations, each operation represented by 4 configuration vectors
320 * of 10 bits programmed in GENI_TX_PACKING_CFG0 and GENI_TX_PACKING_CFG1 for
321 * TX FIFO and in GENI_RX_PACKING_CFG0 and GENI_RX_PACKING_CFG1 for RX FIFO.
322 * Refer to below examples for detailed bit-field description.
323 *
324 * Example 1: word_size = 7, packing_mode = 4 x 8, msb_to_lsb = 1
325 *
326 * +-----------+-------+-------+-------+-------+
327 * | | vec_0 | vec_1 | vec_2 | vec_3 |
328 * +-----------+-------+-------+-------+-------+
329 * | start | 0x6 | 0xe | 0x16 | 0x1e |
330 * | direction | 1 | 1 | 1 | 1 |
331 * | length | 6 | 6 | 6 | 6 |
332 * | stop | 0 | 0 | 0 | 1 |
333 * +-----------+-------+-------+-------+-------+
334 *
335 * Example 2: word_size = 15, packing_mode = 2 x 16, msb_to_lsb = 0
336 *
337 * +-----------+-------+-------+-------+-------+
338 * | | vec_0 | vec_1 | vec_2 | vec_3 |
339 * +-----------+-------+-------+-------+-------+
340 * | start | 0x0 | 0x8 | 0x10 | 0x18 |
341 * | direction | 0 | 0 | 0 | 0 |
342 * | length | 7 | 6 | 7 | 6 |
343 * | stop | 0 | 0 | 0 | 1 |
344 * +-----------+-------+-------+-------+-------+
345 *
346 * Example 3: word_size = 23, packing_mode = 1 x 32, msb_to_lsb = 1
347 *
348 * +-----------+-------+-------+-------+-------+
349 * | | vec_0 | vec_1 | vec_2 | vec_3 |
350 * +-----------+-------+-------+-------+-------+
351 * | start | 0x16 | 0xe | 0x6 | 0x0 |
352 * | direction | 1 | 1 | 1 | 1 |
353 * | length | 7 | 7 | 6 | 0 |
354 * | stop | 0 | 0 | 1 | 0 |
355 * +-----------+-------+-------+-------+-------+
356 *
357 */
358
359#define NUM_PACKING_VECTORS 4
360#define PACKING_START_SHIFT 5
361#define PACKING_DIR_SHIFT 4
362#define PACKING_LEN_SHIFT 1
363#define PACKING_STOP_BIT BIT(0)
364#define PACKING_VECTOR_SHIFT 10
365/**
366 * geni_se_config_packing() - Packing configuration of the serial engine
367 * @se: Pointer to the concerned serial engine
368 * @bpw: Bits of data per transfer word.
369 * @pack_words: Number of words per fifo element.
370 * @msb_to_lsb: Transfer from MSB to LSB or vice-versa.
371 * @tx_cfg: Flag to configure the TX Packing.
372 * @rx_cfg: Flag to configure the RX Packing.
373 *
374 * This function is used to configure the packing rules for the current
375 * transfer.
376 */
377void geni_se_config_packing(struct geni_se *se, int bpw, int pack_words,
378 bool msb_to_lsb, bool tx_cfg, bool rx_cfg)
379{
380 u32 cfg0, cfg1, cfg[NUM_PACKING_VECTORS] = {0};
381 int len;
382 int temp_bpw = bpw;
383 int idx_start = msb_to_lsb ? bpw - 1 : 0;
384 int idx = idx_start;
385 int idx_delta = msb_to_lsb ? -BITS_PER_BYTE : BITS_PER_BYTE;
386 int ceil_bpw = ALIGN(bpw, BITS_PER_BYTE);
387 int iter = (ceil_bpw * pack_words) / BITS_PER_BYTE;
388 int i;
389
390 if (iter <= 0 || iter > NUM_PACKING_VECTORS)
391 return;
392
393 for (i = 0; i < iter; i++) {
394 len = min_t(int, temp_bpw, BITS_PER_BYTE) - 1;
395 cfg[i] = idx << PACKING_START_SHIFT;
396 cfg[i] |= msb_to_lsb << PACKING_DIR_SHIFT;
397 cfg[i] |= len << PACKING_LEN_SHIFT;
398
399 if (temp_bpw <= BITS_PER_BYTE) {
400 idx = ((i + 1) * BITS_PER_BYTE) + idx_start;
401 temp_bpw = bpw;
402 } else {
403 idx = idx + idx_delta;
404 temp_bpw = temp_bpw - BITS_PER_BYTE;
405 }
406 }
407 cfg[iter - 1] |= PACKING_STOP_BIT;
408 cfg0 = cfg[0] | (cfg[1] << PACKING_VECTOR_SHIFT);
409 cfg1 = cfg[2] | (cfg[3] << PACKING_VECTOR_SHIFT);
410
411 if (tx_cfg) {
412 writel_relaxed(cfg0, se->base + SE_GENI_TX_PACKING_CFG0);
413 writel_relaxed(cfg1, se->base + SE_GENI_TX_PACKING_CFG1);
414 }
415 if (rx_cfg) {
416 writel_relaxed(cfg0, se->base + SE_GENI_RX_PACKING_CFG0);
417 writel_relaxed(cfg1, se->base + SE_GENI_RX_PACKING_CFG1);
418 }
419
420 /*
421 * Number of protocol words in each FIFO entry
422 * 0 - 4x8, four words in each entry, max word size of 8 bits
423 * 1 - 2x16, two words in each entry, max word size of 16 bits
424 * 2 - 1x32, one word in each entry, max word size of 32 bits
425 * 3 - undefined
426 */
427 if (pack_words || bpw == 32)
428 writel_relaxed(bpw / 16, se->base + SE_GENI_BYTE_GRAN);
429}
430EXPORT_SYMBOL(geni_se_config_packing);
431
432static void geni_se_clks_off(struct geni_se *se)
433{
434 struct geni_wrapper *wrapper = se->wrapper;
435
436 clk_disable_unprepare(se->clk);
437 clk_bulk_disable_unprepare(ARRAY_SIZE(wrapper->ahb_clks),
438 wrapper->ahb_clks);
439}
440
441/**
442 * geni_se_resources_off() - Turn off resources associated with the serial
443 * engine
444 * @se: Pointer to the concerned serial engine.
445 *
446 * Return: 0 on success, standard Linux error codes on failure/error.
447 */
448int geni_se_resources_off(struct geni_se *se)
449{
450 int ret;
451
452 ret = pinctrl_pm_select_sleep_state(se->dev);
453 if (ret)
454 return ret;
455
456 geni_se_clks_off(se);
457 return 0;
458}
459EXPORT_SYMBOL(geni_se_resources_off);
460
461static int geni_se_clks_on(struct geni_se *se)
462{
463 int ret;
464 struct geni_wrapper *wrapper = se->wrapper;
465
466 ret = clk_bulk_prepare_enable(ARRAY_SIZE(wrapper->ahb_clks),
467 wrapper->ahb_clks);
468 if (ret)
469 return ret;
470
471 ret = clk_prepare_enable(se->clk);
472 if (ret)
473 clk_bulk_disable_unprepare(ARRAY_SIZE(wrapper->ahb_clks),
474 wrapper->ahb_clks);
475 return ret;
476}
477
478/**
479 * geni_se_resources_on() - Turn on resources associated with the serial
480 * engine
481 * @se: Pointer to the concerned serial engine.
482 *
483 * Return: 0 on success, standard Linux error codes on failure/error.
484 */
485int geni_se_resources_on(struct geni_se *se)
486{
487 int ret;
488
489 ret = geni_se_clks_on(se);
490 if (ret)
491 return ret;
492
493 ret = pinctrl_pm_select_default_state(se->dev);
494 if (ret)
495 geni_se_clks_off(se);
496
497 return ret;
498}
499EXPORT_SYMBOL(geni_se_resources_on);
500
501/**
502 * geni_se_clk_tbl_get() - Get the clock table to program DFS
503 * @se: Pointer to the concerned serial engine.
504 * @tbl: Table in which the output is returned.
505 *
506 * This function is called by the protocol drivers to determine the different
507 * clock frequencies supported by serial engine core clock. The protocol
508 * drivers use the output to determine the clock frequency index to be
509 * programmed into DFS.
510 *
511 * Return: number of valid performance levels in the table on success,
512 * standard Linux error codes on failure.
513 */
514int geni_se_clk_tbl_get(struct geni_se *se, unsigned long **tbl)
515{
516 unsigned long freq = 0;
517 int i;
518
519 if (se->clk_perf_tbl) {
520 *tbl = se->clk_perf_tbl;
521 return se->num_clk_levels;
522 }
523
524 se->clk_perf_tbl = devm_kcalloc(se->dev, MAX_CLK_PERF_LEVEL,
525 sizeof(*se->clk_perf_tbl),
526 GFP_KERNEL);
527 if (!se->clk_perf_tbl)
528 return -ENOMEM;
529
530 for (i = 0; i < MAX_CLK_PERF_LEVEL; i++) {
531 freq = clk_round_rate(se->clk, freq + 1);
532 if (!freq || freq == se->clk_perf_tbl[i - 1])
533 break;
534 se->clk_perf_tbl[i] = freq;
535 }
536 se->num_clk_levels = i;
537 *tbl = se->clk_perf_tbl;
538 return se->num_clk_levels;
539}
540EXPORT_SYMBOL(geni_se_clk_tbl_get);
541
542/**
543 * geni_se_clk_freq_match() - Get the matching or closest SE clock frequency
544 * @se: Pointer to the concerned serial engine.
545 * @req_freq: Requested clock frequency.
546 * @index: Index of the resultant frequency in the table.
547 * @res_freq: Resultant frequency which matches or is closer to the
548 * requested frequency.
549 * @exact: Flag to indicate exact multiple requirement of the requested
550 * frequency.
551 *
552 * This function is called by the protocol drivers to determine the matching
553 * or exact multiple of the requested frequency, as provided by the serial
554 * engine clock in order to meet the performance requirements. If there is
555 * no matching or exact multiple of the requested frequency found, then it
556 * selects the closest floor frequency, if exact flag is not set.
557 *
558 * Return: 0 on success, standard Linux error codes on failure.
559 */
560int geni_se_clk_freq_match(struct geni_se *se, unsigned long req_freq,
561 unsigned int *index, unsigned long *res_freq,
562 bool exact)
563{
564 unsigned long *tbl;
565 int num_clk_levels;
566 int i;
567
568 num_clk_levels = geni_se_clk_tbl_get(se, &tbl);
569 if (num_clk_levels < 0)
570 return num_clk_levels;
571
572 if (num_clk_levels == 0)
573 return -EINVAL;
574
575 *res_freq = 0;
576 for (i = 0; i < num_clk_levels; i++) {
577 if (!(tbl[i] % req_freq)) {
578 *index = i;
579 *res_freq = tbl[i];
580 return 0;
581 }
582
583 if (!(*res_freq) || ((tbl[i] > *res_freq) &&
584 (tbl[i] < req_freq))) {
585 *index = i;
586 *res_freq = tbl[i];
587 }
588 }
589
590 if (exact)
591 return -EINVAL;
592
593 return 0;
594}
595EXPORT_SYMBOL(geni_se_clk_freq_match);
596
597#define GENI_SE_DMA_DONE_EN BIT(0)
598#define GENI_SE_DMA_EOT_EN BIT(1)
599#define GENI_SE_DMA_AHB_ERR_EN BIT(2)
600#define GENI_SE_DMA_EOT_BUF BIT(0)
601/**
602 * geni_se_tx_dma_prep() - Prepare the serial engine for TX DMA transfer
603 * @se: Pointer to the concerned serial engine.
604 * @buf: Pointer to the TX buffer.
605 * @len: Length of the TX buffer.
606 * @iova: Pointer to store the mapped DMA address.
607 *
608 * This function is used to prepare the buffers for DMA TX.
609 *
610 * Return: 0 on success, standard Linux error codes on failure.
611 */
612int geni_se_tx_dma_prep(struct geni_se *se, void *buf, size_t len,
613 dma_addr_t *iova)
614{
615 struct geni_wrapper *wrapper = se->wrapper;
616 u32 val;
617
618 *iova = dma_map_single(wrapper->dev, buf, len, DMA_TO_DEVICE);
619 if (dma_mapping_error(wrapper->dev, *iova))
620 return -EIO;
621
622 val = GENI_SE_DMA_DONE_EN;
623 val |= GENI_SE_DMA_EOT_EN;
624 val |= GENI_SE_DMA_AHB_ERR_EN;
625 writel_relaxed(val, se->base + SE_DMA_TX_IRQ_EN_SET);
626 writel_relaxed(lower_32_bits(*iova), se->base + SE_DMA_TX_PTR_L);
627 writel_relaxed(upper_32_bits(*iova), se->base + SE_DMA_TX_PTR_H);
628 writel_relaxed(GENI_SE_DMA_EOT_BUF, se->base + SE_DMA_TX_ATTR);
629 writel_relaxed(len, se->base + SE_DMA_TX_LEN);
630 return 0;
631}
632EXPORT_SYMBOL(geni_se_tx_dma_prep);
633
634/**
635 * geni_se_rx_dma_prep() - Prepare the serial engine for RX DMA transfer
636 * @se: Pointer to the concerned serial engine.
637 * @buf: Pointer to the RX buffer.
638 * @len: Length of the RX buffer.
639 * @iova: Pointer to store the mapped DMA address.
640 *
641 * This function is used to prepare the buffers for DMA RX.
642 *
643 * Return: 0 on success, standard Linux error codes on failure.
644 */
645int geni_se_rx_dma_prep(struct geni_se *se, void *buf, size_t len,
646 dma_addr_t *iova)
647{
648 struct geni_wrapper *wrapper = se->wrapper;
649 u32 val;
650
651 *iova = dma_map_single(wrapper->dev, buf, len, DMA_FROM_DEVICE);
652 if (dma_mapping_error(wrapper->dev, *iova))
653 return -EIO;
654
655 val = GENI_SE_DMA_DONE_EN;
656 val |= GENI_SE_DMA_EOT_EN;
657 val |= GENI_SE_DMA_AHB_ERR_EN;
658 writel_relaxed(val, se->base + SE_DMA_RX_IRQ_EN_SET);
659 writel_relaxed(lower_32_bits(*iova), se->base + SE_DMA_RX_PTR_L);
660 writel_relaxed(upper_32_bits(*iova), se->base + SE_DMA_RX_PTR_H);
661 /* RX does not have EOT buffer type bit. So just reset RX_ATTR */
662 writel_relaxed(0, se->base + SE_DMA_RX_ATTR);
663 writel_relaxed(len, se->base + SE_DMA_RX_LEN);
664 return 0;
665}
666EXPORT_SYMBOL(geni_se_rx_dma_prep);
667
668/**
669 * geni_se_tx_dma_unprep() - Unprepare the serial engine after TX DMA transfer
670 * @se: Pointer to the concerned serial engine.
671 * @iova: DMA address of the TX buffer.
672 * @len: Length of the TX buffer.
673 *
674 * This function is used to unprepare the DMA buffers after DMA TX.
675 */
676void geni_se_tx_dma_unprep(struct geni_se *se, dma_addr_t iova, size_t len)
677{
678 struct geni_wrapper *wrapper = se->wrapper;
679
680 if (iova && !dma_mapping_error(wrapper->dev, iova))
681 dma_unmap_single(wrapper->dev, iova, len, DMA_TO_DEVICE);
682}
683EXPORT_SYMBOL(geni_se_tx_dma_unprep);
684
685/**
686 * geni_se_rx_dma_unprep() - Unprepare the serial engine after RX DMA transfer
687 * @se: Pointer to the concerned serial engine.
688 * @iova: DMA address of the RX buffer.
689 * @len: Length of the RX buffer.
690 *
691 * This function is used to unprepare the DMA buffers after DMA RX.
692 */
693void geni_se_rx_dma_unprep(struct geni_se *se, dma_addr_t iova, size_t len)
694{
695 struct geni_wrapper *wrapper = se->wrapper;
696
697 if (iova && !dma_mapping_error(wrapper->dev, iova))
698 dma_unmap_single(wrapper->dev, iova, len, DMA_FROM_DEVICE);
699}
700EXPORT_SYMBOL(geni_se_rx_dma_unprep);
701
702static int geni_se_probe(struct platform_device *pdev)
703{
704 struct device *dev = &pdev->dev;
705 struct resource *res;
706 struct geni_wrapper *wrapper;
707 int ret;
708
709 wrapper = devm_kzalloc(dev, sizeof(*wrapper), GFP_KERNEL);
710 if (!wrapper)
711 return -ENOMEM;
712
713 wrapper->dev = dev;
714 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
715 wrapper->base = devm_ioremap_resource(dev, res);
716 if (IS_ERR(wrapper->base))
717 return PTR_ERR(wrapper->base);
718
719 wrapper->ahb_clks[0].id = "m-ahb";
720 wrapper->ahb_clks[1].id = "s-ahb";
721 ret = devm_clk_bulk_get(dev, NUM_AHB_CLKS, wrapper->ahb_clks);
722 if (ret) {
723 dev_err(dev, "Err getting AHB clks %d\n", ret);
724 return ret;
725 }
726
727 dev_set_drvdata(dev, wrapper);
728 dev_dbg(dev, "GENI SE Driver probed\n");
729 return devm_of_platform_populate(dev);
730}
731
732static const struct of_device_id geni_se_dt_match[] = {
733 { .compatible = "qcom,geni-se-qup", },
734 {}
735};
736MODULE_DEVICE_TABLE(of, geni_se_dt_match);
737
738static struct platform_driver geni_se_driver = {
739 .driver = {
740 .name = "geni_se_qup",
741 .of_match_table = geni_se_dt_match,
742 },
743 .probe = geni_se_probe,
744};
745module_platform_driver(geni_se_driver);
746
747MODULE_DESCRIPTION("GENI Serial Engine Driver");
748MODULE_LICENSE("GPL v2");
diff --git a/include/linux/qcom-geni-se.h b/include/linux/qcom-geni-se.h
new file mode 100644
index 000000000000..5d6144977828
--- /dev/null
+++ b/include/linux/qcom-geni-se.h
@@ -0,0 +1,425 @@
1/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
2/*
3 * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
4 */
5
6#ifndef _LINUX_QCOM_GENI_SE
7#define _LINUX_QCOM_GENI_SE
8
9/* Transfer mode supported by GENI Serial Engines */
10enum geni_se_xfer_mode {
11 GENI_SE_INVALID,
12 GENI_SE_FIFO,
13 GENI_SE_DMA,
14};
15
16/* Protocols supported by GENI Serial Engines */
17enum geni_se_protocol_type {
18 GENI_SE_NONE,
19 GENI_SE_SPI,
20 GENI_SE_UART,
21 GENI_SE_I2C,
22 GENI_SE_I3C,
23};
24
25struct geni_wrapper;
26struct clk;
27
28/**
29 * struct geni_se - GENI Serial Engine
30 * @base: Base Address of the Serial Engine's register block
31 * @dev: Pointer to the Serial Engine device
32 * @wrapper: Pointer to the parent QUP Wrapper core
33 * @clk: Handle to the core serial engine clock
34 * @num_clk_levels: Number of valid clock levels in clk_perf_tbl
35 * @clk_perf_tbl: Table of clock frequency input to serial engine clock
36 */
37struct geni_se {
38 void __iomem *base;
39 struct device *dev;
40 struct geni_wrapper *wrapper;
41 struct clk *clk;
42 unsigned int num_clk_levels;
43 unsigned long *clk_perf_tbl;
44};
45
46/* Common SE registers */
47#define GENI_FORCE_DEFAULT_REG 0x20
48#define SE_GENI_STATUS 0x40
49#define GENI_SER_M_CLK_CFG 0x48
50#define GENI_SER_S_CLK_CFG 0x4c
51#define GENI_FW_REVISION_RO 0x68
52#define SE_GENI_CLK_SEL 0x7c
53#define SE_GENI_DMA_MODE_EN 0x258
54#define SE_GENI_M_CMD0 0x600
55#define SE_GENI_M_CMD_CTRL_REG 0x604
56#define SE_GENI_M_IRQ_STATUS 0x610
57#define SE_GENI_M_IRQ_EN 0x614
58#define SE_GENI_M_IRQ_CLEAR 0x618
59#define SE_GENI_S_CMD0 0x630
60#define SE_GENI_S_CMD_CTRL_REG 0x634
61#define SE_GENI_S_IRQ_STATUS 0x640
62#define SE_GENI_S_IRQ_EN 0x644
63#define SE_GENI_S_IRQ_CLEAR 0x648
64#define SE_GENI_TX_FIFOn 0x700
65#define SE_GENI_RX_FIFOn 0x780
66#define SE_GENI_TX_FIFO_STATUS 0x800
67#define SE_GENI_RX_FIFO_STATUS 0x804
68#define SE_GENI_TX_WATERMARK_REG 0x80c
69#define SE_GENI_RX_WATERMARK_REG 0x810
70#define SE_GENI_RX_RFR_WATERMARK_REG 0x814
71#define SE_GENI_IOS 0x908
72#define SE_DMA_TX_IRQ_STAT 0xc40
73#define SE_DMA_TX_IRQ_CLR 0xc44
74#define SE_DMA_TX_FSM_RST 0xc58
75#define SE_DMA_RX_IRQ_STAT 0xd40
76#define SE_DMA_RX_IRQ_CLR 0xd44
77#define SE_DMA_RX_FSM_RST 0xd58
78#define SE_HW_PARAM_0 0xe24
79#define SE_HW_PARAM_1 0xe28
80
81/* GENI_FORCE_DEFAULT_REG fields */
82#define FORCE_DEFAULT BIT(0)
83
84/* GENI_STATUS fields */
85#define M_GENI_CMD_ACTIVE BIT(0)
86#define S_GENI_CMD_ACTIVE BIT(12)
87
88/* GENI_SER_M_CLK_CFG/GENI_SER_S_CLK_CFG */
89#define SER_CLK_EN BIT(0)
90#define CLK_DIV_MSK GENMASK(15, 4)
91#define CLK_DIV_SHFT 4
92
93/* GENI_FW_REVISION_RO fields */
94#define FW_REV_PROTOCOL_MSK GENMASK(15, 8)
95#define FW_REV_PROTOCOL_SHFT 8
96
97/* GENI_CLK_SEL fields */
98#define CLK_SEL_MSK GENMASK(2, 0)
99
100/* SE_GENI_DMA_MODE_EN */
101#define GENI_DMA_MODE_EN BIT(0)
102
103/* GENI_M_CMD0 fields */
104#define M_OPCODE_MSK GENMASK(31, 27)
105#define M_OPCODE_SHFT 27
106#define M_PARAMS_MSK GENMASK(26, 0)
107
108/* GENI_M_CMD_CTRL_REG */
109#define M_GENI_CMD_CANCEL BIT(2)
110#define M_GENI_CMD_ABORT BIT(1)
111#define M_GENI_DISABLE BIT(0)
112
113/* GENI_S_CMD0 fields */
114#define S_OPCODE_MSK GENMASK(31, 27)
115#define S_OPCODE_SHFT 27
116#define S_PARAMS_MSK GENMASK(26, 0)
117
118/* GENI_S_CMD_CTRL_REG */
119#define S_GENI_CMD_CANCEL BIT(2)
120#define S_GENI_CMD_ABORT BIT(1)
121#define S_GENI_DISABLE BIT(0)
122
123/* GENI_M_IRQ_EN fields */
124#define M_CMD_DONE_EN BIT(0)
125#define M_CMD_OVERRUN_EN BIT(1)
126#define M_ILLEGAL_CMD_EN BIT(2)
127#define M_CMD_FAILURE_EN BIT(3)
128#define M_CMD_CANCEL_EN BIT(4)
129#define M_CMD_ABORT_EN BIT(5)
130#define M_TIMESTAMP_EN BIT(6)
131#define M_RX_IRQ_EN BIT(7)
132#define M_GP_SYNC_IRQ_0_EN BIT(8)
133#define M_GP_IRQ_0_EN BIT(9)
134#define M_GP_IRQ_1_EN BIT(10)
135#define M_GP_IRQ_2_EN BIT(11)
136#define M_GP_IRQ_3_EN BIT(12)
137#define M_GP_IRQ_4_EN BIT(13)
138#define M_GP_IRQ_5_EN BIT(14)
139#define M_IO_DATA_DEASSERT_EN BIT(22)
140#define M_IO_DATA_ASSERT_EN BIT(23)
141#define M_RX_FIFO_RD_ERR_EN BIT(24)
142#define M_RX_FIFO_WR_ERR_EN BIT(25)
143#define M_RX_FIFO_WATERMARK_EN BIT(26)
144#define M_RX_FIFO_LAST_EN BIT(27)
145#define M_TX_FIFO_RD_ERR_EN BIT(28)
146#define M_TX_FIFO_WR_ERR_EN BIT(29)
147#define M_TX_FIFO_WATERMARK_EN BIT(30)
148#define M_SEC_IRQ_EN BIT(31)
149#define M_COMMON_GENI_M_IRQ_EN (GENMASK(6, 1) | \
150 M_IO_DATA_DEASSERT_EN | \
151 M_IO_DATA_ASSERT_EN | M_RX_FIFO_RD_ERR_EN | \
152 M_RX_FIFO_WR_ERR_EN | M_TX_FIFO_RD_ERR_EN | \
153 M_TX_FIFO_WR_ERR_EN)
154
155/* GENI_S_IRQ_EN fields */
156#define S_CMD_DONE_EN BIT(0)
157#define S_CMD_OVERRUN_EN BIT(1)
158#define S_ILLEGAL_CMD_EN BIT(2)
159#define S_CMD_FAILURE_EN BIT(3)
160#define S_CMD_CANCEL_EN BIT(4)
161#define S_CMD_ABORT_EN BIT(5)
162#define S_GP_SYNC_IRQ_0_EN BIT(8)
163#define S_GP_IRQ_0_EN BIT(9)
164#define S_GP_IRQ_1_EN BIT(10)
165#define S_GP_IRQ_2_EN BIT(11)
166#define S_GP_IRQ_3_EN BIT(12)
167#define S_GP_IRQ_4_EN BIT(13)
168#define S_GP_IRQ_5_EN BIT(14)
169#define S_IO_DATA_DEASSERT_EN BIT(22)
170#define S_IO_DATA_ASSERT_EN BIT(23)
171#define S_RX_FIFO_RD_ERR_EN BIT(24)
172#define S_RX_FIFO_WR_ERR_EN BIT(25)
173#define S_RX_FIFO_WATERMARK_EN BIT(26)
174#define S_RX_FIFO_LAST_EN BIT(27)
175#define S_COMMON_GENI_S_IRQ_EN (GENMASK(5, 1) | GENMASK(13, 9) | \
176 S_RX_FIFO_RD_ERR_EN | S_RX_FIFO_WR_ERR_EN)
177
178/* GENI_/TX/RX/RX_RFR/_WATERMARK_REG fields */
179#define WATERMARK_MSK GENMASK(5, 0)
180
181/* GENI_TX_FIFO_STATUS fields */
182#define TX_FIFO_WC GENMASK(27, 0)
183
184/* GENI_RX_FIFO_STATUS fields */
185#define RX_LAST BIT(31)
186#define RX_LAST_BYTE_VALID_MSK GENMASK(30, 28)
187#define RX_LAST_BYTE_VALID_SHFT 28
188#define RX_FIFO_WC_MSK GENMASK(24, 0)
189
190/* SE_GENI_IOS fields */
191#define IO2_DATA_IN BIT(1)
192#define RX_DATA_IN BIT(0)
193
194/* SE_DMA_TX_IRQ_STAT Register fields */
195#define TX_DMA_DONE BIT(0)
196#define TX_EOT BIT(1)
197#define TX_SBE BIT(2)
198#define TX_RESET_DONE BIT(3)
199
200/* SE_DMA_RX_IRQ_STAT Register fields */
201#define RX_DMA_DONE BIT(0)
202#define RX_EOT BIT(1)
203#define RX_SBE BIT(2)
204#define RX_RESET_DONE BIT(3)
205#define RX_FLUSH_DONE BIT(4)
206#define RX_GENI_GP_IRQ GENMASK(10, 5)
207#define RX_GENI_CANCEL_IRQ BIT(11)
208#define RX_GENI_GP_IRQ_EXT GENMASK(13, 12)
209
210/* SE_HW_PARAM_0 fields */
211#define TX_FIFO_WIDTH_MSK GENMASK(29, 24)
212#define TX_FIFO_WIDTH_SHFT 24
213#define TX_FIFO_DEPTH_MSK GENMASK(21, 16)
214#define TX_FIFO_DEPTH_SHFT 16
215
216/* SE_HW_PARAM_1 fields */
217#define RX_FIFO_WIDTH_MSK GENMASK(29, 24)
218#define RX_FIFO_WIDTH_SHFT 24
219#define RX_FIFO_DEPTH_MSK GENMASK(21, 16)
220#define RX_FIFO_DEPTH_SHFT 16
221
222#define HW_VER_MAJOR_MASK GENMASK(31, 28)
223#define HW_VER_MAJOR_SHFT 28
224#define HW_VER_MINOR_MASK GENMASK(27, 16)
225#define HW_VER_MINOR_SHFT 16
226#define HW_VER_STEP_MASK GENMASK(15, 0)
227
228#if IS_ENABLED(CONFIG_QCOM_GENI_SE)
229
230u32 geni_se_get_qup_hw_version(struct geni_se *se);
231
232#define geni_se_get_wrapper_version(se, major, minor, step) do { \
233 u32 ver; \
234\
235 ver = geni_se_get_qup_hw_version(se); \
236 major = (ver & HW_VER_MAJOR_MASK) >> HW_VER_MAJOR_SHFT; \
237 minor = (ver & HW_VER_MINOR_MASK) >> HW_VER_MINOR_SHFT; \
238 step = version & HW_VER_STEP_MASK; \
239} while (0)
240
241/**
242 * geni_se_read_proto() - Read the protocol configured for a serial engine
243 * @se: Pointer to the concerned serial engine.
244 *
245 * Return: Protocol value as configured in the serial engine.
246 */
247static inline u32 geni_se_read_proto(struct geni_se *se)
248{
249 u32 val;
250
251 val = readl_relaxed(se->base + GENI_FW_REVISION_RO);
252
253 return (val & FW_REV_PROTOCOL_MSK) >> FW_REV_PROTOCOL_SHFT;
254}
255
256/**
257 * geni_se_setup_m_cmd() - Setup the primary sequencer
258 * @se: Pointer to the concerned serial engine.
259 * @cmd: Command/Operation to setup in the primary sequencer.
260 * @params: Parameter for the sequencer command.
261 *
262 * This function is used to configure the primary sequencer with the
263 * command and its associated parameters.
264 */
265static inline void geni_se_setup_m_cmd(struct geni_se *se, u32 cmd, u32 params)
266{
267 u32 m_cmd;
268
269 m_cmd = (cmd << M_OPCODE_SHFT) | (params & M_PARAMS_MSK);
270 writel_relaxed(m_cmd, se->base + SE_GENI_M_CMD0);
271}
272
273/**
274 * geni_se_setup_s_cmd() - Setup the secondary sequencer
275 * @se: Pointer to the concerned serial engine.
276 * @cmd: Command/Operation to setup in the secondary sequencer.
277 * @params: Parameter for the sequencer command.
278 *
279 * This function is used to configure the secondary sequencer with the
280 * command and its associated parameters.
281 */
282static inline void geni_se_setup_s_cmd(struct geni_se *se, u32 cmd, u32 params)
283{
284 u32 s_cmd;
285
286 s_cmd = readl_relaxed(se->base + SE_GENI_S_CMD0);
287 s_cmd &= ~(S_OPCODE_MSK | S_PARAMS_MSK);
288 s_cmd |= (cmd << S_OPCODE_SHFT);
289 s_cmd |= (params & S_PARAMS_MSK);
290 writel_relaxed(s_cmd, se->base + SE_GENI_S_CMD0);
291}
292
293/**
294 * geni_se_cancel_m_cmd() - Cancel the command configured in the primary
295 * sequencer
296 * @se: Pointer to the concerned serial engine.
297 *
298 * This function is used to cancel the currently configured command in the
299 * primary sequencer.
300 */
301static inline void geni_se_cancel_m_cmd(struct geni_se *se)
302{
303 writel_relaxed(M_GENI_CMD_CANCEL, se->base + SE_GENI_M_CMD_CTRL_REG);
304}
305
306/**
307 * geni_se_cancel_s_cmd() - Cancel the command configured in the secondary
308 * sequencer
309 * @se: Pointer to the concerned serial engine.
310 *
311 * This function is used to cancel the currently configured command in the
312 * secondary sequencer.
313 */
314static inline void geni_se_cancel_s_cmd(struct geni_se *se)
315{
316 writel_relaxed(S_GENI_CMD_CANCEL, se->base + SE_GENI_S_CMD_CTRL_REG);
317}
318
319/**
320 * geni_se_abort_m_cmd() - Abort the command configured in the primary sequencer
321 * @se: Pointer to the concerned serial engine.
322 *
323 * This function is used to force abort the currently configured command in the
324 * primary sequencer.
325 */
326static inline void geni_se_abort_m_cmd(struct geni_se *se)
327{
328 writel_relaxed(M_GENI_CMD_ABORT, se->base + SE_GENI_M_CMD_CTRL_REG);
329}
330
331/**
332 * geni_se_abort_s_cmd() - Abort the command configured in the secondary
333 * sequencer
334 * @se: Pointer to the concerned serial engine.
335 *
336 * This function is used to force abort the currently configured command in the
337 * secondary sequencer.
338 */
339static inline void geni_se_abort_s_cmd(struct geni_se *se)
340{
341 writel_relaxed(S_GENI_CMD_ABORT, se->base + SE_GENI_S_CMD_CTRL_REG);
342}
343
344/**
345 * geni_se_get_tx_fifo_depth() - Get the TX fifo depth of the serial engine
346 * @se: Pointer to the concerned serial engine.
347 *
348 * This function is used to get the depth i.e. number of elements in the
349 * TX fifo of the serial engine.
350 *
351 * Return: TX fifo depth in units of FIFO words.
352 */
353static inline u32 geni_se_get_tx_fifo_depth(struct geni_se *se)
354{
355 u32 val;
356
357 val = readl_relaxed(se->base + SE_HW_PARAM_0);
358
359 return (val & TX_FIFO_DEPTH_MSK) >> TX_FIFO_DEPTH_SHFT;
360}
361
362/**
363 * geni_se_get_tx_fifo_width() - Get the TX fifo width of the serial engine
364 * @se: Pointer to the concerned serial engine.
365 *
366 * This function is used to get the width i.e. word size per element in the
367 * TX fifo of the serial engine.
368 *
369 * Return: TX fifo width in bits
370 */
371static inline u32 geni_se_get_tx_fifo_width(struct geni_se *se)
372{
373 u32 val;
374
375 val = readl_relaxed(se->base + SE_HW_PARAM_0);
376
377 return (val & TX_FIFO_WIDTH_MSK) >> TX_FIFO_WIDTH_SHFT;
378}
379
380/**
381 * geni_se_get_rx_fifo_depth() - Get the RX fifo depth of the serial engine
382 * @se: Pointer to the concerned serial engine.
383 *
384 * This function is used to get the depth i.e. number of elements in the
385 * RX fifo of the serial engine.
386 *
387 * Return: RX fifo depth in units of FIFO words
388 */
389static inline u32 geni_se_get_rx_fifo_depth(struct geni_se *se)
390{
391 u32 val;
392
393 val = readl_relaxed(se->base + SE_HW_PARAM_1);
394
395 return (val & RX_FIFO_DEPTH_MSK) >> RX_FIFO_DEPTH_SHFT;
396}
397
398void geni_se_init(struct geni_se *se, u32 rx_wm, u32 rx_rfr);
399
400void geni_se_select_mode(struct geni_se *se, enum geni_se_xfer_mode mode);
401
402void geni_se_config_packing(struct geni_se *se, int bpw, int pack_words,
403 bool msb_to_lsb, bool tx_cfg, bool rx_cfg);
404
405int geni_se_resources_off(struct geni_se *se);
406
407int geni_se_resources_on(struct geni_se *se);
408
409int geni_se_clk_tbl_get(struct geni_se *se, unsigned long **tbl);
410
411int geni_se_clk_freq_match(struct geni_se *se, unsigned long req_freq,
412 unsigned int *index, unsigned long *res_freq,
413 bool exact);
414
415int geni_se_tx_dma_prep(struct geni_se *se, void *buf, size_t len,
416 dma_addr_t *iova);
417
418int geni_se_rx_dma_prep(struct geni_se *se, void *buf, size_t len,
419 dma_addr_t *iova);
420
421void geni_se_tx_dma_unprep(struct geni_se *se, dma_addr_t iova, size_t len);
422
423void geni_se_rx_dma_unprep(struct geni_se *se, dma_addr_t iova, size_t len);
424#endif
425#endif