ipq806x: update bleeding-edge kernel from 4.0 to 4.1

Default kernel doesn't change and stays on 3.18 for now.

Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>

SVN-Revision: 46554
lede-17.01
Felix Fietkau 2015-08-04 23:09:38 +00:00
parent 991e641a76
commit 4d1656e813
41 changed files with 127 additions and 1520 deletions

View File

@ -4,8 +4,9 @@ CONFIG_ALIGNMENT_TRAP=y
CONFIG_APQ_GCC_8084=y CONFIG_APQ_GCC_8084=y
CONFIG_APQ_MMCC_8084=y CONFIG_APQ_MMCC_8084=y
CONFIG_AR8216_PHY=y CONFIG_AR8216_PHY=y
CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y # CONFIG_ARCH_ALPINE is not set
CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y
CONFIG_ARCH_HAS_ELF_RANDOMIZE=y
CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y
CONFIG_ARCH_HAS_SG_CHAIN=y CONFIG_ARCH_HAS_SG_CHAIN=y
CONFIG_ARCH_HAS_TICK_BROADCAST=y CONFIG_ARCH_HAS_TICK_BROADCAST=y
@ -38,6 +39,10 @@ CONFIG_ARM_APPENDED_DTB=y
CONFIG_ARM_ARCH_TIMER=y CONFIG_ARM_ARCH_TIMER=y
CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y
# CONFIG_ARM_ATAG_DTB_COMPAT is not set # CONFIG_ARM_ATAG_DTB_COMPAT is not set
CONFIG_ARM_CCI=y
CONFIG_ARM_CCI400_COMMON=y
CONFIG_ARM_CCI400_PMU=y
# CONFIG_ARM_CPUIDLE is not set
CONFIG_ARM_CPU_SUSPEND=y CONFIG_ARM_CPU_SUSPEND=y
CONFIG_ARM_GIC=y CONFIG_ARM_GIC=y
CONFIG_ARM_HAS_SG_CHAIN=y CONFIG_ARM_HAS_SG_CHAIN=y
@ -107,8 +112,6 @@ CONFIG_CRC16=y
# CONFIG_CRC32_SARWATE is not set # CONFIG_CRC32_SARWATE is not set
CONFIG_CRC32_SLICEBY8=y CONFIG_CRC32_SLICEBY8=y
CONFIG_CROSS_MEMORY_ATTACH=y CONFIG_CROSS_MEMORY_ATTACH=y
# CONFIG_CRYPTO_SHA1_ARM_NEON is not set
# CONFIG_CRYPTO_SHA512_ARM_NEON is not set
CONFIG_CRYPTO_XZ=y CONFIG_CRYPTO_XZ=y
CONFIG_DCACHE_WORD_ACCESS=y CONFIG_DCACHE_WORD_ACCESS=y
CONFIG_DEBUG_BUGVERBOSE=y CONFIG_DEBUG_BUGVERBOSE=y
@ -124,7 +127,6 @@ CONFIG_DMA_ENGINE=y
CONFIG_DMA_OF=y CONFIG_DMA_OF=y
CONFIG_DMA_VIRTUAL_CHANNELS=y CONFIG_DMA_VIRTUAL_CHANNELS=y
CONFIG_DTC=y CONFIG_DTC=y
# CONFIG_DW_DMAC_CORE is not set
# CONFIG_DW_DMAC_PCI is not set # CONFIG_DW_DMAC_PCI is not set
CONFIG_DYNAMIC_DEBUG=y CONFIG_DYNAMIC_DEBUG=y
CONFIG_ETHERNET_PACKET_MANGLE=y CONFIG_ETHERNET_PACKET_MANGLE=y
@ -134,11 +136,11 @@ CONFIG_GENERIC_ALLOCATOR=y
CONFIG_GENERIC_BUG=y CONFIG_GENERIC_BUG=y
CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
CONFIG_GENERIC_CPUFREQ_KRAIT=y CONFIG_GENERIC_CPUFREQ_KRAIT=y
CONFIG_GENERIC_IDLE_POLL_SETUP=y CONFIG_GENERIC_IDLE_POLL_SETUP=y
CONFIG_GENERIC_IO=y CONFIG_GENERIC_IO=y
CONFIG_GENERIC_IRQ_SHOW=y CONFIG_GENERIC_IRQ_SHOW=y
CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
CONFIG_GENERIC_MSI_IRQ=y CONFIG_GENERIC_MSI_IRQ=y
CONFIG_GENERIC_PCI_IOMAP=y CONFIG_GENERIC_PCI_IOMAP=y
CONFIG_GENERIC_PHY=y CONFIG_GENERIC_PHY=y
@ -147,6 +149,7 @@ CONFIG_GENERIC_SCHED_CLOCK=y
CONFIG_GENERIC_SMP_IDLE_THREAD=y CONFIG_GENERIC_SMP_IDLE_THREAD=y
CONFIG_GENERIC_STRNCPY_FROM_USER=y CONFIG_GENERIC_STRNCPY_FROM_USER=y
CONFIG_GENERIC_STRNLEN_USER=y CONFIG_GENERIC_STRNLEN_USER=y
CONFIG_GENERIC_TIME_VSYSCALL=y
CONFIG_GPIOLIB=y CONFIG_GPIOLIB=y
CONFIG_GPIOLIB_IRQCHIP=y CONFIG_GPIOLIB_IRQCHIP=y
CONFIG_GPIO_DEVRES=y CONFIG_GPIO_DEVRES=y
@ -208,6 +211,7 @@ CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y
CONFIG_HIGHMEM=y CONFIG_HIGHMEM=y
CONFIG_HIGHPTE=y CONFIG_HIGHPTE=y
CONFIG_HOTPLUG_CPU=y CONFIG_HOTPLUG_CPU=y
# CONFIG_HSU_DMA_PCI is not set
CONFIG_HWMON=y CONFIG_HWMON=y
CONFIG_HW_RANDOM=y CONFIG_HW_RANDOM=y
CONFIG_HW_RANDOM_MSM=y CONFIG_HW_RANDOM_MSM=y
@ -254,6 +258,7 @@ CONFIG_MIGHT_HAVE_PCI=y
CONFIG_MIGRATION=y CONFIG_MIGRATION=y
CONFIG_MODULES_USE_ELF_REL=y CONFIG_MODULES_USE_ELF_REL=y
CONFIG_MSM_GCC_8660=y CONFIG_MSM_GCC_8660=y
# CONFIG_MSM_GCC_8916 is not set
CONFIG_MSM_GCC_8960=y CONFIG_MSM_GCC_8960=y
CONFIG_MSM_GCC_8974=y CONFIG_MSM_GCC_8974=y
# CONFIG_MSM_LCC_8960 is not set # CONFIG_MSM_LCC_8960 is not set
@ -296,6 +301,7 @@ CONFIG_PCI=y
CONFIG_PCIEAER=y CONFIG_PCIEAER=y
CONFIG_PCIEPORTBUS=y CONFIG_PCIEPORTBUS=y
CONFIG_PCIE_DW=y CONFIG_PCIE_DW=y
# CONFIG_PCIE_IPROC is not set
CONFIG_PCIE_PME=y CONFIG_PCIE_PME=y
CONFIG_PCIE_QCOM=y CONFIG_PCIE_QCOM=y
CONFIG_PCI_DEBUG=y CONFIG_PCI_DEBUG=y
@ -304,10 +310,13 @@ CONFIG_PCI_DOMAINS_GENERIC=y
CONFIG_PCI_MSI=y CONFIG_PCI_MSI=y
CONFIG_PERF_EVENTS=y CONFIG_PERF_EVENTS=y
CONFIG_PERF_USE_VMALLOC=y CONFIG_PERF_USE_VMALLOC=y
CONFIG_PGTABLE_LEVELS=2
CONFIG_PHYLIB=y CONFIG_PHYLIB=y
# CONFIG_PHY_QCOM_APQ8064_SATA is not set # CONFIG_PHY_QCOM_APQ8064_SATA is not set
CONFIG_PHY_QCOM_IPQ806X_SATA=y CONFIG_PHY_QCOM_IPQ806X_SATA=y
# CONFIG_PHY_QCOM_UFS is not set
CONFIG_PINCTRL=y CONFIG_PINCTRL=y
# CONFIG_PINCTRL_AMD is not set
CONFIG_PINCTRL_APQ8064=y CONFIG_PINCTRL_APQ8064=y
# CONFIG_PINCTRL_APQ8084 is not set # CONFIG_PINCTRL_APQ8084 is not set
CONFIG_PINCTRL_IPQ8064=y CONFIG_PINCTRL_IPQ8064=y
@ -330,6 +339,7 @@ CONFIG_POWER_RESET=y
# CONFIG_POWER_RESET_LTC2952 is not set # CONFIG_POWER_RESET_LTC2952 is not set
CONFIG_POWER_RESET_MSM=y CONFIG_POWER_RESET_MSM=y
# CONFIG_POWER_RESET_SYSCON is not set # CONFIG_POWER_RESET_SYSCON is not set
# CONFIG_POWER_RESET_SYSCON_POWEROFF is not set
CONFIG_POWER_SUPPLY=y CONFIG_POWER_SUPPLY=y
CONFIG_PREEMPT=y CONFIG_PREEMPT=y
CONFIG_PREEMPT_COUNT=y CONFIG_PREEMPT_COUNT=y
@ -342,9 +352,11 @@ CONFIG_QCOM_GSBI=y
CONFIG_QCOM_HFPLL=y CONFIG_QCOM_HFPLL=y
CONFIG_QCOM_SCM=y CONFIG_QCOM_SCM=y
CONFIG_QCOM_WDT=y CONFIG_QCOM_WDT=y
# CONFIG_QORIQ_CPUFREQ is not set
CONFIG_RAS=y CONFIG_RAS=y
# CONFIG_RCU_BOOST is not set # CONFIG_RCU_BOOST is not set
CONFIG_RCU_CPU_STALL_TIMEOUT=21 CONFIG_RCU_CPU_STALL_TIMEOUT=21
# CONFIG_RCU_EXPEDITE_BOOT is not set
CONFIG_RCU_STALL_COMMON=y CONFIG_RCU_STALL_COMMON=y
CONFIG_RD_GZIP=y CONFIG_RD_GZIP=y
CONFIG_REGMAP=y CONFIG_REGMAP=y
@ -405,6 +417,7 @@ CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
CONFIG_UNINLINE_SPIN_UNLOCK=y CONFIG_UNINLINE_SPIN_UNLOCK=y
CONFIG_USB_SUPPORT=y CONFIG_USB_SUPPORT=y
CONFIG_USE_OF=y CONFIG_USE_OF=y
CONFIG_VDSO=y
CONFIG_VECTORS_BASE=0xffff0000 CONFIG_VECTORS_BASE=0xffff0000
CONFIG_VFP=y CONFIG_VFP=y
CONFIG_VFPv3=y CONFIG_VFPv3=y

View File

@ -1,522 +0,0 @@
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Subject: spi: qup: Add DMA capabilities
From: Andy Gross <agross@codeaurora.org>
X-Patchwork-Id: 4432401
Message-Id: <1403816781-31008-1-git-send-email-agross@codeaurora.org>
To: Mark Brown <broonie@kernel.org>
Cc: linux-spi@vger.kernel.org, Sagar Dharia <sdharia@codeaurora.org>,
Daniel Sneddon <dsneddon@codeaurora.org>,
Bjorn Andersson <bjorn.andersson@sonymobile.com>,
"Ivan T. Ivanov" <iivanov@mm-sol.com>,
linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
linux-arm-msm@vger.kernel.org, Andy Gross <agross@codeaurora.org>
Date: Thu, 26 Jun 2014 16:06:21 -0500
This patch adds DMA capabilities to the spi-qup driver. If DMA channels are
present, the QUP will use DMA instead of block mode for transfers to/from SPI
peripherals for transactions larger than the length of a block.
Signed-off-by: Andy Gross <agross@codeaurora.org>
---
.../devicetree/bindings/spi/qcom,spi-qup.txt | 10 +
drivers/spi/spi-qup.c | 361 ++++++++++++++++++--
2 files changed, 350 insertions(+), 21 deletions(-)
--- a/Documentation/devicetree/bindings/spi/qcom,spi-qup.txt
+++ b/Documentation/devicetree/bindings/spi/qcom,spi-qup.txt
@@ -27,6 +27,11 @@ Optional properties:
- spi-max-frequency: Specifies maximum SPI clock frequency,
Units - Hz. Definition as per
Documentation/devicetree/bindings/spi/spi-bus.txt
+- dmas : Two DMA channel specifiers following the convention outlined
+ in bindings/dma/dma.txt
+- dma-names: Names for the dma channels, if present. There must be at
+ least one channel named "tx" for transmit and named "rx" for
+ receive.
- num-cs: total number of chipselects
- cs-gpios: should specify GPIOs used for chipselects.
The gpios will be referred to as reg = <index> in the SPI child
@@ -51,6 +56,10 @@ Example:
clocks = <&gcc GCC_BLSP2_QUP2_SPI_APPS_CLK>, <&gcc GCC_BLSP2_AHB_CLK>;
clock-names = "core", "iface";
+ dmas = <&blsp2_bam 2>,
+ <&blsp2_bam 3>;
+ dma-names = "rx", "tx";
+
pinctrl-names = "default";
pinctrl-0 = <&spi8_default>;
--- a/drivers/spi/spi-qup.c
+++ b/drivers/spi/spi-qup.c
@@ -22,6 +22,8 @@
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/spi/spi.h>
+#include <linux/dmaengine.h>
+#include <linux/dma-mapping.h>
#define QUP_CONFIG 0x0000
#define QUP_STATE 0x0004
@@ -116,6 +118,8 @@
#define SPI_NUM_CHIPSELECTS 4
+#define SPI_MAX_XFER (SZ_64K - 64)
+
/* high speed mode is when bus rate is greater then 26MHz */
#define SPI_HS_MIN_RATE 26000000
#define SPI_MAX_RATE 50000000
@@ -143,6 +147,17 @@ struct spi_qup {
int tx_bytes;
int rx_bytes;
int qup_v1;
+
+ int use_dma;
+
+ struct dma_chan *rx_chan;
+ struct dma_slave_config rx_conf;
+ struct dma_chan *tx_chan;
+ struct dma_slave_config tx_conf;
+ dma_addr_t rx_dma;
+ dma_addr_t tx_dma;
+ void *dummy;
+ atomic_t dma_outstanding;
};
@@ -266,6 +281,221 @@ static void spi_qup_fifo_write(struct sp
}
}
+static void qup_dma_callback(void *data)
+{
+ struct spi_qup *controller = data;
+
+ if (atomic_dec_and_test(&controller->dma_outstanding))
+ complete(&controller->done);
+}
+
+static int spi_qup_do_dma(struct spi_qup *controller, struct spi_transfer *xfer)
+{
+ struct dma_async_tx_descriptor *rxd, *txd;
+ dma_cookie_t rx_cookie, tx_cookie;
+ u32 xfer_len, rx_align = 0, tx_align = 0, n_words;
+ struct scatterlist tx_sg[2], rx_sg[2];
+ int ret = 0;
+ u32 bytes_to_xfer = xfer->len;
+ u32 offset = 0;
+ u32 rx_nents = 0, tx_nents = 0;
+ dma_addr_t rx_dma = 0, tx_dma = 0, rx_dummy_dma = 0, tx_dummy_dma = 0;
+
+
+ if (xfer->rx_buf) {
+ rx_dma = dma_map_single(controller->dev, xfer->rx_buf,
+ xfer->len, DMA_FROM_DEVICE);
+
+ if (dma_mapping_error(controller->dev, rx_dma)) {
+ ret = -ENOMEM;
+ return ret;
+ }
+
+ /* check to see if we need dummy buffer for leftover bytes */
+ rx_align = xfer->len % controller->in_blk_sz;
+ if (rx_align) {
+ rx_dummy_dma = dma_map_single(controller->dev,
+ controller->dummy, controller->in_fifo_sz,
+ DMA_FROM_DEVICE);
+
+ if (dma_mapping_error(controller->dev, rx_dummy_dma)) {
+ ret = -ENOMEM;
+ goto err_map_rx_dummy;
+ }
+ }
+ }
+
+ if (xfer->tx_buf) {
+ tx_dma = dma_map_single(controller->dev,
+ (void *)xfer->tx_buf, xfer->len, DMA_TO_DEVICE);
+
+ if (dma_mapping_error(controller->dev, tx_dma)) {
+ ret = -ENOMEM;
+ goto err_map_tx;
+ }
+
+ /* check to see if we need dummy buffer for leftover bytes */
+ tx_align = xfer->len % controller->out_blk_sz;
+ if (tx_align) {
+ memcpy(controller->dummy + SZ_1K,
+ xfer->tx_buf + xfer->len - tx_align,
+ tx_align);
+ memset(controller->dummy + SZ_1K + tx_align, 0,
+ controller->out_blk_sz - tx_align);
+
+ tx_dummy_dma = dma_map_single(controller->dev,
+ controller->dummy + SZ_1K,
+ controller->out_blk_sz, DMA_TO_DEVICE);
+
+ if (dma_mapping_error(controller->dev, tx_dummy_dma)) {
+ ret = -ENOMEM;
+ goto err_map_tx_dummy;
+ }
+ }
+ }
+
+ atomic_set(&controller->dma_outstanding, 0);
+
+ while (bytes_to_xfer > 0) {
+ xfer_len = min_t(u32, bytes_to_xfer, SPI_MAX_XFER);
+ n_words = DIV_ROUND_UP(xfer_len, controller->w_size);
+
+ /* write out current word count to controller */
+ writel_relaxed(n_words, controller->base + QUP_MX_INPUT_CNT);
+ writel_relaxed(n_words, controller->base + QUP_MX_OUTPUT_CNT);
+
+ reinit_completion(&controller->done);
+
+ if (xfer->tx_buf) {
+ /* recalc align for each transaction */
+ tx_align = xfer_len % controller->out_blk_sz;
+
+ if (tx_align)
+ tx_nents = 2;
+ else
+ tx_nents = 1;
+
+ /* initialize scatterlists */
+ sg_init_table(tx_sg, tx_nents);
+ sg_dma_len(&tx_sg[0]) = xfer_len - tx_align;
+ sg_dma_address(&tx_sg[0]) = tx_dma + offset;
+
+ /* account for non block size transfer */
+ if (tx_align) {
+ sg_dma_len(&tx_sg[1]) = controller->out_blk_sz;
+ sg_dma_address(&tx_sg[1]) = tx_dummy_dma;
+ }
+
+ txd = dmaengine_prep_slave_sg(controller->tx_chan,
+ tx_sg, tx_nents, DMA_MEM_TO_DEV, 0);
+ if (!txd) {
+ ret = -ENOMEM;
+ goto err_unmap;
+ }
+
+ atomic_inc(&controller->dma_outstanding);
+
+ txd->callback = qup_dma_callback;
+ txd->callback_param = controller;
+
+ tx_cookie = dmaengine_submit(txd);
+
+ dma_async_issue_pending(controller->tx_chan);
+ }
+
+ if (xfer->rx_buf) {
+ /* recalc align for each transaction */
+ rx_align = xfer_len % controller->in_blk_sz;
+
+ if (rx_align)
+ rx_nents = 2;
+ else
+ rx_nents = 1;
+
+ /* initialize scatterlists */
+ sg_init_table(rx_sg, rx_nents);
+ sg_dma_address(&rx_sg[0]) = rx_dma + offset;
+ sg_dma_len(&rx_sg[0]) = xfer_len - rx_align;
+
+ /* account for non block size transfer */
+ if (rx_align) {
+ sg_dma_len(&rx_sg[1]) = controller->in_blk_sz;
+ sg_dma_address(&rx_sg[1]) = rx_dummy_dma;
+ }
+
+ rxd = dmaengine_prep_slave_sg(controller->rx_chan,
+ rx_sg, rx_nents, DMA_DEV_TO_MEM, 0);
+ if (!rxd) {
+ ret = -ENOMEM;
+ goto err_unmap;
+ }
+
+ atomic_inc(&controller->dma_outstanding);
+
+ rxd->callback = qup_dma_callback;
+ rxd->callback_param = controller;
+
+ rx_cookie = dmaengine_submit(rxd);
+
+ dma_async_issue_pending(controller->rx_chan);
+ }
+
+ if (spi_qup_set_state(controller, QUP_STATE_RUN)) {
+ dev_warn(controller->dev, "cannot set EXECUTE state\n");
+ goto err_unmap;
+ }
+
+ if (!wait_for_completion_timeout(&controller->done,
+ msecs_to_jiffies(1000))) {
+ ret = -ETIMEDOUT;
+
+ /* clear out all the DMA transactions */
+ if (xfer->tx_buf)
+ dmaengine_terminate_all(controller->tx_chan);
+ if (xfer->rx_buf)
+ dmaengine_terminate_all(controller->rx_chan);
+
+ goto err_unmap;
+ }
+
+ if (rx_align)
+ memcpy(xfer->rx_buf + offset + xfer->len - rx_align,
+ controller->dummy, rx_align);
+
+ /* adjust remaining bytes to transfer */
+ bytes_to_xfer -= xfer_len;
+ offset += xfer_len;
+
+
+ /* reset mini-core state so we can program next transaction */
+ if (spi_qup_set_state(controller, QUP_STATE_RESET)) {
+ dev_err(controller->dev, "cannot set RESET state\n");
+ goto err_unmap;
+ }
+ }
+
+ ret = 0;
+
+err_unmap:
+ if (tx_align)
+ dma_unmap_single(controller->dev, tx_dummy_dma,
+ controller->out_fifo_sz, DMA_TO_DEVICE);
+err_map_tx_dummy:
+ if (xfer->tx_buf)
+ dma_unmap_single(controller->dev, tx_dma, xfer->len,
+ DMA_TO_DEVICE);
+err_map_tx:
+ if (rx_align)
+ dma_unmap_single(controller->dev, rx_dummy_dma,
+ controller->in_fifo_sz, DMA_FROM_DEVICE);
+err_map_rx_dummy:
+ if (xfer->rx_buf)
+ dma_unmap_single(controller->dev, rx_dma, xfer->len,
+ DMA_FROM_DEVICE);
+
+ return ret;
+}
+
static irqreturn_t spi_qup_qup_irq(int irq, void *dev_id)
{
struct spi_qup *controller = dev_id;
@@ -315,11 +545,13 @@ static irqreturn_t spi_qup_qup_irq(int i
error = -EIO;
}
- if (opflags & QUP_OP_IN_SERVICE_FLAG)
- spi_qup_fifo_read(controller, xfer);
+ if (!controller->use_dma) {
+ if (opflags & QUP_OP_IN_SERVICE_FLAG)
+ spi_qup_fifo_read(controller, xfer);
- if (opflags & QUP_OP_OUT_SERVICE_FLAG)
- spi_qup_fifo_write(controller, xfer);
+ if (opflags & QUP_OP_OUT_SERVICE_FLAG)
+ spi_qup_fifo_write(controller, xfer);
+ }
spin_lock_irqsave(&controller->lock, flags);
controller->error = error;
@@ -339,6 +571,8 @@ static int spi_qup_io_config(struct spi_
struct spi_qup *controller = spi_master_get_devdata(spi->master);
u32 config, iomode, mode, control;
int ret, n_words, w_size;
+ size_t dma_align = dma_get_cache_alignment();
+ u32 dma_available = 0;
if (spi->mode & SPI_LOOP && xfer->len > controller->in_fifo_sz) {
dev_err(controller->dev, "too big size for loopback %d > %d\n",
@@ -367,6 +601,11 @@ static int spi_qup_io_config(struct spi_
n_words = xfer->len / w_size;
controller->w_size = w_size;
+ if (controller->rx_chan &&
+ IS_ALIGNED((size_t)xfer->tx_buf, dma_align) &&
+ IS_ALIGNED((size_t)xfer->rx_buf, dma_align))
+ dma_available = 1;
+
if (n_words <= (controller->in_fifo_sz / sizeof(u32))) {
mode = QUP_IO_M_MODE_FIFO;
writel_relaxed(n_words, controller->base + QUP_MX_READ_CNT);
@@ -374,19 +613,31 @@ static int spi_qup_io_config(struct spi_
/* must be zero for FIFO */
writel_relaxed(0, controller->base + QUP_MX_INPUT_CNT);
writel_relaxed(0, controller->base + QUP_MX_OUTPUT_CNT);
- } else {
+ controller->use_dma = 0;
+ } else if (!dma_available) {
mode = QUP_IO_M_MODE_BLOCK;
writel_relaxed(n_words, controller->base + QUP_MX_INPUT_CNT);
writel_relaxed(n_words, controller->base + QUP_MX_OUTPUT_CNT);
/* must be zero for BLOCK and BAM */
writel_relaxed(0, controller->base + QUP_MX_READ_CNT);
writel_relaxed(0, controller->base + QUP_MX_WRITE_CNT);
+ controller->use_dma = 0;
+ } else {
+ mode = QUP_IO_M_MODE_DMOV;
+ writel_relaxed(0, controller->base + QUP_MX_READ_CNT);
+ writel_relaxed(0, controller->base + QUP_MX_WRITE_CNT);
+ controller->use_dma = 1;
}
iomode = readl_relaxed(controller->base + QUP_IO_M_MODES);
/* Set input and output transfer mode */
iomode &= ~(QUP_IO_M_INPUT_MODE_MASK | QUP_IO_M_OUTPUT_MODE_MASK);
- iomode &= ~(QUP_IO_M_PACK_EN | QUP_IO_M_UNPACK_EN);
+
+ if (!controller->use_dma)
+ iomode &= ~(QUP_IO_M_PACK_EN | QUP_IO_M_UNPACK_EN);
+ else
+ iomode |= QUP_IO_M_PACK_EN | QUP_IO_M_UNPACK_EN;
+
iomode |= (mode << QUP_IO_M_OUTPUT_MODE_MASK_SHIFT);
iomode |= (mode << QUP_IO_M_INPUT_MODE_MASK_SHIFT);
@@ -428,6 +679,14 @@ static int spi_qup_io_config(struct spi_
config &= ~(QUP_CONFIG_NO_INPUT | QUP_CONFIG_NO_OUTPUT | QUP_CONFIG_N);
config |= xfer->bits_per_word - 1;
config |= QUP_CONFIG_SPI_MODE;
+
+ if (controller->use_dma) {
+ if (!xfer->tx_buf)
+ config |= QUP_CONFIG_NO_OUTPUT;
+ if (!xfer->rx_buf)
+ config |= QUP_CONFIG_NO_INPUT;
+ }
+
writel_relaxed(config, controller->base + QUP_CONFIG);
/* only write to OPERATIONAL_MASK when register is present */
@@ -461,25 +720,29 @@ static int spi_qup_transfer_one(struct s
controller->tx_bytes = 0;
spin_unlock_irqrestore(&controller->lock, flags);
- if (spi_qup_set_state(controller, QUP_STATE_RUN)) {
- dev_warn(controller->dev, "cannot set RUN state\n");
- goto exit;
- }
+ if (controller->use_dma) {
+ ret = spi_qup_do_dma(controller, xfer);
+ } else {
+ if (spi_qup_set_state(controller, QUP_STATE_RUN)) {
+ dev_warn(controller->dev, "cannot set RUN state\n");
+ goto exit;
+ }
- if (spi_qup_set_state(controller, QUP_STATE_PAUSE)) {
- dev_warn(controller->dev, "cannot set PAUSE state\n");
- goto exit;
- }
+ if (spi_qup_set_state(controller, QUP_STATE_PAUSE)) {
+ dev_warn(controller->dev, "cannot set PAUSE state\n");
+ goto exit;
+ }
- spi_qup_fifo_write(controller, xfer);
+ spi_qup_fifo_write(controller, xfer);
- if (spi_qup_set_state(controller, QUP_STATE_RUN)) {
- dev_warn(controller->dev, "cannot set EXECUTE state\n");
- goto exit;
- }
+ if (spi_qup_set_state(controller, QUP_STATE_RUN)) {
+ dev_warn(controller->dev, "cannot set EXECUTE state\n");
+ goto exit;
+ }
- if (!wait_for_completion_timeout(&controller->done, timeout))
- ret = -ETIMEDOUT;
+ if (!wait_for_completion_timeout(&controller->done, timeout))
+ ret = -ETIMEDOUT;
+ }
exit:
spi_qup_set_state(controller, QUP_STATE_RESET);
spin_lock_irqsave(&controller->lock, flags);
@@ -563,6 +826,7 @@ static int spi_qup_probe(struct platform
master->transfer_one = spi_qup_transfer_one;
master->dev.of_node = pdev->dev.of_node;
master->auto_runtime_pm = true;
+ master->dma_alignment = dma_get_cache_alignment();
platform_set_drvdata(pdev, master);
@@ -628,6 +892,56 @@ static int spi_qup_probe(struct platform
QUP_ERROR_INPUT_UNDER_RUN | QUP_ERROR_OUTPUT_UNDER_RUN,
base + QUP_ERROR_FLAGS_EN);
+ /* allocate dma resources, if available */
+ controller->rx_chan = dma_request_slave_channel(&pdev->dev, "rx");
+ if (controller->rx_chan) {
+ controller->tx_chan =
+ dma_request_slave_channel(&pdev->dev, "tx");
+
+ if (!controller->tx_chan) {
+ dev_err(&pdev->dev, "Failed to allocate dma tx chan");
+ dma_release_channel(controller->rx_chan);
+ }
+
+ /* set DMA parameters */
+ controller->rx_conf.device_fc = 1;
+ controller->rx_conf.src_addr = res->start + QUP_INPUT_FIFO;
+ controller->rx_conf.src_maxburst = controller->in_blk_sz;
+
+ controller->tx_conf.device_fc = 1;
+ controller->tx_conf.dst_addr = res->start + QUP_OUTPUT_FIFO;
+ controller->tx_conf.dst_maxburst = controller->out_blk_sz;
+
+ if (dmaengine_slave_config(controller->rx_chan,
+ &controller->rx_conf)) {
+ dev_err(&pdev->dev, "failed to configure RX channel\n");
+
+ dma_release_channel(controller->rx_chan);
+ dma_release_channel(controller->tx_chan);
+ controller->tx_chan = NULL;
+ controller->rx_chan = NULL;
+ } else if (dmaengine_slave_config(controller->tx_chan,
+ &controller->tx_conf)) {
+ dev_err(&pdev->dev, "failed to configure TX channel\n");
+
+ dma_release_channel(controller->rx_chan);
+ dma_release_channel(controller->tx_chan);
+ controller->tx_chan = NULL;
+ controller->rx_chan = NULL;
+ }
+
+ controller->dummy = devm_kmalloc(controller->dev, PAGE_SIZE,
+ GFP_KERNEL);
+
+ if (!controller->dummy) {
+ dma_release_channel(controller->rx_chan);
+ dma_release_channel(controller->tx_chan);
+ controller->tx_chan = NULL;
+ controller->rx_chan = NULL;
+ }
+ }
+
+
writel_relaxed(0, base + SPI_CONFIG);
writel_relaxed(SPI_IO_C_NO_TRI_STATE, base + SPI_IO_CONTROL);
@@ -740,6 +1054,11 @@ static int spi_qup_remove(struct platfor
if (ret)
return ret;
+ if (controller->rx_chan)
+ dma_release_channel(controller->rx_chan);
+ if (controller->tx_chan)
+ dma_release_channel(controller->tx_chan);
+
clk_disable_unprepare(controller->cclk);
clk_disable_unprepare(controller->iclk);

View File

@ -1,376 +0,0 @@
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Subject: [v3] spi: qup: Fix incorrect block transfers
From: Andy Gross <agross@codeaurora.org>
X-Patchwork-Id: 5007321
Message-Id: <1412112088-25928-1-git-send-email-agross@codeaurora.org>
To: Mark Brown <broonie@kernel.org>
Cc: linux-spi@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, linux-arm-msm@vger.kernel.org,
"Ivan T. Ivanov" <iivanov@mm-sol.com>,
Bjorn Andersson <bjorn.andersson@sonymobile.com>,
Kumar Gala <galak@codeaurora.org>, Andy Gross <agross@codeaurora.org>
Date: Tue, 30 Sep 2014 16:21:28 -0500
This patch fixes a number of errors with the QUP block transfer mode. Errors
manifested themselves as input underruns, output overruns, and timed out
transactions.
The block mode does not require the priming that occurs in FIFO mode. At the
moment that the QUP is placed into the RUN state, the QUP will immediately raise
an interrupt if the request is a write. Therefore, there is no need to prime
the pump.
In addition, the block transfers require that whole blocks of data are
read/written at a time. The last block of data that completes a transaction may
contain less than a full blocks worth of data.
Each block of data results in an input/output service interrupt accompanied with
a input/output block flag set. Additional block reads/writes require clearing
of the service flag. It is ok to check for additional blocks of data in the
ISR, but you have to ack every block you transfer. Imbalanced acks result in
early return from complete transactions with pending interrupts that still have
to be ack'd. The next transaction can be affected by these interrupts.
Transactions are deemed complete when the MAX_INPUT or MAX_OUTPUT flag are set.
Changes from v2:
- Added in additional completion check so that transaction done is not
prematurely signaled.
- Fixed various review comments.
Changes from v1:
- Split out read/write block function.
- Removed extraneous checks for transfer length
Signed-off-by: Andy Gross <agross@codeaurora.org>
---
drivers/spi/spi-qup.c | 201 ++++++++++++++++++++++++++++++++++++-------------
1 file changed, 148 insertions(+), 53 deletions(-)
--- a/drivers/spi/spi-qup.c
+++ b/drivers/spi/spi-qup.c
@@ -82,6 +82,8 @@
#define QUP_IO_M_MODE_BAM 3
/* QUP_OPERATIONAL fields */
+#define QUP_OP_IN_BLOCK_READ_REQ BIT(13)
+#define QUP_OP_OUT_BLOCK_WRITE_REQ BIT(12)
#define QUP_OP_MAX_INPUT_DONE_FLAG BIT(11)
#define QUP_OP_MAX_OUTPUT_DONE_FLAG BIT(10)
#define QUP_OP_IN_SERVICE_FLAG BIT(9)
@@ -147,6 +149,7 @@ struct spi_qup {
int tx_bytes;
int rx_bytes;
int qup_v1;
+ int mode;
int use_dma;
@@ -213,30 +216,14 @@ static int spi_qup_set_state(struct spi_
return 0;
}
-
-static void spi_qup_fifo_read(struct spi_qup *controller,
- struct spi_transfer *xfer)
+static void spi_qup_fill_read_buffer(struct spi_qup *controller,
+ struct spi_transfer *xfer, u32 data)
{
u8 *rx_buf = xfer->rx_buf;
- u32 word, state;
- int idx, shift, w_size;
-
- w_size = controller->w_size;
-
- while (controller->rx_bytes < xfer->len) {
-
- state = readl_relaxed(controller->base + QUP_OPERATIONAL);
- if (0 == (state & QUP_OP_IN_FIFO_NOT_EMPTY))
- break;
-
- word = readl_relaxed(controller->base + QUP_INPUT_FIFO);
-
- if (!rx_buf) {
- controller->rx_bytes += w_size;
- continue;
- }
+ int idx, shift;
- for (idx = 0; idx < w_size; idx++, controller->rx_bytes++) {
+ if (rx_buf)
+ for (idx = 0; idx < controller->w_size; idx++) {
/*
* The data format depends on bytes per SPI word:
* 4 bytes: 0x12345678
@@ -244,41 +231,139 @@ static void spi_qup_fifo_read(struct spi
* 1 byte : 0x00000012
*/
shift = BITS_PER_BYTE;
- shift *= (w_size - idx - 1);
- rx_buf[controller->rx_bytes] = word >> shift;
+ shift *= (controller->w_size - idx - 1);
+ rx_buf[controller->rx_bytes + idx] = data >> shift;
+ }
+
+ controller->rx_bytes += controller->w_size;
+}
+
+static void spi_qup_prepare_write_data(struct spi_qup *controller,
+ struct spi_transfer *xfer, u32 *data)
+{
+ const u8 *tx_buf = xfer->tx_buf;
+ u32 val;
+ int idx;
+
+ *data = 0;
+
+ if (tx_buf)
+ for (idx = 0; idx < controller->w_size; idx++) {
+ val = tx_buf[controller->tx_bytes + idx];
+ *data |= val << (BITS_PER_BYTE * (3 - idx));
}
+
+ controller->tx_bytes += controller->w_size;
+}
+
+static void spi_qup_fifo_read(struct spi_qup *controller,
+ struct spi_transfer *xfer)
+{
+ u32 data;
+
+ /* clear service request */
+ writel_relaxed(QUP_OP_IN_SERVICE_FLAG,
+ controller->base + QUP_OPERATIONAL);
+
+ while (controller->rx_bytes < xfer->len) {
+ if (!(readl_relaxed(controller->base + QUP_OPERATIONAL) &
+ QUP_OP_IN_FIFO_NOT_EMPTY))
+ break;
+
+ data = readl_relaxed(controller->base + QUP_INPUT_FIFO);
+
+ spi_qup_fill_read_buffer(controller, xfer, data);
}
}
static void spi_qup_fifo_write(struct spi_qup *controller,
- struct spi_transfer *xfer)
+ struct spi_transfer *xfer)
{
- const u8 *tx_buf = xfer->tx_buf;
- u32 word, state, data;
- int idx, w_size;
+ u32 data;
- w_size = controller->w_size;
+ /* clear service request */
+ writel_relaxed(QUP_OP_OUT_SERVICE_FLAG,
+ controller->base + QUP_OPERATIONAL);
while (controller->tx_bytes < xfer->len) {
- state = readl_relaxed(controller->base + QUP_OPERATIONAL);
- if (state & QUP_OP_OUT_FIFO_FULL)
+ if (readl_relaxed(controller->base + QUP_OPERATIONAL) &
+ QUP_OP_OUT_FIFO_FULL)
break;
- word = 0;
- for (idx = 0; idx < w_size; idx++, controller->tx_bytes++) {
+ spi_qup_prepare_write_data(controller, xfer, &data);
+ writel_relaxed(data, controller->base + QUP_OUTPUT_FIFO);
- if (!tx_buf) {
- controller->tx_bytes += w_size;
- break;
- }
+ }
+}
- data = tx_buf[controller->tx_bytes];
- word |= data << (BITS_PER_BYTE * (3 - idx));
- }
+static void spi_qup_block_read(struct spi_qup *controller,
+ struct spi_transfer *xfer)
+{
+ u32 data;
+ u32 reads_per_blk = controller->in_blk_sz >> 2;
+ u32 num_words = (xfer->len - controller->rx_bytes) / controller->w_size;
+ int i;
+
+ do {
+ /* ACK by clearing service flag */
+ writel_relaxed(QUP_OP_IN_SERVICE_FLAG,
+ controller->base + QUP_OPERATIONAL);
+
+ /* transfer up to a block size of data in a single pass */
+ for (i = 0; num_words && i < reads_per_blk; i++, num_words--) {
+
+ /* read data and fill up rx buffer */
+ data = readl_relaxed(controller->base + QUP_INPUT_FIFO);
+ spi_qup_fill_read_buffer(controller, xfer, data);
+ }
+
+ /* check to see if next block is ready */
+ if (!(readl_relaxed(controller->base + QUP_OPERATIONAL) &
+ QUP_OP_IN_BLOCK_READ_REQ))
+ break;
- writel_relaxed(word, controller->base + QUP_OUTPUT_FIFO);
- }
+ } while (num_words);
+
+ /*
+ * Due to extra stickiness of the QUP_OP_IN_SERVICE_FLAG during block
+ * reads, it has to be cleared again at the very end
+ */
+ if (readl_relaxed(controller->base + QUP_OPERATIONAL) &
+ QUP_OP_MAX_INPUT_DONE_FLAG)
+ writel_relaxed(QUP_OP_IN_SERVICE_FLAG,
+ controller->base + QUP_OPERATIONAL);
+
+}
+
+static void spi_qup_block_write(struct spi_qup *controller,
+ struct spi_transfer *xfer)
+{
+ u32 data;
+ u32 writes_per_blk = controller->out_blk_sz >> 2;
+ u32 num_words = (xfer->len - controller->tx_bytes) / controller->w_size;
+ int i;
+
+ do {
+ /* ACK by clearing service flag */
+ writel_relaxed(QUP_OP_OUT_SERVICE_FLAG,
+ controller->base + QUP_OPERATIONAL);
+
+ /* transfer up to a block size of data in a single pass */
+ for (i = 0; num_words && i < writes_per_blk; i++, num_words--) {
+
+ /* swizzle the bytes for output and write out */
+ spi_qup_prepare_write_data(controller, xfer, &data);
+ writel_relaxed(data,
+ controller->base + QUP_OUTPUT_FIFO);
+ }
+
+ /* check to see if next block is ready */
+ if (!(readl_relaxed(controller->base + QUP_OPERATIONAL) &
+ QUP_OP_OUT_BLOCK_WRITE_REQ))
+ break;
+
+ } while (num_words);
}
static void qup_dma_callback(void *data)
@@ -515,9 +600,9 @@ static irqreturn_t spi_qup_qup_irq(int i
writel_relaxed(qup_err, controller->base + QUP_ERROR_FLAGS);
writel_relaxed(spi_err, controller->base + SPI_ERROR_FLAGS);
- writel_relaxed(opflags, controller->base + QUP_OPERATIONAL);
if (!xfer) {
+ writel_relaxed(opflags, controller->base + QUP_OPERATIONAL);
dev_err_ratelimited(controller->dev, "unexpected irq %08x %08x %08x\n",
qup_err, spi_err, opflags);
return IRQ_HANDLED;
@@ -546,11 +631,19 @@ static irqreturn_t spi_qup_qup_irq(int i
}
if (!controller->use_dma) {
- if (opflags & QUP_OP_IN_SERVICE_FLAG)
- spi_qup_fifo_read(controller, xfer);
+ if (opflags & QUP_OP_IN_SERVICE_FLAG) {
+ if (opflags & QUP_OP_IN_BLOCK_READ_REQ)
+ spi_qup_block_read(controller, xfer);
+ else
+ spi_qup_fifo_read(controller, xfer);
+ }
- if (opflags & QUP_OP_OUT_SERVICE_FLAG)
- spi_qup_fifo_write(controller, xfer);
+ if (opflags & QUP_OP_OUT_SERVICE_FLAG) {
+ if (opflags & QUP_OP_OUT_BLOCK_WRITE_REQ)
+ spi_qup_block_write(controller, xfer);
+ else
+ spi_qup_fifo_write(controller, xfer);
+ }
}
spin_lock_irqsave(&controller->lock, flags);
@@ -558,7 +651,8 @@ static irqreturn_t spi_qup_qup_irq(int i
controller->xfer = xfer;
spin_unlock_irqrestore(&controller->lock, flags);
- if (controller->rx_bytes == xfer->len || error)
+ if ((controller->rx_bytes == xfer->len &&
+ (opflags & QUP_OP_MAX_INPUT_DONE_FLAG)) || error)
complete(&controller->done);
return IRQ_HANDLED;
@@ -569,7 +663,7 @@ static irqreturn_t spi_qup_qup_irq(int i
static int spi_qup_io_config(struct spi_device *spi, struct spi_transfer *xfer)
{
struct spi_qup *controller = spi_master_get_devdata(spi->master);
- u32 config, iomode, mode, control;
+ u32 config, iomode, control;
int ret, n_words, w_size;
size_t dma_align = dma_get_cache_alignment();
u32 dma_available = 0;
@@ -607,7 +701,7 @@ static int spi_qup_io_config(struct spi_
dma_available = 1;
if (n_words <= (controller->in_fifo_sz / sizeof(u32))) {
- mode = QUP_IO_M_MODE_FIFO;
+ controller->mode = QUP_IO_M_MODE_FIFO;
writel_relaxed(n_words, controller->base + QUP_MX_READ_CNT);
writel_relaxed(n_words, controller->base + QUP_MX_WRITE_CNT);
/* must be zero for FIFO */
@@ -615,7 +709,7 @@ static int spi_qup_io_config(struct spi_
writel_relaxed(0, controller->base + QUP_MX_OUTPUT_CNT);
controller->use_dma = 0;
} else if (!dma_available) {
- mode = QUP_IO_M_MODE_BLOCK;
+ controller->mode = QUP_IO_M_MODE_BLOCK;
writel_relaxed(n_words, controller->base + QUP_MX_INPUT_CNT);
writel_relaxed(n_words, controller->base + QUP_MX_OUTPUT_CNT);
/* must be zero for BLOCK and BAM */
@@ -623,7 +717,7 @@ static int spi_qup_io_config(struct spi_
writel_relaxed(0, controller->base + QUP_MX_WRITE_CNT);
controller->use_dma = 0;
} else {
- mode = QUP_IO_M_MODE_DMOV;
+ controller->mode = QUP_IO_M_MODE_DMOV;
writel_relaxed(0, controller->base + QUP_MX_READ_CNT);
writel_relaxed(0, controller->base + QUP_MX_WRITE_CNT);
controller->use_dma = 1;
@@ -638,8 +732,8 @@ static int spi_qup_io_config(struct spi_
else
iomode |= QUP_IO_M_PACK_EN | QUP_IO_M_UNPACK_EN;
- iomode |= (mode << QUP_IO_M_OUTPUT_MODE_MASK_SHIFT);
- iomode |= (mode << QUP_IO_M_INPUT_MODE_MASK_SHIFT);
+ iomode |= (controller->mode << QUP_IO_M_OUTPUT_MODE_MASK_SHIFT);
+ iomode |= (controller->mode << QUP_IO_M_INPUT_MODE_MASK_SHIFT);
writel_relaxed(iomode, controller->base + QUP_IO_M_MODES);
@@ -733,7 +827,8 @@ static int spi_qup_transfer_one(struct s
goto exit;
}
- spi_qup_fifo_write(controller, xfer);
+ if (controller->mode == QUP_IO_M_MODE_FIFO)
+ spi_qup_fifo_write(controller, xfer);
if (spi_qup_set_state(controller, QUP_STATE_RUN)) {
dev_warn(controller->dev, "cannot set EXECUTE state\n");
@@ -750,6 +845,7 @@ exit:
if (!ret)
ret = controller->error;
spin_unlock_irqrestore(&controller->lock, flags);
+
return ret;
}

View File

@ -1,56 +0,0 @@
From 4faba89e3ffbb1c5f6232651375b9b3212b50f02 Mon Sep 17 00:00:00 2001
From: Andy Gross <agross@codeaurora.org>
Date: Thu, 15 Jan 2015 17:56:02 -0800
Subject: [PATCH] spi: qup: Ensure done detection
This patch fixes an issue where a SPI transaction has completed, but the done
condition is missed. This occurs because at the time of interrupt the
MAX_INPUT_DONE_FLAG is not asserted. However, in the process of reading blocks
of data from the FIFO, the last portion of data comes in.
The opflags read at the beginning of the irq handler no longer matches the
current opflag state. To get around this condition, the block read function
should update the opflags so that done detection is correct after the return.
Change-Id: If109e0eeb432f96000d765c4b34dbb2269f8093f
Signed-off-by: Andy Gross <agross@codeaurora.org>
---
drivers/spi/spi-qup.c | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
--- a/drivers/spi/spi-qup.c
+++ b/drivers/spi/spi-qup.c
@@ -298,7 +298,7 @@ static void spi_qup_fifo_write(struct sp
}
static void spi_qup_block_read(struct spi_qup *controller,
- struct spi_transfer *xfer)
+ struct spi_transfer *xfer, u32 *opflags)
{
u32 data;
u32 reads_per_blk = controller->in_blk_sz >> 2;
@@ -327,10 +327,12 @@ static void spi_qup_block_read(struct sp
/*
* Due to extra stickiness of the QUP_OP_IN_SERVICE_FLAG during block
- * reads, it has to be cleared again at the very end
+ * reads, it has to be cleared again at the very end. However, be sure
+ * to refresh opflags value because MAX_INPUT_DONE_FLAG may now be
+ * present and this is used to determine if transaction is complete
*/
- if (readl_relaxed(controller->base + QUP_OPERATIONAL) &
- QUP_OP_MAX_INPUT_DONE_FLAG)
+ *opflags = readl_relaxed(controller->base + QUP_OPERATIONAL);
+ if (*opflags & QUP_OP_MAX_INPUT_DONE_FLAG)
writel_relaxed(QUP_OP_IN_SERVICE_FLAG,
controller->base + QUP_OPERATIONAL);
@@ -633,7 +635,7 @@ static irqreturn_t spi_qup_qup_irq(int i
if (!controller->use_dma) {
if (opflags & QUP_OP_IN_SERVICE_FLAG) {
if (opflags & QUP_OP_IN_BLOCK_READ_REQ)
- spi_qup_block_read(controller, xfer);
+ spi_qup_block_read(controller, xfer, &opflags);
else
spi_qup_fifo_read(controller, xfer);
}

View File

@ -1,67 +0,0 @@
From fded70251b1b58f68de1d3757ece9965f0b75452 Mon Sep 17 00:00:00 2001
From: Mathieu Olivari <mathieu@codeaurora.org>
Date: Thu, 19 Feb 2015 20:19:30 -0800
Subject: [PATCH 1/3] watchdog: qcom: use timer devicetree binding
MSM watchdog configuration happens in the same register block as the
timer, so we'll use the same binding as the existing timer.
The qcom-wdt will now be probed when devicetree has an entry compatible
with "qcom,kpss-timer" or "qcom-scss-timer".
Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
---
drivers/watchdog/qcom-wdt.c | 21 +++++++++++++++------
1 file changed, 15 insertions(+), 6 deletions(-)
--- a/drivers/watchdog/qcom-wdt.c
+++ b/drivers/watchdog/qcom-wdt.c
@@ -20,9 +20,9 @@
#include <linux/reboot.h>
#include <linux/watchdog.h>
-#define WDT_RST 0x0
-#define WDT_EN 0x8
-#define WDT_BITE_TIME 0x24
+#define WDT_RST 0x38
+#define WDT_EN 0x40
+#define WDT_BITE_TIME 0x5C
struct qcom_wdt {
struct watchdog_device wdd;
@@ -117,6 +117,8 @@ static int qcom_wdt_probe(struct platfor
{
struct qcom_wdt *wdt;
struct resource *res;
+ struct device_node *np = pdev->dev.of_node;
+ u32 percpu_offset;
int ret;
wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL);
@@ -124,6 +126,14 @@ static int qcom_wdt_probe(struct platfor
return -ENOMEM;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+ /* We use CPU0's DGT for the watchdog */
+ if (of_property_read_u32(np, "cpu-offset", &percpu_offset))
+ percpu_offset = 0;
+
+ res->start += percpu_offset;
+ res->end += percpu_offset;
+
wdt->base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(wdt->base))
return PTR_ERR(wdt->base);
@@ -203,9 +213,8 @@ static int qcom_wdt_remove(struct platfo
}
static const struct of_device_id qcom_wdt_of_table[] = {
- { .compatible = "qcom,kpss-wdt-msm8960", },
- { .compatible = "qcom,kpss-wdt-apq8064", },
- { .compatible = "qcom,kpss-wdt-ipq8064", },
+ { .compatible = "qcom,kpss-timer" },
+ { .compatible = "qcom,scss-timer" },
{ },
};
MODULE_DEVICE_TABLE(of, qcom_wdt_of_table);

View File

@ -1,48 +0,0 @@
From 297cf8136ecd6a56520888fd28948393766b8ee7 Mon Sep 17 00:00:00 2001
From: Mathieu Olivari <mathieu@codeaurora.org>
Date: Thu, 19 Feb 2015 20:27:39 -0800
Subject: [PATCH 2/3] ARM: qcom: add description of KPSS WDT for IPQ8064
Add the watchdog related entries to the Krait Processor Sub-system
(KPSS) timer IPQ8064 devicetree section. Also, add a fixed-clock
description of SLEEP_CLK, which will do for now.
Signed-off-by: Josh Cartwright <joshc@codeaurora.org>
Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
---
arch/arm/boot/dts/qcom-ipq8064.dtsi | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
--- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
@@ -60,6 +60,14 @@
};
};
+ clocks {
+ sleep_clk: sleep_clk {
+ compatible = "fixed-clock";
+ clock-frequency = <32768>;
+ #clock-cells = <0>;
+ };
+ };
+
soc: soc {
#address-cells = <1>;
#size-cells = <1>;
@@ -89,10 +97,14 @@
compatible = "qcom,kpss-timer", "qcom,msm-timer";
interrupts = <1 1 0x301>,
<1 2 0x301>,
- <1 3 0x301>;
+ <1 3 0x301>,
+ <1 4 0x301>,
+ <1 5 0x301>;
reg = <0x0200a000 0x100>;
clock-frequency = <25000000>,
<32768>;
+ clocks = <&sleep_clk>;
+ clock-names = "sleep";
cpu-offset = <0x80000>;
};

View File

@ -1,50 +0,0 @@
From e535f01dffb6dd9e09934fa219be52af3437a8f6 Mon Sep 17 00:00:00 2001
From: Mathieu Olivari <mathieu@codeaurora.org>
Date: Thu, 19 Feb 2015 20:36:27 -0800
Subject: [PATCH 3/3] ARM: msm: add watchdog entries to DT timer binding doc
The watchdog has been reworked to use the same DT node as the timer.
This change is updating the device tree doc accordingly.
Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
---
Documentation/devicetree/bindings/arm/msm/timer.txt | 16 +++++++++++++---
1 file changed, 13 insertions(+), 3 deletions(-)
--- a/Documentation/devicetree/bindings/arm/msm/timer.txt
+++ b/Documentation/devicetree/bindings/arm/msm/timer.txt
@@ -9,11 +9,17 @@ Properties:
"qcom,scss-timer" - scorpion subsystem
- interrupts : Interrupts for the debug timer, the first general purpose
- timer, and optionally a second general purpose timer in that
- order.
+ timer, and optionally a second general purpose timer, and
+ optionally as well, 2 watchdog interrupts, in that order.
- reg : Specifies the base address of the timer registers.
+- clocks: Reference to the parent clocks, one per output clock. The parents
+ must appear in the same order as the clock names.
+
+- clock-names: The name of the clocks as free-form strings. They should be in
+ the same order as the clocks.
+
- clock-frequency : The frequency of the debug timer and the general purpose
timer(s) in Hz in that order.
@@ -29,9 +35,13 @@ Example:
compatible = "qcom,scss-timer", "qcom,msm-timer";
interrupts = <1 1 0x301>,
<1 2 0x301>,
- <1 3 0x301>;
+ <1 3 0x301>,
+ <1 4 0x301>,
+ <1 5 0x301>;
reg = <0x0200a000 0x100>;
clock-frequency = <19200000>,
<32768>;
+ clocks = <&sleep_clk>;
+ clock-names = "sleep";
cpu-offset = <0x40000>;
};

View File

@ -1,71 +0,0 @@
From 4d54b0adfa67476e6509bc8646b9dbac642e8a29 Mon Sep 17 00:00:00 2001
From: Josh Cartwright <joshc@codeaurora.org>
Date: Thu, 26 Mar 2015 11:29:26 -0700
Subject: [PATCH] mfd: qcom_rpm: Add support for IPQ8064
The IPQ8064 also includes an RPM following the same message structure as
other chips. In addition, it supports a few new resource types to
support the NSS fabric clocks and the SMB208/SMB209 regulators found on
the reference boards.
Signed-off-by: Josh Cartwright <joshc@codeaurora.org>
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
---
drivers/mfd/qcom_rpm.c | 41 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 41 insertions(+)
--- a/drivers/mfd/qcom_rpm.c
+++ b/drivers/mfd/qcom_rpm.c
@@ -323,10 +323,51 @@ static const struct qcom_rpm_data msm896
.n_resources = ARRAY_SIZE(msm8960_rpm_resource_table),
};
+static const struct qcom_rpm_resource ipq806x_rpm_resource_table[] = {
+ [QCOM_RPM_CXO_CLK] = { 25, 9, 5, 1 },
+ [QCOM_RPM_PXO_CLK] = { 26, 10, 6, 1 },
+ [QCOM_RPM_APPS_FABRIC_CLK] = { 27, 11, 8, 1 },
+ [QCOM_RPM_SYS_FABRIC_CLK] = { 28, 12, 9, 1 },
+ [QCOM_RPM_NSS_FABRIC_0_CLK] = { 29, 13, 10, 1 },
+ [QCOM_RPM_DAYTONA_FABRIC_CLK] = { 30, 14, 11, 1 },
+ [QCOM_RPM_SFPB_CLK] = { 31, 15, 12, 1 },
+ [QCOM_RPM_CFPB_CLK] = { 32, 16, 13, 1 },
+ [QCOM_RPM_NSS_FABRIC_1_CLK] = { 33, 17, 14, 1 },
+ [QCOM_RPM_EBI1_CLK] = { 34, 18, 16, 1 },
+ [QCOM_RPM_APPS_FABRIC_HALT] = { 35, 19, 18, 2 },
+ [QCOM_RPM_APPS_FABRIC_MODE] = { 37, 20, 19, 3 },
+ [QCOM_RPM_APPS_FABRIC_IOCTL] = { 40, 21, 20, 1 },
+ [QCOM_RPM_APPS_FABRIC_ARB] = { 41, 22, 21, 12 },
+ [QCOM_RPM_SYS_FABRIC_HALT] = { 53, 23, 22, 2 },
+ [QCOM_RPM_SYS_FABRIC_MODE] = { 55, 24, 23, 3 },
+ [QCOM_RPM_SYS_FABRIC_IOCTL] = { 58, 25, 24, 1 },
+ [QCOM_RPM_SYS_FABRIC_ARB] = { 59, 26, 25, 30 },
+ [QCOM_RPM_MM_FABRIC_HALT] = { 89, 27, 26, 2 },
+ [QCOM_RPM_MM_FABRIC_MODE] = { 91, 28, 27, 3 },
+ [QCOM_RPM_MM_FABRIC_IOCTL] = { 94, 29, 28, 1 },
+ [QCOM_RPM_MM_FABRIC_ARB] = { 95, 30, 29, 2 },
+ [QCOM_RPM_CXO_BUFFERS] = { 209, 33, 31, 1 },
+ [QCOM_RPM_USB_OTG_SWITCH] = { 210, 34, 32, 1 },
+ [QCOM_RPM_HDMI_SWITCH] = { 211, 35, 33, 1 },
+ [QCOM_RPM_DDR_DMM] = { 212, 36, 34, 2 },
+ [QCOM_RPM_VDDMIN_GPIO] = { 215, 40, 39, 1 },
+ [QCOM_RPM_SMB208_S1a] = { 216, 41, 90, 2 },
+ [QCOM_RPM_SMB208_S1b] = { 218, 43, 91, 2 },
+ [QCOM_RPM_SMB208_S2a] = { 220, 45, 92, 2 },
+ [QCOM_RPM_SMB208_S2b] = { 222, 47, 93, 2 },
+};
+
+static const struct qcom_rpm_data ipq806x_template = {
+ .version = 3,
+ .resource_table = ipq806x_rpm_resource_table,
+ .n_resources = ARRAY_SIZE(ipq806x_rpm_resource_table),
+};
+
static const struct of_device_id qcom_rpm_of_match[] = {
{ .compatible = "qcom,rpm-apq8064", .data = &apq8064_template },
{ .compatible = "qcom,rpm-msm8660", .data = &msm8660_template },
{ .compatible = "qcom,rpm-msm8960", .data = &msm8960_template },
+ { .compatible = "qcom,rpm-ipq8064", .data = &ipq806x_template },
{ }
};
MODULE_DEVICE_TABLE(of, qcom_rpm_of_match);

View File

@ -1,42 +0,0 @@
From 30bc3aa5c4ed3072bdff7d915772df1b91307ed4 Mon Sep 17 00:00:00 2001
From: Josh Cartwright <joshc@codeaurora.org>
Date: Thu, 26 Mar 2015 11:29:25 -0700
Subject: [PATCH] mfd: devicetree: qcom_rpm: Document IPQ8064 resources
The IPQ8064 SoC has several RPM-controlled resources, an NSS fabrick
clock and four regulator resources. Provide definitions for them.
Signed-off-by: Josh Cartwright <joshc@codeaurora.org>
[sboyd@codeaurora.org: Drop regulator part of binding]
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
---
Documentation/devicetree/bindings/mfd/qcom-rpm.txt | 1 +
include/dt-bindings/mfd/qcom-rpm.h | 6 ++++++
2 files changed, 7 insertions(+)
--- a/Documentation/devicetree/bindings/mfd/qcom-rpm.txt
+++ b/Documentation/devicetree/bindings/mfd/qcom-rpm.txt
@@ -12,6 +12,7 @@ frequencies.
"qcom,rpm-apq8064"
"qcom,rpm-msm8660"
"qcom,rpm-msm8960"
+ "qcom,rpm-ipq8064"
- reg:
Usage: required
--- a/include/dt-bindings/mfd/qcom-rpm.h
+++ b/include/dt-bindings/mfd/qcom-rpm.h
@@ -141,6 +141,12 @@
#define QCOM_RPM_SYS_FABRIC_MODE 131
#define QCOM_RPM_USB_OTG_SWITCH 132
#define QCOM_RPM_VDDMIN_GPIO 133
+#define QCOM_RPM_NSS_FABRIC_0_CLK 134
+#define QCOM_RPM_NSS_FABRIC_1_CLK 135
+#define QCOM_RPM_SMB208_S1a 136
+#define QCOM_RPM_SMB208_S1b 137
+#define QCOM_RPM_SMB208_S2a 138
+#define QCOM_RPM_SMB208_S2b 139
/*
* Constants used to select force mode for regulators.

View File

@ -1,175 +0,0 @@
From df944689d491e6af533173bf2ef448c3dd334f15 Mon Sep 17 00:00:00 2001
From: Mathieu Olivari <mathieu@codeaurora.org>
Date: Mon, 11 May 2015 15:15:25 -0700
Subject: [PATCH 6/8] net: stmmac: create one debugfs dir per net-device
stmmac DebugFS entries are currently global to the driver. As a result,
having more than one stmmac device in the system creates the following
error:
* ERROR stmmaceth, debugfs create directory failed
* stmmac_hw_setup: failed debugFS registration
This also results in being able to access the debugfs information for
the first registered device only.
This patch changes the debugfs structure to have one sub-directory per
net-device. Files under "/sys/kernel/debug/stmmaceth" will now show-up
under /sys/kernel/debug/stmmaceth/ethN/.
Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
---
drivers/net/ethernet/stmicro/stmmac/stmmac.h | 6 ++
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 76 ++++++++++++++++-------
2 files changed, 59 insertions(+), 23 deletions(-)
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
@@ -116,6 +116,12 @@ struct stmmac_priv {
int use_riwt;
int irq_wake;
spinlock_t ptp_lock;
+
+#ifdef CONFIG_DEBUG_FS
+ struct dentry *dbgfs_dir;
+ struct dentry *dbgfs_rings_status;
+ struct dentry *dbgfs_dma_cap;
+#endif
};
int stmmac_mdio_unregister(struct net_device *ndev);
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -119,7 +119,7 @@ static irqreturn_t stmmac_interrupt(int
#ifdef CONFIG_DEBUG_FS
static int stmmac_init_fs(struct net_device *dev);
-static void stmmac_exit_fs(void);
+static void stmmac_exit_fs(struct net_device *dev);
#endif
#define STMMAC_COAL_TIMER(x) (jiffies + usecs_to_jiffies(x))
@@ -1918,7 +1918,7 @@ static int stmmac_release(struct net_dev
netif_carrier_off(dev);
#ifdef CONFIG_DEBUG_FS
- stmmac_exit_fs();
+ stmmac_exit_fs(dev);
#endif
stmmac_release_ptp(priv);
@@ -2510,8 +2510,6 @@ static int stmmac_ioctl(struct net_devic
#ifdef CONFIG_DEBUG_FS
static struct dentry *stmmac_fs_dir;
-static struct dentry *stmmac_rings_status;
-static struct dentry *stmmac_dma_cap;
static void sysfs_display_ring(void *head, int size, int extend_desc,
struct seq_file *seq)
@@ -2650,36 +2648,39 @@ static const struct file_operations stmm
static int stmmac_init_fs(struct net_device *dev)
{
- /* Create debugfs entries */
- stmmac_fs_dir = debugfs_create_dir(STMMAC_RESOURCE_NAME, NULL);
+ struct stmmac_priv *priv = netdev_priv(dev);
+
+ /* Create per netdev entries */
+ priv->dbgfs_dir = debugfs_create_dir(dev->name, stmmac_fs_dir);
- if (!stmmac_fs_dir || IS_ERR(stmmac_fs_dir)) {
- pr_err("ERROR %s, debugfs create directory failed\n",
- STMMAC_RESOURCE_NAME);
+ if (!priv->dbgfs_dir || IS_ERR(priv->dbgfs_dir)) {
+ pr_err("ERROR %s/%s, debugfs create directory failed\n",
+ STMMAC_RESOURCE_NAME, dev->name);
return -ENOMEM;
}
/* Entry to report DMA RX/TX rings */
- stmmac_rings_status = debugfs_create_file("descriptors_status",
- S_IRUGO, stmmac_fs_dir, dev,
- &stmmac_rings_status_fops);
+ priv->dbgfs_rings_status =
+ debugfs_create_file("descriptors_status", S_IRUGO,
+ priv->dbgfs_dir, dev,
+ &stmmac_rings_status_fops);
- if (!stmmac_rings_status || IS_ERR(stmmac_rings_status)) {
+ if (!priv->dbgfs_rings_status || IS_ERR(priv->dbgfs_rings_status)) {
pr_info("ERROR creating stmmac ring debugfs file\n");
- debugfs_remove(stmmac_fs_dir);
+ debugfs_remove_recursive(priv->dbgfs_dir);
return -ENOMEM;
}
/* Entry to report the DMA HW features */
- stmmac_dma_cap = debugfs_create_file("dma_cap", S_IRUGO, stmmac_fs_dir,
- dev, &stmmac_dma_cap_fops);
+ priv->dbgfs_dma_cap = debugfs_create_file("dma_cap", S_IRUGO,
+ priv->dbgfs_dir,
+ dev, &stmmac_dma_cap_fops);
- if (!stmmac_dma_cap || IS_ERR(stmmac_dma_cap)) {
+ if (!priv->dbgfs_dma_cap || IS_ERR(priv->dbgfs_dma_cap)) {
pr_info("ERROR creating stmmac MMC debugfs file\n");
- debugfs_remove(stmmac_rings_status);
- debugfs_remove(stmmac_fs_dir);
+ debugfs_remove_recursive(priv->dbgfs_dir);
return -ENOMEM;
}
@@ -2687,11 +2688,11 @@ static int stmmac_init_fs(struct net_dev
return 0;
}
-static void stmmac_exit_fs(void)
+static void stmmac_exit_fs(struct net_device *dev)
{
- debugfs_remove(stmmac_rings_status);
- debugfs_remove(stmmac_dma_cap);
- debugfs_remove(stmmac_fs_dir);
+ struct stmmac_priv *priv = netdev_priv(dev);
+
+ debugfs_remove_recursive(priv->dbgfs_dir);
}
#endif /* CONFIG_DEBUG_FS */
@@ -3136,6 +3137,35 @@ err:
__setup("stmmaceth=", stmmac_cmdline_opt);
#endif /* MODULE */
+static int __init stmmac_init(void)
+{
+#ifdef CONFIG_DEBUG_FS
+ /* Create debugfs main directory if it doesn't exist yet */
+ if (stmmac_fs_dir == NULL) {
+ stmmac_fs_dir = debugfs_create_dir(STMMAC_RESOURCE_NAME, NULL);
+
+ if (!stmmac_fs_dir || IS_ERR(stmmac_fs_dir)) {
+ pr_err("ERROR %s, debugfs create directory failed\n",
+ STMMAC_RESOURCE_NAME);
+
+ return -ENOMEM;
+ }
+ }
+#endif
+
+ return 0;
+}
+
+static void __exit stmmac_exit(void)
+{
+#ifdef CONFIG_DEBUG_FS
+ debugfs_remove_recursive(stmmac_fs_dir);
+#endif
+}
+
+module_init(stmmac_init)
+module_exit(stmmac_exit)
+
MODULE_DESCRIPTION("STMMAC 10/100/1000 Ethernet device driver");
MODULE_AUTHOR("Giuseppe Cavallaro <peppe.cavallaro@st.com>");
MODULE_LICENSE("GPL");

View File

@ -17,27 +17,27 @@
i2c4_pins: i2c4_pinmux { i2c4_pins: i2c4_pinmux {
--- a/arch/arm/boot/dts/qcom-ipq8064.dtsi --- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi +++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
@@ -140,7 +140,7 @@ @@ -159,7 +159,7 @@
ranges;
status = "disabled"; syscon-tcsr = <&tcsr>;
- serial@12490000 { - serial@12490000 {
+ uart2: serial@12490000 { + uart2: serial@12490000 {
compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm"; compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
reg = <0x12490000 0x1000>, reg = <0x12490000 0x1000>,
<0x12480000 0x1000>; <0x12480000 0x1000>;
@@ -175,7 +175,7 @@ @@ -197,7 +197,7 @@
ranges;
status = "disabled"; syscon-tcsr = <&tcsr>;
- serial@16340000 { - serial@16340000 {
+ uart4: serial@16340000 { + uart4: serial@16340000 {
compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm"; compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
reg = <0x16340000 0x1000>, reg = <0x16340000 0x1000>,
<0x16300000 0x1000>; <0x16300000 0x1000>;
@@ -209,7 +209,7 @@ @@ -234,7 +234,7 @@
ranges;
status = "disabled"; syscon-tcsr = <&tcsr>;
- serial@1a240000 { - serial@1a240000 {
+ uart5: serial@1a240000 { + uart5: serial@1a240000 {

View File

@ -15,7 +15,7 @@ Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
--- a/arch/arm/boot/dts/Makefile --- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile
@@ -438,6 +438,7 @@ dtb-$(CONFIG_ARCH_QCOM) += \ @@ -451,6 +451,7 @@ dtb-$(CONFIG_ARCH_QCOM) += \
qcom-apq8084-ifc6540.dtb \ qcom-apq8084-ifc6540.dtb \
qcom-apq8084-mtp.dtb \ qcom-apq8084-mtp.dtb \
qcom-ipq8064-ap148.dtb \ qcom-ipq8064-ap148.dtb \

View File

@ -24,7 +24,7 @@
gsbi5: gsbi@1a200000 { gsbi5: gsbi@1a200000 {
--- a/drivers/clk/qcom/gcc-ipq806x.c --- a/drivers/clk/qcom/gcc-ipq806x.c
+++ b/drivers/clk/qcom/gcc-ipq806x.c +++ b/drivers/clk/qcom/gcc-ipq806x.c
@@ -805,7 +805,7 @@ static struct clk_rcg gsbi7_qup_src = { @@ -807,7 +807,7 @@ static struct clk_rcg gsbi7_qup_src = {
.parent_names = gcc_pxo_pll8, .parent_names = gcc_pxo_pll8,
.num_parents = 2, .num_parents = 2,
.ops = &clk_rcg_ops, .ops = &clk_rcg_ops,
@ -33,7 +33,7 @@
}, },
}, },
}; };
@@ -821,7 +821,7 @@ static struct clk_branch gsbi7_qup_clk = @@ -823,7 +823,7 @@ static struct clk_branch gsbi7_qup_clk =
.parent_names = (const char *[]){ "gsbi7_qup_src" }, .parent_names = (const char *[]){ "gsbi7_qup_src" },
.num_parents = 1, .num_parents = 1,
.ops = &clk_branch_ops, .ops = &clk_branch_ops,
@ -42,7 +42,7 @@
}, },
}, },
}; };
@@ -869,7 +869,7 @@ static struct clk_branch gsbi4_h_clk = { @@ -871,7 +871,7 @@ static struct clk_branch gsbi4_h_clk = {
.hw.init = &(struct clk_init_data){ .hw.init = &(struct clk_init_data){
.name = "gsbi4_h_clk", .name = "gsbi4_h_clk",
.ops = &clk_branch_ops, .ops = &clk_branch_ops,

View File

@ -34,7 +34,7 @@ MAINTAINERS | 7 +
--- a/MAINTAINERS --- a/MAINTAINERS
+++ b/MAINTAINERS +++ b/MAINTAINERS
@@ -7511,6 +7511,13 @@ L: linux-pci@vger.kernel.org @@ -7599,6 +7599,13 @@ L: linux-pci@vger.kernel.org
S: Maintained S: Maintained
F: drivers/pci/host/*spear* F: drivers/pci/host/*spear*
@ -50,9 +50,9 @@ MAINTAINERS | 7 +
L: linux-pcmcia@lists.infradead.org L: linux-pcmcia@lists.infradead.org
--- a/drivers/pci/host/Kconfig --- a/drivers/pci/host/Kconfig
+++ b/drivers/pci/host/Kconfig +++ b/drivers/pci/host/Kconfig
@@ -106,4 +106,13 @@ config PCI_VERSATILE @@ -125,4 +125,13 @@ config PCIE_IPROC_PLATFORM
bool "ARM Versatile PB PCI controller" Say Y here if you want to use the Broadcom iProc PCIe controller
depends on ARCH_VERSATILE through the generic platform bus interface
+config PCIE_QCOM +config PCIE_QCOM
+ bool "Qualcomm PCIe controller" + bool "Qualcomm PCIe controller"
@ -746,8 +746,8 @@ MAINTAINERS | 7 +
+MODULE_ALIAS("platform:qcom-pcie"); +MODULE_ALIAS("platform:qcom-pcie");
--- a/drivers/pci/host/Makefile --- a/drivers/pci/host/Makefile
+++ b/drivers/pci/host/Makefile +++ b/drivers/pci/host/Makefile
@@ -13,3 +13,4 @@ obj-$(CONFIG_PCIE_XILINX) += pcie-xilinx @@ -15,3 +15,4 @@ obj-$(CONFIG_PCI_LAYERSCAPE) += pci-laye
obj-$(CONFIG_PCI_XGENE) += pci-xgene.o
obj-$(CONFIG_PCI_LAYERSCAPE) += pci-layerscape.o
obj-$(CONFIG_PCI_VERSATILE) += pci-versatile.o obj-$(CONFIG_PCI_VERSATILE) += pci-versatile.o
obj-$(CONFIG_PCIE_IPROC) += pcie-iproc.o
obj-$(CONFIG_PCIE_IPROC_PLATFORM) += pcie-iproc-platform.o
+obj-$(CONFIG_PCIE_QCOM) += pcie-qcom.o +obj-$(CONFIG_PCIE_QCOM) += pcie-qcom.o

View File

@ -120,20 +120,19 @@ Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
}; };
--- a/arch/arm/boot/dts/qcom-ipq8064.dtsi --- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi +++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
@@ -3,6 +3,8 @@ @@ -4,6 +4,8 @@
#include "skeleton.dtsi"
#include <dt-bindings/clock/qcom,gcc-ipq806x.h> #include <dt-bindings/clock/qcom,gcc-ipq806x.h>
#include <dt-bindings/clock/qcom,lcc-ipq806x.h>
#include <dt-bindings/soc/qcom,gsbi.h> #include <dt-bindings/soc/qcom,gsbi.h>
+#include <dt-bindings/reset/qcom,gcc-ipq806x.h> +#include <dt-bindings/reset/qcom,gcc-ipq806x.h>
+#include <include/dt-bindings/interrupt-controller/arm-gic.h> +#include <include/dt-bindings/interrupt-controller/arm-gic.h>
/ { / {
model = "Qualcomm IPQ8064"; model = "Qualcomm IPQ8064";
@@ -291,5 +293,128 @@ @@ -329,5 +331,128 @@
#clock-cells = <1>;
#reset-cells = <1>; #reset-cells = <1>;
}; };
+
+ pcie0: pci@1b500000 { + pcie0: pci@1b500000 {
+ compatible = "qcom,pcie-v0"; + compatible = "qcom,pcie-v0";
+ reg = <0x1b500000 0x1000 + reg = <0x1b500000 0x1000
@ -256,5 +255,6 @@ Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
+ +
+ status = "disabled"; + status = "disabled";
+ }; + };
+
}; };
}; };

View File

@ -5,12 +5,12 @@
#include "skeleton.dtsi" #include "skeleton.dtsi"
#include <dt-bindings/clock/qcom,gcc-ipq806x.h> #include <dt-bindings/clock/qcom,gcc-ipq806x.h>
+#include <dt-bindings/mfd/qcom-rpm.h> +#include <dt-bindings/mfd/qcom-rpm.h>
#include <dt-bindings/clock/qcom,lcc-ipq806x.h>
#include <dt-bindings/soc/qcom,gsbi.h> #include <dt-bindings/soc/qcom,gsbi.h>
#include <dt-bindings/reset/qcom,gcc-ipq806x.h> #include <dt-bindings/reset/qcom,gcc-ipq806x.h>
#include <include/dt-bindings/interrupt-controller/arm-gic.h> @@ -92,6 +93,63 @@
@@ -76,6 +77,63 @@ reg-names = "lpass-lpaif";
ranges; };
compatible = "simple-bus";
+ rpm@108000 { + rpm@108000 {
+ compatible = "qcom,rpm-ipq8064"; + compatible = "qcom,rpm-ipq8064";
@ -72,7 +72,7 @@
qcom_pinmux: pinmux@800000 { qcom_pinmux: pinmux@800000 {
compatible = "qcom,ipq8064-pinctrl"; compatible = "qcom,ipq8064-pinctrl";
reg = <0x800000 0x4000>; reg = <0x800000 0x4000>;
@@ -120,6 +178,12 @@ @@ -136,6 +194,12 @@
reg = <0x02098000 0x1000>, <0x02008000 0x1000>; reg = <0x02098000 0x1000>, <0x02008000 0x1000>;
}; };

View File

@ -47,7 +47,7 @@ drivers/clk/clk.c | 34 ++++++++++++++++++++++------------
--- a/drivers/clk/clk.c --- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c +++ b/drivers/clk/clk.c
@@ -1696,21 +1696,24 @@ static struct clk_core *clk_propagate_ra @@ -1743,21 +1743,24 @@ static struct clk_core *clk_propagate_ra
* walk down a subtree and set the new rates notifying the rate * walk down a subtree and set the new rates notifying the rate
* change on the way * change on the way
*/ */
@ -79,16 +79,16 @@ drivers/clk/clk.c | 34 ++++++++++++++++++++++------------
if (clk->new_parent && clk->new_parent != clk->parent) { if (clk->new_parent && clk->new_parent != clk->parent) {
old_parent = __clk_set_parent_before(clk, clk->new_parent); old_parent = __clk_set_parent_before(clk, clk->new_parent);
@@ -1730,7 +1733,7 @@ static void clk_change_rate(struct clk_c @@ -1783,7 +1786,7 @@ static void clk_change_rate(struct clk_c
if (!skip_set_rate && clk->ops->set_rate)
clk->ops->set_rate(clk->hw, clk->new_rate, best_parent_rate); trace_clk_set_rate_complete(clk, clk->new_rate);
- clk->rate = clk_recalc(clk, best_parent_rate); - clk->rate = clk_recalc(clk, best_parent_rate);
+ clk->rate = clk->new_rate; + clk->rate = clk->new_rate;
if (clk->notifier_count && old_rate != clk->rate) if (clk->notifier_count && old_rate != clk->rate)
__clk_notify(clk, POST_RATE_CHANGE, old_rate, clk->rate); __clk_notify(clk, POST_RATE_CHANGE, old_rate, clk->rate);
@@ -1743,12 +1746,13 @@ static void clk_change_rate(struct clk_c @@ -1796,12 +1799,13 @@ static void clk_change_rate(struct clk_c
/* Skip children who will be reparented to another clock */ /* Skip children who will be reparented to another clock */
if (child->new_parent && child->new_parent != clk) if (child->new_parent && child->new_parent != clk)
continue; continue;
@ -105,7 +105,7 @@ drivers/clk/clk.c | 34 ++++++++++++++++++++++------------
} }
static int clk_core_set_rate_nolock(struct clk_core *clk, static int clk_core_set_rate_nolock(struct clk_core *clk,
@@ -1757,6 +1761,7 @@ static int clk_core_set_rate_nolock(stru @@ -1810,6 +1814,7 @@ static int clk_core_set_rate_nolock(stru
struct clk_core *top, *fail_clk; struct clk_core *top, *fail_clk;
unsigned long rate = req_rate; unsigned long rate = req_rate;
int ret = 0; int ret = 0;
@ -113,7 +113,7 @@ drivers/clk/clk.c | 34 ++++++++++++++++++++++------------
if (!clk) if (!clk)
return 0; return 0;
@@ -1782,8 +1787,13 @@ static int clk_core_set_rate_nolock(stru @@ -1835,8 +1840,13 @@ static int clk_core_set_rate_nolock(stru
return -EBUSY; return -EBUSY;
} }

View File

@ -47,7 +47,7 @@ handles that problem on Krait, but on other platforms it won't work.
struct clk_core *new_parent; struct clk_core *new_parent;
struct clk_core *new_child; struct clk_core *new_child;
unsigned long flags; unsigned long flags;
@@ -1557,7 +1560,8 @@ out: @@ -1595,7 +1598,8 @@ out:
static void clk_calc_subtree(struct clk_core *clk, unsigned long new_rate, static void clk_calc_subtree(struct clk_core *clk, unsigned long new_rate,
struct clk_core *new_parent, u8 p_index) struct clk_core *new_parent, u8 p_index)
{ {
@ -57,7 +57,7 @@ handles that problem on Krait, but on other platforms it won't work.
clk->new_rate = new_rate; clk->new_rate = new_rate;
clk->new_parent = new_parent; clk->new_parent = new_parent;
@@ -1567,6 +1571,18 @@ static void clk_calc_subtree(struct clk_ @@ -1605,6 +1609,18 @@ static void clk_calc_subtree(struct clk_
if (new_parent && new_parent != clk->parent) if (new_parent && new_parent != clk->parent)
new_parent->new_child = clk; new_parent->new_child = clk;
@ -76,7 +76,7 @@ handles that problem on Krait, but on other platforms it won't work.
hlist_for_each_entry(child, &clk->children, child_node) { hlist_for_each_entry(child, &clk->children, child_node) {
child->new_rate = clk_recalc(child, new_rate); child->new_rate = clk_recalc(child, new_rate);
clk_calc_subtree(child, child->new_rate, NULL, 0); clk_calc_subtree(child, child->new_rate, NULL, 0);
@@ -1662,14 +1678,43 @@ static struct clk_core *clk_propagate_ra @@ -1709,14 +1725,43 @@ static struct clk_core *clk_propagate_ra
unsigned long event) unsigned long event)
{ {
struct clk_core *child, *tmp_clk, *fail_clk = NULL; struct clk_core *child, *tmp_clk, *fail_clk = NULL;
@ -123,7 +123,7 @@ handles that problem on Krait, but on other platforms it won't work.
fail_clk = clk; fail_clk = clk;
} }
@@ -1715,7 +1760,8 @@ clk_change_rate(struct clk_core *clk, un @@ -1762,7 +1807,8 @@ clk_change_rate(struct clk_core *clk, un
old_rate = clk->rate; old_rate = clk->rate;
@ -131,9 +131,9 @@ handles that problem on Krait, but on other platforms it won't work.
+ if (clk->new_parent && clk->new_parent != clk->parent && + if (clk->new_parent && clk->new_parent != clk->parent &&
+ !clk->safe_parent) { + !clk->safe_parent) {
old_parent = __clk_set_parent_before(clk, clk->new_parent); old_parent = __clk_set_parent_before(clk, clk->new_parent);
trace_clk_set_parent(clk, clk->new_parent);
if (clk->ops->set_rate_and_parent) { @@ -1788,9 +1834,6 @@ clk_change_rate(struct clk_core *clk, un
@@ -1735,9 +1781,6 @@ clk_change_rate(struct clk_core *clk, un
clk->rate = clk->new_rate; clk->rate = clk->new_rate;
@ -143,7 +143,7 @@ handles that problem on Krait, but on other platforms it won't work.
/* /*
* Use safe iteration, as change_rate can actually swap parents * Use safe iteration, as change_rate can actually swap parents
* for certain clock types. * for certain clock types.
@@ -1797,6 +1840,8 @@ static int clk_core_set_rate_nolock(stru @@ -1850,6 +1893,8 @@ static int clk_core_set_rate_nolock(stru
clk->req_rate = req_rate; clk->req_rate = req_rate;

View File

@ -73,7 +73,7 @@ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
+ }; + };
--- a/drivers/clk/qcom/Kconfig --- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig
@@ -88,3 +88,11 @@ config MSM_MMCC_8974 @@ -97,3 +97,11 @@ config MSM_MMCC_8974
Support for the multimedia clock controller on msm8974 devices. Support for the multimedia clock controller on msm8974 devices.
Say Y if you want to support multimedia devices such as display, Say Y if you want to support multimedia devices such as display,
graphics, video encode/decode, camera, etc. graphics, video encode/decode, camera, etc.
@ -87,7 +87,7 @@ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
+ such as MSM8974, APQ8084, etc. + such as MSM8974, APQ8084, etc.
--- a/drivers/clk/qcom/Makefile --- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile
@@ -21,3 +21,4 @@ obj-$(CONFIG_MSM_LCC_8960) += lcc-msm896 @@ -22,3 +22,4 @@ obj-$(CONFIG_MSM_LCC_8960) += lcc-msm896
obj-$(CONFIG_MSM_GCC_8974) += gcc-msm8974.o obj-$(CONFIG_MSM_GCC_8974) += gcc-msm8974.o
obj-$(CONFIG_MSM_MMCC_8960) += mmcc-msm8960.o obj-$(CONFIG_MSM_MMCC_8960) += mmcc-msm8960.o
obj-$(CONFIG_MSM_MMCC_8974) += mmcc-msm8974.o obj-$(CONFIG_MSM_MMCC_8974) += mmcc-msm8974.o

View File

@ -115,10 +115,10 @@ drivers/clk/qcom/gcc-ipq806x.c | 83 ++++++++++++++++++++++++++++++++++++++++++
static struct clk_pll pll14 = { static struct clk_pll pll14 = {
.l_reg = 0x31c4, .l_reg = 0x31c4,
.m_reg = 0x31c8, .m_reg = 0x31c8,
@@ -2273,6 +2353,9 @@ static struct clk_regmap *gcc_ipq806x_cl @@ -2307,6 +2387,9 @@ static struct clk_regmap *gcc_ipq806x_cl
[USB_FS1_XCVR_SRC] = &usb_fs1_xcvr_clk_src.clkr,
[USB_FS1_XCVR_CLK] = &usb_fs1_xcvr_clk.clkr,
[USB_FS1_SYSTEM_CLK] = &usb_fs1_sys_clk.clkr, [USB_FS1_SYSTEM_CLK] = &usb_fs1_sys_clk.clkr,
[EBI2_CLK] = &ebi2_clk.clkr,
[EBI2_AON_CLK] = &ebi2_aon_clk.clkr,
+ [PLL9] = &hfpll0.clkr, + [PLL9] = &hfpll0.clkr,
+ [PLL10] = &hfpll1.clkr, + [PLL10] = &hfpll1.clkr,
+ [PLL12] = &hfpll_l2.clkr, + [PLL12] = &hfpll_l2.clkr,

View File

@ -30,7 +30,7 @@ drivers/clk/qcom/Kconfig | 4 ++
--- a/drivers/clk/qcom/Kconfig --- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig
@@ -96,3 +96,7 @@ config QCOM_HFPLL @@ -105,3 +105,7 @@ config QCOM_HFPLL
Support for the high-frequency PLLs present on Qualcomm devices. Support for the high-frequency PLLs present on Qualcomm devices.
Say Y if you want to support CPU frequency scaling on devices Say Y if you want to support CPU frequency scaling on devices
such as MSM8974, APQ8084, etc. such as MSM8974, APQ8084, etc.

View File

@ -82,7 +82,7 @@ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
+ }; + };
--- a/drivers/clk/qcom/Kconfig --- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig
@@ -97,6 +97,14 @@ config QCOM_HFPLL @@ -106,6 +106,14 @@ config QCOM_HFPLL
Say Y if you want to support CPU frequency scaling on devices Say Y if you want to support CPU frequency scaling on devices
such as MSM8974, APQ8084, etc. such as MSM8974, APQ8084, etc.
@ -99,7 +99,7 @@ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
select KRAIT_L2_ACCESSORS select KRAIT_L2_ACCESSORS
--- a/drivers/clk/qcom/Makefile --- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile
@@ -22,4 +22,5 @@ obj-$(CONFIG_MSM_LCC_8960) += lcc-msm896 @@ -23,4 +23,5 @@ obj-$(CONFIG_MSM_LCC_8960) += lcc-msm896
obj-$(CONFIG_MSM_GCC_8974) += gcc-msm8974.o obj-$(CONFIG_MSM_GCC_8974) += gcc-msm8974.o
obj-$(CONFIG_MSM_MMCC_8960) += mmcc-msm8960.o obj-$(CONFIG_MSM_MMCC_8960) += mmcc-msm8960.o
obj-$(CONFIG_MSM_MMCC_8974) += mmcc-msm8974.o obj-$(CONFIG_MSM_MMCC_8974) += mmcc-msm8974.o

View File

@ -56,7 +56,7 @@ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
+ }; + };
--- a/drivers/clk/qcom/Kconfig --- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig
@@ -105,6 +105,14 @@ config KPSS_XCC @@ -114,6 +114,14 @@ config KPSS_XCC
if you want to support CPU frequency scaling on devices such if you want to support CPU frequency scaling on devices such
as MSM8960, APQ8064, etc. as MSM8960, APQ8064, etc.
@ -73,7 +73,7 @@ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
select KRAIT_L2_ACCESSORS select KRAIT_L2_ACCESSORS
--- a/drivers/clk/qcom/Makefile --- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile
@@ -24,3 +24,4 @@ obj-$(CONFIG_MSM_MMCC_8960) += mmcc-msm8 @@ -25,3 +25,4 @@ obj-$(CONFIG_MSM_MMCC_8960) += mmcc-msm8
obj-$(CONFIG_MSM_MMCC_8974) += mmcc-msm8974.o obj-$(CONFIG_MSM_MMCC_8974) += mmcc-msm8974.o
obj-$(CONFIG_KPSS_XCC) += kpss-xcc.o obj-$(CONFIG_KPSS_XCC) += kpss-xcc.o
obj-$(CONFIG_QCOM_HFPLL) += hfpll.o obj-$(CONFIG_QCOM_HFPLL) += hfpll.o

View File

@ -69,7 +69,7 @@ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
+ }; + };
--- a/drivers/cpufreq/Kconfig.arm --- a/drivers/cpufreq/Kconfig.arm
+++ b/drivers/cpufreq/Kconfig.arm +++ b/drivers/cpufreq/Kconfig.arm
@@ -137,6 +137,15 @@ config ARM_OMAP2PLUS_CPUFREQ @@ -146,6 +146,15 @@ config ARM_OMAP2PLUS_CPUFREQ
depends on ARCH_OMAP2PLUS depends on ARCH_OMAP2PLUS
default ARCH_OMAP2PLUS default ARCH_OMAP2PLUS
@ -87,7 +87,7 @@ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
help help
--- a/drivers/cpufreq/Makefile --- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile +++ b/drivers/cpufreq/Makefile
@@ -65,6 +65,7 @@ obj-$(CONFIG_ARM_KIRKWOOD_CPUFREQ) += ki @@ -66,6 +66,7 @@ obj-$(CONFIG_ARM_KIRKWOOD_CPUFREQ) += ki
obj-$(CONFIG_ARM_OMAP2PLUS_CPUFREQ) += omap-cpufreq.o obj-$(CONFIG_ARM_OMAP2PLUS_CPUFREQ) += omap-cpufreq.o
obj-$(CONFIG_ARM_PXA2xx_CPUFREQ) += pxa2xx-cpufreq.o obj-$(CONFIG_ARM_PXA2xx_CPUFREQ) += pxa2xx-cpufreq.o
obj-$(CONFIG_PXA3xx) += pxa3xx-cpufreq.o obj-$(CONFIG_PXA3xx) += pxa3xx-cpufreq.o

View File

@ -1,6 +1,6 @@
--- a/arch/arm/boot/dts/qcom-ipq8064.dtsi --- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi +++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
@@ -24,6 +24,11 @@ @@ -25,6 +25,11 @@
next-level-cache = <&L2>; next-level-cache = <&L2>;
qcom,acc = <&acc0>; qcom,acc = <&acc0>;
qcom,saw = <&saw0>; qcom,saw = <&saw0>;
@ -12,7 +12,7 @@
}; };
cpu@1 { cpu@1 {
@@ -34,11 +39,24 @@ @@ -35,11 +40,24 @@
next-level-cache = <&L2>; next-level-cache = <&L2>;
qcom,acc = <&acc1>; qcom,acc = <&acc1>;
qcom,saw = <&saw1>; qcom,saw = <&saw1>;
@ -37,7 +37,7 @@
}; };
}; };
@@ -71,6 +89,46 @@ @@ -195,6 +213,46 @@
}; };
}; };
@ -84,7 +84,7 @@
soc: soc { soc: soc {
#address-cells = <1>; #address-cells = <1>;
#size-cells = <1>; #size-cells = <1>;
@@ -171,11 +229,13 @@ @@ -310,11 +368,13 @@
acc0: clock-controller@2088000 { acc0: clock-controller@2088000 {
compatible = "qcom,kpss-acc-v1"; compatible = "qcom,kpss-acc-v1";
reg = <0x02088000 0x1000>, <0x02008000 0x1000>; reg = <0x02088000 0x1000>, <0x02008000 0x1000>;

View File

@ -33,7 +33,7 @@ Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
--- a/arch/arm/Kconfig --- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig +++ b/arch/arm/Kconfig
@@ -314,7 +314,7 @@ config ARCH_MULTIPLATFORM @@ -320,7 +320,7 @@ config ARCH_MULTIPLATFORM
select ARCH_WANT_OPTIONAL_GPIOLIB select ARCH_WANT_OPTIONAL_GPIOLIB
select ARM_HAS_SG_CHAIN select ARM_HAS_SG_CHAIN
select ARM_PATCH_PHYS_VIRT select ARM_PATCH_PHYS_VIRT
@ -44,7 +44,7 @@ Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
select GENERIC_CLOCKEVENTS select GENERIC_CLOCKEVENTS
--- a/arch/arm/Makefile --- a/arch/arm/Makefile
+++ b/arch/arm/Makefile +++ b/arch/arm/Makefile
@@ -241,9 +241,11 @@ MACHINE := arch/arm/mach-$(word 1,$(mac @@ -240,9 +240,11 @@ MACHINE := arch/arm/mach-$(word 1,$(mac
else else
MACHINE := MACHINE :=
endif endif

View File

@ -16,7 +16,7 @@ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
--- a/drivers/clk/qcom/gcc-ipq806x.c --- a/drivers/clk/qcom/gcc-ipq806x.c
+++ b/drivers/clk/qcom/gcc-ipq806x.c +++ b/drivers/clk/qcom/gcc-ipq806x.c
@@ -220,11 +220,46 @@ static struct clk_regmap pll14_vote = { @@ -220,12 +220,47 @@ static struct clk_regmap pll14_vote = {
}, },
}; };
@ -53,26 +53,27 @@ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
+ }, + },
+}; +};
+ +
#define P_PXO 0 enum {
#define P_PLL8 1 P_PXO,
#define P_PLL3 1 P_PLL8,
#define P_PLL0 2 P_PLL3,
#define P_CXO 2 P_PLL0,
+#define P_PLL14 3 P_CXO,
+#define P_PLL18 4 + P_PLL14,
+ P_PLL18,
};
static const u8 gcc_pxo_pll8_map[] = { static const struct parent_map gcc_pxo_pll8_map[] = {
[P_PXO] = 0, @@ -277,6 +312,22 @@ static const char *gcc_pxo_pll8_pll0_map
@@ -275,6 +310,22 @@ static const char *gcc_pxo_pll8_pll0_map
"pll0_vote", "pll0_vote",
}; };
+static const u8 gcc_pxo_pll8_pll14_pll18_pll0_map[] = { +static const struct parent_map gcc_pxo_pll8_pll14_pll18_pll0_map[] = {
+ [P_PXO] = 0 , + { P_PXO, 0 },
+ [P_PLL8] = 4, + { P_PLL8, 4 },
+ [P_PLL0] = 2, + { P_PLL0, 2 },
+ [P_PLL14] = 5, + { P_PLL14, 5 },
+ [P_PLL18] = 1, + { P_PLL18, 1 },
+}; +};
+ +
+static const char *gcc_pxo_pll8_pll14_pll18_pll0[] = { +static const char *gcc_pxo_pll8_pll14_pll18_pll0[] = {
@ -86,7 +87,7 @@ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
static struct freq_tbl clk_tbl_gsbi_uart[] = { static struct freq_tbl clk_tbl_gsbi_uart[] = {
{ 1843200, P_PLL8, 2, 6, 625 }, { 1843200, P_PLL8, 2, 6, 625 },
{ 3686400, P_PLL8, 2, 12, 625 }, { 3686400, P_PLL8, 2, 12, 625 },
@@ -2250,6 +2301,472 @@ static struct clk_branch usb_fs1_h_clk = @@ -2282,6 +2333,472 @@ static struct clk_branch ebi2_aon_clk =
}, },
}; };
@ -559,7 +560,7 @@ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
static struct clk_regmap *gcc_ipq806x_clks[] = { static struct clk_regmap *gcc_ipq806x_clks[] = {
[PLL0] = &pll0.clkr, [PLL0] = &pll0.clkr,
[PLL0_VOTE] = &pll0_vote, [PLL0_VOTE] = &pll0_vote,
@@ -2259,6 +2776,7 @@ static struct clk_regmap *gcc_ipq806x_cl @@ -2291,6 +2808,7 @@ static struct clk_regmap *gcc_ipq806x_cl
[PLL8_VOTE] = &pll8_vote, [PLL8_VOTE] = &pll8_vote,
[PLL14] = &pll14.clkr, [PLL14] = &pll14.clkr,
[PLL14_VOTE] = &pll14_vote, [PLL14_VOTE] = &pll14_vote,
@ -567,7 +568,7 @@ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
[GSBI1_UART_SRC] = &gsbi1_uart_src.clkr, [GSBI1_UART_SRC] = &gsbi1_uart_src.clkr,
[GSBI1_UART_CLK] = &gsbi1_uart_clk.clkr, [GSBI1_UART_CLK] = &gsbi1_uart_clk.clkr,
[GSBI2_UART_SRC] = &gsbi2_uart_src.clkr, [GSBI2_UART_SRC] = &gsbi2_uart_src.clkr,
@@ -2356,6 +2874,18 @@ static struct clk_regmap *gcc_ipq806x_cl @@ -2390,6 +2908,18 @@ static struct clk_regmap *gcc_ipq806x_cl
[PLL9] = &hfpll0.clkr, [PLL9] = &hfpll0.clkr,
[PLL10] = &hfpll1.clkr, [PLL10] = &hfpll1.clkr,
[PLL12] = &hfpll_l2.clkr, [PLL12] = &hfpll_l2.clkr,
@ -586,7 +587,7 @@ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
}; };
static const struct qcom_reset_map gcc_ipq806x_resets[] = { static const struct qcom_reset_map gcc_ipq806x_resets[] = {
@@ -2474,6 +3004,48 @@ static const struct qcom_reset_map gcc_i @@ -2508,6 +3038,48 @@ static const struct qcom_reset_map gcc_i
[USB30_1_PHY_RESET] = { 0x3b58, 0 }, [USB30_1_PHY_RESET] = { 0x3b58, 0 },
[NSSFB0_RESET] = { 0x3b60, 6 }, [NSSFB0_RESET] = { 0x3b60, 6 },
[NSSFB1_RESET] = { 0x3b60, 7 }, [NSSFB1_RESET] = { 0x3b60, 7 },
@ -635,7 +636,7 @@ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
}; };
static const struct regmap_config gcc_ipq806x_regmap_config = { static const struct regmap_config gcc_ipq806x_regmap_config = {
@@ -2502,6 +3074,8 @@ static int gcc_ipq806x_probe(struct plat @@ -2536,6 +3108,8 @@ static int gcc_ipq806x_probe(struct plat
{ {
struct clk *clk; struct clk *clk;
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
@ -644,7 +645,7 @@ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
/* Temporary until RPM clocks supported */ /* Temporary until RPM clocks supported */
clk = clk_register_fixed_rate(dev, "cxo", NULL, CLK_IS_ROOT, 25000000); clk = clk_register_fixed_rate(dev, "cxo", NULL, CLK_IS_ROOT, 25000000);
@@ -2512,7 +3086,25 @@ static int gcc_ipq806x_probe(struct plat @@ -2546,7 +3120,25 @@ static int gcc_ipq806x_probe(struct plat
if (IS_ERR(clk)) if (IS_ERR(clk))
return PTR_ERR(clk); return PTR_ERR(clk);
@ -671,16 +672,6 @@ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
} }
static int gcc_ipq806x_remove(struct platform_device *pdev) static int gcc_ipq806x_remove(struct platform_device *pdev)
--- a/include/dt-bindings/clock/qcom,gcc-ipq806x.h
+++ b/include/dt-bindings/clock/qcom,gcc-ipq806x.h
@@ -288,5 +288,7 @@
#define UBI32_CORE2_CLK_SRC 278
#define UBI32_CORE1_CLK 279
#define UBI32_CORE2_CLK 280
+#define NSSTCM_CLK_SRC 281
+#define NSSTCM_CLK 282
#endif
--- a/include/dt-bindings/reset/qcom,gcc-ipq806x.h --- a/include/dt-bindings/reset/qcom,gcc-ipq806x.h
+++ b/include/dt-bindings/reset/qcom,gcc-ipq806x.h +++ b/include/dt-bindings/reset/qcom,gcc-ipq806x.h
@@ -129,4 +129,47 @@ @@ -129,4 +129,47 @@
@ -731,3 +722,13 @@ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
+#define NSS_SRDS_N_RESET 156 +#define NSS_SRDS_N_RESET 156
+ +
#endif #endif
--- a/include/dt-bindings/clock/qcom,gcc-ipq806x.h
+++ b/include/dt-bindings/clock/qcom,gcc-ipq806x.h
@@ -289,5 +289,7 @@
#define UBI32_CORE1_CLK 279
#define UBI32_CORE2_CLK 280
#define EBI2_AON_CLK 281
+#define NSSTCM_CLK_SRC 282
+#define NSSTCM_CLK 283
#endif

View File

@ -67,7 +67,7 @@ Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
pr_err("%s: Could not attach to PHY\n", dev->name); pr_err("%s: Could not attach to PHY\n", dev->name);
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
@@ -27,6 +27,7 @@ @@ -28,6 +28,7 @@
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_net.h> #include <linux/of_net.h>
#include <linux/of_device.h> #include <linux/of_device.h>
@ -75,7 +75,7 @@ Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
#include "stmmac.h" #include "stmmac.h"
#include "stmmac_platform.h" #include "stmmac_platform.h"
@@ -167,13 +168,16 @@ static int stmmac_probe_config_dt(struct @@ -168,13 +169,16 @@ static int stmmac_probe_config_dt(struct
/* Default to phy auto-detection */ /* Default to phy auto-detection */
plat->phy_addr = -1; plat->phy_addr = -1;

View File

@ -17,7 +17,7 @@ Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
@@ -129,13 +129,18 @@ static int stmmac_probe_config_dt(struct @@ -130,13 +130,18 @@ static int stmmac_probe_config_dt(struct
struct device_node *np = pdev->dev.of_node; struct device_node *np = pdev->dev.of_node;
struct stmmac_dma_cfg *dma_cfg; struct stmmac_dma_cfg *dma_cfg;
const struct of_device_id *device; const struct of_device_id *device;
@ -40,7 +40,7 @@ Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
if (device->data) { if (device->data) {
const struct stmmac_of_data *data = device->data; const struct stmmac_of_data *data = device->data;
@@ -231,8 +236,10 @@ static int stmmac_probe_config_dt(struct @@ -236,8 +241,10 @@ static int stmmac_probe_config_dt(struct
if (of_find_property(np, "snps,pbl", NULL)) { if (of_find_property(np, "snps,pbl", NULL)) {
dma_cfg = devm_kzalloc(&pdev->dev, sizeof(*dma_cfg), dma_cfg = devm_kzalloc(&pdev->dev, sizeof(*dma_cfg),
GFP_KERNEL); GFP_KERNEL);
@ -53,7 +53,7 @@ Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
plat->dma_cfg = dma_cfg; plat->dma_cfg = dma_cfg;
of_property_read_u32(np, "snps,pbl", &dma_cfg->pbl); of_property_read_u32(np, "snps,pbl", &dma_cfg->pbl);
dma_cfg->fixed_burst = dma_cfg->fixed_burst =
@@ -250,6 +257,9 @@ static int stmmac_probe_config_dt(struct @@ -255,6 +262,9 @@ static int stmmac_probe_config_dt(struct
} }
return 0; return 0;

View File

@ -29,7 +29,7 @@ Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
} }
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
@@ -176,6 +176,14 @@ static int stmmac_probe_config_dt(struct @@ -177,6 +177,14 @@ static int stmmac_probe_config_dt(struct
/* If we find a phy-handle property, use it as the PHY */ /* If we find a phy-handle property, use it as the PHY */
plat->phy_node = of_parse_phandle(np, "phy-handle", 0); plat->phy_node = of_parse_phandle(np, "phy-handle", 0);
@ -44,7 +44,7 @@ Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
/* "snps,phy-addr" is not a standard property. Mark it as deprecated /* "snps,phy-addr" is not a standard property. Mark it as deprecated
* and warn of its use. Remove this when phy node support is added. * and warn of its use. Remove this when phy node support is added.
*/ */
@@ -238,7 +246,7 @@ static int stmmac_probe_config_dt(struct @@ -243,7 +251,7 @@ static int stmmac_probe_config_dt(struct
GFP_KERNEL); GFP_KERNEL);
if (!dma_cfg) { if (!dma_cfg) {
ret = -ENOMEM; ret = -ENOMEM;
@ -53,7 +53,7 @@ Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
} }
plat->dma_cfg = dma_cfg; plat->dma_cfg = dma_cfg;
of_property_read_u32(np, "snps,pbl", &dma_cfg->pbl); of_property_read_u32(np, "snps,pbl", &dma_cfg->pbl);
@@ -258,6 +266,8 @@ static int stmmac_probe_config_dt(struct @@ -263,6 +271,8 @@ static int stmmac_probe_config_dt(struct
return 0; return 0;

View File

@ -42,7 +42,7 @@ Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
stmmac-pci-objs:= stmmac_pci.o stmmac-pci-objs:= stmmac_pci.o
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
@@ -42,6 +42,7 @@ static const struct of_device_id stmmac_ @@ -43,6 +43,7 @@ static const struct of_device_id stmmac_
{ .compatible = "st,stid127-dwmac", .data = &stid127_dwmac_data}, { .compatible = "st,stid127-dwmac", .data = &stid127_dwmac_data},
{ .compatible = "st,stih407-dwmac", .data = &stih4xx_dwmac_data}, { .compatible = "st,stih407-dwmac", .data = &stih4xx_dwmac_data},
{ .compatible = "altr,socfpga-stmmac", .data = &socfpga_gmac_data }, { .compatible = "altr,socfpga-stmmac", .data = &socfpga_gmac_data },

View File

@ -116,11 +116,10 @@ Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
}; };
--- a/arch/arm/boot/dts/qcom-ipq8064.dtsi --- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi +++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
@@ -540,5 +540,91 @@ @@ -578,5 +578,91 @@
status = "disabled"; status = "disabled";
}; };
+
+ nss_common: syscon@03000000 { + nss_common: syscon@03000000 {
+ compatible = "syscon"; + compatible = "syscon";
+ reg = <0x03000000 0x0000FFFF>; + reg = <0x03000000 0x0000FFFF>;
@ -206,5 +205,6 @@ Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
+ +
+ status = "disabled"; + status = "disabled";
+ }; + };
+
}; };
}; };