aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/mvebu/patches-3.10/0013-drivers-memory-Introduce-Marvell-EBU-Device-Bus-driv.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/mvebu/patches-3.10/0013-drivers-memory-Introduce-Marvell-EBU-Device-Bus-driv.patch')
-rw-r--r--target/linux/mvebu/patches-3.10/0013-drivers-memory-Introduce-Marvell-EBU-Device-Bus-driv.patch568
1 files changed, 0 insertions, 568 deletions
diff --git a/target/linux/mvebu/patches-3.10/0013-drivers-memory-Introduce-Marvell-EBU-Device-Bus-driv.patch b/target/linux/mvebu/patches-3.10/0013-drivers-memory-Introduce-Marvell-EBU-Device-Bus-driv.patch
deleted file mode 100644
index 5f00e9f36e..0000000000
--- a/target/linux/mvebu/patches-3.10/0013-drivers-memory-Introduce-Marvell-EBU-Device-Bus-driv.patch
+++ /dev/null
@@ -1,568 +0,0 @@
-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");