layerscape: update kernel patches

Updated kernel patches to align layerscape kernel
with latest LSDK linux (LSDK-17.09-update-103017-V4.9 tag).

Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
This commit is contained in:
Yangbo Lu 2017-10-16 18:48:11 +08:00 committed by John Crispin
parent ede04541ba
commit ce6311d283
13 changed files with 14969 additions and 1411 deletions

View File

@ -1,4 +1,4 @@
From 11edf9c88acea13d1a02901289060263b4027a77 Mon Sep 17 00:00:00 2001
From 7992b4384d94c5e1bad998ca3a9a5781caac8e62 Mon Sep 17 00:00:00 2001
From: Yangbo Lu <yangbo.lu@nxp.com>
Date: Mon, 25 Sep 2017 09:52:26 +0800
Subject: [PATCH] config: support layerscape
@ -30,11 +30,11 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
drivers/soc/fsl/layerscape/Kconfig | 10 +++
drivers/soc/fsl/layerscape/Makefile | 1 +
drivers/soc/fsl/rcpm.c | 154 ++++++++++++++++++++++++++++++++
drivers/staging/Kconfig | 4 +
drivers/staging/Makefile | 2 +
drivers/staging/Kconfig | 6 ++
drivers/staging/Makefile | 3 +
drivers/staging/fsl-dpaa2/Kconfig | 41 +++++++++
drivers/staging/fsl-dpaa2/Makefile | 9 ++
18 files changed, 309 insertions(+), 4 deletions(-)
18 files changed, 312 insertions(+), 4 deletions(-)
create mode 100644 drivers/soc/fsl/Kconfig
create mode 100644 drivers/soc/fsl/Kconfig.arm
create mode 100644 drivers/soc/fsl/layerscape/Kconfig
@ -43,6 +43,8 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
create mode 100644 drivers/staging/fsl-dpaa2/Kconfig
create mode 100644 drivers/staging/fsl-dpaa2/Makefile
diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig
index e1c0e2e0..4211a7fd 100644
--- a/drivers/base/Kconfig
+++ b/drivers/base/Kconfig
@@ -237,6 +237,7 @@ config GENERIC_CPU_AUTOPROBE
@ -53,9 +55,11 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
source "drivers/base/regmap/Kconfig"
diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile
index ad7250fa..6d788fd7 100644
--- a/drivers/crypto/Makefile
+++ b/drivers/crypto/Makefile
@@ -3,7 +3,7 @@ obj-$(CONFIG_CRYPTO_DEV_ATMEL_SHA) += at
@@ -3,7 +3,7 @@ obj-$(CONFIG_CRYPTO_DEV_ATMEL_SHA) += atmel-sha.o
obj-$(CONFIG_CRYPTO_DEV_ATMEL_TDES) += atmel-tdes.o
obj-$(CONFIG_CRYPTO_DEV_BFIN_CRC) += bfin_crc.o
obj-$(CONFIG_CRYPTO_DEV_CCP) += ccp/
@ -64,6 +68,8 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
obj-$(CONFIG_CRYPTO_DEV_GEODE) += geode-aes.o
obj-$(CONFIG_CRYPTO_DEV_HIFN_795X) += hifn_795x.o
obj-$(CONFIG_CRYPTO_DEV_IMGTEC_HASH) += img-hash.o
diff --git a/drivers/net/ethernet/freescale/Kconfig b/drivers/net/ethernet/freescale/Kconfig
index d1ca45fb..74a2864e 100644
--- a/drivers/net/ethernet/freescale/Kconfig
+++ b/drivers/net/ethernet/freescale/Kconfig
@@ -5,7 +5,7 @@
@ -82,6 +88,8 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
+source "drivers/net/ethernet/freescale/sdk_fman/Kconfig"
+source "drivers/net/ethernet/freescale/sdk_dpaa/Kconfig"
endif # NET_VENDOR_FREESCALE
diff --git a/drivers/net/ethernet/freescale/Makefile b/drivers/net/ethernet/freescale/Makefile
index cbe21dc7..a5d4405f 100644
--- a/drivers/net/ethernet/freescale/Makefile
+++ b/drivers/net/ethernet/freescale/Makefile
@@ -21,4 +21,6 @@ gianfar_driver-objs := gianfar.o \
@ -91,6 +99,8 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
+obj-$(if $(CONFIG_FSL_SDK_FMAN),y) += sdk_fman/
+obj-$(if $(CONFIG_FSL_SDK_DPAA_ETH),y) += sdk_dpaa/
obj-$(CONFIG_FSL_FMAN) += fman/
diff --git a/drivers/ptp/Kconfig b/drivers/ptp/Kconfig
index ee3de342..4c45beda 100644
--- a/drivers/ptp/Kconfig
+++ b/drivers/ptp/Kconfig
@@ -39,6 +39,35 @@ config PTP_1588_CLOCK_GIANFAR
@ -129,6 +139,8 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
config PTP_1588_CLOCK_IXP46X
tristate "Intel IXP46x as PTP clock"
depends on IXP4XX_ETH
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 0723c97e..df610dcd 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -414,6 +414,14 @@ config RTC_DRV_PCF85063
@ -146,9 +158,11 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
config RTC_DRV_PCF8563
tristate "Philips PCF8563/Epson RTC8564"
help
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 1ac694a3..7675b8a7 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -111,6 +111,7 @@ obj-$(CONFIG_RTC_DRV_PCF2127) += rtc-pcf
@@ -111,6 +111,7 @@ obj-$(CONFIG_RTC_DRV_PCF2127) += rtc-pcf2127.o
obj-$(CONFIG_RTC_DRV_PCF50633) += rtc-pcf50633.o
obj-$(CONFIG_RTC_DRV_PCF85063) += rtc-pcf85063.o
obj-$(CONFIG_RTC_DRV_PCF8523) += rtc-pcf8523.o
@ -156,6 +170,8 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
obj-$(CONFIG_RTC_DRV_PCF8563) += rtc-pcf8563.o
obj-$(CONFIG_RTC_DRV_PCF8583) += rtc-pcf8583.o
obj-$(CONFIG_RTC_DRV_PIC32) += rtc-pic32.o
diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig
index e6e90e80..f31bceb6 100644
--- a/drivers/soc/Kconfig
+++ b/drivers/soc/Kconfig
@@ -1,8 +1,7 @@
@ -168,6 +184,9 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
source "drivers/soc/mediatek/Kconfig"
source "drivers/soc/qcom/Kconfig"
source "drivers/soc/rockchip/Kconfig"
diff --git a/drivers/soc/fsl/Kconfig b/drivers/soc/fsl/Kconfig
new file mode 100644
index 00000000..d4cd25f1
--- /dev/null
+++ b/drivers/soc/fsl/Kconfig
@@ -0,0 +1,22 @@
@ -193,6 +212,9 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
+if ARM || ARM64
+source "drivers/soc/fsl/Kconfig.arm"
+endif
diff --git a/drivers/soc/fsl/Kconfig.arm b/drivers/soc/fsl/Kconfig.arm
new file mode 100644
index 00000000..106c9b98
--- /dev/null
+++ b/drivers/soc/fsl/Kconfig.arm
@@ -0,0 +1,16 @@
@ -212,6 +234,8 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
+if LS_SOC_DRIVERS
+ source "drivers/soc/fsl/layerscape/Kconfig"
+endif
diff --git a/drivers/soc/fsl/Makefile b/drivers/soc/fsl/Makefile
index 75e1f533..b8708569 100644
--- a/drivers/soc/fsl/Makefile
+++ b/drivers/soc/fsl/Makefile
@@ -5,3 +5,7 @@
@ -222,6 +246,9 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
+obj-$(CONFIG_FSL_LS2_CONSOLE) += ls2-console/
+obj-$(CONFIG_SUSPEND) += rcpm.o
+obj-$(CONFIG_LS_SOC_DRIVERS) += layerscape/
diff --git a/drivers/soc/fsl/layerscape/Kconfig b/drivers/soc/fsl/layerscape/Kconfig
new file mode 100644
index 00000000..e1373aa1
--- /dev/null
+++ b/drivers/soc/fsl/layerscape/Kconfig
@@ -0,0 +1,10 @@
@ -235,10 +262,16 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
+ Say y here to enable FTM alarm support. The FTM alarm provides
+ alarm functions for wakeup system from deep sleep. There is only
+ one FTM can be used in ALARM(FTM 0).
diff --git a/drivers/soc/fsl/layerscape/Makefile b/drivers/soc/fsl/layerscape/Makefile
new file mode 100644
index 00000000..6299aa1d
--- /dev/null
+++ b/drivers/soc/fsl/layerscape/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_FTM_ALARM) += ftm_alarm.o
diff --git a/drivers/soc/fsl/rcpm.c b/drivers/soc/fsl/rcpm.c
new file mode 100644
index 00000000..a6a31c87
--- /dev/null
+++ b/drivers/soc/fsl/rcpm.c
@@ -0,0 +1,154 @@
@ -396,6 +429,8 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
+}
+
+subsys_initcall(layerscape_rcpm_init);
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index 58a7b350..6c69e3bd 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -94,6 +94,8 @@ source "drivers/staging/fbtft/Kconfig"
@ -407,16 +442,20 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
source "drivers/staging/wilc1000/Kconfig"
source "drivers/staging/most/Kconfig"
@@ -106,4 +108,6 @@ source "drivers/staging/greybus/Kconfig"
@@ -106,4 +108,8 @@ source "drivers/staging/greybus/Kconfig"
source "drivers/staging/vc04_services/Kconfig"
+source "drivers/staging/fsl_qbman/Kconfig"
+
+source "drivers/staging/fsl_ppfe/Kconfig"
+
endif # STAGING
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index 2fa9745d..ee817a5e 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -36,9 +36,11 @@ obj-$(CONFIG_UNISYSSPAR) += unisys/
@@ -36,9 +36,12 @@ obj-$(CONFIG_UNISYSSPAR) += unisys/
obj-$(CONFIG_COMMON_CLK_XLNX_CLKWZRD) += clocking-wizard/
obj-$(CONFIG_FB_TFT) += fbtft/
obj-$(CONFIG_FSL_MC_BUS) += fsl-mc/
@ -428,6 +467,10 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
obj-$(CONFIG_GREYBUS) += greybus/
obj-$(CONFIG_BCM2708_VCHIQ) += vc04_services/
+obj-$(CONFIG_FSL_SDK_DPA) += fsl_qbman/
+obj-$(CONFIG_FSL_PPFE) += fsl_ppfe/
diff --git a/drivers/staging/fsl-dpaa2/Kconfig b/drivers/staging/fsl-dpaa2/Kconfig
new file mode 100644
index 00000000..8042d9cc
--- /dev/null
+++ b/drivers/staging/fsl-dpaa2/Kconfig
@@ -0,0 +1,41 @@
@ -472,6 +515,9 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
+source "drivers/staging/fsl-dpaa2/mac/Kconfig"
+source "drivers/staging/fsl-dpaa2/evb/Kconfig"
+source "drivers/staging/fsl-dpaa2/ethsw/Kconfig"
diff --git a/drivers/staging/fsl-dpaa2/Makefile b/drivers/staging/fsl-dpaa2/Makefile
new file mode 100644
index 00000000..cbaa8c20
--- /dev/null
+++ b/drivers/staging/fsl-dpaa2/Makefile
@@ -0,0 +1,9 @@
@ -484,3 +530,6 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
+obj-$(CONFIG_FSL_DPAA2_EVB) += evb/
+obj-$(CONFIG_FSL_DPAA2_ETHSW) += ethsw/
+obj-$(CONFIG_PTP_1588_CLOCK_DPAA2) += rtc/
--
2.14.1

View File

@ -1,4 +1,4 @@
From 7edaf7ed8fbd5fb50950a4fc8067a9c14557d010 Mon Sep 17 00:00:00 2001
From 739029f49bd9181b821298f9d27b29ce2d292967 Mon Sep 17 00:00:00 2001
From: Yangbo Lu <yangbo.lu@nxp.com>
Date: Mon, 25 Sep 2017 10:03:52 +0800
Subject: [PATCH] arch: support layerscape
@ -34,9 +34,11 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
arch/arm64/include/asm/pgtable-prot.h | 1 +
arch/arm64/include/asm/pgtable.h | 5 +++
arch/arm64/kernel/pci.c | 62 +++++++++++++++++++++++++++++++++++
arch/arm64/mm/dma-mapping.c | 6 ++++
15 files changed, 197 insertions(+), 3 deletions(-)
arch/arm64/mm/dma-mapping.c | 23 ++++++++++---
15 files changed, 209 insertions(+), 8 deletions(-)
diff --git a/arch/arm/include/asm/delay.h b/arch/arm/include/asm/delay.h
index b1ce037e..1445b0ca 100644
--- a/arch/arm/include/asm/delay.h
+++ b/arch/arm/include/asm/delay.h
@@ -57,6 +57,22 @@ extern void __bad_udelay(void);
@ -62,9 +64,11 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
/* Loop-based definitions for assembly code. */
extern void __loop_delay(unsigned long loops);
extern void __loop_udelay(unsigned long usecs);
diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h
index 021692c6..172a4f2e 100644
--- a/arch/arm/include/asm/io.h
+++ b/arch/arm/include/asm/io.h
@@ -129,6 +129,7 @@ static inline u32 __raw_readl(const vola
@@ -129,6 +129,7 @@ static inline u32 __raw_readl(const volatile void __iomem *addr)
#define MT_DEVICE_NONSHARED 1
#define MT_DEVICE_CACHED 2
#define MT_DEVICE_WC 3
@ -72,7 +76,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
/*
* types 4 onwards can be found in asm/mach/map.h and are undefined
* for ioremap
@@ -220,6 +221,34 @@ extern int pci_ioremap_io(unsigned int o
@@ -220,6 +221,34 @@ extern int pci_ioremap_io(unsigned int offset, phys_addr_t phys_addr);
#endif
#endif
@ -107,7 +111,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
/*
* IO port access primitives
* -------------------------
@@ -408,6 +437,8 @@ void __iomem *ioremap_wc(resource_size_t
@@ -408,6 +437,8 @@ void __iomem *ioremap_wc(resource_size_t res_cookie, size_t size);
#define ioremap_wc ioremap_wc
#define ioremap_wt ioremap_wc
@ -116,6 +120,8 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
void iounmap(volatile void __iomem *iomem_cookie);
#define iounmap iounmap
diff --git a/arch/arm/include/asm/mach/map.h b/arch/arm/include/asm/mach/map.h
index 9b7c328f..27f3df7d 100644
--- a/arch/arm/include/asm/mach/map.h
+++ b/arch/arm/include/asm/mach/map.h
@@ -21,9 +21,9 @@ struct map_desc {
@ -130,6 +136,8 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
MT_CACHECLEAN,
MT_MINICLEAN,
MT_LOW_VECTORS,
diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h
index a8d656d9..4ab57b37 100644
--- a/arch/arm/include/asm/pgtable.h
+++ b/arch/arm/include/asm/pgtable.h
@@ -118,6 +118,13 @@ extern pgprot_t pgprot_s2_device;
@ -146,6 +154,8 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
#define pgprot_writecombine(prot) \
__pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_BUFFERABLE)
diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
index 2f0e0773..d2f4869a 100644
--- a/arch/arm/kernel/bios32.c
+++ b/arch/arm/kernel/bios32.c
@@ -11,6 +11,8 @@
@ -157,10 +167,11 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
#include <asm/mach-types.h>
#include <asm/mach/map.h>
@@ -64,6 +66,47 @@ void pcibios_report_status(u_int status_
@@ -63,6 +65,47 @@ void pcibios_report_status(u_int status_mask, int warn)
pcibios_bus_report_status(bus, status_mask, warn);
}
/*
+/*
+ * Check device tree if the service interrupts are there
+ */
+int pcibios_check_service_irqs(struct pci_dev *dev, int *irqs, int mask)
@ -201,13 +212,14 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
+ return count;
+}
+
+/*
/*
* We don't use this to fix the device, but initialisation of it.
* It's not the correct use for this, but it works.
* Note that the arbiter/ISA bridge appears to be buggy, specifically in
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index ab771000..9b5f4465 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -2392,6 +2392,7 @@ void arch_setup_dma_ops(struct device *d
@@ -2392,6 +2392,7 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
set_dma_ops(dev, dma_ops);
}
@ -215,9 +227,11 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
void arch_teardown_dma_ops(struct device *dev)
{
diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c
index ff0eed23..2f2f4269 100644
--- a/arch/arm/mm/ioremap.c
+++ b/arch/arm/mm/ioremap.c
@@ -398,6 +398,13 @@ void __iomem *ioremap_wc(resource_size_t
@@ -398,6 +398,13 @@ void __iomem *ioremap_wc(resource_size_t res_cookie, size_t size)
}
EXPORT_SYMBOL(ioremap_wc);
@ -231,9 +245,11 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
/*
* Remap an arbitrary physical address space into the kernel virtual
* address space as memory. Needed when the kernel wants to execute
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index f7c74135..4a2fb704 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -313,6 +313,13 @@ static struct mem_type mem_types[] __ro_
@@ -313,6 +313,13 @@ static struct mem_type mem_types[] __ro_after_init = {
.prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE,
.domain = DOMAIN_KERNEL,
},
@ -247,7 +263,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
[MT_ROM] = {
.prot_sect = PMD_TYPE_SECT,
.domain = DOMAIN_KERNEL,
@@ -644,6 +651,7 @@ static void __init build_mem_type_table(
@@ -644,6 +651,7 @@ static void __init build_mem_type_table(void)
}
kern_pgprot |= PTE_EXT_AF;
vecs_pgprot |= PTE_EXT_AF;
@ -255,7 +271,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
/*
* Set PXN for user mappings
@@ -672,6 +680,7 @@ static void __init build_mem_type_table(
@@ -672,6 +680,7 @@ static void __init build_mem_type_table(void)
mem_types[MT_MEMORY_RWX].prot_pte |= kern_pgprot;
mem_types[MT_MEMORY_RW].prot_sect |= ecc_mask | cp->pmd;
mem_types[MT_MEMORY_RW].prot_pte |= kern_pgprot;
@ -263,6 +279,8 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
mem_types[MT_MEMORY_DMA_READY].prot_pte |= kern_pgprot;
mem_types[MT_MEMORY_RWX_NONCACHED].prot_sect |= ecc_mask;
mem_types[MT_ROM].prot_sect |= cp->pmd;
diff --git a/arch/arm64/include/asm/cache.h b/arch/arm64/include/asm/cache.h
index 5082b30b..bde44993 100644
--- a/arch/arm64/include/asm/cache.h
+++ b/arch/arm64/include/asm/cache.h
@@ -18,7 +18,7 @@
@ -274,9 +292,11 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
/*
diff --git a/arch/arm64/include/asm/io.h b/arch/arm64/include/asm/io.h
index 0bba427b..36c1fbf3 100644
--- a/arch/arm64/include/asm/io.h
+++ b/arch/arm64/include/asm/io.h
@@ -171,6 +171,8 @@ extern void __iomem *ioremap_cache(phys_
@@ -171,6 +171,8 @@ extern void __iomem *ioremap_cache(phys_addr_t phys_addr, size_t size);
#define ioremap_nocache(addr, size) __ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE))
#define ioremap_wc(addr, size) __ioremap((addr), (size), __pgprot(PROT_NORMAL_NC))
#define ioremap_wt(addr, size) __ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE))
@ -285,9 +305,11 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
#define iounmap __iounmap
/*
diff --git a/arch/arm64/include/asm/pci.h b/arch/arm64/include/asm/pci.h
index b9a7ba9c..8a189159 100644
--- a/arch/arm64/include/asm/pci.h
+++ b/arch/arm64/include/asm/pci.h
@@ -31,6 +31,10 @@ static inline int pci_get_legacy_ide_irq
@@ -31,6 +31,10 @@ static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel)
return -ENODEV;
}
@ -298,6 +320,8 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
static inline int pci_proc_domain(struct pci_bus *bus)
{
return 1;
diff --git a/arch/arm64/include/asm/pgtable-prot.h b/arch/arm64/include/asm/pgtable-prot.h
index 2142c772..cdf8b25d 100644
--- a/arch/arm64/include/asm/pgtable-prot.h
+++ b/arch/arm64/include/asm/pgtable-prot.h
@@ -42,6 +42,7 @@
@ -308,9 +332,11 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
#define PROT_SECT_DEVICE_nGnRE (PROT_SECT_DEFAULT | PMD_SECT_PXN | PMD_SECT_UXN | PMD_ATTRINDX(MT_DEVICE_nGnRE))
#define PROT_SECT_NORMAL (PROT_SECT_DEFAULT | PMD_SECT_PXN | PMD_SECT_UXN | PMD_ATTRINDX(MT_NORMAL))
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index 61e21401..b8c876fb 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -356,6 +356,11 @@ static inline int pmd_protnone(pmd_t pmd
@@ -356,6 +356,11 @@ static inline int pmd_protnone(pmd_t pmd)
__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_DEVICE_nGnRnE) | PTE_PXN | PTE_UXN)
#define pgprot_writecombine(prot) \
__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC) | PTE_PXN | PTE_UXN)
@ -322,6 +348,8 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
#define pgprot_device(prot) \
__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_DEVICE_nGnRE) | PTE_PXN | PTE_UXN)
#define __HAVE_PHYS_MEM_ACCESS_PROT
diff --git a/arch/arm64/kernel/pci.c b/arch/arm64/kernel/pci.c
index 409abc45..0568ec3a 100644
--- a/arch/arm64/kernel/pci.c
+++ b/arch/arm64/kernel/pci.c
@@ -17,6 +17,8 @@
@ -333,11 +361,10 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
#include <linux/pci.h>
#include <linux/pci-acpi.h>
#include <linux/pci-ecam.h>
@@ -53,6 +55,66 @@ int pcibios_alloc_irq(struct pci_dev *de
@@ -54,6 +56,66 @@ int pcibios_alloc_irq(struct pci_dev *dev)
return 0;
}
+
+/*
+ * Check device tree if the service interrupts are there
+ */
@ -397,9 +424,12 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
+
+ return 0;
+}
+
/*
* raw_pci_read/write - Platform-specific PCI config space access.
*/
diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
index b5bf46ce..5a010bcc 100644
--- a/arch/arm64/mm/dma-mapping.c
+++ b/arch/arm64/mm/dma-mapping.c
@@ -30,6 +30,7 @@
@ -410,19 +440,49 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
static int swiotlb __ro_after_init;
@@ -918,6 +919,10 @@ static int __init __iommu_dma_init(void)
@@ -836,14 +837,21 @@ static bool do_iommu_attach(struct device *dev, const struct iommu_ops *ops,
* then the IOMMU core will have already configured a group for this
* device, and allocated the default domain for that group.
*/
- if (!domain || iommu_dma_init_domain(domain, dma_base, size, dev)) {
- pr_warn("Failed to set up IOMMU for device %s; retaining platform DMA ops\n",
- dev_name(dev));
- return false;
+ if (!domain)
+ goto out_err;
+
+ if (domain->type == IOMMU_DOMAIN_DMA) {
+ if (iommu_dma_init_domain(domain, dma_base, size, dev))
+ goto out_err;
+
+ dev->archdata.dma_ops = &iommu_dma_ops;
}
- dev->archdata.dma_ops = &iommu_dma_ops;
return true;
+out_err:
+ pr_warn("Failed to set up IOMMU for device %s; retaining platform DMA ops\n",
+ dev_name(dev));
+ return false;
}
static void queue_iommu_attach(struct device *dev, const struct iommu_ops *ops,
@@ -917,6 +925,10 @@ static int __init __iommu_dma_init(void)
#ifdef CONFIG_PCI
if (!ret)
ret = register_iommu_dma_ops_notifier(&pci_bus_type);
#endif
+#endif
+#ifdef CONFIG_FSL_MC_BUS
+ if (!ret)
+ ret = register_iommu_dma_ops_notifier(&fsl_mc_bus_type);
+#endif
#endif
return ret;
}
arch_initcall(__iommu_dma_init);
@@ -971,3 +976,4 @@ void arch_setup_dma_ops(struct device *d
@@ -971,3 +983,4 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
dev->archdata.dma_coherent = coherent;
__iommu_setup_dma_ops(dev, dma_base, size, iommu);
}
+EXPORT_SYMBOL(arch_setup_dma_ops);
--
2.14.1

View File

@ -1,4 +1,4 @@
From 120fa458ffe2250ea58578ccfc85e674005463dc Mon Sep 17 00:00:00 2001
From a3757157751a8a5302ee5e11faf828dc5db02018 Mon Sep 17 00:00:00 2001
From: Yangbo Lu <yangbo.lu@nxp.com>
Date: Mon, 25 Sep 2017 10:53:50 +0800
Subject: [PATCH] mtd: spi-nor: support layerscape
@ -18,14 +18,16 @@ Signed-off-by: Ash Benz <ash.benz@bk.ru>
Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
---
drivers/mtd/mtdchar.c | 2 +-
drivers/mtd/spi-nor/fsl-quadspi.c | 356 +++++++++++++++++++++++++++++++-------
drivers/mtd/spi-nor/spi-nor.c | 136 +++++++++++++--
drivers/mtd/spi-nor/fsl-quadspi.c | 327 +++++++++++++++++++++++++++++++-------
drivers/mtd/spi-nor/spi-nor.c | 136 ++++++++++++++--
include/linux/mtd/spi-nor.h | 14 +-
4 files changed, 432 insertions(+), 76 deletions(-)
4 files changed, 409 insertions(+), 70 deletions(-)
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index 2a47a3f0..4f21401d 100644
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -451,7 +451,7 @@ static int mtdchar_readoob(struct file *
@@ -451,7 +451,7 @@ static int mtdchar_readoob(struct file *file, struct mtd_info *mtd,
* data. For our userspace tools it is important to dump areas
* with ECC errors!
* For kernel internal usage it also might return -EUCLEAN
@ -34,6 +36,8 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
* been corrected by the ECC algorithm.
*
* Note: currently the standard NAND function, nand_read_oob_std,
diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c
index 5c82e4ef..33ecc27a 100644
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
@@ -41,6 +41,8 @@
@ -86,7 +90,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
.devtype = FSL_QUADSPI_VYBRID,
.rxfifo = 128,
.txfifo = 64,
@@ -232,7 +241,7 @@ static struct fsl_qspi_devtype_data vybr
@@ -232,7 +241,7 @@ static struct fsl_qspi_devtype_data vybrid_data = {
.driver_data = QUADSPI_QUIRK_SWAP_ENDIAN,
};
@ -95,7 +99,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
.devtype = FSL_QUADSPI_IMX6SX,
.rxfifo = 128,
.txfifo = 512,
@@ -241,7 +250,7 @@ static struct fsl_qspi_devtype_data imx6
@@ -241,7 +250,7 @@ static struct fsl_qspi_devtype_data imx6sx_data = {
| QUADSPI_QUIRK_TKT245618,
};
@ -104,7 +108,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
.devtype = FSL_QUADSPI_IMX7D,
.rxfifo = 512,
.txfifo = 512,
@@ -250,7 +259,7 @@ static struct fsl_qspi_devtype_data imx7
@@ -250,7 +259,7 @@ static struct fsl_qspi_devtype_data imx7d_data = {
| QUADSPI_QUIRK_4X_INT_CLK,
};
@ -113,7 +117,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
.devtype = FSL_QUADSPI_IMX6UL,
.rxfifo = 128,
.txfifo = 512,
@@ -267,6 +276,14 @@ static struct fsl_qspi_devtype_data ls10
@@ -267,6 +276,14 @@ static struct fsl_qspi_devtype_data ls1021a_data = {
.driver_data = 0,
};
@ -136,7 +140,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
unsigned int chip_base_addr; /* We may support two chips. */
bool has_second_chip;
bool big_endian;
@@ -309,6 +327,23 @@ static inline int needs_wakeup_wait_mode
@@ -309,6 +327,23 @@ static inline int needs_wakeup_wait_mode(struct fsl_qspi *q)
return q->devtype_data->driver_data & QUADSPI_QUIRK_TKT245618;
}
@ -160,7 +164,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
/*
* R/W functions for big- or little-endian registers:
* The qSPI controller's endian is independent of the CPU core's endian.
@@ -331,6 +366,31 @@ static u32 qspi_readl(struct fsl_qspi *q
@@ -331,6 +366,31 @@ static u32 qspi_readl(struct fsl_qspi *q, void __iomem *addr)
return ioread32(addr);
}
@ -192,7 +196,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
/*
* An IC bug makes us to re-arrange the 32-bit data.
* The following chips, such as IMX6SLX, have fixed this bug.
@@ -373,8 +433,15 @@ static void fsl_qspi_init_lut(struct fsl
@@ -373,8 +433,15 @@ static void fsl_qspi_init_lut(struct fsl_qspi *q)
void __iomem *base = q->iobase;
int rxfifo = q->devtype_data->rxfifo;
u32 lut_base;
@ -209,7 +213,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
fsl_qspi_unlock_lut(q);
@@ -382,25 +449,51 @@ static void fsl_qspi_init_lut(struct fsl
@@ -382,25 +449,51 @@ static void fsl_qspi_init_lut(struct fsl_qspi *q)
for (i = 0; i < QUADSPI_LUT_NUM; i++)
qspi_writel(q, 0, base + QUADSPI_LUT_BASE + i * 4);
@ -226,10 +230,11 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
- addrlen = ADDR32BIT;
- dummy = 8;
- }
-
- qspi_writel(q, LUT0(CMD, PAD1, cmd) | LUT1(ADDR, PAD1, addrlen),
+ /* Read */
+ lut_base = SEQID_READ * 4;
- qspi_writel(q, LUT0(CMD, PAD1, cmd) | LUT1(ADDR, PAD1, addrlen),
+
+ if (nor->flash_read == SPI_NOR_FAST) {
+ qspi_writel(q, LUT0(CMD, PAD1, read_op) |
+ LUT1(ADDR, PAD1, addrlen),
@ -276,7 +281,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
/* Write enable */
lut_base = SEQID_WREN * 4;
qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_WREN),
@@ -409,16 +502,8 @@ static void fsl_qspi_init_lut(struct fsl
@@ -409,16 +502,8 @@ static void fsl_qspi_init_lut(struct fsl_qspi *q)
/* Page Program */
lut_base = SEQID_PP * 4;
@ -295,7 +300,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
base + QUADSPI_LUT(lut_base));
qspi_writel(q, LUT0(FSL_WRITE, PAD1, 0),
base + QUADSPI_LUT(lut_base + 1));
@@ -432,10 +517,8 @@ static void fsl_qspi_init_lut(struct fsl
@@ -432,10 +517,8 @@ static void fsl_qspi_init_lut(struct fsl_qspi *q)
/* Erase a sector */
lut_base = SEQID_SE * 4;
@ -308,7 +313,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
base + QUADSPI_LUT(lut_base));
/* Erase the whole chip */
@@ -476,6 +559,44 @@ static void fsl_qspi_init_lut(struct fsl
@@ -476,6 +559,44 @@ static void fsl_qspi_init_lut(struct fsl_qspi *q)
qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_BRWR),
base + QUADSPI_LUT(lut_base));
@ -353,7 +358,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
fsl_qspi_lock_lut(q);
}
@@ -483,8 +604,24 @@ static void fsl_qspi_init_lut(struct fsl
@@ -483,8 +604,24 @@ static void fsl_qspi_init_lut(struct fsl_qspi *q)
static int fsl_qspi_get_seqid(struct fsl_qspi *q, u8 cmd)
{
switch (cmd) {
@ -379,7 +384,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
case SPINOR_OP_WREN:
return SEQID_WREN;
case SPINOR_OP_WRDI:
@@ -496,6 +633,7 @@ static int fsl_qspi_get_seqid(struct fsl
@@ -496,6 +633,7 @@ static int fsl_qspi_get_seqid(struct fsl_qspi *q, u8 cmd)
case SPINOR_OP_CHIP_ERASE:
return SEQID_CHIP_ERASE;
case SPINOR_OP_PP:
@ -387,7 +392,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
return SEQID_PP;
case SPINOR_OP_RDID:
return SEQID_RDID;
@@ -507,6 +645,8 @@ static int fsl_qspi_get_seqid(struct fsl
@@ -507,6 +645,8 @@ static int fsl_qspi_get_seqid(struct fsl_qspi *q, u8 cmd)
return SEQID_EN4B;
case SPINOR_OP_BRWR:
return SEQID_BRWR;
@ -396,7 +401,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
default:
if (cmd == q->nor[0].erase_opcode)
return SEQID_SE;
@@ -531,8 +671,11 @@ fsl_qspi_runcmd(struct fsl_qspi *q, u8 c
@@ -531,8 +671,11 @@ fsl_qspi_runcmd(struct fsl_qspi *q, u8 cmd, unsigned int addr, int len)
/* save the reg */
reg = qspi_readl(q, base + QUADSPI_MCR);
@ -410,7 +415,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
qspi_writel(q, QUADSPI_RBCT_WMRK_MASK | QUADSPI_RBCT_RXBRD_USEIPS,
base + QUADSPI_RBCT);
qspi_writel(q, reg | QUADSPI_MCR_CLR_RXF_MASK, base + QUADSPI_MCR);
@@ -582,10 +725,10 @@ static void fsl_qspi_read_data(struct fs
@@ -582,10 +725,10 @@ static void fsl_qspi_read_data(struct fsl_qspi *q, int len, u8 *rxbuf)
q->chip_base_addr, tmp);
if (len >= 4) {
@ -423,7 +428,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
break;
}
@@ -619,11 +762,12 @@ static inline void fsl_qspi_invalid(stru
@@ -619,11 +762,12 @@ static inline void fsl_qspi_invalid(struct fsl_qspi *q)
}
static ssize_t fsl_qspi_nor_write(struct fsl_qspi *q, struct spi_nor *nor,
@ -437,7 +442,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
dev_dbg(q->dev, "to 0x%.8x:0x%.8x, len : %d\n",
q->chip_base_addr, to, count);
@@ -633,10 +777,13 @@ static ssize_t fsl_qspi_nor_write(struct
@@ -633,10 +777,13 @@ static ssize_t fsl_qspi_nor_write(struct fsl_qspi *q, struct spi_nor *nor,
qspi_writel(q, tmp | QUADSPI_MCR_CLR_TXF_MASK, q->iobase + QUADSPI_MCR);
/* fill the TX data to the FIFO */
@ -453,7 +458,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
}
/* fill the TXFIFO upto 16 bytes for i.MX7d */
@@ -657,11 +804,43 @@ static void fsl_qspi_set_map_addr(struct
@@ -657,11 +804,43 @@ static void fsl_qspi_set_map_addr(struct fsl_qspi *q)
{
int nor_size = q->nor_size;
void __iomem *base = q->iobase;
@ -501,50 +506,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
}
/*
@@ -681,19 +860,36 @@ static void fsl_qspi_init_abh_read(struc
{
void __iomem *base = q->iobase;
int seqid;
+ const struct fsl_qspi_devtype_data *devtype_data = q->devtype_data;
/* AHB configuration for access buffer 0/1/2 .*/
qspi_writel(q, QUADSPI_BUFXCR_INVALID_MSTRID, base + QUADSPI_BUF0CR);
qspi_writel(q, QUADSPI_BUFXCR_INVALID_MSTRID, base + QUADSPI_BUF1CR);
qspi_writel(q, QUADSPI_BUFXCR_INVALID_MSTRID, base + QUADSPI_BUF2CR);
+
/*
- * Set ADATSZ with the maximum AHB buffer size to improve the
- * read performance.
+ * Errata: A-009282: QuadSPI data prefetch may result in incorrect data
+ * Workaround: Keep the read data size to 64 bits (8 bytes).
+ * This disables the prefetch on the AHB buffer and
+ * prevents this issue from occurring.
*/
- qspi_writel(q, QUADSPI_BUF3CR_ALLMST_MASK |
- ((q->devtype_data->ahb_buf_size / 8)
- << QUADSPI_BUF3CR_ADATSZ_SHIFT),
- base + QUADSPI_BUF3CR);
+ if (devtype_data->devtype == FSL_QUADSPI_LS2080A ||
+ devtype_data->devtype == FSL_QUADSPI_LS1021A) {
+
+ qspi_writel(q, QUADSPI_BUF3CR_ALLMST_MASK |
+ (1 << QUADSPI_BUF3CR_ADATSZ_SHIFT),
+ base + QUADSPI_BUF3CR);
+
+ } else {
+ /*
+ * Set ADATSZ with the maximum AHB buffer size to improve the
+ * read performance.
+ */
+ qspi_writel(q, QUADSPI_BUF3CR_ALLMST_MASK |
+ ((q->devtype_data->ahb_buf_size / 8)
+ << QUADSPI_BUF3CR_ADATSZ_SHIFT),
+ base + QUADSPI_BUF3CR);
+ }
/* We only use the buffer3 */
qspi_writel(q, 0, base + QUADSPI_BUF0IND);
@@ -704,6 +900,11 @@ static void fsl_qspi_init_abh_read(struc
@@ -704,6 +883,11 @@ static void fsl_qspi_init_abh_read(struct fsl_qspi *q)
seqid = fsl_qspi_get_seqid(q, q->nor[0].read_opcode);
qspi_writel(q, seqid << QUADSPI_BFGENCR_SEQID_SHIFT,
q->iobase + QUADSPI_BFGENCR);
@ -556,7 +518,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
}
/* This function was used to prepare and enable QSPI clock */
@@ -822,6 +1023,7 @@ static const struct of_device_id fsl_qsp
@@ -822,6 +1006,7 @@ static const struct of_device_id fsl_qspi_dt_ids[] = {
{ .compatible = "fsl,imx7d-qspi", .data = (void *)&imx7d_data, },
{ .compatible = "fsl,imx6ul-qspi", .data = (void *)&imx6ul_data, },
{ .compatible = "fsl,ls1021a-qspi", .data = (void *)&ls1021a_data, },
@ -564,21 +526,21 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, fsl_qspi_dt_ids);
@@ -835,8 +1037,12 @@ static int fsl_qspi_read_reg(struct spi_
@@ -835,8 +1020,12 @@ static int fsl_qspi_read_reg(struct spi_nor *nor, u8 opcode, u8 *buf, int len)
{
int ret;
struct fsl_qspi *q = nor->priv;
+ u32 to = 0;
+
+ if (opcode == SPINOR_OP_SPANSION_RDAR)
+ u8tou32(&to, nor->cmd_buf, 4);
- ret = fsl_qspi_runcmd(q, opcode, 0, len);
+ if (opcode == SPINOR_OP_SPANSION_RDAR)
+ u8tou32(&to, nor->cmd_buf, 4);
+
+ ret = fsl_qspi_runcmd(q, opcode, to, len);
if (ret)
return ret;
@@ -848,9 +1054,13 @@ static int fsl_qspi_write_reg(struct spi
@@ -848,9 +1037,13 @@ static int fsl_qspi_write_reg(struct spi_nor *nor, u8 opcode, u8 *buf, int len)
{
struct fsl_qspi *q = nor->priv;
int ret;
@ -593,7 +555,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
if (ret)
return ret;
@@ -859,7 +1069,7 @@ static int fsl_qspi_write_reg(struct spi
@@ -859,7 +1052,7 @@ static int fsl_qspi_write_reg(struct spi_nor *nor, u8 opcode, u8 *buf, int len)
} else if (len > 0) {
ret = fsl_qspi_nor_write(q, nor, opcode, 0,
@ -602,7 +564,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
if (ret > 0)
return 0;
} else {
@@ -875,7 +1085,7 @@ static ssize_t fsl_qspi_write(struct spi
@@ -875,7 +1068,7 @@ static ssize_t fsl_qspi_write(struct spi_nor *nor, loff_t to,
{
struct fsl_qspi *q = nor->priv;
ssize_t ret = fsl_qspi_nor_write(q, nor, nor->program_opcode, to,
@ -611,7 +573,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
/* invalid the data in the AHB buffer. */
fsl_qspi_invalid(q);
@@ -922,7 +1132,7 @@ static ssize_t fsl_qspi_read(struct spi_
@@ -922,7 +1115,7 @@ static ssize_t fsl_qspi_read(struct spi_nor *nor, loff_t from,
len);
/* Read out the data directly from the AHB buffer.*/
@ -620,7 +582,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
len);
return len;
@@ -980,6 +1190,8 @@ static int fsl_qspi_probe(struct platfor
@@ -980,6 +1173,8 @@ static int fsl_qspi_probe(struct platform_device *pdev)
struct spi_nor *nor;
struct mtd_info *mtd;
int ret, i = 0;
@ -629,7 +591,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
q = devm_kzalloc(dev, sizeof(*q), GFP_KERNEL);
if (!q)
@@ -1027,6 +1239,12 @@ static int fsl_qspi_probe(struct platfor
@@ -1027,6 +1222,12 @@ static int fsl_qspi_probe(struct platform_device *pdev)
goto clk_failed;
}
@ -642,7 +604,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
/* find the irq */
ret = platform_get_irq(pdev, 0);
if (ret < 0) {
@@ -1050,6 +1268,7 @@ static int fsl_qspi_probe(struct platfor
@@ -1050,6 +1251,7 @@ static int fsl_qspi_probe(struct platform_device *pdev)
mutex_init(&q->lock);
@ -650,7 +612,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
/* iterate the subnodes. */
for_each_available_child_of_node(dev->of_node, np) {
/* skip the holes */
@@ -1076,18 +1295,25 @@ static int fsl_qspi_probe(struct platfor
@@ -1076,18 +1278,25 @@ static int fsl_qspi_probe(struct platform_device *pdev)
ret = of_property_read_u32(np, "spi-max-frequency",
&q->clk_rate);
if (ret < 0)
@ -680,7 +642,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
/* Set the correct NOR size now. */
if (q->nor_size == 0) {
@@ -1110,8 +1336,12 @@ static int fsl_qspi_probe(struct platfor
@@ -1110,8 +1319,12 @@ static int fsl_qspi_probe(struct platform_device *pdev)
nor->page_size = q->devtype_data->txfifo;
i++;
@ -693,6 +655,8 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
/* finish the rest init. */
ret = fsl_qspi_nor_setup_last(q);
if (ret)
diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index 793d321d..190e0e45 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -40,6 +40,13 @@
@ -740,7 +704,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
*/
static int read_cr(struct spi_nor *nor)
{
@@ -160,6 +170,8 @@ static inline int spi_nor_read_dummy_cyc
@@ -160,6 +170,8 @@ static inline int spi_nor_read_dummy_cycles(struct spi_nor *nor)
case SPI_NOR_DUAL:
case SPI_NOR_QUAD:
return 8;
@ -749,7 +713,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
case SPI_NOR_NORMAL:
return 0;
}
@@ -961,6 +973,8 @@ static const struct flash_info spi_nor_i
@@ -961,6 +973,8 @@ static const struct flash_info spi_nor_ids[] = {
/* ESMT */
{ "f25l32pa", INFO(0x8c2016, 0, 64 * 1024, 64, SECT_4K | SPI_NOR_HAS_LOCK) },
@ -758,7 +722,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
/* Everspin */
{ "mr25h256", CAT25_INFO( 32 * 1024, 1, 256, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
@@ -1014,12 +1028,15 @@ static const struct flash_info spi_nor_i
@@ -1014,12 +1028,15 @@ static const struct flash_info spi_nor_ids[] = {
{ "mx25l3205d", INFO(0xc22016, 0, 64 * 1024, 64, SECT_4K) },
{ "mx25l3255e", INFO(0xc29e16, 0, 64 * 1024, 64, SECT_4K) },
{ "mx25l6405d", INFO(0xc22017, 0, 64 * 1024, 128, SECT_4K) },
@ -775,7 +739,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
{ "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) },
{ "mx66l51235l", INFO(0xc2201a, 0, 64 * 1024, 1024, SPI_NOR_QUAD_READ) },
{ "mx66l1g55g", INFO(0xc2261b, 0, 64 * 1024, 2048, SPI_NOR_QUAD_READ) },
@@ -1033,10 +1050,11 @@ static const struct flash_info spi_nor_i
@@ -1033,10 +1050,11 @@ static const struct flash_info spi_nor_ids[] = {
{ "n25q128a11", INFO(0x20bb18, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_QUAD_READ) },
{ "n25q128a13", INFO(0x20ba18, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_QUAD_READ) },
{ "n25q256a", INFO(0x20ba19, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_QUAD_READ) },
@ -789,7 +753,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
/* PMC */
{ "pm25lv512", INFO(0, 0, 32 * 1024, 2, SECT_4K_PMC) },
@@ -1054,8 +1072,11 @@ static const struct flash_info spi_nor_i
@@ -1054,8 +1072,11 @@ static const struct flash_info spi_nor_ids[] = {
{ "s70fl01gs", INFO(0x010221, 0x4d00, 256 * 1024, 256, 0) },
{ "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024, 64, 0) },
{ "s25sl12801", INFO(0x012018, 0x0301, 64 * 1024, 256, 0) },
@ -802,7 +766,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
{ "s25fl129p1", INFO(0x012018, 0x4d01, 64 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
{ "s25sl004a", INFO(0x010212, 0, 64 * 1024, 8, 0) },
{ "s25sl008a", INFO(0x010213, 0, 64 * 1024, 16, 0) },
@@ -1130,6 +1151,9 @@ static const struct flash_info spi_nor_i
@@ -1130,6 +1151,9 @@ static const struct flash_info spi_nor_ids[] = {
{ "w25x80", INFO(0xef3014, 0, 64 * 1024, 16, SECT_4K) },
{ "w25x16", INFO(0xef3015, 0, 64 * 1024, 32, SECT_4K) },
{ "w25x32", INFO(0xef3016, 0, 64 * 1024, 64, SECT_4K) },
@ -812,7 +776,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
{ "w25q32", INFO(0xef4016, 0, 64 * 1024, 64, SECT_4K) },
{
"w25q32dw", INFO(0xef6016, 0, 64 * 1024, 64,
@@ -1192,6 +1216,53 @@ static const struct flash_info *spi_nor_
@@ -1192,6 +1216,53 @@ static const struct flash_info *spi_nor_read_id(struct spi_nor *nor)
id[0], id[1], id[2]);
return ERR_PTR(-ENODEV);
}
@ -866,7 +830,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
static int spi_nor_read(struct mtd_info *mtd, loff_t from, size_t len,
size_t *retlen, u_char *buf)
@@ -1411,7 +1482,7 @@ static int macronix_quad_enable(struct s
@@ -1411,7 +1482,7 @@ static int macronix_quad_enable(struct spi_nor *nor)
* Write status Register and configuration register with 2 bytes
* The first byte will be written to the status register, while the
* second byte will be written to the configuration register.
@ -875,7 +839,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
*/
static int write_sr_cr(struct spi_nor *nor, u16 val)
{
@@ -1459,6 +1530,24 @@ static int spansion_quad_enable(struct s
@@ -1459,6 +1530,24 @@ static int spansion_quad_enable(struct spi_nor *nor)
return 0;
}
@ -900,7 +864,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
static int set_quad_mode(struct spi_nor *nor, const struct flash_info *info)
{
int status;
@@ -1604,9 +1693,25 @@ int spi_nor_scan(struct spi_nor *nor, co
@@ -1604,9 +1693,25 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode)
write_sr(nor, 0);
spi_nor_wait_till_ready(nor);
}
@ -926,7 +890,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
mtd->priv = nor;
mtd->type = MTD_NORFLASH;
mtd->writesize = 1;
@@ -1639,6 +1744,8 @@ int spi_nor_scan(struct spi_nor *nor, co
@@ -1639,6 +1744,8 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode)
nor->flags |= SNOR_F_USE_FSR;
if (info->flags & SPI_NOR_HAS_TB)
nor->flags |= SNOR_F_HAS_SR_TB;
@ -935,7 +899,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
#ifdef CONFIG_MTD_SPI_NOR_USE_4K_SECTORS
/* prefer "small sector" erase if possible */
@@ -1676,9 +1783,15 @@ int spi_nor_scan(struct spi_nor *nor, co
@@ -1676,9 +1783,15 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode)
/* Some devices cannot do fast-read, no matter what DT tells us */
if (info->flags & SPI_NOR_NO_FR)
nor->flash_read = SPI_NOR_NORMAL;
@ -954,7 +918,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
ret = set_quad_mode(nor, info);
if (ret) {
dev_err(dev, "quad mode not supported\n");
@@ -1691,6 +1804,9 @@ int spi_nor_scan(struct spi_nor *nor, co
@@ -1691,6 +1804,9 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode)
/* Default commands */
switch (nor->flash_read) {
@ -964,6 +928,8 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
case SPI_NOR_QUAD:
nor->read_opcode = SPINOR_OP_READ_1_1_4;
break;
diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h
index f2a71803..5003ff64 100644
--- a/include/linux/mtd/spi-nor.h
+++ b/include/linux/mtd/spi-nor.h
@@ -31,10 +31,10 @@
@ -1028,3 +994,6 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
int (*prepare)(struct spi_nor *nor, enum spi_nor_ops ops);
void (*unprepare)(struct spi_nor *nor, enum spi_nor_ops ops);
--
2.14.1

View File

@ -1,4 +1,4 @@
From c4813da334b0c31e9c55eea015f1e898e84ff45b Mon Sep 17 00:00:00 2001
From 9e6e0a53b29190dbd86a39304b59c3028f5b36c2 Mon Sep 17 00:00:00 2001
From: Yangbo Lu <yangbo.lu@nxp.com>
Date: Mon, 25 Sep 2017 11:04:10 +0800
Subject: [PATCH] pci: support layerscape
@ -15,21 +15,23 @@ Signed-off-by: Mingkai Hu <mingkai.hu@nxp.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
---
drivers/irqchip/irq-ls-scfg-msi.c | 256 +++++++--
drivers/irqchip/irq-ls-scfg-msi.c | 257 +++++++--
drivers/pci/host/Makefile | 2 +-
drivers/pci/host/pci-layerscape-ep-debugfs.c | 758 +++++++++++++++++++++++++++
drivers/pci/host/pci-layerscape-ep.c | 309 +++++++++++
drivers/pci/host/pci-layerscape-ep.h | 115 ++++
drivers/pci/host/pci-layerscape.c | 37 +-
drivers/pci/host/pci-layerscape.c | 38 +-
drivers/pci/host/pcie-designware.c | 6 +
drivers/pci/host/pcie-designware.h | 1 +
drivers/pci/pcie/portdrv_core.c | 181 +++----
include/linux/pci.h | 1 +
10 files changed, 1518 insertions(+), 148 deletions(-)
10 files changed, 1520 insertions(+), 148 deletions(-)
create mode 100644 drivers/pci/host/pci-layerscape-ep-debugfs.c
create mode 100644 drivers/pci/host/pci-layerscape-ep.c
create mode 100644 drivers/pci/host/pci-layerscape-ep.h
diff --git a/drivers/irqchip/irq-ls-scfg-msi.c b/drivers/irqchip/irq-ls-scfg-msi.c
index 02cca74c..57e3d900 100644
--- a/drivers/irqchip/irq-ls-scfg-msi.c
+++ b/drivers/irqchip/irq-ls-scfg-msi.c
@@ -17,13 +17,32 @@
@ -82,7 +84,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
};
static struct irq_chip ls_scfg_msi_irq_chip = {
@@ -49,19 +71,56 @@ static struct msi_domain_info ls_scfg_ms
@@ -49,19 +71,56 @@ static struct msi_domain_info ls_scfg_msi_domain_info = {
.chip = &ls_scfg_msi_irq_chip,
};
@ -141,7 +143,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
}
static struct irq_chip ls_scfg_msi_parent_chip = {
@@ -81,8 +140,8 @@ static int ls_scfg_msi_domain_irq_alloc(
@@ -81,8 +140,8 @@ static int ls_scfg_msi_domain_irq_alloc(struct irq_domain *domain,
WARN_ON(nr_irqs != 1);
spin_lock(&msi_data->lock);
@ -152,7 +154,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
__set_bit(pos, msi_data->used);
else
err = -ENOSPC;
@@ -106,7 +165,7 @@ static void ls_scfg_msi_domain_irq_free(
@@ -106,7 +165,7 @@ static void ls_scfg_msi_domain_irq_free(struct irq_domain *domain,
int pos;
pos = d->hwirq;
@ -161,7 +163,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
pr_err("failed to teardown msi. Invalid hwirq %d\n", pos);
return;
}
@@ -123,15 +182,22 @@ static const struct irq_domain_ops ls_sc
@@ -123,15 +182,22 @@ static const struct irq_domain_ops ls_scfg_msi_domain_ops = {
static void ls_scfg_msi_irq_handler(struct irq_desc *desc)
{
@ -189,7 +191,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
if (virq)
generic_handle_irq(virq);
}
@@ -143,7 +209,7 @@ static int ls_scfg_msi_domains_init(stru
@@ -143,7 +209,7 @@ static int ls_scfg_msi_domains_init(struct ls_scfg_msi *msi_data)
{
/* Initialize MSI domain parent */
msi_data->parent = irq_domain_add_linear(NULL,
@ -198,7 +200,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
&ls_scfg_msi_domain_ops,
msi_data);
if (!msi_data->parent) {
@@ -164,16 +230,117 @@ static int ls_scfg_msi_domains_init(stru
@@ -164,16 +230,118 @@ static int ls_scfg_msi_domains_init(struct ls_scfg_msi *msi_data)
return 0;
}
@ -288,6 +290,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
+ { .compatible = "fsl,1s1021a-msi", .data = &ls1021_msi_cfg},
+ { .compatible = "fsl,1s1043a-msi", .data = &ls1021_msi_cfg},
+
+ { .compatible = "fsl,ls1012a-msi", .data = &ls1021_msi_cfg },
+ { .compatible = "fsl,ls1021a-msi", .data = &ls1021_msi_cfg },
+ { .compatible = "fsl,ls1043a-msi", .data = &ls1021_msi_cfg },
+ { .compatible = "fsl,ls1043a-v1.1-msi", .data = &ls1043_v1_1_msi_cfg },
@ -317,7 +320,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
msi_data->regs = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(msi_data->regs)) {
@@ -182,23 +349,48 @@ static int ls_scfg_msi_probe(struct plat
@@ -182,23 +350,48 @@ static int ls_scfg_msi_probe(struct platform_device *pdev)
}
msi_data->msiir_addr = res->start;
@ -376,7 +379,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
platform_set_drvdata(pdev, msi_data);
return 0;
@@ -207,8 +399,10 @@ static int ls_scfg_msi_probe(struct plat
@@ -207,8 +400,10 @@ static int ls_scfg_msi_probe(struct platform_device *pdev)
static int ls_scfg_msi_remove(struct platform_device *pdev)
{
struct ls_scfg_msi *msi_data = platform_get_drvdata(pdev);
@ -388,7 +391,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
irq_domain_remove(msi_data->msi_domain);
irq_domain_remove(msi_data->parent);
@@ -218,12 +412,6 @@ static int ls_scfg_msi_remove(struct pla
@@ -218,12 +413,6 @@ static int ls_scfg_msi_remove(struct platform_device *pdev)
return 0;
}
@ -401,9 +404,11 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
static struct platform_driver ls_scfg_msi_driver = {
.driver = {
.name = "ls-scfg-msi",
diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
index 084cb498..88e87704 100644
--- a/drivers/pci/host/Makefile
+++ b/drivers/pci/host/Makefile
@@ -17,7 +17,7 @@ obj-$(CONFIG_PCIE_XILINX) += pcie-xilinx
@@ -17,7 +17,7 @@ obj-$(CONFIG_PCIE_XILINX) += pcie-xilinx.o
obj-$(CONFIG_PCIE_XILINX_NWL) += pcie-xilinx-nwl.o
obj-$(CONFIG_PCI_XGENE) += pci-xgene.o
obj-$(CONFIG_PCI_XGENE_MSI) += pci-xgene-msi.o
@ -412,6 +417,9 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
obj-$(CONFIG_PCI_VERSATILE) += pci-versatile.o
obj-$(CONFIG_PCIE_IPROC) += pcie-iproc.o
obj-$(CONFIG_PCIE_IPROC_MSI) += pcie-iproc-msi.o
diff --git a/drivers/pci/host/pci-layerscape-ep-debugfs.c b/drivers/pci/host/pci-layerscape-ep-debugfs.c
new file mode 100644
index 00000000..5f4870ba
--- /dev/null
+++ b/drivers/pci/host/pci-layerscape-ep-debugfs.c
@@ -0,0 +1,758 @@
@ -1173,6 +1181,9 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
+MODULE_AUTHOR("Minghuan Lian <Minghuan.Lian@freescale.com>");
+MODULE_DESCRIPTION("Freescale Layerscape PCIe EP controller driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/pci/host/pci-layerscape-ep.c b/drivers/pci/host/pci-layerscape-ep.c
new file mode 100644
index 00000000..8f1cca6e
--- /dev/null
+++ b/drivers/pci/host/pci-layerscape-ep.c
@@ -0,0 +1,309 @@
@ -1485,6 +1496,9 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
+MODULE_AUTHOR("Minghuan Lian <Minghuan.Lian@freescale.com>");
+MODULE_DESCRIPTION("Freescale Layerscape PCIe EP driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/pci/host/pci-layerscape-ep.h b/drivers/pci/host/pci-layerscape-ep.h
new file mode 100644
index 00000000..990c0ff5
--- /dev/null
+++ b/drivers/pci/host/pci-layerscape-ep.h
@@ -0,0 +1,115 @@
@ -1603,6 +1617,8 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
+int ls_pcie_ep_dbgfs_remove(struct ls_pcie *pcie);
+
+#endif /* _PCIE_LAYERSCAPE_EP_H */
diff --git a/drivers/pci/host/pci-layerscape.c b/drivers/pci/host/pci-layerscape.c
index 65370799..7ce32ff0 100644
--- a/drivers/pci/host/pci-layerscape.c
+++ b/drivers/pci/host/pci-layerscape.c
@@ -35,12 +35,14 @@
@ -1622,7 +1638,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
struct pcie_host_ops *ops;
};
@@ -86,6 +88,14 @@ static void ls_pcie_drop_msg_tlp(struct
@@ -86,6 +88,14 @@ static void ls_pcie_drop_msg_tlp(struct ls_pcie *pcie)
iowrite32(val, pcie->pp.dbi_base + PCIE_STRFMR1);
}
@ -1637,7 +1653,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
static int ls1021_pcie_link_up(struct pcie_port *pp)
{
u32 state;
@@ -134,7 +144,7 @@ static int ls_pcie_link_up(struct pcie_p
@@ -134,7 +144,7 @@ static int ls_pcie_link_up(struct pcie_port *pp)
struct ls_pcie *pcie = to_ls_pcie(pp);
u32 state;
@ -1646,7 +1662,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
pcie->drvdata->ltssm_shift) &
LTSSM_STATE_MASK;
@@ -153,6 +163,9 @@ static void ls_pcie_host_init(struct pci
@@ -153,6 +163,9 @@ static void ls_pcie_host_init(struct pcie_port *pp)
ls_pcie_clear_multifunction(pcie);
ls_pcie_drop_msg_tlp(pcie);
iowrite32(0, pcie->pp.dbi_base + PCIE_DBI_RO_WR_EN);
@ -1656,7 +1672,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
}
static int ls_pcie_msi_host_init(struct pcie_port *pp,
@@ -196,20 +209,38 @@ static struct ls_pcie_drvdata ls1021_drv
@@ -196,20 +209,39 @@ static struct ls_pcie_drvdata ls1021_drvdata = {
static struct ls_pcie_drvdata ls1043_drvdata = {
.lut_offset = 0x10000,
.ltssm_shift = 24,
@ -1686,6 +1702,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
};
static const struct of_device_id ls_pcie_of_match[] = {
+ { .compatible = "fsl,ls1012a-pcie", .data = &ls1046_drvdata },
{ .compatible = "fsl,ls1021a-pcie", .data = &ls1021_drvdata },
{ .compatible = "fsl,ls1043a-pcie", .data = &ls1043_drvdata },
+ { .compatible = "fsl,ls1046a-pcie", .data = &ls1046_drvdata },
@ -1695,9 +1712,11 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
{ },
};
diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c
index af8f6e92..2358e049 100644
--- a/drivers/pci/host/pcie-designware.c
+++ b/drivers/pci/host/pcie-designware.c
@@ -478,6 +478,12 @@ int dw_pcie_wait_for_link(struct pcie_po
@@ -478,6 +478,12 @@ int dw_pcie_wait_for_link(struct pcie_port *pp)
return -ETIMEDOUT;
}
@ -1710,18 +1729,22 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
int dw_pcie_link_up(struct pcie_port *pp)
{
u32 val;
diff --git a/drivers/pci/host/pcie-designware.h b/drivers/pci/host/pcie-designware.h
index a567ea28..4e6672b2 100644
--- a/drivers/pci/host/pcie-designware.h
+++ b/drivers/pci/host/pcie-designware.h
@@ -82,5 +82,6 @@ int dw_pcie_wait_for_link(struct pcie_po
@@ -82,5 +82,6 @@ int dw_pcie_wait_for_link(struct pcie_port *pp);
int dw_pcie_link_up(struct pcie_port *pp);
void dw_pcie_setup_rc(struct pcie_port *pp);
int dw_pcie_host_init(struct pcie_port *pp);
+void dw_pcie_disable_outbound_atu(struct pcie_port *pp, int index);
#endif /* _PCIE_DESIGNWARE_H */
diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c
index e9270b40..1bad877a 100644
--- a/drivers/pci/pcie/portdrv_core.c
+++ b/drivers/pci/pcie/portdrv_core.c
@@ -44,52 +44,30 @@ static void release_pcie_device(struct d
@@ -44,52 +44,30 @@ static void release_pcie_device(struct device *dev)
}
/**
@ -1785,7 +1808,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
/*
* Allocate as many entries as the port wants, so that we can check
@@ -97,20 +75,13 @@ static int pcie_port_enable_msix(struct
@@ -97,20 +75,13 @@ static int pcie_port_enable_msix(struct pci_dev *dev, int *vectors, int mask)
* equal to the number of entries this port actually uses, we'll happily
* go through without any tricks.
*/
@ -1811,7 +1834,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
/*
* The code below follows the PCI Express Base Specification 2.0
@@ -125,18 +96,16 @@ static int pcie_port_enable_msix(struct
@@ -125,18 +96,16 @@ static int pcie_port_enable_msix(struct pci_dev *dev, int *vectors, int mask)
pcie_capability_read_word(dev, PCI_EXP_FLAGS, &reg16);
entry = (reg16 & PCI_EXP_FLAGS_IRQ) >> 9;
if (entry >= nr_entries)
@ -1835,7 +1858,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
/*
* The code below follows Section 7.10.10 of the PCI Express
@@ -151,13 +120,11 @@ static int pcie_port_enable_msix(struct
@@ -151,13 +120,11 @@ static int pcie_port_enable_msix(struct pci_dev *dev, int *vectors, int mask)
pci_read_config_dword(dev, pos + PCI_ERR_ROOT_STATUS, &reg32);
entry = reg32 >> 27;
if (entry >= nr_entries)
@ -1852,7 +1875,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
}
/*
@@ -165,41 +132,54 @@ static int pcie_port_enable_msix(struct
@@ -165,41 +132,54 @@ static int pcie_port_enable_msix(struct pci_dev *dev, int *vectors, int mask)
* what we have. Otherwise, the port has some extra entries not for the
* services we know and we need to work around that.
*/
@ -1926,7 +1949,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
/*
* If MSI cannot be used for PCIe PME or hotplug, we have to use
@@ -207,41 +187,25 @@ static int init_service_irqs(struct pci_
@@ -207,41 +187,25 @@ static int init_service_irqs(struct pci_dev *dev, int *irqs, int mask)
*/
if (((mask & PCIE_PORT_SERVICE_PME) && pcie_pme_no_msi()) ||
((mask & PCIE_PORT_SERVICE_HP) && pciehp_no_msi())) {
@ -1980,7 +2003,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
/**
* get_port_device_capability - discover capabilities of a PCI Express port
* @dev: PCI Express port to examine
@@ -378,7 +342,7 @@ int pcie_port_device_register(struct pci
@@ -378,7 +342,7 @@ int pcie_port_device_register(struct pci_dev *dev)
* that can be used in the absence of irqs. Allow them to determine
* if that is to be used.
*/
@ -1989,7 +2012,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
if (status) {
capabilities &= PCIE_PORT_SERVICE_VC | PCIE_PORT_SERVICE_HP;
if (!capabilities)
@@ -401,7 +365,7 @@ int pcie_port_device_register(struct pci
@@ -401,7 +365,7 @@ int pcie_port_device_register(struct pci_dev *dev)
return 0;
error_cleanup_irqs:
@ -1998,7 +2021,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
error_disable:
pci_disable_device(dev);
return status;
@@ -469,7 +433,7 @@ static int remove_iter(struct device *de
@@ -469,7 +433,7 @@ static int remove_iter(struct device *dev, void *data)
void pcie_port_device_remove(struct pci_dev *dev)
{
device_for_each_child(&dev->dev, NULL, remove_iter);
@ -2007,7 +2030,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
pci_disable_device(dev);
}
@@ -499,7 +463,6 @@ static int pcie_port_probe_service(struc
@@ -499,7 +463,6 @@ static int pcie_port_probe_service(struct device *dev)
if (status)
return status;
@ -2015,7 +2038,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
get_device(dev);
return 0;
}
@@ -524,8 +487,6 @@ static int pcie_port_remove_service(stru
@@ -524,8 +487,6 @@ static int pcie_port_remove_service(struct device *dev)
pciedev = to_pcie_device(dev);
driver = to_service_driver(dev->driver);
if (driver && driver->remove) {
@ -2024,9 +2047,11 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
driver->remove(pciedev);
put_device(dev);
}
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 1b711796..6738d816 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1823,6 +1823,7 @@ void pcibios_release_device(struct pci_d
@@ -1823,6 +1823,7 @@ void pcibios_release_device(struct pci_dev *dev);
void pcibios_penalize_isa_irq(int irq, int active);
int pcibios_alloc_irq(struct pci_dev *dev);
void pcibios_free_irq(struct pci_dev *dev);
@ -2034,3 +2059,6 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
#ifdef CONFIG_HIBERNATE_CALLBACKS
extern struct dev_pm_ops pcibios_pm_ops;
--
2.14.1

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
From 659603c5f6cbc3d39922d4374df25ae4627d0e88 Mon Sep 17 00:00:00 2001
From 854c1f0e9574e9b25a55b439608c71e013b34a56 Mon Sep 17 00:00:00 2001
From: Yangbo Lu <yangbo.lu@nxp.com>
Date: Mon, 25 Sep 2017 12:12:20 +0800
Subject: [PATCH] dma: support layerscape
@ -8,8 +8,9 @@ This is a integrated patch for layerscape dma support.
Signed-off-by: jiaheng.fan <jiaheng.fan@nxp.com>
Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
---
drivers/dma/Kconfig | 14 +
drivers/dma/Makefile | 2 +
drivers/dma/Kconfig | 31 +
drivers/dma/Makefile | 3 +
drivers/dma/caam_dma.c | 563 +++++++++++++++
drivers/dma/dpaa2-qdma/Kconfig | 8 +
drivers/dma/dpaa2-qdma/Makefile | 8 +
drivers/dma/dpaa2-qdma/dpaa2-qdma.c | 986 +++++++++++++++++++++++++
@ -18,7 +19,8 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
drivers/dma/dpaa2-qdma/fsl_dpdmai.h | 521 ++++++++++++++
drivers/dma/dpaa2-qdma/fsl_dpdmai_cmd.h | 222 ++++++
drivers/dma/fsl-qdma.c | 1201 +++++++++++++++++++++++++++++++
10 files changed, 3678 insertions(+)
11 files changed, 4259 insertions(+)
create mode 100644 drivers/dma/caam_dma.c
create mode 100644 drivers/dma/dpaa2-qdma/Kconfig
create mode 100644 drivers/dma/dpaa2-qdma/Makefile
create mode 100644 drivers/dma/dpaa2-qdma/dpaa2-qdma.c
@ -28,6 +30,8 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
create mode 100644 drivers/dma/dpaa2-qdma/fsl_dpdmai_cmd.h
create mode 100644 drivers/dma/fsl-qdma.c
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 141aefbe..8caaf091 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -192,6 +192,20 @@ config FSL_EDMA
@ -51,6 +55,32 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
config FSL_RAID
tristate "Freescale RAID engine Support"
depends on FSL_SOC && !ASYNC_TX_ENABLE_CHANNEL_SWITCH
@@ -564,6 +578,23 @@ config ZX_DMA
help
Support the DMA engine for ZTE ZX296702 platform devices.
+config CRYPTO_DEV_FSL_CAAM_DMA
+ tristate "CAAM DMA engine support"
+ depends on CRYPTO_DEV_FSL_CAAM_JR
+ default y
+ select DMA_ENGINE
+ select ASYNC_CORE
+ select ASYNC_TX_ENABLE_CHANNEL_SWITCH
+ help
+ Selecting this will offload the DMA operations for users of
+ the scatter gather memcopy API to the CAAM via job rings. The
+ CAAM is a hardware module that provides hardware acceleration to
+ cryptographic operations. It has a built-in DMA controller that can
+ be programmed to read/write cryptographic data. This module defines
+ a DMA driver that uses the DMA capabilities of the CAAM.
+
+ To compile this as a module, choose M here: the module
+ will be called caam_dma.
# driver files
source "drivers/dma/bestcomm/Kconfig"
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index e4dc9cac..a694da0e 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -29,6 +29,8 @@ obj-$(CONFIG_DW_DMAC_CORE) += dw/
@ -62,6 +92,586 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
obj-$(CONFIG_FSL_RAID) += fsl_raid.o
obj-$(CONFIG_HSU_DMA) += hsu/
obj-$(CONFIG_IMG_MDC_DMA) += img-mdc-dma.o
@@ -67,6 +69,7 @@ obj-$(CONFIG_TI_DMA_CROSSBAR) += ti-dma-crossbar.o
obj-$(CONFIG_TI_EDMA) += edma.o
obj-$(CONFIG_XGENE_DMA) += xgene-dma.o
obj-$(CONFIG_ZX_DMA) += zx296702_dma.o
+obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_DMA) += caam_dma.o
obj-y += qcom/
obj-y += xilinx/
diff --git a/drivers/dma/caam_dma.c b/drivers/dma/caam_dma.c
new file mode 100644
index 00000000..e430b320
--- /dev/null
+++ b/drivers/dma/caam_dma.c
@@ -0,0 +1,563 @@
+/*
+ * caam support for SG DMA
+ *
+ * Copyright 2016 Freescale Semiconductor, Inc
+ * Copyright 2017 NXP
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/interrupt.h>
+#include <linux/slab.h>
+#include <linux/debugfs.h>
+
+#include <linux/dmaengine.h>
+#include "dmaengine.h"
+
+#include "../crypto/caam/regs.h"
+#include "../crypto/caam/jr.h"
+#include "../crypto/caam/error.h"
+#include "../crypto/caam/intern.h"
+#include "../crypto/caam/desc_constr.h"
+#include "../crypto/caam/sg_sw_sec4.h"
+
+#define DESC_DMA_MEMCPY_LEN ((CAAM_DESC_BYTES_MAX - DESC_JOB_IO_LEN) / \
+ CAAM_CMD_SZ)
+
+/* This is max chunk size of a DMA transfer. If a buffer is larger than this
+ * value it is internally broken into chunks of max CAAM_DMA_CHUNK_SIZE bytes
+ * and for each chunk a DMA transfer request is issued.
+ * This value is the largest number on 16 bits that is a multiple of 256 bytes
+ * (the largest configurable CAAM DMA burst size).
+ */
+#define CAAM_DMA_CHUNK_SIZE 65280
+
+struct caam_dma_sh_desc {
+ u32 desc[DESC_DMA_MEMCPY_LEN] ____cacheline_aligned;
+ dma_addr_t desc_dma;
+};
+
+/* caam dma extended descriptor */
+struct caam_dma_edesc {
+ struct dma_async_tx_descriptor async_tx;
+ struct list_head node;
+ struct caam_dma_ctx *ctx;
+ dma_addr_t src_dma;
+ dma_addr_t dst_dma;
+ unsigned int src_len;
+ unsigned int dst_len;
+ struct sec4_sg_entry *sec4_sg;
+ u32 jd[] ____cacheline_aligned;
+};
+
+/*
+ * caam_dma_ctx - per jr/channel context
+ * @chan: dma channel used by async_tx API
+ * @node: list_head used to attach to the global dma_ctx_list
+ * @jrdev: Job Ring device
+ * @submit_q: queue of pending (submitted, but not enqueued) jobs
+ * @done_not_acked: jobs that have been completed by jr, but maybe not acked
+ * @edesc_lock: protects extended descriptor
+ */
+struct caam_dma_ctx {
+ struct dma_chan chan;
+ struct list_head node;
+ struct device *jrdev;
+ struct list_head submit_q;
+ struct list_head done_not_acked;
+ spinlock_t edesc_lock;
+};
+
+static struct dma_device *dma_dev;
+static struct caam_dma_sh_desc *dma_sh_desc;
+static LIST_HEAD(dma_ctx_list);
+
+static dma_cookie_t caam_dma_tx_submit(struct dma_async_tx_descriptor *tx)
+{
+ struct caam_dma_edesc *edesc = NULL;
+ struct caam_dma_ctx *ctx = NULL;
+ dma_cookie_t cookie;
+
+ edesc = container_of(tx, struct caam_dma_edesc, async_tx);
+ ctx = container_of(tx->chan, struct caam_dma_ctx, chan);
+
+ spin_lock_bh(&ctx->edesc_lock);
+
+ cookie = dma_cookie_assign(tx);
+ list_add_tail(&edesc->node, &ctx->submit_q);
+
+ spin_unlock_bh(&ctx->edesc_lock);
+
+ return cookie;
+}
+
+static unsigned int caam_dma_sg_dma_len(struct scatterlist *sg,
+ unsigned int nents)
+{
+ unsigned int len;
+
+ for (len = 0; sg && nents; sg = sg_next(sg), nents--)
+ len += sg_dma_len(sg);
+
+ return len;
+}
+
+static struct caam_dma_edesc *
+caam_dma_sg_edesc_alloc(struct dma_chan *chan,
+ struct scatterlist *dst_sg, unsigned int dst_nents,
+ struct scatterlist *src_sg, unsigned int src_nents,
+ unsigned long flags)
+{
+ struct caam_dma_ctx *ctx = container_of(chan, struct caam_dma_ctx,
+ chan);
+ struct device *jrdev = ctx->jrdev;
+ struct caam_dma_edesc *edesc;
+ struct sec4_sg_entry *sec4_sg;
+ dma_addr_t sec4_sg_dma_src;
+ unsigned int sec4_sg_bytes;
+
+ if (!dst_sg || !src_sg || !dst_nents || !src_nents)
+ return NULL;
+
+ sec4_sg_bytes = (src_nents + dst_nents) * sizeof(*sec4_sg);
+
+ edesc = kzalloc(sizeof(*edesc) + DESC_JOB_IO_LEN + sec4_sg_bytes,
+ GFP_DMA | GFP_NOWAIT);
+ if (!edesc)
+ return ERR_PTR(-ENOMEM);
+
+ edesc->src_len = caam_dma_sg_dma_len(src_sg, src_nents);
+ edesc->dst_len = caam_dma_sg_dma_len(dst_sg, dst_nents);
+ if (edesc->src_len != edesc->dst_len) {
+ dev_err(jrdev, "%s: src(%u) and dst(%u) len mismatch.\n",
+ __func__, edesc->src_len, edesc->dst_len);
+ kfree(edesc);
+ return ERR_PTR(-EINVAL);
+ }
+
+ dma_async_tx_descriptor_init(&edesc->async_tx, chan);
+ edesc->async_tx.tx_submit = caam_dma_tx_submit;
+ edesc->async_tx.flags = flags;
+ edesc->async_tx.cookie = -EBUSY;
+
+ /* Prepare SEC SGs */
+ edesc->sec4_sg = (void *)edesc + offsetof(struct caam_dma_edesc, jd) +
+ DESC_JOB_IO_LEN;
+
+ sec4_sg = edesc->sec4_sg;
+ sg_to_sec4_sg_last(src_sg, src_nents, sec4_sg, 0);
+
+ sec4_sg += src_nents;
+ sg_to_sec4_sg_last(dst_sg, dst_nents, sec4_sg, 0);
+
+ sec4_sg_dma_src = dma_map_single(jrdev, edesc->sec4_sg, sec4_sg_bytes,
+ DMA_TO_DEVICE);
+ if (dma_mapping_error(jrdev, sec4_sg_dma_src)) {
+ dev_err(jrdev, "error mapping segments to device\n");
+ kfree(edesc);
+ return ERR_PTR(-ENOMEM);
+ }
+
+ edesc->src_dma = sec4_sg_dma_src;
+ edesc->dst_dma = sec4_sg_dma_src + src_nents * sizeof(*sec4_sg);
+ edesc->ctx = ctx;
+
+ return edesc;
+}
+
+static void caam_jr_chan_free_edesc(struct caam_dma_edesc *edesc)
+{
+ struct caam_dma_ctx *ctx = edesc->ctx;
+ struct caam_dma_edesc *_edesc = NULL;
+
+ spin_lock_bh(&ctx->edesc_lock);
+
+ list_add_tail(&edesc->node, &ctx->done_not_acked);
+ list_for_each_entry_safe(edesc, _edesc, &ctx->done_not_acked, node) {
+ if (async_tx_test_ack(&edesc->async_tx)) {
+ list_del(&edesc->node);
+ kfree(edesc);
+ }
+ }
+
+ spin_unlock_bh(&ctx->edesc_lock);
+}
+
+static void caam_dma_done(struct device *dev, u32 *hwdesc, u32 err,
+ void *context)
+{
+ struct caam_dma_edesc *edesc = context;
+ struct caam_dma_ctx *ctx = edesc->ctx;
+ dma_async_tx_callback callback;
+ void *callback_param;
+
+ if (err)
+ caam_jr_strstatus(ctx->jrdev, err);
+
+ dma_run_dependencies(&edesc->async_tx);
+
+ spin_lock_bh(&ctx->edesc_lock);
+ dma_cookie_complete(&edesc->async_tx);
+ spin_unlock_bh(&ctx->edesc_lock);
+
+ callback = edesc->async_tx.callback;
+ callback_param = edesc->async_tx.callback_param;
+
+ dma_descriptor_unmap(&edesc->async_tx);
+
+ caam_jr_chan_free_edesc(edesc);
+
+ if (callback)
+ callback(callback_param);
+}
+
+static void caam_dma_sg_init_job_desc(struct caam_dma_edesc *edesc)
+{
+ u32 *jd = edesc->jd;
+ u32 *sh_desc = dma_sh_desc->desc;
+ dma_addr_t desc_dma = dma_sh_desc->desc_dma;
+
+ /* init the job descriptor */
+ init_job_desc_shared(jd, desc_dma, desc_len(sh_desc), HDR_REVERSE);
+
+ /* set SEQIN PTR */
+ append_seq_in_ptr(jd, edesc->src_dma, edesc->src_len, LDST_SGF);
+
+ /* set SEQOUT PTR */
+ append_seq_out_ptr(jd, edesc->dst_dma, edesc->dst_len, LDST_SGF);
+
+#ifdef DEBUG
+ print_hex_dump(KERN_ERR, "caam dma desc@" __stringify(__LINE__) ": ",
+ DUMP_PREFIX_ADDRESS, 16, 4, jd, desc_bytes(jd), 1);
+#endif
+}
+
+/* This function can be called from an interrupt context */
+static struct dma_async_tx_descriptor *
+caam_dma_prep_sg(struct dma_chan *chan, struct scatterlist *dst_sg,
+ unsigned int dst_nents, struct scatterlist *src_sg,
+ unsigned int src_nents, unsigned long flags)
+{
+ struct caam_dma_edesc *edesc;
+
+ /* allocate extended descriptor */
+ edesc = caam_dma_sg_edesc_alloc(chan, dst_sg, dst_nents, src_sg,
+ src_nents, flags);
+ if (IS_ERR_OR_NULL(edesc))
+ return ERR_CAST(edesc);
+
+ /* Initialize job descriptor */
+ caam_dma_sg_init_job_desc(edesc);
+
+ return &edesc->async_tx;
+}
+
+static void caam_dma_memcpy_init_job_desc(struct caam_dma_edesc *edesc)
+{
+ u32 *jd = edesc->jd;
+ u32 *sh_desc = dma_sh_desc->desc;
+ dma_addr_t desc_dma = dma_sh_desc->desc_dma;
+
+ /* init the job descriptor */
+ init_job_desc_shared(jd, desc_dma, desc_len(sh_desc), HDR_REVERSE);
+
+ /* set SEQIN PTR */
+ append_seq_in_ptr(jd, edesc->src_dma, edesc->src_len, 0);
+
+ /* set SEQOUT PTR */
+ append_seq_out_ptr(jd, edesc->dst_dma, edesc->dst_len, 0);
+
+#ifdef DEBUG
+ print_hex_dump(KERN_ERR, "caam dma desc@" __stringify(__LINE__) ": ",
+ DUMP_PREFIX_ADDRESS, 16, 4, jd, desc_bytes(jd), 1);
+#endif
+}
+
+static struct dma_async_tx_descriptor *
+caam_dma_prep_memcpy(struct dma_chan *chan, dma_addr_t dst, dma_addr_t src,
+ size_t len, unsigned long flags)
+{
+ struct caam_dma_edesc *edesc;
+ struct caam_dma_ctx *ctx = container_of(chan, struct caam_dma_ctx,
+ chan);
+
+ edesc = kzalloc(sizeof(*edesc) + DESC_JOB_IO_LEN, GFP_DMA | GFP_NOWAIT);
+ if (!edesc)
+ return ERR_PTR(-ENOMEM);
+
+ dma_async_tx_descriptor_init(&edesc->async_tx, chan);
+ edesc->async_tx.tx_submit = caam_dma_tx_submit;
+ edesc->async_tx.flags = flags;
+ edesc->async_tx.cookie = -EBUSY;
+
+ edesc->src_dma = src;
+ edesc->src_len = len;
+ edesc->dst_dma = dst;
+ edesc->dst_len = len;
+ edesc->ctx = ctx;
+
+ caam_dma_memcpy_init_job_desc(edesc);
+
+ return &edesc->async_tx;
+}
+
+/* This function can be called in an interrupt context */
+static void caam_dma_issue_pending(struct dma_chan *chan)
+{
+ struct caam_dma_ctx *ctx = container_of(chan, struct caam_dma_ctx,
+ chan);
+ struct caam_dma_edesc *edesc, *_edesc;
+
+ spin_lock_bh(&ctx->edesc_lock);
+ list_for_each_entry_safe(edesc, _edesc, &ctx->submit_q, node) {
+ if (caam_jr_enqueue(ctx->jrdev, edesc->jd,
+ caam_dma_done, edesc) < 0)
+ break;
+ list_del(&edesc->node);
+ }
+ spin_unlock_bh(&ctx->edesc_lock);
+}
+
+static void caam_dma_free_chan_resources(struct dma_chan *chan)
+{
+ struct caam_dma_ctx *ctx = container_of(chan, struct caam_dma_ctx,
+ chan);
+ struct caam_dma_edesc *edesc, *_edesc;
+
+ spin_lock_bh(&ctx->edesc_lock);
+ list_for_each_entry_safe(edesc, _edesc, &ctx->submit_q, node) {
+ list_del(&edesc->node);
+ kfree(edesc);
+ }
+ list_for_each_entry_safe(edesc, _edesc, &ctx->done_not_acked, node) {
+ list_del(&edesc->node);
+ kfree(edesc);
+ }
+ spin_unlock_bh(&ctx->edesc_lock);
+}
+
+static int caam_dma_jr_chan_bind(void)
+{
+ struct device *jrdev;
+ struct caam_dma_ctx *ctx;
+ int bonds = 0;
+ int i;
+
+ for (i = 0; i < caam_jr_driver_probed(); i++) {
+ jrdev = caam_jridx_alloc(i);
+ if (IS_ERR(jrdev)) {
+ pr_err("job ring device %d allocation failed\n", i);
+ continue;
+ }
+
+ ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
+ if (!ctx) {
+ caam_jr_free(jrdev);
+ continue;
+ }
+
+ ctx->chan.device = dma_dev;
+ ctx->chan.private = ctx;
+
+ ctx->jrdev = jrdev;
+
+ INIT_LIST_HEAD(&ctx->submit_q);
+ INIT_LIST_HEAD(&ctx->done_not_acked);
+ INIT_LIST_HEAD(&ctx->node);
+ spin_lock_init(&ctx->edesc_lock);
+
+ dma_cookie_init(&ctx->chan);
+
+ /* add the context of this channel to the context list */
+ list_add_tail(&ctx->node, &dma_ctx_list);
+
+ /* add this channel to the device chan list */
+ list_add_tail(&ctx->chan.device_node, &dma_dev->channels);
+
+ bonds++;
+ }
+
+ return bonds;
+}
+
+static inline void caam_jr_dma_free(struct dma_chan *chan)
+{
+ struct caam_dma_ctx *ctx = container_of(chan, struct caam_dma_ctx,
+ chan);
+
+ list_del(&ctx->node);
+ list_del(&chan->device_node);
+ caam_jr_free(ctx->jrdev);
+ kfree(ctx);
+}
+
+static void set_caam_dma_desc(u32 *desc)
+{
+ u32 *jmp_cmd;
+
+ /* dma shared descriptor */
+ init_sh_desc(desc, HDR_SHARE_NEVER | (1 << HDR_START_IDX_SHIFT));
+
+ /* REG1 = CAAM_DMA_CHUNK_SIZE */
+ append_math_add_imm_u32(desc, REG1, ZERO, IMM, CAAM_DMA_CHUNK_SIZE);
+
+ /* REG0 = SEQINLEN - CAAM_DMA_CHUNK_SIZE */
+ append_math_sub_imm_u32(desc, REG0, SEQINLEN, IMM, CAAM_DMA_CHUNK_SIZE);
+
+ /* if (REG0 > 0)
+ * jmp to LABEL1
+ */
+ jmp_cmd = append_jump(desc, JUMP_TEST_INVALL | JUMP_COND_MATH_N |
+ JUMP_COND_MATH_Z);
+
+ /* REG1 = SEQINLEN */
+ append_math_sub(desc, REG1, SEQINLEN, ZERO, CAAM_CMD_SZ);
+
+ /* LABEL1 */
+ set_jump_tgt_here(desc, jmp_cmd);
+
+ /* VARSEQINLEN = REG1 */
+ append_math_add(desc, VARSEQINLEN, REG1, ZERO, CAAM_CMD_SZ);
+
+ /* VARSEQOUTLEN = REG1 */
+ append_math_add(desc, VARSEQOUTLEN, REG1, ZERO, CAAM_CMD_SZ);
+
+ /* do FIFO STORE */
+ append_seq_fifo_store(desc, 0, FIFOST_TYPE_METADATA | LDST_VLF);
+
+ /* do FIFO LOAD */
+ append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 |
+ FIFOLD_TYPE_IFIFO | LDST_VLF);
+
+ /* if (REG0 > 0)
+ * jmp 0xF8 (after shared desc header)
+ */
+ append_jump(desc, JUMP_TEST_INVALL | JUMP_COND_MATH_N |
+ JUMP_COND_MATH_Z | 0xF8);
+
+#ifdef DEBUG
+ print_hex_dump(KERN_ERR, "caam dma shdesc@" __stringify(__LINE__) ": ",
+ DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1);
+#endif
+}
+
+static int __init caam_dma_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct device *ctrldev = dev->parent;
+ struct dma_chan *chan, *_chan;
+ u32 *sh_desc;
+ int err = -ENOMEM;
+ int bonds;
+
+ if (!caam_jr_driver_probed()) {
+ dev_info(dev, "Defer probing after JR driver probing\n");
+ return -EPROBE_DEFER;
+ }
+
+ dma_dev = kzalloc(sizeof(*dma_dev), GFP_KERNEL);
+ if (!dma_dev)
+ return -ENOMEM;
+
+ dma_sh_desc = kzalloc(sizeof(*dma_sh_desc), GFP_KERNEL | GFP_DMA);
+ if (!dma_sh_desc)
+ goto desc_err;
+
+ sh_desc = dma_sh_desc->desc;
+ set_caam_dma_desc(sh_desc);
+ dma_sh_desc->desc_dma = dma_map_single(ctrldev, sh_desc,
+ desc_bytes(sh_desc),
+ DMA_TO_DEVICE);
+ if (dma_mapping_error(ctrldev, dma_sh_desc->desc_dma)) {
+ dev_err(dev, "unable to map dma descriptor\n");
+ goto map_err;
+ }
+
+ INIT_LIST_HEAD(&dma_dev->channels);
+
+ bonds = caam_dma_jr_chan_bind();
+ if (!bonds) {
+ err = -ENODEV;
+ goto jr_bind_err;
+ }
+
+ dma_dev->dev = dev;
+ dma_dev->residue_granularity = DMA_RESIDUE_GRANULARITY_DESCRIPTOR;
+ dma_cap_set(DMA_SG, dma_dev->cap_mask);
+ dma_cap_set(DMA_MEMCPY, dma_dev->cap_mask);
+ dma_cap_set(DMA_PRIVATE, dma_dev->cap_mask);
+ dma_dev->device_tx_status = dma_cookie_status;
+ dma_dev->device_issue_pending = caam_dma_issue_pending;
+ dma_dev->device_prep_dma_sg = caam_dma_prep_sg;
+ dma_dev->device_prep_dma_memcpy = caam_dma_prep_memcpy;
+ dma_dev->device_free_chan_resources = caam_dma_free_chan_resources;
+
+ err = dma_async_device_register(dma_dev);
+ if (err) {
+ dev_err(dev, "Failed to register CAAM DMA engine\n");
+ goto jr_bind_err;
+ }
+
+ dev_info(dev, "caam dma support with %d job rings\n", bonds);
+
+ return err;
+
+jr_bind_err:
+ list_for_each_entry_safe(chan, _chan, &dma_dev->channels, device_node)
+ caam_jr_dma_free(chan);
+
+ dma_unmap_single(ctrldev, dma_sh_desc->desc_dma, desc_bytes(sh_desc),
+ DMA_TO_DEVICE);
+map_err:
+ kfree(dma_sh_desc);
+desc_err:
+ kfree(dma_dev);
+ return err;
+}
+
+static int caam_dma_remove(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct device *ctrldev = dev->parent;
+ struct caam_dma_ctx *ctx, *_ctx;
+
+ dma_async_device_unregister(dma_dev);
+
+ list_for_each_entry_safe(ctx, _ctx, &dma_ctx_list, node) {
+ list_del(&ctx->node);
+ caam_jr_free(ctx->jrdev);
+ kfree(ctx);
+ }
+
+ dma_unmap_single(ctrldev, dma_sh_desc->desc_dma,
+ desc_bytes(dma_sh_desc->desc), DMA_TO_DEVICE);
+
+ kfree(dma_sh_desc);
+ kfree(dma_dev);
+
+ dev_info(dev, "caam dma support disabled\n");
+ return 0;
+}
+
+static const struct of_device_id caam_dma_match[] = {
+ { .compatible = "fsl,sec-v5.4-dma", },
+ { .compatible = "fsl,sec-v5.0-dma", },
+ { .compatible = "fsl,sec-v4.0-dma", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, caam_dma_match);
+
+static struct platform_driver caam_dma_driver = {
+ .driver = {
+ .name = "caam-dma",
+ .of_match_table = caam_dma_match,
+ },
+ .probe = caam_dma_probe,
+ .remove = caam_dma_remove,
+};
+module_platform_driver(caam_dma_driver);
+
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_DESCRIPTION("NXP CAAM support for SG DMA");
+MODULE_AUTHOR("NXP Semiconductors");
diff --git a/drivers/dma/dpaa2-qdma/Kconfig b/drivers/dma/dpaa2-qdma/Kconfig
new file mode 100644
index 00000000..084e34bf
--- /dev/null
+++ b/drivers/dma/dpaa2-qdma/Kconfig
@@ -0,0 +1,8 @@
@ -73,6 +683,9 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
+ ---help---
+ NXP Data Path Acceleration Architecture 2 QDMA driver,
+ using the NXP MC bus driver.
diff --git a/drivers/dma/dpaa2-qdma/Makefile b/drivers/dma/dpaa2-qdma/Makefile
new file mode 100644
index 00000000..ba599ac6
--- /dev/null
+++ b/drivers/dma/dpaa2-qdma/Makefile
@@ -0,0 +1,8 @@
@ -84,6 +697,9 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
+obj-$(CONFIG_FSL_DPAA2_QDMA) += fsl-dpaa2-qdma.o
+
+fsl-dpaa2-qdma-objs := dpaa2-qdma.o dpdmai.o
diff --git a/drivers/dma/dpaa2-qdma/dpaa2-qdma.c b/drivers/dma/dpaa2-qdma/dpaa2-qdma.c
new file mode 100644
index 00000000..ad6b03f7
--- /dev/null
+++ b/drivers/dma/dpaa2-qdma/dpaa2-qdma.c
@@ -0,0 +1,986 @@
@ -1073,6 +1689,9 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
+
+MODULE_DESCRIPTION("NXP DPAA2 qDMA driver");
+MODULE_LICENSE("Dual BSD/GPL");
diff --git a/drivers/dma/dpaa2-qdma/dpaa2-qdma.h b/drivers/dma/dpaa2-qdma/dpaa2-qdma.h
new file mode 100644
index 00000000..71a00db8
--- /dev/null
+++ b/drivers/dma/dpaa2-qdma/dpaa2-qdma.h
@@ -0,0 +1,262 @@
@ -1338,6 +1957,9 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
+#define SG_POOL_SIZE (sizeof(struct qdma_sg_blk) +\
+ sizeof(struct dpaa2_qdma_sg) * NUM_SG_PER_BLK)
+#endif /* __DPAA2_QDMA_H */
diff --git a/drivers/dma/dpaa2-qdma/dpdmai.c b/drivers/dma/dpaa2-qdma/dpdmai.c
new file mode 100644
index 00000000..ad13fc1e
--- /dev/null
+++ b/drivers/dma/dpaa2-qdma/dpdmai.c
@@ -0,0 +1,454 @@
@ -1795,6 +2417,9 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
+
+ return 0;
+}
diff --git a/drivers/dma/dpaa2-qdma/fsl_dpdmai.h b/drivers/dma/dpaa2-qdma/fsl_dpdmai.h
new file mode 100644
index 00000000..e931ce16
--- /dev/null
+++ b/drivers/dma/dpaa2-qdma/fsl_dpdmai.h
@@ -0,0 +1,521 @@
@ -2319,6 +2944,9 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
+ struct dpdmai_tx_queue_attr *attr);
+
+#endif /* __FSL_DPDMAI_H */
diff --git a/drivers/dma/dpaa2-qdma/fsl_dpdmai_cmd.h b/drivers/dma/dpaa2-qdma/fsl_dpdmai_cmd.h
new file mode 100644
index 00000000..7d403c01
--- /dev/null
+++ b/drivers/dma/dpaa2-qdma/fsl_dpdmai_cmd.h
@@ -0,0 +1,222 @@
@ -2544,6 +3172,9 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
+ MC_RSP_OP(cmd, 1, 0, 32, uint32_t, attr->fqid)
+
+#endif /* _FSL_DPDMAI_CMD_H */
diff --git a/drivers/dma/fsl-qdma.c b/drivers/dma/fsl-qdma.c
new file mode 100644
index 00000000..6c4c2813
--- /dev/null
+++ b/drivers/dma/fsl-qdma.c
@@ -0,0 +1,1201 @@
@ -3748,3 +4379,6 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
+MODULE_ALIAS("platform:fsl-qdma");
+MODULE_DESCRIPTION("Freescale qDMA engine driver");
+MODULE_LICENSE("GPL v2");
--
2.14.1

View File

@ -1,4 +1,4 @@
From a5b3155b532289af793c26251cb087b4a24d5c15 Mon Sep 17 00:00:00 2001
From 76cd2ef6b69b67c09480a3248f7b910897f0bb2f Mon Sep 17 00:00:00 2001
From: Yangbo Lu <yangbo.lu@nxp.com>
Date: Mon, 25 Sep 2017 12:13:12 +0800
Subject: [PATCH] flextimer: support layerscape
@ -10,13 +10,15 @@ Signed-off-by: Meng Yi <meng.yi@nxp.com>
Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
---
drivers/clocksource/fsl_ftm_timer.c | 8 +-
drivers/soc/fsl/layerscape/ftm_alarm.c | 286 +++++++++++++++++++++++++++++++++
2 files changed, 290 insertions(+), 4 deletions(-)
drivers/soc/fsl/layerscape/ftm_alarm.c | 367 +++++++++++++++++++++++++++++++++
2 files changed, 371 insertions(+), 4 deletions(-)
create mode 100644 drivers/soc/fsl/layerscape/ftm_alarm.c
diff --git a/drivers/clocksource/fsl_ftm_timer.c b/drivers/clocksource/fsl_ftm_timer.c
index 738515b8..770bbbca 100644
--- a/drivers/clocksource/fsl_ftm_timer.c
+++ b/drivers/clocksource/fsl_ftm_timer.c
@@ -83,11 +83,11 @@ static inline void ftm_counter_disable(v
@@ -83,11 +83,11 @@ static inline void ftm_counter_disable(void __iomem *base)
static inline void ftm_irq_acknowledge(void __iomem *base)
{
@ -32,9 +34,12 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
}
static inline void ftm_irq_enable(void __iomem *base)
diff --git a/drivers/soc/fsl/layerscape/ftm_alarm.c b/drivers/soc/fsl/layerscape/ftm_alarm.c
new file mode 100644
index 00000000..49865b0b
--- /dev/null
+++ b/drivers/soc/fsl/layerscape/ftm_alarm.c
@@ -0,0 +1,286 @@
@@ -0,0 +1,367 @@
+/*
+ * Freescale FlexTimer Module (FTM) Alarm driver.
+ *
@ -53,6 +58,10 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/libata.h>
+#include <linux/module.h>
+
+#define FTM_SC 0x00
+#define FTM_SC_CLK_SHIFT 3
@ -77,6 +86,57 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
+static u32 alarm_freq;
+static bool big_endian;
+
+enum pmu_endian_type {
+ BIG_ENDIAN,
+ LITTLE_ENDIAN,
+};
+
+struct rcpm_cfg {
+ enum pmu_endian_type big_endian; /* Big/Little endian of PMU module */
+ u32 flextimer_set_bit; /* FlexTimer1 is not powerdown during device LPM20 */
+};
+
+static struct rcpm_cfg ls1012a_rcpm_cfg = {
+ .big_endian = BIG_ENDIAN,
+ .flextimer_set_bit = 0x20000,
+};
+
+static struct rcpm_cfg ls1021a_rcpm_cfg = {
+ .big_endian = BIG_ENDIAN,
+ .flextimer_set_bit = 0x20000,
+};
+
+static struct rcpm_cfg ls1043a_rcpm_cfg = {
+ .big_endian = BIG_ENDIAN,
+ .flextimer_set_bit = 0x20000,
+};
+
+static struct rcpm_cfg ls1046a_rcpm_cfg = {
+ .big_endian = BIG_ENDIAN,
+ .flextimer_set_bit = 0x20000,
+};
+
+static struct rcpm_cfg ls1088a_rcpm_cfg = {
+ .big_endian = LITTLE_ENDIAN,
+ .flextimer_set_bit = 0x4000,
+};
+
+static struct rcpm_cfg ls208xa_rcpm_cfg = {
+ .big_endian = LITTLE_ENDIAN,
+ .flextimer_set_bit = 0x4000,
+};
+
+static const struct of_device_id ippdexpcr_of_match[] = {
+ { .compatible = "fsl,ls1012a-ftm", .data = &ls1012a_rcpm_cfg},
+ { .compatible = "fsl,ls1021a-ftm", .data = &ls1021a_rcpm_cfg},
+ { .compatible = "fsl,ls1043a-ftm", .data = &ls1043a_rcpm_cfg},
+ { .compatible = "fsl,ls1046a-ftm", .data = &ls1046a_rcpm_cfg},
+ { .compatible = "fsl,ls1088a-ftm", .data = &ls1088a_rcpm_cfg},
+ { .compatible = "fsl,ls208xa-ftm", .data = &ls208xa_rcpm_cfg},
+ {},
+};
+MODULE_DEVICE_TABLE(of, ippdexpcr_of_match);
+
+static inline u32 ftm_readl(void __iomem *addr)
+{
+ if (big_endian)
@ -251,7 +311,10 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
+ struct resource *r;
+ int irq;
+ int ret;
+ u32 ippdexpcr;
+ struct rcpm_cfg *rcpm_cfg;
+ u32 ippdexpcr, flextimer;
+ const struct of_device_id *of_id;
+ enum pmu_endian_type endian;
+
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!r)
@ -261,14 +324,32 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
+ if (IS_ERR(ftm1_base))
+ return PTR_ERR(ftm1_base);
+
+ of_id = of_match_node(ippdexpcr_of_match, np);
+ if (!of_id)
+ return -ENODEV;
+
+ rcpm_cfg = devm_kzalloc(&pdev->dev, sizeof(*rcpm_cfg), GFP_KERNEL);
+ if (!rcpm_cfg)
+ return -ENOMEM;
+
+ rcpm_cfg = (struct rcpm_cfg*)of_id->data;
+ endian = rcpm_cfg->big_endian;
+ flextimer = rcpm_cfg->flextimer_set_bit;
+
+ r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "FlexTimer1");
+ if (r) {
+ rcpm_ftm_addr = devm_ioremap_resource(&pdev->dev, r);
+ if (IS_ERR(rcpm_ftm_addr))
+ return PTR_ERR(rcpm_ftm_addr);
+ ippdexpcr = ioread32be(rcpm_ftm_addr);
+ ippdexpcr |= 0x20000;
+ iowrite32be(ippdexpcr, rcpm_ftm_addr);
+ if (endian == BIG_ENDIAN)
+ ippdexpcr = ioread32be(rcpm_ftm_addr);
+ else
+ ippdexpcr = ioread32(rcpm_ftm_addr);
+ ippdexpcr |= flextimer;
+ if (endian == BIG_ENDIAN)
+ iowrite32be(ippdexpcr, rcpm_ftm_addr);
+ else
+ iowrite32(ippdexpcr, rcpm_ftm_addr);
+ }
+
+ irq = irq_of_parse_and_map(np, 0);
@ -302,7 +383,12 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
+}
+
+static const struct of_device_id ftm_alarm_match[] = {
+ { .compatible = "fsl,ftm-alarm", },
+ { .compatible = "fsl,ls1012a-ftm", },
+ { .compatible = "fsl,ls1021a-ftm", },
+ { .compatible = "fsl,ls1043a-ftm", },
+ { .compatible = "fsl,ls1046a-ftm", },
+ { .compatible = "fsl,ls1088a-ftm", },
+ { .compatible = "fsl,ls208xa-ftm", },
+ { .compatible = "fsl,ftm-timer", },
+ { },
+};
@ -321,3 +407,6 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
+ return platform_driver_register(&ftm_alarm_driver);
+}
+device_initcall(ftm_alarm_init);
--
2.14.1

View File

@ -1,4 +1,4 @@
From f1874c71c855bd8ca8478a622053276f2c61eeca Mon Sep 17 00:00:00 2001
From 152f316e7829f6aeb3a36009e7e5ec0f1d97d770 Mon Sep 17 00:00:00 2001
From: Yangbo Lu <yangbo.lu@nxp.com>
Date: Wed, 27 Sep 2017 10:33:26 +0800
Subject: [PATCH] iommu: support layerscape
@ -12,20 +12,22 @@ Signed-off-by: Sunil Goutham <sgoutham@cavium.com>
Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
---
drivers/iommu/amd_iommu.c | 56 ++++++----
drivers/iommu/arm-smmu-v3.c | 35 ++++++-
drivers/iommu/arm-smmu.c | 74 ++++++++++---
drivers/iommu/arm-smmu-v3.c | 117 ++++++++++++++-------
drivers/iommu/arm-smmu.c | 100 +++++++++++++++---
drivers/iommu/dma-iommu.c | 242 ++++++++++++++++++++++++++++++++++++-------
drivers/iommu/intel-iommu.c | 92 ++++++++++++----
drivers/iommu/iommu.c | 191 ++++++++++++++++++++++++++++++++--
drivers/iommu/iommu.c | 219 ++++++++++++++++++++++++++++++++++++---
drivers/iommu/mtk_iommu.c | 2 +
drivers/iommu/mtk_iommu_v1.c | 2 +
include/linux/dma-iommu.h | 11 ++
include/linux/iommu.h | 55 +++++++---
10 files changed, 645 insertions(+), 115 deletions(-)
10 files changed, 739 insertions(+), 157 deletions(-)
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
index c380b7e8..93199931 100644
--- a/drivers/iommu/amd_iommu.c
+++ b/drivers/iommu/amd_iommu.c
@@ -373,6 +373,8 @@ static struct iommu_group *acpihid_devic
@@ -373,6 +373,8 @@ static struct iommu_group *acpihid_device_group(struct device *dev)
if (!entry->group)
entry->group = generic_device_group(dev);
@ -34,7 +36,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
return entry->group;
}
@@ -3160,9 +3162,10 @@ static bool amd_iommu_capable(enum iommu
@@ -3159,9 +3161,10 @@ static bool amd_iommu_capable(enum iommu_cap cap)
return false;
}
@ -47,7 +49,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
struct unity_map_entry *entry;
int devid;
@@ -3171,41 +3174,56 @@ static void amd_iommu_get_dm_regions(str
@@ -3170,41 +3173,56 @@ static void amd_iommu_get_dm_regions(struct device *dev,
return;
list_for_each_entry(entry, &amd_iommu_unity_map, list) {
@ -118,7 +120,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
{
struct dma_ops_domain *dma_dom = to_dma_ops_domain(to_pdomain(domain));
unsigned long start, end;
@@ -3229,9 +3247,9 @@ static const struct iommu_ops amd_iommu_
@@ -3228,9 +3246,9 @@ static const struct iommu_ops amd_iommu_ops = {
.add_device = amd_iommu_add_device,
.remove_device = amd_iommu_remove_device,
.device_group = amd_iommu_device_group,
@ -131,6 +133,8 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
.pgsize_bitmap = AMD_IOMMU_PGSIZES,
};
diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
index e6f9b2d7..48e2a7c4 100644
--- a/drivers/iommu/arm-smmu-v3.c
+++ b/drivers/iommu/arm-smmu-v3.c
@@ -410,6 +410,9 @@
@ -143,7 +147,92 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
static bool disable_bypass;
module_param_named(disable_bypass, disable_bypass, bool, S_IRUGO);
MODULE_PARM_DESC(disable_bypass,
@@ -1370,8 +1373,6 @@ static bool arm_smmu_capable(enum iommu_
@@ -552,9 +555,14 @@ struct arm_smmu_s2_cfg {
};
struct arm_smmu_strtab_ent {
- bool valid;
-
- bool bypass; /* Overrides s1/s2 config */
+ /*
+ * An STE is "assigned" if the master emitting the corresponding SID
+ * is attached to a domain. The behaviour of an unassigned STE is
+ * determined by the disable_bypass parameter, whereas an assigned
+ * STE behaves according to s1_cfg/s2_cfg, which themselves are
+ * configured according to the domain type.
+ */
+ bool assigned;
struct arm_smmu_s1_cfg *s1_cfg;
struct arm_smmu_s2_cfg *s2_cfg;
};
@@ -627,6 +635,7 @@ enum arm_smmu_domain_stage {
ARM_SMMU_DOMAIN_S1 = 0,
ARM_SMMU_DOMAIN_S2,
ARM_SMMU_DOMAIN_NESTED,
+ ARM_SMMU_DOMAIN_BYPASS,
};
struct arm_smmu_domain {
@@ -1000,9 +1009,9 @@ static void arm_smmu_write_strtab_ent(struct arm_smmu_device *smmu, u32 sid,
* This is hideously complicated, but we only really care about
* three cases at the moment:
*
- * 1. Invalid (all zero) -> bypass (init)
- * 2. Bypass -> translation (attach)
- * 3. Translation -> bypass (detach)
+ * 1. Invalid (all zero) -> bypass/fault (init)
+ * 2. Bypass/fault -> translation/bypass (attach)
+ * 3. Translation/bypass -> bypass/fault (detach)
*
* Given that we can't update the STE atomically and the SMMU
* doesn't read the thing in a defined order, that leaves us
@@ -1040,17 +1049,16 @@ static void arm_smmu_write_strtab_ent(struct arm_smmu_device *smmu, u32 sid,
}
}
- /* Nuke the existing Config, as we're going to rewrite it */
- val &= ~(STRTAB_STE_0_CFG_MASK << STRTAB_STE_0_CFG_SHIFT);
+ /* Nuke the existing STE_0 value, as we're going to rewrite it */
+ val = STRTAB_STE_0_V;
- if (ste->valid)
- val |= STRTAB_STE_0_V;
- else
- val &= ~STRTAB_STE_0_V;
+ /* Bypass/fault */
+ if (!ste->assigned || !(ste->s1_cfg || ste->s2_cfg)) {
+ if (!ste->assigned && disable_bypass)
+ val |= STRTAB_STE_0_CFG_ABORT;
+ else
+ val |= STRTAB_STE_0_CFG_BYPASS;
- if (ste->bypass) {
- val |= disable_bypass ? STRTAB_STE_0_CFG_ABORT
- : STRTAB_STE_0_CFG_BYPASS;
dst[0] = cpu_to_le64(val);
dst[1] = cpu_to_le64(STRTAB_STE_1_SHCFG_INCOMING
<< STRTAB_STE_1_SHCFG_SHIFT);
@@ -1081,7 +1089,6 @@ static void arm_smmu_write_strtab_ent(struct arm_smmu_device *smmu, u32 sid,
val |= (ste->s1_cfg->cdptr_dma & STRTAB_STE_0_S1CTXPTR_MASK
<< STRTAB_STE_0_S1CTXPTR_SHIFT) |
STRTAB_STE_0_CFG_S1_TRANS;
-
}
if (ste->s2_cfg) {
@@ -1114,10 +1121,7 @@ static void arm_smmu_write_strtab_ent(struct arm_smmu_device *smmu, u32 sid,
static void arm_smmu_init_bypass_stes(u64 *strtab, unsigned int nent)
{
unsigned int i;
- struct arm_smmu_strtab_ent ste = {
- .valid = true,
- .bypass = true,
- };
+ struct arm_smmu_strtab_ent ste = { .assigned = false };
for (i = 0; i < nent; ++i) {
arm_smmu_write_strtab_ent(NULL, -1, strtab, &ste);
@@ -1370,8 +1374,6 @@ static bool arm_smmu_capable(enum iommu_cap cap)
switch (cap) {
case IOMMU_CAP_CACHE_COHERENCY:
return true;
@ -152,7 +241,96 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
case IOMMU_CAP_NOEXEC:
return true;
default:
@@ -1709,6 +1710,9 @@ arm_smmu_iova_to_phys(struct iommu_domai
@@ -1383,7 +1385,9 @@ static struct iommu_domain *arm_smmu_domain_alloc(unsigned type)
{
struct arm_smmu_domain *smmu_domain;
- if (type != IOMMU_DOMAIN_UNMANAGED && type != IOMMU_DOMAIN_DMA)
+ if (type != IOMMU_DOMAIN_UNMANAGED &&
+ type != IOMMU_DOMAIN_DMA &&
+ type != IOMMU_DOMAIN_IDENTITY)
return NULL;
/*
@@ -1514,6 +1518,11 @@ static int arm_smmu_domain_finalise(struct iommu_domain *domain)
struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
struct arm_smmu_device *smmu = smmu_domain->smmu;
+ if (domain->type == IOMMU_DOMAIN_IDENTITY) {
+ smmu_domain->stage = ARM_SMMU_DOMAIN_BYPASS;
+ return 0;
+ }
+
/* Restrict the stage to what we can actually support */
if (!(smmu->features & ARM_SMMU_FEAT_TRANS_S1))
smmu_domain->stage = ARM_SMMU_DOMAIN_S2;
@@ -1584,7 +1593,7 @@ static __le64 *arm_smmu_get_step_for_sid(struct arm_smmu_device *smmu, u32 sid)
return step;
}
-static int arm_smmu_install_ste_for_dev(struct iommu_fwspec *fwspec)
+static void arm_smmu_install_ste_for_dev(struct iommu_fwspec *fwspec)
{
int i;
struct arm_smmu_master_data *master = fwspec->iommu_priv;
@@ -1596,17 +1605,14 @@ static int arm_smmu_install_ste_for_dev(struct iommu_fwspec *fwspec)
arm_smmu_write_strtab_ent(smmu, sid, step, &master->ste);
}
-
- return 0;
}
static void arm_smmu_detach_dev(struct device *dev)
{
struct arm_smmu_master_data *master = dev->iommu_fwspec->iommu_priv;
- master->ste.bypass = true;
- if (arm_smmu_install_ste_for_dev(dev->iommu_fwspec) < 0)
- dev_warn(dev, "failed to install bypass STE\n");
+ master->ste.assigned = false;
+ arm_smmu_install_ste_for_dev(dev->iommu_fwspec);
}
static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
@@ -1625,7 +1631,7 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
ste = &master->ste;
/* Already attached to a different domain? */
- if (!ste->bypass)
+ if (ste->assigned)
arm_smmu_detach_dev(dev);
mutex_lock(&smmu_domain->init_mutex);
@@ -1646,10 +1652,12 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
goto out_unlock;
}
- ste->bypass = false;
- ste->valid = true;
+ ste->assigned = true;
- if (smmu_domain->stage == ARM_SMMU_DOMAIN_S1) {
+ if (smmu_domain->stage == ARM_SMMU_DOMAIN_BYPASS) {
+ ste->s1_cfg = NULL;
+ ste->s2_cfg = NULL;
+ } else if (smmu_domain->stage == ARM_SMMU_DOMAIN_S1) {
ste->s1_cfg = &smmu_domain->s1_cfg;
ste->s2_cfg = NULL;
arm_smmu_write_ctx_desc(smmu, ste->s1_cfg);
@@ -1658,10 +1666,7 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
ste->s2_cfg = &smmu_domain->s2_cfg;
}
- ret = arm_smmu_install_ste_for_dev(dev->iommu_fwspec);
- if (ret < 0)
- ste->valid = false;
-
+ arm_smmu_install_ste_for_dev(dev->iommu_fwspec);
out_unlock:
mutex_unlock(&smmu_domain->init_mutex);
return ret;
@@ -1709,6 +1714,9 @@ arm_smmu_iova_to_phys(struct iommu_domain *domain, dma_addr_t iova)
struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
struct io_pgtable_ops *ops = smmu_domain->pgtbl_ops;
@ -162,7 +340,36 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
if (!ops)
return 0;
@@ -1880,6 +1884,31 @@ static int arm_smmu_of_xlate(struct devi
@@ -1807,7 +1815,7 @@ static void arm_smmu_remove_device(struct device *dev)
return;
master = fwspec->iommu_priv;
- if (master && master->ste.valid)
+ if (master && master->ste.assigned)
arm_smmu_detach_dev(dev);
iommu_group_remove_device(dev);
kfree(master);
@@ -1836,6 +1844,9 @@ static int arm_smmu_domain_get_attr(struct iommu_domain *domain,
{
struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
+ if (domain->type != IOMMU_DOMAIN_UNMANAGED)
+ return -EINVAL;
+
switch (attr) {
case DOMAIN_ATTR_NESTING:
*(int *)data = (smmu_domain->stage == ARM_SMMU_DOMAIN_NESTED);
@@ -1851,6 +1862,9 @@ static int arm_smmu_domain_set_attr(struct iommu_domain *domain,
int ret = 0;
struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
+ if (domain->type != IOMMU_DOMAIN_UNMANAGED)
+ return -EINVAL;
+
mutex_lock(&smmu_domain->init_mutex);
switch (attr) {
@@ -1880,6 +1894,31 @@ static int arm_smmu_of_xlate(struct device *dev, struct of_phandle_args *args)
return iommu_fwspec_add_ids(dev, args->args, 1);
}
@ -194,7 +401,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
static struct iommu_ops arm_smmu_ops = {
.capable = arm_smmu_capable,
.domain_alloc = arm_smmu_domain_alloc,
@@ -1895,6 +1924,8 @@ static struct iommu_ops arm_smmu_ops = {
@@ -1895,6 +1934,8 @@ static struct iommu_ops arm_smmu_ops = {
.domain_get_attr = arm_smmu_domain_get_attr,
.domain_set_attr = arm_smmu_domain_set_attr,
.of_xlate = arm_smmu_of_xlate,
@ -203,6 +410,8 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
.pgsize_bitmap = -1UL, /* Restricted during device attach */
};
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 8f728144..3243a96d 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -49,6 +49,7 @@
@ -231,7 +440,65 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
static int force_stage;
module_param(force_stage, int, S_IRUGO);
MODULE_PARM_DESC(force_stage,
@@ -1343,6 +1348,9 @@ static phys_addr_t arm_smmu_iova_to_phys
@@ -401,6 +406,7 @@ enum arm_smmu_domain_stage {
ARM_SMMU_DOMAIN_S1 = 0,
ARM_SMMU_DOMAIN_S2,
ARM_SMMU_DOMAIN_NESTED,
+ ARM_SMMU_DOMAIN_BYPASS,
};
struct arm_smmu_domain {
@@ -821,6 +827,12 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain,
if (smmu_domain->smmu)
goto out_unlock;
+ if (domain->type == IOMMU_DOMAIN_IDENTITY) {
+ smmu_domain->stage = ARM_SMMU_DOMAIN_BYPASS;
+ smmu_domain->smmu = smmu;
+ goto out_unlock;
+ }
+
/*
* Mapping the requested stage onto what we support is surprisingly
* complicated, mainly because the spec allows S1+S2 SMMUs without
@@ -981,7 +993,7 @@ static void arm_smmu_destroy_domain_context(struct iommu_domain *domain)
void __iomem *cb_base;
int irq;
- if (!smmu)
+ if (!smmu || domain->type == IOMMU_DOMAIN_IDENTITY)
return;
/*
@@ -1004,7 +1016,9 @@ static struct iommu_domain *arm_smmu_domain_alloc(unsigned type)
{
struct arm_smmu_domain *smmu_domain;
- if (type != IOMMU_DOMAIN_UNMANAGED && type != IOMMU_DOMAIN_DMA)
+ if (type != IOMMU_DOMAIN_UNMANAGED &&
+ type != IOMMU_DOMAIN_DMA &&
+ type != IOMMU_DOMAIN_IDENTITY)
return NULL;
/*
* Allocate the domain and initialise some of its data structures.
@@ -1202,10 +1216,15 @@ static int arm_smmu_domain_add_master(struct arm_smmu_domain *smmu_domain,
{
struct arm_smmu_device *smmu = smmu_domain->smmu;
struct arm_smmu_s2cr *s2cr = smmu->s2crs;
- enum arm_smmu_s2cr_type type = S2CR_TYPE_TRANS;
u8 cbndx = smmu_domain->cfg.cbndx;
+ enum arm_smmu_s2cr_type type;
int i, idx;
+ if (smmu_domain->stage == ARM_SMMU_DOMAIN_BYPASS)
+ type = S2CR_TYPE_BYPASS;
+ else
+ type = S2CR_TYPE_TRANS;
+
for_each_cfg_sme(fwspec, i, idx) {
if (type == s2cr[idx].type && cbndx == s2cr[idx].cbndx)
continue;
@@ -1343,6 +1362,9 @@ static phys_addr_t arm_smmu_iova_to_phys(struct iommu_domain *domain,
struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
struct io_pgtable_ops *ops= smmu_domain->pgtbl_ops;
@ -241,7 +508,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
if (!ops)
return 0;
@@ -1368,8 +1376,6 @@ static bool arm_smmu_capable(enum iommu_
@@ -1368,8 +1390,6 @@ static bool arm_smmu_capable(enum iommu_cap cap)
* requests.
*/
return true;
@ -250,7 +517,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
case IOMMU_CAP_NOEXEC:
return true;
default:
@@ -1478,10 +1484,12 @@ static struct iommu_group *arm_smmu_devi
@@ -1478,10 +1498,12 @@ static struct iommu_group *arm_smmu_device_group(struct device *dev)
}
if (group)
@ -264,7 +531,27 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
else
group = generic_device_group(dev);
@@ -1534,17 +1542,44 @@ out_unlock:
@@ -1493,6 +1515,9 @@ static int arm_smmu_domain_get_attr(struct iommu_domain *domain,
{
struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
+ if (domain->type != IOMMU_DOMAIN_UNMANAGED)
+ return -EINVAL;
+
switch (attr) {
case DOMAIN_ATTR_NESTING:
*(int *)data = (smmu_domain->stage == ARM_SMMU_DOMAIN_NESTED);
@@ -1508,6 +1533,9 @@ static int arm_smmu_domain_set_attr(struct iommu_domain *domain,
int ret = 0;
struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
+ if (domain->type != IOMMU_DOMAIN_UNMANAGED)
+ return -EINVAL;
+
mutex_lock(&smmu_domain->init_mutex);
switch (attr) {
@@ -1534,17 +1562,44 @@ static int arm_smmu_domain_set_attr(struct iommu_domain *domain,
static int arm_smmu_of_xlate(struct device *dev, struct of_phandle_args *args)
{
@ -310,7 +597,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
static struct iommu_ops arm_smmu_ops = {
.capable = arm_smmu_capable,
.domain_alloc = arm_smmu_domain_alloc,
@@ -1560,6 +1595,8 @@ static struct iommu_ops arm_smmu_ops = {
@@ -1560,6 +1615,8 @@ static struct iommu_ops arm_smmu_ops = {
.domain_get_attr = arm_smmu_domain_get_attr,
.domain_set_attr = arm_smmu_domain_set_attr,
.of_xlate = arm_smmu_of_xlate,
@ -319,7 +606,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
.pgsize_bitmap = -1UL, /* Restricted during device attach */
};
@@ -1581,16 +1618,22 @@ static void arm_smmu_device_reset(struct
@@ -1581,16 +1638,22 @@ static void arm_smmu_device_reset(struct arm_smmu_device *smmu)
for (i = 0; i < smmu->num_mapping_groups; ++i)
arm_smmu_write_sme(smmu, i);
@ -351,7 +638,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
writel_relaxed(reg, gr0_base + ARM_SMMU_GR0_sACR);
}
@@ -2024,6 +2067,11 @@ static int arm_smmu_device_dt_probe(stru
@@ -2024,6 +2087,11 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev)
bus_set_iommu(&pci_bus_type, &arm_smmu_ops);
}
#endif
@ -363,6 +650,8 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
return 0;
}
diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
index 1520e7f0..3ade4153 100644
--- a/drivers/iommu/dma-iommu.c
+++ b/drivers/iommu/dma-iommu.c
@@ -37,15 +37,50 @@ struct iommu_dma_msi_page {
@ -420,10 +709,11 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
}
int iommu_dma_init(void)
@@ -62,25 +97,53 @@ int iommu_dma_init(void)
@@ -61,26 +96,54 @@ int iommu_dma_init(void)
* callback when domain->type == IOMMU_DOMAIN_DMA.
*/
int iommu_get_dma_cookie(struct iommu_domain *domain)
{
+{
+ if (domain->iova_cookie)
+ return -EEXIST;
+
@ -448,7 +738,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
+ * used by the devices attached to @domain.
+ */
+int iommu_get_msi_cookie(struct iommu_domain *domain, dma_addr_t base)
+{
{
struct iommu_dma_cookie *cookie;
+ if (domain->type != IOMMU_DOMAIN_UNMANAGED)
@ -479,7 +769,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
*
* IOMMU drivers should normally call this from their domain_free callback.
*/
@@ -92,7 +155,7 @@ void iommu_put_dma_cookie(struct iommu_d
@@ -92,7 +155,7 @@ void iommu_put_dma_cookie(struct iommu_domain *domain)
if (!cookie)
return;
@ -488,7 +778,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
put_iova_domain(&cookie->iovad);
list_for_each_entry_safe(msi, tmp, &cookie->msi_page_list, list) {
@@ -104,21 +167,99 @@ void iommu_put_dma_cookie(struct iommu_d
@@ -104,21 +167,99 @@ void iommu_put_dma_cookie(struct iommu_domain *domain)
}
EXPORT_SYMBOL(iommu_put_dma_cookie);
@ -594,7 +884,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
}
/**
@@ -136,11 +277,12 @@ static void iova_reserve_pci_windows(str
@@ -136,11 +277,12 @@ static void iova_reserve_pci_windows(struct pci_dev *dev,
int iommu_dma_init_domain(struct iommu_domain *domain, dma_addr_t base,
u64 size, struct device *dev)
{
@ -610,7 +900,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
/* Use the smallest supported page size for IOVA granularity */
order = __ffs(domain->pgsize_bitmap);
@@ -160,22 +302,37 @@ int iommu_dma_init_domain(struct iommu_d
@@ -160,22 +302,37 @@ int iommu_dma_init_domain(struct iommu_domain *domain, dma_addr_t base,
end_pfn = min_t(unsigned long, end_pfn,
domain->geometry.aperture_end >> order);
}
@ -657,7 +947,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
}
EXPORT_SYMBOL(iommu_dma_init_domain);
@@ -643,11 +800,12 @@ static struct iommu_dma_msi_page *iommu_
@@ -643,11 +800,12 @@ static struct iommu_dma_msi_page *iommu_dma_get_msi_page(struct device *dev,
{
struct iommu_dma_cookie *cookie = domain->iova_cookie;
struct iommu_dma_msi_page *msi_page;
@ -672,7 +962,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
list_for_each_entry(msi_page, &cookie->msi_page_list, list)
if (msi_page->phys == msi_addr)
return msi_page;
@@ -656,13 +814,18 @@ static struct iommu_dma_msi_page *iommu_
@@ -656,13 +814,18 @@ static struct iommu_dma_msi_page *iommu_dma_get_msi_page(struct device *dev,
if (!msi_page)
return NULL;
@ -697,7 +987,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
goto out_free_iova;
INIT_LIST_HEAD(&msi_page->list);
@@ -670,7 +833,10 @@ static struct iommu_dma_msi_page *iommu_
@@ -670,7 +833,10 @@ static struct iommu_dma_msi_page *iommu_dma_get_msi_page(struct device *dev,
return msi_page;
out_free_iova:
@ -709,7 +999,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
out_free_page:
kfree(msi_page);
return NULL;
@@ -711,7 +877,7 @@ void iommu_dma_map_msi_msg(int irq, stru
@@ -711,7 +877,7 @@ void iommu_dma_map_msi_msg(int irq, struct msi_msg *msg)
msg->data = ~0U;
} else {
msg->address_hi = upper_32_bits(msi_page->iova);
@ -718,6 +1008,8 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
msg->address_lo += lower_32_bits(msi_page->iova);
}
}
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index 002f8a42..befbfd30 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -440,6 +440,7 @@ struct dmar_rmrr_unit {
@ -728,7 +1020,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
};
struct dmar_atsr_unit {
@@ -4250,27 +4251,40 @@ static inline void init_iommu_pm_ops(voi
@@ -4250,27 +4251,40 @@ static inline void init_iommu_pm_ops(void) {}
int __init dmar_parse_one_rmrr(struct acpi_dmar_header *header, void *arg)
{
struct acpi_dmar_reserved_memory *rmrr;
@ -782,7 +1074,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
kfree(rmrru);
}
@@ -5219,6 +5234,45 @@ static void intel_iommu_remove_device(st
@@ -5219,6 +5234,45 @@ static void intel_iommu_remove_device(struct device *dev)
iommu_device_unlink(iommu->iommu_dev, dev);
}
@ -828,7 +1120,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
#ifdef CONFIG_INTEL_IOMMU_SVM
#define MAX_NR_PASID_BITS (20)
static inline unsigned long intel_iommu_get_pts(struct intel_iommu *iommu)
@@ -5349,19 +5403,21 @@ struct intel_iommu *intel_svm_device_to_
@@ -5349,19 +5403,21 @@ struct intel_iommu *intel_svm_device_to_iommu(struct device *dev)
#endif /* CONFIG_INTEL_IOMMU_SVM */
static const struct iommu_ops intel_iommu_ops = {
@ -863,9 +1155,19 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
};
static void quirk_iommu_g4x_gfx(struct pci_dev *dev)
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 87d3060f..e6a8c225 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -68,6 +68,13 @@ struct iommu_group_attribute {
@@ -36,6 +36,7 @@
static struct kset *iommu_group_kset;
static DEFINE_IDA(iommu_group_ida);
+static unsigned int iommu_def_domain_type = IOMMU_DOMAIN_DMA;
struct iommu_callback_data {
const struct iommu_ops *ops;
@@ -68,6 +69,13 @@ struct iommu_group_attribute {
const char *buf, size_t count);
};
@ -879,7 +1181,26 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
#define IOMMU_GROUP_ATTR(_name, _mode, _show, _store) \
struct iommu_group_attribute iommu_group_attr_##_name = \
__ATTR(_name, _mode, _show, _store)
@@ -133,8 +140,131 @@ static ssize_t iommu_group_show_name(str
@@ -86,6 +94,18 @@ static int __iommu_attach_group(struct iommu_domain *domain,
static void __iommu_detach_group(struct iommu_domain *domain,
struct iommu_group *group);
+static int __init iommu_set_def_domain_type(char *str)
+{
+ bool pt;
+
+ if (!str || strtobool(str, &pt))
+ return -EINVAL;
+
+ iommu_def_domain_type = pt ? IOMMU_DOMAIN_IDENTITY : IOMMU_DOMAIN_DMA;
+ return 0;
+}
+early_param("iommu.passthrough", iommu_set_def_domain_type);
+
static ssize_t iommu_group_attr_show(struct kobject *kobj,
struct attribute *__attr, char *buf)
{
@@ -133,8 +153,131 @@ static ssize_t iommu_group_show_name(struct iommu_group *group, char *buf)
return sprintf(buf, "%s\n", group->name);
}
@ -1011,7 +1332,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
static void iommu_group_release(struct kobject *kobj)
{
struct iommu_group *group = to_iommu_group(kobj);
@@ -212,6 +342,11 @@ struct iommu_group *iommu_group_alloc(vo
@@ -212,6 +355,11 @@ struct iommu_group *iommu_group_alloc(void)
*/
kobject_put(&group->kobj);
@ -1023,7 +1344,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
pr_debug("Allocated group %d\n", group->id);
return group;
@@ -318,7 +453,7 @@ static int iommu_group_create_direct_map
@@ -318,7 +466,7 @@ static int iommu_group_create_direct_mappings(struct iommu_group *group,
struct device *dev)
{
struct iommu_domain *domain = group->default_domain;
@ -1032,7 +1353,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
struct list_head mappings;
unsigned long pg_size;
int ret = 0;
@@ -331,18 +466,21 @@ static int iommu_group_create_direct_map
@@ -331,18 +479,21 @@ static int iommu_group_create_direct_mappings(struct iommu_group *group,
pg_size = 1UL << __ffs(domain->pgsize_bitmap);
INIT_LIST_HEAD(&mappings);
@ -1057,7 +1378,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
for (addr = start; addr < end; addr += pg_size) {
phys_addr_t phys_addr;
@@ -358,7 +496,7 @@ static int iommu_group_create_direct_map
@@ -358,7 +509,7 @@ static int iommu_group_create_direct_mappings(struct iommu_group *group,
}
out:
@ -1066,10 +1387,11 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
return ret;
}
@@ -563,6 +701,19 @@ struct iommu_group *iommu_group_get(stru
@@ -562,6 +713,19 @@ struct iommu_group *iommu_group_get(struct device *dev)
}
EXPORT_SYMBOL_GPL(iommu_group_get);
/**
+/**
+ * iommu_group_ref_get - Increment reference on a group
+ * @group: the group to use, must not be NULL
+ *
@ -1082,11 +1404,33 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
+ return group;
+}
+
+/**
/**
* iommu_group_put - Decrement group reference
* @group: the group to use
*
@@ -1557,20 +1708,38 @@ int iommu_domain_set_attr(struct iommu_d
@@ -845,10 +1009,19 @@ struct iommu_group *iommu_group_get_for_dev(struct device *dev)
* IOMMU driver.
*/
if (!group->default_domain) {
- group->default_domain = __iommu_domain_alloc(dev->bus,
- IOMMU_DOMAIN_DMA);
+ struct iommu_domain *dom;
+
+ dom = __iommu_domain_alloc(dev->bus, iommu_def_domain_type);
+ if (!dom && iommu_def_domain_type != IOMMU_DOMAIN_DMA) {
+ dev_warn(dev,
+ "failed to allocate default IOMMU domain of type %u; falling back to IOMMU_DOMAIN_DMA",
+ iommu_def_domain_type);
+ dom = __iommu_domain_alloc(dev->bus, IOMMU_DOMAIN_DMA);
+ }
+
+ group->default_domain = dom;
if (!group->domain)
- group->domain = group->default_domain;
+ group->domain = dom;
}
ret = iommu_group_add_device(group, dev);
@@ -1557,20 +1730,38 @@ int iommu_domain_set_attr(struct iommu_domain *domain,
}
EXPORT_SYMBOL_GPL(iommu_domain_set_attr);
@ -1131,9 +1475,11 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
}
/* Request that a device is direct mapped by the IOMMU */
diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index b12c12d7..9799daea 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -410,6 +410,8 @@ static struct iommu_group *mtk_iommu_dev
@@ -410,6 +410,8 @@ static struct iommu_group *mtk_iommu_device_group(struct device *dev)
data->m4u_group = iommu_group_alloc();
if (IS_ERR(data->m4u_group))
dev_err(dev, "Failed to allocate M4U IOMMU group\n");
@ -1142,9 +1488,11 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
}
return data->m4u_group;
}
diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c
index b8aeb076..c7063e9d 100644
--- a/drivers/iommu/mtk_iommu_v1.c
+++ b/drivers/iommu/mtk_iommu_v1.c
@@ -502,6 +502,8 @@ static struct iommu_group *mtk_iommu_dev
@@ -502,6 +502,8 @@ static struct iommu_group *mtk_iommu_device_group(struct device *dev)
data->m4u_group = iommu_group_alloc();
if (IS_ERR(data->m4u_group))
dev_err(dev, "Failed to allocate M4U IOMMU group\n");
@ -1153,6 +1501,8 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
}
return data->m4u_group;
}
diff --git a/include/linux/dma-iommu.h b/include/linux/dma-iommu.h
index 32c58906..36d3206d 100644
--- a/include/linux/dma-iommu.h
+++ b/include/linux/dma-iommu.h
@@ -27,6 +27,7 @@ int iommu_dma_init(void);
@ -1163,7 +1513,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
void iommu_put_dma_cookie(struct iommu_domain *domain);
/* Setup call for arch DMA mapping code */
@@ -66,6 +67,7 @@ int iommu_dma_mapping_error(struct devic
@@ -66,6 +67,7 @@ int iommu_dma_mapping_error(struct device *dev, dma_addr_t dma_addr);
/* The DMA API isn't _quite_ the whole story, though... */
void iommu_dma_map_msi_msg(int irq, struct msi_msg *msg);
@ -1171,7 +1521,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
#else
@@ -82,6 +84,11 @@ static inline int iommu_get_dma_cookie(s
@@ -82,6 +84,11 @@ static inline int iommu_get_dma_cookie(struct iommu_domain *domain)
return -ENODEV;
}
@ -1183,7 +1533,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
static inline void iommu_put_dma_cookie(struct iommu_domain *domain)
{
}
@@ -90,6 +97,10 @@ static inline void iommu_dma_map_msi_msg
@@ -90,6 +97,10 @@ static inline void iommu_dma_map_msi_msg(int irq, struct msi_msg *msg)
{
}
@ -1194,6 +1544,8 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
#endif /* CONFIG_IOMMU_DMA */
#endif /* __KERNEL__ */
#endif /* __DMA_IOMMU_H */
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 436dc213..188599f5 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -117,18 +117,32 @@ enum iommu_attr {
@ -1262,7 +1614,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
/* Window handling functions */
int (*domain_window_enable)(struct iommu_domain *domain, u32 wnd_nr,
@@ -233,9 +248,14 @@ extern phys_addr_t iommu_iova_to_phys(st
@@ -233,9 +248,14 @@ extern phys_addr_t iommu_iova_to_phys(struct iommu_domain *domain, dma_addr_t io
extern void iommu_set_fault_handler(struct iommu_domain *domain,
iommu_fault_handler_t handler, void *token);
@ -1279,7 +1631,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
extern int iommu_attach_group(struct iommu_domain *domain,
struct iommu_group *group);
@@ -253,6 +273,7 @@ extern void iommu_group_remove_device(st
@@ -253,6 +273,7 @@ extern void iommu_group_remove_device(struct device *dev);
extern int iommu_group_for_each_dev(struct iommu_group *group, void *data,
int (*fn)(struct device *, void *));
extern struct iommu_group *iommu_group_get(struct device *dev);
@ -1287,7 +1639,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
extern void iommu_group_put(struct iommu_group *group);
extern int iommu_group_register_notifier(struct iommu_group *group,
struct notifier_block *nb);
@@ -439,16 +460,22 @@ static inline void iommu_set_fault_handl
@@ -439,16 +460,22 @@ static inline void iommu_set_fault_handler(struct iommu_domain *domain,
{
}
@ -1312,3 +1664,6 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
static inline int iommu_request_dm_for_dev(struct device *dev)
{
return -ENODEV;
--
2.14.1

View File

@ -1,4 +1,4 @@
From f8daa8e984213554008e73cd155530dceec5a109 Mon Sep 17 00:00:00 2001
From b14460ee524a34d3b94b44032b52155c4cd708e5 Mon Sep 17 00:00:00 2001
From: Yangbo Lu <yangbo.lu@nxp.com>
Date: Wed, 27 Sep 2017 10:34:07 +0800
Subject: [PATCH] usb: support layerscape
@ -15,6 +15,7 @@ Signed-off-by: Suresh Gupta <suresh.gupta@freescale.com>
Signed-off-by: Zhao Chenhui <chenhui.zhao@freescale.com>
Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
---
drivers/net/usb/r8152.c | 4 +
drivers/usb/common/common.c | 50 ++++++
drivers/usb/core/hub.c | 8 +
drivers/usb/dwc3/core.c | 235 ++++++++++++++++++++++++++-
@ -32,11 +33,28 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
drivers/usb/phy/phy-fsl-usb.h | 8 +
include/linux/usb.h | 1 +
include/linux/usb/of.h | 2 +
17 files changed, 726 insertions(+), 73 deletions(-)
18 files changed, 730 insertions(+), 73 deletions(-)
diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index afb953a2..c9c86495 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -1812,6 +1812,10 @@ static int rx_bottom(struct r8152 *tp, int budget)
unsigned int pkt_len;
struct sk_buff *skb;
+ /* limite the skb numbers for rx_queue */
+ if (unlikely(skb_queue_len(&tp->rx_queue) >= 1000))
+ break;
+
pkt_len = le32_to_cpu(rx_desc->opts1) & RX_LEN_MASK;
if (pkt_len < ETH_ZLEN)
break;
diff --git a/drivers/usb/common/common.c b/drivers/usb/common/common.c
index 5ef8da6e..176dee01 100644
--- a/drivers/usb/common/common.c
+++ b/drivers/usb/common/common.c
@@ -105,6 +105,56 @@ static const char *const usb_dr_modes[]
@@ -105,6 +105,56 @@ static const char *const usb_dr_modes[] = {
[USB_DR_MODE_OTG] = "otg",
};
@ -93,9 +111,11 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
static enum usb_dr_mode usb_get_dr_mode_from_string(const char *str)
{
int ret;
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 80d4ef31..e23acf03 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -4412,6 +4412,14 @@ hub_port_init(struct usb_hub *hub, struc
@@ -4412,6 +4412,14 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1,
else
speed = usb_speed_string(udev->speed);
@ -110,9 +130,11 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
if (udev->speed < USB_SPEED_SUPER)
dev_info(&udev->dev,
"%s %s USB device number %d using %s\n",
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index fea44690..e34ef90a 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -58,6 +58,7 @@ static int dwc3_get_dr_mode(struct dwc3
@@ -58,6 +58,7 @@ static int dwc3_get_dr_mode(struct dwc3 *dwc)
enum usb_dr_mode mode;
struct device *dev = dwc->dev;
unsigned int hw_mode;
@ -120,7 +142,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
if (dwc->dr_mode == USB_DR_MODE_UNKNOWN)
dwc->dr_mode = USB_DR_MODE_OTG;
@@ -83,6 +84,24 @@ static int dwc3_get_dr_mode(struct dwc3
@@ -83,6 +84,24 @@ static int dwc3_get_dr_mode(struct dwc3 *dwc)
mode = USB_DR_MODE_HOST;
break;
default:
@ -145,7 +167,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
if (IS_ENABLED(CONFIG_USB_DWC3_HOST))
mode = USB_DR_MODE_HOST;
else if (IS_ENABLED(CONFIG_USB_DWC3_GADGET))
@@ -213,8 +232,9 @@ static void dwc3_frame_length_adjustment
@@ -213,8 +232,9 @@ static void dwc3_frame_length_adjustment(struct dwc3 *dwc)
reg = dwc3_readl(dwc->regs, DWC3_GFLADJ);
dft = reg & DWC3_GFLADJ_30MHZ_MASK;
@ -157,7 +179,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
reg &= ~DWC3_GFLADJ_30MHZ_MASK;
reg |= DWC3_GFLADJ_30MHZ_SDBND_SEL | dwc->fladj;
dwc3_writel(dwc->regs, DWC3_GFLADJ, reg);
@@ -579,6 +599,99 @@ static int dwc3_phy_setup(struct dwc3 *d
@@ -579,6 +599,99 @@ static int dwc3_phy_setup(struct dwc3 *dwc)
return 0;
}
@ -257,7 +279,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
static void dwc3_core_exit(struct dwc3 *dwc)
{
dwc3_event_buffers_cleanup(dwc);
@@ -721,6 +834,8 @@ static int dwc3_core_init(struct dwc3 *d
@@ -721,6 +834,8 @@ static int dwc3_core_init(struct dwc3 *dwc)
if (ret)
goto err1;
@ -266,7 +288,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
/* Adjust Frame Length */
dwc3_frame_length_adjustment(dwc);
@@ -919,11 +1034,109 @@ static void dwc3_core_exit_mode(struct d
@@ -919,11 +1034,109 @@ static void dwc3_core_exit_mode(struct dwc3 *dwc)
}
}
@ -376,7 +398,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
struct resource *res;
struct dwc3 *dwc;
u8 lpm_nyet_threshold;
@@ -955,6 +1168,11 @@ static int dwc3_probe(struct platform_de
@@ -955,6 +1168,11 @@ static int dwc3_probe(struct platform_device *pdev)
dwc->xhci_resources[0].flags = res->flags;
dwc->xhci_resources[0].name = res->name;
@ -388,7 +410,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
res->start += DWC3_GLOBALS_REGS_START;
/*
@@ -997,6 +1215,12 @@ static int dwc3_probe(struct platform_de
@@ -997,6 +1215,12 @@ static int dwc3_probe(struct platform_device *pdev)
dwc->usb3_lpm_capable = device_property_read_bool(dev,
"snps,usb3_lpm_capable");
@ -401,7 +423,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
dwc->disable_scramble_quirk = device_property_read_bool(dev,
"snps,disable_scramble_quirk");
dwc->u2exit_lfps_quirk = device_property_read_bool(dev,
@@ -1041,6 +1265,8 @@ static int dwc3_probe(struct platform_de
@@ -1041,6 +1265,8 @@ static int dwc3_probe(struct platform_device *pdev)
dwc->hird_threshold = hird_threshold
| (dwc->is_utmi_l1_suspend << 4);
@ -410,7 +432,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
platform_set_drvdata(pdev, dwc);
dwc3_cache_hwparams(dwc);
@@ -1064,6 +1290,11 @@ static int dwc3_probe(struct platform_de
@@ -1064,6 +1290,11 @@ static int dwc3_probe(struct platform_device *pdev)
if (ret < 0)
goto err1;
@ -422,6 +444,8 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
pm_runtime_forbid(dev);
ret = dwc3_alloc_event_buffers(dwc, DWC3_EVENT_BUFFERS_SIZE);
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 884c4371..9151eef4 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -26,6 +26,7 @@
@ -539,6 +563,8 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
};
/* -------------------------------------------------------------------------- */
diff --git a/drivers/usb/dwc3/host.c b/drivers/usb/dwc3/host.c
index 626d87d5..f1b98273 100644
--- a/drivers/usb/dwc3/host.c
+++ b/drivers/usb/dwc3/host.c
@@ -17,6 +17,8 @@
@ -574,6 +600,8 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
dwc->xhci = xhci;
ret = platform_device_add_resources(xhci, dwc->xhci_resources,
diff --git a/drivers/usb/gadget/udc/fsl_udc_core.c b/drivers/usb/gadget/udc/fsl_udc_core.c
index aac0ce8a..fe49e758 100644
--- a/drivers/usb/gadget/udc/fsl_udc_core.c
+++ b/drivers/usb/gadget/udc/fsl_udc_core.c
@@ -198,7 +198,11 @@ __acquires(ep->udc->lock)
@ -589,7 +617,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
spin_lock(&ep->udc->lock);
ep->stopped = stopped;
@@ -245,10 +249,10 @@ static int dr_controller_setup(struct fs
@@ -245,10 +249,10 @@ static int dr_controller_setup(struct fsl_udc *udc)
if (udc->pdata->have_sysif_regs) {
if (udc->pdata->controller_ver) {
/* controller version 1.6 or above */
@ -602,7 +630,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
}
}
portctrl |= PORTSCX_PTS_ULPI;
@@ -257,13 +261,14 @@ static int dr_controller_setup(struct fs
@@ -257,13 +261,14 @@ static int dr_controller_setup(struct fsl_udc *udc)
portctrl |= PORTSCX_PTW_16BIT;
/* fall through */
case FSL_USB2_PHY_UTMI:
@ -619,7 +647,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
mdelay(FSL_UTMI_PHY_DLY); /* Delay for UTMI
PHY CLK to become stable - 10ms*/
}
@@ -329,22 +334,22 @@ static int dr_controller_setup(struct fs
@@ -329,22 +334,22 @@ static int dr_controller_setup(struct fsl_udc *udc)
/* Config control enable i/o output, cpu endian register */
#ifndef CONFIG_ARCH_MXC
if (udc->pdata->have_sysif_regs) {
@ -647,7 +675,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
}
#endif
@@ -1057,7 +1062,7 @@ static int fsl_ep_fifo_status(struct usb
@@ -1057,7 +1062,7 @@ static int fsl_ep_fifo_status(struct usb_ep *_ep)
struct ep_queue_head *qh;
ep = container_of(_ep, struct fsl_ep, ep);
@ -656,7 +684,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
return -ENODEV;
udc = (struct fsl_udc *)ep->udc;
@@ -1599,14 +1604,13 @@ static int process_ep_req(struct fsl_udc
@@ -1599,14 +1604,13 @@ static int process_ep_req(struct fsl_udc *udc, int pipe,
struct fsl_req *curr_req)
{
struct ep_td_struct *curr_td;
@ -672,7 +700,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
actual = curr_req->req.length;
for (j = 0; j < curr_req->dtd_count; j++) {
@@ -1651,11 +1655,9 @@ static int process_ep_req(struct fsl_udc
@@ -1651,11 +1655,9 @@ static int process_ep_req(struct fsl_udc *udc, int pipe,
status = -EPROTO;
break;
} else {
@ -684,7 +712,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
VDBG("dTD transmitted successful");
}
@@ -1698,7 +1700,7 @@ static void dtd_complete_irq(struct fsl_
@@ -1698,7 +1700,7 @@ static void dtd_complete_irq(struct fsl_udc *udc)
curr_ep = get_ep_by_pipe(udc, i);
/* If the ep is configured */
@ -693,7 +721,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
WARNING("Invalid EP?");
continue;
}
@@ -2420,10 +2422,12 @@ static int fsl_udc_probe(struct platform
@@ -2420,10 +2422,12 @@ static int fsl_udc_probe(struct platform_device *pdev)
usb_sys_regs = (void *)dr_regs + USB_DR_SYS_OFFSET;
#endif
@ -706,7 +734,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
/* Read Device Controller Capability Parameters register */
dccparams = fsl_readl(&dr_regs->dccparams);
@@ -2463,9 +2467,11 @@ static int fsl_udc_probe(struct platform
@@ -2463,9 +2467,11 @@ static int fsl_udc_probe(struct platform_device *pdev)
dr_controller_setup(udc_controller);
}
@ -718,7 +746,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
/* Setup gadget structure */
udc_controller->gadget.ops = &fsl_gadget_ops;
@@ -2478,6 +2484,7 @@ static int fsl_udc_probe(struct platform
@@ -2478,6 +2484,7 @@ static int fsl_udc_probe(struct platform_device *pdev)
/* Setup gadget.dev and register with kernel */
dev_set_name(&udc_controller->gadget.dev, "gadget");
udc_controller->gadget.dev.of_node = pdev->dev.of_node;
@ -726,7 +754,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
if (!IS_ERR_OR_NULL(udc_controller->transceiver))
udc_controller->gadget.is_otg = 1;
@@ -2529,7 +2536,9 @@ err_free_irq:
@@ -2529,7 +2536,9 @@ static int fsl_udc_probe(struct platform_device *pdev)
err_iounmap:
if (pdata->exit)
pdata->exit(pdev);
@ -736,7 +764,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
err_iounmap_noclk:
iounmap(dr_regs);
err_release_mem_region:
@@ -2557,8 +2566,9 @@ static int fsl_udc_remove(struct platfor
@@ -2557,8 +2566,9 @@ static int fsl_udc_remove(struct platform_device *pdev)
udc_controller->done = &done;
usb_del_gadget_udc(&udc_controller->gadget);
@ -747,7 +775,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
/* DR has been stopped in usb_gadget_unregister_driver() */
remove_proc_file();
@@ -2570,7 +2580,7 @@ static int fsl_udc_remove(struct platfor
@@ -2570,7 +2580,7 @@ static int fsl_udc_remove(struct platform_device *pdev)
dma_pool_destroy(udc_controller->td_pool);
free_irq(udc_controller->irq, udc_controller);
iounmap(dr_regs);
@ -756,6 +784,8 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
release_mem_region(res->start, resource_size(res));
/* free udc --wait for the release() finished */
diff --git a/drivers/usb/gadget/udc/fsl_usb2_udc.h b/drivers/usb/gadget/udc/fsl_usb2_udc.h
index 84715625..f76c4ddd 100644
--- a/drivers/usb/gadget/udc/fsl_usb2_udc.h
+++ b/drivers/usb/gadget/udc/fsl_usb2_udc.h
@@ -20,6 +20,10 @@
@ -788,6 +818,8 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
#endif
#endif
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 0b80cee3..a57d95c3 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -165,7 +165,7 @@ config XPS_USB_HCD_XILINX
@ -799,6 +831,8 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
select USB_EHCI_ROOT_HUB_TT
---help---
Variation of ARC USB block used in some Freescale chips.
diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c
index 9f5ffb62..cd16860c 100644
--- a/drivers/usb/host/ehci-fsl.c
+++ b/drivers/usb/host/ehci-fsl.c
@@ -37,13 +37,141 @@
@ -943,7 +977,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
/* configure so an HC device and id are always provided */
/* always called with process context; sleeping is OK */
@@ -131,6 +259,12 @@ static int fsl_ehci_drv_probe(struct pla
@@ -131,6 +259,12 @@ static int fsl_ehci_drv_probe(struct platform_device *pdev)
clrsetbits_be32(hcd->regs + FSL_SOC_USB_CTRL,
CONTROL_REGISTER_W1C_MASK, 0x4);
@ -956,7 +990,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
/*
* Enable UTMI phy and program PTS field in UTMI mode before asserting
* controller reset for USB Controller version 2.5
@@ -143,16 +277,20 @@ static int fsl_ehci_drv_probe(struct pla
@@ -143,16 +277,20 @@ static int fsl_ehci_drv_probe(struct platform_device *pdev)
/* Don't need to set host mode here. It will be done by tdi_reset() */
@ -979,7 +1013,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
dev_dbg(&pdev->dev, "hcd=0x%p ehci=0x%p, phy=0x%p\n",
hcd, ehci, hcd->usb_phy);
@@ -168,6 +306,11 @@ static int fsl_ehci_drv_probe(struct pla
@@ -168,6 +306,11 @@ static int fsl_ehci_drv_probe(struct platform_device *pdev)
retval = -ENODEV;
goto err2;
}
@ -991,7 +1025,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
}
#endif
return retval;
@@ -181,6 +324,18 @@ static int fsl_ehci_drv_probe(struct pla
@@ -181,6 +324,18 @@ static int fsl_ehci_drv_probe(struct platform_device *pdev)
return retval;
}
@ -1010,7 +1044,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
static int ehci_fsl_setup_phy(struct usb_hcd *hcd,
enum fsl_usb2_phy_modes phy_mode,
unsigned int port_offset)
@@ -219,6 +374,21 @@ static int ehci_fsl_setup_phy(struct usb
@@ -219,6 +374,21 @@ static int ehci_fsl_setup_phy(struct usb_hcd *hcd,
/* fall through */
case FSL_USB2_PHY_UTMI:
case FSL_USB2_PHY_UTMI_DUAL:
@ -1032,7 +1066,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
if (pdata->have_sysif_regs && pdata->controller_ver) {
/* controller version 1.6 or above */
clrsetbits_be32(non_ehci + FSL_SOC_USB_CTRL,
@@ -292,14 +462,9 @@ static int ehci_fsl_usb_setup(struct ehc
@@ -292,14 +462,9 @@ static int ehci_fsl_usb_setup(struct ehci_hcd *ehci)
return -EINVAL;
if (pdata->operating_mode == FSL_USB2_MPH_HOST) {
@ -1048,7 +1082,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
ehci->has_fsl_port_bug = 1;
if (pdata->port_enables & FSL_USB2_PORT0_ENABLED)
@@ -379,16 +544,57 @@ static int ehci_fsl_setup(struct usb_hcd
@@ -379,16 +544,57 @@ static int ehci_fsl_setup(struct usb_hcd *hcd)
return retval;
}
@ -1113,7 +1147,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
#ifdef CONFIG_PPC_MPC512x
static int ehci_fsl_mpc512x_drv_suspend(struct device *dev)
@@ -535,26 +741,43 @@ static inline int ehci_fsl_mpc512x_drv_r
@@ -535,26 +741,43 @@ static inline int ehci_fsl_mpc512x_drv_resume(struct device *dev)
}
#endif /* CONFIG_PPC_MPC512x */
@ -1164,7 +1198,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
if (!fsl_deep_sleep())
return 0;
@@ -568,12 +791,34 @@ static int ehci_fsl_drv_resume(struct de
@@ -568,12 +791,34 @@ static int ehci_fsl_drv_resume(struct device *dev)
struct ehci_fsl *ehci_fsl = hcd_to_ehci_fsl(hcd);
struct ehci_hcd *ehci = hcd_to_ehci(hcd);
void __iomem *non_ehci = hcd->regs;
@ -1199,6 +1233,8 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
ehci_prepare_ports_for_controller_resume(ehci);
if (!fsl_deep_sleep())
return 0;
diff --git a/drivers/usb/host/ehci-fsl.h b/drivers/usb/host/ehci-fsl.h
index 1a8a60a5..42ea2976 100644
--- a/drivers/usb/host/ehci-fsl.h
+++ b/drivers/usb/host/ehci-fsl.h
@@ -63,4 +63,7 @@
@ -1209,9 +1245,11 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
+/* Retry count for checking UTMI PHY CLK validity */
+#define UTMI_PHY_CLK_VALID_CHK_RETRY 5
#endif /* _EHCI_FSL_H */
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
index 255acca8..c8838c33 100644
--- a/drivers/usb/host/ehci-hub.c
+++ b/drivers/usb/host/ehci-hub.c
@@ -305,6 +305,8 @@ static int ehci_bus_suspend (struct usb_
@@ -305,6 +305,8 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
USB_PORT_STAT_HIGH_SPEED)
fs_idle_delay = true;
ehci_writel(ehci, t2, reg);
@ -1220,9 +1258,11 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
changed = 1;
}
}
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index 3b06bb77..f296d1fb 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -180,6 +180,9 @@ struct ehci_hcd { /* one per controlle
@@ -180,6 +180,9 @@ struct ehci_hcd { /* one per controller */
unsigned periodic_count; /* periodic activity count */
unsigned uframe_periodic_max; /* max periodic time per uframe */
@ -1232,7 +1272,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
/* list of itds & sitds completed while now_frame was still active */
struct list_head cached_itd_list;
@@ -706,8 +709,10 @@ ehci_port_speed(struct ehci_hcd *ehci, u
@@ -706,8 +709,10 @@ ehci_port_speed(struct ehci_hcd *ehci, unsigned int portsc)
* incoming packets get corrupted in HS mode
*/
#define ehci_has_fsl_hs_errata(e) ((e)->has_fsl_hs_errata)
@ -1243,9 +1283,11 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
#endif
/*
diff --git a/drivers/usb/host/fsl-mph-dr-of.c b/drivers/usb/host/fsl-mph-dr-of.c
index f07ccb25..1e59ea9f 100644
--- a/drivers/usb/host/fsl-mph-dr-of.c
+++ b/drivers/usb/host/fsl-mph-dr-of.c
@@ -226,6 +226,18 @@ static int fsl_usb2_mph_dr_of_probe(stru
@@ -226,6 +226,18 @@ static int fsl_usb2_mph_dr_of_probe(struct platform_device *ofdev)
of_property_read_bool(np, "fsl,usb-erratum-a007792");
pdata->has_fsl_erratum_a005275 =
of_property_read_bool(np, "fsl,usb-erratum-a005275");
@ -1264,6 +1306,8 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
/*
* Determine whether phy_clk_valid needs to be checked
diff --git a/drivers/usb/phy/phy-fsl-usb.c b/drivers/usb/phy/phy-fsl-usb.c
index 94eb2923..836355fa 100644
--- a/drivers/usb/phy/phy-fsl-usb.c
+++ b/drivers/usb/phy/phy-fsl-usb.c
@@ -1,5 +1,5 @@
@ -1281,7 +1325,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
struct device *dev;
struct fsl_otg *otg_dev =
container_of(otg->usb_phy, struct fsl_otg, phy);
@@ -486,6 +487,7 @@ int fsl_otg_start_host(struct otg_fsm *f
@@ -486,6 +487,7 @@ int fsl_otg_start_host(struct otg_fsm *fsm, int on)
otg_reset_controller();
VDBG("host on......\n");
if (dev->driver->pm && dev->driver->pm->resume) {
@ -1289,7 +1333,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
retval = dev->driver->pm->resume(dev);
if (fsm->id) {
/* default-b */
@@ -510,8 +512,11 @@ int fsl_otg_start_host(struct otg_fsm *f
@@ -510,8 +512,11 @@ int fsl_otg_start_host(struct otg_fsm *fsm, int on)
else {
VDBG("host off......\n");
if (dev && dev->driver) {
@ -1302,7 +1346,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
if (fsm->id)
/* default-b */
fsl_otg_drv_vbus(fsm, 0);
@@ -539,8 +544,17 @@ int fsl_otg_start_gadget(struct otg_fsm
@@ -539,8 +544,17 @@ int fsl_otg_start_gadget(struct otg_fsm *fsm, int on)
dev = otg->gadget->dev.parent;
if (on) {
@ -1321,7 +1365,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
} else {
if (dev->driver->suspend)
dev->driver->suspend(dev, otg_suspend_state);
@@ -672,6 +686,10 @@ static void fsl_otg_event(struct work_st
@@ -672,6 +686,10 @@ static void fsl_otg_event(struct work_struct *work)
fsl_otg_start_host(fsm, 0);
otg_drv_vbus(fsm, 0);
fsl_otg_start_gadget(fsm, 1);
@ -1332,7 +1376,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
}
}
@@ -724,6 +742,7 @@ irqreturn_t fsl_otg_isr(int irq, void *d
@@ -724,6 +742,7 @@ irqreturn_t fsl_otg_isr(int irq, void *dev_id)
{
struct otg_fsm *fsm = &((struct fsl_otg *)dev_id)->fsm;
struct usb_otg *otg = ((struct fsl_otg *)dev_id)->phy.otg;
@ -1340,7 +1384,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
u32 otg_int_src, otg_sc;
otg_sc = fsl_readl(&usb_dr_regs->otgsc);
@@ -753,18 +772,8 @@ irqreturn_t fsl_otg_isr(int irq, void *d
@@ -753,18 +772,8 @@ irqreturn_t fsl_otg_isr(int irq, void *dev_id)
otg->gadget->is_a_peripheral = !fsm->id;
VDBG("ID int (ID is %d)\n", fsm->id);
@ -1361,7 +1405,7 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
return IRQ_HANDLED;
}
}
@@ -923,12 +932,32 @@ int usb_otg_start(struct platform_device
@@ -923,12 +932,32 @@ int usb_otg_start(struct platform_device *pdev)
temp &= ~(PORTSC_PHY_TYPE_SEL | PORTSC_PTW);
switch (pdata->phy_mode) {
case FSL_USB2_PHY_ULPI:
@ -1394,6 +1438,8 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
temp |= PORTSC_PTS_UTMI;
/* fall through */
default:
diff --git a/drivers/usb/phy/phy-fsl-usb.h b/drivers/usb/phy/phy-fsl-usb.h
index 23149954..c4c08730 100644
--- a/drivers/usb/phy/phy-fsl-usb.h
+++ b/drivers/usb/phy/phy-fsl-usb.h
@@ -199,6 +199,14 @@
@ -1411,6 +1457,8 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
/* BCSR5 */
#define BCSR5_INT_USB (0x02)
diff --git a/include/linux/usb.h b/include/linux/usb.h
index eba1f10e..c334e281 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -362,6 +362,7 @@ struct usb_bus {
@ -1421,6 +1469,8 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
unsigned is_b_host:1; /* true during some HNP roleswitches */
unsigned b_hnp_enable:1; /* OTG: did A-Host enable HNP? */
unsigned no_stop_on_short:1; /*
diff --git a/include/linux/usb/of.h b/include/linux/usb/of.h
index 5ff9032e..2a57e0d2 100644
--- a/include/linux/usb/of.h
+++ b/include/linux/usb/of.h
@@ -11,6 +11,8 @@
@ -1432,3 +1482,6 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
#if IS_ENABLED(CONFIG_OF)
enum usb_dr_mode of_usb_get_dr_mode_by_phy(struct device_node *np, int arg0);
bool of_usb_host_tpl_support(struct device_node *np);
--
2.14.1