mirror of https://github.com/hak5/openwrt-owl.git
mvebu: backport mainline patches from kernel 3.11
This is a backport of the patches accepted to the Linux mainline related to mvebu SoC (Armada XP and Armada 370) between Linux v3.10, and Linux v3.11. This work mainly covers: * Enabling USB storage, and PCI to mvebu_defconfig. * Add support for NOR flash. * Some PCI device tree related updates, and bus parsing. * Adding Armada XP & 370 PCI driver, and update some clock gating specifics. * Introduce Marvell EBU Device Bus driver. * Enaling USB in the armada*.dts. * Enabling, and updating the mvebu-mbus. * Some SATA and Ethernet related fixes. Signed-off-by: Seif Mazareeb <seif.mazareeb@gmail.com> CC: Luka Perkov <luka@openwrt.org> SVN-Revision: 39564owl
parent
31fb795fd0
commit
69d323f231
|
@ -0,0 +1,28 @@
|
||||||
|
From 6c52eba54044791592aefd139bdc2a7b6127e981 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
|
||||||
|
Date: Wed, 17 Apr 2013 16:51:34 -0300
|
||||||
|
Subject: [PATCH 001/203] ARM: mvebu: Add support for USB storage class in
|
||||||
|
mvebu_defconfig
|
||||||
|
|
||||||
|
Some boards can have built-in USB storage class controllers so
|
||||||
|
it's better to have this option included by default.
|
||||||
|
|
||||||
|
Currently this option is needed to support built-in USB MMC controller
|
||||||
|
found in Globalscale Mirabox board.
|
||||||
|
|
||||||
|
Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
|
||||||
|
Signed-off-by: Jason Cooper <jason@lakedaemon.net>
|
||||||
|
---
|
||||||
|
arch/arm/configs/mvebu_defconfig | 1 +
|
||||||
|
1 file changed, 1 insertion(+)
|
||||||
|
|
||||||
|
--- a/arch/arm/configs/mvebu_defconfig
|
||||||
|
+++ b/arch/arm/configs/mvebu_defconfig
|
||||||
|
@@ -60,6 +60,7 @@ CONFIG_USB_SUPPORT=y
|
||||||
|
CONFIG_USB=y
|
||||||
|
CONFIG_USB_EHCI_HCD=y
|
||||||
|
CONFIG_USB_EHCI_ROOT_HUB_TT=y
|
||||||
|
+CONFIG_USB_STORAGE=y
|
||||||
|
CONFIG_MMC=y
|
||||||
|
CONFIG_MMC_MVSDIO=y
|
||||||
|
CONFIG_NEW_LEDS=y
|
|
@ -0,0 +1,133 @@
|
||||||
|
From cf6eb4599d60cb9fa81465aa018c71d11e19ea6a Mon Sep 17 00:00:00 2001
|
||||||
|
From: Simon Baatz <gmbnomis@gmail.com>
|
||||||
|
Date: Mon, 13 May 2013 23:18:58 +0200
|
||||||
|
Subject: [PATCH 002/203] ARM: mvebu: Use standard MMC binding for all users of
|
||||||
|
mvsdio
|
||||||
|
|
||||||
|
In order to prepare the switch to the standard MMC device tree parser
|
||||||
|
for mvsdio, adapt all current uses of mvsdio in the dts files to the
|
||||||
|
standard format.
|
||||||
|
|
||||||
|
Signed-off-by: Simon Baatz <gmbnomis@gmail.com>
|
||||||
|
Signed-off-by: Jason Cooper <jason@lakedaemon.net>
|
||||||
|
---
|
||||||
|
arch/arm/boot/dts/armada-370-db.dts | 1 +
|
||||||
|
arch/arm/boot/dts/armada-370-mirabox.dts | 1 +
|
||||||
|
arch/arm/boot/dts/armada-370-rd.dts | 1 +
|
||||||
|
arch/arm/boot/dts/armada-370-xp.dtsi | 4 ++++
|
||||||
|
arch/arm/boot/dts/armada-xp-db.dts | 1 +
|
||||||
|
arch/arm/boot/dts/kirkwood-dreamplug.dts | 1 +
|
||||||
|
arch/arm/boot/dts/kirkwood-guruplug-server-plus.dts | 2 ++
|
||||||
|
arch/arm/boot/dts/kirkwood-mplcec4.dts | 2 +-
|
||||||
|
arch/arm/boot/dts/kirkwood-topkick.dts | 1 +
|
||||||
|
arch/arm/boot/dts/kirkwood.dtsi | 4 ++++
|
||||||
|
10 files changed, 17 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
--- a/arch/arm/boot/dts/armada-370-db.dts
|
||||||
|
+++ b/arch/arm/boot/dts/armada-370-db.dts
|
||||||
|
@@ -74,6 +74,7 @@
|
||||||
|
*/
|
||||||
|
status = "disabled";
|
||||||
|
/* No CD or WP GPIOs */
|
||||||
|
+ broken-cd;
|
||||||
|
};
|
||||||
|
|
||||||
|
usb@50000 {
|
||||||
|
--- a/arch/arm/boot/dts/armada-370-mirabox.dts
|
||||||
|
+++ b/arch/arm/boot/dts/armada-370-mirabox.dts
|
||||||
|
@@ -99,6 +99,7 @@
|
||||||
|
* No CD or WP GPIOs: SDIO interface used for
|
||||||
|
* Wifi/Bluetooth chip
|
||||||
|
*/
|
||||||
|
+ broken-cd;
|
||||||
|
};
|
||||||
|
|
||||||
|
usb@50000 {
|
||||||
|
--- a/arch/arm/boot/dts/armada-370-rd.dts
|
||||||
|
+++ b/arch/arm/boot/dts/armada-370-rd.dts
|
||||||
|
@@ -64,6 +64,7 @@
|
||||||
|
pinctrl-names = "default";
|
||||||
|
status = "okay";
|
||||||
|
/* No CD or WP GPIOs */
|
||||||
|
+ broken-cd;
|
||||||
|
};
|
||||||
|
|
||||||
|
usb@50000 {
|
||||||
|
--- a/arch/arm/boot/dts/armada-370-xp.dtsi
|
||||||
|
+++ b/arch/arm/boot/dts/armada-370-xp.dtsi
|
||||||
|
@@ -143,6 +143,10 @@
|
||||||
|
reg = <0xd4000 0x200>;
|
||||||
|
interrupts = <54>;
|
||||||
|
clocks = <&gateclk 17>;
|
||||||
|
+ bus-width = <4>;
|
||||||
|
+ cap-sdio-irq;
|
||||||
|
+ cap-sd-highspeed;
|
||||||
|
+ cap-mmc-highspeed;
|
||||||
|
status = "disabled";
|
||||||
|
};
|
||||||
|
|
||||||
|
--- a/arch/arm/boot/dts/armada-xp-db.dts
|
||||||
|
+++ b/arch/arm/boot/dts/armada-xp-db.dts
|
||||||
|
@@ -97,6 +97,7 @@
|
||||||
|
pinctrl-names = "default";
|
||||||
|
status = "okay";
|
||||||
|
/* No CD or WP GPIOs */
|
||||||
|
+ broken-cd;
|
||||||
|
};
|
||||||
|
|
||||||
|
usb@50000 {
|
||||||
|
--- a/arch/arm/boot/dts/kirkwood-dreamplug.dts
|
||||||
|
+++ b/arch/arm/boot/dts/kirkwood-dreamplug.dts
|
||||||
|
@@ -79,6 +79,7 @@
|
||||||
|
pinctrl-names = "default";
|
||||||
|
status = "okay";
|
||||||
|
/* No CD or WP GPIOs */
|
||||||
|
+ broken-cd;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
--- a/arch/arm/boot/dts/kirkwood-guruplug-server-plus.dts
|
||||||
|
+++ b/arch/arm/boot/dts/kirkwood-guruplug-server-plus.dts
|
||||||
|
@@ -72,6 +72,8 @@
|
||||||
|
|
||||||
|
mvsdio@90000 {
|
||||||
|
status = "okay";
|
||||||
|
+ /* No CD or WP GPIOs */
|
||||||
|
+ broken-cd;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
--- a/arch/arm/boot/dts/kirkwood-mplcec4.dts
|
||||||
|
+++ b/arch/arm/boot/dts/kirkwood-mplcec4.dts
|
||||||
|
@@ -136,7 +136,7 @@
|
||||||
|
pinctrl-0 = <&pmx_sdio &pmx_sdio_cd>;
|
||||||
|
pinctrl-names = "default";
|
||||||
|
status = "okay";
|
||||||
|
- cd-gpios = <&gpio1 15 0>;
|
||||||
|
+ cd-gpios = <&gpio1 15 1>;
|
||||||
|
/* No WP GPIO */
|
||||||
|
};
|
||||||
|
};
|
||||||
|
--- a/arch/arm/boot/dts/kirkwood-topkick.dts
|
||||||
|
+++ b/arch/arm/boot/dts/kirkwood-topkick.dts
|
||||||
|
@@ -154,6 +154,7 @@
|
||||||
|
pinctrl-names = "default";
|
||||||
|
status = "okay";
|
||||||
|
/* No CD or WP GPIOs */
|
||||||
|
+ broken-cd;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
--- a/arch/arm/boot/dts/kirkwood.dtsi
|
||||||
|
+++ b/arch/arm/boot/dts/kirkwood.dtsi
|
||||||
|
@@ -200,6 +200,10 @@
|
||||||
|
reg = <0x90000 0x200>;
|
||||||
|
interrupts = <28>;
|
||||||
|
clocks = <&gate_clk 4>;
|
||||||
|
+ bus-width = <4>;
|
||||||
|
+ cap-sdio-irq;
|
||||||
|
+ cap-sd-highspeed;
|
||||||
|
+ cap-mmc-highspeed;
|
||||||
|
status = "disabled";
|
||||||
|
};
|
||||||
|
};
|
|
@ -0,0 +1,71 @@
|
||||||
|
From 74cd8c09ae416261d7595021fc8062836dc750a2 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
|
||||||
|
Date: Fri, 17 May 2013 08:09:58 -0300
|
||||||
|
Subject: [PATCH 003/203] ARM: mvebu: Add support for NOR flash device on
|
||||||
|
Armada XP-DB board
|
||||||
|
|
||||||
|
The Armada XP Development Board (DB-78460-BP) has a NOR flash device
|
||||||
|
connected to the Device Bus. This commit adds the device tree node
|
||||||
|
to support this device.
|
||||||
|
|
||||||
|
This SoC supports a flexible and dynamic decoding window allocation
|
||||||
|
scheme; but since this feature is still not implemented we need
|
||||||
|
to specify the window base address in the device tree node itself.
|
||||||
|
|
||||||
|
This base address has been selected in a completely arbitrary fashion.
|
||||||
|
|
||||||
|
Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
|
||||||
|
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||||
|
Signed-off-by: Jason Cooper <jason@lakedaemon.net>
|
||||||
|
---
|
||||||
|
arch/arm/boot/dts/armada-xp-db.dts | 32 ++++++++++++++++++++++++++++++++
|
||||||
|
1 file changed, 32 insertions(+)
|
||||||
|
|
||||||
|
--- a/arch/arm/boot/dts/armada-xp-db.dts
|
||||||
|
+++ b/arch/arm/boot/dts/armada-xp-db.dts
|
||||||
|
@@ -30,6 +30,9 @@
|
||||||
|
};
|
||||||
|
|
||||||
|
soc {
|
||||||
|
+ ranges = <0 0 0xd0000000 0x100000 /* Internal registers 1MiB */
|
||||||
|
+ 0xf0000000 0 0xf0000000 0x1000000>; /* Device Bus, NOR 16MiB */
|
||||||
|
+
|
||||||
|
internal-regs {
|
||||||
|
serial@12000 {
|
||||||
|
clock-frequency = <250000000>;
|
||||||
|
@@ -156,6 +159,35 @@
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
+
|
||||||
|
+ devbus-bootcs@10400 {
|
||||||
|
+ status = "okay";
|
||||||
|
+ ranges = <0 0xf0000000 0x1000000>;
|
||||||
|
+
|
||||||
|
+ /* Device Bus parameters are required */
|
||||||
|
+
|
||||||
|
+ /* Read parameters */
|
||||||
|
+ devbus,bus-width = <8>;
|
||||||
|
+ devbus,turn-off-ps = <60000>;
|
||||||
|
+ devbus,badr-skew-ps = <0>;
|
||||||
|
+ devbus,acc-first-ps = <124000>;
|
||||||
|
+ devbus,acc-next-ps = <248000>;
|
||||||
|
+ devbus,rd-setup-ps = <0>;
|
||||||
|
+ devbus,rd-hold-ps = <0>;
|
||||||
|
+
|
||||||
|
+ /* Write parameters */
|
||||||
|
+ devbus,sync-enable = <0>;
|
||||||
|
+ devbus,wr-high-ps = <60000>;
|
||||||
|
+ devbus,wr-low-ps = <60000>;
|
||||||
|
+ devbus,ale-wr-ps = <60000>;
|
||||||
|
+
|
||||||
|
+ /* NOR 16 MiB */
|
||||||
|
+ nor@0 {
|
||||||
|
+ compatible = "cfi-flash";
|
||||||
|
+ reg = <0 0x1000000>;
|
||||||
|
+ bank-width = <2>;
|
||||||
|
+ };
|
||||||
|
+ };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
|
@ -0,0 +1,196 @@
|
||||||
|
From 7d375772a601bdf227902454705e402fc65b8bdf Mon Sep 17 00:00:00 2001
|
||||||
|
From: Andrew Murray <Andrew.Murray@arm.com>
|
||||||
|
Date: Tue, 7 May 2013 16:31:12 +0100
|
||||||
|
Subject: [PATCH 004/203] of/pci: Provide support for parsing PCI DT ranges
|
||||||
|
property
|
||||||
|
|
||||||
|
This patch factors out common implementation patterns to reduce overall kernel
|
||||||
|
code and provide a means for host bridge drivers to directly obtain struct
|
||||||
|
resources from the DT's ranges property without relying on architecture specific
|
||||||
|
DT handling. This will make it easier to write archiecture independent host bridge
|
||||||
|
drivers and mitigate against further duplication of DT parsing code.
|
||||||
|
|
||||||
|
This patch can be used in the following way:
|
||||||
|
|
||||||
|
struct of_pci_range_parser parser;
|
||||||
|
struct of_pci_range range;
|
||||||
|
|
||||||
|
if (of_pci_range_parser_init(&parser, np))
|
||||||
|
; //no ranges property
|
||||||
|
|
||||||
|
for_each_of_pci_range(&parser, &range) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
directly access properties of the address range, e.g.:
|
||||||
|
range.pci_space, range.pci_addr, range.cpu_addr,
|
||||||
|
range.size, range.flags
|
||||||
|
|
||||||
|
alternatively obtain a struct resource, e.g.:
|
||||||
|
struct resource res;
|
||||||
|
of_pci_range_to_resource(&range, np, &res);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
Additionally the implementation takes care of adjacent ranges and merges them
|
||||||
|
into a single range (as was the case with powerpc and microblaze).
|
||||||
|
|
||||||
|
Signed-off-by: Andrew Murray <Andrew.Murray@arm.com>
|
||||||
|
Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
|
||||||
|
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||||
|
Reviewed-by: Rob Herring <rob.herring@calxeda.com>
|
||||||
|
Tested-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||||
|
Tested-by: Linus Walleij <linus.walleij@linaro.org>
|
||||||
|
Tested-by: Jingoo Han <jg1.han@samsung.com>
|
||||||
|
Acked-by: Grant Likely <grant.likely@secretlab.ca>
|
||||||
|
---
|
||||||
|
drivers/of/address.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
include/linux/of_address.h | 48 +++++++++++++++++++++++++++++++++
|
||||||
|
2 files changed, 115 insertions(+)
|
||||||
|
|
||||||
|
--- a/drivers/of/address.c
|
||||||
|
+++ b/drivers/of/address.c
|
||||||
|
@@ -223,6 +223,73 @@ int of_pci_address_to_resource(struct de
|
||||||
|
return __of_address_to_resource(dev, addrp, size, flags, NULL, r);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(of_pci_address_to_resource);
|
||||||
|
+
|
||||||
|
+int of_pci_range_parser_init(struct of_pci_range_parser *parser,
|
||||||
|
+ struct device_node *node)
|
||||||
|
+{
|
||||||
|
+ const int na = 3, ns = 2;
|
||||||
|
+ int rlen;
|
||||||
|
+
|
||||||
|
+ parser->node = node;
|
||||||
|
+ parser->pna = of_n_addr_cells(node);
|
||||||
|
+ parser->np = parser->pna + na + ns;
|
||||||
|
+
|
||||||
|
+ parser->range = of_get_property(node, "ranges", &rlen);
|
||||||
|
+ if (parser->range == NULL)
|
||||||
|
+ return -ENOENT;
|
||||||
|
+
|
||||||
|
+ parser->end = parser->range + rlen / sizeof(__be32);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+EXPORT_SYMBOL_GPL(of_pci_range_parser_init);
|
||||||
|
+
|
||||||
|
+struct of_pci_range *of_pci_range_parser_one(struct of_pci_range_parser *parser,
|
||||||
|
+ struct of_pci_range *range)
|
||||||
|
+{
|
||||||
|
+ const int na = 3, ns = 2;
|
||||||
|
+
|
||||||
|
+ if (!range)
|
||||||
|
+ return NULL;
|
||||||
|
+
|
||||||
|
+ if (!parser->range || parser->range + parser->np > parser->end)
|
||||||
|
+ return NULL;
|
||||||
|
+
|
||||||
|
+ range->pci_space = parser->range[0];
|
||||||
|
+ range->flags = of_bus_pci_get_flags(parser->range);
|
||||||
|
+ range->pci_addr = of_read_number(parser->range + 1, ns);
|
||||||
|
+ range->cpu_addr = of_translate_address(parser->node,
|
||||||
|
+ parser->range + na);
|
||||||
|
+ range->size = of_read_number(parser->range + parser->pna + na, ns);
|
||||||
|
+
|
||||||
|
+ parser->range += parser->np;
|
||||||
|
+
|
||||||
|
+ /* Now consume following elements while they are contiguous */
|
||||||
|
+ while (parser->range + parser->np <= parser->end) {
|
||||||
|
+ u32 flags, pci_space;
|
||||||
|
+ u64 pci_addr, cpu_addr, size;
|
||||||
|
+
|
||||||
|
+ pci_space = be32_to_cpup(parser->range);
|
||||||
|
+ flags = of_bus_pci_get_flags(parser->range);
|
||||||
|
+ pci_addr = of_read_number(parser->range + 1, ns);
|
||||||
|
+ cpu_addr = of_translate_address(parser->node,
|
||||||
|
+ parser->range + na);
|
||||||
|
+ size = of_read_number(parser->range + parser->pna + na, ns);
|
||||||
|
+
|
||||||
|
+ if (flags != range->flags)
|
||||||
|
+ break;
|
||||||
|
+ if (pci_addr != range->pci_addr + range->size ||
|
||||||
|
+ cpu_addr != range->cpu_addr + range->size)
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
+ range->size += size;
|
||||||
|
+ parser->range += parser->np;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return range;
|
||||||
|
+}
|
||||||
|
+EXPORT_SYMBOL_GPL(of_pci_range_parser_one);
|
||||||
|
+
|
||||||
|
#endif /* CONFIG_PCI */
|
||||||
|
|
||||||
|
/*
|
||||||
|
--- a/include/linux/of_address.h
|
||||||
|
+++ b/include/linux/of_address.h
|
||||||
|
@@ -4,6 +4,36 @@
|
||||||
|
#include <linux/errno.h>
|
||||||
|
#include <linux/of.h>
|
||||||
|
|
||||||
|
+struct of_pci_range_parser {
|
||||||
|
+ struct device_node *node;
|
||||||
|
+ const __be32 *range;
|
||||||
|
+ const __be32 *end;
|
||||||
|
+ int np;
|
||||||
|
+ int pna;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+struct of_pci_range {
|
||||||
|
+ u32 pci_space;
|
||||||
|
+ u64 pci_addr;
|
||||||
|
+ u64 cpu_addr;
|
||||||
|
+ u64 size;
|
||||||
|
+ u32 flags;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+#define for_each_of_pci_range(parser, range) \
|
||||||
|
+ for (; of_pci_range_parser_one(parser, range);)
|
||||||
|
+
|
||||||
|
+static inline void of_pci_range_to_resource(struct of_pci_range *range,
|
||||||
|
+ struct device_node *np,
|
||||||
|
+ struct resource *res)
|
||||||
|
+{
|
||||||
|
+ res->flags = range->flags;
|
||||||
|
+ res->start = range->cpu_addr;
|
||||||
|
+ res->end = range->cpu_addr + range->size - 1;
|
||||||
|
+ res->parent = res->child = res->sibling = NULL;
|
||||||
|
+ res->name = np->full_name;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
#ifdef CONFIG_OF_ADDRESS
|
||||||
|
extern u64 of_translate_address(struct device_node *np, const __be32 *addr);
|
||||||
|
extern bool of_can_translate_address(struct device_node *dev);
|
||||||
|
@@ -27,6 +57,11 @@ static inline unsigned long pci_address_
|
||||||
|
#define pci_address_to_pio pci_address_to_pio
|
||||||
|
#endif
|
||||||
|
|
||||||
|
+extern int of_pci_range_parser_init(struct of_pci_range_parser *parser,
|
||||||
|
+ struct device_node *node);
|
||||||
|
+extern struct of_pci_range *of_pci_range_parser_one(
|
||||||
|
+ struct of_pci_range_parser *parser,
|
||||||
|
+ struct of_pci_range *range);
|
||||||
|
#else /* CONFIG_OF_ADDRESS */
|
||||||
|
#ifndef of_address_to_resource
|
||||||
|
static inline int of_address_to_resource(struct device_node *dev, int index,
|
||||||
|
@@ -53,6 +88,19 @@ static inline const __be32 *of_get_addre
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+static inline int of_pci_range_parser_init(struct of_pci_range_parser *parser,
|
||||||
|
+ struct device_node *node)
|
||||||
|
+{
|
||||||
|
+ return -1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static inline struct of_pci_range *of_pci_range_parser_one(
|
||||||
|
+ struct of_pci_range_parser *parser,
|
||||||
|
+ struct of_pci_range *range)
|
||||||
|
+{
|
||||||
|
+ return NULL;
|
||||||
|
+}
|
||||||
|
#endif /* CONFIG_OF_ADDRESS */
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
From 3f368ae1994efc17b59ffd34307c76b1f642527e Mon Sep 17 00:00:00 2001
|
||||||
|
From: Thierry Reding <thierry.reding@avionic-design.de>
|
||||||
|
Date: Mon, 11 Feb 2013 09:22:20 +0100
|
||||||
|
Subject: [PATCH 006/203] of/pci: Add of_pci_parse_bus_range() function
|
||||||
|
|
||||||
|
This function can be used to parse a bus-range property as specified by
|
||||||
|
device nodes representing PCI bridges.
|
||||||
|
|
||||||
|
Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>
|
||||||
|
---
|
||||||
|
drivers/of/of_pci.c | 25 +++++++++++++++++++++++++
|
||||||
|
include/linux/of_pci.h | 1 +
|
||||||
|
2 files changed, 26 insertions(+)
|
||||||
|
|
||||||
|
--- a/drivers/of/of_pci.c
|
||||||
|
+++ b/drivers/of/of_pci.c
|
||||||
|
@@ -64,3 +64,28 @@ int of_pci_get_devfn(struct device_node
|
||||||
|
return (be32_to_cpup(reg) >> 8) & 0xff;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(of_pci_get_devfn);
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * of_pci_parse_bus_range() - parse the bus-range property of a PCI device
|
||||||
|
+ * @node: device node
|
||||||
|
+ * @res: address to a struct resource to return the bus-range
|
||||||
|
+ *
|
||||||
|
+ * Returns 0 on success or a negative error-code on failure.
|
||||||
|
+ */
|
||||||
|
+int of_pci_parse_bus_range(struct device_node *node, struct resource *res)
|
||||||
|
+{
|
||||||
|
+ const __be32 *values;
|
||||||
|
+ int len;
|
||||||
|
+
|
||||||
|
+ values = of_get_property(node, "bus-range", &len);
|
||||||
|
+ if (!values || len < sizeof(*values) * 2)
|
||||||
|
+ return -EINVAL;
|
||||||
|
+
|
||||||
|
+ res->name = node->name;
|
||||||
|
+ res->start = be32_to_cpup(values++);
|
||||||
|
+ res->end = be32_to_cpup(values);
|
||||||
|
+ res->flags = IORESOURCE_BUS;
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+EXPORT_SYMBOL_GPL(of_pci_parse_bus_range);
|
||||||
|
--- a/include/linux/of_pci.h
|
||||||
|
+++ b/include/linux/of_pci.h
|
||||||
|
@@ -11,5 +11,6 @@ struct device_node;
|
||||||
|
struct device_node *of_pci_find_child_device(struct device_node *parent,
|
||||||
|
unsigned int devfn);
|
||||||
|
int of_pci_get_devfn(struct device_node *np);
|
||||||
|
+int of_pci_parse_bus_range(struct device_node *node, struct resource *res);
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,30 @@
|
||||||
|
From f12aa05cbfb88e5541814ffa7be7e195471568bd Mon Sep 17 00:00:00 2001
|
||||||
|
From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||||
|
Date: Fri, 7 Dec 2012 20:35:20 +0100
|
||||||
|
Subject: [PATCH 007/203] clk: mvebu: create parent-child relation for PCIe
|
||||||
|
clocks on Armada 370
|
||||||
|
|
||||||
|
The Armada 370 has two gatable clocks for each PCIe interface, and we
|
||||||
|
want both of them to be enabled. We therefore make one of the two
|
||||||
|
clocks a child of the other, as we did for the sataX and sataXlnk
|
||||||
|
clocks on Armada XP.
|
||||||
|
|
||||||
|
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||||
|
Cc: Mike Turquette <mturquette@linaro.org>
|
||||||
|
---
|
||||||
|
drivers/clk/mvebu/clk-gating-ctrl.c | 4 ++--
|
||||||
|
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/clk/mvebu/clk-gating-ctrl.c
|
||||||
|
+++ b/drivers/clk/mvebu/clk-gating-ctrl.c
|
||||||
|
@@ -119,8 +119,8 @@ static const struct mvebu_soc_descr __in
|
||||||
|
{ "pex1_en", NULL, 2 },
|
||||||
|
{ "ge1", NULL, 3 },
|
||||||
|
{ "ge0", NULL, 4 },
|
||||||
|
- { "pex0", NULL, 5 },
|
||||||
|
- { "pex1", NULL, 9 },
|
||||||
|
+ { "pex0", "pex0_en", 5 },
|
||||||
|
+ { "pex1", "pex1_en", 9 },
|
||||||
|
{ "sata0", NULL, 15 },
|
||||||
|
{ "sdio", NULL, 17 },
|
||||||
|
{ "tdm", NULL, 25 },
|
|
@ -0,0 +1,50 @@
|
||||||
|
From 5006da299ae65cadf92932f2f7b062b5a8c65798 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||||
|
Date: Fri, 18 Jan 2013 16:42:01 +0100
|
||||||
|
Subject: [PATCH 008/203] clk: mvebu: add more PCIe clocks for Armada XP
|
||||||
|
|
||||||
|
The current revision of the datasheet only mentions the gatable clocks
|
||||||
|
for the PCIe 0.0, 0.1, 0.2 and 0.3 interfaces, and forgot to mention
|
||||||
|
the ones for the PCIe 1.0, 1.1, 1.2, 1.3, 2.0 and 3.0
|
||||||
|
interfaces. After confirmation with Marvell engineers, this patch adds
|
||||||
|
the missing gatable clocks for those PCIe interfaces.
|
||||||
|
|
||||||
|
It also changes the name of the previously existing PCIe gatable
|
||||||
|
clocks, in order to match the naming using the datasheets.
|
||||||
|
|
||||||
|
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||||
|
Cc: Mike Turquette <mturquette@linaro.org>
|
||||||
|
---
|
||||||
|
drivers/clk/mvebu/clk-gating-ctrl.c | 14 ++++++++++----
|
||||||
|
1 file changed, 10 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/clk/mvebu/clk-gating-ctrl.c
|
||||||
|
+++ b/drivers/clk/mvebu/clk-gating-ctrl.c
|
||||||
|
@@ -137,10 +137,14 @@ static const struct mvebu_soc_descr __in
|
||||||
|
{ "ge2", NULL, 2 },
|
||||||
|
{ "ge1", NULL, 3 },
|
||||||
|
{ "ge0", NULL, 4 },
|
||||||
|
- { "pex0", NULL, 5 },
|
||||||
|
- { "pex1", NULL, 6 },
|
||||||
|
- { "pex2", NULL, 7 },
|
||||||
|
- { "pex3", NULL, 8 },
|
||||||
|
+ { "pex00", NULL, 5 },
|
||||||
|
+ { "pex01", NULL, 6 },
|
||||||
|
+ { "pex02", NULL, 7 },
|
||||||
|
+ { "pex03", NULL, 8 },
|
||||||
|
+ { "pex10", NULL, 9 },
|
||||||
|
+ { "pex11", NULL, 10 },
|
||||||
|
+ { "pex12", NULL, 11 },
|
||||||
|
+ { "pex13", NULL, 12 },
|
||||||
|
{ "bp", NULL, 13 },
|
||||||
|
{ "sata0lnk", NULL, 14 },
|
||||||
|
{ "sata0", "sata0lnk", 15 },
|
||||||
|
@@ -152,6 +156,8 @@ static const struct mvebu_soc_descr __in
|
||||||
|
{ "xor0", NULL, 22 },
|
||||||
|
{ "crypto", NULL, 23 },
|
||||||
|
{ "tdm", NULL, 25 },
|
||||||
|
+ { "pex20", NULL, 26 },
|
||||||
|
+ { "pex30", NULL, 27 },
|
||||||
|
{ "xor1", NULL, 28 },
|
||||||
|
{ "sata1lnk", NULL, 29 },
|
||||||
|
{ "sata1", "sata1lnk", 30 },
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,25 @@
|
||||||
|
From 430d545623552ddc6b68785032cc9129d0a00b43 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||||
|
Date: Fri, 7 Dec 2012 20:56:52 +0100
|
||||||
|
Subject: [PATCH 010/203] arm: mvebu: PCIe support is now available on mvebu
|
||||||
|
|
||||||
|
Now that the PCIe driver for mvebu has been integrated and all its
|
||||||
|
relevant dependencies, we can mark the ARCH_MVEBU platform has
|
||||||
|
MIGHT_HAVE_PCI, which allows to select the PCI bus support if needed.
|
||||||
|
|
||||||
|
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||||
|
---
|
||||||
|
arch/arm/mach-mvebu/Kconfig | 2 ++
|
||||||
|
1 file changed, 2 insertions(+)
|
||||||
|
|
||||||
|
--- a/arch/arm/mach-mvebu/Kconfig
|
||||||
|
+++ b/arch/arm/mach-mvebu/Kconfig
|
||||||
|
@@ -16,6 +16,8 @@ config ARCH_MVEBU
|
||||||
|
select MVEBU_MBUS
|
||||||
|
select ZONE_DMA if ARM_LPAE
|
||||||
|
select ARCH_REQUIRE_GPIOLIB
|
||||||
|
+ select MIGHT_HAVE_PCI
|
||||||
|
+ select PCI_QUIRKS if PCI
|
||||||
|
|
||||||
|
if ARCH_MVEBU
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
From c3da1bb20af37c09a07756d54420470788f131c7 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||||
|
Date: Fri, 7 Dec 2012 22:49:57 +0100
|
||||||
|
Subject: [PATCH 011/203] arm: mvebu: update defconfig with PCI and USB support
|
||||||
|
|
||||||
|
Now that we have the necessary drivers and Device Tree informations to
|
||||||
|
support PCIe on Armada 370 and Armada XP, enable the CONFIG_PCI
|
||||||
|
option.
|
||||||
|
|
||||||
|
Also, since the Armada 370 Mirabox has a built-in USB XHCI controller
|
||||||
|
connected on the PCIe bus, enable the corresponding options as well.
|
||||||
|
|
||||||
|
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||||
|
---
|
||||||
|
arch/arm/configs/mvebu_defconfig | 3 +++
|
||||||
|
1 file changed, 3 insertions(+)
|
||||||
|
|
||||||
|
--- a/arch/arm/configs/mvebu_defconfig
|
||||||
|
+++ b/arch/arm/configs/mvebu_defconfig
|
||||||
|
@@ -13,6 +13,8 @@ CONFIG_MACH_ARMADA_370=y
|
||||||
|
CONFIG_MACH_ARMADA_XP=y
|
||||||
|
# CONFIG_CACHE_L2X0 is not set
|
||||||
|
# CONFIG_SWP_EMULATE is not set
|
||||||
|
+CONFIG_PCI=y
|
||||||
|
+CONFIG_PCI_MVEBU=y
|
||||||
|
CONFIG_SMP=y
|
||||||
|
CONFIG_AEABI=y
|
||||||
|
CONFIG_HIGHMEM=y
|
||||||
|
@@ -61,6 +63,7 @@ CONFIG_USB=y
|
||||||
|
CONFIG_USB_EHCI_HCD=y
|
||||||
|
CONFIG_USB_EHCI_ROOT_HUB_TT=y
|
||||||
|
CONFIG_USB_STORAGE=y
|
||||||
|
+CONFIG_USB_XHCI_HCD=y
|
||||||
|
CONFIG_MMC=y
|
||||||
|
CONFIG_MMC_MVSDIO=y
|
||||||
|
CONFIG_NEW_LEDS=y
|
|
@ -0,0 +1,40 @@
|
||||||
|
From f865fd0e1c10bb044d56037eaa6ac4a4a122c62a Mon Sep 17 00:00:00 2001
|
||||||
|
From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||||
|
Date: Tue, 21 May 2013 12:33:28 +0200
|
||||||
|
Subject: [PATCH 012/203] arm: mvebu: mark functions of armada-370-xp.c as
|
||||||
|
static
|
||||||
|
|
||||||
|
All the functions in armada-370-xp.c are called from the
|
||||||
|
DT_MACHINE_START function pointers, so there is no need for them to be
|
||||||
|
visible outside of this file, and we therefore mark them as static.
|
||||||
|
|
||||||
|
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||||
|
Signed-off-by: Jason Cooper <jason@lakedaemon.net>
|
||||||
|
---
|
||||||
|
arch/arm/mach-mvebu/armada-370-xp.c | 6 +++---
|
||||||
|
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
--- a/arch/arm/mach-mvebu/armada-370-xp.c
|
||||||
|
+++ b/arch/arm/mach-mvebu/armada-370-xp.c
|
||||||
|
@@ -38,18 +38,18 @@ static struct map_desc armada_370_xp_io_
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
-void __init armada_370_xp_map_io(void)
|
||||||
|
+static void __init armada_370_xp_map_io(void)
|
||||||
|
{
|
||||||
|
iotable_init(armada_370_xp_io_desc, ARRAY_SIZE(armada_370_xp_io_desc));
|
||||||
|
}
|
||||||
|
|
||||||
|
-void __init armada_370_xp_timer_and_clk_init(void)
|
||||||
|
+static void __init armada_370_xp_timer_and_clk_init(void)
|
||||||
|
{
|
||||||
|
mvebu_clocks_init();
|
||||||
|
armada_370_xp_timer_init();
|
||||||
|
}
|
||||||
|
|
||||||
|
-void __init armada_370_xp_init_early(void)
|
||||||
|
+static void __init armada_370_xp_init_early(void)
|
||||||
|
{
|
||||||
|
char *mbus_soc_name;
|
||||||
|
|
|
@ -0,0 +1,568 @@
|
||||||
|
From 8b417cc752ac4158dcfcf02beafce80b90fd827d Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
|
||||||
|
Date: Tue, 23 Apr 2013 16:21:26 -0300
|
||||||
|
Subject: [PATCH 013/203] drivers: memory: Introduce Marvell EBU Device Bus
|
||||||
|
driver
|
||||||
|
|
||||||
|
Marvell EBU SoCs such as Armada 370/XP, Orion5x (88f5xxx) and
|
||||||
|
Discovery (mv78xx0) supports a Device Bus controller to access several
|
||||||
|
kinds of memories and I/O devices (NOR, NAND, SRAM, FPGA).
|
||||||
|
|
||||||
|
This commit adds a driver to handle this controller. So far only
|
||||||
|
Armada 370, Armada XP and Discovery SoCs are supported.
|
||||||
|
|
||||||
|
The driver must be registered through a device tree node;
|
||||||
|
as explained in the binding document.
|
||||||
|
|
||||||
|
For each child node in the device tree, this driver will:
|
||||||
|
* set timing parameters
|
||||||
|
* register a child device
|
||||||
|
* setup an address decoding window, using the mbus driver
|
||||||
|
|
||||||
|
Keep in mind the address decoding window setup is only a temporary hack.
|
||||||
|
This code will be removed from this devbus driver as soon as a proper device
|
||||||
|
tree binding for the mbus driver is added.
|
||||||
|
|
||||||
|
Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
|
||||||
|
Acked-by: Arnd Bergmann <arnd@arndb.de>
|
||||||
|
Acked-by: Jason Cooper <jason@lakedaemon.net>
|
||||||
|
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||||
|
---
|
||||||
|
.../bindings/memory-controllers/mvebu-devbus.txt | 156 ++++++++++
|
||||||
|
drivers/memory/Kconfig | 10 +
|
||||||
|
drivers/memory/Makefile | 1 +
|
||||||
|
drivers/memory/mvebu-devbus.c | 340 +++++++++++++++++++++
|
||||||
|
4 files changed, 507 insertions(+)
|
||||||
|
create mode 100644 Documentation/devicetree/bindings/memory-controllers/mvebu-devbus.txt
|
||||||
|
create mode 100644 drivers/memory/mvebu-devbus.c
|
||||||
|
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/Documentation/devicetree/bindings/memory-controllers/mvebu-devbus.txt
|
||||||
|
@@ -0,0 +1,156 @@
|
||||||
|
+Device tree bindings for MVEBU Device Bus controllers
|
||||||
|
+
|
||||||
|
+The Device Bus controller available in some Marvell's SoC allows to control
|
||||||
|
+different types of standard memory and I/O devices such as NOR, NAND, and FPGA.
|
||||||
|
+The actual devices are instantiated from the child nodes of a Device Bus node.
|
||||||
|
+
|
||||||
|
+Required properties:
|
||||||
|
+
|
||||||
|
+ - compatible: Currently only Armada 370/XP SoC are supported,
|
||||||
|
+ with this compatible string:
|
||||||
|
+
|
||||||
|
+ marvell,mvebu-devbus
|
||||||
|
+
|
||||||
|
+ - reg: A resource specifier for the register space.
|
||||||
|
+ This is the base address of a chip select within
|
||||||
|
+ the controller's register space.
|
||||||
|
+ (see the example below)
|
||||||
|
+
|
||||||
|
+ - #address-cells: Must be set to 1
|
||||||
|
+ - #size-cells: Must be set to 1
|
||||||
|
+ - ranges: Must be set up to reflect the memory layout with four
|
||||||
|
+ integer values for each chip-select line in use:
|
||||||
|
+ 0 <physical address of mapping> <size>
|
||||||
|
+
|
||||||
|
+Mandatory timing properties for child nodes:
|
||||||
|
+
|
||||||
|
+Read parameters:
|
||||||
|
+
|
||||||
|
+ - devbus,turn-off-ps: Defines the time during which the controller does not
|
||||||
|
+ drive the AD bus after the completion of a device read.
|
||||||
|
+ This prevents contentions on the Device Bus after a read
|
||||||
|
+ cycle from a slow device.
|
||||||
|
+
|
||||||
|
+ - devbus,bus-width: Defines the bus width (e.g. <16>)
|
||||||
|
+
|
||||||
|
+ - devbus,badr-skew-ps: Defines the time delay from from A[2:0] toggle,
|
||||||
|
+ to read data sample. This parameter is useful for
|
||||||
|
+ synchronous pipelined devices, where the address
|
||||||
|
+ precedes the read data by one or two cycles.
|
||||||
|
+
|
||||||
|
+ - devbus,acc-first-ps: Defines the time delay from the negation of
|
||||||
|
+ ALE[0] to the cycle that the first read data is sampled
|
||||||
|
+ by the controller.
|
||||||
|
+
|
||||||
|
+ - devbus,acc-next-ps: Defines the time delay between the cycle that
|
||||||
|
+ samples data N and the cycle that samples data N+1
|
||||||
|
+ (in burst accesses).
|
||||||
|
+
|
||||||
|
+ - devbus,rd-setup-ps: Defines the time delay between DEV_CSn assertion to
|
||||||
|
+ DEV_OEn assertion. If set to 0 (default),
|
||||||
|
+ DEV_OEn and DEV_CSn are asserted at the same cycle.
|
||||||
|
+ This parameter has no affect on <acc-first-ps> parameter
|
||||||
|
+ (no affect on first data sample). Set <rd-setup-ps>
|
||||||
|
+ to a value smaller than <acc-first-ps>.
|
||||||
|
+
|
||||||
|
+ - devbus,rd-hold-ps: Defines the time between the last data sample to the
|
||||||
|
+ de-assertion of DEV_CSn. If set to 0 (default),
|
||||||
|
+ DEV_OEn and DEV_CSn are de-asserted at the same cycle
|
||||||
|
+ (the cycle of the last data sample).
|
||||||
|
+ This parameter has no affect on DEV_OEn de-assertion.
|
||||||
|
+ DEV_OEn is always de-asserted the next cycle after
|
||||||
|
+ last data sampled. Also this parameter has no
|
||||||
|
+ affect on <turn-off-ps> parameter.
|
||||||
|
+ Set <rd-hold-ps> to a value smaller than <turn-off-ps>.
|
||||||
|
+
|
||||||
|
+Write parameters:
|
||||||
|
+
|
||||||
|
+ - devbus,ale-wr-ps: Defines the time delay from the ALE[0] negation cycle
|
||||||
|
+ to the DEV_WEn assertion.
|
||||||
|
+
|
||||||
|
+ - devbus,wr-low-ps: Defines the time during which DEV_WEn is active.
|
||||||
|
+ A[2:0] and Data are kept valid as long as DEV_WEn
|
||||||
|
+ is active. This parameter defines the setup time of
|
||||||
|
+ address and data to DEV_WEn rise.
|
||||||
|
+
|
||||||
|
+ - devbus,wr-high-ps: Defines the time during which DEV_WEn is kept
|
||||||
|
+ inactive (high) between data beats of a burst write.
|
||||||
|
+ DEV_A[2:0] and Data are kept valid (do not toggle) for
|
||||||
|
+ <wr-high-ps> - <tick> ps.
|
||||||
|
+ This parameter defines the hold time of address and
|
||||||
|
+ data after DEV_WEn rise.
|
||||||
|
+
|
||||||
|
+ - devbus,sync-enable: Synchronous device enable.
|
||||||
|
+ 1: True
|
||||||
|
+ 0: False
|
||||||
|
+
|
||||||
|
+An example for an Armada XP GP board, with a 16 MiB NOR device as child
|
||||||
|
+is showed below. Note that the Device Bus driver is in charge of allocating
|
||||||
|
+the mbus address decoding window for each of its child devices.
|
||||||
|
+The window is created using the chip select specified in the child
|
||||||
|
+device node together with the base address and size specified in the ranges
|
||||||
|
+property. For instance, in the example below the allocated decoding window
|
||||||
|
+will start at base address 0xf0000000, with a size 0x1000000 (16 MiB)
|
||||||
|
+for chip select 0 (a.k.a DEV_BOOTCS).
|
||||||
|
+
|
||||||
|
+This address window handling is done in this mvebu-devbus only as a temporary
|
||||||
|
+solution. It will be removed when the support for mbus device tree binding is
|
||||||
|
+added.
|
||||||
|
+
|
||||||
|
+The reg property implicitly specifies the chip select as this:
|
||||||
|
+
|
||||||
|
+ 0x10400: DEV_BOOTCS
|
||||||
|
+ 0x10408: DEV_CS0
|
||||||
|
+ 0x10410: DEV_CS1
|
||||||
|
+ 0x10418: DEV_CS2
|
||||||
|
+ 0x10420: DEV_CS3
|
||||||
|
+
|
||||||
|
+Example:
|
||||||
|
+
|
||||||
|
+ devbus-bootcs@d0010400 {
|
||||||
|
+ status = "okay";
|
||||||
|
+ ranges = <0 0xf0000000 0x1000000>; /* @addr 0xf0000000, size 0x1000000 */
|
||||||
|
+ #address-cells = <1>;
|
||||||
|
+ #size-cells = <1>;
|
||||||
|
+
|
||||||
|
+ /* Device Bus parameters are required */
|
||||||
|
+
|
||||||
|
+ /* Read parameters */
|
||||||
|
+ devbus,bus-width = <8>;
|
||||||
|
+ devbus,turn-off-ps = <60000>;
|
||||||
|
+ devbus,badr-skew-ps = <0>;
|
||||||
|
+ devbus,acc-first-ps = <124000>;
|
||||||
|
+ devbus,acc-next-ps = <248000>;
|
||||||
|
+ devbus,rd-setup-ps = <0>;
|
||||||
|
+ devbus,rd-hold-ps = <0>;
|
||||||
|
+
|
||||||
|
+ /* Write parameters */
|
||||||
|
+ devbus,sync-enable = <0>;
|
||||||
|
+ devbus,wr-high-ps = <60000>;
|
||||||
|
+ devbus,wr-low-ps = <60000>;
|
||||||
|
+ devbus,ale-wr-ps = <60000>;
|
||||||
|
+
|
||||||
|
+ flash@0 {
|
||||||
|
+ compatible = "cfi-flash";
|
||||||
|
+
|
||||||
|
+ /* 16 MiB */
|
||||||
|
+ reg = <0 0x1000000>;
|
||||||
|
+ bank-width = <2>;
|
||||||
|
+ #address-cells = <1>;
|
||||||
|
+ #size-cells = <1>;
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * We split the 16 MiB in two partitions,
|
||||||
|
+ * just as an example.
|
||||||
|
+ */
|
||||||
|
+ partition@0 {
|
||||||
|
+ label = "First";
|
||||||
|
+ reg = <0 0x800000>;
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ partition@800000 {
|
||||||
|
+ label = "Second";
|
||||||
|
+ reg = <0x800000 0x800000>;
|
||||||
|
+ };
|
||||||
|
+ };
|
||||||
|
+ };
|
||||||
|
--- a/drivers/memory/Kconfig
|
||||||
|
+++ b/drivers/memory/Kconfig
|
||||||
|
@@ -20,6 +20,16 @@ config TI_EMIF
|
||||||
|
parameters and other settings during frequency, voltage and
|
||||||
|
temperature changes
|
||||||
|
|
||||||
|
+config MVEBU_DEVBUS
|
||||||
|
+ bool "Marvell EBU Device Bus Controller"
|
||||||
|
+ default y
|
||||||
|
+ depends on PLAT_ORION && OF
|
||||||
|
+ help
|
||||||
|
+ This driver is for the Device Bus controller available in some
|
||||||
|
+ Marvell EBU SoCs such as Discovery (mv78xx0), Orion (88f5xxx) and
|
||||||
|
+ Armada 370 and Armada XP. This controller allows to handle flash
|
||||||
|
+ devices such as NOR, NAND, SRAM, and FPGA.
|
||||||
|
+
|
||||||
|
config TEGRA20_MC
|
||||||
|
bool "Tegra20 Memory Controller(MC) driver"
|
||||||
|
default y
|
||||||
|
--- a/drivers/memory/Makefile
|
||||||
|
+++ b/drivers/memory/Makefile
|
||||||
|
@@ -6,5 +6,6 @@ ifeq ($(CONFIG_DDR),y)
|
||||||
|
obj-$(CONFIG_OF) += of_memory.o
|
||||||
|
endif
|
||||||
|
obj-$(CONFIG_TI_EMIF) += emif.o
|
||||||
|
+obj-$(CONFIG_MVEBU_DEVBUS) += mvebu-devbus.o
|
||||||
|
obj-$(CONFIG_TEGRA20_MC) += tegra20-mc.o
|
||||||
|
obj-$(CONFIG_TEGRA30_MC) += tegra30-mc.o
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/drivers/memory/mvebu-devbus.c
|
||||||
|
@@ -0,0 +1,340 @@
|
||||||
|
+/*
|
||||||
|
+ * Marvell EBU SoC Device Bus Controller
|
||||||
|
+ * (memory controller for NOR/NAND/SRAM/FPGA devices)
|
||||||
|
+ *
|
||||||
|
+ * Copyright (C) 2013 Marvell
|
||||||
|
+ *
|
||||||
|
+ * This program is free software: you can redistribute it and/or modify
|
||||||
|
+ * it under the terms of the GNU General Public License as published by
|
||||||
|
+ * the Free Software Foundation version 2 of the License.
|
||||||
|
+ *
|
||||||
|
+ * This program is distributed in the hope that it will be useful,
|
||||||
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
+ * GNU General Public License for more details.
|
||||||
|
+ *
|
||||||
|
+ * You should have received a copy of the GNU General Public License
|
||||||
|
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
+ *
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#include <linux/kernel.h>
|
||||||
|
+#include <linux/module.h>
|
||||||
|
+#include <linux/slab.h>
|
||||||
|
+#include <linux/err.h>
|
||||||
|
+#include <linux/io.h>
|
||||||
|
+#include <linux/clk.h>
|
||||||
|
+#include <linux/mbus.h>
|
||||||
|
+#include <linux/of_platform.h>
|
||||||
|
+#include <linux/of_address.h>
|
||||||
|
+#include <linux/platform_device.h>
|
||||||
|
+
|
||||||
|
+/* Register definitions */
|
||||||
|
+#define DEV_WIDTH_BIT 30
|
||||||
|
+#define BADR_SKEW_BIT 28
|
||||||
|
+#define RD_HOLD_BIT 23
|
||||||
|
+#define ACC_NEXT_BIT 17
|
||||||
|
+#define RD_SETUP_BIT 12
|
||||||
|
+#define ACC_FIRST_BIT 6
|
||||||
|
+
|
||||||
|
+#define SYNC_ENABLE_BIT 24
|
||||||
|
+#define WR_HIGH_BIT 16
|
||||||
|
+#define WR_LOW_BIT 8
|
||||||
|
+
|
||||||
|
+#define READ_PARAM_OFFSET 0x0
|
||||||
|
+#define WRITE_PARAM_OFFSET 0x4
|
||||||
|
+
|
||||||
|
+static const char * const devbus_wins[] = {
|
||||||
|
+ "devbus-boot",
|
||||||
|
+ "devbus-cs0",
|
||||||
|
+ "devbus-cs1",
|
||||||
|
+ "devbus-cs2",
|
||||||
|
+ "devbus-cs3",
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+struct devbus_read_params {
|
||||||
|
+ u32 bus_width;
|
||||||
|
+ u32 badr_skew;
|
||||||
|
+ u32 turn_off;
|
||||||
|
+ u32 acc_first;
|
||||||
|
+ u32 acc_next;
|
||||||
|
+ u32 rd_setup;
|
||||||
|
+ u32 rd_hold;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+struct devbus_write_params {
|
||||||
|
+ u32 sync_enable;
|
||||||
|
+ u32 wr_high;
|
||||||
|
+ u32 wr_low;
|
||||||
|
+ u32 ale_wr;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+struct devbus {
|
||||||
|
+ struct device *dev;
|
||||||
|
+ void __iomem *base;
|
||||||
|
+ unsigned long tick_ps;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static int get_timing_param_ps(struct devbus *devbus,
|
||||||
|
+ struct device_node *node,
|
||||||
|
+ const char *name,
|
||||||
|
+ u32 *ticks)
|
||||||
|
+{
|
||||||
|
+ u32 time_ps;
|
||||||
|
+ int err;
|
||||||
|
+
|
||||||
|
+ err = of_property_read_u32(node, name, &time_ps);
|
||||||
|
+ if (err < 0) {
|
||||||
|
+ dev_err(devbus->dev, "%s has no '%s' property\n",
|
||||||
|
+ name, node->full_name);
|
||||||
|
+ return err;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ *ticks = (time_ps + devbus->tick_ps - 1) / devbus->tick_ps;
|
||||||
|
+
|
||||||
|
+ dev_dbg(devbus->dev, "%s: %u ps -> 0x%x\n",
|
||||||
|
+ name, time_ps, *ticks);
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int devbus_set_timing_params(struct devbus *devbus,
|
||||||
|
+ struct device_node *node)
|
||||||
|
+{
|
||||||
|
+ struct devbus_read_params r;
|
||||||
|
+ struct devbus_write_params w;
|
||||||
|
+ u32 value;
|
||||||
|
+ int err;
|
||||||
|
+
|
||||||
|
+ dev_dbg(devbus->dev, "Setting timing parameter, tick is %lu ps\n",
|
||||||
|
+ devbus->tick_ps);
|
||||||
|
+
|
||||||
|
+ /* Get read timings */
|
||||||
|
+ err = of_property_read_u32(node, "devbus,bus-width", &r.bus_width);
|
||||||
|
+ if (err < 0) {
|
||||||
|
+ dev_err(devbus->dev,
|
||||||
|
+ "%s has no 'devbus,bus-width' property\n",
|
||||||
|
+ node->full_name);
|
||||||
|
+ return err;
|
||||||
|
+ }
|
||||||
|
+ /* Convert bit width to byte width */
|
||||||
|
+ r.bus_width /= 8;
|
||||||
|
+
|
||||||
|
+ err = get_timing_param_ps(devbus, node, "devbus,badr-skew-ps",
|
||||||
|
+ &r.badr_skew);
|
||||||
|
+ if (err < 0)
|
||||||
|
+ return err;
|
||||||
|
+
|
||||||
|
+ err = get_timing_param_ps(devbus, node, "devbus,turn-off-ps",
|
||||||
|
+ &r.turn_off);
|
||||||
|
+ if (err < 0)
|
||||||
|
+ return err;
|
||||||
|
+
|
||||||
|
+ err = get_timing_param_ps(devbus, node, "devbus,acc-first-ps",
|
||||||
|
+ &r.acc_first);
|
||||||
|
+ if (err < 0)
|
||||||
|
+ return err;
|
||||||
|
+
|
||||||
|
+ err = get_timing_param_ps(devbus, node, "devbus,acc-next-ps",
|
||||||
|
+ &r.acc_next);
|
||||||
|
+ if (err < 0)
|
||||||
|
+ return err;
|
||||||
|
+
|
||||||
|
+ err = get_timing_param_ps(devbus, node, "devbus,rd-setup-ps",
|
||||||
|
+ &r.rd_setup);
|
||||||
|
+ if (err < 0)
|
||||||
|
+ return err;
|
||||||
|
+
|
||||||
|
+ err = get_timing_param_ps(devbus, node, "devbus,rd-hold-ps",
|
||||||
|
+ &r.rd_hold);
|
||||||
|
+ if (err < 0)
|
||||||
|
+ return err;
|
||||||
|
+
|
||||||
|
+ /* Get write timings */
|
||||||
|
+ err = of_property_read_u32(node, "devbus,sync-enable",
|
||||||
|
+ &w.sync_enable);
|
||||||
|
+ if (err < 0) {
|
||||||
|
+ dev_err(devbus->dev,
|
||||||
|
+ "%s has no 'devbus,sync-enable' property\n",
|
||||||
|
+ node->full_name);
|
||||||
|
+ return err;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ err = get_timing_param_ps(devbus, node, "devbus,ale-wr-ps",
|
||||||
|
+ &w.ale_wr);
|
||||||
|
+ if (err < 0)
|
||||||
|
+ return err;
|
||||||
|
+
|
||||||
|
+ err = get_timing_param_ps(devbus, node, "devbus,wr-low-ps",
|
||||||
|
+ &w.wr_low);
|
||||||
|
+ if (err < 0)
|
||||||
|
+ return err;
|
||||||
|
+
|
||||||
|
+ err = get_timing_param_ps(devbus, node, "devbus,wr-high-ps",
|
||||||
|
+ &w.wr_high);
|
||||||
|
+ if (err < 0)
|
||||||
|
+ return err;
|
||||||
|
+
|
||||||
|
+ /* Set read timings */
|
||||||
|
+ value = r.bus_width << DEV_WIDTH_BIT |
|
||||||
|
+ r.badr_skew << BADR_SKEW_BIT |
|
||||||
|
+ r.rd_hold << RD_HOLD_BIT |
|
||||||
|
+ r.acc_next << ACC_NEXT_BIT |
|
||||||
|
+ r.rd_setup << RD_SETUP_BIT |
|
||||||
|
+ r.acc_first << ACC_FIRST_BIT |
|
||||||
|
+ r.turn_off;
|
||||||
|
+
|
||||||
|
+ dev_dbg(devbus->dev, "read parameters register 0x%p = 0x%x\n",
|
||||||
|
+ devbus->base + READ_PARAM_OFFSET,
|
||||||
|
+ value);
|
||||||
|
+
|
||||||
|
+ writel(value, devbus->base + READ_PARAM_OFFSET);
|
||||||
|
+
|
||||||
|
+ /* Set write timings */
|
||||||
|
+ value = w.sync_enable << SYNC_ENABLE_BIT |
|
||||||
|
+ w.wr_low << WR_LOW_BIT |
|
||||||
|
+ w.wr_high << WR_HIGH_BIT |
|
||||||
|
+ w.ale_wr;
|
||||||
|
+
|
||||||
|
+ dev_dbg(devbus->dev, "write parameters register: 0x%p = 0x%x\n",
|
||||||
|
+ devbus->base + WRITE_PARAM_OFFSET,
|
||||||
|
+ value);
|
||||||
|
+
|
||||||
|
+ writel(value, devbus->base + WRITE_PARAM_OFFSET);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int mvebu_devbus_probe(struct platform_device *pdev)
|
||||||
|
+{
|
||||||
|
+ struct device *dev = &pdev->dev;
|
||||||
|
+ struct device_node *node = pdev->dev.of_node;
|
||||||
|
+ struct device_node *parent;
|
||||||
|
+ struct devbus *devbus;
|
||||||
|
+ struct resource *res;
|
||||||
|
+ struct clk *clk;
|
||||||
|
+ unsigned long rate;
|
||||||
|
+ const __be32 *ranges;
|
||||||
|
+ int err, cs;
|
||||||
|
+ int addr_cells, p_addr_cells, size_cells;
|
||||||
|
+ int ranges_len, tuple_len;
|
||||||
|
+ u32 base, size;
|
||||||
|
+
|
||||||
|
+ devbus = devm_kzalloc(&pdev->dev, sizeof(struct devbus), GFP_KERNEL);
|
||||||
|
+ if (!devbus)
|
||||||
|
+ return -ENOMEM;
|
||||||
|
+
|
||||||
|
+ devbus->dev = dev;
|
||||||
|
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||||
|
+ devbus->base = devm_ioremap_resource(&pdev->dev, res);
|
||||||
|
+ if (IS_ERR(devbus->base))
|
||||||
|
+ return PTR_ERR(devbus->base);
|
||||||
|
+
|
||||||
|
+ clk = devm_clk_get(&pdev->dev, NULL);
|
||||||
|
+ if (IS_ERR(clk))
|
||||||
|
+ return PTR_ERR(clk);
|
||||||
|
+ clk_prepare_enable(clk);
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Obtain clock period in picoseconds,
|
||||||
|
+ * we need this in order to convert timing
|
||||||
|
+ * parameters from cycles to picoseconds.
|
||||||
|
+ */
|
||||||
|
+ rate = clk_get_rate(clk) / 1000;
|
||||||
|
+ devbus->tick_ps = 1000000000 / rate;
|
||||||
|
+
|
||||||
|
+ /* Read the device tree node and set the new timing parameters */
|
||||||
|
+ err = devbus_set_timing_params(devbus, node);
|
||||||
|
+ if (err < 0)
|
||||||
|
+ return err;
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Allocate an address window for this device.
|
||||||
|
+ * If the device probing fails, then we won't be able to
|
||||||
|
+ * remove the allocated address decoding window.
|
||||||
|
+ *
|
||||||
|
+ * FIXME: This is only a temporary hack! We need to do this here
|
||||||
|
+ * because we still don't have device tree bindings for mbus.
|
||||||
|
+ * Once that support is added, we will declare these address windows
|
||||||
|
+ * statically in the device tree, and remove the window configuration
|
||||||
|
+ * from here.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Get the CS to choose the window string.
|
||||||
|
+ * This is a bit hacky, but it will be removed once the
|
||||||
|
+ * address windows are declared in the device tree.
|
||||||
|
+ */
|
||||||
|
+ cs = (((unsigned long)devbus->base) % 0x400) / 8;
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Parse 'ranges' property to obtain a (base,size) window tuple.
|
||||||
|
+ * This will be removed once the address windows
|
||||||
|
+ * are declared in the device tree.
|
||||||
|
+ */
|
||||||
|
+ parent = of_get_parent(node);
|
||||||
|
+ if (!parent)
|
||||||
|
+ return -EINVAL;
|
||||||
|
+
|
||||||
|
+ p_addr_cells = of_n_addr_cells(parent);
|
||||||
|
+ of_node_put(parent);
|
||||||
|
+
|
||||||
|
+ addr_cells = of_n_addr_cells(node);
|
||||||
|
+ size_cells = of_n_size_cells(node);
|
||||||
|
+ tuple_len = (p_addr_cells + addr_cells + size_cells) * sizeof(__be32);
|
||||||
|
+
|
||||||
|
+ ranges = of_get_property(node, "ranges", &ranges_len);
|
||||||
|
+ if (ranges == NULL || ranges_len != tuple_len)
|
||||||
|
+ return -EINVAL;
|
||||||
|
+
|
||||||
|
+ base = of_translate_address(node, ranges + addr_cells);
|
||||||
|
+ if (base == OF_BAD_ADDR)
|
||||||
|
+ return -EINVAL;
|
||||||
|
+ size = of_read_number(ranges + addr_cells + p_addr_cells, size_cells);
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Create an mbus address windows.
|
||||||
|
+ * FIXME: Remove this, together with the above code, once the
|
||||||
|
+ * address windows are declared in the device tree.
|
||||||
|
+ */
|
||||||
|
+ err = mvebu_mbus_add_window(devbus_wins[cs], base, size);
|
||||||
|
+ if (err < 0)
|
||||||
|
+ return err;
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * We need to create a child device explicitly from here to
|
||||||
|
+ * guarantee that the child will be probed after the timing
|
||||||
|
+ * parameters for the bus are written.
|
||||||
|
+ */
|
||||||
|
+ err = of_platform_populate(node, NULL, NULL, dev);
|
||||||
|
+ if (err < 0) {
|
||||||
|
+ mvebu_mbus_del_window(base, size);
|
||||||
|
+ return err;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static const struct of_device_id mvebu_devbus_of_match[] = {
|
||||||
|
+ { .compatible = "marvell,mvebu-devbus" },
|
||||||
|
+ {},
|
||||||
|
+};
|
||||||
|
+MODULE_DEVICE_TABLE(of, mvebu_devbus_of_match);
|
||||||
|
+
|
||||||
|
+static struct platform_driver mvebu_devbus_driver = {
|
||||||
|
+ .probe = mvebu_devbus_probe,
|
||||||
|
+ .driver = {
|
||||||
|
+ .name = "mvebu-devbus",
|
||||||
|
+ .owner = THIS_MODULE,
|
||||||
|
+ .of_match_table = mvebu_devbus_of_match,
|
||||||
|
+ },
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static int __init mvebu_devbus_init(void)
|
||||||
|
+{
|
||||||
|
+ return platform_driver_register(&mvebu_devbus_driver);
|
||||||
|
+}
|
||||||
|
+module_init(mvebu_devbus_init);
|
||||||
|
+
|
||||||
|
+MODULE_LICENSE("GPL v2");
|
||||||
|
+MODULE_AUTHOR("Ezequiel Garcia <ezequiel.garcia@free-electrons.com>");
|
||||||
|
+MODULE_DESCRIPTION("Marvell EBU SoC Device Bus controller");
|
|
@ -0,0 +1,35 @@
|
||||||
|
From 348fc73a301b88ec3f2da8c1f02858c75e79455e Mon Sep 17 00:00:00 2001
|
||||||
|
From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||||
|
Date: Tue, 21 May 2013 19:53:09 +0200
|
||||||
|
Subject: [PATCH 014/203] arm: mvebu: enable two USB interfaces on the Armada
|
||||||
|
XP GP board
|
||||||
|
|
||||||
|
The Armada XP GP board has two USB slots: one on the front side and
|
||||||
|
one on the back side. This commit enables the two USB host controllers
|
||||||
|
that correspond to those wo USB slots.
|
||||||
|
|
||||||
|
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||||
|
Signed-off-by: Jason Cooper <jason@lakedaemon.net>
|
||||||
|
---
|
||||||
|
arch/arm/boot/dts/armada-xp-gp.dts | 10 ++++++++++
|
||||||
|
1 file changed, 10 insertions(+)
|
||||||
|
|
||||||
|
--- a/arch/arm/boot/dts/armada-xp-gp.dts
|
||||||
|
+++ b/arch/arm/boot/dts/armada-xp-gp.dts
|
||||||
|
@@ -105,6 +105,16 @@
|
||||||
|
phy-mode = "rgmii-id";
|
||||||
|
};
|
||||||
|
|
||||||
|
+ /* Front-side USB slot */
|
||||||
|
+ usb@50000 {
|
||||||
|
+ status = "okay";
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ /* Back-side USB slot */
|
||||||
|
+ usb@51000 {
|
||||||
|
+ status = "okay";
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
spi0: spi@10600 {
|
||||||
|
status = "okay";
|
||||||
|
|
|
@ -0,0 +1,97 @@
|
||||||
|
From 34361044442206dd7d10ff3309f8e0713e0fd856 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||||
|
Date: Thu, 23 May 2013 16:32:51 +0200
|
||||||
|
Subject: [PATCH 015/203] pci: mvebu: no longer fake the slot location of
|
||||||
|
downstream devices
|
||||||
|
|
||||||
|
By default, the Marvell hardware, for each PCIe interface, exhibits
|
||||||
|
the following devices:
|
||||||
|
|
||||||
|
* On slot 0, a "Marvell Memory controller", identical on all PCIe
|
||||||
|
interfaces, and which isn't useful when the Marvell SoC is the PCIe
|
||||||
|
root complex (i.e, the normal case when we run Linux on the Marvell
|
||||||
|
SoC).
|
||||||
|
|
||||||
|
* On slot 1, the real PCIe card connected into the PCIe slot of the
|
||||||
|
board.
|
||||||
|
|
||||||
|
So, what the Marvell PCIe driver was doing in its PCI-to-PCI bridge
|
||||||
|
emulation is that when the Linux PCI core was trying to access the
|
||||||
|
device in slot 0, we were in fact forwarding the configuration
|
||||||
|
transaction to the device in slot 1. For all other slots, we were
|
||||||
|
telling the Linux PCI core that there was no device connected.
|
||||||
|
|
||||||
|
However, new versions of bootloaders from Marvell change the default
|
||||||
|
PCIe configuration, and make the real device appear in slot 0, and the
|
||||||
|
"Marvell Memory controller" in slot 1.
|
||||||
|
|
||||||
|
Therefore, this commit modifies the Marvell PCIe driver to adjust the
|
||||||
|
PCIe hardware configuration to make sure that this behavior (real
|
||||||
|
device in slot 0, "Marvell Memory controller" in slot 1) is the one
|
||||||
|
we'll see regardless of what the bootloader has done. It allows to
|
||||||
|
remove the little hack that was forwarding configuration transactions
|
||||||
|
on slot 0 to slot 1, which is nice.
|
||||||
|
|
||||||
|
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||||
|
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
|
||||||
|
Signed-off-by: Jason Cooper <jason@lakedaemon.net>
|
||||||
|
---
|
||||||
|
drivers/pci/host/pci-mvebu.c | 19 +++++++++++++++----
|
||||||
|
1 file changed, 15 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/pci/host/pci-mvebu.c
|
||||||
|
+++ b/drivers/pci/host/pci-mvebu.c
|
||||||
|
@@ -51,6 +51,7 @@
|
||||||
|
#define PCIE_CTRL_X1_MODE 0x0001
|
||||||
|
#define PCIE_STAT_OFF 0x1a04
|
||||||
|
#define PCIE_STAT_BUS 0xff00
|
||||||
|
+#define PCIE_STAT_DEV 0x1f0000
|
||||||
|
#define PCIE_STAT_LINK_DOWN BIT(0)
|
||||||
|
#define PCIE_DEBUG_CTRL 0x1a60
|
||||||
|
#define PCIE_DEBUG_SOFT_RESET BIT(20)
|
||||||
|
@@ -148,6 +149,16 @@ static void mvebu_pcie_set_local_bus_nr(
|
||||||
|
writel(stat, port->base + PCIE_STAT_OFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void mvebu_pcie_set_local_dev_nr(struct mvebu_pcie_port *port, int nr)
|
||||||
|
+{
|
||||||
|
+ u32 stat;
|
||||||
|
+
|
||||||
|
+ stat = readl(port->base + PCIE_STAT_OFF);
|
||||||
|
+ stat &= ~PCIE_STAT_DEV;
|
||||||
|
+ stat |= nr << 16;
|
||||||
|
+ writel(stat, port->base + PCIE_STAT_OFF);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* Setup PCIE BARs and Address Decode Wins:
|
||||||
|
* BAR[0,2] -> disabled, BAR[1] -> covers all DRAM banks
|
||||||
|
@@ -572,8 +583,7 @@ static int mvebu_pcie_wr_conf(struct pci
|
||||||
|
|
||||||
|
/* Access the real PCIe interface */
|
||||||
|
spin_lock_irqsave(&port->conf_lock, flags);
|
||||||
|
- ret = mvebu_pcie_hw_wr_conf(port, bus,
|
||||||
|
- PCI_DEVFN(1, PCI_FUNC(devfn)),
|
||||||
|
+ ret = mvebu_pcie_hw_wr_conf(port, bus, devfn,
|
||||||
|
where, size, val);
|
||||||
|
spin_unlock_irqrestore(&port->conf_lock, flags);
|
||||||
|
|
||||||
|
@@ -606,8 +616,7 @@ static int mvebu_pcie_rd_conf(struct pci
|
||||||
|
|
||||||
|
/* Access the real PCIe interface */
|
||||||
|
spin_lock_irqsave(&port->conf_lock, flags);
|
||||||
|
- ret = mvebu_pcie_hw_rd_conf(port, bus,
|
||||||
|
- PCI_DEVFN(1, PCI_FUNC(devfn)),
|
||||||
|
+ ret = mvebu_pcie_hw_rd_conf(port, bus, devfn,
|
||||||
|
where, size, val);
|
||||||
|
spin_unlock_irqrestore(&port->conf_lock, flags);
|
||||||
|
|
||||||
|
@@ -817,6 +826,8 @@ static int __init mvebu_pcie_probe(struc
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ mvebu_pcie_set_local_dev_nr(port, 1);
|
||||||
|
+
|
||||||
|
if (mvebu_pcie_link_up(port)) {
|
||||||
|
port->haslink = 1;
|
||||||
|
dev_info(&pdev->dev, "PCIe%d.%d: link up\n",
|
|
@ -0,0 +1,97 @@
|
||||||
|
From 10f725e3a9e73aab2e5601206c88cf9cbc599243 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||||
|
Date: Thu, 23 May 2013 16:32:52 +0200
|
||||||
|
Subject: [PATCH 016/203] pci: mvebu: allow the enumeration of devices beyond
|
||||||
|
physical bridges
|
||||||
|
|
||||||
|
Until now, the Marvell PCIe driver was only allowing the enumeration
|
||||||
|
of the devices in the secondary bus of the emulated PCI-to-PCI
|
||||||
|
bridge. This works fine when a PCIe device is directly connected into
|
||||||
|
a PCIe slot of the Marvell board.
|
||||||
|
|
||||||
|
However, when the device connected in the PCIe slot is a physical PCIe
|
||||||
|
bridge, beyond which a real PCIe device is connected, it no longer
|
||||||
|
worked, as the driver was preventing the Linux PCI core from seeing
|
||||||
|
such devices.
|
||||||
|
|
||||||
|
This commit fixes that by ensuring that configuration transactions on
|
||||||
|
subordinate busses are properly forwarded on the right PCIe interface.
|
||||||
|
|
||||||
|
Thanks to this patch, a PCIe card beyond a PCIe bridge, itself beyond
|
||||||
|
the emulated PCI-to-PCI bridge is properly detected, with the
|
||||||
|
following layout:
|
||||||
|
|
||||||
|
-[0000:00]-+-01.0-[01]----00.0
|
||||||
|
+-09.0-[02-07]----00.0-[03-07]--+-01.0-[04]--
|
||||||
|
| +-05.0-[05]--
|
||||||
|
| +-07.0-[06]--
|
||||||
|
| \-09.0-[07]----00.0
|
||||||
|
\-0a.0-[08]----00.0
|
||||||
|
|
||||||
|
Where the PCIe interface that sits beyond the emulated PCI-to-PCI
|
||||||
|
bridge at 09.0 allows to access the secondary bus 02, on which there
|
||||||
|
is a PCIe bridge that allows to access the 3 to 7 busses, that are
|
||||||
|
subordinates to this bridge. And on one of this bus (bus 7), there is
|
||||||
|
one real PCIe device connected.
|
||||||
|
|
||||||
|
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||||
|
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
|
||||||
|
Signed-off-by: Jason Cooper <jason@lakedaemon.net>
|
||||||
|
---
|
||||||
|
drivers/pci/host/pci-mvebu.c | 31 ++++++++++++++++++++++++++++---
|
||||||
|
1 file changed, 28 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/pci/host/pci-mvebu.c
|
||||||
|
+++ b/drivers/pci/host/pci-mvebu.c
|
||||||
|
@@ -554,7 +554,8 @@ mvebu_pcie_find_port(struct mvebu_pcie *
|
||||||
|
if (bus->number == 0 && port->devfn == devfn)
|
||||||
|
return port;
|
||||||
|
if (bus->number != 0 &&
|
||||||
|
- port->bridge.secondary_bus == bus->number)
|
||||||
|
+ bus->number >= port->bridge.secondary_bus &&
|
||||||
|
+ bus->number <= port->bridge.subordinate_bus)
|
||||||
|
return port;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -578,7 +579,18 @@ static int mvebu_pcie_wr_conf(struct pci
|
||||||
|
if (bus->number == 0)
|
||||||
|
return mvebu_sw_pci_bridge_write(port, where, size, val);
|
||||||
|
|
||||||
|
- if (!port->haslink || PCI_SLOT(devfn) != 0)
|
||||||
|
+ if (!port->haslink)
|
||||||
|
+ return PCIBIOS_DEVICE_NOT_FOUND;
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * On the secondary bus, we don't want to expose any other
|
||||||
|
+ * device than the device physically connected in the PCIe
|
||||||
|
+ * slot, visible in slot 0. In slot 1, there's a special
|
||||||
|
+ * Marvell device that only makes sense when the Armada is
|
||||||
|
+ * used as a PCIe endpoint.
|
||||||
|
+ */
|
||||||
|
+ if (bus->number == port->bridge.secondary_bus &&
|
||||||
|
+ PCI_SLOT(devfn) != 0)
|
||||||
|
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||||
|
|
||||||
|
/* Access the real PCIe interface */
|
||||||
|
@@ -609,7 +621,20 @@ static int mvebu_pcie_rd_conf(struct pci
|
||||||
|
if (bus->number == 0)
|
||||||
|
return mvebu_sw_pci_bridge_read(port, where, size, val);
|
||||||
|
|
||||||
|
- if (!port->haslink || PCI_SLOT(devfn) != 0) {
|
||||||
|
+ if (!port->haslink) {
|
||||||
|
+ *val = 0xffffffff;
|
||||||
|
+ return PCIBIOS_DEVICE_NOT_FOUND;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * On the secondary bus, we don't want to expose any other
|
||||||
|
+ * device than the device physically connected in the PCIe
|
||||||
|
+ * slot, visible in slot 0. In slot 1, there's a special
|
||||||
|
+ * Marvell device that only makes sense when the Armada is
|
||||||
|
+ * used as a PCIe endpoint.
|
||||||
|
+ */
|
||||||
|
+ if (bus->number == port->bridge.secondary_bus &&
|
||||||
|
+ PCI_SLOT(devfn) != 0) {
|
||||||
|
*val = 0xffffffff;
|
||||||
|
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||||
|
}
|
|
@ -0,0 +1,87 @@
|
||||||
|
From 33e771556f5e1a59c7dbcd953ce858dd3e50ed66 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||||
|
Date: Thu, 23 May 2013 16:32:53 +0200
|
||||||
|
Subject: [PATCH 017/203] pci: mvebu: fix the emulation of the status register
|
||||||
|
|
||||||
|
The status register of the PCI configuration space of PCI-to-PCI
|
||||||
|
bridges contain some read-only bits, and so write-1-to-clear bits. So,
|
||||||
|
the Linux PCI core sometimes writes 0xffff to this status register,
|
||||||
|
and in the current PCI-to-PCI bridge emulation code of the Marvell
|
||||||
|
driver, we do take all those 1s being written. Even the read-only bits
|
||||||
|
are being overwritten.
|
||||||
|
|
||||||
|
For now, all the read-only bits should be emulated to have the zero
|
||||||
|
value.
|
||||||
|
|
||||||
|
The other bits, that are write-1-to-clear bits are used to report
|
||||||
|
various kind of errors, and are never set by the emulated bridge, so
|
||||||
|
there is no need to support this write-1-to-clear bits mechanism.
|
||||||
|
|
||||||
|
As a conclusion, the easiest solution is to simply emulate this status
|
||||||
|
register by returning zero when read, and ignore the writes to it.
|
||||||
|
|
||||||
|
This has two visible effects:
|
||||||
|
|
||||||
|
* The devsel is no longer 'unknown' in, i.e
|
||||||
|
|
||||||
|
Flags: bus master, 66MHz, user-definable features, ?? devsel, latency 0
|
||||||
|
|
||||||
|
becomes:
|
||||||
|
|
||||||
|
Flags: bus master, 66MHz, user-definable features, fast devsel, latency 0
|
||||||
|
|
||||||
|
in lspci -v.
|
||||||
|
|
||||||
|
This was caused by a value of 11b being read for devsel, which is
|
||||||
|
an invalid value. This 11b value being read was due to a previous
|
||||||
|
write of 0xffff into the status register.
|
||||||
|
|
||||||
|
* The capability list is no longer broken, because we indicate to the
|
||||||
|
Linux PCI core that we don't have a Capabilities Pointer in the PCI
|
||||||
|
configuration space of this bridge. The following message is
|
||||||
|
therefore no longer visible in lspci -v:
|
||||||
|
|
||||||
|
Capabilities: [fc] <chain broken>
|
||||||
|
|
||||||
|
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||||
|
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
|
||||||
|
Signed-off-by: Jason Cooper <jason@lakedaemon.net>
|
||||||
|
---
|
||||||
|
drivers/pci/host/pci-mvebu.c | 5 +----
|
||||||
|
1 file changed, 1 insertion(+), 4 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/pci/host/pci-mvebu.c
|
||||||
|
+++ b/drivers/pci/host/pci-mvebu.c
|
||||||
|
@@ -69,7 +69,6 @@ struct mvebu_sw_pci_bridge {
|
||||||
|
u16 vendor;
|
||||||
|
u16 device;
|
||||||
|
u16 command;
|
||||||
|
- u16 status;
|
||||||
|
u16 class;
|
||||||
|
u8 interface;
|
||||||
|
u8 revision;
|
||||||
|
@@ -359,7 +358,6 @@ static void mvebu_sw_pci_bridge_init(str
|
||||||
|
|
||||||
|
memset(bridge, 0, sizeof(struct mvebu_sw_pci_bridge));
|
||||||
|
|
||||||
|
- bridge->status = PCI_STATUS_CAP_LIST;
|
||||||
|
bridge->class = PCI_CLASS_BRIDGE_PCI;
|
||||||
|
bridge->vendor = PCI_VENDOR_ID_MARVELL;
|
||||||
|
bridge->device = MARVELL_EMULATED_PCI_PCI_BRIDGE_ID;
|
||||||
|
@@ -386,7 +384,7 @@ static int mvebu_sw_pci_bridge_read(stru
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PCI_COMMAND:
|
||||||
|
- *value = bridge->status << 16 | bridge->command;
|
||||||
|
+ *value = bridge->command;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PCI_CLASS_REVISION:
|
||||||
|
@@ -479,7 +477,6 @@ static int mvebu_sw_pci_bridge_write(str
|
||||||
|
switch (where & ~3) {
|
||||||
|
case PCI_COMMAND:
|
||||||
|
bridge->command = value & 0xffff;
|
||||||
|
- bridge->status = value >> 16;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PCI_BASE_ADDRESS_0 ... PCI_BASE_ADDRESS_1:
|
|
@ -0,0 +1,30 @@
|
||||||
|
From fc7dfe5cd096f5b5343f01f679a96ebc23e9da67 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||||
|
Date: Tue, 21 May 2013 12:33:26 +0200
|
||||||
|
Subject: [PATCH 018/203] arm: mvebu: fix length of SATA registers area in
|
||||||
|
.dtsi
|
||||||
|
|
||||||
|
The length of the registers area for the Marvell 370/XP SATA
|
||||||
|
controller was incorrect in the .dtsi: 0x2400 while it should have
|
||||||
|
been 0x5000. Until now, this problem wasn't noticed because there was
|
||||||
|
a large static mapping for all I/Os set up by ->map_io(). But since
|
||||||
|
we're going to get rid of this static mapping, we need to ensure that
|
||||||
|
the register areas are properly sized.
|
||||||
|
|
||||||
|
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||||
|
Signed-off-by: Jason Cooper <jason@lakedaemon.net>
|
||||||
|
---
|
||||||
|
arch/arm/boot/dts/armada-370-xp.dtsi | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
--- a/arch/arm/boot/dts/armada-370-xp.dtsi
|
||||||
|
+++ b/arch/arm/boot/dts/armada-370-xp.dtsi
|
||||||
|
@@ -80,7 +80,7 @@
|
||||||
|
|
||||||
|
sata@a0000 {
|
||||||
|
compatible = "marvell,orion-sata";
|
||||||
|
- reg = <0xa0000 0x2400>;
|
||||||
|
+ reg = <0xa0000 0x5000>;
|
||||||
|
interrupts = <55>;
|
||||||
|
clocks = <&gateclk 15>, <&gateclk 30>;
|
||||||
|
clock-names = "0", "1";
|
|
@ -0,0 +1,63 @@
|
||||||
|
From d887da014c3fabf5fa4da47b143edc069e72fd62 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||||
|
Date: Tue, 21 May 2013 12:33:27 +0200
|
||||||
|
Subject: [PATCH 019/203] arm: mvebu: fix length of Ethernet registers area in
|
||||||
|
.dtsi
|
||||||
|
|
||||||
|
The length of the registers area for the Marvell 370/XP Ethernet
|
||||||
|
controller was incorrect in the .dtsi: 0x2400 while it should have
|
||||||
|
been 0x4000. Until now, this problem wasn't noticed because there was
|
||||||
|
a large static mapping for all I/Os set up by ->map_io(). But since
|
||||||
|
we're going to get rid of this static mapping, we need to ensure that
|
||||||
|
the register areas are properly sized.
|
||||||
|
|
||||||
|
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||||
|
Signed-off-by: Jason Cooper <jason@lakedaemon.net>
|
||||||
|
---
|
||||||
|
arch/arm/boot/dts/armada-370-xp.dtsi | 4 ++--
|
||||||
|
arch/arm/boot/dts/armada-xp-mv78460.dtsi | 2 +-
|
||||||
|
arch/arm/boot/dts/armada-xp.dtsi | 2 +-
|
||||||
|
3 files changed, 4 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
--- a/arch/arm/boot/dts/armada-370-xp.dtsi
|
||||||
|
+++ b/arch/arm/boot/dts/armada-370-xp.dtsi
|
||||||
|
@@ -96,7 +96,7 @@
|
||||||
|
|
||||||
|
ethernet@70000 {
|
||||||
|
compatible = "marvell,armada-370-neta";
|
||||||
|
- reg = <0x70000 0x2500>;
|
||||||
|
+ reg = <0x70000 0x4000>;
|
||||||
|
interrupts = <8>;
|
||||||
|
clocks = <&gateclk 4>;
|
||||||
|
status = "disabled";
|
||||||
|
@@ -104,7 +104,7 @@
|
||||||
|
|
||||||
|
ethernet@74000 {
|
||||||
|
compatible = "marvell,armada-370-neta";
|
||||||
|
- reg = <0x74000 0x2500>;
|
||||||
|
+ reg = <0x74000 0x4000>;
|
||||||
|
interrupts = <10>;
|
||||||
|
clocks = <&gateclk 3>;
|
||||||
|
status = "disabled";
|
||||||
|
--- a/arch/arm/boot/dts/armada-xp-mv78460.dtsi
|
||||||
|
+++ b/arch/arm/boot/dts/armada-xp-mv78460.dtsi
|
||||||
|
@@ -107,7 +107,7 @@
|
||||||
|
|
||||||
|
ethernet@34000 {
|
||||||
|
compatible = "marvell,armada-370-neta";
|
||||||
|
- reg = <0x34000 0x2500>;
|
||||||
|
+ reg = <0x34000 0x4000>;
|
||||||
|
interrupts = <14>;
|
||||||
|
clocks = <&gateclk 1>;
|
||||||
|
status = "disabled";
|
||||||
|
--- a/arch/arm/boot/dts/armada-xp.dtsi
|
||||||
|
+++ b/arch/arm/boot/dts/armada-xp.dtsi
|
||||||
|
@@ -88,7 +88,7 @@
|
||||||
|
|
||||||
|
ethernet@30000 {
|
||||||
|
compatible = "marvell,armada-370-neta";
|
||||||
|
- reg = <0x30000 0x2500>;
|
||||||
|
+ reg = <0x30000 0x4000>;
|
||||||
|
interrupts = <12>;
|
||||||
|
clocks = <&gateclk 2>;
|
||||||
|
status = "disabled";
|
|
@ -0,0 +1,112 @@
|
||||||
|
From 25d3318a445c4f4360f86bf6d1d1a320d9646bb5 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||||
|
Date: Tue, 4 Jun 2013 04:52:23 +0000
|
||||||
|
Subject: [PATCH 020/203] net: mvneta: read MAC address from hardware when
|
||||||
|
available
|
||||||
|
|
||||||
|
This patch improves the logic used by the mvneta driver to find a MAC
|
||||||
|
address for a particular interface. Until now, it was only looking at
|
||||||
|
the Device Tree, and if no address was found, was falling back to
|
||||||
|
generating a random MAC address.
|
||||||
|
|
||||||
|
This patch adds the intermediate solution of reading the MAC address
|
||||||
|
from the hardware registers, in case it has been set by the
|
||||||
|
bootloader. So the order is now:
|
||||||
|
|
||||||
|
1) MAC address from the Device Tree
|
||||||
|
2) MAC address from the hardware registers
|
||||||
|
3) Random MAC address
|
||||||
|
|
||||||
|
This requires moving the MAC address initialization a little bit later
|
||||||
|
in the ->probe() code, because it now requires the hardware registers
|
||||||
|
to be remapped.
|
||||||
|
|
||||||
|
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||||
|
Cc: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
|
||||||
|
Cc: Joe Perches <joe@perches.com>
|
||||||
|
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||||
|
---
|
||||||
|
drivers/net/ethernet/marvell/mvneta.c | 44 ++++++++++++++++++++++++++++-------
|
||||||
|
1 file changed, 35 insertions(+), 9 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/net/ethernet/marvell/mvneta.c
|
||||||
|
+++ b/drivers/net/ethernet/marvell/mvneta.c
|
||||||
|
@@ -2260,6 +2260,21 @@ static int mvneta_change_mtu(struct net_
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+/* Get mac address */
|
||||||
|
+static void mvneta_get_mac_addr(struct mvneta_port *pp, unsigned char *addr)
|
||||||
|
+{
|
||||||
|
+ u32 mac_addr_l, mac_addr_h;
|
||||||
|
+
|
||||||
|
+ mac_addr_l = mvreg_read(pp, MVNETA_MAC_ADDR_LOW);
|
||||||
|
+ mac_addr_h = mvreg_read(pp, MVNETA_MAC_ADDR_HIGH);
|
||||||
|
+ addr[0] = (mac_addr_h >> 24) & 0xFF;
|
||||||
|
+ addr[1] = (mac_addr_h >> 16) & 0xFF;
|
||||||
|
+ addr[2] = (mac_addr_h >> 8) & 0xFF;
|
||||||
|
+ addr[3] = mac_addr_h & 0xFF;
|
||||||
|
+ addr[4] = (mac_addr_l >> 8) & 0xFF;
|
||||||
|
+ addr[5] = mac_addr_l & 0xFF;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/* Handle setting mac address */
|
||||||
|
static int mvneta_set_mac_addr(struct net_device *dev, void *addr)
|
||||||
|
{
|
||||||
|
@@ -2678,7 +2693,9 @@ static int mvneta_probe(struct platform_
|
||||||
|
u32 phy_addr;
|
||||||
|
struct mvneta_port *pp;
|
||||||
|
struct net_device *dev;
|
||||||
|
- const char *mac_addr;
|
||||||
|
+ const char *dt_mac_addr;
|
||||||
|
+ char hw_mac_addr[ETH_ALEN];
|
||||||
|
+ const char *mac_from;
|
||||||
|
int phy_mode;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
@@ -2714,13 +2731,6 @@ static int mvneta_probe(struct platform_
|
||||||
|
goto err_free_irq;
|
||||||
|
}
|
||||||
|
|
||||||
|
- mac_addr = of_get_mac_address(dn);
|
||||||
|
-
|
||||||
|
- if (!mac_addr || !is_valid_ether_addr(mac_addr))
|
||||||
|
- eth_hw_addr_random(dev);
|
||||||
|
- else
|
||||||
|
- memcpy(dev->dev_addr, mac_addr, ETH_ALEN);
|
||||||
|
-
|
||||||
|
dev->tx_queue_len = MVNETA_MAX_TXD;
|
||||||
|
dev->watchdog_timeo = 5 * HZ;
|
||||||
|
dev->netdev_ops = &mvneta_netdev_ops;
|
||||||
|
@@ -2751,6 +2761,21 @@ static int mvneta_probe(struct platform_
|
||||||
|
|
||||||
|
clk_prepare_enable(pp->clk);
|
||||||
|
|
||||||
|
+ dt_mac_addr = of_get_mac_address(dn);
|
||||||
|
+ if (dt_mac_addr && is_valid_ether_addr(dt_mac_addr)) {
|
||||||
|
+ mac_from = "device tree";
|
||||||
|
+ memcpy(dev->dev_addr, dt_mac_addr, ETH_ALEN);
|
||||||
|
+ } else {
|
||||||
|
+ mvneta_get_mac_addr(pp, hw_mac_addr);
|
||||||
|
+ if (is_valid_ether_addr(hw_mac_addr)) {
|
||||||
|
+ mac_from = "hardware";
|
||||||
|
+ memcpy(dev->dev_addr, hw_mac_addr, ETH_ALEN);
|
||||||
|
+ } else {
|
||||||
|
+ mac_from = "random";
|
||||||
|
+ eth_hw_addr_random(dev);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
pp->tx_done_timer.data = (unsigned long)dev;
|
||||||
|
|
||||||
|
pp->tx_ring_size = MVNETA_MAX_TXD;
|
||||||
|
@@ -2783,7 +2808,8 @@ static int mvneta_probe(struct platform_
|
||||||
|
goto err_deinit;
|
||||||
|
}
|
||||||
|
|
||||||
|
- netdev_info(dev, "mac: %pM\n", dev->dev_addr);
|
||||||
|
+ netdev_info(dev, "Using %s mac address %pM\n", mac_from,
|
||||||
|
+ dev->dev_addr);
|
||||||
|
|
||||||
|
platform_set_drvdata(pdev, pp->dev);
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
From 67373874e07eb8c54ab27f8fe9998690e50b1e91 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||||
|
Date: Thu, 6 Jun 2013 11:21:23 +0200
|
||||||
|
Subject: [PATCH 021/203] arm: mvebu: armada-xp-db: ensure PCIe range is
|
||||||
|
specified
|
||||||
|
|
||||||
|
The ranges DT entry needed by the PCIe controller is defined at the
|
||||||
|
SoC .dtsi level. However, some boards have a NOR flash, and to support
|
||||||
|
it, they need to override the SoC-level ranges property to add an
|
||||||
|
additional range. Since PCIe and NOR support came separately, some
|
||||||
|
boards were not properly changed to include the PCIe range in their
|
||||||
|
ranges property at the .dts level.
|
||||||
|
|
||||||
|
This commit fixes those platforms.
|
||||||
|
|
||||||
|
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||||
|
Signed-off-by: Jason Cooper <jason@lakedaemon.net>
|
||||||
|
---
|
||||||
|
arch/arm/boot/dts/armada-xp-db.dts | 1 +
|
||||||
|
1 file changed, 1 insertion(+)
|
||||||
|
|
||||||
|
--- a/arch/arm/boot/dts/armada-xp-db.dts
|
||||||
|
+++ b/arch/arm/boot/dts/armada-xp-db.dts
|
||||||
|
@@ -31,6 +31,7 @@
|
||||||
|
|
||||||
|
soc {
|
||||||
|
ranges = <0 0 0xd0000000 0x100000 /* Internal registers 1MiB */
|
||||||
|
+ 0xe0000000 0 0xe0000000 0x8100000 /* PCIe */
|
||||||
|
0xf0000000 0 0xf0000000 0x1000000>; /* Device Bus, NOR 16MiB */
|
||||||
|
|
||||||
|
internal-regs {
|
|
@ -0,0 +1,54 @@
|
||||||
|
From 35e8d985e056f583290406258e3f17789bd05bce Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
|
||||||
|
Date: Fri, 7 Jun 2013 13:47:38 -0300
|
||||||
|
Subject: [PATCH 022/203] bus: mvebu-mbus: Use pr_fmt
|
||||||
|
|
||||||
|
In order to clean message printing, we replace pr_info with pr_fmt.
|
||||||
|
This is purely cosmetic change, with the sole purpose of making
|
||||||
|
the code a bit more readable.
|
||||||
|
|
||||||
|
Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
|
||||||
|
Acked-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||||
|
Signed-off-by: Jason Cooper <jason@lakedaemon.net>
|
||||||
|
---
|
||||||
|
drivers/bus/mvebu-mbus.c | 8 +++++---
|
||||||
|
1 file changed, 5 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/bus/mvebu-mbus.c
|
||||||
|
+++ b/drivers/bus/mvebu-mbus.c
|
||||||
|
@@ -49,6 +49,8 @@
|
||||||
|
* configuration (file 'devices').
|
||||||
|
*/
|
||||||
|
|
||||||
|
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||||
|
+
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/init.h>
|
||||||
|
@@ -762,7 +764,7 @@ int mvebu_mbus_add_window_remap_flags(co
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (!s->soc->map[i].name) {
|
||||||
|
- pr_err("mvebu-mbus: unknown device '%s'\n", devname);
|
||||||
|
+ pr_err("unknown device '%s'\n", devname);
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -775,7 +777,7 @@ int mvebu_mbus_add_window_remap_flags(co
|
||||||
|
attr |= 0x28;
|
||||||
|
|
||||||
|
if (!mvebu_mbus_window_conflicts(s, base, size, target, attr)) {
|
||||||
|
- pr_err("mvebu-mbus: cannot add window '%s', conflicts with another window\n",
|
||||||
|
+ pr_err("cannot add window '%s', conflicts with another window\n",
|
||||||
|
devname);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
@@ -842,7 +844,7 @@ int __init mvebu_mbus_init(const char *s
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (!of_id->compatible) {
|
||||||
|
- pr_err("mvebu-mbus: could not find a matching SoC family\n");
|
||||||
|
+ pr_err("could not find a matching SoC family\n");
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
From df8ceea297967c3452a514bbde715acebf3bda29 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
|
||||||
|
Date: Fri, 7 Jun 2013 13:47:49 -0300
|
||||||
|
Subject: [PATCH 023/203] ARM: mvebu: Remove device tree unused properties on
|
||||||
|
A370
|
||||||
|
|
||||||
|
These properties are not needed so it's safe to remove them.
|
||||||
|
|
||||||
|
Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
|
||||||
|
Acked-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||||
|
Signed-off-by: Jason Cooper <jason@lakedaemon.net>
|
||||||
|
---
|
||||||
|
arch/arm/boot/dts/armada-370.dtsi | 4 ----
|
||||||
|
1 file changed, 4 deletions(-)
|
||||||
|
|
||||||
|
--- a/arch/arm/boot/dts/armada-370.dtsi
|
||||||
|
+++ b/arch/arm/boot/dts/armada-370.dtsi
|
||||||
|
@@ -180,10 +180,6 @@
|
||||||
|
|
||||||
|
bus-range = <0x00 0xff>;
|
||||||
|
|
||||||
|
- reg = <0x40000 0x2000>, <0x80000 0x2000>;
|
||||||
|
-
|
||||||
|
- reg-names = "pcie0.0", "pcie1.0";
|
||||||
|
-
|
||||||
|
ranges = <0x82000000 0 0x40000 0x40000 0 0x00002000 /* Port 0.0 registers */
|
||||||
|
0x82000000 0 0x80000 0x80000 0 0x00002000 /* Port 1.0 registers */
|
||||||
|
0x82000000 0 0xe0000000 0xe0000000 0 0x08000000 /* non-prefetchable memory */
|
|
@ -0,0 +1,99 @@
|
||||||
|
From 9398729313b826469fede3acda5fedd1eb21cb3e Mon Sep 17 00:00:00 2001
|
||||||
|
From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||||
|
Date: Wed, 5 Jun 2013 09:04:54 +0200
|
||||||
|
Subject: [PATCH 024/203] arm: mvebu: remove dependency of SMP init on static
|
||||||
|
I/O mapping
|
||||||
|
|
||||||
|
The ->smp_init_cpus() function is called very early during boot, at a
|
||||||
|
point where dynamic I/O mappings are not yet possible. However, in the
|
||||||
|
Armada 370/XP implementation of this function, we have to get the
|
||||||
|
number of CPUs. We used to do that by accessing a hardware register,
|
||||||
|
which requires relying on a static I/O mapping set up by
|
||||||
|
->map_io(). Not only this requires hardcoding a virtual address, but
|
||||||
|
it also prevents us from removing the static I/O mapping.
|
||||||
|
|
||||||
|
So this commit changes the way used to get the number of CPUs: we now
|
||||||
|
use the Device Tree, which is a representation of the hardware, and
|
||||||
|
provides us the number of available CPUs. This is also more accurate,
|
||||||
|
because it potentially allows to boot the Linux kernel on only a
|
||||||
|
number of CPUs given by the Device Tree, instead of unconditionally on
|
||||||
|
all CPUs.
|
||||||
|
|
||||||
|
As a consequence, the coherency_get_cpu_count() function becomes no
|
||||||
|
longer used, so we remove it.
|
||||||
|
|
||||||
|
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||||
|
Acked-by: Arnd Bergmann <arnd@arndb.de>
|
||||||
|
Signed-off-by: Jason Cooper <jason@lakedaemon.net>
|
||||||
|
---
|
||||||
|
arch/arm/mach-mvebu/coherency.c | 12 ------------
|
||||||
|
arch/arm/mach-mvebu/coherency.h | 4 ----
|
||||||
|
arch/arm/mach-mvebu/common.h | 2 ++
|
||||||
|
arch/arm/mach-mvebu/platsmp.c | 10 +++++++++-
|
||||||
|
4 files changed, 11 insertions(+), 17 deletions(-)
|
||||||
|
|
||||||
|
--- a/arch/arm/mach-mvebu/coherency.c
|
||||||
|
+++ b/arch/arm/mach-mvebu/coherency.c
|
||||||
|
@@ -47,18 +47,6 @@ static struct of_device_id of_coherency_
|
||||||
|
{ /* end of list */ },
|
||||||
|
};
|
||||||
|
|
||||||
|
-#ifdef CONFIG_SMP
|
||||||
|
-int coherency_get_cpu_count(void)
|
||||||
|
-{
|
||||||
|
- int reg, cnt;
|
||||||
|
-
|
||||||
|
- reg = readl(coherency_base + COHERENCY_FABRIC_CFG_OFFSET);
|
||||||
|
- cnt = (reg & 0xF) + 1;
|
||||||
|
-
|
||||||
|
- return cnt;
|
||||||
|
-}
|
||||||
|
-#endif
|
||||||
|
-
|
||||||
|
/* Function defined in coherency_ll.S */
|
||||||
|
int ll_set_cpu_coherent(void __iomem *base_addr, unsigned int hw_cpu_id);
|
||||||
|
|
||||||
|
--- a/arch/arm/mach-mvebu/coherency.h
|
||||||
|
+++ b/arch/arm/mach-mvebu/coherency.h
|
||||||
|
@@ -14,10 +14,6 @@
|
||||||
|
#ifndef __MACH_370_XP_COHERENCY_H
|
||||||
|
#define __MACH_370_XP_COHERENCY_H
|
||||||
|
|
||||||
|
-#ifdef CONFIG_SMP
|
||||||
|
-int coherency_get_cpu_count(void);
|
||||||
|
-#endif
|
||||||
|
-
|
||||||
|
int set_cpu_coherent(int cpu_id, int smp_group_id);
|
||||||
|
int coherency_init(void);
|
||||||
|
|
||||||
|
--- a/arch/arm/mach-mvebu/common.h
|
||||||
|
+++ b/arch/arm/mach-mvebu/common.h
|
||||||
|
@@ -15,6 +15,8 @@
|
||||||
|
#ifndef __ARCH_MVEBU_COMMON_H
|
||||||
|
#define __ARCH_MVEBU_COMMON_H
|
||||||
|
|
||||||
|
+#define ARMADA_XP_MAX_CPUS 4
|
||||||
|
+
|
||||||
|
void mvebu_restart(char mode, const char *cmd);
|
||||||
|
|
||||||
|
void armada_370_xp_init_irq(void);
|
||||||
|
--- a/arch/arm/mach-mvebu/platsmp.c
|
||||||
|
+++ b/arch/arm/mach-mvebu/platsmp.c
|
||||||
|
@@ -88,8 +88,16 @@ static int __cpuinit armada_xp_boot_seco
|
||||||
|
|
||||||
|
static void __init armada_xp_smp_init_cpus(void)
|
||||||
|
{
|
||||||
|
+ struct device_node *np;
|
||||||
|
unsigned int i, ncores;
|
||||||
|
- ncores = coherency_get_cpu_count();
|
||||||
|
+
|
||||||
|
+ np = of_find_node_by_name(NULL, "cpus");
|
||||||
|
+ if (!np)
|
||||||
|
+ panic("No 'cpus' node found\n");
|
||||||
|
+
|
||||||
|
+ ncores = of_get_child_count(np);
|
||||||
|
+ if (ncores == 0 || ncores > ARMADA_XP_MAX_CPUS)
|
||||||
|
+ panic("Invalid number of CPUs in DT\n");
|
||||||
|
|
||||||
|
/* Limit possible CPUs to defconfig */
|
||||||
|
if (ncores > nr_cpu_ids) {
|
|
@ -0,0 +1,81 @@
|
||||||
|
From a4dd628f515f361cecfae08e568891442042e4e2 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||||
|
Date: Wed, 5 Jun 2013 09:04:55 +0200
|
||||||
|
Subject: [PATCH 025/203] arm: mvebu: avoid hardcoded virtual address in
|
||||||
|
coherency code
|
||||||
|
|
||||||
|
Now that the coherency_get_cpu_count() function no longer requires a
|
||||||
|
very early mapping of the coherency unit registers, we can avoid the
|
||||||
|
hardcoded virtual address in coherency.c. However, the coherency
|
||||||
|
features are still used quite early, so we need to do the of_iomap()
|
||||||
|
early enough, at the ->init_timer() level, so we have the call of
|
||||||
|
coherency_init() at this point.
|
||||||
|
|
||||||
|
Unfortunately, at ->init_timer() time, it is not possible to register
|
||||||
|
a bus notifier, so we add a separate coherency_late_init() function
|
||||||
|
that gets called as as postcore_initcall(), when bus notifiers are
|
||||||
|
available.
|
||||||
|
|
||||||
|
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||||
|
Acked-by: Arnd Bergmann <arnd@arndb.de>
|
||||||
|
Signed-off-by: Jason Cooper <jason@lakedaemon.net>
|
||||||
|
---
|
||||||
|
arch/arm/mach-mvebu/armada-370-xp.c | 2 +-
|
||||||
|
arch/arm/mach-mvebu/coherency.c | 20 ++++++++++----------
|
||||||
|
2 files changed, 11 insertions(+), 11 deletions(-)
|
||||||
|
|
||||||
|
--- a/arch/arm/mach-mvebu/armada-370-xp.c
|
||||||
|
+++ b/arch/arm/mach-mvebu/armada-370-xp.c
|
||||||
|
@@ -47,6 +47,7 @@ static void __init armada_370_xp_timer_a
|
||||||
|
{
|
||||||
|
mvebu_clocks_init();
|
||||||
|
armada_370_xp_timer_init();
|
||||||
|
+ coherency_init();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __init armada_370_xp_init_early(void)
|
||||||
|
@@ -76,7 +77,6 @@ static void __init armada_370_xp_init_ea
|
||||||
|
static void __init armada_370_xp_dt_init(void)
|
||||||
|
{
|
||||||
|
of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
|
||||||
|
- coherency_init();
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char * const armada_370_xp_dt_compat[] = {
|
||||||
|
--- a/arch/arm/mach-mvebu/coherency.c
|
||||||
|
+++ b/arch/arm/mach-mvebu/coherency.c
|
||||||
|
@@ -27,14 +27,7 @@
|
||||||
|
#include <asm/smp_plat.h>
|
||||||
|
#include "armada-370-xp.h"
|
||||||
|
|
||||||
|
-/*
|
||||||
|
- * Some functions in this file are called very early during SMP
|
||||||
|
- * initialization. At that time the device tree framework is not yet
|
||||||
|
- * ready, and it is not possible to get the register address to
|
||||||
|
- * ioremap it. That's why the pointer below is given with an initial
|
||||||
|
- * value matching its virtual mapping
|
||||||
|
- */
|
||||||
|
-static void __iomem *coherency_base = ARMADA_370_XP_REGS_VIRT_BASE + 0x20200;
|
||||||
|
+static void __iomem *coherency_base;
|
||||||
|
static void __iomem *coherency_cpu_base;
|
||||||
|
|
||||||
|
/* Coherency fabric registers */
|
||||||
|
@@ -135,9 +128,16 @@ int __init coherency_init(void)
|
||||||
|
coherency_base = of_iomap(np, 0);
|
||||||
|
coherency_cpu_base = of_iomap(np, 1);
|
||||||
|
set_cpu_coherent(cpu_logical_map(smp_processor_id()), 0);
|
||||||
|
- bus_register_notifier(&platform_bus_type,
|
||||||
|
- &mvebu_hwcc_platform_nb);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+static int __init coherency_late_init(void)
|
||||||
|
+{
|
||||||
|
+ bus_register_notifier(&platform_bus_type,
|
||||||
|
+ &mvebu_hwcc_platform_nb);
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+postcore_initcall(coherency_late_init);
|
|
@ -0,0 +1,54 @@
|
||||||
|
From c7c7e6309ae12f2cb0d9053875876b57bb7587e4 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||||
|
Date: Wed, 5 Jun 2013 09:04:56 +0200
|
||||||
|
Subject: [PATCH 026/203] arm: mvebu: move cache and mvebu-mbus initialization
|
||||||
|
later
|
||||||
|
|
||||||
|
Current, the L2 cache and the mvebu-mbus drivers are initialized at
|
||||||
|
->init_early() time. However, at ->init_early() time, ioremap() only
|
||||||
|
works if a static I/O mapping has already been put in place. If it's
|
||||||
|
not the case, it tries to do a memory allocation with kmalloc() which
|
||||||
|
is not possible so early at this stage of the initialization.
|
||||||
|
|
||||||
|
Since we want to get rid of the static I/O mapping, we cannot
|
||||||
|
initialize the L2 cache driver and the mvebu-mbus driver so early. So,
|
||||||
|
we move their initialization to the ->init_time() level, which is
|
||||||
|
slightly later (so ioremap() works properly), but sufficiently early
|
||||||
|
to be before the call of the ->smp_prepare_cpus() hook, which creates
|
||||||
|
an address decoding window for the BootROM, which requires the
|
||||||
|
mvebu-mbus driver to be properly initialized.
|
||||||
|
|
||||||
|
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||||
|
Acked-by: Arnd Bergmann <arnd@arndb.de>
|
||||||
|
Signed-off-by: Jason Cooper <jason@lakedaemon.net>
|
||||||
|
---
|
||||||
|
arch/arm/mach-mvebu/armada-370-xp.c | 8 ++------
|
||||||
|
1 file changed, 2 insertions(+), 6 deletions(-)
|
||||||
|
|
||||||
|
--- a/arch/arm/mach-mvebu/armada-370-xp.c
|
||||||
|
+++ b/arch/arm/mach-mvebu/armada-370-xp.c
|
||||||
|
@@ -45,14 +45,11 @@ static void __init armada_370_xp_map_io(
|
||||||
|
|
||||||
|
static void __init armada_370_xp_timer_and_clk_init(void)
|
||||||
|
{
|
||||||
|
+ char *mbus_soc_name;
|
||||||
|
+
|
||||||
|
mvebu_clocks_init();
|
||||||
|
armada_370_xp_timer_init();
|
||||||
|
coherency_init();
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-static void __init armada_370_xp_init_early(void)
|
||||||
|
-{
|
||||||
|
- char *mbus_soc_name;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This initialization will be replaced by a DT-based
|
||||||
|
@@ -88,7 +85,6 @@ DT_MACHINE_START(ARMADA_XP_DT, "Marvell
|
||||||
|
.smp = smp_ops(armada_xp_smp_ops),
|
||||||
|
.init_machine = armada_370_xp_dt_init,
|
||||||
|
.map_io = armada_370_xp_map_io,
|
||||||
|
- .init_early = armada_370_xp_init_early,
|
||||||
|
.init_irq = irqchip_init,
|
||||||
|
.init_time = armada_370_xp_timer_and_clk_init,
|
||||||
|
.restart = mvebu_restart,
|
|
@ -0,0 +1,52 @@
|
||||||
|
From fe4fce3c521f5d9f3a64c4d06a73a5e6b7324116 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||||
|
Date: Wed, 5 Jun 2013 09:04:57 +0200
|
||||||
|
Subject: [PATCH 027/203] arm: mvebu: remove hardcoded static I/O mapping
|
||||||
|
|
||||||
|
Now that we have removed the need of the static I/O mapping for early
|
||||||
|
initialization reasons, and fixed the registers area length that were
|
||||||
|
broken, we can get rid of the static I/O mapping. Only the earlyprintk
|
||||||
|
mapping needs to be set up, using the debug_ll_io_init() helper
|
||||||
|
function.
|
||||||
|
|
||||||
|
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||||
|
Acked-by: Arnd Bergmann <arnd@arndb.de>
|
||||||
|
Signed-off-by: Jason Cooper <jason@lakedaemon.net>
|
||||||
|
---
|
||||||
|
arch/arm/mach-mvebu/armada-370-xp.c | 11 +----------
|
||||||
|
arch/arm/mach-mvebu/armada-370-xp.h | 2 --
|
||||||
|
2 files changed, 1 insertion(+), 12 deletions(-)
|
||||||
|
|
||||||
|
--- a/arch/arm/mach-mvebu/armada-370-xp.c
|
||||||
|
+++ b/arch/arm/mach-mvebu/armada-370-xp.c
|
||||||
|
@@ -29,18 +29,9 @@
|
||||||
|
#include "common.h"
|
||||||
|
#include "coherency.h"
|
||||||
|
|
||||||
|
-static struct map_desc armada_370_xp_io_desc[] __initdata = {
|
||||||
|
- {
|
||||||
|
- .virtual = (unsigned long) ARMADA_370_XP_REGS_VIRT_BASE,
|
||||||
|
- .pfn = __phys_to_pfn(ARMADA_370_XP_REGS_PHYS_BASE),
|
||||||
|
- .length = ARMADA_370_XP_REGS_SIZE,
|
||||||
|
- .type = MT_DEVICE,
|
||||||
|
- },
|
||||||
|
-};
|
||||||
|
-
|
||||||
|
static void __init armada_370_xp_map_io(void)
|
||||||
|
{
|
||||||
|
- iotable_init(armada_370_xp_io_desc, ARRAY_SIZE(armada_370_xp_io_desc));
|
||||||
|
+ debug_ll_io_init();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __init armada_370_xp_timer_and_clk_init(void)
|
||||||
|
--- a/arch/arm/mach-mvebu/armada-370-xp.h
|
||||||
|
+++ b/arch/arm/mach-mvebu/armada-370-xp.h
|
||||||
|
@@ -16,8 +16,6 @@
|
||||||
|
#define __MACH_ARMADA_370_XP_H
|
||||||
|
|
||||||
|
#define ARMADA_370_XP_REGS_PHYS_BASE 0xd0000000
|
||||||
|
-#define ARMADA_370_XP_REGS_VIRT_BASE IOMEM(0xfec00000)
|
||||||
|
-#define ARMADA_370_XP_REGS_SIZE SZ_1M
|
||||||
|
|
||||||
|
/* These defines can go away once mvebu-mbus has a DT binding */
|
||||||
|
#define ARMADA_370_XP_MBUS_WINS_BASE (ARMADA_370_XP_REGS_PHYS_BASE + 0x20000)
|
|
@ -0,0 +1,91 @@
|
||||||
|
From 88260610ea7a2c5a164721af28f59856880221b4 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||||
|
Date: Thu, 6 Jun 2013 12:24:28 +0200
|
||||||
|
Subject: [PATCH 028/203] arm: mvebu: don't hardcode a physical address in
|
||||||
|
headsmp.S
|
||||||
|
|
||||||
|
Now that the coherency_init() function is called a bit earlier, we can
|
||||||
|
actually read the physical address of the coherency unit registers
|
||||||
|
from the Device Tree, and communicate that to the headsmp.S code,
|
||||||
|
which avoids hardcoding a physical address.
|
||||||
|
|
||||||
|
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||||
|
Acked-by: Arnd Bergmann <arnd@arndb.de>
|
||||||
|
Reviewed-by: Will Deacon <will.deacon@arm.com>
|
||||||
|
Acked-by: Nicolas Pitre <nico@linaro.org>
|
||||||
|
Signed-off-by: Jason Cooper <jason@lakedaemon.net>
|
||||||
|
---
|
||||||
|
arch/arm/mach-mvebu/coherency.c | 12 ++++++++++++
|
||||||
|
arch/arm/mach-mvebu/headsmp.S | 16 ++++++++--------
|
||||||
|
2 files changed, 20 insertions(+), 8 deletions(-)
|
||||||
|
|
||||||
|
--- a/arch/arm/mach-mvebu/coherency.c
|
||||||
|
+++ b/arch/arm/mach-mvebu/coherency.c
|
||||||
|
@@ -25,8 +25,10 @@
|
||||||
|
#include <linux/dma-mapping.h>
|
||||||
|
#include <linux/platform_device.h>
|
||||||
|
#include <asm/smp_plat.h>
|
||||||
|
+#include <asm/cacheflush.h>
|
||||||
|
#include "armada-370-xp.h"
|
||||||
|
|
||||||
|
+unsigned long __cpuinitdata coherency_phys_base;
|
||||||
|
static void __iomem *coherency_base;
|
||||||
|
static void __iomem *coherency_cpu_base;
|
||||||
|
|
||||||
|
@@ -124,7 +126,17 @@ int __init coherency_init(void)
|
||||||
|
|
||||||
|
np = of_find_matching_node(NULL, of_coherency_table);
|
||||||
|
if (np) {
|
||||||
|
+ struct resource res;
|
||||||
|
pr_info("Initializing Coherency fabric\n");
|
||||||
|
+ of_address_to_resource(np, 0, &res);
|
||||||
|
+ coherency_phys_base = res.start;
|
||||||
|
+ /*
|
||||||
|
+ * Ensure secondary CPUs will see the updated value,
|
||||||
|
+ * which they read before they join the coherency
|
||||||
|
+ * fabric, and therefore before they are coherent with
|
||||||
|
+ * the boot CPU cache.
|
||||||
|
+ */
|
||||||
|
+ sync_cache_w(&coherency_phys_base);
|
||||||
|
coherency_base = of_iomap(np, 0);
|
||||||
|
coherency_cpu_base = of_iomap(np, 1);
|
||||||
|
set_cpu_coherent(cpu_logical_map(smp_processor_id()), 0);
|
||||||
|
--- a/arch/arm/mach-mvebu/headsmp.S
|
||||||
|
+++ b/arch/arm/mach-mvebu/headsmp.S
|
||||||
|
@@ -21,12 +21,6 @@
|
||||||
|
#include <linux/linkage.h>
|
||||||
|
#include <linux/init.h>
|
||||||
|
|
||||||
|
-/*
|
||||||
|
- * At this stage the secondary CPUs don't have acces yet to the MMU, so
|
||||||
|
- * we have to provide physical addresses
|
||||||
|
- */
|
||||||
|
-#define ARMADA_XP_CFB_BASE 0xD0020200
|
||||||
|
-
|
||||||
|
__CPUINIT
|
||||||
|
|
||||||
|
/*
|
||||||
|
@@ -35,15 +29,21 @@
|
||||||
|
* startup
|
||||||
|
*/
|
||||||
|
ENTRY(armada_xp_secondary_startup)
|
||||||
|
+ /* Get coherency fabric base physical address */
|
||||||
|
+ adr r0, 1f
|
||||||
|
+ ldr r1, [r0]
|
||||||
|
+ ldr r0, [r0, r1]
|
||||||
|
|
||||||
|
/* Read CPU id */
|
||||||
|
mrc p15, 0, r1, c0, c0, 5
|
||||||
|
and r1, r1, #0xF
|
||||||
|
|
||||||
|
/* Add CPU to coherency fabric */
|
||||||
|
- ldr r0, =ARMADA_XP_CFB_BASE
|
||||||
|
-
|
||||||
|
bl ll_set_cpu_coherent
|
||||||
|
b secondary_startup
|
||||||
|
|
||||||
|
ENDPROC(armada_xp_secondary_startup)
|
||||||
|
+
|
||||||
|
+ .align 2
|
||||||
|
+1:
|
||||||
|
+ .long coherency_phys_base - .
|
|
@ -0,0 +1,109 @@
|
||||||
|
From 070469397154c87b14fab48d2fc231ba83007c1b Mon Sep 17 00:00:00 2001
|
||||||
|
From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||||
|
Date: Wed, 5 Jun 2013 09:04:59 +0200
|
||||||
|
Subject: [PATCH 029/203] arm: mvebu: don't hardcode the physical address for
|
||||||
|
mvebu-mbus
|
||||||
|
|
||||||
|
Since the mvebu-mbus driver doesn't yet have a DT binding (and this DT
|
||||||
|
binding may not necessarily be ready for 3.11), the physical address
|
||||||
|
of the mvebu-mbus registers are currently hardcoded. This doesn't play
|
||||||
|
well with the fact that the internal registers base address may be
|
||||||
|
different depending on the bootloader.
|
||||||
|
|
||||||
|
In order to have only one central place for the physical address of
|
||||||
|
the internal registers, we now use of_translate_address() to translate
|
||||||
|
the mvebu-mbus register offsets into the real physical address, by
|
||||||
|
using DT-based address translation. This will go away once the
|
||||||
|
mvebu-mbus driver gains a proper DT binding.
|
||||||
|
|
||||||
|
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||||
|
Acked-by: Arnd Bergmann <arnd@arndb.de>
|
||||||
|
Signed-off-by: Jason Cooper <jason@lakedaemon.net>
|
||||||
|
---
|
||||||
|
arch/arm/mach-mvebu/armada-370-xp.c | 38 ++++++++++++++++++++++++++-----------
|
||||||
|
arch/arm/mach-mvebu/armada-370-xp.h | 8 --------
|
||||||
|
2 files changed, 27 insertions(+), 19 deletions(-)
|
||||||
|
|
||||||
|
--- a/arch/arm/mach-mvebu/armada-370-xp.c
|
||||||
|
+++ b/arch/arm/mach-mvebu/armada-370-xp.c
|
||||||
|
@@ -14,6 +14,7 @@
|
||||||
|
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/init.h>
|
||||||
|
+#include <linux/of_address.h>
|
||||||
|
#include <linux/of_platform.h>
|
||||||
|
#include <linux/io.h>
|
||||||
|
#include <linux/time-armada-370-xp.h>
|
||||||
|
@@ -34,29 +35,44 @@ static void __init armada_370_xp_map_io(
|
||||||
|
debug_ll_io_init();
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void __init armada_370_xp_timer_and_clk_init(void)
|
||||||
|
+/*
|
||||||
|
+ * This initialization will be replaced by a DT-based
|
||||||
|
+ * initialization once the mvebu-mbus driver gains DT support.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#define ARMADA_370_XP_MBUS_WINS_OFFS 0x20000
|
||||||
|
+#define ARMADA_370_XP_MBUS_WINS_SIZE 0x100
|
||||||
|
+#define ARMADA_370_XP_SDRAM_WINS_OFFS 0x20180
|
||||||
|
+#define ARMADA_370_XP_SDRAM_WINS_SIZE 0x20
|
||||||
|
+
|
||||||
|
+static void __init armada_370_xp_mbus_init(void)
|
||||||
|
{
|
||||||
|
char *mbus_soc_name;
|
||||||
|
+ struct device_node *dn;
|
||||||
|
+ const __be32 mbus_wins_offs = cpu_to_be32(ARMADA_370_XP_MBUS_WINS_OFFS);
|
||||||
|
+ const __be32 sdram_wins_offs = cpu_to_be32(ARMADA_370_XP_SDRAM_WINS_OFFS);
|
||||||
|
|
||||||
|
- mvebu_clocks_init();
|
||||||
|
- armada_370_xp_timer_init();
|
||||||
|
- coherency_init();
|
||||||
|
-
|
||||||
|
- /*
|
||||||
|
- * This initialization will be replaced by a DT-based
|
||||||
|
- * initialization once the mvebu-mbus driver gains DT support.
|
||||||
|
- */
|
||||||
|
if (of_machine_is_compatible("marvell,armada370"))
|
||||||
|
mbus_soc_name = "marvell,armada370-mbus";
|
||||||
|
else
|
||||||
|
mbus_soc_name = "marvell,armadaxp-mbus";
|
||||||
|
|
||||||
|
+ dn = of_find_node_by_name(NULL, "internal-regs");
|
||||||
|
+ BUG_ON(!dn);
|
||||||
|
+
|
||||||
|
mvebu_mbus_init(mbus_soc_name,
|
||||||
|
- ARMADA_370_XP_MBUS_WINS_BASE,
|
||||||
|
+ of_translate_address(dn, &mbus_wins_offs),
|
||||||
|
ARMADA_370_XP_MBUS_WINS_SIZE,
|
||||||
|
- ARMADA_370_XP_SDRAM_WINS_BASE,
|
||||||
|
+ of_translate_address(dn, &sdram_wins_offs),
|
||||||
|
ARMADA_370_XP_SDRAM_WINS_SIZE);
|
||||||
|
+}
|
||||||
|
|
||||||
|
+static void __init armada_370_xp_timer_and_clk_init(void)
|
||||||
|
+{
|
||||||
|
+ mvebu_clocks_init();
|
||||||
|
+ armada_370_xp_timer_init();
|
||||||
|
+ coherency_init();
|
||||||
|
+ armada_370_xp_mbus_init();
|
||||||
|
#ifdef CONFIG_CACHE_L2X0
|
||||||
|
l2x0_of_init(0, ~0UL);
|
||||||
|
#endif
|
||||||
|
--- a/arch/arm/mach-mvebu/armada-370-xp.h
|
||||||
|
+++ b/arch/arm/mach-mvebu/armada-370-xp.h
|
||||||
|
@@ -15,14 +15,6 @@
|
||||||
|
#ifndef __MACH_ARMADA_370_XP_H
|
||||||
|
#define __MACH_ARMADA_370_XP_H
|
||||||
|
|
||||||
|
-#define ARMADA_370_XP_REGS_PHYS_BASE 0xd0000000
|
||||||
|
-
|
||||||
|
-/* These defines can go away once mvebu-mbus has a DT binding */
|
||||||
|
-#define ARMADA_370_XP_MBUS_WINS_BASE (ARMADA_370_XP_REGS_PHYS_BASE + 0x20000)
|
||||||
|
-#define ARMADA_370_XP_MBUS_WINS_SIZE 0x100
|
||||||
|
-#define ARMADA_370_XP_SDRAM_WINS_BASE (ARMADA_370_XP_REGS_PHYS_BASE + 0x20180)
|
||||||
|
-#define ARMADA_370_XP_SDRAM_WINS_SIZE 0x20
|
||||||
|
-
|
||||||
|
#ifdef CONFIG_SMP
|
||||||
|
#include <linux/cpumask.h>
|
||||||
|
|
|
@ -0,0 +1,85 @@
|
||||||
|
From 70c30ca997919a4b8c9051a3903f30c79c735f12 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||||
|
Date: Wed, 5 Jun 2013 09:05:00 +0200
|
||||||
|
Subject: [PATCH 030/203] arm: mvebu: add another earlyprintk Kconfig option
|
||||||
|
|
||||||
|
In order to support both old and new bootloaders, we add a new Kconfig
|
||||||
|
option for the earlyprintk UART selection. The existing option allows
|
||||||
|
to work with old bootloaders (that keep the internal registers mapped
|
||||||
|
at 0xd0000000), while the newly introduced option allows to work with
|
||||||
|
new bootloaders (that remap the internal registers at 0xf1000000).
|
||||||
|
|
||||||
|
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||||
|
Acked-by: Arnd Bergmann <arnd@arndb.de>
|
||||||
|
Signed-off-by: Jason Cooper <jason@lakedaemon.net>
|
||||||
|
---
|
||||||
|
arch/arm/Kconfig.debug | 30 ++++++++++++++++++++++++++++--
|
||||||
|
arch/arm/include/debug/mvebu.S | 5 +++++
|
||||||
|
2 files changed, 33 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
--- a/arch/arm/Kconfig.debug
|
||||||
|
+++ b/arch/arm/Kconfig.debug
|
||||||
|
@@ -303,12 +303,37 @@ choice
|
||||||
|
their output to the serial port on MSM 8960 devices.
|
||||||
|
|
||||||
|
config DEBUG_MVEBU_UART
|
||||||
|
- bool "Kernel low-level debugging messages via MVEBU UART"
|
||||||
|
+ bool "Kernel low-level debugging messages via MVEBU UART (old bootloaders)"
|
||||||
|
depends on ARCH_MVEBU
|
||||||
|
help
|
||||||
|
Say Y here if you want kernel low-level debugging support
|
||||||
|
on MVEBU based platforms.
|
||||||
|
|
||||||
|
+ This option should be used with the old bootloaders
|
||||||
|
+ that left the internal registers mapped at
|
||||||
|
+ 0xd0000000. As of today, this is the case on
|
||||||
|
+ platforms such as the Globalscale Mirabox or the
|
||||||
|
+ Plathome OpenBlocks AX3, when using the original
|
||||||
|
+ bootloader.
|
||||||
|
+
|
||||||
|
+ If the wrong DEBUG_MVEBU_UART* option is selected,
|
||||||
|
+ when u-boot hands over to the kernel, the system
|
||||||
|
+ silently crashes, with no serial output at all.
|
||||||
|
+
|
||||||
|
+ config DEBUG_MVEBU_UART_ALTERNATE
|
||||||
|
+ bool "Kernel low-level debugging messages via MVEBU UART (new bootloaders)"
|
||||||
|
+ depends on ARCH_MVEBU
|
||||||
|
+ help
|
||||||
|
+ Say Y here if you want kernel low-level debugging support
|
||||||
|
+ on MVEBU based platforms.
|
||||||
|
+
|
||||||
|
+ This option should be used with the new bootloaders
|
||||||
|
+ that remap the internal registers at 0xf1000000.
|
||||||
|
+
|
||||||
|
+ If the wrong DEBUG_MVEBU_UART* option is selected,
|
||||||
|
+ when u-boot hands over to the kernel, the system
|
||||||
|
+ silently crashes, with no serial output at all.
|
||||||
|
+
|
||||||
|
config DEBUG_NOMADIK_UART
|
||||||
|
bool "Kernel low-level debugging messages via NOMADIK UART"
|
||||||
|
depends on ARCH_NOMADIK
|
||||||
|
@@ -632,7 +657,8 @@ config DEBUG_LL_INCLUDE
|
||||||
|
DEBUG_IMX51_UART || \
|
||||||
|
DEBUG_IMX53_UART ||\
|
||||||
|
DEBUG_IMX6Q_UART
|
||||||
|
- default "debug/mvebu.S" if DEBUG_MVEBU_UART
|
||||||
|
+ default "debug/mvebu.S" if DEBUG_MVEBU_UART || \
|
||||||
|
+ DEBUG_MVEBU_UART_ALTERNATE
|
||||||
|
default "debug/mxs.S" if DEBUG_IMX23_UART || DEBUG_IMX28_UART
|
||||||
|
default "debug/nomadik.S" if DEBUG_NOMADIK_UART
|
||||||
|
default "debug/omap2plus.S" if DEBUG_OMAP2PLUS_UART
|
||||||
|
--- a/arch/arm/include/debug/mvebu.S
|
||||||
|
+++ b/arch/arm/include/debug/mvebu.S
|
||||||
|
@@ -11,7 +11,12 @@
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
+#ifdef CONFIG_DEBUG_MVEBU_UART_ALTERNATE
|
||||||
|
+#define ARMADA_370_XP_REGS_PHYS_BASE 0xf1000000
|
||||||
|
+#else
|
||||||
|
#define ARMADA_370_XP_REGS_PHYS_BASE 0xd0000000
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
#define ARMADA_370_XP_REGS_VIRT_BASE 0xfec00000
|
||||||
|
|
||||||
|
.macro addruart, rp, rv, tmp
|
|
@ -0,0 +1,27 @@
|
||||||
|
From 7a3b99b8d16f2eb9ae5ac4ddf5e201eacdfacbf4 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||||
|
Date: Wed, 5 Jun 2013 09:05:01 +0200
|
||||||
|
Subject: [PATCH 031/203] arm: mvebu: disable DEBUG_LL/EARLY_PRINTK in
|
||||||
|
defconfig
|
||||||
|
|
||||||
|
Now that we have two different addresses for the UART, depending on
|
||||||
|
which bootloader is used, it is no longer desirable to enable
|
||||||
|
earlyprintk by default in the defconfig. Users who need earlyprintk
|
||||||
|
support will have to enable it explicitly, and select the right UART
|
||||||
|
configuration depending on their platform.
|
||||||
|
|
||||||
|
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||||
|
Acked-by: Arnd Bergmann <arnd@arndb.de>
|
||||||
|
Signed-off-by: Jason Cooper <jason@lakedaemon.net>
|
||||||
|
---
|
||||||
|
arch/arm/configs/mvebu_defconfig | 2 --
|
||||||
|
1 file changed, 2 deletions(-)
|
||||||
|
|
||||||
|
--- a/arch/arm/configs/mvebu_defconfig
|
||||||
|
+++ b/arch/arm/configs/mvebu_defconfig
|
||||||
|
@@ -100,5 +100,3 @@ CONFIG_TIMER_STATS=y
|
||||||
|
# CONFIG_DEBUG_BUGVERBOSE is not set
|
||||||
|
CONFIG_DEBUG_INFO=y
|
||||||
|
CONFIG_DEBUG_USER=y
|
||||||
|
-CONFIG_DEBUG_LL=y
|
||||||
|
-CONFIG_EARLY_PRINTK=y
|
|
@ -0,0 +1,42 @@
|
||||||
|
From e552d168344e941a1781682207269dbfd27850b1 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||||
|
Date: Tue, 18 Jun 2013 15:37:41 +0200
|
||||||
|
Subject: [PATCH 032/203] arm: mvebu: enable mini-PCIe connectors on Armada 370
|
||||||
|
RD
|
||||||
|
|
||||||
|
The Armada 370 RD board has two internal mini-PCIe connectors. This
|
||||||
|
commit adds the necessary Device Tree informations to enable the usage
|
||||||
|
of those mini-PCIe connectors.
|
||||||
|
|
||||||
|
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||||
|
Cc: Florian Fainelli <florian@openwrt.org>
|
||||||
|
Signed-off-by: Jason Cooper <jason@lakedaemon.net>
|
||||||
|
---
|
||||||
|
arch/arm/boot/dts/armada-370-rd.dts | 16 ++++++++++++++++
|
||||||
|
1 file changed, 16 insertions(+)
|
||||||
|
|
||||||
|
--- a/arch/arm/boot/dts/armada-370-rd.dts
|
||||||
|
+++ b/arch/arm/boot/dts/armada-370-rd.dts
|
||||||
|
@@ -85,6 +85,22 @@
|
||||||
|
gpios = <&gpio0 6 1>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
+
|
||||||
|
+ pcie-controller {
|
||||||
|
+ status = "okay";
|
||||||
|
+
|
||||||
|
+ /* Internal mini-PCIe connector */
|
||||||
|
+ pcie@1,0 {
|
||||||
|
+ /* Port 0, Lane 0 */
|
||||||
|
+ status = "okay";
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ /* Internal mini-PCIe connector */
|
||||||
|
+ pcie@2,0 {
|
||||||
|
+ /* Port 1, Lane 0 */
|
||||||
|
+ status = "okay";
|
||||||
|
+ };
|
||||||
|
+ };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
|
@ -0,0 +1,41 @@
|
||||||
|
From 3891658a01af7e875d4c176ebb5d713d74a6e998 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||||
|
Date: Thu, 20 Jun 2013 09:45:26 +0200
|
||||||
|
Subject: [PATCH 033/203] arm: mvebu: fix coherency_late_init() for
|
||||||
|
multiplatform
|
||||||
|
|
||||||
|
As noticed by Arnaud Patard (Rtp) <arnaud.patard@rtp-net.org>, commit
|
||||||
|
865e0527d2d7 ('arm: mvebu: avoid hardcoded virtual address in
|
||||||
|
coherency code') added a postcore_initcall() to register the bus
|
||||||
|
notifier that the mvebu code needs to apply correct DMA operations on
|
||||||
|
its platform devices breaks the multiplatform boot on other platforms,
|
||||||
|
because the bus notifier registration is unconditional.
|
||||||
|
|
||||||
|
This commit fixes that by registering the bus notifier only if we have
|
||||||
|
the mvebu coherency unit described in the Device Tree. The conditional
|
||||||
|
used is exactly the same in which the bus_register_notifier() call was
|
||||||
|
originally enclosed before 865e0527d2d7 ('arm: mvebu: avoid hardcoded
|
||||||
|
virtual address in coherency code').
|
||||||
|
|
||||||
|
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||||
|
Reported-by: Arnaud Patard (Rtp) <arnaud.patard@rtp-net.org>
|
||||||
|
Acked-by: Andrew Lunn <andrew@lunn.ch>
|
||||||
|
Signed-off-by: Jason Cooper <jason@lakedaemon.net>
|
||||||
|
---
|
||||||
|
arch/arm/mach-mvebu/coherency.c | 5 +++--
|
||||||
|
1 file changed, 3 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
--- a/arch/arm/mach-mvebu/coherency.c
|
||||||
|
+++ b/arch/arm/mach-mvebu/coherency.c
|
||||||
|
@@ -147,8 +147,9 @@ int __init coherency_init(void)
|
||||||
|
|
||||||
|
static int __init coherency_late_init(void)
|
||||||
|
{
|
||||||
|
- bus_register_notifier(&platform_bus_type,
|
||||||
|
- &mvebu_hwcc_platform_nb);
|
||||||
|
+ if (of_find_matching_node(NULL, of_coherency_table))
|
||||||
|
+ bus_register_notifier(&platform_bus_type,
|
||||||
|
+ &mvebu_hwcc_platform_nb);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
From 4f6da1286d2602e00c049c29eb9e816587c752a5 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
|
||||||
|
Date: Sat, 22 Jun 2013 13:52:27 -0300
|
||||||
|
Subject: [PATCH 034/203] ARM: mvebu: fix length of ethernet registers in
|
||||||
|
mv78260 dtsi
|
||||||
|
|
||||||
|
The length of the registers area for the Marvell 370/XP Ethernet controller
|
||||||
|
was incorrect in the .dtsi: 0x2500, while it should have been 0x4000.
|
||||||
|
This problem wasn't noticed because there used to be a static mapping for
|
||||||
|
all the MMIO register region set up by ->map_io().
|
||||||
|
|
||||||
|
The register length was fixed in all the other device tree files,
|
||||||
|
except from the armada-xp-mv78260.dtsi, in the following commit:
|
||||||
|
|
||||||
|
commit cf8088c5cac6ce20d914b9131533844b9291a054
|
||||||
|
Author: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||||
|
Date: Tue May 21 12:33:27 2013 +0200
|
||||||
|
|
||||||
|
arm: mvebu: fix length of Ethernet registers area in .dtsi
|
||||||
|
|
||||||
|
This commit fixes a kernel panic in mvneta_probe(), when the kernel
|
||||||
|
tries to access the unmapped registers:
|
||||||
|
|
||||||
|
[ 163.639092] mvneta d0070000.ethernet eth0: mac: 6e:3c:4f:87:17:2e
|
||||||
|
[ 163.646962] mvneta d0074000.ethernet eth1: mac: 6a:04:4e:6f:f5:ef
|
||||||
|
[ 163.654853] mvneta d0030000.ethernet eth2: mac: 2a:99:19:19:fc:4c
|
||||||
|
[ 163.661258] Unable to handle kernel paging request at virtual address f011bcf0
|
||||||
|
[ 163.668523] pgd = c0004000
|
||||||
|
[ 163.671237] [f011bcf0] *pgd=2f006811, *pte=00000000, *ppte=00000000
|
||||||
|
[ 163.677565] Internal error: Oops: 807 [#1] SMP ARM
|
||||||
|
[ 163.682370] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 3.10.0-rc6-01850-gba0682e #11
|
||||||
|
[ 163.690046] task: ef04c000 ti: ef03e000 task.ti: ef03e000
|
||||||
|
[ 163.695467] PC is at mvneta_probe+0x34c/0xabc
|
||||||
|
[...]
|
||||||
|
|
||||||
|
Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
|
||||||
|
Acked-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||||
|
Signed-off-by: Jason Cooper <jason@lakedaemon.net>
|
||||||
|
---
|
||||||
|
arch/arm/boot/dts/armada-xp-mv78260.dtsi | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
--- a/arch/arm/boot/dts/armada-xp-mv78260.dtsi
|
||||||
|
+++ b/arch/arm/boot/dts/armada-xp-mv78260.dtsi
|
||||||
|
@@ -92,7 +92,7 @@
|
||||||
|
|
||||||
|
ethernet@34000 {
|
||||||
|
compatible = "marvell,armada-370-neta";
|
||||||
|
- reg = <0x34000 0x2500>;
|
||||||
|
+ reg = <0x34000 0x4000>;
|
||||||
|
interrupts = <14>;
|
||||||
|
clocks = <&gateclk 1>;
|
||||||
|
status = "disabled";
|
|
@ -0,0 +1,51 @@
|
||||||
|
From 76de914223ec09274a7857e0d8cd7b739205dc3c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Gregory CLEMENT <gregory.clement@free-electrons.com>
|
||||||
|
Date: Fri, 21 Jun 2013 15:32:06 +0200
|
||||||
|
Subject: [PATCH 035/203] i2c: mv64xxx: Set bus frequency to 100kHz if
|
||||||
|
clock-frequency is not provided
|
||||||
|
|
||||||
|
This commit adds checking whether clock-frequency property acquisition
|
||||||
|
has succeeded. If not, the frequency is set to 100kHz by default.
|
||||||
|
|
||||||
|
The Device Tree binding documentation is updated accordingly.
|
||||||
|
|
||||||
|
Based on the intials patches from Zbigniew Bodek
|
||||||
|
|
||||||
|
Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
|
||||||
|
Signed-off-by: Zbigniew Bodek <zbb@semihalf.com>
|
||||||
|
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
|
||||||
|
---
|
||||||
|
Documentation/devicetree/bindings/i2c/i2c-mv64xxx.txt | 6 +++++-
|
||||||
|
drivers/i2c/busses/i2c-mv64xxx.c | 6 +++++-
|
||||||
|
2 files changed, 10 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
--- a/Documentation/devicetree/bindings/i2c/i2c-mv64xxx.txt
|
||||||
|
+++ b/Documentation/devicetree/bindings/i2c/i2c-mv64xxx.txt
|
||||||
|
@@ -6,7 +6,11 @@ Required properties :
|
||||||
|
- reg : Offset and length of the register set for the device
|
||||||
|
- compatible : Should be "marvell,mv64xxx-i2c"
|
||||||
|
- interrupts : The interrupt number
|
||||||
|
- - clock-frequency : Desired I2C bus clock frequency in Hz.
|
||||||
|
+
|
||||||
|
+Optional properties :
|
||||||
|
+
|
||||||
|
+ - clock-frequency : Desired I2C bus clock frequency in Hz. If not set the
|
||||||
|
+default frequency is 100kHz
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
--- a/drivers/i2c/busses/i2c-mv64xxx.c
|
||||||
|
+++ b/drivers/i2c/busses/i2c-mv64xxx.c
|
||||||
|
@@ -580,7 +580,11 @@ mv64xxx_of_config(struct mv64xxx_i2c_dat
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
tclk = clk_get_rate(drv_data->clk);
|
||||||
|
- of_property_read_u32(np, "clock-frequency", &bus_freq);
|
||||||
|
+
|
||||||
|
+ rc = of_property_read_u32(np, "clock-frequency", &bus_freq);
|
||||||
|
+ if (rc)
|
||||||
|
+ bus_freq = 100000; /* 100kHz by default */
|
||||||
|
+
|
||||||
|
if (!mv64xxx_find_baud_factors(bus_freq, tclk,
|
||||||
|
&drv_data->freq_n, &drv_data->freq_m)) {
|
||||||
|
rc = -EINVAL;
|
|
@ -0,0 +1,91 @@
|
||||||
|
From 71a32c9519ba223d1dafcbe58d1699710720c5a8 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||||
|
Date: Thu, 1 Aug 2013 15:44:19 +0200
|
||||||
|
Subject: [PATCH 036/203] PCI: mvebu: Disable prefetchable memory support in
|
||||||
|
PCI-to-PCI bridge
|
||||||
|
|
||||||
|
The Marvell PCIe driver uses an emulated PCI-to-PCI bridge to be able
|
||||||
|
to dynamically set up MBus address decoding windows for PCI I/O and
|
||||||
|
memory regions depending on the PCI devices enumerated by Linux.
|
||||||
|
|
||||||
|
However, this emulated PCI-to-PCI bridge logic makes the Linux PCI
|
||||||
|
core believe that prefetchable memory regions are supported (because
|
||||||
|
the registers are read/write), while in fact no adress decoding window
|
||||||
|
is ever created for such regions. Since the Marvell MBus address
|
||||||
|
decoding windows do not distinguish memory regions and prefetchable
|
||||||
|
memory regions, this patch takes a simple approach: change the
|
||||||
|
PCI-to-PCI bridge emulation to let the Linux PCI core know that we
|
||||||
|
don't support prefetchable memory regions.
|
||||||
|
|
||||||
|
To achieve this, we simply make the prefetchable memory base a
|
||||||
|
read-only register that always returns 0. Reading/writing all the
|
||||||
|
other prefetchable memory related registers has no effect.
|
||||||
|
|
||||||
|
This problem was originally reported by Finn Hoffmann
|
||||||
|
<finn@uni-bremen.de>, who couldn't get a RTL8111/8168B PCI NIC working
|
||||||
|
on the NSA310 Kirkwood platform after updating to 3.11-rc. The problem
|
||||||
|
was that the PCI-to-PCI bridge emulation was making the Linux PCI core
|
||||||
|
believe that we support prefetchable memory, so the Linux PCI core was
|
||||||
|
only filling the prefetchable memory base and limit registers, which
|
||||||
|
does not lead to a MBus window being created. The below patch has been
|
||||||
|
confirmed by Finn Hoffmann to fix his problem on Kirkwood, and has
|
||||||
|
otherwise been successfully tested on the Armada XP GP platform with a
|
||||||
|
e1000e PCIe NIC and a Marvell SATA PCIe card.
|
||||||
|
|
||||||
|
Reported-by: Finn Hoffmann <finn@uni-bremen.de>
|
||||||
|
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||||
|
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
|
||||||
|
---
|
||||||
|
drivers/pci/host/pci-mvebu.c | 27 +--------------------------
|
||||||
|
1 file changed, 1 insertion(+), 26 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/pci/host/pci-mvebu.c
|
||||||
|
+++ b/drivers/pci/host/pci-mvebu.c
|
||||||
|
@@ -86,10 +86,6 @@ struct mvebu_sw_pci_bridge {
|
||||||
|
u16 secondary_status;
|
||||||
|
u16 membase;
|
||||||
|
u16 memlimit;
|
||||||
|
- u16 prefmembase;
|
||||||
|
- u16 prefmemlimit;
|
||||||
|
- u32 prefbaseupper;
|
||||||
|
- u32 preflimitupper;
|
||||||
|
u16 iobaseupper;
|
||||||
|
u16 iolimitupper;
|
||||||
|
u8 cappointer;
|
||||||
|
@@ -419,15 +415,7 @@ static int mvebu_sw_pci_bridge_read(stru
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PCI_PREF_MEMORY_BASE:
|
||||||
|
- *value = (bridge->prefmemlimit << 16 | bridge->prefmembase);
|
||||||
|
- break;
|
||||||
|
-
|
||||||
|
- case PCI_PREF_BASE_UPPER32:
|
||||||
|
- *value = bridge->prefbaseupper;
|
||||||
|
- break;
|
||||||
|
-
|
||||||
|
- case PCI_PREF_LIMIT_UPPER32:
|
||||||
|
- *value = bridge->preflimitupper;
|
||||||
|
+ *value = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PCI_IO_BASE_UPPER16:
|
||||||
|
@@ -501,19 +489,6 @@ static int mvebu_sw_pci_bridge_write(str
|
||||||
|
mvebu_pcie_handle_membase_change(port);
|
||||||
|
break;
|
||||||
|
|
||||||
|
- case PCI_PREF_MEMORY_BASE:
|
||||||
|
- bridge->prefmembase = value & 0xffff;
|
||||||
|
- bridge->prefmemlimit = value >> 16;
|
||||||
|
- break;
|
||||||
|
-
|
||||||
|
- case PCI_PREF_BASE_UPPER32:
|
||||||
|
- bridge->prefbaseupper = value;
|
||||||
|
- break;
|
||||||
|
-
|
||||||
|
- case PCI_PREF_LIMIT_UPPER32:
|
||||||
|
- bridge->preflimitupper = value;
|
||||||
|
- break;
|
||||||
|
-
|
||||||
|
case PCI_IO_BASE_UPPER16:
|
||||||
|
bridge->iobaseupper = value & 0xffff;
|
||||||
|
bridge->iolimitupper = value >> 16;
|
|
@ -0,0 +1,109 @@
|
||||||
|
From 9760aafa716292050a96d71a4bd7bd4e66053975 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
|
||||||
|
Date: Tue, 21 May 2013 10:24:48 -0300
|
||||||
|
Subject: [PATCH 037/203] memory: mvebu-devbus: Remove address decoding window
|
||||||
|
workaround
|
||||||
|
|
||||||
|
Now that mbus device tree binding has been introduced, remove the address
|
||||||
|
decoding window management from this driver.
|
||||||
|
A suitable 'ranges' entry should be added to the devbus-compatible node in
|
||||||
|
the device tree, as described by the mbus binding documentation.
|
||||||
|
|
||||||
|
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||||
|
Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
|
||||||
|
Tested-by: Andrew Lunn <andrew@lunn.ch>
|
||||||
|
Tested-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
|
||||||
|
---
|
||||||
|
drivers/memory/mvebu-devbus.c | 64 ++-----------------------------------------
|
||||||
|
1 file changed, 2 insertions(+), 62 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/memory/mvebu-devbus.c
|
||||||
|
+++ b/drivers/memory/mvebu-devbus.c
|
||||||
|
@@ -208,16 +208,11 @@ static int mvebu_devbus_probe(struct pla
|
||||||
|
{
|
||||||
|
struct device *dev = &pdev->dev;
|
||||||
|
struct device_node *node = pdev->dev.of_node;
|
||||||
|
- struct device_node *parent;
|
||||||
|
struct devbus *devbus;
|
||||||
|
struct resource *res;
|
||||||
|
struct clk *clk;
|
||||||
|
unsigned long rate;
|
||||||
|
- const __be32 *ranges;
|
||||||
|
- int err, cs;
|
||||||
|
- int addr_cells, p_addr_cells, size_cells;
|
||||||
|
- int ranges_len, tuple_len;
|
||||||
|
- u32 base, size;
|
||||||
|
+ int err;
|
||||||
|
|
||||||
|
devbus = devm_kzalloc(&pdev->dev, sizeof(struct devbus), GFP_KERNEL);
|
||||||
|
if (!devbus)
|
||||||
|
@@ -248,68 +243,13 @@ static int mvebu_devbus_probe(struct pla
|
||||||
|
return err;
|
||||||
|
|
||||||
|
/*
|
||||||
|
- * Allocate an address window for this device.
|
||||||
|
- * If the device probing fails, then we won't be able to
|
||||||
|
- * remove the allocated address decoding window.
|
||||||
|
- *
|
||||||
|
- * FIXME: This is only a temporary hack! We need to do this here
|
||||||
|
- * because we still don't have device tree bindings for mbus.
|
||||||
|
- * Once that support is added, we will declare these address windows
|
||||||
|
- * statically in the device tree, and remove the window configuration
|
||||||
|
- * from here.
|
||||||
|
- */
|
||||||
|
-
|
||||||
|
- /*
|
||||||
|
- * Get the CS to choose the window string.
|
||||||
|
- * This is a bit hacky, but it will be removed once the
|
||||||
|
- * address windows are declared in the device tree.
|
||||||
|
- */
|
||||||
|
- cs = (((unsigned long)devbus->base) % 0x400) / 8;
|
||||||
|
-
|
||||||
|
- /*
|
||||||
|
- * Parse 'ranges' property to obtain a (base,size) window tuple.
|
||||||
|
- * This will be removed once the address windows
|
||||||
|
- * are declared in the device tree.
|
||||||
|
- */
|
||||||
|
- parent = of_get_parent(node);
|
||||||
|
- if (!parent)
|
||||||
|
- return -EINVAL;
|
||||||
|
-
|
||||||
|
- p_addr_cells = of_n_addr_cells(parent);
|
||||||
|
- of_node_put(parent);
|
||||||
|
-
|
||||||
|
- addr_cells = of_n_addr_cells(node);
|
||||||
|
- size_cells = of_n_size_cells(node);
|
||||||
|
- tuple_len = (p_addr_cells + addr_cells + size_cells) * sizeof(__be32);
|
||||||
|
-
|
||||||
|
- ranges = of_get_property(node, "ranges", &ranges_len);
|
||||||
|
- if (ranges == NULL || ranges_len != tuple_len)
|
||||||
|
- return -EINVAL;
|
||||||
|
-
|
||||||
|
- base = of_translate_address(node, ranges + addr_cells);
|
||||||
|
- if (base == OF_BAD_ADDR)
|
||||||
|
- return -EINVAL;
|
||||||
|
- size = of_read_number(ranges + addr_cells + p_addr_cells, size_cells);
|
||||||
|
-
|
||||||
|
- /*
|
||||||
|
- * Create an mbus address windows.
|
||||||
|
- * FIXME: Remove this, together with the above code, once the
|
||||||
|
- * address windows are declared in the device tree.
|
||||||
|
- */
|
||||||
|
- err = mvebu_mbus_add_window(devbus_wins[cs], base, size);
|
||||||
|
- if (err < 0)
|
||||||
|
- return err;
|
||||||
|
-
|
||||||
|
- /*
|
||||||
|
* We need to create a child device explicitly from here to
|
||||||
|
* guarantee that the child will be probed after the timing
|
||||||
|
* parameters for the bus are written.
|
||||||
|
*/
|
||||||
|
err = of_platform_populate(node, NULL, NULL, dev);
|
||||||
|
- if (err < 0) {
|
||||||
|
- mvebu_mbus_del_window(base, size);
|
||||||
|
+ if (err < 0)
|
||||||
|
return err;
|
||||||
|
- }
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,90 @@
|
||||||
|
From 93b6bd1bf81cffd3e5739478c4434bf25458ec7d Mon Sep 17 00:00:00 2001
|
||||||
|
From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||||
|
Date: Fri, 5 Jul 2013 14:54:16 +0200
|
||||||
|
Subject: [PATCH 038/203] bus: mvebu-mbus: Add new API for window creation
|
||||||
|
|
||||||
|
We add an API to create MBus address decoding windows from the target
|
||||||
|
ID and attribute. This function will be used later and deprecate the
|
||||||
|
current name based scheme.
|
||||||
|
|
||||||
|
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||||
|
Tested-by: Andrew Lunn <andrew@lunn.ch>
|
||||||
|
Tested-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
|
||||||
|
---
|
||||||
|
drivers/bus/mvebu-mbus.c | 33 +++++++++++++++++++++++++--------
|
||||||
|
include/linux/mbus.h | 6 ++++++
|
||||||
|
2 files changed, 31 insertions(+), 8 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/bus/mvebu-mbus.c
|
||||||
|
+++ b/drivers/bus/mvebu-mbus.c
|
||||||
|
@@ -748,6 +748,22 @@ static const struct of_device_id of_mveb
|
||||||
|
/*
|
||||||
|
* Public API of the driver
|
||||||
|
*/
|
||||||
|
+int mvebu_mbus_add_window_remap_by_id(unsigned int target,
|
||||||
|
+ unsigned int attribute,
|
||||||
|
+ phys_addr_t base, size_t size,
|
||||||
|
+ phys_addr_t remap)
|
||||||
|
+{
|
||||||
|
+ struct mvebu_mbus_state *s = &mbus_state;
|
||||||
|
+
|
||||||
|
+ if (!mvebu_mbus_window_conflicts(s, base, size, target, attribute)) {
|
||||||
|
+ pr_err("cannot add window '%x:%x', conflicts with another window\n",
|
||||||
|
+ target, attribute);
|
||||||
|
+ return -EINVAL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return mvebu_mbus_alloc_window(s, base, size, remap, target, attribute);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
int mvebu_mbus_add_window_remap_flags(const char *devname, phys_addr_t base,
|
||||||
|
size_t size, phys_addr_t remap,
|
||||||
|
unsigned int flags)
|
||||||
|
@@ -776,14 +792,8 @@ int mvebu_mbus_add_window_remap_flags(co
|
||||||
|
else if (flags == MVEBU_MBUS_PCI_WA)
|
||||||
|
attr |= 0x28;
|
||||||
|
|
||||||
|
- if (!mvebu_mbus_window_conflicts(s, base, size, target, attr)) {
|
||||||
|
- pr_err("cannot add window '%s', conflicts with another window\n",
|
||||||
|
- devname);
|
||||||
|
- return -EINVAL;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- return mvebu_mbus_alloc_window(s, base, size, remap, target, attr);
|
||||||
|
-
|
||||||
|
+ return mvebu_mbus_add_window_remap_by_id(target, attr, base,
|
||||||
|
+ size, remap);
|
||||||
|
}
|
||||||
|
|
||||||
|
int mvebu_mbus_add_window(const char *devname, phys_addr_t base, size_t size)
|
||||||
|
@@ -792,6 +802,13 @@ int mvebu_mbus_add_window(const char *de
|
||||||
|
MVEBU_MBUS_NO_REMAP, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
+int mvebu_mbus_add_window_by_id(unsigned int target, unsigned int attribute,
|
||||||
|
+ phys_addr_t base, size_t size)
|
||||||
|
+{
|
||||||
|
+ return mvebu_mbus_add_window_remap_by_id(target, attribute, base,
|
||||||
|
+ size, MVEBU_MBUS_NO_REMAP);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
int mvebu_mbus_del_window(phys_addr_t base, size_t size)
|
||||||
|
{
|
||||||
|
int win;
|
||||||
|
--- a/include/linux/mbus.h
|
||||||
|
+++ b/include/linux/mbus.h
|
||||||
|
@@ -62,8 +62,14 @@ static inline const struct mbus_dram_tar
|
||||||
|
int mvebu_mbus_add_window_remap_flags(const char *devname, phys_addr_t base,
|
||||||
|
size_t size, phys_addr_t remap,
|
||||||
|
unsigned int flags);
|
||||||
|
+int mvebu_mbus_add_window_remap_by_id(unsigned int target,
|
||||||
|
+ unsigned int attribute,
|
||||||
|
+ phys_addr_t base, size_t size,
|
||||||
|
+ phys_addr_t remap);
|
||||||
|
int mvebu_mbus_add_window(const char *devname, phys_addr_t base,
|
||||||
|
size_t size);
|
||||||
|
+int mvebu_mbus_add_window_by_id(unsigned int target, unsigned int attribute,
|
||||||
|
+ phys_addr_t base, size_t size);
|
||||||
|
int mvebu_mbus_del_window(phys_addr_t base, size_t size);
|
||||||
|
int mvebu_mbus_init(const char *soc, phys_addr_t mbus_phys_base,
|
||||||
|
size_t mbus_size, phys_addr_t sdram_phys_base,
|
|
@ -0,0 +1,81 @@
|
||||||
|
From 5be79ea0d2bcec8c7360cfe3e7a491e5f176fa84 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
|
||||||
|
Date: Tue, 21 May 2013 10:44:54 -0300
|
||||||
|
Subject: [PATCH 043/203] bus: mvebu-mbus: Factor out initialization details
|
||||||
|
|
||||||
|
We introduce a common initialization function mvebu_mbus_common_init()
|
||||||
|
that will be used by both legacy and device-tree initialization code.
|
||||||
|
This patch is an intermediate step, which will allow to introduce the
|
||||||
|
DT binding for this driver in a less intrusive way.
|
||||||
|
|
||||||
|
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||||
|
Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
|
||||||
|
Tested-by: Andrew Lunn <andrew@lunn.ch>
|
||||||
|
Tested-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
|
||||||
|
---
|
||||||
|
drivers/bus/mvebu-mbus.c | 47 ++++++++++++++++++++++++++++++-----------------
|
||||||
|
1 file changed, 30 insertions(+), 17 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/bus/mvebu-mbus.c
|
||||||
|
+++ b/drivers/bus/mvebu-mbus.c
|
||||||
|
@@ -847,26 +847,14 @@ static __init int mvebu_mbus_debugfs_ini
|
||||||
|
}
|
||||||
|
fs_initcall(mvebu_mbus_debugfs_init);
|
||||||
|
|
||||||
|
-int __init mvebu_mbus_init(const char *soc, phys_addr_t mbuswins_phys_base,
|
||||||
|
- size_t mbuswins_size,
|
||||||
|
- phys_addr_t sdramwins_phys_base,
|
||||||
|
- size_t sdramwins_size)
|
||||||
|
+static int __init mvebu_mbus_common_init(struct mvebu_mbus_state *mbus,
|
||||||
|
+ phys_addr_t mbuswins_phys_base,
|
||||||
|
+ size_t mbuswins_size,
|
||||||
|
+ phys_addr_t sdramwins_phys_base,
|
||||||
|
+ size_t sdramwins_size)
|
||||||
|
{
|
||||||
|
- struct mvebu_mbus_state *mbus = &mbus_state;
|
||||||
|
- const struct of_device_id *of_id;
|
||||||
|
int win;
|
||||||
|
|
||||||
|
- for (of_id = of_mvebu_mbus_ids; of_id->compatible; of_id++)
|
||||||
|
- if (!strcmp(of_id->compatible, soc))
|
||||||
|
- break;
|
||||||
|
-
|
||||||
|
- if (!of_id->compatible) {
|
||||||
|
- pr_err("could not find a matching SoC family\n");
|
||||||
|
- return -ENODEV;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- mbus->soc = of_id->data;
|
||||||
|
-
|
||||||
|
mbus->mbuswins_base = ioremap(mbuswins_phys_base, mbuswins_size);
|
||||||
|
if (!mbus->mbuswins_base)
|
||||||
|
return -ENOMEM;
|
||||||
|
@@ -887,3 +875,28 @@ int __init mvebu_mbus_init(const char *s
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+int __init mvebu_mbus_init(const char *soc, phys_addr_t mbuswins_phys_base,
|
||||||
|
+ size_t mbuswins_size,
|
||||||
|
+ phys_addr_t sdramwins_phys_base,
|
||||||
|
+ size_t sdramwins_size)
|
||||||
|
+{
|
||||||
|
+ const struct of_device_id *of_id;
|
||||||
|
+
|
||||||
|
+ for (of_id = of_mvebu_mbus_ids; of_id->compatible; of_id++)
|
||||||
|
+ if (!strcmp(of_id->compatible, soc))
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
+ if (!of_id->compatible) {
|
||||||
|
+ pr_err("could not find a matching SoC family\n");
|
||||||
|
+ return -ENODEV;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ mbus_state.soc = of_id->data;
|
||||||
|
+
|
||||||
|
+ return mvebu_mbus_common_init(&mbus_state,
|
||||||
|
+ mbuswins_phys_base,
|
||||||
|
+ mbuswins_size,
|
||||||
|
+ sdramwins_phys_base,
|
||||||
|
+ sdramwins_size);
|
||||||
|
+}
|
|
@ -0,0 +1,83 @@
|
||||||
|
From e4123095febc94c547c0459db752e7879db79d76 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
|
||||||
|
Date: Tue, 21 May 2013 10:48:54 -0300
|
||||||
|
Subject: [PATCH 044/203] bus: mvebu-mbus: Introduce device tree binding
|
||||||
|
|
||||||
|
This patch adds the most fundamental device-tree initialization.
|
||||||
|
We only introduce what's required to be able to probe the mvebu-mbus
|
||||||
|
driver from the DT. Follow-up patches will extend the device tree binding,
|
||||||
|
allowing to describe static address decoding windows.
|
||||||
|
|
||||||
|
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||||
|
Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
|
||||||
|
Tested-by: Andrew Lunn <andrew@lunn.ch>
|
||||||
|
Tested-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
|
||||||
|
---
|
||||||
|
drivers/bus/mvebu-mbus.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
include/linux/mbus.h | 1 +
|
||||||
|
2 files changed, 50 insertions(+)
|
||||||
|
|
||||||
|
--- a/drivers/bus/mvebu-mbus.c
|
||||||
|
+++ b/drivers/bus/mvebu-mbus.c
|
||||||
|
@@ -900,3 +900,52 @@ int __init mvebu_mbus_init(const char *s
|
||||||
|
sdramwins_phys_base,
|
||||||
|
sdramwins_size);
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+#ifdef CONFIG_OF
|
||||||
|
+int __init mvebu_mbus_dt_init(void)
|
||||||
|
+{
|
||||||
|
+ struct resource mbuswins_res, sdramwins_res;
|
||||||
|
+ struct device_node *np, *controller;
|
||||||
|
+ const struct of_device_id *of_id;
|
||||||
|
+ const __be32 *prop;
|
||||||
|
+ int ret;
|
||||||
|
+
|
||||||
|
+ np = of_find_matching_node(NULL, of_mvebu_mbus_ids);
|
||||||
|
+ if (!np) {
|
||||||
|
+ pr_err("could not find a matching SoC family\n");
|
||||||
|
+ return -ENODEV;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ of_id = of_match_node(of_mvebu_mbus_ids, np);
|
||||||
|
+ mbus_state.soc = of_id->data;
|
||||||
|
+
|
||||||
|
+ prop = of_get_property(np, "controller", NULL);
|
||||||
|
+ if (!prop) {
|
||||||
|
+ pr_err("required 'controller' property missing\n");
|
||||||
|
+ return -EINVAL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ controller = of_find_node_by_phandle(be32_to_cpup(prop));
|
||||||
|
+ if (!controller) {
|
||||||
|
+ pr_err("could not find an 'mbus-controller' node\n");
|
||||||
|
+ return -ENODEV;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (of_address_to_resource(controller, 0, &mbuswins_res)) {
|
||||||
|
+ pr_err("cannot get MBUS register address\n");
|
||||||
|
+ return -EINVAL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (of_address_to_resource(controller, 1, &sdramwins_res)) {
|
||||||
|
+ pr_err("cannot get SDRAM register address\n");
|
||||||
|
+ return -EINVAL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ ret = mvebu_mbus_common_init(&mbus_state,
|
||||||
|
+ mbuswins_res.start,
|
||||||
|
+ resource_size(&mbuswins_res),
|
||||||
|
+ sdramwins_res.start,
|
||||||
|
+ resource_size(&sdramwins_res));
|
||||||
|
+ return ret;
|
||||||
|
+}
|
||||||
|
+#endif
|
||||||
|
--- a/include/linux/mbus.h
|
||||||
|
+++ b/include/linux/mbus.h
|
||||||
|
@@ -74,5 +74,6 @@ int mvebu_mbus_del_window(phys_addr_t ba
|
||||||
|
int mvebu_mbus_init(const char *soc, phys_addr_t mbus_phys_base,
|
||||||
|
size_t mbus_size, phys_addr_t sdram_phys_base,
|
||||||
|
size_t sdram_size);
|
||||||
|
+int mvebu_mbus_dt_init(void);
|
||||||
|
|
||||||
|
#endif /* __LINUX_MBUS_H */
|
|
@ -0,0 +1,160 @@
|
||||||
|
From ece28a7e105cedb5a9ebd2553aa41d965fb83b64 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
|
||||||
|
Date: Tue, 28 May 2013 07:58:31 -0300
|
||||||
|
Subject: [PATCH 045/203] bus: mvebu-mbus: Add static window allocation to the
|
||||||
|
DT binding
|
||||||
|
|
||||||
|
This patch adds static window allocation to the device tree binding.
|
||||||
|
Each first-child of the mbus-compatible node, with a suitable 'ranges'
|
||||||
|
property, declaring an address translation, will trigger an address
|
||||||
|
decoding window allocation.
|
||||||
|
|
||||||
|
Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
|
||||||
|
Tested-by: Andrew Lunn <andrew@lunn.ch>
|
||||||
|
Tested-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
|
||||||
|
---
|
||||||
|
drivers/bus/mvebu-mbus.c | 127 ++++++++++++++++++++++++++++++++++++++++++++++-
|
||||||
|
1 file changed, 126 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
--- a/drivers/bus/mvebu-mbus.c
|
||||||
|
+++ b/drivers/bus/mvebu-mbus.c
|
||||||
|
@@ -902,6 +902,127 @@ int __init mvebu_mbus_init(const char *s
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_OF
|
||||||
|
+/*
|
||||||
|
+ * The window IDs in the ranges DT property have the following format:
|
||||||
|
+ * - bits 28 to 31: MBus custom field
|
||||||
|
+ * - bits 24 to 27: window target ID
|
||||||
|
+ * - bits 16 to 23: window attribute ID
|
||||||
|
+ * - bits 0 to 15: unused
|
||||||
|
+ */
|
||||||
|
+#define CUSTOM(id) (((id) & 0xF0000000) >> 24)
|
||||||
|
+#define TARGET(id) (((id) & 0x0F000000) >> 24)
|
||||||
|
+#define ATTR(id) (((id) & 0x00FF0000) >> 16)
|
||||||
|
+
|
||||||
|
+static int __init mbus_dt_setup_win(struct mvebu_mbus_state *mbus,
|
||||||
|
+ u32 base, u32 size,
|
||||||
|
+ u8 target, u8 attr)
|
||||||
|
+{
|
||||||
|
+ const struct mvebu_mbus_mapping *map = mbus->soc->map;
|
||||||
|
+ const char *name;
|
||||||
|
+ int i;
|
||||||
|
+
|
||||||
|
+ /* Search for a suitable window in the existing mappings */
|
||||||
|
+ for (i = 0; map[i].name; i++)
|
||||||
|
+ if (map[i].target == target &&
|
||||||
|
+ map[i].attr == (attr & map[i].attrmask))
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
+ name = map[i].name;
|
||||||
|
+ if (!name) {
|
||||||
|
+ pr_err("window 0x%x:0x%x is unknown, skipping\n",
|
||||||
|
+ target, attr);
|
||||||
|
+ return -EINVAL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!mvebu_mbus_window_conflicts(mbus, base, size, target, attr)) {
|
||||||
|
+ pr_err("cannot add window '%s', conflicts with another window\n",
|
||||||
|
+ name);
|
||||||
|
+ return -EBUSY;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (mvebu_mbus_alloc_window(mbus, base, size, MVEBU_MBUS_NO_REMAP,
|
||||||
|
+ target, attr)) {
|
||||||
|
+ pr_err("cannot add window '%s', too many windows\n",
|
||||||
|
+ name);
|
||||||
|
+ return -ENOMEM;
|
||||||
|
+ }
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int __init
|
||||||
|
+mbus_parse_ranges(struct device_node *node,
|
||||||
|
+ int *addr_cells, int *c_addr_cells, int *c_size_cells,
|
||||||
|
+ int *cell_count, const __be32 **ranges_start,
|
||||||
|
+ const __be32 **ranges_end)
|
||||||
|
+{
|
||||||
|
+ const __be32 *prop;
|
||||||
|
+ int ranges_len, tuple_len;
|
||||||
|
+
|
||||||
|
+ /* Allow a node with no 'ranges' property */
|
||||||
|
+ *ranges_start = of_get_property(node, "ranges", &ranges_len);
|
||||||
|
+ if (*ranges_start == NULL) {
|
||||||
|
+ *addr_cells = *c_addr_cells = *c_size_cells = *cell_count = 0;
|
||||||
|
+ *ranges_start = *ranges_end = NULL;
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+ *ranges_end = *ranges_start + ranges_len / sizeof(__be32);
|
||||||
|
+
|
||||||
|
+ *addr_cells = of_n_addr_cells(node);
|
||||||
|
+
|
||||||
|
+ prop = of_get_property(node, "#address-cells", NULL);
|
||||||
|
+ *c_addr_cells = be32_to_cpup(prop);
|
||||||
|
+
|
||||||
|
+ prop = of_get_property(node, "#size-cells", NULL);
|
||||||
|
+ *c_size_cells = be32_to_cpup(prop);
|
||||||
|
+
|
||||||
|
+ *cell_count = *addr_cells + *c_addr_cells + *c_size_cells;
|
||||||
|
+ tuple_len = (*cell_count) * sizeof(__be32);
|
||||||
|
+
|
||||||
|
+ if (ranges_len % tuple_len) {
|
||||||
|
+ pr_warn("malformed ranges entry '%s'\n", node->name);
|
||||||
|
+ return -EINVAL;
|
||||||
|
+ }
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int __init mbus_dt_setup(struct mvebu_mbus_state *mbus,
|
||||||
|
+ struct device_node *np)
|
||||||
|
+{
|
||||||
|
+ int addr_cells, c_addr_cells, c_size_cells;
|
||||||
|
+ int i, ret, cell_count;
|
||||||
|
+ const __be32 *r, *ranges_start, *ranges_end;
|
||||||
|
+
|
||||||
|
+ ret = mbus_parse_ranges(np, &addr_cells, &c_addr_cells,
|
||||||
|
+ &c_size_cells, &cell_count,
|
||||||
|
+ &ranges_start, &ranges_end);
|
||||||
|
+ if (ret < 0)
|
||||||
|
+ return ret;
|
||||||
|
+
|
||||||
|
+ for (i = 0, r = ranges_start; r < ranges_end; r += cell_count, i++) {
|
||||||
|
+ u32 windowid, base, size;
|
||||||
|
+ u8 target, attr;
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * An entry with a non-zero custom field do not
|
||||||
|
+ * correspond to a static window, so skip it.
|
||||||
|
+ */
|
||||||
|
+ windowid = of_read_number(r, 1);
|
||||||
|
+ if (CUSTOM(windowid))
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
+ target = TARGET(windowid);
|
||||||
|
+ attr = ATTR(windowid);
|
||||||
|
+
|
||||||
|
+ base = of_read_number(r + c_addr_cells, addr_cells);
|
||||||
|
+ size = of_read_number(r + c_addr_cells + addr_cells,
|
||||||
|
+ c_size_cells);
|
||||||
|
+ ret = mbus_dt_setup_win(mbus, base, size, target, attr);
|
||||||
|
+ if (ret < 0)
|
||||||
|
+ return ret;
|
||||||
|
+ }
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
int __init mvebu_mbus_dt_init(void)
|
||||||
|
{
|
||||||
|
struct resource mbuswins_res, sdramwins_res;
|
||||||
|
@@ -946,6 +1067,10 @@ int __init mvebu_mbus_dt_init(void)
|
||||||
|
resource_size(&mbuswins_res),
|
||||||
|
sdramwins_res.start,
|
||||||
|
resource_size(&sdramwins_res));
|
||||||
|
- return ret;
|
||||||
|
+ if (ret)
|
||||||
|
+ return ret;
|
||||||
|
+
|
||||||
|
+ /* Setup statically declared windows in the DT */
|
||||||
|
+ return mbus_dt_setup(&mbus_state, np);
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -0,0 +1,121 @@
|
||||||
|
From c9646c891dbd07061a9ff5e061f9f9e54c571349 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
|
||||||
|
Date: Tue, 9 Jul 2013 10:41:53 -0300
|
||||||
|
Subject: [PATCH 046/203] bus: mvebu-mbus: Add new API for the PCIe memory and
|
||||||
|
IO aperture
|
||||||
|
|
||||||
|
We add two optional properties to the MBus DT binding, to encode
|
||||||
|
the PCIe memory and IO aperture. This allows such information to
|
||||||
|
be retrieved by -for instance- the pci driver to allocate the
|
||||||
|
MBus decoding windows.
|
||||||
|
|
||||||
|
Correspondingly, and in order to retrieve this information,
|
||||||
|
we add two new APIs.
|
||||||
|
|
||||||
|
Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
|
||||||
|
Tested-by: Andrew Lunn <andrew@lunn.ch>
|
||||||
|
Tested-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
|
||||||
|
---
|
||||||
|
drivers/bus/mvebu-mbus.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
include/linux/mbus.h | 4 ++++
|
||||||
|
2 files changed, 53 insertions(+)
|
||||||
|
|
||||||
|
--- a/drivers/bus/mvebu-mbus.c
|
||||||
|
+++ b/drivers/bus/mvebu-mbus.c
|
||||||
|
@@ -142,6 +142,8 @@ struct mvebu_mbus_state {
|
||||||
|
struct dentry *debugfs_root;
|
||||||
|
struct dentry *debugfs_sdram;
|
||||||
|
struct dentry *debugfs_devs;
|
||||||
|
+ struct resource pcie_mem_aperture;
|
||||||
|
+ struct resource pcie_io_aperture;
|
||||||
|
const struct mvebu_mbus_soc_data *soc;
|
||||||
|
int hw_io_coherency;
|
||||||
|
};
|
||||||
|
@@ -821,6 +823,20 @@ int mvebu_mbus_del_window(phys_addr_t ba
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+void mvebu_mbus_get_pcie_mem_aperture(struct resource *res)
|
||||||
|
+{
|
||||||
|
+ if (!res)
|
||||||
|
+ return;
|
||||||
|
+ *res = mbus_state.pcie_mem_aperture;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void mvebu_mbus_get_pcie_io_aperture(struct resource *res)
|
||||||
|
+{
|
||||||
|
+ if (!res)
|
||||||
|
+ return;
|
||||||
|
+ *res = mbus_state.pcie_io_aperture;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static __init int mvebu_mbus_debugfs_init(void)
|
||||||
|
{
|
||||||
|
struct mvebu_mbus_state *s = &mbus_state;
|
||||||
|
@@ -1023,6 +1039,35 @@ static int __init mbus_dt_setup(struct m
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void __init mvebu_mbus_get_pcie_resources(struct device_node *np,
|
||||||
|
+ struct resource *mem,
|
||||||
|
+ struct resource *io)
|
||||||
|
+{
|
||||||
|
+ u32 reg[2];
|
||||||
|
+ int ret;
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * These are optional, so we clear them and they'll
|
||||||
|
+ * be zero if they are missing from the DT.
|
||||||
|
+ */
|
||||||
|
+ memset(mem, 0, sizeof(struct resource));
|
||||||
|
+ memset(io, 0, sizeof(struct resource));
|
||||||
|
+
|
||||||
|
+ ret = of_property_read_u32_array(np, "pcie-mem-aperture", reg, ARRAY_SIZE(reg));
|
||||||
|
+ if (!ret) {
|
||||||
|
+ mem->start = reg[0];
|
||||||
|
+ mem->end = mem->start + reg[1];
|
||||||
|
+ mem->flags = IORESOURCE_MEM;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ ret = of_property_read_u32_array(np, "pcie-io-aperture", reg, ARRAY_SIZE(reg));
|
||||||
|
+ if (!ret) {
|
||||||
|
+ io->start = reg[0];
|
||||||
|
+ io->end = io->start + reg[1];
|
||||||
|
+ io->flags = IORESOURCE_IO;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
int __init mvebu_mbus_dt_init(void)
|
||||||
|
{
|
||||||
|
struct resource mbuswins_res, sdramwins_res;
|
||||||
|
@@ -1062,6 +1107,10 @@ int __init mvebu_mbus_dt_init(void)
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ /* Get optional pcie-{mem,io}-aperture properties */
|
||||||
|
+ mvebu_mbus_get_pcie_resources(np, &mbus_state.pcie_mem_aperture,
|
||||||
|
+ &mbus_state.pcie_io_aperture);
|
||||||
|
+
|
||||||
|
ret = mvebu_mbus_common_init(&mbus_state,
|
||||||
|
mbuswins_res.start,
|
||||||
|
resource_size(&mbuswins_res),
|
||||||
|
--- a/include/linux/mbus.h
|
||||||
|
+++ b/include/linux/mbus.h
|
||||||
|
@@ -11,6 +11,8 @@
|
||||||
|
#ifndef __LINUX_MBUS_H
|
||||||
|
#define __LINUX_MBUS_H
|
||||||
|
|
||||||
|
+struct resource;
|
||||||
|
+
|
||||||
|
struct mbus_dram_target_info
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
@@ -59,6 +61,8 @@ static inline const struct mbus_dram_tar
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
+void mvebu_mbus_get_pcie_mem_aperture(struct resource *res);
|
||||||
|
+void mvebu_mbus_get_pcie_io_aperture(struct resource *res);
|
||||||
|
int mvebu_mbus_add_window_remap_flags(const char *devname, phys_addr_t base,
|
||||||
|
size_t size, phys_addr_t remap,
|
||||||
|
unsigned int flags);
|
|
@ -0,0 +1,184 @@
|
||||||
|
From 90b1f963b07d05e8243e5053a910e8a47222f7a1 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||||
|
Date: Fri, 5 Jul 2013 14:54:17 +0200
|
||||||
|
Subject: [PATCH 047/203] PCI: mvebu: Adapt to the new device tree layout
|
||||||
|
|
||||||
|
The new device tree layout encodes the window's target ID and attribute
|
||||||
|
in the PCIe controller node's ranges property. This allows to parse
|
||||||
|
such entries to obtain such information and use the recently introduced
|
||||||
|
MBus API to create the windows, instead of using the current name based
|
||||||
|
scheme.
|
||||||
|
|
||||||
|
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
|
||||||
|
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||||
|
Tested-by: Andrew Lunn <andrew@lunn.ch>
|
||||||
|
Tested-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
|
||||||
|
---
|
||||||
|
drivers/pci/host/pci-mvebu.c | 113 ++++++++++++++++++++++++++++++++-----------
|
||||||
|
1 file changed, 84 insertions(+), 29 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/pci/host/pci-mvebu.c
|
||||||
|
+++ b/drivers/pci/host/pci-mvebu.c
|
||||||
|
@@ -119,6 +119,10 @@ struct mvebu_pcie_port {
|
||||||
|
u32 port;
|
||||||
|
u32 lane;
|
||||||
|
int devfn;
|
||||||
|
+ unsigned int mem_target;
|
||||||
|
+ unsigned int mem_attr;
|
||||||
|
+ unsigned int io_target;
|
||||||
|
+ unsigned int io_attr;
|
||||||
|
struct clk *clk;
|
||||||
|
struct mvebu_sw_pci_bridge bridge;
|
||||||
|
struct device_node *dn;
|
||||||
|
@@ -303,10 +307,9 @@ static void mvebu_pcie_handle_iobase_cha
|
||||||
|
(port->bridge.iolimitupper << 16)) -
|
||||||
|
iobase);
|
||||||
|
|
||||||
|
- mvebu_mbus_add_window_remap_flags(port->name, port->iowin_base,
|
||||||
|
- port->iowin_size,
|
||||||
|
- iobase,
|
||||||
|
- MVEBU_MBUS_PCI_IO);
|
||||||
|
+ mvebu_mbus_add_window_remap_by_id(port->io_target, port->io_attr,
|
||||||
|
+ port->iowin_base, port->iowin_size,
|
||||||
|
+ iobase);
|
||||||
|
|
||||||
|
pci_ioremap_io(iobase, port->iowin_base);
|
||||||
|
}
|
||||||
|
@@ -338,10 +341,8 @@ static void mvebu_pcie_handle_membase_ch
|
||||||
|
(((port->bridge.memlimit & 0xFFF0) << 16) | 0xFFFFF) -
|
||||||
|
port->memwin_base;
|
||||||
|
|
||||||
|
- mvebu_mbus_add_window_remap_flags(port->name, port->memwin_base,
|
||||||
|
- port->memwin_size,
|
||||||
|
- MVEBU_MBUS_NO_REMAP,
|
||||||
|
- MVEBU_MBUS_PCI_MEM);
|
||||||
|
+ mvebu_mbus_add_window_by_id(port->mem_target, port->mem_attr,
|
||||||
|
+ port->memwin_base, port->memwin_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
@@ -730,12 +731,54 @@ mvebu_pcie_map_registers(struct platform
|
||||||
|
return devm_request_and_ioremap(&pdev->dev, ®s);
|
||||||
|
}
|
||||||
|
|
||||||
|
+#define DT_FLAGS_TO_TYPE(flags) (((flags) >> 24) & 0x03)
|
||||||
|
+#define DT_TYPE_IO 0x1
|
||||||
|
+#define DT_TYPE_MEM32 0x2
|
||||||
|
+#define DT_CPUADDR_TO_TARGET(cpuaddr) (((cpuaddr) >> 56) & 0xFF)
|
||||||
|
+#define DT_CPUADDR_TO_ATTR(cpuaddr) (((cpuaddr) >> 48) & 0xFF)
|
||||||
|
+
|
||||||
|
+static int mvebu_get_tgt_attr(struct device_node *np, int devfn,
|
||||||
|
+ unsigned long type, int *tgt, int *attr)
|
||||||
|
+{
|
||||||
|
+ const int na = 3, ns = 2;
|
||||||
|
+ const __be32 *range;
|
||||||
|
+ int rlen, nranges, rangesz, pna, i;
|
||||||
|
+
|
||||||
|
+ range = of_get_property(np, "ranges", &rlen);
|
||||||
|
+ if (!range)
|
||||||
|
+ return -EINVAL;
|
||||||
|
+
|
||||||
|
+ pna = of_n_addr_cells(np);
|
||||||
|
+ rangesz = pna + na + ns;
|
||||||
|
+ nranges = rlen / sizeof(__be32) / rangesz;
|
||||||
|
+
|
||||||
|
+ for (i = 0; i < nranges; i++) {
|
||||||
|
+ u32 flags = of_read_number(range, 1);
|
||||||
|
+ u32 slot = of_read_number(range, 2);
|
||||||
|
+ u64 cpuaddr = of_read_number(range + na, pna);
|
||||||
|
+ unsigned long rtype;
|
||||||
|
+
|
||||||
|
+ if (DT_FLAGS_TO_TYPE(flags) == DT_TYPE_IO)
|
||||||
|
+ rtype = IORESOURCE_IO;
|
||||||
|
+ else if (DT_FLAGS_TO_TYPE(flags) == DT_TYPE_MEM32)
|
||||||
|
+ rtype = IORESOURCE_MEM;
|
||||||
|
+
|
||||||
|
+ if (slot == PCI_SLOT(devfn) && type == rtype) {
|
||||||
|
+ *tgt = DT_CPUADDR_TO_TARGET(cpuaddr);
|
||||||
|
+ *attr = DT_CPUADDR_TO_ATTR(cpuaddr);
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ range += rangesz;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return -ENOENT;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int __init mvebu_pcie_probe(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
struct mvebu_pcie *pcie;
|
||||||
|
struct device_node *np = pdev->dev.of_node;
|
||||||
|
- struct of_pci_range range;
|
||||||
|
- struct of_pci_range_parser parser;
|
||||||
|
struct device_node *child;
|
||||||
|
int i, ret;
|
||||||
|
|
||||||
|
@@ -746,29 +789,25 @@ static int __init mvebu_pcie_probe(struc
|
||||||
|
|
||||||
|
pcie->pdev = pdev;
|
||||||
|
|
||||||
|
- if (of_pci_range_parser_init(&parser, np))
|
||||||
|
+ /* Get the PCIe memory and I/O aperture */
|
||||||
|
+ mvebu_mbus_get_pcie_mem_aperture(&pcie->mem);
|
||||||
|
+ if (resource_size(&pcie->mem) == 0) {
|
||||||
|
+ dev_err(&pdev->dev, "invalid memory aperture size\n");
|
||||||
|
return -EINVAL;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- /* Get the I/O and memory ranges from DT */
|
||||||
|
- for_each_of_pci_range(&parser, &range) {
|
||||||
|
- unsigned long restype = range.flags & IORESOURCE_TYPE_BITS;
|
||||||
|
- if (restype == IORESOURCE_IO) {
|
||||||
|
- of_pci_range_to_resource(&range, np, &pcie->io);
|
||||||
|
- of_pci_range_to_resource(&range, np, &pcie->realio);
|
||||||
|
- pcie->io.name = "I/O";
|
||||||
|
- pcie->realio.start = max_t(resource_size_t,
|
||||||
|
- PCIBIOS_MIN_IO,
|
||||||
|
- range.pci_addr);
|
||||||
|
- pcie->realio.end = min_t(resource_size_t,
|
||||||
|
- IO_SPACE_LIMIT,
|
||||||
|
- range.pci_addr + range.size);
|
||||||
|
- }
|
||||||
|
- if (restype == IORESOURCE_MEM) {
|
||||||
|
- of_pci_range_to_resource(&range, np, &pcie->mem);
|
||||||
|
- pcie->mem.name = "MEM";
|
||||||
|
- }
|
||||||
|
+ mvebu_mbus_get_pcie_io_aperture(&pcie->io);
|
||||||
|
+ if (resource_size(&pcie->io) == 0) {
|
||||||
|
+ dev_err(&pdev->dev, "invalid I/O aperture size\n");
|
||||||
|
+ return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ pcie->realio.flags = pcie->io.flags;
|
||||||
|
+ pcie->realio.start = PCIBIOS_MIN_IO;
|
||||||
|
+ pcie->realio.end = min_t(resource_size_t,
|
||||||
|
+ IO_SPACE_LIMIT,
|
||||||
|
+ resource_size(&pcie->io));
|
||||||
|
+
|
||||||
|
/* Get the bus range */
|
||||||
|
ret = of_pci_parse_bus_range(np, &pcie->busn);
|
||||||
|
if (ret) {
|
||||||
|
@@ -816,6 +855,22 @@ static int __init mvebu_pcie_probe(struc
|
||||||
|
if (port->devfn < 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
+ ret = mvebu_get_tgt_attr(np, port->devfn, IORESOURCE_MEM,
|
||||||
|
+ &port->mem_target, &port->mem_attr);
|
||||||
|
+ if (ret < 0) {
|
||||||
|
+ dev_err(&pdev->dev, "PCIe%d.%d: cannot get tgt/attr for mem window\n",
|
||||||
|
+ port->port, port->lane);
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ ret = mvebu_get_tgt_attr(np, port->devfn, IORESOURCE_IO,
|
||||||
|
+ &port->io_target, &port->io_attr);
|
||||||
|
+ if (ret < 0) {
|
||||||
|
+ dev_err(&pdev->dev, "PCIe%d.%d: cannot get tgt/attr for io window\n",
|
||||||
|
+ port->port, port->lane);
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
port->base = mvebu_pcie_map_registers(pdev, child, port);
|
||||||
|
if (!port->base) {
|
||||||
|
dev_err(&pdev->dev, "PCIe%d.%d: cannot map registers\n",
|
|
@ -0,0 +1,29 @@
|
||||||
|
From 3dc077a80c71050e198e7884707ece042443fe3c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
|
||||||
|
Date: Tue, 23 Jul 2013 07:36:00 -0300
|
||||||
|
Subject: [PATCH 048/203] PCI: mvebu: Check valid base address before port
|
||||||
|
setup
|
||||||
|
|
||||||
|
This driver does not fail to probe when it cannot obtain
|
||||||
|
a port base address. Therefore, add a check for NULL base address
|
||||||
|
before setting up the port, which prevents a kernel panic in such
|
||||||
|
cases.
|
||||||
|
|
||||||
|
Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
|
||||||
|
Tested-by: Andrew Lunn <andrew@lunn.ch>
|
||||||
|
Tested-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
|
||||||
|
---
|
||||||
|
drivers/pci/host/pci-mvebu.c | 2 ++
|
||||||
|
1 file changed, 2 insertions(+)
|
||||||
|
|
||||||
|
--- a/drivers/pci/host/pci-mvebu.c
|
||||||
|
+++ b/drivers/pci/host/pci-mvebu.c
|
||||||
|
@@ -637,6 +637,8 @@ static int __init mvebu_pcie_setup(int n
|
||||||
|
|
||||||
|
for (i = 0; i < pcie->nports; i++) {
|
||||||
|
struct mvebu_pcie_port *port = &pcie->ports[i];
|
||||||
|
+ if (!port->base)
|
||||||
|
+ continue;
|
||||||
|
mvebu_pcie_setup_hw(port);
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,82 @@
|
||||||
|
From 1e94a8740cb1f9c328a3ae8ec4727d90bfb2d7f7 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||||
|
Date: Fri, 5 Jul 2013 14:54:23 +0200
|
||||||
|
Subject: [PATCH 049/203] bus: mvebu-mbus: Remove the no longer used name-based
|
||||||
|
API
|
||||||
|
|
||||||
|
Now that every user of the deprecated name-based API has been
|
||||||
|
converted to using the ID-based API, let's remove the former one.
|
||||||
|
|
||||||
|
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||||
|
Tested-by: Andrew Lunn <andrew@lunn.ch>
|
||||||
|
Tested-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
|
||||||
|
---
|
||||||
|
drivers/bus/mvebu-mbus.c | 38 --------------------------------------
|
||||||
|
include/linux/mbus.h | 5 -----
|
||||||
|
2 files changed, 43 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/bus/mvebu-mbus.c
|
||||||
|
+++ b/drivers/bus/mvebu-mbus.c
|
||||||
|
@@ -766,44 +766,6 @@ int mvebu_mbus_add_window_remap_by_id(un
|
||||||
|
return mvebu_mbus_alloc_window(s, base, size, remap, target, attribute);
|
||||||
|
}
|
||||||
|
|
||||||
|
-int mvebu_mbus_add_window_remap_flags(const char *devname, phys_addr_t base,
|
||||||
|
- size_t size, phys_addr_t remap,
|
||||||
|
- unsigned int flags)
|
||||||
|
-{
|
||||||
|
- struct mvebu_mbus_state *s = &mbus_state;
|
||||||
|
- u8 target, attr;
|
||||||
|
- int i;
|
||||||
|
-
|
||||||
|
- if (!s->soc->map)
|
||||||
|
- return -ENODEV;
|
||||||
|
-
|
||||||
|
- for (i = 0; s->soc->map[i].name; i++)
|
||||||
|
- if (!strcmp(s->soc->map[i].name, devname))
|
||||||
|
- break;
|
||||||
|
-
|
||||||
|
- if (!s->soc->map[i].name) {
|
||||||
|
- pr_err("unknown device '%s'\n", devname);
|
||||||
|
- return -ENODEV;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- target = s->soc->map[i].target;
|
||||||
|
- attr = s->soc->map[i].attr;
|
||||||
|
-
|
||||||
|
- if (flags == MVEBU_MBUS_PCI_MEM)
|
||||||
|
- attr |= 0x8;
|
||||||
|
- else if (flags == MVEBU_MBUS_PCI_WA)
|
||||||
|
- attr |= 0x28;
|
||||||
|
-
|
||||||
|
- return mvebu_mbus_add_window_remap_by_id(target, attr, base,
|
||||||
|
- size, remap);
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-int mvebu_mbus_add_window(const char *devname, phys_addr_t base, size_t size)
|
||||||
|
-{
|
||||||
|
- return mvebu_mbus_add_window_remap_flags(devname, base, size,
|
||||||
|
- MVEBU_MBUS_NO_REMAP, 0);
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
int mvebu_mbus_add_window_by_id(unsigned int target, unsigned int attribute,
|
||||||
|
phys_addr_t base, size_t size)
|
||||||
|
{
|
||||||
|
--- a/include/linux/mbus.h
|
||||||
|
+++ b/include/linux/mbus.h
|
||||||
|
@@ -63,15 +63,10 @@ static inline const struct mbus_dram_tar
|
||||||
|
|
||||||
|
void mvebu_mbus_get_pcie_mem_aperture(struct resource *res);
|
||||||
|
void mvebu_mbus_get_pcie_io_aperture(struct resource *res);
|
||||||
|
-int mvebu_mbus_add_window_remap_flags(const char *devname, phys_addr_t base,
|
||||||
|
- size_t size, phys_addr_t remap,
|
||||||
|
- unsigned int flags);
|
||||||
|
int mvebu_mbus_add_window_remap_by_id(unsigned int target,
|
||||||
|
unsigned int attribute,
|
||||||
|
phys_addr_t base, size_t size,
|
||||||
|
phys_addr_t remap);
|
||||||
|
-int mvebu_mbus_add_window(const char *devname, phys_addr_t base,
|
||||||
|
- size_t size);
|
||||||
|
int mvebu_mbus_add_window_by_id(unsigned int target, unsigned int attribute,
|
||||||
|
phys_addr_t base, size_t size);
|
||||||
|
int mvebu_mbus_del_window(phys_addr_t base, size_t size);
|
|
@ -0,0 +1,266 @@
|
||||||
|
From 08c3b38a75ca47b74c81d14e1715ab9dc7b0e5cb Mon Sep 17 00:00:00 2001
|
||||||
|
From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||||
|
Date: Fri, 5 Jul 2013 14:54:24 +0200
|
||||||
|
Subject: [PATCH 050/203] bus: mvebu-mbus: Remove name -> target, attribute
|
||||||
|
mapping tables
|
||||||
|
|
||||||
|
This tables were used together with the name-based MBus window
|
||||||
|
creation API. Since that's has been removed, we can also remove
|
||||||
|
the tables.
|
||||||
|
|
||||||
|
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||||
|
Tested-by: Andrew Lunn <andrew@lunn.ch>
|
||||||
|
Tested-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
|
||||||
|
---
|
||||||
|
drivers/bus/mvebu-mbus.c | 150 +++--------------------------------------------
|
||||||
|
1 file changed, 7 insertions(+), 143 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/bus/mvebu-mbus.c
|
||||||
|
+++ b/drivers/bus/mvebu-mbus.c
|
||||||
|
@@ -97,33 +97,6 @@
|
||||||
|
|
||||||
|
#define DOVE_DDR_BASE_CS_OFF(n) ((n) << 4)
|
||||||
|
|
||||||
|
-struct mvebu_mbus_mapping {
|
||||||
|
- const char *name;
|
||||||
|
- u8 target;
|
||||||
|
- u8 attr;
|
||||||
|
- u8 attrmask;
|
||||||
|
-};
|
||||||
|
-
|
||||||
|
-/*
|
||||||
|
- * Masks used for the 'attrmask' field of mvebu_mbus_mapping. They
|
||||||
|
- * allow to get the real attribute value, discarding the special bits
|
||||||
|
- * used to select a PCI MEM region or a PCI WA region. This allows the
|
||||||
|
- * debugfs code to reverse-match the name of a device from its
|
||||||
|
- * target/attr values.
|
||||||
|
- *
|
||||||
|
- * For all devices except PCI, all bits of 'attr' must be
|
||||||
|
- * considered. For most SoCs, only bit 3 should be ignored (it allows
|
||||||
|
- * to select between PCI MEM and PCI I/O). On Orion5x however, there
|
||||||
|
- * is the special bit 5 to select a PCI WA region.
|
||||||
|
- */
|
||||||
|
-#define MAPDEF_NOMASK 0xff
|
||||||
|
-#define MAPDEF_PCIMASK 0xf7
|
||||||
|
-#define MAPDEF_ORIONPCIMASK 0xd7
|
||||||
|
-
|
||||||
|
-/* Macro used to define one mvebu_mbus_mapping entry */
|
||||||
|
-#define MAPDEF(__n, __t, __a, __m) \
|
||||||
|
- { .name = __n, .target = __t, .attr = __a, .attrmask = __m }
|
||||||
|
-
|
||||||
|
struct mvebu_mbus_state;
|
||||||
|
|
||||||
|
struct mvebu_mbus_soc_data {
|
||||||
|
@@ -133,7 +106,6 @@ struct mvebu_mbus_soc_data {
|
||||||
|
void (*setup_cpu_target)(struct mvebu_mbus_state *s);
|
||||||
|
int (*show_cpu_target)(struct mvebu_mbus_state *s,
|
||||||
|
struct seq_file *seq, void *v);
|
||||||
|
- const struct mvebu_mbus_mapping *map;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct mvebu_mbus_state {
|
||||||
|
@@ -430,8 +402,7 @@ static int mvebu_devs_debug_show(struct
|
||||||
|
u64 wbase, wremap;
|
||||||
|
u32 wsize;
|
||||||
|
u8 wtarget, wattr;
|
||||||
|
- int enabled, i;
|
||||||
|
- const char *name;
|
||||||
|
+ int enabled;
|
||||||
|
|
||||||
|
mvebu_mbus_read_window(mbus, win,
|
||||||
|
&enabled, &wbase, &wsize,
|
||||||
|
@@ -442,18 +413,9 @@ static int mvebu_devs_debug_show(struct
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
-
|
||||||
|
- for (i = 0; mbus->soc->map[i].name; i++)
|
||||||
|
- if (mbus->soc->map[i].target == wtarget &&
|
||||||
|
- mbus->soc->map[i].attr ==
|
||||||
|
- (wattr & mbus->soc->map[i].attrmask))
|
||||||
|
- break;
|
||||||
|
-
|
||||||
|
- name = mbus->soc->map[i].name ?: "unknown";
|
||||||
|
-
|
||||||
|
- seq_printf(seq, "[%02d] %016llx - %016llx : %s",
|
||||||
|
+ seq_printf(seq, "[%02d] %016llx - %016llx : %04x:%04x",
|
||||||
|
win, (unsigned long long)wbase,
|
||||||
|
- (unsigned long long)(wbase + wsize), name);
|
||||||
|
+ (unsigned long long)(wbase + wsize), wtarget, wattr);
|
||||||
|
|
||||||
|
if (win < mbus->soc->num_remappable_wins) {
|
||||||
|
seq_printf(seq, " (remap %016llx)\n",
|
||||||
|
@@ -578,45 +540,12 @@ mvebu_mbus_dove_setup_cpu_target(struct
|
||||||
|
mvebu_mbus_dram_info.num_cs = cs;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static const struct mvebu_mbus_mapping armada_370_map[] = {
|
||||||
|
- MAPDEF("bootrom", 1, 0xe0, MAPDEF_NOMASK),
|
||||||
|
- MAPDEF("devbus-boot", 1, 0x2f, MAPDEF_NOMASK),
|
||||||
|
- MAPDEF("devbus-cs0", 1, 0x3e, MAPDEF_NOMASK),
|
||||||
|
- MAPDEF("devbus-cs1", 1, 0x3d, MAPDEF_NOMASK),
|
||||||
|
- MAPDEF("devbus-cs2", 1, 0x3b, MAPDEF_NOMASK),
|
||||||
|
- MAPDEF("devbus-cs3", 1, 0x37, MAPDEF_NOMASK),
|
||||||
|
- MAPDEF("pcie0.0", 4, 0xe0, MAPDEF_PCIMASK),
|
||||||
|
- MAPDEF("pcie1.0", 8, 0xe0, MAPDEF_PCIMASK),
|
||||||
|
- {},
|
||||||
|
-};
|
||||||
|
-
|
||||||
|
static const struct mvebu_mbus_soc_data armada_370_mbus_data = {
|
||||||
|
.num_wins = 20,
|
||||||
|
.num_remappable_wins = 8,
|
||||||
|
.win_cfg_offset = armada_370_xp_mbus_win_offset,
|
||||||
|
.setup_cpu_target = mvebu_mbus_default_setup_cpu_target,
|
||||||
|
.show_cpu_target = mvebu_sdram_debug_show_orion,
|
||||||
|
- .map = armada_370_map,
|
||||||
|
-};
|
||||||
|
-
|
||||||
|
-static const struct mvebu_mbus_mapping armada_xp_map[] = {
|
||||||
|
- MAPDEF("bootrom", 1, 0x1d, MAPDEF_NOMASK),
|
||||||
|
- MAPDEF("devbus-boot", 1, 0x2f, MAPDEF_NOMASK),
|
||||||
|
- MAPDEF("devbus-cs0", 1, 0x3e, MAPDEF_NOMASK),
|
||||||
|
- MAPDEF("devbus-cs1", 1, 0x3d, MAPDEF_NOMASK),
|
||||||
|
- MAPDEF("devbus-cs2", 1, 0x3b, MAPDEF_NOMASK),
|
||||||
|
- MAPDEF("devbus-cs3", 1, 0x37, MAPDEF_NOMASK),
|
||||||
|
- MAPDEF("pcie0.0", 4, 0xe0, MAPDEF_PCIMASK),
|
||||||
|
- MAPDEF("pcie0.1", 4, 0xd0, MAPDEF_PCIMASK),
|
||||||
|
- MAPDEF("pcie0.2", 4, 0xb0, MAPDEF_PCIMASK),
|
||||||
|
- MAPDEF("pcie0.3", 4, 0x70, MAPDEF_PCIMASK),
|
||||||
|
- MAPDEF("pcie1.0", 8, 0xe0, MAPDEF_PCIMASK),
|
||||||
|
- MAPDEF("pcie1.1", 8, 0xd0, MAPDEF_PCIMASK),
|
||||||
|
- MAPDEF("pcie1.2", 8, 0xb0, MAPDEF_PCIMASK),
|
||||||
|
- MAPDEF("pcie1.3", 8, 0x70, MAPDEF_PCIMASK),
|
||||||
|
- MAPDEF("pcie2.0", 4, 0xf0, MAPDEF_PCIMASK),
|
||||||
|
- MAPDEF("pcie3.0", 8, 0xf0, MAPDEF_PCIMASK),
|
||||||
|
- {},
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct mvebu_mbus_soc_data armada_xp_mbus_data = {
|
||||||
|
@@ -625,15 +554,6 @@ static const struct mvebu_mbus_soc_data
|
||||||
|
.win_cfg_offset = armada_370_xp_mbus_win_offset,
|
||||||
|
.setup_cpu_target = mvebu_mbus_default_setup_cpu_target,
|
||||||
|
.show_cpu_target = mvebu_sdram_debug_show_orion,
|
||||||
|
- .map = armada_xp_map,
|
||||||
|
-};
|
||||||
|
-
|
||||||
|
-static const struct mvebu_mbus_mapping kirkwood_map[] = {
|
||||||
|
- MAPDEF("pcie0.0", 4, 0xe0, MAPDEF_PCIMASK),
|
||||||
|
- MAPDEF("pcie1.0", 4, 0xd0, MAPDEF_PCIMASK),
|
||||||
|
- MAPDEF("sram", 3, 0x01, MAPDEF_NOMASK),
|
||||||
|
- MAPDEF("nand", 1, 0x2f, MAPDEF_NOMASK),
|
||||||
|
- {},
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct mvebu_mbus_soc_data kirkwood_mbus_data = {
|
||||||
|
@@ -642,16 +562,6 @@ static const struct mvebu_mbus_soc_data
|
||||||
|
.win_cfg_offset = orion_mbus_win_offset,
|
||||||
|
.setup_cpu_target = mvebu_mbus_default_setup_cpu_target,
|
||||||
|
.show_cpu_target = mvebu_sdram_debug_show_orion,
|
||||||
|
- .map = kirkwood_map,
|
||||||
|
-};
|
||||||
|
-
|
||||||
|
-static const struct mvebu_mbus_mapping dove_map[] = {
|
||||||
|
- MAPDEF("pcie0.0", 0x4, 0xe0, MAPDEF_PCIMASK),
|
||||||
|
- MAPDEF("pcie1.0", 0x8, 0xe0, MAPDEF_PCIMASK),
|
||||||
|
- MAPDEF("cesa", 0x3, 0x01, MAPDEF_NOMASK),
|
||||||
|
- MAPDEF("bootrom", 0x1, 0xfd, MAPDEF_NOMASK),
|
||||||
|
- MAPDEF("scratchpad", 0xd, 0x0, MAPDEF_NOMASK),
|
||||||
|
- {},
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct mvebu_mbus_soc_data dove_mbus_data = {
|
||||||
|
@@ -660,18 +570,6 @@ static const struct mvebu_mbus_soc_data
|
||||||
|
.win_cfg_offset = orion_mbus_win_offset,
|
||||||
|
.setup_cpu_target = mvebu_mbus_dove_setup_cpu_target,
|
||||||
|
.show_cpu_target = mvebu_sdram_debug_show_dove,
|
||||||
|
- .map = dove_map,
|
||||||
|
-};
|
||||||
|
-
|
||||||
|
-static const struct mvebu_mbus_mapping orion5x_map[] = {
|
||||||
|
- MAPDEF("pcie0.0", 4, 0x51, MAPDEF_ORIONPCIMASK),
|
||||||
|
- MAPDEF("pci0.0", 3, 0x51, MAPDEF_ORIONPCIMASK),
|
||||||
|
- MAPDEF("devbus-boot", 1, 0x0f, MAPDEF_NOMASK),
|
||||||
|
- MAPDEF("devbus-cs0", 1, 0x1e, MAPDEF_NOMASK),
|
||||||
|
- MAPDEF("devbus-cs1", 1, 0x1d, MAPDEF_NOMASK),
|
||||||
|
- MAPDEF("devbus-cs2", 1, 0x1b, MAPDEF_NOMASK),
|
||||||
|
- MAPDEF("sram", 0, 0x00, MAPDEF_NOMASK),
|
||||||
|
- {},
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
@@ -684,7 +582,6 @@ static const struct mvebu_mbus_soc_data
|
||||||
|
.win_cfg_offset = orion_mbus_win_offset,
|
||||||
|
.setup_cpu_target = mvebu_mbus_default_setup_cpu_target,
|
||||||
|
.show_cpu_target = mvebu_sdram_debug_show_orion,
|
||||||
|
- .map = orion5x_map,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct mvebu_mbus_soc_data orion5x_2win_mbus_data = {
|
||||||
|
@@ -693,21 +590,6 @@ static const struct mvebu_mbus_soc_data
|
||||||
|
.win_cfg_offset = orion_mbus_win_offset,
|
||||||
|
.setup_cpu_target = mvebu_mbus_default_setup_cpu_target,
|
||||||
|
.show_cpu_target = mvebu_sdram_debug_show_orion,
|
||||||
|
- .map = orion5x_map,
|
||||||
|
-};
|
||||||
|
-
|
||||||
|
-static const struct mvebu_mbus_mapping mv78xx0_map[] = {
|
||||||
|
- MAPDEF("pcie0.0", 4, 0xe0, MAPDEF_PCIMASK),
|
||||||
|
- MAPDEF("pcie0.1", 4, 0xd0, MAPDEF_PCIMASK),
|
||||||
|
- MAPDEF("pcie0.2", 4, 0xb0, MAPDEF_PCIMASK),
|
||||||
|
- MAPDEF("pcie0.3", 4, 0x70, MAPDEF_PCIMASK),
|
||||||
|
- MAPDEF("pcie1.0", 8, 0xe0, MAPDEF_PCIMASK),
|
||||||
|
- MAPDEF("pcie1.1", 8, 0xd0, MAPDEF_PCIMASK),
|
||||||
|
- MAPDEF("pcie1.2", 8, 0xb0, MAPDEF_PCIMASK),
|
||||||
|
- MAPDEF("pcie1.3", 8, 0x70, MAPDEF_PCIMASK),
|
||||||
|
- MAPDEF("pcie2.0", 4, 0xf0, MAPDEF_PCIMASK),
|
||||||
|
- MAPDEF("pcie3.0", 8, 0xf0, MAPDEF_PCIMASK),
|
||||||
|
- {},
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct mvebu_mbus_soc_data mv78xx0_mbus_data = {
|
||||||
|
@@ -716,7 +598,6 @@ static const struct mvebu_mbus_soc_data
|
||||||
|
.win_cfg_offset = mv78xx0_mbus_win_offset,
|
||||||
|
.setup_cpu_target = mvebu_mbus_default_setup_cpu_target,
|
||||||
|
.show_cpu_target = mvebu_sdram_debug_show_orion,
|
||||||
|
- .map = mv78xx0_map,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
@@ -895,33 +776,16 @@ static int __init mbus_dt_setup_win(stru
|
||||||
|
u32 base, u32 size,
|
||||||
|
u8 target, u8 attr)
|
||||||
|
{
|
||||||
|
- const struct mvebu_mbus_mapping *map = mbus->soc->map;
|
||||||
|
- const char *name;
|
||||||
|
- int i;
|
||||||
|
-
|
||||||
|
- /* Search for a suitable window in the existing mappings */
|
||||||
|
- for (i = 0; map[i].name; i++)
|
||||||
|
- if (map[i].target == target &&
|
||||||
|
- map[i].attr == (attr & map[i].attrmask))
|
||||||
|
- break;
|
||||||
|
-
|
||||||
|
- name = map[i].name;
|
||||||
|
- if (!name) {
|
||||||
|
- pr_err("window 0x%x:0x%x is unknown, skipping\n",
|
||||||
|
- target, attr);
|
||||||
|
- return -EINVAL;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
if (!mvebu_mbus_window_conflicts(mbus, base, size, target, attr)) {
|
||||||
|
- pr_err("cannot add window '%s', conflicts with another window\n",
|
||||||
|
- name);
|
||||||
|
+ pr_err("cannot add window '%04x:%04x', conflicts with another window\n",
|
||||||
|
+ target, attr);
|
||||||
|
return -EBUSY;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mvebu_mbus_alloc_window(mbus, base, size, MVEBU_MBUS_NO_REMAP,
|
||||||
|
target, attr)) {
|
||||||
|
- pr_err("cannot add window '%s', too many windows\n",
|
||||||
|
- name);
|
||||||
|
+ pr_err("cannot add window '%04x:%04x', too many windows\n",
|
||||||
|
+ target, attr);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
return 0;
|
|
@ -0,0 +1,35 @@
|
||||||
|
From 8f14bc2a883316dfd95383900c61d7d9183e8eaf Mon Sep 17 00:00:00 2001
|
||||||
|
From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||||
|
Date: Fri, 5 Jul 2013 14:54:25 +0200
|
||||||
|
Subject: [PATCH 051/203] bus: mvebu-mbus: Update main description
|
||||||
|
|
||||||
|
After replacing the MBus name-based by the new ID-based API
|
||||||
|
let's fix the general description of the driver at the beginning
|
||||||
|
of the file.
|
||||||
|
|
||||||
|
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||||
|
Tested-by: Andrew Lunn <andrew@lunn.ch>
|
||||||
|
Tested-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
|
||||||
|
---
|
||||||
|
drivers/bus/mvebu-mbus.c | 10 +++-------
|
||||||
|
1 file changed, 3 insertions(+), 7 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/bus/mvebu-mbus.c
|
||||||
|
+++ b/drivers/bus/mvebu-mbus.c
|
||||||
|
@@ -35,13 +35,9 @@
|
||||||
|
*
|
||||||
|
* - Provides an API for platform code or device drivers to
|
||||||
|
* dynamically add or remove address decoding windows for the CPU ->
|
||||||
|
- * device accesses. This API is mvebu_mbus_add_window(),
|
||||||
|
- * mvebu_mbus_add_window_remap_flags() and
|
||||||
|
- * mvebu_mbus_del_window(). Since the (target, attribute) values
|
||||||
|
- * differ from one SoC family to another, the API uses a 'const char
|
||||||
|
- * *' string to identify devices, and this driver is responsible for
|
||||||
|
- * knowing the mapping between the name of a device and its
|
||||||
|
- * corresponding (target, attribute) in the current SoC family.
|
||||||
|
+ * device accesses. This API is mvebu_mbus_add_window_by_id(),
|
||||||
|
+ * mvebu_mbus_add_window_remap_by_id() and
|
||||||
|
+ * mvebu_mbus_del_window().
|
||||||
|
*
|
||||||
|
* - Provides a debugfs interface in /sys/kernel/debug/mvebu-mbus/ to
|
||||||
|
* see the list of CPU -> SDRAM windows and their configuration
|
|
@ -0,0 +1,48 @@
|
||||||
|
From 2c8f0b1810ff9cd45ed2055441b4c43afcfb7d2a Mon Sep 17 00:00:00 2001
|
||||||
|
From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||||
|
Date: Fri, 5 Jul 2013 14:54:26 +0200
|
||||||
|
Subject: [PATCH 052/203] bus: mvebu-mbus: Factorize Armada 370/XP data
|
||||||
|
structures
|
||||||
|
|
||||||
|
These structures were only different in the mapping tables.
|
||||||
|
Now that those tables have been removed, it doesn't make any sense
|
||||||
|
to keep different structures.
|
||||||
|
|
||||||
|
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||||
|
Tested-by: Andrew Lunn <andrew@lunn.ch>
|
||||||
|
Tested-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
|
||||||
|
---
|
||||||
|
drivers/bus/mvebu-mbus.c | 14 +++-----------
|
||||||
|
1 file changed, 3 insertions(+), 11 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/bus/mvebu-mbus.c
|
||||||
|
+++ b/drivers/bus/mvebu-mbus.c
|
||||||
|
@@ -536,15 +536,7 @@ mvebu_mbus_dove_setup_cpu_target(struct
|
||||||
|
mvebu_mbus_dram_info.num_cs = cs;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static const struct mvebu_mbus_soc_data armada_370_mbus_data = {
|
||||||
|
- .num_wins = 20,
|
||||||
|
- .num_remappable_wins = 8,
|
||||||
|
- .win_cfg_offset = armada_370_xp_mbus_win_offset,
|
||||||
|
- .setup_cpu_target = mvebu_mbus_default_setup_cpu_target,
|
||||||
|
- .show_cpu_target = mvebu_sdram_debug_show_orion,
|
||||||
|
-};
|
||||||
|
-
|
||||||
|
-static const struct mvebu_mbus_soc_data armada_xp_mbus_data = {
|
||||||
|
+static const struct mvebu_mbus_soc_data armada_370_xp_mbus_data = {
|
||||||
|
.num_wins = 20,
|
||||||
|
.num_remappable_wins = 8,
|
||||||
|
.win_cfg_offset = armada_370_xp_mbus_win_offset,
|
||||||
|
@@ -604,9 +596,9 @@ static const struct mvebu_mbus_soc_data
|
||||||
|
*/
|
||||||
|
static const struct of_device_id of_mvebu_mbus_ids[] = {
|
||||||
|
{ .compatible = "marvell,armada370-mbus",
|
||||||
|
- .data = &armada_370_mbus_data, },
|
||||||
|
+ .data = &armada_370_xp_mbus_data, },
|
||||||
|
{ .compatible = "marvell,armadaxp-mbus",
|
||||||
|
- .data = &armada_xp_mbus_data, },
|
||||||
|
+ .data = &armada_370_xp_mbus_data, },
|
||||||
|
{ .compatible = "marvell,kirkwood-mbus",
|
||||||
|
.data = &kirkwood_mbus_data, },
|
||||||
|
{ .compatible = "marvell,dove-mbus",
|
Loading…
Reference in New Issue