From 71e2e5d39770325c6acccedbe4629cad4336f6d4 Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Tue, 22 Apr 2014 23:26:09 +0200 Subject: memory: mvebu-devbus: use ARMADA_ prefix in defines The mvebu-devbus driver currently only supports the Armada 370/XP family, but it can also cover the Orion5x family. However, the Orion5x family has a different organization of the register. Therefore, in preparation to the introduction of Orion5x support, we rename the Armada 370/XP specific definitions to have an ARMADA_ prefix. Signed-off-by: Thomas Petazzoni Acked-by: Sebastian Hesselbarth Tested-by: Ezequiel Garcia Link: https://lkml.kernel.org/r/1398202002-28530-6-git-send-email-thomas.petazzoni@free-electrons.com Signed-off-by: Jason Cooper --- drivers/memory/mvebu-devbus.c | 48 +++++++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 24 deletions(-) (limited to 'drivers/memory/mvebu-devbus.c') diff --git a/drivers/memory/mvebu-devbus.c b/drivers/memory/mvebu-devbus.c index b59a17fb7c3e..e66de7f3c33c 100644 --- a/drivers/memory/mvebu-devbus.c +++ b/drivers/memory/mvebu-devbus.c @@ -30,19 +30,19 @@ #include /* 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 ARMADA_DEV_WIDTH_BIT 30 +#define ARMADA_BADR_SKEW_BIT 28 +#define ARMADA_RD_HOLD_BIT 23 +#define ARMADA_ACC_NEXT_BIT 17 +#define ARMADA_RD_SETUP_BIT 12 +#define ARMADA_ACC_FIRST_BIT 6 -#define SYNC_ENABLE_BIT 24 -#define WR_HIGH_BIT 16 -#define WR_LOW_BIT 8 +#define ARMADA_SYNC_ENABLE_BIT 24 +#define ARMADA_WR_HIGH_BIT 16 +#define ARMADA_WR_LOW_BIT 8 -#define READ_PARAM_OFFSET 0x0 -#define WRITE_PARAM_OFFSET 0x4 +#define ARMADA_READ_PARAM_OFFSET 0x0 +#define ARMADA_WRITE_PARAM_OFFSET 0x4 struct devbus_read_params { u32 bus_width; @@ -178,31 +178,31 @@ static int devbus_set_timing_params(struct devbus *devbus, 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 | + value = r.bus_width << ARMADA_DEV_WIDTH_BIT | + r.badr_skew << ARMADA_BADR_SKEW_BIT | + r.rd_hold << ARMADA_RD_HOLD_BIT | + r.acc_next << ARMADA_ACC_NEXT_BIT | + r.rd_setup << ARMADA_RD_SETUP_BIT | + r.acc_first << ARMADA_ACC_FIRST_BIT | r.turn_off; dev_dbg(devbus->dev, "read parameters register 0x%p = 0x%x\n", - devbus->base + READ_PARAM_OFFSET, + devbus->base + ARMADA_READ_PARAM_OFFSET, value); - writel(value, devbus->base + READ_PARAM_OFFSET); + writel(value, devbus->base + ARMADA_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 | + value = w.sync_enable << ARMADA_SYNC_ENABLE_BIT | + w.wr_low << ARMADA_WR_LOW_BIT | + w.wr_high << ARMADA_WR_HIGH_BIT | w.ale_wr; dev_dbg(devbus->dev, "write parameters register: 0x%p = 0x%x\n", - devbus->base + WRITE_PARAM_OFFSET, + devbus->base + ARMADA_WRITE_PARAM_OFFSET, value); - writel(value, devbus->base + WRITE_PARAM_OFFSET); + writel(value, devbus->base + ARMADA_WRITE_PARAM_OFFSET); return 0; } -- cgit v1.2.3 From 8a33692ee8f10f1ceb38001101a4f55de921d726 Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Tue, 22 Apr 2014 23:26:10 +0200 Subject: memory: mvebu-devbus: use _SHIFT suffixes instead of _BIT As noted by Sebastian Hesselbarth, the definitions in mvebu-devbus.c are not bit definition, but rather shift values, so a _SHIFT prefix would make more sense. This commit therefore replaces the *_BIT definitions by *_SHIFT definitions. Signed-off-by: Thomas Petazzoni Acked-by: Sebastian Hesselbarth Tested-by: Ezequiel Garcia Link: https://lkml.kernel.org/r/1398202002-28530-7-git-send-email-thomas.petazzoni@free-electrons.com Signed-off-by: Jason Cooper --- drivers/memory/mvebu-devbus.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) (limited to 'drivers/memory/mvebu-devbus.c') diff --git a/drivers/memory/mvebu-devbus.c b/drivers/memory/mvebu-devbus.c index e66de7f3c33c..0f196b36cc3e 100644 --- a/drivers/memory/mvebu-devbus.c +++ b/drivers/memory/mvebu-devbus.c @@ -30,16 +30,16 @@ #include /* Register definitions */ -#define ARMADA_DEV_WIDTH_BIT 30 -#define ARMADA_BADR_SKEW_BIT 28 -#define ARMADA_RD_HOLD_BIT 23 -#define ARMADA_ACC_NEXT_BIT 17 -#define ARMADA_RD_SETUP_BIT 12 -#define ARMADA_ACC_FIRST_BIT 6 +#define ARMADA_DEV_WIDTH_SHIFT 30 +#define ARMADA_BADR_SKEW_SHIFT 28 +#define ARMADA_RD_HOLD_SHIFT 23 +#define ARMADA_ACC_NEXT_SHIFT 17 +#define ARMADA_RD_SETUP_SHIFT 12 +#define ARMADA_ACC_FIRST_SHIFT 6 -#define ARMADA_SYNC_ENABLE_BIT 24 -#define ARMADA_WR_HIGH_BIT 16 -#define ARMADA_WR_LOW_BIT 8 +#define ARMADA_SYNC_ENABLE_SHIFT 24 +#define ARMADA_WR_HIGH_SHIFT 16 +#define ARMADA_WR_LOW_SHIFT 8 #define ARMADA_READ_PARAM_OFFSET 0x0 #define ARMADA_WRITE_PARAM_OFFSET 0x4 @@ -178,12 +178,12 @@ static int devbus_set_timing_params(struct devbus *devbus, return err; /* Set read timings */ - value = r.bus_width << ARMADA_DEV_WIDTH_BIT | - r.badr_skew << ARMADA_BADR_SKEW_BIT | - r.rd_hold << ARMADA_RD_HOLD_BIT | - r.acc_next << ARMADA_ACC_NEXT_BIT | - r.rd_setup << ARMADA_RD_SETUP_BIT | - r.acc_first << ARMADA_ACC_FIRST_BIT | + value = r.bus_width << ARMADA_DEV_WIDTH_SHIFT | + r.badr_skew << ARMADA_BADR_SKEW_SHIFT | + r.rd_hold << ARMADA_RD_HOLD_SHIFT | + r.acc_next << ARMADA_ACC_NEXT_SHIFT | + r.rd_setup << ARMADA_RD_SETUP_SHIFT | + r.acc_first << ARMADA_ACC_FIRST_SHIFT | r.turn_off; dev_dbg(devbus->dev, "read parameters register 0x%p = 0x%x\n", @@ -193,9 +193,9 @@ static int devbus_set_timing_params(struct devbus *devbus, writel(value, devbus->base + ARMADA_READ_PARAM_OFFSET); /* Set write timings */ - value = w.sync_enable << ARMADA_SYNC_ENABLE_BIT | - w.wr_low << ARMADA_WR_LOW_BIT | - w.wr_high << ARMADA_WR_HIGH_BIT | + value = w.sync_enable << ARMADA_SYNC_ENABLE_SHIFT | + w.wr_low << ARMADA_WR_LOW_SHIFT | + w.wr_high << ARMADA_WR_HIGH_SHIFT | w.ale_wr; dev_dbg(devbus->dev, "write parameters register: 0x%p = 0x%x\n", -- cgit v1.2.3 From 30bd30b603462ae64a0b261a704a8b2b070c6688 Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Tue, 22 Apr 2014 23:26:11 +0200 Subject: memory: mvebu-devbus: split functions The mvebu-devbus driver currently only supports the Armada 370/XP family, but it can also cover the Orion5x family. However, the Orion5x family has a different organization of the registers. Therefore, in preparation to the introduction of Orion5x support, we separate into two functions the code that 1/ retrieves the timing parameters from the Device Tree and 2/ applies those timings parameters into the hardware registers. Signed-off-by: Thomas Petazzoni Acked-by: Sebastian Hesselbarth Tested-by: Ezequiel Garcia Link: https://lkml.kernel.org/r/1398202002-28530-8-git-send-email-thomas.petazzoni@free-electrons.com Signed-off-by: Jason Cooper --- drivers/memory/mvebu-devbus.c | 90 ++++++++++++++++++++++++------------------- 1 file changed, 51 insertions(+), 39 deletions(-) (limited to 'drivers/memory/mvebu-devbus.c') diff --git a/drivers/memory/mvebu-devbus.c b/drivers/memory/mvebu-devbus.c index 0f196b36cc3e..5dc9c6360943 100644 --- a/drivers/memory/mvebu-devbus.c +++ b/drivers/memory/mvebu-devbus.c @@ -89,19 +89,15 @@ static int get_timing_param_ps(struct devbus *devbus, return 0; } -static int devbus_set_timing_params(struct devbus *devbus, - struct device_node *node) +static int devbus_get_timing_params(struct devbus *devbus, + struct device_node *node, + struct devbus_read_params *r, + struct devbus_write_params *w) { - 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); + 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", @@ -113,48 +109,48 @@ static int devbus_set_timing_params(struct devbus *devbus, * The bus width is encoded into the register as 0 for 8 bits, * and 1 for 16 bits, so we do the necessary conversion here. */ - if (r.bus_width == 8) - r.bus_width = 0; - else if (r.bus_width == 16) - r.bus_width = 1; + if (r->bus_width == 8) + r->bus_width = 0; + else if (r->bus_width == 16) + r->bus_width = 1; else { - dev_err(devbus->dev, "invalid bus width %d\n", r.bus_width); + dev_err(devbus->dev, "invalid bus width %d\n", r->bus_width); return -EINVAL; } err = get_timing_param_ps(devbus, node, "devbus,badr-skew-ps", - &r.badr_skew); + &r->badr_skew); if (err < 0) return err; err = get_timing_param_ps(devbus, node, "devbus,turn-off-ps", - &r.turn_off); + &r->turn_off); if (err < 0) return err; err = get_timing_param_ps(devbus, node, "devbus,acc-first-ps", - &r.acc_first); + &r->acc_first); if (err < 0) return err; err = get_timing_param_ps(devbus, node, "devbus,acc-next-ps", - &r.acc_next); + &r->acc_next); if (err < 0) return err; err = get_timing_param_ps(devbus, node, "devbus,rd-setup-ps", - &r.rd_setup); + &r->rd_setup); if (err < 0) return err; err = get_timing_param_ps(devbus, node, "devbus,rd-hold-ps", - &r.rd_hold); + &r->rd_hold); if (err < 0) return err; /* Get write timings */ err = of_property_read_u32(node, "devbus,sync-enable", - &w.sync_enable); + &w->sync_enable); if (err < 0) { dev_err(devbus->dev, "%s has no 'devbus,sync-enable' property\n", @@ -163,28 +159,38 @@ static int devbus_set_timing_params(struct devbus *devbus, } err = get_timing_param_ps(devbus, node, "devbus,ale-wr-ps", - &w.ale_wr); + &w->ale_wr); if (err < 0) return err; err = get_timing_param_ps(devbus, node, "devbus,wr-low-ps", - &w.wr_low); + &w->wr_low); if (err < 0) return err; err = get_timing_param_ps(devbus, node, "devbus,wr-high-ps", - &w.wr_high); + &w->wr_high); if (err < 0) return err; + return 0; +} + +static void devbus_armada_set_timing_params(struct devbus *devbus, + struct device_node *node, + struct devbus_read_params *r, + struct devbus_write_params *w) +{ + u32 value; + /* Set read timings */ - value = r.bus_width << ARMADA_DEV_WIDTH_SHIFT | - r.badr_skew << ARMADA_BADR_SKEW_SHIFT | - r.rd_hold << ARMADA_RD_HOLD_SHIFT | - r.acc_next << ARMADA_ACC_NEXT_SHIFT | - r.rd_setup << ARMADA_RD_SETUP_SHIFT | - r.acc_first << ARMADA_ACC_FIRST_SHIFT | - r.turn_off; + value = r->bus_width << ARMADA_DEV_WIDTH_SHIFT | + r->badr_skew << ARMADA_BADR_SKEW_SHIFT | + r->rd_hold << ARMADA_RD_HOLD_SHIFT | + r->acc_next << ARMADA_ACC_NEXT_SHIFT | + r->rd_setup << ARMADA_RD_SETUP_SHIFT | + r->acc_first << ARMADA_ACC_FIRST_SHIFT | + r->turn_off; dev_dbg(devbus->dev, "read parameters register 0x%p = 0x%x\n", devbus->base + ARMADA_READ_PARAM_OFFSET, @@ -193,24 +199,24 @@ static int devbus_set_timing_params(struct devbus *devbus, writel(value, devbus->base + ARMADA_READ_PARAM_OFFSET); /* Set write timings */ - value = w.sync_enable << ARMADA_SYNC_ENABLE_SHIFT | - w.wr_low << ARMADA_WR_LOW_SHIFT | - w.wr_high << ARMADA_WR_HIGH_SHIFT | - w.ale_wr; + value = w->sync_enable << ARMADA_SYNC_ENABLE_SHIFT | + w->wr_low << ARMADA_WR_LOW_SHIFT | + w->wr_high << ARMADA_WR_HIGH_SHIFT | + w->ale_wr; dev_dbg(devbus->dev, "write parameters register: 0x%p = 0x%x\n", devbus->base + ARMADA_WRITE_PARAM_OFFSET, value); writel(value, devbus->base + ARMADA_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 devbus_read_params r; + struct devbus_write_params w; struct devbus *devbus; struct resource *res; struct clk *clk; @@ -240,11 +246,17 @@ static int mvebu_devbus_probe(struct platform_device *pdev) 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); + dev_dbg(devbus->dev, "Setting timing parameter, tick is %lu ps\n", + devbus->tick_ps); + + /* Read the Device Tree node */ + err = devbus_get_timing_params(devbus, node, &r, &w); if (err < 0) return err; + /* Set the new timing parameters */ + devbus_armada_set_timing_params(devbus, node, &r, &w); + /* * We need to create a child device explicitly from here to * guarantee that the child will be probed after the timing -- cgit v1.2.3 From c4ec7430c30a4012a04aa5535919845f543f075d Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Tue, 22 Apr 2014 23:26:12 +0200 Subject: memory: mvebu-devbus: add Orion5x support This commit adds support for the Orion5x family of Marvell processors into the mvebu-devbus driver. It differs from the already supported Armada 370/XP by: * Having a single register (instead of two) for doing all the timing configuration. * Having a few less timing configuration parameters. For this reason, a separate compatible string "marvell,orion-devbus" is introduced. Signed-off-by: Thomas Petazzoni Acked-by: Sebastian Hesselbarth Tested-by: Ezequiel Garcia Link: https://lkml.kernel.org/r/1398202002-28530-9-git-send-email-thomas.petazzoni@free-electrons.com Signed-off-by: Jason Cooper --- .../bindings/memory-controllers/mvebu-devbus.txt | 25 ++++- drivers/memory/mvebu-devbus.c | 107 +++++++++++++++++---- 2 files changed, 106 insertions(+), 26 deletions(-) (limited to 'drivers/memory/mvebu-devbus.c') diff --git a/Documentation/devicetree/bindings/memory-controllers/mvebu-devbus.txt b/Documentation/devicetree/bindings/memory-controllers/mvebu-devbus.txt index 653c90c34a71..55adde214627 100644 --- a/Documentation/devicetree/bindings/memory-controllers/mvebu-devbus.txt +++ b/Documentation/devicetree/bindings/memory-controllers/mvebu-devbus.txt @@ -6,10 +6,11 @@ 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: + - compatible: Armada 370/XP SoC are supported using the + "marvell,mvebu-devbus" compatible string. - marvell,mvebu-devbus + Orion5x SoC are supported using the + "marvell,orion-devbus" compatible string. - reg: A resource specifier for the register space. This is the base address of a chip select within @@ -22,7 +23,7 @@ Required properties: integer values for each chip-select line in use: 0 -Mandatory timing properties for child nodes: +Timing properties for child nodes: Read parameters: @@ -30,21 +31,26 @@ Read parameters: 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. + Mandatory. - - devbus,bus-width: Defines the bus width (e.g. <16>) + - devbus,bus-width: Defines the bus width, in bits (e.g. <16>). + Mandatory. - 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. + Mandatory. - 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. + Mandatory. - 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). + Mandatory. - devbus,rd-setup-ps: Defines the time delay between DEV_CSn assertion to DEV_OEn assertion. If set to 0 (default), @@ -52,6 +58,8 @@ Read parameters: This parameter has no affect on parameter (no affect on first data sample). Set to a value smaller than . + Mandatory for "marvell,mvebu-devbus" + compatible string, ignored otherwise. - devbus,rd-hold-ps: Defines the time between the last data sample to the de-assertion of DEV_CSn. If set to 0 (default), @@ -62,16 +70,20 @@ Read parameters: last data sampled. Also this parameter has no affect on parameter. Set to a value smaller than . + Mandatory for "marvell,mvebu-devbus" + compatible string, ignored otherwise. Write parameters: - devbus,ale-wr-ps: Defines the time delay from the ALE[0] negation cycle to the DEV_WEn assertion. + Mandatory. - 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. + Mandatory. - devbus,wr-high-ps: Defines the time during which DEV_WEn is kept inactive (high) between data beats of a burst write. @@ -79,10 +91,13 @@ Write parameters: - ps. This parameter defines the hold time of address and data after DEV_WEn rise. + Mandatory. - devbus,sync-enable: Synchronous device enable. 1: True 0: False + Mandatory for "marvell,mvebu-devbus" compatible + string, ignored otherwise. 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 diff --git a/drivers/memory/mvebu-devbus.c b/drivers/memory/mvebu-devbus.c index 5dc9c6360943..c8f3dad8a825 100644 --- a/drivers/memory/mvebu-devbus.c +++ b/drivers/memory/mvebu-devbus.c @@ -2,7 +2,7 @@ * Marvell EBU SoC Device Bus Controller * (memory controller for NOR/NAND/SRAM/FPGA devices) * - * Copyright (C) 2013 Marvell + * Copyright (C) 2013-2014 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 @@ -44,6 +44,34 @@ #define ARMADA_READ_PARAM_OFFSET 0x0 #define ARMADA_WRITE_PARAM_OFFSET 0x4 +#define ORION_RESERVED (0x2 << 30) +#define ORION_BADR_SKEW_SHIFT 28 +#define ORION_WR_HIGH_EXT_BIT BIT(27) +#define ORION_WR_HIGH_EXT_MASK 0x8 +#define ORION_WR_LOW_EXT_BIT BIT(26) +#define ORION_WR_LOW_EXT_MASK 0x8 +#define ORION_ALE_WR_EXT_BIT BIT(25) +#define ORION_ALE_WR_EXT_MASK 0x8 +#define ORION_ACC_NEXT_EXT_BIT BIT(24) +#define ORION_ACC_NEXT_EXT_MASK 0x10 +#define ORION_ACC_FIRST_EXT_BIT BIT(23) +#define ORION_ACC_FIRST_EXT_MASK 0x10 +#define ORION_TURN_OFF_EXT_BIT BIT(22) +#define ORION_TURN_OFF_EXT_MASK 0x8 +#define ORION_DEV_WIDTH_SHIFT 20 +#define ORION_WR_HIGH_SHIFT 17 +#define ORION_WR_HIGH_MASK 0x7 +#define ORION_WR_LOW_SHIFT 14 +#define ORION_WR_LOW_MASK 0x7 +#define ORION_ALE_WR_SHIFT 11 +#define ORION_ALE_WR_MASK 0x7 +#define ORION_ACC_NEXT_SHIFT 7 +#define ORION_ACC_NEXT_MASK 0xF +#define ORION_ACC_FIRST_SHIFT 3 +#define ORION_ACC_FIRST_MASK 0xF +#define ORION_TURN_OFF_SHIFT 0 +#define ORION_TURN_OFF_MASK 0x7 + struct devbus_read_params { u32 bus_width; u32 badr_skew; @@ -96,7 +124,6 @@ static int devbus_get_timing_params(struct devbus *devbus, { int err; - /* Get read timings */ err = of_property_read_u32(node, "devbus,bus-width", &r->bus_width); if (err < 0) { dev_err(devbus->dev, @@ -138,24 +165,25 @@ static int devbus_get_timing_params(struct devbus *devbus, 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; + if (of_device_is_compatible(devbus->dev->of_node, "marvell,mvebu-devbus")) { + 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; + + 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", @@ -176,6 +204,39 @@ static int devbus_get_timing_params(struct devbus *devbus, return 0; } +static void devbus_orion_set_timing_params(struct devbus *devbus, + struct device_node *node, + struct devbus_read_params *r, + struct devbus_write_params *w) +{ + u32 value; + + /* + * The hardware designers found it would be a good idea to + * split most of the values in the register into two fields: + * one containing all the low-order bits, and another one + * containing just the high-order bit. For all of those + * fields, we have to split the value into these two parts. + */ + value = (r->turn_off & ORION_TURN_OFF_MASK) << ORION_TURN_OFF_SHIFT | + (r->acc_first & ORION_ACC_FIRST_MASK) << ORION_ACC_FIRST_SHIFT | + (r->acc_next & ORION_ACC_NEXT_MASK) << ORION_ACC_NEXT_SHIFT | + (w->ale_wr & ORION_ALE_WR_MASK) << ORION_ALE_WR_SHIFT | + (w->wr_low & ORION_WR_LOW_MASK) << ORION_WR_LOW_SHIFT | + (w->wr_high & ORION_WR_HIGH_MASK) << ORION_WR_HIGH_SHIFT | + r->bus_width << ORION_DEV_WIDTH_SHIFT | + ((r->turn_off & ORION_TURN_OFF_EXT_MASK) ? ORION_TURN_OFF_EXT_BIT : 0) | + ((r->acc_first & ORION_ACC_FIRST_EXT_MASK) ? ORION_ACC_FIRST_EXT_BIT : 0) | + ((r->acc_next & ORION_ACC_NEXT_EXT_MASK) ? ORION_ACC_NEXT_EXT_BIT : 0) | + ((w->ale_wr & ORION_ALE_WR_EXT_MASK) ? ORION_ALE_WR_EXT_BIT : 0) | + ((w->wr_low & ORION_WR_LOW_EXT_MASK) ? ORION_WR_LOW_EXT_BIT : 0) | + ((w->wr_high & ORION_WR_HIGH_EXT_MASK) ? ORION_WR_HIGH_EXT_BIT : 0) | + (r->badr_skew << ORION_BADR_SKEW_SHIFT) | + ORION_RESERVED; + + writel(value, devbus->base); +} + static void devbus_armada_set_timing_params(struct devbus *devbus, struct device_node *node, struct devbus_read_params *r, @@ -255,7 +316,10 @@ static int mvebu_devbus_probe(struct platform_device *pdev) return err; /* Set the new timing parameters */ - devbus_armada_set_timing_params(devbus, node, &r, &w); + if (of_device_is_compatible(node, "marvell,orion-devbus")) + devbus_orion_set_timing_params(devbus, node, &r, &w); + else + devbus_armada_set_timing_params(devbus, node, &r, &w); /* * We need to create a child device explicitly from here to @@ -271,6 +335,7 @@ static int mvebu_devbus_probe(struct platform_device *pdev) static const struct of_device_id mvebu_devbus_of_match[] = { { .compatible = "marvell,mvebu-devbus" }, + { .compatible = "marvell,orion-devbus" }, {}, }; MODULE_DEVICE_TABLE(of, mvebu_devbus_of_match); -- cgit v1.2.3 From 0456d3300edba52e47c6b5582cfe9d87756f5590 Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Tue, 22 Apr 2014 23:26:13 +0200 Subject: memory: mvebu-devbus: add a devbus, keep-config property Currently, the mvebu-devbus Device Tree binding makes defining the timing parameters mandatory. However, in practice, when converting Orion5x platforms to the Device Tree, we may not necessarily have easy access to the hardware platforms to fetch those values which were not defined in old-style board files: all these platforms rely on the bootloader setting the timing parameters correctly. In order to facilitate the migration to the Device Tree of this platform, this commit relaxes the mvebu-devbus Device Tree binding by introducing a 'devbus,keep-config' boolean property, which, if defined, will ignore all timing parameters passed in the Device Tree, and simply rely on the timing values already defined by the bootloader. Signed-off-by: Thomas Petazzoni Acked-by: Sebastian Hesselbarth Tested-by: Ezequiel Garcia Link: https://lkml.kernel.org/r/1398202002-28530-10-git-send-email-thomas.petazzoni@free-electrons.com Signed-off-by: Jason Cooper --- .../bindings/memory-controllers/mvebu-devbus.txt | 29 ++++++++++++++-------- drivers/memory/mvebu-devbus.c | 20 ++++++++------- 2 files changed, 29 insertions(+), 20 deletions(-) (limited to 'drivers/memory/mvebu-devbus.c') diff --git a/Documentation/devicetree/bindings/memory-controllers/mvebu-devbus.txt b/Documentation/devicetree/bindings/memory-controllers/mvebu-devbus.txt index 55adde214627..1ee3bc09f319 100644 --- a/Documentation/devicetree/bindings/memory-controllers/mvebu-devbus.txt +++ b/Documentation/devicetree/bindings/memory-controllers/mvebu-devbus.txt @@ -23,6 +23,13 @@ Required properties: integer values for each chip-select line in use: 0 +Optional properties: + + - devbus,keep-config This property can optionally be used to keep + using the timing parameters set by the + bootloader. It makes all the timing properties + described below unused. + Timing properties for child nodes: Read parameters: @@ -31,26 +38,26 @@ Read parameters: 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. - Mandatory. + Mandatory, except if devbus,keep-config is used. - devbus,bus-width: Defines the bus width, in bits (e.g. <16>). - Mandatory. + Mandatory, except if devbus,keep-config is used. - 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. - Mandatory. + Mandatory, except if devbus,keep-config is used. - 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. - Mandatory. + Mandatory, except if devbus,keep-config is used. - 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). - Mandatory. + Mandatory, except if devbus,keep-config is used. - devbus,rd-setup-ps: Defines the time delay between DEV_CSn assertion to DEV_OEn assertion. If set to 0 (default), @@ -58,8 +65,8 @@ Read parameters: This parameter has no affect on parameter (no affect on first data sample). Set to a value smaller than . - Mandatory for "marvell,mvebu-devbus" - compatible string, ignored otherwise. + Mandatory for "marvell,mvebu-devbus" compatible string, + except if devbus,keep-config is used. - devbus,rd-hold-ps: Defines the time between the last data sample to the de-assertion of DEV_CSn. If set to 0 (default), @@ -70,8 +77,8 @@ Read parameters: last data sampled. Also this parameter has no affect on parameter. Set to a value smaller than . - Mandatory for "marvell,mvebu-devbus" - compatible string, ignored otherwise. + Mandatory for "marvell,mvebu-devbus" compatible string, + except if devbus,keep-config is used. Write parameters: @@ -96,8 +103,8 @@ Write parameters: - devbus,sync-enable: Synchronous device enable. 1: True 0: False - Mandatory for "marvell,mvebu-devbus" compatible - string, ignored otherwise. + Mandatory for "marvell,mvebu-devbus" compatible string, + except if devbus,keep-config is used. 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 diff --git a/drivers/memory/mvebu-devbus.c b/drivers/memory/mvebu-devbus.c index c8f3dad8a825..ff7138fd66d1 100644 --- a/drivers/memory/mvebu-devbus.c +++ b/drivers/memory/mvebu-devbus.c @@ -310,16 +310,18 @@ static int mvebu_devbus_probe(struct platform_device *pdev) dev_dbg(devbus->dev, "Setting timing parameter, tick is %lu ps\n", devbus->tick_ps); - /* Read the Device Tree node */ - err = devbus_get_timing_params(devbus, node, &r, &w); - if (err < 0) - return err; + if (!of_property_read_bool(node, "devbus,keep-config")) { + /* Read the Device Tree node */ + err = devbus_get_timing_params(devbus, node, &r, &w); + if (err < 0) + return err; - /* Set the new timing parameters */ - if (of_device_is_compatible(node, "marvell,orion-devbus")) - devbus_orion_set_timing_params(devbus, node, &r, &w); - else - devbus_armada_set_timing_params(devbus, node, &r, &w); + /* Set the new timing parameters */ + if (of_device_is_compatible(node, "marvell,orion-devbus")) + devbus_orion_set_timing_params(devbus, node, &r, &w); + else + devbus_armada_set_timing_params(devbus, node, &r, &w); + } /* * We need to create a child device explicitly from here to -- cgit v1.2.3