mvebu: add inital support for Marvell Armada XP/370 SoCs

This brings in the initial support for the Marvell Armada XP/370 SoCs.
Successfully tested on RD-A370-A1 and DB-MV784MP-GP boards the following
interfaces:

- Ethernet
- SDIO
- GPIOs
- SATA

Signed-off-by: Florian Fainelli <florian@openwrt.org>

SVN-Revision: 35058
v19.07.3_mercusys_ac12_duma
Florian Fainelli 12 years ago
parent 97acd10458
commit 25475a095e

@ -1025,6 +1025,7 @@ CONFIG_HZ_100=y
# CONFIG_I2C_ALI15X3 is not set
# CONFIG_I2C_AMD756 is not set
# CONFIG_I2C_AMD8111 is not set
# CONFIG_I2C_CBUS_GPIO is not set
# CONFIG_I2C_CHARDEV is not set
# CONFIG_I2C_COMPAT is not set
# CONFIG_I2C_DEBUG_ALGO is not set

@ -0,0 +1,24 @@
#
# Copyright (C) 2012 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
include $(TOPDIR)/rules.mk
ARCH:=arm
BOARD:=mvebu
BOARDNAME:=Marvell Armada XP/370 boards
FEATURES:=targz usb jffs2 pci pcie gpio
CFLAGS:=-Os -pipe -march=armv7-a -mfpu=vfpv3-d16 -mfloat-abi=softfp
MAINTAINER:=Florian Fainelli <florian@openwrt.org>
LINUX_VERSION:=3.8-rc2
include $(INCLUDE_DIR)/target.mk
KERNELNAME:="zImage dtbs"
DEFAULT_PACKAGES +=
$(eval $(call BuildTarget))

@ -0,0 +1,255 @@
CONFIG_ALIGNMENT_TRAP=y
# CONFIG_AMBA_PL08X is not set
# CONFIG_ARCH_BCM is not set
CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y
CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y
CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y
CONFIG_ARCH_MULTIPLATFORM=y
# CONFIG_ARCH_MULTI_CPU_AUTO is not set
# CONFIG_ARCH_MULTI_V6 is not set
CONFIG_ARCH_MULTI_V6_V7=y
CONFIG_ARCH_MULTI_V7=y
CONFIG_ARCH_MVEBU=y
# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set
CONFIG_ARCH_NR_GPIO=0
CONFIG_ARCH_REQUIRE_GPIOLIB=y
# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
# CONFIG_ARCH_SUNXI is not set
CONFIG_ARCH_SUSPEND_POSSIBLE=y
CONFIG_ARCH_VEXPRESS=y
# CONFIG_ARCH_VEXPRESS_CA9X4 is not set
CONFIG_ARCH_VEXPRESS_CORTEX_A5_A9_ERRATA=y
# CONFIG_ARCH_VT8500_SINGLE is not set
CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
CONFIG_ARM=y
CONFIG_ARMADA_370_XP_TIMER=y
CONFIG_ARM_AMBA=y
CONFIG_ARM_APPENDED_DTB=y
# CONFIG_ARM_ATAG_DTB_COMPAT is not set
# CONFIG_ARM_CHARLCD is not set
# CONFIG_ARM_CPU_SUSPEND is not set
# CONFIG_ARM_ERRATA_430973 is not set
# CONFIG_ARM_ERRATA_458693 is not set
# CONFIG_ARM_ERRATA_460075 is not set
CONFIG_ARM_ERRATA_720789=y
# CONFIG_ARM_ERRATA_743622 is not set
CONFIG_ARM_ERRATA_751472=y
# CONFIG_ARM_ERRATA_754322 is not set
CONFIG_ARM_GIC=y
CONFIG_ARM_L1_CACHE_SHIFT=6
CONFIG_ARM_L1_CACHE_SHIFT_6=y
# CONFIG_ARM_LPAE is not set
CONFIG_ARM_NR_BANKS=8
CONFIG_ARM_PATCH_PHYS_VIRT=y
# CONFIG_ARM_SP805_WATCHDOG is not set
CONFIG_ARM_THUMB=y
# CONFIG_ARM_THUMBEE is not set
CONFIG_ARM_TIMER_SP804=y
CONFIG_ASYNC_TX_DMA=y
CONFIG_ASYNC_TX_ENABLE_CHANNEL_SWITCH=y
CONFIG_ATAGS=y
CONFIG_AUTO_ZRELADDR=y
CONFIG_BOUNCE=y
CONFIG_CACHE_L2X0=y
CONFIG_CACHE_PL310=y
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_CLKDEV_LOOKUP=y
CONFIG_CLKSRC_MMIO=y
CONFIG_CLONE_BACKWARDS=y
CONFIG_COMMON_CLK=y
CONFIG_COMMON_CLK_VERSATILE=y
CONFIG_CPU_32v6K=y
CONFIG_CPU_32v7=y
CONFIG_CPU_ABRT_EV7=y
# CONFIG_CPU_BPREDICT_DISABLE is not set
CONFIG_CPU_CACHE_V7=y
CONFIG_CPU_CACHE_VIPT=y
CONFIG_CPU_COPY_V6=y
CONFIG_CPU_CP15=y
CONFIG_CPU_CP15_MMU=y
CONFIG_CPU_HAS_ASID=y
# CONFIG_CPU_ICACHE_DISABLE is not set
CONFIG_CPU_PABRT_V7=y
CONFIG_CPU_PJ4B=y
CONFIG_CPU_TLB_V7=y
CONFIG_CPU_V7=y
CONFIG_CRC_ITU_T=m
CONFIG_CRYPTO_AES=y
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_ALGAPI2=y
CONFIG_DCACHE_WORD_ACCESS=y
CONFIG_DEBUG_INFO=y
CONFIG_DEBUG_LL=y
CONFIG_DEBUG_LL_INCLUDE="debug/mvebu.S"
CONFIG_DEBUG_MVEBU_UART=y
# CONFIG_DEBUG_PINCTRL is not set
CONFIG_DEBUG_USER=y
# CONFIG_DEBUG_VEXPRESS_UART0_CA9 is not set
# CONFIG_DEBUG_VEXPRESS_UART0_DETECT is not set
# CONFIG_DEBUG_VEXPRESS_UART0_RS1 is not set
CONFIG_DECOMPRESS_LZMA=y
CONFIG_DMADEVICES=y
CONFIG_DMA_ENGINE=y
CONFIG_DTC=y
# CONFIG_DW_DMAC is not set
CONFIG_EARLY_PRINTK=y
CONFIG_EXT2_FS=y
CONFIG_EXT3_FS=y
CONFIG_FAT_FS=y
CONFIG_FRAME_POINTER=y
CONFIG_GENERIC_BUG=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
CONFIG_GENERIC_GPIO=y
CONFIG_GENERIC_IO=y
CONFIG_GENERIC_IRQ_CHIP=y
CONFIG_GENERIC_IRQ_SHOW=y
CONFIG_GENERIC_PCI_IOMAP=y
CONFIG_GENERIC_SMP_IDLE_THREAD=y
CONFIG_GENERIC_STRNCPY_FROM_USER=y
CONFIG_GENERIC_STRNLEN_USER=y
CONFIG_GPIOLIB=y
CONFIG_GPIO_GENERIC=y
CONFIG_GPIO_MVEBU=y
CONFIG_GPIO_SYSFS=y
CONFIG_HARDIRQS_SW_RESEND=y
CONFIG_HAS_DMA=y
CONFIG_HAS_IOMEM=y
CONFIG_HAVE_AOUT=y
CONFIG_HAVE_ARCH_JUMP_LABEL=y
CONFIG_HAVE_ARCH_KGDB=y
CONFIG_HAVE_ARCH_PFN_VALID=y
CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_HAVE_BPF_JIT=y
CONFIG_HAVE_CLK=y
CONFIG_HAVE_CLK_PREPARE=y
CONFIG_HAVE_C_RECORDMCOUNT=y
CONFIG_HAVE_DEBUG_KMEMLEAK=y
CONFIG_HAVE_DMA_API_DEBUG=y
CONFIG_HAVE_DMA_ATTRS=y
CONFIG_HAVE_DMA_CONTIGUOUS=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
CONFIG_HAVE_GENERIC_HARDIRQS=y
CONFIG_HAVE_IRQ_WORK=y
CONFIG_HAVE_KERNEL_GZIP=y
CONFIG_HAVE_KERNEL_LZMA=y
CONFIG_HAVE_KERNEL_LZO=y
CONFIG_HAVE_KERNEL_XZ=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
CONFIG_HAVE_MEMBLOCK=y
CONFIG_HAVE_NET_DSA=y
CONFIG_HAVE_OPROFILE=y
CONFIG_HAVE_PATA_PLATFORM=y
CONFIG_HAVE_PERF_EVENTS=y
CONFIG_HAVE_PROC_CPU=y
CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
CONFIG_HAVE_SMP=y
CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
CONFIG_HAVE_UID16=y
CONFIG_HIGHMEM=y
# CONFIG_HIGHPTE is not set
CONFIG_ICST=y
CONFIG_INITRAMFS_SOURCE=""
CONFIG_IRQ_DOMAIN=y
CONFIG_IRQ_DOMAIN_DEBUG=y
CONFIG_ISO9660_FS=y
CONFIG_JBD=y
CONFIG_JUMP_LABEL=y
CONFIG_KTIME_SCALAR=y
CONFIG_LOG_BUF_SHIFT=14
CONFIG_MACH_ARMADA_370=y
CONFIG_MACH_ARMADA_370_XP=y
CONFIG_MACH_ARMADA_XP=y
CONFIG_MAGIC_SYSRQ=y
CONFIG_MDIO_BOARDINFO=y
CONFIG_MIGHT_HAVE_CACHE_L2X0=y
CONFIG_MODULES_USE_ELF_REL=y
CONFIG_MSDOS_FS=y
CONFIG_MTD_OF_PARTS=y
# CONFIG_MTD_PHYSMAP_OF is not set
CONFIG_MULTI_IRQ_HANDLER=y
CONFIG_MVEBU_CLK_CORE=y
CONFIG_MVEBU_CLK_CPU=y
CONFIG_MVEBU_CLK_GATING=y
CONFIG_MVMDIO=y
CONFIG_MVNETA=y
CONFIG_MV_XOR=y
CONFIG_NEED_DMA_MAP_STATE=y
CONFIG_NEED_PER_CPU_KM=y
# CONFIG_NEON is not set
CONFIG_NET_DMA=y
CONFIG_NLS=y
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_CODEPAGE_850=y
CONFIG_NLS_ISO8859_1=y
CONFIG_NLS_ISO8859_2=y
CONFIG_NLS_UTF8=y
CONFIG_NO_IOPORT=y
CONFIG_OF=y
CONFIG_OF_ADDRESS=y
CONFIG_OF_DEVICE=y
CONFIG_OF_EARLY_FLATTREE=y
CONFIG_OF_FLATTREE=y
CONFIG_OF_GPIO=y
CONFIG_OF_IRQ=y
CONFIG_OF_MDIO=y
CONFIG_OF_MTD=y
CONFIG_OF_NET=y
CONFIG_OUTER_CACHE=y
CONFIG_OUTER_CACHE_SYNC=y
CONFIG_PAGEFLAGS_EXTENDED=y
CONFIG_PAGE_OFFSET=0xC0000000
# CONFIG_PCI_SYSCALL is not set
CONFIG_PERCPU_RWSEM=y
CONFIG_PERF_USE_VMALLOC=y
CONFIG_PHYLIB=y
CONFIG_PINCONF=y
CONFIG_PINCTRL=y
CONFIG_PINCTRL_ARMADA_370=y
CONFIG_PINCTRL_ARMADA_XP=y
# CONFIG_PINCTRL_EXYNOS4 is not set
CONFIG_PINCTRL_MVEBU=y
# CONFIG_PINCTRL_SINGLE is not set
CONFIG_PINMUX=y
# CONFIG_PL310_ERRATA_588369 is not set
# CONFIG_PL310_ERRATA_727915 is not set
CONFIG_PL310_ERRATA_753970=y
# CONFIG_PL310_ERRATA_769419 is not set
# CONFIG_PL330_DMA is not set
CONFIG_PLAT_ORION=y
CONFIG_PLAT_VERSATILE=y
CONFIG_PLAT_VERSATILE_CLCD=y
CONFIG_PLAT_VERSATILE_SCHED_CLOCK=y
# CONFIG_PREEMPT_RCU is not set
# CONFIG_SCSI_DMA is not set
# CONFIG_SERIAL_AMBA_PL010 is not set
# CONFIG_SERIAL_AMBA_PL011 is not set
CONFIG_SERIAL_OF_PLATFORM=y
CONFIG_SERIAL_8250_DW=y
CONFIG_SPARSE_IRQ=y
# CONFIG_SWP_EMULATE is not set
CONFIG_SYS_SUPPORTS_APM_EMULATION=y
# CONFIG_THUMB2_KERNEL is not set
CONFIG_TICK_CPU_ACCOUNTING=y
CONFIG_TIMER_STATS=y
CONFIG_UDF_FS=m
CONFIG_UID16=y
CONFIG_UIDGID_CONVERTED=y
# CONFIG_USB_ARCH_HAS_OHCI is not set
# CONFIG_USB_ARCH_HAS_XHCI is not set
CONFIG_USE_OF=y
CONFIG_VECTORS_BASE=0xffff0000
CONFIG_VEXPRESS_CONFIG=y
CONFIG_VFAT_FS=y
CONFIG_VFP=y
CONFIG_VFPv3=y
# CONFIG_XEN is not set
CONFIG_ZBOOT_ROM_BSS=0x0
CONFIG_ZBOOT_ROM_TEXT=0x0
CONFIG_ZONE_DMA_FLAG=0

@ -0,0 +1,51 @@
#
# Copyright (C) 2012 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/image.mk
TARGET_DTBS := armada-xp-db armada-370-db armada-xp-openblocks-ax3-4 armada-370-mirabox
LOADADDR:=0x00008000
JFFS2_BLOCKSIZE = 128k
UIMAGE:=$(BIN_DIR)/$(IMG_PREFIX)-uImage
ifeq ($(CONFIG_TARGET_ROOTFS_INITRAMFS),y)
UIMAGE:=$(BIN_DIR)/$(IMG_PREFIX)-uImage-initramfs
endif
define Image/Build/MkuImage
mkimage -A arm -O linux -T kernel -a $(LOADADDR) -C none -e $(LOADADDR) \
-n 'ARM OpenWrt Linux-$(LINUX_VERSION)' -d $(1) $(2);
endef
define Image/Build/DTB
cp $(KDIR)/zImage $(KDIR)/zImage-$(1);
cat $(LINUX_DIR)/arch/$(ARCH)/boot/dts/$(1).dtb >> $(KDIR)/zImage-$(1);
$(call Image/Build/MkuImage,$(KDIR)/zImage-$(1),$(KDIR)/uImage-$(1))
cp $(KDIR)/uImage-$(1) $(UIMAGE)-$(1);
endef
define Image/Prepare
cp $(LINUX_DIR)/arch/$(ARCH)/boot/zImage $(KDIR)/zImage
endef
define Image/BuildKernel
$(foreach dtb,$(TARGET_DTBS),$(call Image/Build/DTB,$(dtb)))
$(call Image/Build/Initramfs)
endef
define Image/Build/squashfs
$(STAGING_DIR_HOST)/bin/padjffs2 $(KDIR)/root.squashfs 128
endef
define Image/Build
$(call Image/Build/$(1))
dd if=$(KDIR)/root.$(1) of=$(BIN_DIR)/$(IMG_PREFIX)-root.$(1) bs=128k conv=sync
endef
$(eval $(call BuildImage))

@ -0,0 +1,28 @@
From: Joshua Coombs <josh.coombs@gmail.com>
If the Orion WDT driver is built as a module, an opps occurs during
clk lookup when calling mvebu_clk_gating_get_src(). Remove the
inappropriate __init tag so the function is available for modules
after kernel init.
Signed-off-by: Joshua Coombs <josh.coombs@gmail.com>
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
drivers/clk/mvebu/clk-gating-ctrl.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/clk/mvebu/clk-gating-ctrl.c b/drivers/clk/mvebu/clk-gating-ctrl.c
index c6d3c26..8fa5408 100644
--- a/drivers/clk/mvebu/clk-gating-ctrl.c
+++ b/drivers/clk/mvebu/clk-gating-ctrl.c
@@ -32,7 +32,7 @@ struct mvebu_soc_descr {
#define to_clk_gate(_hw) container_of(_hw, struct clk_gate, hw)
-static struct clk __init *mvebu_clk_gating_get_src(
+static struct clk *mvebu_clk_gating_get_src(
struct of_phandle_args *clkspec, void *data)
{
struct mvebu_gating_ctrl *ctrl = (struct mvebu_gating_ctrl *)data;
--
1.7.10.4

@ -0,0 +1,38 @@
From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
When mv_xor_channel_add() fails for one XOR channel, we jump to the
err_channel_add label to clean up all previous channels that had been
initialized correctly. Unfortunately, while handling this error
condition, we were disposing the IRQ mapping before calling
mv_xor_channel_remove() (which does the free_irq()), which is
incorrect.
Instead, do things properly in the reverse order of the
initialization: first remove the XOR channel (so that free_irq() is
done), and then dispose the IRQ mapping.
This avoids ugly warnings when for some reason one of the XOR channel
fails to initialize.
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
drivers/dma/mv_xor.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c
index ac71f55..cc5d23d 100644
--- a/drivers/dma/mv_xor.c
+++ b/drivers/dma/mv_xor.c
@@ -1361,9 +1361,9 @@ static int mv_xor_probe(struct platform_device *pdev)
err_channel_add:
for (i = 0; i < MV_XOR_MAX_CHANNELS; i++)
if (xordev->channels[i]) {
+ mv_xor_channel_remove(xordev->channels[i]);
if (pdev->dev.of_node)
irq_dispose_mapping(xordev->channels[i]->irq);
- mv_xor_channel_remove(xordev->channels[i]);
}
clk_disable_unprepare(xordev->clk);
--
1.7.10.4

@ -0,0 +1,35 @@
From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
When a channel fails to initialize, we release all ressources,
including clocks. However, a XOR unit is not necessarily associated to
a clock (some variants of Marvell SoCs have a clock for XOR units,
some don't), so we shouldn't unconditionally be releasing the clock.
Instead, just like we do in the mv_xor_remove() function, we should
check if one clock was found before releasing it.
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
drivers/dma/mv_xor.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c
index cc5d23d..e17fad0 100644
--- a/drivers/dma/mv_xor.c
+++ b/drivers/dma/mv_xor.c
@@ -1366,8 +1366,11 @@ err_channel_add:
irq_dispose_mapping(xordev->channels[i]->irq);
}
- clk_disable_unprepare(xordev->clk);
- clk_put(xordev->clk);
+ if (!IS_ERR(xordev->clk)) {
+ clk_disable_unprepare(xordev->clk);
+ clk_put(xordev->clk);
+ }
+
return ret;
}
--
1.7.10.4

@ -0,0 +1,75 @@
From: Dmitri Epshtein <dima@marvell.com>
In order for the driver to behave properly in a SMP context, the same
transmit queue should be used by the kernel in dev_queue_xmit() and in
the driver's mvneta_tx() function. To achieve that, the driver now
implements the ->ndo_select_txq() operation.
For now, it always returns the same transmit queue, txq_def, until the
driver is expanded to properly take advantage of the multiqueue
capabilities of the hardware.
Without this patch, the network driver crashes the kernel almost
immediately on Armada XP platforms, if the network load is at least a
little bit parallel (i.e several threads).
[Thomas Petazzoni: reword commit message]
Signed-off-by: Dmitri Epshtein <dima@marvell.com>
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
This is 3.8-rc material.
---
drivers/net/ethernet/marvell/mvneta.c | 17 +++++++++++++++--
1 file changed, 15 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
index b6025c3..af2c421 100644
--- a/drivers/net/ethernet/marvell/mvneta.c
+++ b/drivers/net/ethernet/marvell/mvneta.c
@@ -1310,6 +1310,17 @@ static u32 mvneta_skb_tx_csum(struct mvneta_port *pp, struct sk_buff *skb)
return MVNETA_TX_L4_CSUM_NOT;
}
+static u16 mvneta_tx_policy(struct mvneta_port *pp, struct sk_buff *skb)
+{
+ return (u16)txq_def;
+}
+
+static u16 mvneta_select_txq(struct net_device *dev, struct sk_buff *skb)
+{
+ struct mvneta_port *pp = netdev_priv(dev);
+ return mvneta_tx_policy(pp, skb);
+}
+
/* Returns rx queue pointer (find last set bit) according to causeRxTx
* value
*/
@@ -1476,7 +1487,8 @@ error:
static int mvneta_tx(struct sk_buff *skb, struct net_device *dev)
{
struct mvneta_port *pp = netdev_priv(dev);
- struct mvneta_tx_queue *txq = &pp->txqs[txq_def];
+ u16 txq_id = mvneta_tx_policy(pp, skb);
+ struct mvneta_tx_queue *txq = &pp->txqs[txq_id];
struct mvneta_tx_desc *tx_desc;
struct netdev_queue *nq;
int frags = 0;
@@ -1486,7 +1498,7 @@ static int mvneta_tx(struct sk_buff *skb, struct net_device *dev)
goto out;
frags = skb_shinfo(skb)->nr_frags + 1;
- nq = netdev_get_tx_queue(dev, txq_def);
+ nq = netdev_get_tx_queue(dev, txq_id);
/* Get a descriptor for the first part of the packet */
tx_desc = mvneta_txq_next_desc_get(txq);
@@ -2550,6 +2562,7 @@ static const struct net_device_ops mvneta_netdev_ops = {
.ndo_change_mtu = mvneta_change_mtu,
.ndo_tx_timeout = mvneta_tx_timeout,
.ndo_get_stats64 = mvneta_get_stats64,
+ .ndo_select_queue = mvneta_select_txq,
};
const struct ethtool_ops mvneta_eth_tool_ops = {
--
1.7.9.5

@ -0,0 +1,174 @@
The Armada XP GPIO controller has two ways of notifying interrupts:
using global interrupts or using per-CPU interrupts. In an attempt to
use the best available features, the 'marvell,armadaxp-gpio'
compatible string selects a variant of the gpio-mvebu driver that
makes use of the per-CPU interrupts.
Unfortunately, this doesn't work properly in a SMP context, because we
fall into cases where the GPIO interrupt is enabled on CPU X at the
GPIO controller level, but on CPU Y at the interrupt controller
level. It is not yet clear how to fix that easily.
So for 3.8, our approach is to switch to global interrupts for GPIOs,
so that we do not fall into this per-CPU interrupts problem.
This patch therefore fixes GPIO interrupts on Armada XP
platforms. Without this patch, GPIO interrupts simply do not work
reliably, because their proper operation depends on which CPU the code
requesting the interrupt is running.
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
This is 3.8-rc material.
---
arch/arm/boot/dts/armada-xp-mv78230.dtsi | 14 ++++++--------
arch/arm/boot/dts/armada-xp-mv78260.dtsi | 21 +++++++++------------
arch/arm/boot/dts/armada-xp-mv78460.dtsi | 21 +++++++++------------
3 files changed, 24 insertions(+), 32 deletions(-)
diff --git a/arch/arm/boot/dts/armada-xp-mv78230.dtsi b/arch/arm/boot/dts/armada-xp-mv78230.dtsi
index 271855a..e041f42 100644
--- a/arch/arm/boot/dts/armada-xp-mv78230.dtsi
+++ b/arch/arm/boot/dts/armada-xp-mv78230.dtsi
@@ -50,27 +50,25 @@
};
gpio0: gpio@d0018100 {
- compatible = "marvell,armadaxp-gpio";
- reg = <0xd0018100 0x40>,
- <0xd0018800 0x30>;
+ compatible = "marvell,orion-gpio";
+ reg = <0xd0018100 0x40>;
ngpios = <32>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupts-cells = <2>;
- interrupts = <16>, <17>, <18>, <19>;
+ interrupts = <82>, <83>, <84>, <85>;
};
gpio1: gpio@d0018140 {
- compatible = "marvell,armadaxp-gpio";
- reg = <0xd0018140 0x40>,
- <0xd0018840 0x30>;
+ compatible = "marvell,orion-gpio";
+ reg = <0xd0018140 0x40>;
ngpios = <17>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupts-cells = <2>;
- interrupts = <20>, <21>, <22>;
+ interrupts = <87>, <88>, <89>;
};
};
};
diff --git a/arch/arm/boot/dts/armada-xp-mv78260.dtsi b/arch/arm/boot/dts/armada-xp-mv78260.dtsi
index 1c1937d..9e23bd8 100644
--- a/arch/arm/boot/dts/armada-xp-mv78260.dtsi
+++ b/arch/arm/boot/dts/armada-xp-mv78260.dtsi
@@ -51,39 +51,36 @@
};
gpio0: gpio@d0018100 {
- compatible = "marvell,armadaxp-gpio";
- reg = <0xd0018100 0x40>,
- <0xd0018800 0x30>;
+ compatible = "marvell,orion-gpio";
+ reg = <0xd0018100 0x40>;
ngpios = <32>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupts-cells = <2>;
- interrupts = <16>, <17>, <18>, <19>;
+ interrupts = <82>, <83>, <84>, <85>;
};
gpio1: gpio@d0018140 {
- compatible = "marvell,armadaxp-gpio";
- reg = <0xd0018140 0x40>,
- <0xd0018840 0x30>;
+ compatible = "marvell,orion-gpio";
+ reg = <0xd0018140 0x40>;
ngpios = <32>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupts-cells = <2>;
- interrupts = <20>, <21>, <22>, <23>;
+ interrupts = <87>, <88>, <89>, <90>;
};
gpio2: gpio@d0018180 {
- compatible = "marvell,armadaxp-gpio";
- reg = <0xd0018180 0x40>,
- <0xd0018870 0x30>;
+ compatible = "marvell,orion-gpio";
+ reg = <0xd0018180 0x40>;
ngpios = <3>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupts-cells = <2>;
- interrupts = <24>;
+ interrupts = <91>;
};
ethernet@d0034000 {
diff --git a/arch/arm/boot/dts/armada-xp-mv78460.dtsi b/arch/arm/boot/dts/armada-xp-mv78460.dtsi
index 4905cf3..9659661 100644
--- a/arch/arm/boot/dts/armada-xp-mv78460.dtsi
+++ b/arch/arm/boot/dts/armada-xp-mv78460.dtsi
@@ -66,39 +66,36 @@
};
gpio0: gpio@d0018100 {
- compatible = "marvell,armadaxp-gpio";
- reg = <0xd0018100 0x40>,
- <0xd0018800 0x30>;
+ compatible = "marvell,orion-gpio";
+ reg = <0xd0018100 0x40>;
ngpios = <32>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupts-cells = <2>;
- interrupts = <16>, <17>, <18>, <19>;
+ interrupts = <82>, <83>, <84>, <85>;
};
gpio1: gpio@d0018140 {
- compatible = "marvell,armadaxp-gpio";
- reg = <0xd0018140 0x40>,
- <0xd0018840 0x30>;
+ compatible = "marvell,orion-gpio";
+ reg = <0xd0018140 0x40>;
ngpios = <32>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupts-cells = <2>;
- interrupts = <20>, <21>, <22>, <23>;
+ interrupts = <87>, <88>, <89>, <90>;
};
gpio2: gpio@d0018180 {
- compatible = "marvell,armadaxp-gpio";
- reg = <0xd0018180 0x40>,
- <0xd0018870 0x30>;
+ compatible = "marvell,orion-gpio";
+ reg = <0xd0018180 0x40>;
ngpios = <3>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupts-cells = <2>;
- interrupts = <24>;
+ interrupts = <91>;
};
ethernet@d0034000 {
--
1.7.9.5

@ -0,0 +1,101 @@
The MMC core subsystem provides in drivers/mmc/core/slot-gpio.c a nice
set of helper functions to simplify the management of the write
protect GPIO in MMC host drivers. This patch migrates the mvsdio
driver to using those helpers, which will make the ->probe() code
simpler, and therefore ease the process of adding a Device Tree
binding for this driver.
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
drivers/mmc/host/mvsdio.c | 34 +++++-----------------------------
1 file changed, 5 insertions(+), 29 deletions(-)
diff --git a/drivers/mmc/host/mvsdio.c b/drivers/mmc/host/mvsdio.c
index de4c20b..a24a22f 100644
--- a/drivers/mmc/host/mvsdio.c
+++ b/drivers/mmc/host/mvsdio.c
@@ -22,6 +22,7 @@
#include <linux/clk.h>
#include <linux/gpio.h>
#include <linux/mmc/host.h>
+#include <linux/mmc/slot-gpio.h>
#include <asm/sizes.h>
#include <asm/unaligned.h>
@@ -54,7 +55,6 @@ struct mvsd_host {
int irq;
struct clk *clk;
int gpio_card_detect;
- int gpio_write_protect;
};
#define mvsd_write(offs, val) writel(val, iobase + (offs))
@@ -566,20 +566,6 @@ static void mvsd_enable_sdio_irq(struct mmc_host *mmc, int enable)
spin_unlock_irqrestore(&host->lock, flags);
}
-static int mvsd_get_ro(struct mmc_host *mmc)
-{
- struct mvsd_host *host = mmc_priv(mmc);
-
- if (host->gpio_write_protect)
- return gpio_get_value(host->gpio_write_protect);
-
- /*
- * Board doesn't support read only detection; let the mmc core
- * decide what to do.
- */
- return -ENOSYS;
-}
-
static void mvsd_power_up(struct mvsd_host *host)
{
void __iomem *iobase = host->base;
@@ -676,7 +662,7 @@ static void mvsd_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
static const struct mmc_host_ops mvsd_ops = {
.request = mvsd_request,
- .get_ro = mvsd_get_ro,
+ .get_ro = mmc_gpio_get_ro,
.set_ios = mvsd_set_ios,
.enable_sdio_irq = mvsd_enable_sdio_irq,
};
@@ -798,15 +784,7 @@ static int __init mvsd_probe(struct platform_device *pdev)
if (!host->gpio_card_detect)
mmc->caps |= MMC_CAP_NEEDS_POLL;
- if (mvsd_data->gpio_write_protect) {
- ret = gpio_request(mvsd_data->gpio_write_protect,
- DRIVER_NAME " wp");
- if (ret == 0) {
- gpio_direction_input(mvsd_data->gpio_write_protect);
- host->gpio_write_protect =
- mvsd_data->gpio_write_protect;
- }
- }
+ mmc_gpio_request_ro(mmc, mvsd_data->gpio_write_protect);
setup_timer(&host->timer, mvsd_timeout_timer, (unsigned long)host);
platform_set_drvdata(pdev, mmc);
@@ -831,8 +809,7 @@ out:
free_irq(gpio_to_irq(host->gpio_card_detect), host);
gpio_free(host->gpio_card_detect);
}
- if (host->gpio_write_protect)
- gpio_free(host->gpio_write_protect);
+ mmc_gpio_free_ro(mmc);
if (host->base)
iounmap(host->base);
}
@@ -861,8 +838,7 @@ static int __exit mvsd_remove(struct platform_device *pdev)
}
mmc_remove_host(mmc);
free_irq(host->irq, host);
- if (host->gpio_write_protect)
- gpio_free(host->gpio_write_protect);
+ mmc_gpio_free_ro(mmc);
del_timer_sync(&host->timer);
mvsd_power_down(host);
iounmap(host->base);
--
1.7.9.5

@ -0,0 +1,105 @@
The MMC core subsystem provides in drivers/mmc/core/slot-gpio.c a nice
set of helper functions to simplify the management of the card detect
GPIO in MMC host drivers. This patch migrates the mvsdio driver to
using those helpers, which will make the ->probe() code simpler, and
therefore ease the process of adding a Device Tree binding for this
driver.
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
drivers/mmc/host/mvsdio.c | 44 +++++++++-----------------------------------
1 file changed, 9 insertions(+), 35 deletions(-)
diff --git a/drivers/mmc/host/mvsdio.c b/drivers/mmc/host/mvsdio.c
index a24a22f..baf19fc 100644
--- a/drivers/mmc/host/mvsdio.c
+++ b/drivers/mmc/host/mvsdio.c
@@ -54,7 +54,6 @@ struct mvsd_host {
struct resource *res;
int irq;
struct clk *clk;
- int gpio_card_detect;
};
#define mvsd_write(offs, val) writel(val, iobase + (offs))
@@ -540,13 +539,6 @@ static void mvsd_timeout_timer(unsigned long data)
mmc_request_done(host->mmc, mrq);
}
-static irqreturn_t mvsd_card_detect_irq(int irq, void *dev)
-{
- struct mvsd_host *host = dev;
- mmc_detect_change(host->mmc, msecs_to_jiffies(100));
- return IRQ_HANDLED;
-}
-
static void mvsd_enable_sdio_irq(struct mmc_host *mmc, int enable)
{
struct mvsd_host *host = mmc_priv(mmc);
@@ -765,23 +757,11 @@ static int __init mvsd_probe(struct platform_device *pdev)
clk_prepare_enable(host->clk);
}
- if (mvsd_data->gpio_card_detect) {
- ret = gpio_request(mvsd_data->gpio_card_detect,
- DRIVER_NAME " cd");
- if (ret == 0) {
- gpio_direction_input(mvsd_data->gpio_card_detect);
- irq = gpio_to_irq(mvsd_data->gpio_card_detect);
- ret = request_irq(irq, mvsd_card_detect_irq,
- IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING,
- DRIVER_NAME " cd", host);
- if (ret == 0)
- host->gpio_card_detect =
- mvsd_data->gpio_card_detect;
- else
- gpio_free(mvsd_data->gpio_card_detect);
- }
- }
- if (!host->gpio_card_detect)
+ if (gpio_is_valid(mvsd_data->gpio_card_detect)) {
+ ret = mmc_gpio_request_cd(mmc, mvsd_data->gpio_card_detect);
+ if (ret)
+ goto out;
+ } else
mmc->caps |= MMC_CAP_NEEDS_POLL;
mmc_gpio_request_ro(mmc, mvsd_data->gpio_write_protect);
@@ -794,9 +774,9 @@ static int __init mvsd_probe(struct platform_device *pdev)
pr_notice("%s: %s driver initialized, ",
mmc_hostname(mmc), DRIVER_NAME);
- if (host->gpio_card_detect)
+ if (!(mmc->caps & MMC_CAP_NEEDS_POLL))
printk("using GPIO %d for card detection\n",
- host->gpio_card_detect);
+ mvsd_data->gpio_card_detect);
else
printk("lacking card detect (fall back to polling)\n");
return 0;
@@ -805,10 +785,7 @@ out:
if (host) {
if (host->irq)
free_irq(host->irq, host);
- if (host->gpio_card_detect) {
- free_irq(gpio_to_irq(host->gpio_card_detect), host);
- gpio_free(host->gpio_card_detect);
- }
+ mmc_gpio_free_cd(mmc);
mmc_gpio_free_ro(mmc);
if (host->base)
iounmap(host->base);
@@ -832,10 +809,7 @@ static int __exit mvsd_remove(struct platform_device *pdev)
if (mmc) {
struct mvsd_host *host = mmc_priv(mmc);
- if (host->gpio_card_detect) {
- free_irq(gpio_to_irq(host->gpio_card_detect), host);
- gpio_free(host->gpio_card_detect);
- }
+ mmc_gpio_free_cd(mmc);
mmc_remove_host(mmc);
free_irq(host->irq, host);
mmc_gpio_free_ro(mmc);
--
1.7.9.5

@ -0,0 +1,169 @@
This patch adds a simple Device Tree binding for the mvsdio driver, as
well as the necessary documentation for it. Compatibility with non-DT
platforms is preserved, by keeping the platform_data based
initialization.
We introduce a small difference between non-DT and DT platforms: DT
platforms are required to provide a clocks = <...> property, which the
driver uses to get the frequency of the clock that goes to the SDIO
IP. The behaviour on non-DT platforms is kept unchanged: a clock
reference is not mandatory, but the clock frequency must be passed in
the "clock" field of the mvsdio_platform_data structure.
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
.../devicetree/bindings/mmc/orion-sdio.txt | 17 ++++++
drivers/mmc/host/mvsdio.c | 60 +++++++++++++++-----
2 files changed, 62 insertions(+), 15 deletions(-)
create mode 100644 Documentation/devicetree/bindings/mmc/orion-sdio.txt
diff --git a/Documentation/devicetree/bindings/mmc/orion-sdio.txt b/Documentation/devicetree/bindings/mmc/orion-sdio.txt
new file mode 100644
index 0000000..84f0ebd
--- /dev/null
+++ b/Documentation/devicetree/bindings/mmc/orion-sdio.txt
@@ -0,0 +1,17 @@
+* Marvell orion-sdio controller
+
+This file documents differences between the core properties in mmc.txt
+and the properties used by the orion-sdio driver.
+
+- compatible: Should be "marvell,orion-sdio"
+- clocks: reference to the clock of the SDIO interface
+
+Example:
+
+ mvsdio@d00d4000 {
+ compatible = "marvell,orion-sdio";
+ reg = <0xd00d4000 0x200>;
+ interrupts = <54>;
+ clocks = <&gateclk 17>;
+ status = "disabled";
+ };
diff --git a/drivers/mmc/host/mvsdio.c b/drivers/mmc/host/mvsdio.c
index baf19fc..56954bc 100644
--- a/drivers/mmc/host/mvsdio.c
+++ b/drivers/mmc/host/mvsdio.c
@@ -21,6 +21,8 @@
#include <linux/irq.h>
#include <linux/clk.h>
#include <linux/gpio.h>
+#include <linux/of_gpio.h>
+#include <linux/of_irq.h>
#include <linux/mmc/host.h>
#include <linux/mmc/slot-gpio.h>
@@ -683,17 +685,17 @@ mv_conf_mbus_windows(struct mvsd_host *host,
static int __init mvsd_probe(struct platform_device *pdev)
{
+ struct device_node *np = pdev->dev.of_node;
struct mmc_host *mmc = NULL;
struct mvsd_host *host = NULL;
- const struct mvsdio_platform_data *mvsd_data;
const struct mbus_dram_target_info *dram;
struct resource *r;
int ret, irq;
+ int gpio_card_detect, gpio_write_protect;
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
irq = platform_get_irq(pdev, 0);
- mvsd_data = pdev->dev.platform_data;
- if (!r || irq < 0 || !mvsd_data)
+ if (!r || irq < 0)
return -ENXIO;
r = request_mem_region(r->start, SZ_1K, DRIVER_NAME);
@@ -710,7 +712,35 @@ static int __init mvsd_probe(struct platform_device *pdev)
host->mmc = mmc;
host->dev = &pdev->dev;
host->res = r;
- host->base_clock = mvsd_data->clock / 2;
+
+ /* Some non-DT platforms do not pass a clock, and the clock
+ frequency is passed through platform_data. On DT platforms,
+ a clock must always be passed, even if there is no gatable
+ clock associated to the SDIO interface (it can simply be a
+ fixed rate clock). */
+ host->clk = clk_get(&pdev->dev, NULL);
+ if (!IS_ERR(host->clk))
+ clk_prepare_enable(host->clk);
+
+ if (np) {
+ if (IS_ERR(host->clk)) {
+ dev_err(&pdev->dev, "DT platforms must have a clock associated\n");
+ ret = -EINVAL;
+ goto out;
+ }
+
+ host->base_clock = clk_get_rate(host->clk) / 2;
+ gpio_card_detect = of_get_named_gpio(np, "cd-gpios", 0);
+ gpio_write_protect = of_get_named_gpio(np, "wp-gpios", 0);
+ } else {
+ const struct mvsdio_platform_data *mvsd_data;
+ mvsd_data = pdev->dev.platform_data;
+ if (!mvsd_data)
+ return -ENXIO;
+ host->base_clock = mvsd_data->clock / 2;
+ gpio_card_detect = mvsd_data->gpio_card_detect;
+ gpio_write_protect = mvsd_data->gpio_write_protect;
+ }
mmc->ops = &mvsd_ops;
@@ -750,21 +780,14 @@ static int __init mvsd_probe(struct platform_device *pdev)
} else
host->irq = irq;
- /* Not all platforms can gate the clock, so it is not
- an error if the clock does not exists. */
- host->clk = clk_get(&pdev->dev, NULL);
- if (!IS_ERR(host->clk)) {
- clk_prepare_enable(host->clk);
- }
-
- if (gpio_is_valid(mvsd_data->gpio_card_detect)) {
- ret = mmc_gpio_request_cd(mmc, mvsd_data->gpio_card_detect);
+ if (gpio_is_valid(gpio_card_detect)) {
+ ret = mmc_gpio_request_cd(mmc, gpio_card_detect);
if (ret)
goto out;
} else
mmc->caps |= MMC_CAP_NEEDS_POLL;
- mmc_gpio_request_ro(mmc, mvsd_data->gpio_write_protect);
+ mmc_gpio_request_ro(mmc, gpio_write_protect);
setup_timer(&host->timer, mvsd_timeout_timer, (unsigned long)host);
platform_set_drvdata(pdev, mmc);
@@ -776,7 +799,7 @@ static int __init mvsd_probe(struct platform_device *pdev)
mmc_hostname(mmc), DRIVER_NAME);
if (!(mmc->caps & MMC_CAP_NEEDS_POLL))
printk("using GPIO %d for card detection\n",
- mvsd_data->gpio_card_detect);
+ gpio_card_detect);
else
printk("lacking card detect (fall back to polling)\n");
return 0;
@@ -855,12 +878,19 @@ static int mvsd_resume(struct platform_device *dev)
#define mvsd_resume NULL
#endif
+static const struct of_device_id mvsdio_dt_ids[] = {
+ { .compatible = "marvell,orion-sdio" },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, mvsdio_dt_ids);
+
static struct platform_driver mvsd_driver = {
.remove = __exit_p(mvsd_remove),
.suspend = mvsd_suspend,
.resume = mvsd_resume,
.driver = {
.name = DRIVER_NAME,
+ .of_match_table = mvsdio_dt_ids,
},
};
--
1.7.9.5

@ -0,0 +1,48 @@
On many Marvell SoCs, the pins used for the SDIO interface are part of
the MPP pins, that are muxable pins. In order to get the muxing of
those pins correct, this commit integrates the mvsdio driver with the
pinctrl infrastructure by calling devm_pinctrl_get_select_default()
during ->probe().
Note that we permit this function to fail because not all Marvell
platforms have yet been fully converted to using the pinctrl
infrastructure.
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
drivers/mmc/host/mvsdio.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/mmc/host/mvsdio.c b/drivers/mmc/host/mvsdio.c
index 56954bc..feb16bd 100644
--- a/drivers/mmc/host/mvsdio.c
+++ b/drivers/mmc/host/mvsdio.c
@@ -25,6 +25,7 @@
#include <linux/of_irq.h>
#include <linux/mmc/host.h>
#include <linux/mmc/slot-gpio.h>
+#include <linux/pinctrl/consumer.h>
#include <asm/sizes.h>
#include <asm/unaligned.h>
@@ -692,6 +693,7 @@ static int __init mvsd_probe(struct platform_device *pdev)
struct resource *r;
int ret, irq;
int gpio_card_detect, gpio_write_protect;
+ struct pinctrl *pinctrl;
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
irq = platform_get_irq(pdev, 0);
@@ -713,6 +715,10 @@ static int __init mvsd_probe(struct platform_device *pdev)
host->dev = &pdev->dev;
host->res = r;
+ pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
+ if (IS_ERR(pinctrl))
+ dev_warn(&pdev->dev, "no pins associated\n");
+
/* Some non-DT platforms do not pass a clock, and the clock
frequency is passed through platform_data. On DT platforms,
a clock must always be passed, even if there is no gatable
--
1.7.9.5

@ -0,0 +1,30 @@
Now that the mvsdio MMC driver has a Device Tree binding, we add the
Device Tree informations to describe the SDIO interface available in
the Armada 370/XP SoCs.
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
arch/arm/boot/dts/armada-370-xp.dtsi | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/arch/arm/boot/dts/armada-370-xp.dtsi b/arch/arm/boot/dts/armada-370-xp.dtsi
index cf6c48a..41a5b11 100644
--- a/arch/arm/boot/dts/armada-370-xp.dtsi
+++ b/arch/arm/boot/dts/armada-370-xp.dtsi
@@ -129,6 +129,14 @@
clocks = <&coreclk 0>;
status = "disabled";
};
+
+ mvsdio@d00d4000 {
+ compatible = "marvell,orion-sdio";
+ reg = <0xd00d4000 0x200>;
+ interrupts = <54>;
+ clocks = <&gateclk 17>;
+ status = "disabled";
+ };
};
};
--
1.7.9.5

@ -0,0 +1,38 @@
The SDIO interface is available either on pins MPP9/11/12/13/14/15 or
MPP47/48/49/50/51/52 on the Armada 370. Even though all combinations
are potentially possible, those two muxing options are the most
probable ones, so we provide those at the SoC level .dtsi file.
In practice, in turns out the Armada 370 DB board uses the former,
while the Armada 370 Mirabox uses the latter.
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
arch/arm/boot/dts/armada-370.dtsi | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/arch/arm/boot/dts/armada-370.dtsi b/arch/arm/boot/dts/armada-370.dtsi
index 636cf7d..88f9bab 100644
--- a/arch/arm/boot/dts/armada-370.dtsi
+++ b/arch/arm/boot/dts/armada-370.dtsi
@@ -47,6 +47,18 @@
pinctrl {
compatible = "marvell,mv88f6710-pinctrl";
reg = <0xd0018000 0x38>;
+
+ sdio_pins1: sdio-pins1 {
+ marvell,pins = "mpp9", "mpp11", "mpp12",
+ "mpp13", "mpp14", "mpp15";
+ marvell,function = "sd0";
+ };
+
+ sdio_pins2: sdio-pins2 {
+ marvell,pins = "mpp47", "mpp48", "mpp49",
+ "mpp50", "mpp51", "mpp52";
+ marvell,function = "sd0";
+ };
};
gpio0: gpio@d0018100 {
--
1.7.9.5

@ -0,0 +1,69 @@
The SDIO interface is only available on pins MPP30/31/32/33/34/35 on
the various Armada XP variants, so we provide a pin muxing option for
this in the Armada XP .dtsi files.
Even though those muxing options are the same for MV78230, MV78260 and
MV78460, we keep them in each .dtsi file, because the number of pins,
and therefore the declaration of the pinctrl node, is different for
each SoC variant.
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
arch/arm/boot/dts/armada-xp-mv78230.dtsi | 6 ++++++
arch/arm/boot/dts/armada-xp-mv78260.dtsi | 6 ++++++
arch/arm/boot/dts/armada-xp-mv78460.dtsi | 6 ++++++
3 files changed, 18 insertions(+)
diff --git a/arch/arm/boot/dts/armada-xp-mv78230.dtsi b/arch/arm/boot/dts/armada-xp-mv78230.dtsi
index c45c7b4..3fa9c84 100644
--- a/arch/arm/boot/dts/armada-xp-mv78230.dtsi
+++ b/arch/arm/boot/dts/armada-xp-mv78230.dtsi
@@ -40,6 +40,12 @@
pinctrl {
compatible = "marvell,mv78230-pinctrl";
reg = <0xd0018000 0x38>;
+
+ sdio_pins: sdio-pins {
+ marvell,pins = "mpp30", "mpp31", "mpp32",
+ "mpp33", "mpp34", "mpp35";
+ marvell,function = "sd0";
+ };
};
gpio0: gpio@d0018100 {
diff --git a/arch/arm/boot/dts/armada-xp-mv78260.dtsi b/arch/arm/boot/dts/armada-xp-mv78260.dtsi
index a2aee57..5a907b3 100644
--- a/arch/arm/boot/dts/armada-xp-mv78260.dtsi
+++ b/arch/arm/boot/dts/armada-xp-mv78260.dtsi
@@ -48,6 +48,12 @@
pinctrl {
compatible = "marvell,mv78260-pinctrl";
reg = <0xd0018000 0x38>;
+
+ sdio_pins: sdio-pins {
+ marvell,pins = "mpp30", "mpp31", "mpp32",
+ "mpp33", "mpp34", "mpp35";
+ marvell,function = "sd0";
+ };
};
gpio0: gpio@d0018100 {
diff --git a/arch/arm/boot/dts/armada-xp-mv78460.dtsi b/arch/arm/boot/dts/armada-xp-mv78460.dtsi
index da03a12..6dcdc50d 100644
--- a/arch/arm/boot/dts/armada-xp-mv78460.dtsi
+++ b/arch/arm/boot/dts/armada-xp-mv78460.dtsi
@@ -63,6 +63,12 @@
pinctrl {
compatible = "marvell,mv78460-pinctrl";
reg = <0xd0018000 0x38>;
+
+ sdio_pins: sdio-pins {
+ marvell,pins = "mpp30", "mpp31", "mpp32",
+ "mpp33", "mpp34", "mpp35";
+ marvell,function = "sd0";
+ };
};
gpio0: gpio@d0018100 {
--
1.7.9.5

@ -0,0 +1,29 @@
The Armada XP DB evaluation board has one SD card slot, directly
connected to the SDIO IP of the SoC, so we enable this
IP. Unfortunately, there are no GPIOs for card-detect and
write-protect.
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
arch/arm/boot/dts/armada-xp-db.dts | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/arch/arm/boot/dts/armada-xp-db.dts b/arch/arm/boot/dts/armada-xp-db.dts
index 8e53b25..c7035c5 100644
--- a/arch/arm/boot/dts/armada-xp-db.dts
+++ b/arch/arm/boot/dts/armada-xp-db.dts
@@ -90,5 +90,12 @@
phy = <&phy3>;
phy-mode = "sgmii";
};
+
+ mvsdio@d00d4000 {
+ pinctrl-0 = <&sdio_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+ /* No CD or WP GPIOs */
+ };
};
};
--
1.7.9.5

@ -0,0 +1,46 @@
The Armada XP DB evaluation board has one SD card slot, directly
connected to the SDIO IP of the SoC, so we add a device tree
description for it.
However, in the default configuration of the board, the SD card slot
is not usable: the connector plugged into CON40 must be changed
against a different one, provided with the board by the
manufacturer. Since such a manual modification of the hardware is
needed, we did not enable the SDIO interface by default, and left it
to the board user to modify the Device Tree if needed. Since this
board is really only an evaluation board for developers and not a
final product, it is not too bad.
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
[florian: changed status to "okay" for RD-A370-A1]
arch/arm/boot/dts/armada-370-db.dts | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/arch/arm/boot/dts/armada-370-db.dts b/arch/arm/boot/dts/armada-370-db.dts
index 0004402..43ff156 100644
--- a/arch/arm/boot/dts/armada-370-db.dts
+++ b/arch/arm/boot/dts/armada-370-db.dts
@@ -59,5 +59,20 @@
phy = <&phy1>;
phy-mode = "rgmii-id";
};
+
+ mvsdio@d00d4000 {
+ pinctrl-0 = <&sdio_pins1>;
+ pinctrl-names = "default";
+ /*
+ * This device is disabled by default, because
+ * using the SD card connector requires
+ * changing the default CON40 connector
+ * "DB-88F6710_MPP_2xRGMII_DEVICE_Jumper" to a
+ * different connector
+ * "DB-88F6710_MPP_RGMII_SD_Jumper".
+ */
+ status = "okay";
+ /* No CD or WP GPIOs */
+ };
};
};
--
1.7.9.5

@ -0,0 +1,31 @@
The Globalscale Mirabox uses the SDIO interface of the Armada 370 to
connect to a Wifi/Bluetooth SD8787 chip, so we enable the SDIO
interface of this board in its Device Tree file.
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
arch/arm/boot/dts/armada-370-mirabox.dts | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/arch/arm/boot/dts/armada-370-mirabox.dts b/arch/arm/boot/dts/armada-370-mirabox.dts
index 3b40713..1864820 100644
--- a/arch/arm/boot/dts/armada-370-mirabox.dts
+++ b/arch/arm/boot/dts/armada-370-mirabox.dts
@@ -52,5 +52,15 @@
phy = <&phy1>;
phy-mode = "rgmii-id";
};
+
+ mvsdio@d00d4000 {
+ pinctrl-0 = <&sdio_pins2>;
+ pinctrl-names = "default";
+ status = "okay";
+ /*
+ * No CD or WP GPIOs: SDIO interface used for
+ * Wifi/Bluetooth chip
+ */
+ };
};
};
--
1.7.9.5

@ -0,0 +1,52 @@
From e84ed03e1c5d45305fdd9b872e0b7be97bcfda16 Mon Sep 17 00:00:00 2001
From: Gregory CLEMENT <gregory.clement@free-electrons.com>
Date: Thu, 13 Dec 2012 15:03:27 +0100
Subject: [PATCH] arm: cache-l2x0: aurora: Invalidate during clean operation
with WT enable
This patch fixes a bug for Aurora L2 cache controller when the
write-through mode is enable. For the clean operation even if we don't
have to flush the lines we still need to invalidate them.
Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
arch/arm/mm/cache-l2x0.c | 22 ++++++++++++++--------
1 file changed, 14 insertions(+), 8 deletions(-)
diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index 6911b8b..7ffe943 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -505,15 +505,21 @@ static void aurora_clean_range(unsigned long start, unsigned long end)
static void aurora_flush_range(unsigned long start, unsigned long end)
{
- if (!l2_wt_override) {
- start &= ~(CACHE_LINE_SIZE - 1);
- end = ALIGN(end, CACHE_LINE_SIZE);
- while (start != end) {
- unsigned long range_end = calc_range_end(start, end);
+ start &= ~(CACHE_LINE_SIZE - 1);
+ end = ALIGN(end, CACHE_LINE_SIZE);
+ while (start != end) {
+ unsigned long range_end = calc_range_end(start, end);
+ /*
+ * If L2 is forced to WT, the L2 will always be clean and we
+ * just need to invalidate.
+ */
+ if (l2_wt_override)
aurora_pa_range(start, range_end - CACHE_LINE_SIZE,
- AURORA_FLUSH_RANGE_REG);
- start = range_end;
- }
+ AURORA_INVAL_RANGE_REG);
+ else
+ aurora_pa_range(start, range_end - CACHE_LINE_SIZE,
+ AURORA_FLUSH_RANGE_REG);
+ start = range_end;
}
}
--
1.7.10.4

@ -0,0 +1,45 @@
From 6c8928f877a1572f16cfc8a0c055d7e16320c741 Mon Sep 17 00:00:00 2001
From: Gregory CLEMENT <gregory.clement@free-electrons.com>
Date: Thu, 13 Dec 2012 18:33:06 +0100
Subject: [PATCH] arm: cache-l2x0: aurora: Use writel_relaxed instead of
writel
The use of writel instead of writel_relaxed lead to deadlock in some
situation (SMP on Armada 370 for instance). The use of writel_relaxed
as it was done in the rest of this driver fixes this bug.
Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
arch/arm/mm/cache-l2x0.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index 7ffe943..96a1ae4 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -459,8 +459,8 @@ static void aurora_pa_range(unsigned long start, unsigned long end,
unsigned long flags;
raw_spin_lock_irqsave(&l2x0_lock, flags);
- writel(start, l2x0_base + AURORA_RANGE_BASE_ADDR_REG);
- writel(end, l2x0_base + offset);
+ writel_relaxed(start, l2x0_base + AURORA_RANGE_BASE_ADDR_REG);
+ writel_relaxed(end, l2x0_base + offset);
raw_spin_unlock_irqrestore(&l2x0_lock, flags);
cache_sync();
@@ -674,8 +674,9 @@ static void pl310_resume(void)
static void aurora_resume(void)
{
if (!(readl(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN)) {
- writel(l2x0_saved_regs.aux_ctrl, l2x0_base + L2X0_AUX_CTRL);
- writel(l2x0_saved_regs.ctrl, l2x0_base + L2X0_CTRL);
+ writel_relaxed(l2x0_saved_regs.aux_ctrl,
+ l2x0_base + L2X0_AUX_CTRL);
+ writel_relaxed(l2x0_saved_regs.ctrl, l2x0_base + L2X0_CTRL);
}
}
--
1.7.10.4

@ -0,0 +1,88 @@
From 3487b074a742bc3300683e91e3ade383b659fbe9 Mon Sep 17 00:00:00 2001
From: Gregory CLEMENT <gregory.clement@free-electrons.com>
Date: Tue, 4 Dec 2012 18:04:59 +0100
Subject: [PATCH] arm: mvebu: Use dw-apb-uart instead of ns16650 as UART
driver
The UART controller used in the Armada 370 and Armada XP SoCs is the
Synopsys DesignWare 8250 (aka Synopsys DesignWare ABP UART). The
improper use of the ns16550 can lead to a kernel oops during boot if
a character is sent to the UART before the initialization of the
driver. The DW APB has an extra interrupt that gets raised when
writing to the LCR when busy. This explains why we need to use
dw-apb-uart driver to handle this.
Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
arch/arm/boot/dts/armada-370-xp.dtsi | 6 ++++--
arch/arm/boot/dts/armada-xp.dtsi | 6 ++++--
arch/arm/configs/mvebu_defconfig | 1 +
3 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/arch/arm/boot/dts/armada-370-xp.dtsi b/arch/arm/boot/dts/armada-370-xp.dtsi
index cf6c48a..4c0abe8 100644
--- a/arch/arm/boot/dts/armada-370-xp.dtsi
+++ b/arch/arm/boot/dts/armada-370-xp.dtsi
@@ -50,17 +50,19 @@
ranges;
serial@d0012000 {
- compatible = "ns16550";
+ compatible = "snps,dw-apb-uart";
reg = <0xd0012000 0x100>;
reg-shift = <2>;
interrupts = <41>;
+ reg-io-width = <4>;
status = "disabled";
};
serial@d0012100 {
- compatible = "ns16550";
+ compatible = "snps,dw-apb-uart";
reg = <0xd0012100 0x100>;
reg-shift = <2>;
interrupts = <42>;
+ reg-io-width = <4>;
status = "disabled";
};
diff --git a/arch/arm/boot/dts/armada-xp.dtsi b/arch/arm/boot/dts/armada-xp.dtsi
index 367aa3f..8a85ffe 100644
--- a/arch/arm/boot/dts/armada-xp.dtsi
+++ b/arch/arm/boot/dts/armada-xp.dtsi
@@ -42,17 +42,19 @@
soc {
serial@d0012200 {
- compatible = "ns16550";
+ compatible = "snps,dw-apb-uart";
reg = <0xd0012200 0x100>;
reg-shift = <2>;
interrupts = <43>;
+ reg-io-width = <4>;
status = "disabled";
};
serial@d0012300 {
- compatible = "ns16550";
+ compatible = "snps,dw-apb-uart";
reg = <0xd0012300 0x100>;
reg-shift = <2>;
interrupts = <44>;
+ reg-io-width = <4>;
status = "disabled";
};
diff --git a/arch/arm/configs/mvebu_defconfig b/arch/arm/configs/mvebu_defconfig
index a702fb3..3ba35f1 100644
--- a/arch/arm/configs/mvebu_defconfig
+++ b/arch/arm/configs/mvebu_defconfig
@@ -34,6 +34,7 @@ CONFIG_MARVELL_PHY=y
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_SERIAL_8250_DW=y
CONFIG_I2C=y
CONFIG_I2C_MV64XXX=y
CONFIG_GPIOLIB=y
--
1.7.10.4
Loading…
Cancel
Save