Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit dd66ce00 authored by Sujeev Dias's avatar Sujeev Dias
Browse files

dmaengine: qcom: Add support for GPI DMA engine



Add dmaengine framework support for QCOM GPI DMA controller.
GPI controller can be used by peripheral buses such as I2C,
UART, and SPI for transferring data between system memory
and peripheral.

CRs-Fixed: 2042764
Change-Id: I645f52361dbd8a0588d65b23c6a1b2202a97cbda
Signed-off-by: default avatarSujeev Dias <sdias@codeaurora.org>
parent 0e6032e3
Loading
Loading
Loading
Loading
+84 −0
Original line number Diff line number Diff line
Qualcomm Technologies Inc GPI DMA controller

QCOM GPI DMA controller provides DMA capabilities for
peripheral buses such as I2C, UART, and SPI.

==============
Node Structure
==============

Main node properties:

- #dma-cells
  Usage: required
  Value type: <u32>
  Definition: Number of parameters client will provide.  Must be set to 6.
	1st parameter: gpii index
	2nd parameter: channel index
	3rd parameter: serial engine index
	4th parameter: bus protocol, 1 for SPI, 2 for UART, 3 for I2C
	5th parameter: channel ring length in transfer ring elements
	6th parameter: event processing priority, set to 0 for lowest latency

- compatible
  Usage: required
  Value type: <string>
  Definition: "qcom,gpi-dma"

- reg
  Usage: required
  Value type: Array of <u32>
  Definition: register address space location and size

- reg-name
  Usage: required
  Value type: <string>
  Definition: register space name, must be "gpi-top"

- interrupts
  Usage: required
  Value type: Array of <u32>
  Definition: Array of tuples which describe interrupt line for each GPII
	instance.

- qcom,max-num-gpii
  Usage: required
  Value type: <u32>
  Definition: Total number of GPII instances available for this controller.

- qcom,gpii-mask
  Usage: required
  Value type: <u32>
  Definition: Bitmap of supported GPII instances in hlos.

- qcom,ev-factor
  Usage: required
  Value type: <u32>
  Definition: Event ring transfer size compare to channel transfer ring. Event
	ring length = ev-factor * transfer ring size

- iommus
  Usage: required
  Value type: <phandle u32 u32>
  Definition: phandle for apps smmu controller and SID, and mask
	for the controller.  For more detail please check binding
	documentation arm,smmu.txt

========
Example:
========
gpi_dma0: qcom,gpi-dma@0x800000 {
	#dma-cells = <6>;
	compatible = "qcom,gpi-dma";
	reg = <0x800000 0x60000>;
	reg-names = "gpi-top";
	interrupts = <0 244 0>, <0 245 0>, <0 246 0>, <0 247 0>,
                <0 248 0>, <0 249 0>, <0 250 0>, <0 251 0>,
                <0 252 0>, <0 253 0>, <0 254 0>, <0 255 0>,
                <0 256 0>;
	qcom,max-num-gpii = <13>;
	qcom,gpii-mask = <0xfa>;
	qcom,ev-factor = <2>;
	iommus = <&apps_smmu 0x0016 0x0>;
	status = "ok";
};
+19 −0
Original line number Diff line number Diff line
@@ -27,3 +27,22 @@ config QCOM_HIDMA
	  (user to kernel, kernel to kernel, etc.).  It only supports
	  memcpy interface. The core is not intended for general
	  purpose slave DMA.

config QCOM_GPI_DMA
	tristate "Qualcomm Technologies Inc GPI DMA support"
	depends on ARCH_QCOM
	select DMA_ENGINE
	select DMA_VIRTUAL_CHANNELS
	help
	  Enable support for the QCOM GPI DMA controller. This controller
	  provides DMA capabilities for a variety of peripheral buses such
	  as I2C, UART, and SPI. By using GPI dmaengine driver, bus drivers
	  can use a standardize interface that is protocol independent to
	  transfer data between DDR and peripheral.

config QCOM_GPI_DMA_DEBUG
	bool "Qualcomm Technologies Inc GPI debug support"
	depends on QCOM_GPI_DMA
	help
	  Enable detailed logging for QCOM GPI driver. Extra logging will be
	  helpful when debugging critical issues.
+1 −0
Original line number Diff line number Diff line
@@ -3,3 +3,4 @@ obj-$(CONFIG_QCOM_HIDMA_MGMT) += hdma_mgmt.o
hdma_mgmt-objs	 := hidma_mgmt.o hidma_mgmt_sys.o
obj-$(CONFIG_QCOM_HIDMA) +=  hdma.o
hdma-objs        := hidma_ll.o hidma.o hidma_dbg.o
obj-$(CONFIG_QCOM_GPI_DMA) += gpi.o

drivers/dma/qcom/gpi.c

0 → 100644
+2816 −0

File added.

Preview size limit exceeded, changes collapsed.

+224 −0
Original line number Diff line number Diff line
/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

/* Register offsets from gpi-top */
#define GPI_GPII_n_CH_k_CNTXT_0_OFFS(n, k) \
	(0x20000 + (0x4000 * (n)) + (0x80 * (k)))
#define GPI_GPII_n_CH_k_CNTXT_0_ELEMENT_SIZE_BMSK (0xFF000000)
#define GPI_GPII_n_CH_k_CNTXT_0_ELEMENT_SIZE_SHFT (24)
#define GPI_GPII_n_CH_k_CNTXT_0_CHSTATE_BMSK (0xF00000)
#define GPI_GPII_n_CH_k_CNTXT_0_CHSTATE_SHFT (20)
#define GPI_GPII_n_CH_k_CNTXT_0_ERINDEX_BMSK (0x7C000)
#define GPI_GPII_n_CH_k_CNTXT_0_ERINDEX_SHFT (14)
#define GPI_GPII_n_CH_k_CNTXT_0_CHID_BMSK (0x1F00)
#define GPI_GPII_n_CH_k_CNTXT_0_CHID_SHFT (8)
#define GPI_GPII_n_CH_k_CNTXT_0_EE_BMSK (0xF0)
#define GPI_GPII_n_CH_k_CNTXT_0_EE_SHFT (4)
#define GPI_GPII_n_CH_k_CNTXT_0_CHTYPE_DIR_BMSK (0x8)
#define GPI_GPII_n_CH_k_CNTXT_0_CHTYPE_DIR_SHFT (3)
#define GPI_GPII_n_CH_k_CNTXT_0_CHTYPE_PROTO_BMSK (0x7)
#define GPI_GPII_n_CH_k_CNTXT_0_CHTYPE_PROTO_SHFT (0)
#define GPI_GPII_n_CH_k_CNTXT_0(el_size, erindex, chtype_dir, chtype_proto) \
	((el_size << 24) | (erindex << 14) | (chtype_dir << 3) | (chtype_proto))
#define GPI_CHTYPE_DIR_IN (0)
#define GPI_CHTYPE_DIR_OUT (1)
#define GPI_CHTYPE_PROTO_GPI (0x2)
#define GPI_GPII_n_CH_k_CNTXT_1_R_LENGTH_BMSK (0xFFFF)
#define GPI_GPII_n_CH_k_CNTXT_1_R_LENGTH_SHFT (0)
#define GPI_GPII_n_CH_k_DOORBELL_0_OFFS(n, k) (0x22000 + (0x4000 * (n)) \
					       + (0x8 * (k)))
#define GPI_GPII_n_CH_CMD_OFFS(n) (0x23008 + (0x4000 * (n)))
#define GPI_GPII_n_CH_CMD_OPCODE_BMSK (0xFF000000)
#define GPI_GPII_n_CH_CMD_OPCODE_SHFT (24)
#define GPI_GPII_n_CH_CMD_CHID_BMSK (0xFF)
#define GPI_GPII_n_CH_CMD_CHID_SHFT (0)
#define GPI_GPII_n_CH_CMD(opcode, chid) ((opcode << 24) | chid)
#define GPI_GPII_n_CH_CMD_ALLOCATE (0)
#define GPI_GPII_n_CH_CMD_START (1)
#define GPI_GPII_n_CH_CMD_STOP (2)
#define GPI_GPII_n_CH_CMD_RESET (9)
#define GPI_GPII_n_CH_CMD_DE_ALLOC (10)
#define GPI_GPII_n_CH_CMD_UART_SW_STALE (32)
#define GPI_GPII_n_CH_CMD_UART_RFR_READY (33)
#define GPI_GPII_n_CH_CMD_UART_RFR_NOT_READY (34)

/* EV Context Array */
#define GPI_GPII_n_EV_CH_k_CNTXT_0_OFFS(n, k) \
	(0x21000 + (0x4000 * (n)) + (0x80 * (k)))
#define GPI_GPII_n_EV_CH_k_CNTXT_0_ELEMENT_SIZE_BMSK (0xFF000000)
#define GPI_GPII_n_EV_CH_k_CNTXT_0_ELEMENT_SIZE_SHFT (24)
#define GPI_GPII_n_EV_CH_k_CNTXT_0_CHSTATE_BMSK (0xF00000)
#define GPI_GPII_n_EV_CH_k_CNTXT_0_CHSTATE_SHFT (20)
#define GPI_GPII_n_EV_CH_k_CNTXT_0_INTYPE_BMSK (0x10000)
#define GPI_GPII_n_EV_CH_k_CNTXT_0_INTYPE_SHFT (16)
#define GPI_GPII_n_EV_CH_k_CNTXT_0_EVCHID_BMSK (0xFF00)
#define GPI_GPII_n_EV_CH_k_CNTXT_0_EVCHID_SHFT (8)
#define GPI_GPII_n_EV_CH_k_CNTXT_0_EE_BMSK (0xF0)
#define GPI_GPII_n_EV_CH_k_CNTXT_0_EE_SHFT (4)
#define GPI_GPII_n_EV_CH_k_CNTXT_0_CHTYPE_BMSK (0xF)
#define GPI_GPII_n_EV_CH_k_CNTXT_0_CHTYPE_SHFT (0)
#define GPI_GPII_n_EV_CH_k_CNTXT_0(el_size, intype, chtype) \
	((el_size << 24) | (intype << 16) | (chtype))
#define GPI_INTTYPE_IRQ (1)
#define GPI_CHTYPE_GPI_EV (0x2)
#define GPI_GPII_n_EV_CH_k_CNTXT_1_R_LENGTH_BMSK (0xFFFF)
#define GPI_GPII_n_EV_CH_k_CNTXT_1_R_LENGTH_SHFT (0)

enum CNTXT_OFFS {
	CNTXT_0_CONFIG = 0x0,
	CNTXT_1_R_LENGTH = 0x4,
	CNTXT_2_RING_BASE_LSB = 0x8,
	CNTXT_3_RING_BASE_MSB = 0xC,
	CNTXT_4_RING_RP_LSB = 0x10,
	CNTXT_5_RING_RP_MSB = 0x14,
	CNTXT_6_RING_WP_LSB = 0x18,
	CNTXT_7_RING_WP_MSB = 0x1C,
	CNTXT_8_RING_INT_MOD = 0x20,
	CNTXT_9_RING_INTVEC = 0x24,
	CNTXT_10_RING_MSI_LSB = 0x28,
	CNTXT_11_RING_MSI_MSB = 0x2C,
	CNTXT_12_RING_RP_UPDATE_LSB = 0x30,
	CNTXT_13_RING_RP_UPDATE_MSB = 0x34,
};

#define GPI_GPII_n_EV_CH_k_DOORBELL_0_OFFS(n, k) \
	(0x22100 + (0x4000 * (n)) + (0x8 * (k)))
#define GPI_GPII_n_EV_CH_CMD_OFFS(n) \
	(0x23010 + (0x4000 * (n)))
#define GPI_GPII_n_EV_CH_CMD_OPCODE_BMSK (0xFF000000)
#define GPI_GPII_n_EV_CH_CMD_OPCODE_SHFT (24)
#define GPI_GPII_n_EV_CH_CMD_CHID_BMSK (0xFF)
#define GPI_GPII_n_EV_CH_CMD_CHID_SHFT (0)
#define GPI_GPII_n_EV_CH_CMD(opcode, chid) \
	((opcode << 24) | chid)
#define GPI_GPII_n_EV_CH_CMD_ALLOCATE (0x00)
#define GPI_GPII_n_EV_CH_CMD_RESET (0x09)
#define GPI_GPII_n_EV_CH_CMD_DE_ALLOC (0x0A)

#define GPI_GPII_n_CNTXT_TYPE_IRQ_OFFS(n) \
	(0x23080 + (0x4000 * (n)))

/* mask type register */
#define GPI_GPII_n_CNTXT_TYPE_IRQ_MSK_OFFS(n) \
	(0x23088 + (0x4000 * (n)))
#define GPI_GPII_n_CNTXT_TYPE_IRQ_MSK_BMSK (0x7F)
#define GPI_GPII_n_CNTXT_TYPE_IRQ_MSK_SHFT (0)
#define GPI_GPII_n_CNTXT_TYPE_IRQ_MSK_GENERAL (0x40)
#define GPI_GPII_n_CNTXT_TYPE_IRQ_MSK_INTER_GPII_EV_CTRL (0x20)
#define GPI_GPII_n_CNTXT_TYPE_IRQ_MSK_INTER_GPII_CH_CTRL (0x10)
#define GPI_GPII_n_CNTXT_TYPE_IRQ_MSK_IEOB (0x08)
#define GPI_GPII_n_CNTXT_TYPE_IRQ_MSK_GLOB (0x04)
#define GPI_GPII_n_CNTXT_TYPE_IRQ_MSK_EV_CTRL (0x02)
#define GPI_GPII_n_CNTXT_TYPE_IRQ_MSK_CH_CTRL (0x01)

#define GPI_GPII_n_CNTXT_SRC_GPII_CH_IRQ_OFFS(n) \
	(0x23090 + (0x4000 * (n)))
#define GPI_GPII_n_CNTXT_SRC_EV_CH_IRQ_OFFS(n) \
	(0x23094 + (0x4000 * (n)))

/* Mask channel control interrupt register */
#define GPI_GPII_n_CNTXT_SRC_CH_IRQ_MSK_OFFS(n) \
	(0x23098 + (0x4000 * (n)))
#define GPI_GPII_n_CNTXT_SRC_CH_IRQ_MSK_BMSK (0x3)
#define GPI_GPII_n_CNTXT_SRC_CH_IRQ_MSK_SHFT (0)

/* Mask event control interrupt register */
#define GPI_GPII_n_CNTXT_SRC_EV_CH_IRQ_MSK_OFFS(n) \
	(0x2309C + (0x4000 * (n)))
#define GPI_GPII_n_CNTXT_SRC_EV_CH_IRQ_MSK_BMSK (0x1)
#define GPI_GPII_n_CNTXT_SRC_EV_CH_IRQ_MSK_SHFT (0)

#define GPI_GPII_n_CNTXT_SRC_CH_IRQ_CLR_OFFS(n) \
	(0x230A0 + (0x4000 * (n)))
#define GPI_GPII_n_CNTXT_SRC_EV_CH_IRQ_CLR_OFFS(n) \
	(0x230A4 + (0x4000 * (n)))
#define GPI_GPII_n_CNTXT_SRC_IEOB_IRQ_OFFS(n) \
	(0x230B0 + (0x4000 * (n)))

/* Mask event interrupt register */
#define GPI_GPII_n_CNTXT_SRC_IEOB_IRQ_MSK_OFFS(n) \
	(0x230B8 + (0x4000 * (n)))
#define GPI_GPII_n_CNTXT_SRC_IEOB_IRQ_MSK_BMSK (0x1)
#define GPI_GPII_n_CNTXT_SRC_IEOB_IRQ_MSK_SHFT (0)

#define GPI_GPII_n_CNTXT_SRC_IEOB_IRQ_CLR_OFFS(n) \
	(0x230C0 + (0x4000 * (n)))
#define GPI_GPII_n_CNTXT_GLOB_IRQ_STTS_OFFS(n) \
	(0x23100 + (0x4000 * (n)))
#define GPI_GLOB_IRQ_ERROR_INT_MSK (0x1)
#define GPI_GLOB_IRQ_GP_INT1_MSK (0x2)
#define GPI_GLOB_IRQ_GP_INT2_MSK (0x4)
#define GPI_GLOB_IRQ_GP_INT3_MSK (0x8)

/* GPII specific Global - Enable bit register */
#define GPI_GPII_n_CNTXT_GLOB_IRQ_EN_OFFS(n) \
	(0x23108 + (0x4000 * (n)))
#define GPI_GPII_n_CNTXT_GLOB_IRQ_EN_BMSK (0xF)
#define GPI_GPII_n_CNTXT_GLOB_IRQ_EN_SHFT (0)
#define GPI_GPII_n_CNTXT_GLOB_IRQ_EN_GP_INT3 (0x8)
#define GPI_GPII_n_CNTXT_GLOB_IRQ_EN_GP_INT2 (0x4)
#define GPI_GPII_n_CNTXT_GLOB_IRQ_EN_GP_INT1 (0x2)
#define GPI_GPII_n_CNTXT_GLOB_IRQ_EN_ERROR_INT (0x1)

#define GPI_GPII_n_CNTXT_GLOB_IRQ_CLR_OFFS(n) \
	(0x23110 + (0x4000 * (n)))
#define GPI_GPII_n_CNTXT_GPII_IRQ_STTS_OFFS(n) \
	(0x23118 + (0x4000 * (n)))

/* GPII general interrupt - Enable bit register */
#define GPI_GPII_n_CNTXT_GPII_IRQ_EN_OFFS(n) \
	(0x23120 + (0x4000 * (n)))
#define GPI_GPII_n_CNTXT_GPII_IRQ_EN_BMSK (0xF)
#define GPI_GPII_n_CNTXT_GPII_IRQ_EN_SHFT (0)
#define GPI_GPII_n_CNTXT_GPII_IRQ_EN_STACK_OVRFLOW (0x8)
#define GPI_GPII_n_CNTXT_GLOB_IRQ_EN_CMD_FIFO_OVRFLOW (0x4)
#define GPI_GPII_n_CNTXT_GLOB_IRQ_EN_BUS_ERROR (0x2)
#define GPI_GPII_n_CNTXT_GLOB_IRQ_EN_BREAK_POINT (0x1)

#define GPI_GPII_n_CNTXT_GPII_IRQ_CLR_OFFS(n) \
	(0x23128 + (0x4000 * (n)))

/* GPII Interrupt Type register */
#define GPI_GPII_n_CNTXT_INTSET_OFFS(n) \
	(0x23180 + (0x4000 * (n)))
#define GPI_GPII_n_CNTXT_INTSET_BMSK (0x1)
#define GPI_GPII_n_CNTXT_INTSET_SHFT (0)

#define GPI_GPII_n_CNTXT_MSI_BASE_LSB_OFFS(n) \
	(0x23188 + (0x4000 * (n)))
#define GPI_GPII_n_CNTXT_MSI_BASE_MSB_OFFS(n) \
	(0x2318C + (0x4000 * (n)))
#define GPI_GPII_n_CNTXT_SCRATCH_0_OFFS(n) \
	(0x23400 + (0x4000 * (n)))
#define GPI_GPII_n_CNTXT_SCRATCH_1_OFFS(n) \
	(0x23404 + (0x4000 * (n)))

#define GPI_GPII_n_ERROR_LOG_OFFS(n) \
	(0x23200 + (0x4000 * (n)))
#define GPI_GPII_n_ERROR_LOG_CLR_OFFS(n) \
	(0x23210 + (0x4000 * (n)))

/* QOS Registers */
#define GPI_GPII_n_CH_k_QOS_OFFS(n, k) \
	(0x2005C + (0x4000 * (n)) + (0x80 * (k)))

/* Scratch registeres */
#define GPI_GPII_n_CH_k_SCRATCH_0_OFFS(n, k) \
	(0x20060 + (0x4000 * (n)) + (0x80 * (k)))
#define GPI_GPII_n_CH_K_SCRATCH_0(pair, proto, seid) \
	((pair << 16) | (proto << 4) | seid)
#define GPI_GPII_n_CH_k_SCRATCH_1_OFFS(n, k) \
	(0x20064 + (0x4000 * (n)) + (0x80 * (k)))
#define GPI_GPII_n_CH_k_SCRATCH_2_OFFS(n, k) \
	(0x20068 + (0x4000 * (n)) + (0x80 * (k)))
#define GPI_GPII_n_CH_k_SCRATCH_3_OFFS(n, k) \
	(0x2006C + (0x4000 * (n)) + (0x80 * (k)))
Loading