diff options
Diffstat (limited to 'target/linux/mvebu/patches-3.8')
36 files changed, 2525 insertions, 0 deletions
diff --git a/target/linux/mvebu/patches-3.8/006-mmc_mvsdio_use_slot_gpio.patch b/target/linux/mvebu/patches-3.8/006-mmc_mvsdio_use_slot_gpio.patch new file mode 100644 index 000000000..7bb8c20d5 --- /dev/null +++ b/target/linux/mvebu/patches-3.8/006-mmc_mvsdio_use_slot_gpio.patch @@ -0,0 +1,115 @@ +From patchwork Wed Jan 16 13:13:57 2013 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Subject: [2/5] mmc: mvsdio: use slot-gpio infrastructure for write protect gpio +Date: Wed, 16 Jan 2013 13:13:57 -0000 +From: Andrew Lunn <andrew@lunn.ch> +X-Patchwork-Id: 1987931 +Message-Id: <1358342040-7130-3-git-send-email-andrew@lunn.ch> +To: Jason Cooper <jason@lakedaemon.net> +Cc: linux ARM <linux-arm-kernel@lists.infradead.org>, + linux-mmc@vger.kernel.org, linux@arm.linux.org.uk, + Thomas Petazzoni <thomas.petazzoni@free-electrons.com>, + Andrew Lunn <andrew@lunn.ch> + +From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> + +The MMC core subsystem provides in drivers/mmc/core/slot-gpio.c a nice +set of helper functions to simplify the management of the write +protect GPIO in MMC host drivers. This patch migrates the mvsdio +driver to using those helpers, which will make the ->probe() code +simpler, and therefore ease the process of adding a Device Tree +binding for this driver. + +Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> +Signed-off-by: Andrew Lunn <andrew@lunn.ch> +Tested-by: Stefan Peter <s.peter@mpl.ch> +Tested-by: Florian Fainelli <florian@openwrt.org> +Signed-off-by: Jason Cooper <jason@lakedaemon.net> + +--- +drivers/mmc/host/mvsdio.c | 30 +++++------------------------- + 1 file changed, 5 insertions(+), 25 deletions(-) + +--- a/drivers/mmc/host/mvsdio.c ++++ b/drivers/mmc/host/mvsdio.c +@@ -22,6 +22,7 @@ + #include <linux/clk.h> + #include <linux/gpio.h> + #include <linux/mmc/host.h> ++#include <linux/mmc/slot-gpio.h> + + #include <asm/sizes.h> + #include <asm/unaligned.h> +@@ -52,7 +53,6 @@ struct mvsd_host { + struct device *dev; + struct clk *clk; + int gpio_card_detect; +- int gpio_write_protect; + }; + + #define mvsd_write(offs, val) writel(val, iobase + (offs)) +@@ -564,20 +564,6 @@ static void mvsd_enable_sdio_irq(struct + spin_unlock_irqrestore(&host->lock, flags); + } + +-static int mvsd_get_ro(struct mmc_host *mmc) +-{ +- struct mvsd_host *host = mmc_priv(mmc); +- +- if (host->gpio_write_protect) +- return gpio_get_value(host->gpio_write_protect); +- +- /* +- * Board doesn't support read only detection; let the mmc core +- * decide what to do. +- */ +- return -ENOSYS; +-} +- + static void mvsd_power_up(struct mvsd_host *host) + { + void __iomem *iobase = host->base; +@@ -674,7 +660,7 @@ static void mvsd_set_ios(struct mmc_host + + static const struct mmc_host_ops mvsd_ops = { + .request = mvsd_request, +- .get_ro = mvsd_get_ro, ++ .get_ro = mmc_gpio_get_ro, + .set_ios = mvsd_set_ios, + .enable_sdio_irq = mvsd_enable_sdio_irq, + }; +@@ -793,15 +779,7 @@ static int __init mvsd_probe(struct plat + if (!host->gpio_card_detect) + mmc->caps |= MMC_CAP_NEEDS_POLL; + +- if (mvsd_data->gpio_write_protect) { +- ret = devm_gpio_request_one(&pdev->dev, +- mvsd_data->gpio_write_protect, +- GPIOF_IN, DRIVER_NAME " wp"); +- if (ret == 0) { +- host->gpio_write_protect = +- mvsd_data->gpio_write_protect; +- } +- } ++ mmc_gpio_request_ro(mmc, mvsd_data->gpio_write_protect); + + setup_timer(&host->timer, mvsd_timeout_timer, (unsigned long)host); + platform_set_drvdata(pdev, mmc); +@@ -820,6 +798,7 @@ static int __init mvsd_probe(struct plat + + out: + if (mmc) { ++ mmc_gpio_free_ro(mmc); + if (!IS_ERR(host->clk)) + clk_disable_unprepare(host->clk); + mmc_free_host(mmc); +@@ -834,6 +813,7 @@ static int __exit mvsd_remove(struct pla + + struct mvsd_host *host = mmc_priv(mmc); + ++ mmc_gpio_free_ro(mmc); + mmc_remove_host(mmc); + del_timer_sync(&host->timer); + mvsd_power_down(host); diff --git a/target/linux/mvebu/patches-3.8/007-mmc_mvsdio_use_slot_gpio_for_cd.patch b/target/linux/mvebu/patches-3.8/007-mmc_mvsdio_use_slot_gpio_for_cd.patch new file mode 100644 index 000000000..a1b3b8723 --- /dev/null +++ b/target/linux/mvebu/patches-3.8/007-mmc_mvsdio_use_slot_gpio_for_cd.patch @@ -0,0 +1,117 @@ +From patchwork Wed Jan 16 13:13:58 2013 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Subject: [3/5] mmc: mvsdio: use slot-gpio for card detect gpio +Date: Wed, 16 Jan 2013 13:13:58 -0000 +From: Andrew Lunn <andrew@lunn.ch> +X-Patchwork-Id: 1987941 +Message-Id: <1358342040-7130-4-git-send-email-andrew@lunn.ch> +To: Jason Cooper <jason@lakedaemon.net> +Cc: linux ARM <linux-arm-kernel@lists.infradead.org>, + linux-mmc@vger.kernel.org, linux@arm.linux.org.uk, + Thomas Petazzoni <thomas.petazzoni@free-electrons.com>, + Andrew Lunn <andrew@lunn.ch> + +From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> + +The MMC core subsystem provides in drivers/mmc/core/slot-gpio.c a nice +set of helper functions to simplify the management of the card detect +GPIO in MMC host drivers. This patch migrates the mvsdio driver to +using those helpers, which will make the ->probe() code simpler, and +therefore ease the process of adding a Device Tree binding for this +driver. + +Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> +Signed-off-by: Andrew Lunn <andrew@lunn.ch> +Tested-by: Stefan Peter <s.peter@mpl.ch> +Tested-by: Florian Fainelli <florian@openwrt.org> +Signed-off-by: Jason Cooper <jason@lakedaemon.net> + +--- +drivers/mmc/host/mvsdio.c | 39 +++++++++------------------------------ + 1 file changed, 9 insertions(+), 30 deletions(-) + +--- a/drivers/mmc/host/mvsdio.c ++++ b/drivers/mmc/host/mvsdio.c +@@ -52,7 +52,6 @@ struct mvsd_host { + struct mmc_host *mmc; + struct device *dev; + struct clk *clk; +- int gpio_card_detect; + }; + + #define mvsd_write(offs, val) writel(val, iobase + (offs)) +@@ -538,13 +537,6 @@ static void mvsd_timeout_timer(unsigned + mmc_request_done(host->mmc, mrq); + } + +-static irqreturn_t mvsd_card_detect_irq(int irq, void *dev) +-{ +- struct mvsd_host *host = dev; +- mmc_detect_change(host->mmc, msecs_to_jiffies(100)); +- return IRQ_HANDLED; +-} +- + static void mvsd_enable_sdio_irq(struct mmc_host *mmc, int enable) + { + struct mvsd_host *host = mmc_priv(mmc); +@@ -757,26 +749,11 @@ static int __init mvsd_probe(struct plat + if (!IS_ERR(host->clk)) + clk_prepare_enable(host->clk); + +- if (mvsd_data->gpio_card_detect) { +- ret = devm_gpio_request_one(&pdev->dev, +- mvsd_data->gpio_card_detect, +- GPIOF_IN, DRIVER_NAME " cd"); +- if (ret == 0) { +- irq = gpio_to_irq(mvsd_data->gpio_card_detect); +- ret = devm_request_irq(&pdev->dev, irq, +- mvsd_card_detect_irq, +- IRQ_TYPE_EDGE_RISING | +- IRQ_TYPE_EDGE_FALLING, +- DRIVER_NAME " cd", host); +- if (ret == 0) +- host->gpio_card_detect = +- mvsd_data->gpio_card_detect; +- else +- devm_gpio_free(&pdev->dev, +- mvsd_data->gpio_card_detect); +- } +- } +- if (!host->gpio_card_detect) ++ if (gpio_is_valid(mvsd_data->gpio_card_detect)) { ++ ret = mmc_gpio_request_cd(mmc, mvsd_data->gpio_card_detect); ++ if (ret) ++ goto out; ++ } else + mmc->caps |= MMC_CAP_NEEDS_POLL; + + mmc_gpio_request_ro(mmc, mvsd_data->gpio_write_protect); +@@ -789,15 +766,16 @@ static int __init mvsd_probe(struct plat + + pr_notice("%s: %s driver initialized, ", + mmc_hostname(mmc), DRIVER_NAME); +- if (host->gpio_card_detect) ++ if (!(mmc->caps & MMC_CAP_NEEDS_POLL)) + printk("using GPIO %d for card detection\n", +- host->gpio_card_detect); ++ mvsd_data->gpio_card_detect); + else + printk("lacking card detect (fall back to polling)\n"); + return 0; + + out: + if (mmc) { ++ mmc_gpio_free_cd(mmc); + mmc_gpio_free_ro(mmc); + if (!IS_ERR(host->clk)) + clk_disable_unprepare(host->clk); +@@ -813,6 +791,7 @@ static int __exit mvsd_remove(struct pla + + struct mvsd_host *host = mmc_priv(mmc); + ++ mmc_gpio_free_cd(mmc); + mmc_gpio_free_ro(mmc); + mmc_remove_host(mmc); + del_timer_sync(&host->timer); diff --git a/target/linux/mvebu/patches-3.8/008-mmc_mvsdio_implement_a_device_tree_binding.patch b/target/linux/mvebu/patches-3.8/008-mmc_mvsdio_implement_a_device_tree_binding.patch new file mode 100644 index 000000000..baec5a146 --- /dev/null +++ b/target/linux/mvebu/patches-3.8/008-mmc_mvsdio_implement_a_device_tree_binding.patch @@ -0,0 +1,186 @@ +From patchwork Wed Jan 16 13:13:59 2013 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Subject: [4/5] mmc: mvsdio: implement a Device Tree binding +Date: Wed, 16 Jan 2013 13:13:59 -0000 +From: Andrew Lunn <andrew@lunn.ch> +X-Patchwork-Id: 1987921 +Message-Id: <1358342040-7130-5-git-send-email-andrew@lunn.ch> +To: Jason Cooper <jason@lakedaemon.net> +Cc: linux ARM <linux-arm-kernel@lists.infradead.org>, + linux-mmc@vger.kernel.org, linux@arm.linux.org.uk, + Thomas Petazzoni <thomas.petazzoni@free-electrons.com>, + Andrew Lunn <andrew@lunn.ch> + +From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> + +This patch adds a simple Device Tree binding for the mvsdio driver, as +well as the necessary documentation for it. Compatibility with non-DT +platforms is preserved, by keeping the platform_data based +initialization. + +We introduce a small difference between non-DT and DT platforms: DT +platforms are required to provide a clocks = <...> property, which the +driver uses to get the frequency of the clock that goes to the SDIO +IP. The behaviour on non-DT platforms is kept unchanged: a clock +reference is not mandatory, but the clock frequency must be passed in +the "clock" field of the mvsdio_platform_data structure. + +Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> +Signed-off-by: Andrew Lunn <andrew@lunn.ch> +Tested-by: Stefan Peter <s.peter@mpl.ch> +Tested-by: Florian Fainelli <florian@openwrt.org> +Signed-off-by: Jason Cooper <jason@lakedaemon.net> + +--- +.../devicetree/bindings/mmc/orion-sdio.txt | 17 ++++++ + drivers/mmc/host/mvsdio.c | 62 +++++++++++++++----- + 2 files changed, 64 insertions(+), 15 deletions(-) + create mode 100644 Documentation/devicetree/bindings/mmc/orion-sdio.txt + +--- /dev/null ++++ b/Documentation/devicetree/bindings/mmc/orion-sdio.txt +@@ -0,0 +1,17 @@ ++* Marvell orion-sdio controller ++ ++This file documents differences between the core properties in mmc.txt ++and the properties used by the orion-sdio driver. ++ ++- compatible: Should be "marvell,orion-sdio" ++- clocks: reference to the clock of the SDIO interface ++ ++Example: ++ ++ mvsdio@d00d4000 { ++ compatible = "marvell,orion-sdio"; ++ reg = <0xd00d4000 0x200>; ++ interrupts = <54>; ++ clocks = <&gateclk 17>; ++ status = "disabled"; ++ }; +--- a/drivers/mmc/host/mvsdio.c ++++ b/drivers/mmc/host/mvsdio.c +@@ -21,6 +21,8 @@ + #include <linux/irq.h> + #include <linux/clk.h> + #include <linux/gpio.h> ++#include <linux/of_gpio.h> ++#include <linux/of_irq.h> + #include <linux/mmc/host.h> + #include <linux/mmc/slot-gpio.h> + +@@ -681,17 +683,17 @@ mv_conf_mbus_windows(struct mvsd_host *h + + static int __init mvsd_probe(struct platform_device *pdev) + { ++ struct device_node *np = pdev->dev.of_node; + struct mmc_host *mmc = NULL; + struct mvsd_host *host = NULL; +- const struct mvsdio_platform_data *mvsd_data; + const struct mbus_dram_target_info *dram; + struct resource *r; + int ret, irq; ++ int gpio_card_detect, gpio_write_protect; + + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + irq = platform_get_irq(pdev, 0); +- mvsd_data = pdev->dev.platform_data; +- if (!r || irq < 0 || !mvsd_data) ++ if (!r || irq < 0) + return -ENXIO; + + mmc = mmc_alloc_host(sizeof(struct mvsd_host), &pdev->dev); +@@ -703,8 +705,37 @@ static int __init mvsd_probe(struct plat + host = mmc_priv(mmc); + host->mmc = mmc; + host->dev = &pdev->dev; +- host->base_clock = mvsd_data->clock / 2; +- host->clk = ERR_PTR(-EINVAL); ++ ++ /* Some non-DT platforms do not pass a clock, and the clock ++ frequency is passed through platform_data. On DT platforms, ++ a clock must always be passed, even if there is no gatable ++ clock associated to the SDIO interface (it can simply be a ++ fixed rate clock). */ ++ host->clk = devm_clk_get(&pdev->dev, NULL); ++ if (!IS_ERR(host->clk)) ++ clk_prepare_enable(host->clk); ++ ++ if (np) { ++ if (IS_ERR(host->clk)) { ++ dev_err(&pdev->dev, "DT platforms must have a clock associated\n"); ++ ret = -EINVAL; ++ goto out; ++ } ++ ++ host->base_clock = clk_get_rate(host->clk) / 2; ++ gpio_card_detect = of_get_named_gpio(np, "cd-gpios", 0); ++ gpio_write_protect = of_get_named_gpio(np, "wp-gpios", 0); ++ } else { ++ const struct mvsdio_platform_data *mvsd_data; ++ mvsd_data = pdev->dev.platform_data; ++ if (!mvsd_data) { ++ ret = -ENXIO; ++ goto out; ++ } ++ host->base_clock = mvsd_data->clock / 2; ++ gpio_card_detect = mvsd_data->gpio_card_detect; ++ gpio_write_protect = mvsd_data->gpio_write_protect; ++ } + + mmc->ops = &mvsd_ops; + +@@ -743,20 +774,14 @@ static int __init mvsd_probe(struct plat + goto out; + } + +- /* Not all platforms can gate the clock, so it is not +- an error if the clock does not exists. */ +- host->clk = devm_clk_get(&pdev->dev, NULL); +- if (!IS_ERR(host->clk)) +- clk_prepare_enable(host->clk); +- +- if (gpio_is_valid(mvsd_data->gpio_card_detect)) { +- ret = mmc_gpio_request_cd(mmc, mvsd_data->gpio_card_detect); ++ if (gpio_is_valid(gpio_card_detect)) { ++ ret = mmc_gpio_request_cd(mmc, gpio_card_detect); + if (ret) + goto out; + } else + mmc->caps |= MMC_CAP_NEEDS_POLL; + +- mmc_gpio_request_ro(mmc, mvsd_data->gpio_write_protect); ++ mmc_gpio_request_ro(mmc, gpio_write_protect); + + setup_timer(&host->timer, mvsd_timeout_timer, (unsigned long)host); + platform_set_drvdata(pdev, mmc); +@@ -768,7 +793,7 @@ static int __init mvsd_probe(struct plat + mmc_hostname(mmc), DRIVER_NAME); + if (!(mmc->caps & MMC_CAP_NEEDS_POLL)) + printk("using GPIO %d for card detection\n", +- mvsd_data->gpio_card_detect); ++ gpio_card_detect); + else + printk("lacking card detect (fall back to polling)\n"); + return 0; +@@ -832,12 +857,19 @@ static int mvsd_resume(struct platform_d + #define mvsd_resume NULL + #endif + ++static const struct of_device_id mvsdio_dt_ids[] = { ++ { .compatible = "marvell,orion-sdio" }, ++ { /* sentinel */ } ++}; ++MODULE_DEVICE_TABLE(of, mvsdio_dt_ids); ++ + static struct platform_driver mvsd_driver = { + .remove = __exit_p(mvsd_remove), + .suspend = mvsd_suspend, + .resume = mvsd_resume, + .driver = { + .name = DRIVER_NAME, ++ .of_match_table = mvsdio_dt_ids, + }, + }; + diff --git a/target/linux/mvebu/patches-3.8/009-mmc_mvsdio_add_pinctrl.patch b/target/linux/mvebu/patches-3.8/009-mmc_mvsdio_add_pinctrl.patch new file mode 100644 index 000000000..394ca5b9f --- /dev/null +++ b/target/linux/mvebu/patches-3.8/009-mmc_mvsdio_add_pinctrl.patch @@ -0,0 +1,66 @@ +From patchwork Wed Jan 16 13:14:00 2013 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Subject: [5/5] mmc: mvsdio: add pinctrl integration +Date: Wed, 16 Jan 2013 13:14:00 -0000 +From: Andrew Lunn <andrew@lunn.ch> +X-Patchwork-Id: 1987901 +Message-Id: <1358342040-7130-6-git-send-email-andrew@lunn.ch> +To: Jason Cooper <jason@lakedaemon.net> +Cc: linux ARM <linux-arm-kernel@lists.infradead.org>, + linux-mmc@vger.kernel.org, linux@arm.linux.org.uk, + Thomas Petazzoni <thomas.petazzoni@free-electrons.com>, + Andrew Lunn <andrew@lunn.ch> + +From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> + +On many Marvell SoCs, the pins used for the SDIO interface are part of +the MPP pins, that are muxable pins. In order to get the muxing of +those pins correct, this commit integrates the mvsdio driver with the +pinctrl infrastructure by calling devm_pinctrl_get_select_default() +during ->probe(). + +Note that we permit this function to fail because not all Marvell +platforms have yet been fully converted to using the pinctrl +infrastructure. + +Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> +Signed-off-by: Andrew Lunn <andrew@lunn.ch> +Tested-by: Stefan Peter <s.peter@mpl.ch> +Tested-by: Florian Fainelli <florian@openwrt.org> +Signed-off-by: Jason Cooper <jason@lakedaemon.net> + +--- +drivers/mmc/host/mvsdio.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/drivers/mmc/host/mvsdio.c ++++ b/drivers/mmc/host/mvsdio.c +@@ -25,6 +25,7 @@ + #include <linux/of_irq.h> + #include <linux/mmc/host.h> + #include <linux/mmc/slot-gpio.h> ++#include <linux/pinctrl/consumer.h> + + #include <asm/sizes.h> + #include <asm/unaligned.h> +@@ -690,6 +691,7 @@ static int __init mvsd_probe(struct plat + struct resource *r; + int ret, irq; + int gpio_card_detect, gpio_write_protect; ++ struct pinctrl *pinctrl; + + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + irq = platform_get_irq(pdev, 0); +@@ -706,6 +708,10 @@ static int __init mvsd_probe(struct plat + host->mmc = mmc; + host->dev = &pdev->dev; + ++ pinctrl = devm_pinctrl_get_select_default(&pdev->dev); ++ if (IS_ERR(pinctrl)) ++ dev_warn(&pdev->dev, "no pins associated\n"); ++ + /* Some non-DT platforms do not pass a clock, and the clock + frequency is passed through platform_data. On DT platforms, + a clock must always be passed, even if there is no gatable diff --git a/target/linux/mvebu/patches-3.8/010-arm_mvebu_add_dt_info_a370.patch b/target/linux/mvebu/patches-3.8/010-arm_mvebu_add_dt_info_a370.patch new file mode 100644 index 000000000..bf4d9d4f5 --- /dev/null +++ b/target/linux/mvebu/patches-3.8/010-arm_mvebu_add_dt_info_a370.patch @@ -0,0 +1,26 @@ +Now that the mvsdio MMC driver has a Device Tree binding, we add the +Device Tree informations to describe the SDIO interface available in +the Armada 370/XP SoCs. + +Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> +--- + arch/arm/boot/dts/armada-370-xp.dtsi | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/arch/arm/boot/dts/armada-370-xp.dtsi ++++ b/arch/arm/boot/dts/armada-370-xp.dtsi +@@ -131,6 +131,14 @@ + clocks = <&coreclk 0>; + status = "disabled"; + }; ++ ++ mvsdio@d00d4000 { ++ compatible = "marvell,orion-sdio"; ++ reg = <0xd00d4000 0x200>; ++ interrupts = <54>; ++ clocks = <&gateclk 17>; ++ status = "disabled"; ++ }; + }; + }; + diff --git a/target/linux/mvebu/patches-3.8/011-arm_mvebu_add_pin_mux_options_a370.patch b/target/linux/mvebu/patches-3.8/011-arm_mvebu_add_pin_mux_options_a370.patch new file mode 100644 index 000000000..4072ae50c --- /dev/null +++ b/target/linux/mvebu/patches-3.8/011-arm_mvebu_add_pin_mux_options_a370.patch @@ -0,0 +1,34 @@ +The SDIO interface is available either on pins MPP9/11/12/13/14/15 or +MPP47/48/49/50/51/52 on the Armada 370. Even though all combinations +are potentially possible, those two muxing options are the most +probable ones, so we provide those at the SoC level .dtsi file. + +In practice, in turns out the Armada 370 DB board uses the former, +while the Armada 370 Mirabox uses the latter. + +Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> +--- + arch/arm/boot/dts/armada-370.dtsi | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +--- a/arch/arm/boot/dts/armada-370.dtsi ++++ b/arch/arm/boot/dts/armada-370.dtsi +@@ -47,6 +47,18 @@ + pinctrl { + compatible = "marvell,mv88f6710-pinctrl"; + reg = <0xd0018000 0x38>; ++ ++ sdio_pins1: sdio-pins1 { ++ marvell,pins = "mpp9", "mpp11", "mpp12", ++ "mpp13", "mpp14", "mpp15"; ++ marvell,function = "sd0"; ++ }; ++ ++ sdio_pins2: sdio-pins2 { ++ marvell,pins = "mpp47", "mpp48", "mpp49", ++ "mpp50", "mpp51", "mpp52"; ++ marvell,function = "sd0"; ++ }; + }; + + gpio0: gpio@d0018100 { diff --git a/target/linux/mvebu/patches-3.8/012-arm_mvebu_add_pin_mux_options_axp.patch b/target/linux/mvebu/patches-3.8/012-arm_mvebu_add_pin_mux_options_axp.patch new file mode 100644 index 000000000..716971dff --- /dev/null +++ b/target/linux/mvebu/patches-3.8/012-arm_mvebu_add_pin_mux_options_axp.patch @@ -0,0 +1,61 @@ +The SDIO interface is only available on pins MPP30/31/32/33/34/35 on +the various Armada XP variants, so we provide a pin muxing option for +this in the Armada XP .dtsi files. + +Even though those muxing options are the same for MV78230, MV78260 and +MV78460, we keep them in each .dtsi file, because the number of pins, +and therefore the declaration of the pinctrl node, is different for +each SoC variant. + +Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> +--- + arch/arm/boot/dts/armada-xp-mv78230.dtsi | 6 ++++++ + arch/arm/boot/dts/armada-xp-mv78260.dtsi | 6 ++++++ + arch/arm/boot/dts/armada-xp-mv78460.dtsi | 6 ++++++ + 3 files changed, 18 insertions(+) + +--- a/arch/arm/boot/dts/armada-xp-mv78230.dtsi ++++ b/arch/arm/boot/dts/armada-xp-mv78230.dtsi +@@ -47,6 +47,12 @@ + pinctrl { + compatible = "marvell,mv78230-pinctrl"; + reg = <0xd0018000 0x38>; ++ ++ sdio_pins: sdio-pins { ++ marvell,pins = "mpp30", "mpp31", "mpp32", ++ "mpp33", "mpp34", "mpp35"; ++ marvell,function = "sd0"; ++ }; + }; + + gpio0: gpio@d0018100 { +--- a/arch/arm/boot/dts/armada-xp-mv78260.dtsi ++++ b/arch/arm/boot/dts/armada-xp-mv78260.dtsi +@@ -48,6 +48,12 @@ + pinctrl { + compatible = "marvell,mv78260-pinctrl"; + reg = <0xd0018000 0x38>; ++ ++ sdio_pins: sdio-pins { ++ marvell,pins = "mpp30", "mpp31", "mpp32", ++ "mpp33", "mpp34", "mpp35"; ++ marvell,function = "sd0"; ++ }; + }; + + gpio0: gpio@d0018100 { +--- a/arch/arm/boot/dts/armada-xp-mv78460.dtsi ++++ b/arch/arm/boot/dts/armada-xp-mv78460.dtsi +@@ -63,6 +63,12 @@ + pinctrl { + compatible = "marvell,mv78460-pinctrl"; + reg = <0xd0018000 0x38>; ++ ++ sdio_pins: sdio-pins { ++ marvell,pins = "mpp30", "mpp31", "mpp32", ++ "mpp33", "mpp34", "mpp35"; ++ marvell,function = "sd0"; ++ }; + }; + + gpio0: gpio@d0018100 { diff --git a/target/linux/mvebu/patches-3.8/013-arm_mvebu_enable_sd_cart_slot_axp_db.patch b/target/linux/mvebu/patches-3.8/013-arm_mvebu_enable_sd_cart_slot_axp_db.patch new file mode 100644 index 000000000..5a6faf9d9 --- /dev/null +++ b/target/linux/mvebu/patches-3.8/013-arm_mvebu_enable_sd_cart_slot_axp_db.patch @@ -0,0 +1,25 @@ +The Armada XP DB evaluation board has one SD card slot, directly +connected to the SDIO IP of the SoC, so we enable this +IP. Unfortunately, there are no GPIOs for card-detect and +write-protect. + +Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> +--- + arch/arm/boot/dts/armada-xp-db.dts | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/arch/arm/boot/dts/armada-xp-db.dts ++++ b/arch/arm/boot/dts/armada-xp-db.dts +@@ -90,5 +90,12 @@ + phy = <&phy3>; + phy-mode = "sgmii"; + }; ++ ++ mvsdio@d00d4000 { ++ pinctrl-0 = <&sdio_pins>; ++ pinctrl-names = "default"; ++ status = "okay"; ++ /* No CD or WP GPIOs */ ++ }; + }; + }; diff --git a/target/linux/mvebu/patches-3.8/014-arm_mvebu_enable_sd_card_slot_a370_db.patch b/target/linux/mvebu/patches-3.8/014-arm_mvebu_enable_sd_card_slot_a370_db.patch new file mode 100644 index 000000000..d9214163c --- /dev/null +++ b/target/linux/mvebu/patches-3.8/014-arm_mvebu_enable_sd_card_slot_a370_db.patch @@ -0,0 +1,41 @@ +The Armada XP DB evaluation board has one SD card slot, directly +connected to the SDIO IP of the SoC, so we add a device tree +description for it. + +However, in the default configuration of the board, the SD card slot +is not usable: the connector plugged into CON40 must be changed +against a different one, provided with the board by the +manufacturer. Since such a manual modification of the hardware is +needed, we did not enable the SDIO interface by default, and left it +to the board user to modify the Device Tree if needed. Since this +board is really only an evaluation board for developers and not a +final product, it is not too bad. + +Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> +--- + arch/arm/boot/dts/armada-370-db.dts | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +--- a/arch/arm/boot/dts/armada-370-db.dts ++++ b/arch/arm/boot/dts/armada-370-db.dts +@@ -59,5 +59,20 @@ + phy = <&phy1>; + phy-mode = "rgmii-id"; + }; ++ ++ mvsdio@d00d4000 { ++ pinctrl-0 = <&sdio_pins1>; ++ pinctrl-names = "default"; ++ /* ++ * This device is disabled by default, because ++ * using the SD card connector requires ++ * changing the default CON40 connector ++ * "DB-88F6710_MPP_2xRGMII_DEVICE_Jumper" to a ++ * different connector ++ * "DB-88F6710_MPP_RGMII_SD_Jumper". ++ */ ++ status = "disabled"; ++ /* No CD or WP GPIOs */ ++ }; + }; + }; diff --git a/target/linux/mvebu/patches-3.8/015-arm_mvebu_enable_sd_card_slot_mirabox.patch b/target/linux/mvebu/patches-3.8/015-arm_mvebu_enable_sd_card_slot_mirabox.patch new file mode 100644 index 000000000..0cf6ee410 --- /dev/null +++ b/target/linux/mvebu/patches-3.8/015-arm_mvebu_enable_sd_card_slot_mirabox.patch @@ -0,0 +1,27 @@ +The Globalscale Mirabox uses the SDIO interface of the Armada 370 to +connect to a Wifi/Bluetooth SD8787 chip, so we enable the SDIO +interface of this board in its Device Tree file. + +Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> +--- + arch/arm/boot/dts/armada-370-mirabox.dts | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +--- a/arch/arm/boot/dts/armada-370-mirabox.dts ++++ b/arch/arm/boot/dts/armada-370-mirabox.dts +@@ -52,5 +52,15 @@ + phy = <&phy1>; + phy-mode = "rgmii-id"; + }; ++ ++ mvsdio@d00d4000 { ++ pinctrl-0 = <&sdio_pins2>; ++ pinctrl-names = "default"; ++ status = "okay"; ++ /* ++ * No CD or WP GPIOs: SDIO interface used for ++ * Wifi/Bluetooth chip ++ */ ++ }; + }; + }; diff --git a/target/linux/mvebu/patches-3.8/019-rtc_add_support_for_rtc_mv_for_mvebu.patch b/target/linux/mvebu/patches-3.8/019-rtc_add_support_for_rtc_mv_for_mvebu.patch new file mode 100644 index 000000000..373058ae5 --- /dev/null +++ b/target/linux/mvebu/patches-3.8/019-rtc_add_support_for_rtc_mv_for_mvebu.patch @@ -0,0 +1,21 @@ +The Armada 370 and Armada XP Socs have the same controller that the +one used in the orion platforms. This patch enables the selection of +rtc-mv with mvebu platforms. + +Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com> +Acked-by: Andrew Lunn <andrew@lunn.ch> +--- + drivers/rtc/Kconfig | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/rtc/Kconfig ++++ b/drivers/rtc/Kconfig +@@ -1041,7 +1041,7 @@ config RTC_DRV_TX4939 + + config RTC_DRV_MV + tristate "Marvell SoC RTC" +- depends on ARCH_KIRKWOOD || ARCH_DOVE ++ depends on ARCH_KIRKWOOD || ARCH_DOVE || ARCH_MVEBU + help + If you say yes here you will get support for the in-chip RTC + that can be found in some of Marvell's SoC devices, such as diff --git a/target/linux/mvebu/patches-3.8/020-arm_mvebu_add_rtc_support_for_a370_and_axp.patch b/target/linux/mvebu/patches-3.8/020-arm_mvebu_add_rtc_support_for_a370_and_axp.patch new file mode 100644 index 000000000..307e81546 --- /dev/null +++ b/target/linux/mvebu/patches-3.8/020-arm_mvebu_add_rtc_support_for_a370_and_axp.patch @@ -0,0 +1,25 @@ +The Armada 370 and Armada XP Socs have the same controller that the +one used in the orion platforms. This patch updates the device tree +for these SoCs. + +Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com> +Acked-by: Andrew Lunn <andrew@lunn.ch> +--- + arch/arm/boot/dts/armada-370-xp.dtsi | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/arch/arm/boot/dts/armada-370-xp.dtsi ++++ b/arch/arm/boot/dts/armada-370-xp.dtsi +@@ -139,6 +139,12 @@ + clocks = <&gateclk 17>; + status = "disabled"; + }; ++ ++ rtc@10300 { ++ compatible = "marvell,orion-rtc"; ++ reg = <0xd0010300 0x20>; ++ interrupts = <50>; ++ }; + }; + }; + diff --git a/target/linux/mvebu/patches-3.8/021-arm_mvebu_add_rd_a370_a1_dts.patch b/target/linux/mvebu/patches-3.8/021-arm_mvebu_add_rd_a370_a1_dts.patch new file mode 100644 index 000000000..6f52500e3 --- /dev/null +++ b/target/linux/mvebu/patches-3.8/021-arm_mvebu_add_rd_a370_a1_dts.patch @@ -0,0 +1,91 @@ +From fcc7654b592cb80cfb33c509db1005ce9252192b Mon Sep 17 00:00:00 2001 +From: Florian Fainelli <florian@openwrt.org> +Date: Wed, 9 Jan 2013 20:39:55 +0100 +Subject: [PATCH] arm: mvebu: add DTS file for Marvell RD-A370-A1 board + +This patch adds the DTS file to support the Marvell RD-A370-A1 +(Reference Design board) also known as RD-88F6710 board. It is almost +entirely similar to the DB-A370 board except that the first Ethernet PHY +is SGMII-wired and the second is a switch which is RGMII-wired. + +Signed-off-by: Florian Fainelli <florian@openwrt.org> +--- + arch/arm/boot/dts/Makefile | 1 + + arch/arm/boot/dts/armada-370-rd.dts | 61 +++++++++++++++++++++++++++++++++++ + 2 files changed, 62 insertions(+) + create mode 100644 arch/arm/boot/dts/armada-370-rd.dts + +--- a/arch/arm/boot/dts/Makefile ++++ b/arch/arm/boot/dts/Makefile +@@ -77,6 +77,7 @@ dtb-$(CONFIG_ARCH_MSM) += msm8660-surf.d + msm8960-cdp.dtb + dtb-$(CONFIG_ARCH_MVEBU) += armada-370-db.dtb \ + armada-370-mirabox.dtb \ ++ armada-370-rd.dtb \ + armada-xp-db.dtb \ + armada-xp-openblocks-ax3-4.dtb + dtb-$(CONFIG_ARCH_MXC) += imx51-babbage.dtb \ +--- /dev/null ++++ b/arch/arm/boot/dts/armada-370-rd.dts +@@ -0,0 +1,61 @@ ++/* ++ * Device Tree file for Marvell Armada 370 Reference Design board ++ * (RD-88F6710-A1) ++ * ++ * Copied from arch/arm/boot/dts/armada-370-db.dts ++ * ++ * Copyright (C) 2013 Florian Fainelli <florian@openwrt.org> ++ * ++ * This file is licensed under the terms of the GNU General Public ++ * License version 2. This program is licensed "as is" without any ++ * warranty of any kind, whether express or implied. ++ */ ++ ++/dts-v1/; ++/include/ "armada-370.dtsi" ++ ++/ { ++ model = "Marvell Armada 370 Reference Design"; ++ compatible = "marvell,a370-rd", "marvell,armada370", "marvell,armada-370-xp"; ++ ++ chosen { ++ bootargs = "console=ttyS0,115200 earlyprintk"; ++ }; ++ ++ memory { ++ device_type = "memory"; ++ reg = <0x00000000 0x20000000>; /* 512 MB */ ++ }; ++ ++ soc { ++ serial@d0012000 { ++ clock-frequency = <200000000>; ++ status = "okay"; ++ }; ++ sata@d00a0000 { ++ nr-ports = <2>; ++ status = "okay"; ++ }; ++ ++ mdio { ++ phy0: ethernet-phy@0 { ++ reg = <0>; ++ }; ++ ++ phy1: ethernet-phy@1 { ++ reg = <1>; ++ }; ++ }; ++ ++ ethernet@d0070000 { ++ status = "okay"; ++ phy = <&phy0>; ++ phy-mode = "sgmii"; ++ }; ++ ethernet@d0074000 { ++ status = "okay"; ++ phy = <&phy1>; ++ phy-mode = "rgmii-id"; ++ }; ++ }; ++}; diff --git a/target/linux/mvebu/patches-3.8/022-arm_mvebu_enable_sd_card_slot_a370_rd.patch b/target/linux/mvebu/patches-3.8/022-arm_mvebu_enable_sd_card_slot_a370_rd.patch new file mode 100644 index 000000000..439711aae --- /dev/null +++ b/target/linux/mvebu/patches-3.8/022-arm_mvebu_enable_sd_card_slot_a370_rd.patch @@ -0,0 +1,27 @@ +From 883b6ab543ea3f893447307c0e757668ca1b5396 Mon Sep 17 00:00:00 2001 +From: Florian Fainelli <florian@openwrt.org> +Date: Wed, 9 Jan 2013 20:50:04 +0100 +Subject: [PATCH] arm: mvebu: add SDIO support to Armada 370 Reference Design + +This patch enables the use of the SDIO controller on the Armada 370 +Reference Design board. + +Signed-off-by: Florian Fainelli <florian@openwrt.org> +--- + arch/arm/boot/dts/armada-370-rd.dts | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/arch/arm/boot/dts/armada-370-rd.dts ++++ b/arch/arm/boot/dts/armada-370-rd.dts +@@ -57,5 +57,11 @@ + phy = <&phy1>; + phy-mode = "rgmii-id"; + }; ++ ++ mvsdio@d00d4000 { ++ pinctrl-0 = <&sdio_pins1>; ++ pinctrl-names = "default"; ++ status = "okay"; ++ }; + }; + }; diff --git a/target/linux/mvebu/patches-3.8/023-arm_mvebu_add_support_for_usb_host.patch b/target/linux/mvebu/patches-3.8/023-arm_mvebu_add_support_for_usb_host.patch new file mode 100644 index 000000000..1484c08ee --- /dev/null +++ b/target/linux/mvebu/patches-3.8/023-arm_mvebu_add_support_for_usb_host.patch @@ -0,0 +1,91 @@ +The Armada 370 and Armada XP SoC has an Orion EHCI USB controller. +This patch adds support for this controller in Armada 370 +and Armada XP SoC common device tree files. + +Cc: Lior Amsalem <alior@marvell.com> +Cc: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> +Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com> +Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com> +--- + arch/arm/boot/dts/armada-370-xp.dtsi | 15 +++++++++++++++ + arch/arm/boot/dts/armada-370.dtsi | 9 +++++++++ + arch/arm/boot/dts/armada-xp.dtsi | 17 +++++++++++++++++ + arch/arm/mach-mvebu/Kconfig | 1 + + 4 files changed, 42 insertions(+), 0 deletions(-) + +--- a/arch/arm/boot/dts/armada-370-xp.dtsi ++++ b/arch/arm/boot/dts/armada-370-xp.dtsi +@@ -145,6 +145,21 @@ + reg = <0xd0010300 0x20>; + interrupts = <50>; + }; ++ ++ usb@d0050000 { ++ compatible = "marvell,orion-ehci"; ++ reg = <0xd0050000 0x500>; ++ interrupts = <45>; ++ status = "disabled"; ++ }; ++ ++ usb@d0051000 { ++ compatible = "marvell,orion-ehci"; ++ reg = <0xd0051000 0x500>; ++ interrupts = <46>; ++ status = "disabled"; ++ }; ++ + }; + }; + +--- a/arch/arm/boot/dts/armada-370.dtsi ++++ b/arch/arm/boot/dts/armada-370.dtsi +@@ -144,5 +144,14 @@ + dmacap,memset; + }; + }; ++ ++ usb@d0050000 { ++ clocks = <&coreclk 0>; ++ }; ++ ++ usb@d0051000 { ++ clocks = <&coreclk 0>; ++ }; ++ + }; + }; +--- a/arch/arm/boot/dts/armada-xp.dtsi ++++ b/arch/arm/boot/dts/armada-xp.dtsi +@@ -134,5 +134,22 @@ + dmacap,memset; + }; + }; ++ ++ usb@d0050000 { ++ clocks = <&gateclk 18>; ++ }; ++ ++ usb@d0051000 { ++ clocks = <&gateclk 19>; ++ }; ++ ++ usb@d0052000 { ++ compatible = "marvell,orion-ehci"; ++ reg = <0xd0052000 0x500>; ++ interrupts = <47>; ++ clocks = <&gateclk 20>; ++ status = "disabled"; ++ }; ++ + }; + }; +--- a/arch/arm/mach-mvebu/Kconfig ++++ b/arch/arm/mach-mvebu/Kconfig +@@ -24,6 +24,7 @@ config MACH_ARMADA_370_XP + select HAVE_SMP + select CACHE_L2X0 + select CPU_PJ4B ++ select USB_ARCH_HAS_EHCI if USB_SUPPORT + + config MACH_ARMADA_370 + bool "Marvell Armada 370 boards" diff --git a/target/linux/mvebu/patches-3.8/024-arm_mvebu_enable_usb_a370.patch b/target/linux/mvebu/patches-3.8/024-arm_mvebu_enable_usb_a370.patch new file mode 100644 index 000000000..1a20a144b --- /dev/null +++ b/target/linux/mvebu/patches-3.8/024-arm_mvebu_enable_usb_a370.patch @@ -0,0 +1,24 @@ +Cc: Lior Amsalem <alior@marvell.com> +Cc: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> +Cc: Gregory CLEMENT <gregory.clement@free-electrons.com> +Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com> +--- + arch/arm/boot/dts/armada-370-db.dts | 8 ++++++++ + 1 files changed, 8 insertions(+), 0 deletions(-) + +--- a/arch/arm/boot/dts/armada-370-db.dts ++++ b/arch/arm/boot/dts/armada-370-db.dts +@@ -74,5 +74,13 @@ + status = "disabled"; + /* No CD or WP GPIOs */ + }; ++ ++ usb@d0050000 { ++ status = "okay"; ++ }; ++ ++ usb@d0051000 { ++ status = "okay"; ++ }; + }; + }; diff --git a/target/linux/mvebu/patches-3.8/025-arm_mvebu_enable_usb_a370_mirabox.patch b/target/linux/mvebu/patches-3.8/025-arm_mvebu_enable_usb_a370_mirabox.patch new file mode 100644 index 000000000..82d059eb7 --- /dev/null +++ b/target/linux/mvebu/patches-3.8/025-arm_mvebu_enable_usb_a370_mirabox.patch @@ -0,0 +1,24 @@ +Cc: Lior Amsalem <alior@marvell.com> +Cc: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> +Cc: Gregory CLEMENT <gregory.clement@free-electrons.com> +Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com> +--- + arch/arm/boot/dts/armada-370-mirabox.dts | 8 ++++++++ + 1 files changed, 8 insertions(+), 0 deletions(-) + +--- a/arch/arm/boot/dts/armada-370-mirabox.dts ++++ b/arch/arm/boot/dts/armada-370-mirabox.dts +@@ -62,5 +62,13 @@ + * Wifi/Bluetooth chip + */ + }; ++ ++ usb@d0050000 { ++ status = "okay"; ++ }; ++ ++ usb@d0051000 { ++ status = "okay"; ++ }; + }; + }; diff --git a/target/linux/mvebu/patches-3.8/026-arm_mvebu_enale_usb_axp.patch b/target/linux/mvebu/patches-3.8/026-arm_mvebu_enale_usb_axp.patch new file mode 100644 index 000000000..f3851b039 --- /dev/null +++ b/target/linux/mvebu/patches-3.8/026-arm_mvebu_enale_usb_axp.patch @@ -0,0 +1,28 @@ +Cc: Lior Amsalem <alior@marvell.com> +Cc: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> +Cc: Gregory CLEMENT <gregory.clement@free-electrons.com> +Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com> +--- + arch/arm/boot/dts/armada-xp-db.dts | 12 ++++++++++++ + 1 files changed, 12 insertions(+), 0 deletions(-) + +--- a/arch/arm/boot/dts/armada-xp-db.dts ++++ b/arch/arm/boot/dts/armada-xp-db.dts +@@ -97,5 +97,17 @@ + status = "okay"; + /* No CD or WP GPIOs */ + }; ++ ++ usb@d0050000 { ++ status = "okay"; ++ }; ++ ++ usb@d0051000 { ++ status = "okay"; ++ }; ++ ++ usb@d0052000 { ++ status = "okay"; ++ }; + }; + }; diff --git a/target/linux/mvebu/patches-3.8/027-arm_mvebu_enable_axp_openblocks.patch b/target/linux/mvebu/patches-3.8/027-arm_mvebu_enable_axp_openblocks.patch new file mode 100644 index 000000000..2078260d6 --- /dev/null +++ b/target/linux/mvebu/patches-3.8/027-arm_mvebu_enable_axp_openblocks.patch @@ -0,0 +1,25 @@ +Cc: Lior Amsalem <alior@marvell.com> +Cc: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> +Cc: Gregory CLEMENT <gregory.clement@free-electrons.com> +Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com> +--- + arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts | 9 +++++++++ + 1 files changed, 9 insertions(+), 0 deletions(-) + +--- a/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts ++++ b/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts +@@ -121,5 +121,14 @@ + nr-ports = <2>; + status = "okay"; + }; ++ usb@d0050000 { ++ status = "okay"; ++ }; ++ usb@d0051000 { ++ status = "okay"; ++ }; ++ usb@d0052000 { ++ status = "okay"; ++ }; + }; + }; diff --git a/target/linux/mvebu/patches-3.8/028-lib_devres_dont_enclose_pcim.patch b/target/linux/mvebu/patches-3.8/028-lib_devres_dont_enclose_pcim.patch new file mode 100644 index 000000000..3cde2a308 --- /dev/null +++ b/target/linux/mvebu/patches-3.8/028-lib_devres_dont_enclose_pcim.patch @@ -0,0 +1,28 @@ +The pcim_*() functions are used by the libata-sff subsystem, and this +subsystem is used for many SATA drivers on ARM platforms that do not +necessarily have I/O ports. + +Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> +Cc: Paul Gortmaker <paul.gortmaker@windriver.com> +Cc: Jesse Barnes <jbarnes@virtuousgeek.org> +Cc: Yinghai Lu <yinghai@kernel.org> +Cc: linux-kernel@vger.kernel.org +--- + lib/devres.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/lib/devres.c ++++ b/lib/devres.c +@@ -226,6 +226,7 @@ void devm_ioport_unmap(struct device *de + devm_ioport_map_match, (void *)addr)); + } + EXPORT_SYMBOL(devm_ioport_unmap); ++#endif /* CONFIG_HAS_IOPORT */ + + #ifdef CONFIG_PCI + /* +@@ -431,4 +432,3 @@ void pcim_iounmap_regions(struct pci_dev + } + EXPORT_SYMBOL(pcim_iounmap_regions); + #endif /* CONFIG_PCI */ +-#endif /* CONFIG_HAS_IOPORT */ diff --git a/target/linux/mvebu/patches-3.8/029-clk_mvebu_create_parent_child_relation.patch b/target/linux/mvebu/patches-3.8/029-clk_mvebu_create_parent_child_relation.patch new file mode 100644 index 000000000..2cccc0357 --- /dev/null +++ b/target/linux/mvebu/patches-3.8/029-clk_mvebu_create_parent_child_relation.patch @@ -0,0 +1,24 @@ +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 }, diff --git a/target/linux/mvebu/patches-3.8/030-arm_plat_orion_introduce_win_ctrl_enable.patch b/target/linux/mvebu/patches-3.8/030-arm_plat_orion_introduce_win_ctrl_enable.patch new file mode 100644 index 000000000..9a237ec9b --- /dev/null +++ b/target/linux/mvebu/patches-3.8/030-arm_plat_orion_introduce_win_ctrl_enable.patch @@ -0,0 +1,28 @@ +Instead of hardcoding "1" as being the bit value to enable an address +decoding window, introduce and use a WIN_CTRL_ENABLE definition. + +Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> +--- + arch/arm/plat-orion/addr-map.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/arch/arm/plat-orion/addr-map.c ++++ b/arch/arm/plat-orion/addr-map.c +@@ -38,6 +38,7 @@ EXPORT_SYMBOL_GPL(mv_mbus_dram_info); + * CPU Address Decode Windows registers + */ + #define WIN_CTRL_OFF 0x0000 ++#define WIN_CTRL_ENABLE BIT(0) + #define WIN_BASE_OFF 0x0004 + #define WIN_REMAP_LO_OFF 0x0008 + #define WIN_REMAP_HI_OFF 0x000c +@@ -79,7 +80,8 @@ void __init orion_setup_cpu_win(const st + } + + base_high = base & 0xffff0000; +- ctrl = ((size - 1) & 0xffff0000) | (attr << 8) | (target << 4) | 1; ++ ctrl = ((size - 1) & 0xffff0000) | (attr << 8) | (target << 4) | ++ WIN_CTRL_ENABLE; + + writel(base_high, addr + WIN_BASE_OFF); + writel(ctrl, addr + WIN_CTRL_OFF); diff --git a/target/linux/mvebu/patches-3.8/031-arm_plat_orion_refactor.patch b/target/linux/mvebu/patches-3.8/031-arm_plat_orion_refactor.patch new file mode 100644 index 000000000..fe9f6285f --- /dev/null +++ b/target/linux/mvebu/patches-3.8/031-arm_plat_orion_refactor.patch @@ -0,0 +1,80 @@ +In the address decoding code, the orion_disable_wins() function is +used at boot time to disable all address decoding windows, before +configuring only the ones that are needed. This allows to make sure +that no configuration is left from the bootloader. + +As a preparation for the introduction of address decoding window +allocation/deallocation function, we refactor this function into an +orion_disable_cpu_win() which disables a single window. + +The orion_config_wins() function is changed to call +orion_disable_cpu_win() in a loop, to preserve an identical behavior. + +Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> +--- + arch/arm/plat-orion/addr-map.c | 35 +++++++++++++++++------------------ + 1 file changed, 17 insertions(+), 18 deletions(-) + +--- a/arch/arm/plat-orion/addr-map.c ++++ b/arch/arm/plat-orion/addr-map.c +@@ -95,6 +95,19 @@ void __init orion_setup_cpu_win(const st + } + } + ++static void __init orion_disable_cpu_win(const struct orion_addr_map_cfg *cfg, ++ const int win) ++{ ++ void __iomem *addr = cfg->win_cfg_base(cfg, win); ++ ++ writel(0, addr + WIN_BASE_OFF); ++ writel(0, addr + WIN_CTRL_OFF); ++ if (cfg->cpu_win_can_remap(cfg, win)) { ++ writel(0, addr + WIN_REMAP_LO_OFF); ++ writel(0, addr + WIN_REMAP_HI_OFF); ++ } ++} ++ + /* + * Configure a number of windows. + */ +@@ -108,36 +121,22 @@ static void __init orion_setup_cpu_wins( + } + } + +-static void __init orion_disable_wins(const struct orion_addr_map_cfg * cfg) +-{ +- void __iomem *addr; +- int i; +- +- for (i = 0; i < cfg->num_wins; i++) { +- addr = cfg->win_cfg_base(cfg, i); +- +- writel(0, addr + WIN_BASE_OFF); +- writel(0, addr + WIN_CTRL_OFF); +- if (cfg->cpu_win_can_remap(cfg, i)) { +- writel(0, addr + WIN_REMAP_LO_OFF); +- writel(0, addr + WIN_REMAP_HI_OFF); +- } +- } +-} +- + /* + * Disable, clear and configure windows. + */ + void __init orion_config_wins(struct orion_addr_map_cfg * cfg, + const struct orion_addr_map_info *info) + { ++ int win; ++ + if (!cfg->cpu_win_can_remap) + cfg->cpu_win_can_remap = orion_cpu_win_can_remap; + + if (!cfg->win_cfg_base) + cfg->win_cfg_base = orion_win_cfg_base; + +- orion_disable_wins(cfg); ++ for (win = 0; win < cfg->num_wins; win++) ++ orion_disable_cpu_win(cfg, win); + + if (info) + orion_setup_cpu_wins(cfg, info); diff --git a/target/linux/mvebu/patches-3.8/032-arm_plat_orion_introduce_orion_alloc_free_cpu_win.patch b/target/linux/mvebu/patches-3.8/032-arm_plat_orion_introduce_orion_alloc_free_cpu_win.patch new file mode 100644 index 000000000..91ed678b2 --- /dev/null +++ b/target/linux/mvebu/patches-3.8/032-arm_plat_orion_introduce_orion_alloc_free_cpu_win.patch @@ -0,0 +1,96 @@ +In the address decoding code, we implement two new functions: +orion_alloc_cpu_win() and orion_free_cpu_win(). The first function +finds an unused address decoding window, and configures it according +to the given arguments (in terms of base address, size, target, +attributes). The second function frees an address decoding window, +given a physical base address. + +Those two new functions will be used by the PCIe code, which needs to +dynamically register address decoding windows depending on the PCIe +devices that are detected. + +The orion_free_cpu_win() function is only here to handle error cases +in the PCIe devices initialization, in the normal case, address +decoding windows are never freed. + +Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> +--- + arch/arm/plat-orion/addr-map.c | 50 +++++++++++++++++++++++++++ + arch/arm/plat-orion/include/plat/addr-map.h | 7 ++++ + 2 files changed, 57 insertions(+) + +--- a/arch/arm/plat-orion/addr-map.c ++++ b/arch/arm/plat-orion/addr-map.c +@@ -109,6 +109,56 @@ static void __init orion_disable_cpu_win + } + + /* ++ * Find an unused address decoding window, and enable it according to ++ * the arguments passed (base, size, target, attributes, remap). ++ */ ++int __init orion_alloc_cpu_win(const struct orion_addr_map_cfg *cfg, ++ const u32 base, const u32 size, ++ const u8 target, const u8 attr, const int remap) ++{ ++ int win; ++ ++ for (win = 0; win < cfg->num_wins; win++) { ++ void __iomem *addr = cfg->win_cfg_base(cfg, win); ++ u32 ctrl = readl(addr + WIN_CTRL_OFF); ++ if (!(ctrl & WIN_CTRL_ENABLE)) ++ break; ++ } ++ ++ /* No more windows available */ ++ if (win == cfg->num_wins) ++ return -ENOMEM; ++ ++ orion_setup_cpu_win(cfg, win, base, size, target, attr, remap); ++ return 0; ++} ++ ++/* ++ * Free an address decoding window, given its base address. ++ */ ++int __init orion_free_cpu_win(const struct orion_addr_map_cfg *cfg, ++ const u32 base) ++{ ++ int win; ++ ++ for (win = 0; win < cfg->num_wins; win++) { ++ void __iomem *addr = cfg->win_cfg_base(cfg, win); ++ u32 winbase = readl(addr + WIN_BASE_OFF); ++ u32 ctrl = readl(addr + WIN_CTRL_OFF); ++ ++ if (!(ctrl & WIN_CTRL_ENABLE)) ++ continue; ++ ++ if (winbase == (base & 0xffff0000)) { ++ orion_disable_cpu_win(cfg, win); ++ return 0; ++ } ++ } ++ ++ return -EINVAL; ++} ++ ++/* + * Configure a number of windows. + */ + static void __init orion_setup_cpu_wins(const struct orion_addr_map_cfg * cfg, +--- a/arch/arm/plat-orion/include/plat/addr-map.h ++++ b/arch/arm/plat-orion/include/plat/addr-map.h +@@ -49,6 +49,13 @@ void __init orion_setup_cpu_win(const st + const u32 size, const u8 target, + const u8 attr, const int remap); + ++int __init orion_alloc_cpu_win(const struct orion_addr_map_cfg *cfg, ++ const u32 base, const u32 size, ++ const u8 target, const u8 attr, const int remap); ++ ++int __init orion_free_cpu_win(const struct orion_addr_map_cfg *cfg, ++ const u32 base); ++ + void __init orion_setup_cpu_mbus_target(const struct orion_addr_map_cfg *cfg, + const void __iomem *ddr_window_cpu_base); + #endif diff --git a/target/linux/mvebu/patches-3.8/033-arm_mvebu_add_functions_to_alloc_free_pcie.patch b/target/linux/mvebu/patches-3.8/033-arm_mvebu_add_functions_to_alloc_free_pcie.patch new file mode 100644 index 000000000..fd3c1af92 --- /dev/null +++ b/target/linux/mvebu/patches-3.8/033-arm_mvebu_add_functions_to_alloc_free_pcie.patch @@ -0,0 +1,201 @@ +This commit adds two functions armada_370_xp_alloc_pcie_window() and +armada_370_xp_free_pcie_window() that respectively allocate and free +an address decoding window pointing to either a memory or I/O region +of a PCIe device. + +Those functions will be used by the PCIe driver to create and remove +those regions depending on the PCIe devices that are detected. + +Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> +--- + arch/arm/mach-mvebu/addr-map.c | 156 ++++++++++++++++++++++++++++++++++++++-- + arch/arm/mach-mvebu/common.h | 4 ++ + 2 files changed, 156 insertions(+), 4 deletions(-) + +--- a/arch/arm/mach-mvebu/addr-map.c ++++ b/arch/arm/mach-mvebu/addr-map.c +@@ -24,14 +24,10 @@ + #define ARMADA_XP_TARGET_DEV_BUS 1 + #define ARMADA_XP_ATTR_DEV_BOOTROM 0x1D + #define ARMADA_XP_TARGET_ETH1 3 +-#define ARMADA_XP_TARGET_PCIE_0_2 4 + #define ARMADA_XP_TARGET_ETH0 7 +-#define ARMADA_XP_TARGET_PCIE_1_3 8 + + #define ARMADA_370_TARGET_DEV_BUS 1 + #define ARMADA_370_ATTR_DEV_BOOTROM 0x1D +-#define ARMADA_370_TARGET_PCIE_0 4 +-#define ARMADA_370_TARGET_PCIE_1 8 + + #define ARMADA_WINDOW_8_PLUS_OFFSET 0x90 + #define ARMADA_SDRAM_ADDR_DECODING_OFFSET 0x180 +@@ -89,6 +85,158 @@ static struct __initdata orion_addr_map_ + .win_cfg_base = armada_cfg_base, + }; + ++#ifdef CONFIG_PCI ++/* ++ * PCIe windows allocation code. ++ */ ++#define ARMADA_370_XP_PCIE_MEM_START 0xC0000000 ++#define ARMADA_370_XP_PCIE_MEM_END (ARMADA_370_XP_PCIE_MEM_START + SZ_256M) ++#define ARMADA_370_XP_PCIE_IO_START 0xF2000000 ++#define ARMADA_370_XP_PCIE_IO_END (ARMADA_370_XP_PCIE_IO_START + SZ_1M) ++ ++static unsigned long armada_370_xp_pcie_memaddr = ARMADA_370_XP_PCIE_MEM_START; ++static unsigned long armada_370_xp_pcie_ioaddr = ARMADA_370_XP_PCIE_IO_START; ++ ++/* ++ * This structure and the following arrays allow to map a PCIe (port, ++ * lane) tuple to the corresponding (target, attribute) tuple needed ++ * to configure an address decoding window for the given PCIe (port, ++ * lane). ++ */ ++struct pcie_mapping { ++ int port; ++ int lane; ++ u8 target; ++ u8 attr; ++}; ++ ++struct pcie_mapping armada_xp_pcie_mappings[] = { ++ { .port = 0, .lane = 0, .target = 4, .attr = 0xE0 }, ++ { .port = 0, .lane = 1, .target = 4, .attr = 0xD0 }, ++ { .port = 0, .lane = 2, .target = 4, .attr = 0xB0 }, ++ { .port = 0, .lane = 3, .target = 4, .attr = 0x70 }, ++ { .port = 1, .lane = 0, .target = 8, .attr = 0xE0 }, ++ { .port = 1, .lane = 1, .target = 8, .attr = 0xD0 }, ++ { .port = 1, .lane = 2, .target = 8, .attr = 0xB0 }, ++ { .port = 1, .lane = 3, .target = 8, .attr = 0x70 }, ++ { .port = 2, .lane = 0, .target = 4, .attr = 0xF0 }, ++ { .port = 3, .lane = 0, .target = 8, .attr = 0xF0 }, ++ { .port = -1 }, ++}; ++ ++struct pcie_mapping armada_370_pcie_mappings[] = { ++ { .port = 0, .lane = 0, .target = 4, .attr = 0xE0 }, ++ { .port = 1, .lane = 0, .target = 8, .attr = 0xE0 }, ++ { .port = -1 }, ++}; ++ ++/* ++ * This function finds an available physical address range between ++ * ARMADA_370_XP_PCIE_MEM_START and ARMADA_370_XP_PCIE_MEM_END (for ++ * PCIe memory regions) or between ARMADA_370_XP_PCIE_IO_START and ++ * ARMADA_370_XP_PCIE_IO_END (for PCIe I/O regions) and creates an ++ * address decoding window from this allocated address pointing to the ++ * right PCIe device. ++ * ++ * An error code is returned, the allocated base address is returned ++ * through the 'outbase' argument. ++ */ ++int __init armada_370_xp_alloc_pcie_window(int pcie_port, int pcie_lane, ++ int type, u32 size, ++ unsigned long *outbase) ++{ ++ struct pcie_mapping *mapping, *mappings; ++ u8 target, attr; ++ u32 base; ++ int ret; ++ ++ if (of_machine_is_compatible("marvell,armadaxp")) ++ mappings = armada_xp_pcie_mappings; ++ else if (of_machine_is_compatible("marvell,armada370")) ++ mappings = armada_370_pcie_mappings; ++ else ++ return -ENODEV; ++ ++ for (mapping = mappings; mapping->port != -1; mapping++) ++ if (mapping->port == pcie_port && mapping->lane == pcie_lane) ++ break; ++ ++ if (mapping->port == -1) ++ return -ENODEV; ++ ++ target = mapping->target; ++ attr = mapping->attr; ++ ++ if (type == IORESOURCE_MEM) { ++ /* ++ * Bit 3 of the attributes indicates that it is a ++ * memory region, as opposed to an I/O region ++ */ ++ attr |= (1 << 3); ++ ++ if (armada_370_xp_pcie_memaddr + size > ++ ARMADA_370_XP_PCIE_MEM_END) ++ return -ENOMEM; ++ ++ base = armada_370_xp_pcie_memaddr; ++ armada_370_xp_pcie_memaddr += size; ++ ++ ret = orion_alloc_cpu_win(&addr_map_cfg, base, size, target, ++ attr, -1); ++ if (ret) { ++ armada_370_xp_pcie_memaddr -= size; ++ return ret; ++ } ++ } else if (type == IORESOURCE_IO) { ++ if (armada_370_xp_pcie_ioaddr + size > ++ ARMADA_370_XP_PCIE_IO_END) ++ return -ENOMEM; ++ ++ base = armada_370_xp_pcie_ioaddr; ++ armada_370_xp_pcie_ioaddr += size; ++ ++ ret = orion_alloc_cpu_win(&addr_map_cfg, base, size, target, ++ attr, -1); ++ if (ret) { ++ armada_370_xp_pcie_ioaddr -= size; ++ return ret; ++ } ++ } else ++ return -ENODEV; ++ ++ *outbase = base; ++ return 0; ++} ++ ++/* ++ * Frees an address decoding window previously allocated by ++ * armada_370_xp_alloc_pcie_window(). Note that only the last window ++ * allocated for a given type (MEM or IO) can be freed, due to the ++ * simplicity of the allocator. This is however sufficient to handle ++ * the error cases when initializing one PCIe device. ++ */ ++int __init armada_370_xp_free_pcie_window(int type, unsigned long base, ++ u32 size) ++{ ++ if (type == IORESOURCE_MEM) { ++ /* We can only free the last allocated window */ ++ if (base + size != armada_370_xp_pcie_memaddr) ++ return -EINVAL; ++ orion_free_cpu_win(&addr_map_cfg, base); ++ armada_370_xp_pcie_memaddr -= size; ++ } else if (type == IORESOURCE_IO) { ++ /* We can only free the last allocated window */ ++ if (base + size != armada_370_xp_pcie_ioaddr) ++ return -EINVAL; ++ orion_free_cpu_win(&addr_map_cfg, base); ++ armada_370_xp_pcie_ioaddr -= size; ++ } else ++ return -EINVAL; ++ ++ return 0; ++} ++#endif ++ + static int __init armada_setup_cpu_mbus(void) + { + struct device_node *np; +--- a/arch/arm/mach-mvebu/common.h ++++ b/arch/arm/mach-mvebu/common.h +@@ -25,4 +25,8 @@ int armada_370_xp_coherency_init(void); + int armada_370_xp_pmsu_init(void); + void armada_xp_secondary_startup(void); + extern struct smp_operations armada_xp_smp_ops; ++ ++int armada_370_xp_alloc_pcie_window(int pcie_port, int pcie_lane, ++ int type, u32 size, unsigned long *outbase); ++int armada_370_xp_free_pcie_window(int type, unsigned long base, u32 size); + #endif diff --git a/target/linux/mvebu/patches-3.8/034-arm_plat_orion_make_common_pcie.patch b/target/linux/mvebu/patches-3.8/034-arm_plat_orion_make_common_pcie.patch new file mode 100644 index 000000000..40ac714c1 --- /dev/null +++ b/target/linux/mvebu/patches-3.8/034-arm_plat_orion_make_common_pcie.patch @@ -0,0 +1,25 @@ +mvebu is a new-style Orion platform, so it only selects PLAT_ORION, +but not PLAT_ORION_LEGACY. It will however need the common PCIe code +from plat-orion, so make this code available for PLAT_ORION platforms +as a whole, and not only PLAT_ORION_LEGACY platforms. + +We also take this opportunity to build the PCIe code only when +CONFIG_PCI is enabled. + +Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> +--- + arch/arm/plat-orion/Makefile | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/arch/arm/plat-orion/Makefile ++++ b/arch/arm/plat-orion/Makefile +@@ -4,7 +4,8 @@ + ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include + + obj-y += addr-map.o ++obj-$(CONFIG_PCI) += pcie.o + + orion-gpio-$(CONFIG_GENERIC_GPIO) += gpio.o +-obj-$(CONFIG_PLAT_ORION_LEGACY) += irq.o pcie.o time.o common.o mpp.o ++obj-$(CONFIG_PLAT_ORION_LEGACY) += irq.o time.o common.o mpp.o + obj-$(CONFIG_PLAT_ORION_LEGACY) += $(orion-gpio-y) diff --git a/target/linux/mvebu/patches-3.8/035-arm_mvebu_the_core_pcie_driver.patch b/target/linux/mvebu/patches-3.8/035-arm_mvebu_the_core_pcie_driver.patch new file mode 100644 index 000000000..aa4e1f426 --- /dev/null +++ b/target/linux/mvebu/patches-3.8/035-arm_mvebu_the_core_pcie_driver.patch @@ -0,0 +1,474 @@ +This driver implements the hw_pci operations needed by the core ARM +PCI code to setup PCI devices and get their corresponding IRQs, and +the pci_ops operations that are used by the PCI core to read/write the +configuration space of PCI devices. + +In addition, this driver enumerates the different PCIe slots, and for +those having a device plugged in, it allocates the necessary address +decoding windows, using the new armada_370_xp_alloc_pcie_window() +function from mach-mvebu/addr-map.c. + +Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> +--- + .../devicetree/bindings/pci/armada-370-xp-pcie.txt | 136 +++++++++ + arch/arm/mach-mvebu/Makefile | 1 + + arch/arm/mach-mvebu/pcie.c | 306 ++++++++++++++++++++ + 3 files changed, 443 insertions(+) + create mode 100644 Documentation/devicetree/bindings/pci/armada-370-xp-pcie.txt + create mode 100644 arch/arm/mach-mvebu/pcie.c + +--- /dev/null ++++ b/Documentation/devicetree/bindings/pci/armada-370-xp-pcie.txt +@@ -0,0 +1,136 @@ ++* Marvell Armada 370/XP PCIe interfaces ++ ++Mandatory properties: ++- compatible: must be "marvell,armada-370-xp-pcie" ++- status: either "disabled" or "okay" ++- #address-cells, set to <1> ++- #size-cells, set to <1> ++- ranges: describes the association between the physical addresses of ++ the PCIe registers for each PCIe interface with "virtual" addresses ++ as seen by the sub-nodes. One entry per PCIe interface. Each entry ++ must have 3 values: the "virtual" address seen by the sub-nodes, the ++ real physical address of the PCIe registers, and the size. ++ ++In addition, the Device Tree node must have sub-nodes describing each ++PCIe interface, having the following mandatory properties: ++- reg: the address and size of the PCIe registers (translated ++ addresses according to the ranges property of the parent) ++- interrupts: the interrupt number of this PCIe interface ++- clocks: the clock associated to this PCIe interface ++- marvell,pcie-port: the physical PCIe port number ++- status: either "disabled" or "okay" ++ ++and the following optional properties: ++- marvell,pcie-lane: the physical PCIe lane number, for ports having ++ multiple lanes. If this property is not found, we assume that the ++ value is 0. ++ ++Example: ++ ++pcie-controller { ++ compatible = "marvell,armada-370-xp-pcie"; ++ status = "disabled"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges = <0 0xd0040000 0x2000 /* port0x1_port0 */ ++ 0x2000 0xd0042000 0x2000 /* port2x1_port0 */ ++ 0x4000 0xd0044000 0x2000 /* port0x1_port1 */ ++ 0x8000 0xd0048000 0x2000 /* port0x1_port2 */ ++ 0xC000 0xd004C000 0x2000 /* port0x1_port3 */ ++ 0x10000 0xd0080000 0x2000 /* port1x1_port0 */ ++ 0x12000 0xd0082000 0x2000 /* port3x1_port0 */ ++ 0x14000 0xd0084000 0x2000 /* port1x1_port1 */ ++ 0x18000 0xd0088000 0x2000 /* port1x1_port2 */ ++ 0x1C000 0xd008C000 0x2000 /* port1x1_port3 */>; ++ ++ pcie0.0@0xd0040000 { ++ reg = <0x0 0x2000>; ++ interrupts = <58>; ++ clocks = <&gateclk 5>; ++ marvell,pcie-port = <0>; ++ marvell,pcie-lane = <0>; ++ status = "disabled"; ++ }; ++ ++ pcie0.1@0xd0044000 { ++ reg = <0x4000 0x2000>; ++ interrupts = <59>; ++ clocks = <&gateclk 5>; ++ marvell,pcie-port = <0>; ++ marvell,pcie-lane = <1>; ++ status = "disabled"; ++ }; ++ ++ pcie0.2@0xd0048000 { ++ reg = <0x8000 0x2000>; ++ interrupts = <60>; ++ clocks = <&gateclk 5>; ++ marvell,pcie-port = <0>; ++ marvell,pcie-lane = <2>; ++ status = "disabled"; ++ }; ++ ++ pcie0.3@0xd004C000 { ++ reg = <0xC000 0x2000>; ++ interrupts = <61>; ++ clocks = <&gateclk 5>; ++ marvell,pcie-port = <0>; ++ marvell,pcie-lane = <3>; ++ status = "disabled"; ++ }; ++ ++ pcie1.0@0xd0040000 { ++ reg = <0x10000 0x2000>; ++ interrupts = <62>; ++ clocks = <&gateclk 6>; ++ marvell,pcie-port = <1>; ++ marvell,pcie-lane = <0>; ++ status = "disabled"; ++ }; ++ ++ pcie1.1@0xd0044000 { ++ reg = <0x14000 0x2000>; ++ interrupts = <63>; ++ clocks = <&gateclk 6>; ++ marvell,pcie-port = <1>; ++ marvell,pcie-lane = <1>; ++ status = "disabled"; ++ }; ++ ++ pcie1.2@0xd0048000 { ++ reg = <0x18000 0x2000>; ++ interrupts = <64>; ++ clocks = <&gateclk 6>; ++ marvell,pcie-port = <1>; ++ marvell,pcie-lane = <2>; ++ status = "disabled"; ++ }; ++ ++ pcie1.3@0xd004C000 { ++ reg = <0x1C000 0x2000>; ++ interrupts = <65>; ++ clocks = <&gateclk 6>; ++ marvell,pcie-port = <1>; ++ marvell,pcie-lane = <3>; ++ status = "disabled"; ++ }; ++ ++ pcie2@0xd0042000 { ++ reg = <0x2000 0x2000>; ++ interrupts = <99>; ++ clocks = <&gateclk 7>; ++ marvell,pcie-port = <2>; ++ marvell,pcie-lane = <0>; ++ status = "disabled"; ++ }; ++ ++ pcie3@0xd0082000 { ++ reg = <0x12000 0x2000>; ++ interrupts = <103>; ++ clocks = <&gateclk 8>; ++ marvell,pcie-port = <3>; ++ marvell,pcie-lane = <0>; ++ status = "disabled"; ++ }; ++}; ++ +--- a/arch/arm/mach-mvebu/Makefile ++++ b/arch/arm/mach-mvebu/Makefile +@@ -7,3 +7,4 @@ obj-y += system-controller.o + obj-$(CONFIG_MACH_ARMADA_370_XP) += armada-370-xp.o irq-armada-370-xp.o addr-map.o coherency.o coherency_ll.o pmsu.o + obj-$(CONFIG_SMP) += platsmp.o headsmp.o + obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o ++obj-$(CONFIG_PCI) += pcie.o +--- /dev/null ++++ b/arch/arm/mach-mvebu/pcie.c +@@ -0,0 +1,306 @@ ++/* ++ * PCIe driver for Marvell Armada 370 and Armada XP SoCs ++ * ++ * This file is licensed under the terms of the GNU General Public ++ * License version 2. This program is licensed "as is" without any ++ * warranty of any kind, whether express or implied. ++ */ ++ ++#include <linux/kernel.h> ++#include <linux/pci.h> ++#include <linux/clk.h> ++#include <linux/module.h> ++#include <linux/slab.h> ++#include <linux/platform_device.h> ++#include <linux/of_address.h> ++#include <linux/of_pci.h> ++#include <linux/of_irq.h> ++#include <linux/of_platform.h> ++#include <plat/pcie.h> ++#include "common.h" ++ ++struct pcie_port { ++ u8 root_bus_nr; ++ void __iomem *base; ++ spinlock_t conf_lock; ++ int irq; ++ struct resource res; ++ int haslink; ++ u32 port; ++ u32 lane; ++ struct clk *clk; ++}; ++ ++static struct pcie_port *pcie_ports; ++ ++static int pcie_valid_config(struct pcie_port *pp, int bus, int dev) ++{ ++ /* ++ * Don't go out when trying to access -- ++ * 1. nonexisting device on local bus ++ * 2. where there's no device connected (no link) ++ */ ++ if (bus == pp->root_bus_nr && dev == 0) ++ return 1; ++ ++ if (!orion_pcie_link_up(pp->base)) ++ return 0; ++ ++ if (bus == pp->root_bus_nr && dev != 1) ++ return 0; ++ ++ return 1; ++} ++ ++/* ++ * PCIe config cycles are done by programming the PCIE_CONF_ADDR register ++ * and then reading the PCIE_CONF_DATA register. Need to make sure these ++ * transactions are atomic. ++ */ ++static int pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where, ++ int size, u32 *val) ++{ ++ struct pci_sys_data *sys = bus->sysdata; ++ struct pcie_port *pp = sys->private_data; ++ unsigned long flags; ++ int ret; ++ ++ if (pcie_valid_config(pp, bus->number, PCI_SLOT(devfn)) == 0) { ++ *val = 0xffffffff; ++ return PCIBIOS_DEVICE_NOT_FOUND; ++ } ++ ++ spin_lock_irqsave(&pp->conf_lock, flags); ++ ret = orion_pcie_rd_conf(pp->base, bus, devfn, where, size, val); ++ spin_unlock_irqrestore(&pp->conf_lock, flags); ++ ++ return ret; ++} ++ ++static int pcie_wr_conf(struct pci_bus *bus, u32 devfn, ++ int where, int size, u32 val) ++{ ++ struct pci_sys_data *sys = bus->sysdata; ++ struct pcie_port *pp = sys->private_data; ++ unsigned long flags; ++ int ret; ++ ++ if (pcie_valid_config(pp, bus->number, PCI_SLOT(devfn)) == 0) ++ return PCIBIOS_DEVICE_NOT_FOUND; ++ ++ spin_lock_irqsave(&pp->conf_lock, flags); ++ ret = orion_pcie_wr_conf(pp->base, bus, devfn, where, size, val); ++ spin_unlock_irqrestore(&pp->conf_lock, flags); ++ ++ return ret; ++} ++ ++static struct pci_ops pcie_ops = { ++ .read = pcie_rd_conf, ++ .write = pcie_wr_conf, ++}; ++ ++/* ++ * Returns 0 when the device could not be initialized, 1 when ++ * initialization is successful ++ */ ++static int __init armada_370_xp_pcie_setup(int nr, struct pci_sys_data *sys) ++{ ++ struct pcie_port *port = &pcie_ports[nr]; ++ unsigned long membase, iobase; ++ int ret; ++ ++ if (!port->haslink) ++ return 0; ++ ++ sys->private_data = port; ++ port->root_bus_nr = sys->busnr; ++ spin_lock_init(&port->conf_lock); ++ ++ ret = armada_370_xp_alloc_pcie_window(port->port, port->lane, ++ IORESOURCE_MEM, SZ_64M, &membase); ++ if (ret) { ++ pr_err("PCIe%d.%d: Cannot get memory window, device disabled\n", ++ port->port, port->lane); ++ return 0; ++ } ++ ++ ret = armada_370_xp_alloc_pcie_window(port->port, port->lane, ++ IORESOURCE_IO, SZ_64K, &iobase); ++ if (ret) { ++ pr_err("PCIe%d.%d: Cannot get I/O window, device disabled\n", ++ port->port, port->lane); ++ armada_370_xp_free_pcie_window(IORESOURCE_MEM, membase, SZ_64M); ++ return 0; ++ } ++ ++ port->res.name = kasprintf(GFP_KERNEL, "PCIe %d.%d MEM", ++ port->port, port->lane); ++ if (!port->res.name) { ++ armada_370_xp_free_pcie_window(IORESOURCE_IO, iobase, SZ_64K); ++ armada_370_xp_free_pcie_window(IORESOURCE_MEM, membase, SZ_64M); ++ return 0; ++ } ++ ++ port->res.start = membase; ++ port->res.end = membase + SZ_32M - 1; ++ port->res.flags = IORESOURCE_MEM; ++ ++ pci_ioremap_io(SZ_64K * sys->busnr, iobase); ++ ++ if (request_resource(&iomem_resource, &port->res)) { ++ pr_err("PCIe%d.%d: Cannot request memory resource\n", ++ port->port, port->lane); ++ kfree(port->res.name); ++ armada_370_xp_free_pcie_window(IORESOURCE_IO, iobase, SZ_64K); ++ armada_370_xp_free_pcie_window(IORESOURCE_MEM, membase, SZ_64M); ++ return 0; ++ } ++ ++ pci_add_resource_offset(&sys->resources, &port->res, sys->mem_offset); ++ ++ orion_pcie_set_local_bus_nr(port->base, sys->busnr); ++ orion_pcie_setup(port->base); ++ ++ return 1; ++} ++ ++static void rc_pci_fixup(struct pci_dev *dev) ++{ ++ /* ++ * Prevent enumeration of root complex. ++ */ ++ if (dev->bus->parent == NULL && dev->devfn == 0) { ++ int i; ++ ++ for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { ++ dev->resource[i].start = 0; ++ dev->resource[i].end = 0; ++ dev->resource[i].flags = 0; ++ } ++ } ++} ++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL, PCI_ANY_ID, rc_pci_fixup); ++ ++static int __init armada_370_xp_pcie_map_irq(const struct pci_dev *dev, u8 slot, ++ u8 pin) ++{ ++ struct pci_sys_data *sys = dev->sysdata; ++ struct pcie_port *port = sys->private_data; ++ ++ return port->irq; ++} ++ ++static struct hw_pci armada_370_xp_pci __initdata = { ++ .setup = armada_370_xp_pcie_setup, ++ .map_irq = armada_370_xp_pcie_map_irq, ++ .ops = &pcie_ops, ++}; ++ ++static int __init armada_370_xp_pcie_probe(struct platform_device *pdev) ++{ ++ struct device_node *child; ++ int nports, i; ++ ++ nports = 0; ++ for_each_child_of_node(pdev->dev.of_node, child) { ++ if (!of_device_is_available(child)) ++ continue; ++ nports++; ++ } ++ ++ pcie_ports = devm_kzalloc(&pdev->dev, nports * sizeof(*pcie_ports), ++ GFP_KERNEL); ++ if (!pcie_ports) ++ return -ENOMEM; ++ ++ i = 0; ++ for_each_child_of_node(pdev->dev.of_node, child) { ++ struct pcie_port *port = &pcie_ports[i]; ++ ++ if (!of_device_is_available(child)) ++ continue; ++ ++ if (of_property_read_u32(child, "marvell,pcie-port", ++ &port->port)) ++ continue; ++ ++ if (of_property_read_u32(child, "marvell,pcie-lane", ++ &port->lane)) ++ port->lane = 0; ++ ++ port->base = of_iomap(child, 0); ++ if (!port->base) { ++ dev_err(&pdev->dev, "PCIe%d.%d: cannot map registers\n", ++ port->port, port->lane); ++ continue; ++ } ++ ++ if (orion_pcie_link_up(port->base)) { ++ port->haslink = 1; ++ dev_info(&pdev->dev, "PCIe%d.%d: link up\n", ++ port->port, port->lane); ++ } else { ++ port->haslink = 0; ++ dev_info(&pdev->dev, "PCIe%d.%d: link down\n", ++ port->port, port->lane); ++ iounmap(port->base); ++ continue; ++ } ++ ++ port->irq = irq_of_parse_and_map(child, 0); ++ if (port->irq == 0) { ++ dev_err(&pdev->dev, "PCIe%d.%d: cannot parse and map IRQ\n", ++ port->port, port->lane); ++ iounmap(port->base); ++ port->haslink = 0; ++ continue; ++ } ++ ++ port->clk = of_clk_get_by_name(child, NULL); ++ if (!port->clk) { ++ dev_err(&pdev->dev, "PCIe%d.%d: cannot get clock\n", ++ port->port, port->lane); ++ irq_dispose_mapping(port->irq); ++ iounmap(port->base); ++ port->haslink = 0; ++ continue; ++ } ++ ++ clk_prepare_enable(port->clk); ++ ++ i++; ++ } ++ ++ armada_370_xp_pci.nr_controllers = nports; ++ pci_common_init(&armada_370_xp_pci); ++ ++ return 0; ++} ++ ++static const struct of_device_id armada_370_xp_pcie_of_match_table[] = { ++ { .compatible = "marvell,armada-370-xp-pcie", }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, armada_370_xp_pcie_of_match_table); ++ ++static struct platform_driver armada_370_xp_pcie_driver = { ++ .driver = { ++ .owner = THIS_MODULE, ++ .name = "armada-370-xp-pcie", ++ .of_match_table = ++ of_match_ptr(armada_370_xp_pcie_of_match_table), ++ }, ++}; ++ ++static int armada_370_xp_pcie_init(void) ++{ ++ return platform_driver_probe(&armada_370_xp_pcie_driver, ++ armada_370_xp_pcie_probe); ++} ++ ++subsys_initcall(armada_370_xp_pcie_init); ++ ++MODULE_AUTHOR("Thomas Petazzoni <thomas.petazzoni@free-electrons.com>"); ++MODULE_DESCRIPTION("Marvell Armada 370/XP PCIe driver"); ++MODULE_LICENSE("GPL"); diff --git a/target/linux/mvebu/patches-3.8/036-arm_mvebu_pcie_support_is_now_available.patch b/target/linux/mvebu/patches-3.8/036-arm_mvebu_pcie_support_is_now_available.patch new file mode 100644 index 000000000..b3c9a63d5 --- /dev/null +++ b/target/linux/mvebu/patches-3.8/036-arm_mvebu_pcie_support_is_now_available.patch @@ -0,0 +1,20 @@ +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 +@@ -13,6 +13,8 @@ config ARCH_MVEBU + select MVEBU_CLK_CORE + select MVEBU_CLK_CPU + select MVEBU_CLK_GATING ++ select MIGHT_HAVE_PCI ++ select PCI_QUIRKS if PCI + + if ARCH_MVEBU + diff --git a/target/linux/mvebu/patches-3.8/037-arm_mvebu_add_pcie_dt_a370.patch b/target/linux/mvebu/patches-3.8/037-arm_mvebu_add_pcie_dt_a370.patch new file mode 100644 index 000000000..2cb8a17f0 --- /dev/null +++ b/target/linux/mvebu/patches-3.8/037-arm_mvebu_add_pcie_dt_a370.patch @@ -0,0 +1,40 @@ +The Armada 370 SoC has two 1x PCIe 2.0 interfaces, so we add the +necessary Device Tree informations to make these interfaces availabel. + +Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> +--- + arch/arm/boot/dts/armada-370.dtsi | 25 +++++++++++++++++++++++++ + 1 file changed, 25 insertions(+) + +--- a/arch/arm/boot/dts/armada-370.dtsi ++++ b/arch/arm/boot/dts/armada-370.dtsi +@@ -153,5 +153,29 @@ + clocks = <&coreclk 0>; + }; + ++ pcie-controller { ++ compatible = "marvell,armada-370-xp-pcie"; ++ status = "disabled"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges = <0 0xd0040000 0x2000 ++ 0x2000 0xd0080000 0x2000>; ++ ++ pcie0@0xd0040000 { ++ reg = <0x0 0x2000>; ++ interrupts = <58>; ++ clocks = <&gateclk 5>; ++ status = "disabled"; ++ marvell,pcie-port = <0>; ++ }; ++ ++ pcie1@0xd0080000 { ++ reg = <0x2000 0x2000>; ++ interrupts = <62>; ++ clocks = <&gateclk 9>; ++ status = "disabled"; ++ marvell,pcie-port = <1>; ++ }; ++ }; + }; + }; diff --git a/target/linux/mvebu/patches-3.8/038-arm_mvebu_add_pcie_dt_axp.patch b/target/linux/mvebu/patches-3.8/038-arm_mvebu_add_pcie_dt_axp.patch new file mode 100644 index 000000000..647f1da5f --- /dev/null +++ b/target/linux/mvebu/patches-3.8/038-arm_mvebu_add_pcie_dt_axp.patch @@ -0,0 +1,284 @@ +The Armada XP SoCs have multiple PCIe interfaces. The MV78230 has 2 +PCIe units (one 4x or quad 1x, the other 1x only), the MV78260 has 3 +PCIe units (two 4x or quad 1x and one 4x/1x), the MV78460 has 4 PCIe +units (two 4x or quad 1x and two 4x/1x). We therefore add the +necessary Device Tree informations to make those PCIe interfaces +usable. + +Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> +--- + arch/arm/boot/dts/armada-xp-mv78230.dtsi | 62 +++++++++++++++++ + arch/arm/boot/dts/armada-xp-mv78260.dtsi | 72 +++++++++++++++++++ + arch/arm/boot/dts/armada-xp-mv78460.dtsi | 112 ++++++++++++++++++++++++++++++ + 3 files changed, 246 insertions(+) + +--- a/arch/arm/boot/dts/armada-xp-mv78230.dtsi ++++ b/arch/arm/boot/dts/armada-xp-mv78230.dtsi +@@ -76,5 +76,67 @@ + #interrupts-cells = <2>; + interrupts = <87>, <88>, <89>; + }; ++ ++ /* ++ * MV78230 has 2 PCIe units Gen2.0: One unit can be ++ * configured as x4 or quad x1 lanes. One unit is ++ * x4/x1. ++ */ ++ pcie-controller { ++ compatible = "marvell,armada-370-xp-pcie"; ++ status = "disabled"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges = <0 0xd0040000 0x2000 /* port0x1_port0 */ ++ 0x2000 0xd0042000 0x2000 /* port2x1_port0 */ ++ 0x4000 0xd0044000 0x2000 /* port0x1_port1 */ ++ 0x8000 0xd0048000 0x2000 /* port0x1_port2 */ ++ 0xC000 0xd004C000 0x2000 /* port0x1_port3 */>; ++ ++ pcie0.0@0xd0040000 { ++ reg = <0x0 0x2000>; ++ interrupts = <58>; ++ clocks = <&gateclk 5>; ++ marvell,pcie-port = <0>; ++ marvell,pcie-lane = <0>; ++ status = "disabled"; ++ }; ++ ++ pcie0.1@0xd0044000 { ++ reg = <0x4000 0x2000>; ++ interrupts = <59>; ++ clocks = <&gateclk 5>; ++ marvell,pcie-port = <0>; ++ marvell,pcie-lane = <1>; ++ status = "disabled"; ++ }; ++ ++ pcie0.2@0xd0048000 { ++ reg = <0x8000 0x2000>; ++ interrupts = <60>; ++ clocks = <&gateclk 5>; ++ marvell,pcie-port = <0>; ++ marvell,pcie-lane = <2>; ++ status = "disabled"; ++ }; ++ ++ pcie0.3@0xd004C000 { ++ reg = <0xC000 0x2000>; ++ interrupts = <61>; ++ clocks = <&gateclk 5>; ++ marvell,pcie-port = <0>; ++ marvell,pcie-lane = <3>; ++ status = "disabled"; ++ }; ++ ++ pcie2@0xd0042000 { ++ reg = <0x2000 0x2000>; ++ interrupts = <99>; ++ clocks = <&gateclk 7>; ++ marvell,pcie-port = <2>; ++ marvell,pcie-lane = <0>; ++ status = "disabled"; ++ }; ++ }; + }; + }; +--- a/arch/arm/boot/dts/armada-xp-mv78260.dtsi ++++ b/arch/arm/boot/dts/armada-xp-mv78260.dtsi +@@ -96,5 +96,77 @@ + clocks = <&gateclk 1>; + status = "disabled"; + }; ++ ++ /* ++ * MV78260 has 3 PCIe units Gen2.0: Two units can be ++ * configured as x4 or quad x1 lanes. One unit is ++ * x4/x1. ++ */ ++ pcie-controller { ++ compatible = "marvell,armada-370-xp-pcie"; ++ status = "okay"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges = <0 0xd0040000 0x2000 /* port0x1_port0 */ ++ 0x2000 0xd0042000 0x2000 /* port2x1_port0 */ ++ 0x4000 0xd0044000 0x2000 /* port0x1_port1 */ ++ 0x8000 0xd0048000 0x2000 /* port0x1_port2 */ ++ 0xC000 0xd004C000 0x2000 /* port0x1_port3 */ ++ 0x12000 0xd0082000 0x2000 /* port3x1_port0 */>; ++ ++ pcie0.0@0xd0040000 { ++ reg = <0x0 0x2000>; ++ interrupts = <58>; ++ clocks = <&gateclk 5>; ++ marvell,pcie-port = <0>; ++ marvell,pcie-lane = <0>; ++ status = "disabled"; ++ }; ++ ++ pcie0.1@0xd0044000 { ++ reg = <0x4000 0x2000>; ++ interrupts = <59>; ++ clocks = <&gateclk 5>; ++ marvell,pcie-port = <0>; ++ marvell,pcie-lane = <1>; ++ status = "disabled"; ++ }; ++ ++ pcie0.2@0xd0048000 { ++ reg = <0x8000 0x2000>; ++ interrupts = <60>; ++ clocks = <&gateclk 5>; ++ marvell,pcie-port = <0>; ++ marvell,pcie-lane = <2>; ++ status = "disabled"; ++ }; ++ ++ pcie0.3@0xd004C000 { ++ reg = <0xC000 0x2000>; ++ interrupts = <61>; ++ clocks = <&gateclk 5>; ++ marvell,pcie-port = <0>; ++ marvell,pcie-lane = <3>; ++ status = "disabled"; ++ }; ++ ++ pcie2@0xd0042000 { ++ reg = <0x2000 0x2000>; ++ interrupts = <99>; ++ clocks = <&gateclk 7>; ++ marvell,pcie-port = <2>; ++ marvell,pcie-lane = <0>; ++ status = "disabled"; ++ }; ++ ++ pcie3@0xd0082000 { ++ reg = <0x12000 0x2000>; ++ interrupts = <103>; ++ clocks = <&gateclk 8>; ++ marvell,pcie-port = <3>; ++ marvell,pcie-lane = <0>; ++ status = "disabled"; ++ }; ++ }; + }; + }; +--- a/arch/arm/boot/dts/armada-xp-mv78460.dtsi ++++ b/arch/arm/boot/dts/armada-xp-mv78460.dtsi +@@ -111,5 +111,117 @@ + clocks = <&gateclk 1>; + status = "disabled"; + }; ++ ++ /* ++ * MV78460 has 4 PCIe units Gen2.0: Two units can be ++ * configured as x4 or quad x1 lanes. Two units are ++ * x4/x1. ++ */ ++ pcie-controller { ++ compatible = "marvell,armada-370-xp-pcie"; ++ status = "disabled"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges = <0 0xd0040000 0x2000 /* port0x1_port0 */ ++ 0x2000 0xd0042000 0x2000 /* port2x1_port0 */ ++ 0x4000 0xd0044000 0x2000 /* port0x1_port1 */ ++ 0x8000 0xd0048000 0x2000 /* port0x1_port2 */ ++ 0xC000 0xd004C000 0x2000 /* port0x1_port3 */ ++ 0x10000 0xd0080000 0x2000 /* port1x1_port0 */ ++ 0x12000 0xd0082000 0x2000 /* port3x1_port0 */ ++ 0x14000 0xd0084000 0x2000 /* port1x1_port1 */ ++ 0x18000 0xd0088000 0x2000 /* port1x1_port2 */ ++ 0x1C000 0xd008C000 0x2000 /* port1x1_port3 */>; ++ ++ pcie0.0@0xd0040000 { ++ reg = <0x0 0x2000>; ++ interrupts = <58>; ++ clocks = <&gateclk 5>; ++ marvell,pcie-port = <0>; ++ marvell,pcie-lane = <0>; ++ status = "disabled"; ++ }; ++ ++ pcie0.1@0xd0044000 { ++ reg = <0x4000 0x2000>; ++ interrupts = <59>; ++ clocks = <&gateclk 5>; ++ marvell,pcie-port = <0>; ++ marvell,pcie-lane = <1>; ++ status = "disabled"; ++ }; ++ ++ pcie0.2@0xd0048000 { ++ reg = <0x8000 0x2000>; ++ interrupts = <60>; ++ clocks = <&gateclk 5>; ++ marvell,pcie-port = <0>; ++ marvell,pcie-lane = <2>; ++ status = "disabled"; ++ }; ++ ++ pcie0.3@0xd004C000 { ++ reg = <0xC000 0x2000>; ++ interrupts = <61>; ++ clocks = <&gateclk 5>; ++ marvell,pcie-port = <0>; ++ marvell,pcie-lane = <3>; ++ status = "disabled"; ++ }; ++ ++ pcie1.0@0xd0040000 { ++ reg = <0x10000 0x2000>; ++ interrupts = <62>; ++ clocks = <&gateclk 6>; ++ marvell,pcie-port = <1>; ++ marvell,pcie-lane = <0>; ++ status = "disabled"; ++ }; ++ ++ pcie1.1@0xd0044000 { ++ reg = <0x14000 0x2000>; ++ interrupts = <63>; ++ clocks = <&gateclk 6>; ++ marvell,pcie-port = <1>; ++ marvell,pcie-lane = <1>; ++ status = "disabled"; ++ }; ++ ++ pcie1.2@0xd0048000 { ++ reg = <0x18000 0x2000>; ++ interrupts = <64>; ++ clocks = <&gateclk 6>; ++ marvell,pcie-port = <1>; ++ marvell,pcie-lane = <2>; ++ status = "disabled"; ++ }; ++ ++ pcie1.3@0xd004C000 { ++ reg = <0x1C000 0x2000>; ++ interrupts = <65>; ++ clocks = <&gateclk 6>; ++ marvell,pcie-port = <1>; ++ marvell,pcie-lane = <3>; ++ status = "disabled"; ++ }; ++ ++ pcie2@0xd0042000 { ++ reg = <0x2000 0x2000>; ++ interrupts = <99>; ++ clocks = <&gateclk 7>; ++ marvell,pcie-port = <2>; ++ marvell,pcie-lane = <0>; ++ status = "disabled"; ++ }; ++ ++ pcie3@0xd0082000 { ++ reg = <0x12000 0x2000>; ++ interrupts = <103>; ++ clocks = <&gateclk 8>; ++ marvell,pcie-port = <3>; ++ marvell,pcie-lane = <0>; ++ status = "disabled"; ++ }; ++ }; + }; + }; diff --git a/target/linux/mvebu/patches-3.8/039-arm_mvebu_add_pcie_dt_ax34.patch b/target/linux/mvebu/patches-3.8/039-arm_mvebu_add_pcie_dt_ax34.patch new file mode 100644 index 000000000..893c073eb --- /dev/null +++ b/target/linux/mvebu/patches-3.8/039-arm_mvebu_add_pcie_dt_ax34.patch @@ -0,0 +1,24 @@ +The PlatHome OpenBlocks AX3-4 has an internal mini-PCIe slot that can +be used to plug mini-PCIe devices. We therefore enable the PCIe +interface that corresponds to this slot. + +Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> +--- + arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts ++++ b/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts +@@ -130,5 +130,12 @@ + usb@d0052000 { + status = "okay"; + }; ++ pcie-controller { ++ status = "okay"; ++ /* Internal mini-PCIe connector */ ++ pcie0.0@0xd0040000 { ++ status = "okay"; ++ }; ++ }; + }; + }; diff --git a/target/linux/mvebu/patches-3.8/040-arm_mvebu_add_pcie_axp_db.patch b/target/linux/mvebu/patches-3.8/040-arm_mvebu_add_pcie_axp_db.patch new file mode 100644 index 000000000..af15d4b85 --- /dev/null +++ b/target/linux/mvebu/patches-3.8/040-arm_mvebu_add_pcie_axp_db.patch @@ -0,0 +1,44 @@ +The Marvell evaluation board (DB) for the Armada XP SoC has 6 +physicals full-size PCIe slots, so we enable the corresponding PCIe +interfaces in the Device Tree. + +Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> +--- + arch/arm/boot/dts/armada-xp-db.dts | 27 +++++++++++++++++++++++++++ + 1 file changed, 27 insertions(+) + +--- a/arch/arm/boot/dts/armada-xp-db.dts ++++ b/arch/arm/boot/dts/armada-xp-db.dts +@@ -109,5 +109,32 @@ + usb@d0052000 { + status = "okay"; + }; ++ ++ pcie-controller { ++ status = "okay"; ++ ++ /* ++ * All 6 slots are physically present as ++ * standard PCIe slots on the board. ++ */ ++ pcie0.0@0xd0040000 { ++ status = "okay"; ++ }; ++ pcie0.1@0xd0044000 { ++ status = "okay"; ++ }; ++ pcie0.2@0xd0048000 { ++ status = "okay"; ++ }; ++ pcie0.3@0xd004C000 { ++ status = "okay"; ++ }; ++ pcie2@0xd0042000 { ++ status = "okay"; ++ }; ++ pcie3@0xd0082000 { ++ status = "okay"; ++ }; ++ }; + }; + }; diff --git a/target/linux/mvebu/patches-3.8/041-arm_mvebu_add_pcie_dt_mirabox.patch b/target/linux/mvebu/patches-3.8/041-arm_mvebu_add_pcie_dt_mirabox.patch new file mode 100644 index 000000000..1b6089eef --- /dev/null +++ b/target/linux/mvebu/patches-3.8/041-arm_mvebu_add_pcie_dt_mirabox.patch @@ -0,0 +1,32 @@ +The Globalscale Mirabox platform uses one PCIe interface for an +available mini-PCIe slot, and the other PCIe interface for an internal +USB 3.0 controller. We add the necessary Device Tree informations to +enable those two interfaces. + +Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> +--- + arch/arm/boot/dts/armada-370-mirabox.dts | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +--- a/arch/arm/boot/dts/armada-370-mirabox.dts ++++ b/arch/arm/boot/dts/armada-370-mirabox.dts +@@ -70,5 +70,19 @@ + usb@d0051000 { + status = "okay"; + }; ++ ++ pcie-controller { ++ status = "okay"; ++ ++ /* Internal mini-PCIe connector */ ++ pcie0@0xd0040000 { ++ status = "okay"; ++ }; ++ ++ /* Connected on the PCB to a USB 3.0 XHCI controller */ ++ pcie1@0xd0080000 { ++ status = "okay"; ++ }; ++ }; + }; + }; diff --git a/target/linux/mvebu/patches-3.8/042-arm_mvebu_add_pcie_dt_a370_db.patch b/target/linux/mvebu/patches-3.8/042-arm_mvebu_add_pcie_dt_a370_db.patch new file mode 100644 index 000000000..1a853f35c --- /dev/null +++ b/target/linux/mvebu/patches-3.8/042-arm_mvebu_add_pcie_dt_a370_db.patch @@ -0,0 +1,32 @@ +The Marvell evaluation board (DB) for the Armada 370 SoC has 2 +physical full-size PCIe slots, so we enable the corresponding PCIe +interfaces in the Device Tree. + +Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> +--- + arch/arm/boot/dts/armada-370-db.dts | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +--- a/arch/arm/boot/dts/armada-370-db.dts ++++ b/arch/arm/boot/dts/armada-370-db.dts +@@ -82,5 +82,20 @@ + usb@d0051000 { + status = "okay"; + }; ++ ++ pcie-controller { ++ status = "okay"; ++ /* ++ * The two PCIe units are accessible through ++ * both standard PCIe slots and mini-PCIe ++ * slots on the board. ++ */ ++ pcie0@0xd0040000 { ++ status = "okay"; ++ }; ++ pcie1@0xd0080000 { ++ status = "okay"; ++ }; ++ }; + }; + }; diff --git a/target/linux/mvebu/patches-3.8/043-arm_mvebu_enable_usb_a370_rd.patch b/target/linux/mvebu/patches-3.8/043-arm_mvebu_enable_usb_a370_rd.patch new file mode 100644 index 000000000..5bc0482fa --- /dev/null +++ b/target/linux/mvebu/patches-3.8/043-arm_mvebu_enable_usb_a370_rd.patch @@ -0,0 +1,16 @@ +--- a/arch/arm/boot/dts/armada-370-rd.dts ++++ b/arch/arm/boot/dts/armada-370-rd.dts +@@ -63,5 +63,13 @@ + pinctrl-names = "default"; + status = "okay"; + }; ++ ++ usb@d0050000 { ++ status = "okay"; ++ }; ++ ++ usb@d0051000 { ++ status = "okay"; ++ }; + }; + }; diff --git a/target/linux/mvebu/patches-3.8/044-arm_mvebu_add_pcie_dt_a370_rd.patch b/target/linux/mvebu/patches-3.8/044-arm_mvebu_add_pcie_dt_a370_rd.patch new file mode 100644 index 000000000..f3a02d787 --- /dev/null +++ b/target/linux/mvebu/patches-3.8/044-arm_mvebu_add_pcie_dt_a370_rd.patch @@ -0,0 +1,23 @@ +--- a/arch/arm/boot/dts/armada-370-rd.dts ++++ b/arch/arm/boot/dts/armada-370-rd.dts +@@ -71,5 +71,20 @@ + usb@d0051000 { + status = "okay"; + }; ++ ++ pcie-controller { ++ status = "okay"; ++ /* ++ * The two PCIe units are accessible through ++ * both standard PCIe slots and mini-PCIe ++ * slots on the board. ++ */ ++ pcie0@0xd0040000 { ++ status = "okay"; ++ }; ++ pcie1@0xd0080000 { ++ status = "okay"; ++ }; ++ }; + }; + }; |