aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/soc/qcom/qcom-geni-se.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-06-11 21:19:45 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2018-06-11 21:19:45 -0400
commit8efcf34a263965e471e3999904f94d1f6799d42a (patch)
treea1fe88517cb8a4eb54b50c3ce32eaa1954518b9c /drivers/soc/qcom/qcom-geni-se.c
parent32bcbf8b6d09428907fd045a4ea90562ec7dc4a2 (diff)
parent14321604c82c5415a72e894b83b587a345f5bdf2 (diff)
Merge tag 'armsoc-late' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull ARM SoC late updates from Olof Johansson: "This is a branch with a few merge requests that either came in late, or took a while longer for us to review and merge than usual and thus cut it a bit close to the merge window. We stage them in a separate branch and if things look good, we still send them up -- and that's the case here. This is mostly DT additions for Renesas platforms, adding IP block descriptions for existing and new SoCs. There are also some driver updates for Qualcomm platforms for SMEM/QMI and GENI, which is their generalized serial protocol interface" * tag 'armsoc-late' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (186 commits) soc: qcom: smem: introduce qcom_smem_virt_to_phys() soc: qcom: qmi: fix a buffer sizing bug MAINTAINERS: Update pattern for qcom_scm soc: Unconditionally include qcom Makefile soc: qcom: smem: check sooner in qcom_smem_set_global_partition() soc: qcom: smem: fix qcom_smem_set_global_partition() soc: qcom: smem: fix off-by-one error in qcom_smem_alloc_private() soc: qcom: smem: byte swap values properly soc: qcom: smem: return proper type for cached entry functions soc: qcom: smem: fix first cache entry calculation soc: qcom: cmd-db: Make endian-agnostic drivers: qcom: add command DB driver arm64: dts: renesas: salvator-common: Add ADV7482 support ARM: dts: r8a7740: Add CEU1 ARM: dts: r8a7740: Add CEU0 arm64: dts: renesas: salvator-common: enable VIN arm64: dts: renesas: r8a77970: add VIN and CSI-2 nodes arm64: dts: renesas: r8a77965: add VIN and CSI-2 nodes arm64: dts: renesas: r8a7796: add VIN and CSI-2 nodes arm64: dts: renesas: r8a7795-es1: add CSI-2 node ...
Diffstat (limited to 'drivers/soc/qcom/qcom-geni-se.c')
-rw-r--r--drivers/soc/qcom/qcom-geni-se.c748
1 files changed, 748 insertions, 0 deletions
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");