2016-11-07 08:30:18

by Mirza Krak

[permalink] [raw]
Subject: [PATCH V4 0/6] Add support for Tegra GMI bus controller

From: Mirza Krak <[email protected]>

Hi.

This patch series adds support for the Tegra GMI bus controller.

I have tested this series on a Tegra30 using a Colibri T30 SOM on a custom
carrier board which has multiple CAN controllers (SJA1000) connected to the
GMI bus.

I have re-based on top of latest tegra/for-next in V4. Also see individual
patches for changes in V4.

Hopefully this will be the last round.

See below links for previous discussions.

Comments on RFC:
https://marc.info/?l=linux-clk&m=146893557629903&w=2
https://marc.info/?l=linux-tegra&m=146893541829801&w=2
https://marc.info/?l=linux-tegra&m=146893542429814&w=2

Comments on V1:
https://marc.info/?l=linux-arm-kernel&m=147051551821122&w=2
https://marc.info/?l=linux-arm-kernel&m=147051553121150&w=2
https://marc.info/?l=linux-arm-kernel&m=147194856600627&w=2
https://marc.info/?l=linux-arm-kernel&m=147072742432211&w=2

Comments on V2:
https://marc.info/?l=devicetree&m=147522253920226&w=2
https://marc.info/?l=linux-tegra&m=147204588027687&w=2
https://marc.info/?l=linux-tegra&m=147204588027687&w=2
https://marc.info/?l=devicetree&m=147256931318922&w=2

Comments on V3:
https://marc.info/?l=linux-tegra&m=147789181607782&w=2
https://marc.info/?l=linux-tegra&m=147816818203104&w=2
https://marc.info/?l=linux-tegra&m=147816897003332&w=2
https://marc.info/?l=linux-tegra&m=147818119107204&w=2

Mirza Krak (6):
clk: tegra: add TEGRA20_CLK_NOR to init table
clk: tegra: add TEGRA30_CLK_NOR to init table
dt/bindings: Add bindings for Tegra GMI controller
ARM: tegra: Add Tegra30 GMI support
ARM: tegra: Add Tegra20 GMI support
bus: Add support for Tegra Generic Memory Interface

.../devicetree/bindings/bus/nvidia,tegra20-gmi.txt | 132 ++++++++++
arch/arm/boot/dts/tegra20.dtsi | 13 +
arch/arm/boot/dts/tegra30.dtsi | 13 +
drivers/bus/Kconfig | 7 +
drivers/bus/Makefile | 1 +
drivers/bus/tegra-gmi.c | 275 +++++++++++++++++++++
drivers/clk/tegra/clk-tegra20.c | 1 +
drivers/clk/tegra/clk-tegra30.c | 1 +
8 files changed, 443 insertions(+)
create mode 100644 Documentation/devicetree/bindings/bus/nvidia,tegra20-gmi.txt
create mode 100644 drivers/bus/tegra-gmi.c

--
2.1.4


2016-11-07 08:30:28

by Mirza Krak

[permalink] [raw]
Subject: [PATCH V4 4/6] ARM: tegra: Add Tegra30 GMI support

From: Mirza Krak <[email protected]>

Add a device node for the GMI controller found on Tegra30.

Signed-off-by: Mirza Krak <[email protected]>
Tested-by: Marcel Ziswiler <[email protected]>
Tested-on: Colibri T20/T30 on EvalBoard V3.x and GMI-Memory Board
Acked-by: Jon Hunter <[email protected]>
---

Changes in v2:
- added address-cells, size-cells and ranges properties

Changes in v3:
- no changes

Changes in v4:
- no changes

arch/arm/boot/dts/tegra30.dtsi | 13 +++++++++++++
1 file changed, 13 insertions(+)

diff --git a/arch/arm/boot/dts/tegra30.dtsi b/arch/arm/boot/dts/tegra30.dtsi
index 5030065..bbb1c00 100644
--- a/arch/arm/boot/dts/tegra30.dtsi
+++ b/arch/arm/boot/dts/tegra30.dtsi
@@ -439,6 +439,19 @@
status = "disabled";
};

+ gmi@70009000 {
+ compatible = "nvidia,tegra30-gmi";
+ reg = <0x70009000 0x1000>;
+ #address-cells = <2>;
+ #size-cells = <1>;
+ ranges = <0 0 0x48000000 0x7ffffff>;
+ clocks = <&tegra_car TEGRA30_CLK_NOR>;
+ clock-names = "gmi";
+ resets = <&tegra_car 42>;
+ reset-names = "gmi";
+ status = "disabled";
+ };
+
pwm: pwm@7000a000 {
compatible = "nvidia,tegra30-pwm", "nvidia,tegra20-pwm";
reg = <0x7000a000 0x100>;
--
2.1.4

2016-11-07 08:30:26

by Mirza Krak

[permalink] [raw]
Subject: [PATCH V4 5/6] ARM: tegra: Add Tegra20 GMI support

From: Mirza Krak <[email protected]>

Add a device node for the GMI controller found on Tegra20.

Signed-off-by: Mirza Krak <[email protected]>
Tested-by: Marcel Ziswiler <[email protected]>
Tested-on: Colibri T20/T30 on EvalBoard V3.x and GMI-Memory Board
Acked-by: Jon Hunter <[email protected]>
---

Changes in v2:
- added address-cells, size-cells and ranges properties

Changes in v3:
- fixed range address which is not the same as Tegra30.

Changes in v4:
- removed extra newline and a initial space in resets property.

arch/arm/boot/dts/tegra20.dtsi | 13 +++++++++++++
1 file changed, 13 insertions(+)

diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi
index 2207c08..e880750 100644
--- a/arch/arm/boot/dts/tegra20.dtsi
+++ b/arch/arm/boot/dts/tegra20.dtsi
@@ -376,6 +376,19 @@
status = "disabled";
};

+ gmi@70009000 {
+ compatible = "nvidia,tegra20-gmi";
+ reg = <0x70009000 0x1000>;
+ #address-cells = <2>;
+ #size-cells = <1>;
+ ranges = <0 0 0xd0000000 0xfffffff>;
+ clocks = <&tegra_car TEGRA20_CLK_NOR>;
+ clock-names = "gmi";
+ resets = <&tegra_car 42>;
+ reset-names = "gmi";
+ status = "disabled";
+ };
+
pwm: pwm@7000a000 {
compatible = "nvidia,tegra20-pwm";
reg = <0x7000a000 0x100>;
--
2.1.4

2016-11-07 08:30:24

by Mirza Krak

[permalink] [raw]
Subject: [PATCH V4 3/6] dt/bindings: Add bindings for Tegra GMI controller

From: Mirza Krak <[email protected]>

Document the devicetree bindings for the Generic Memory Interface (GMI)
bus driver found on Tegra SOCs.

Signed-off-by: Mirza Krak <[email protected]>
Tested-by: Marcel Ziswiler <[email protected]>
Tested-on: Colibri T20/T30 on EvalBoard V3.x and GMI-Memory Board
Acked-by: Rob Herring <[email protected]>
---

Changes in v2:
- Updated examples and some information based on comments from Jon Hunter.

Changes in v3:
- Updates ranges description based on comments from Rob Herring

Changes in v4:
- renamed snor-*-inv to snor-*-active-high

.../devicetree/bindings/bus/nvidia,tegra20-gmi.txt | 132 +++++++++++++++++++++
1 file changed, 132 insertions(+)
create mode 100644 Documentation/devicetree/bindings/bus/nvidia,tegra20-gmi.txt

diff --git a/Documentation/devicetree/bindings/bus/nvidia,tegra20-gmi.txt b/Documentation/devicetree/bindings/bus/nvidia,tegra20-gmi.txt
new file mode 100644
index 0000000..83b0e54
--- /dev/null
+++ b/Documentation/devicetree/bindings/bus/nvidia,tegra20-gmi.txt
@@ -0,0 +1,132 @@
+Device tree bindings for NVIDIA Tegra Generic Memory Interface bus
+
+The Generic Memory Interface bus enables memory transfers between internal and
+external memory. Can be used to attach various high speed devices such as
+synchronous/asynchronous NOR, FPGA, UARTS and more.
+
+The actual devices are instantiated from the child nodes of a GMI node.
+
+Required properties:
+ - compatible : Should contain one of the following:
+ For Tegra20 must contain "nvidia,tegra20-gmi".
+ For Tegra30 must contain "nvidia,tegra30-gmi".
+ - reg: Should contain GMI controller registers location and length.
+ - clocks: Must contain an entry for each entry in clock-names.
+ - clock-names: Must include the following entries: "gmi"
+ - resets : Must contain an entry for each entry in reset-names.
+ - reset-names : Must include the following entries: "gmi"
+ - #address-cells: The number of cells used to represent physical base
+ addresses in the GMI address space. Should be 2.
+ - #size-cells: The number of cells used to represent the size of an address
+ range in the GMI address space. Should be 1.
+ - ranges: Must be set up to reflect the memory layout with three integer values
+ for each chip-select line in use (only one entry is supported, see below
+ comments):
+ <cs-number> <offset> <physical address of mapping> <size>
+
+Note that the GMI controller does not have any internal chip-select address
+decoding, because of that chip-selects either need to be managed via software
+or by employing external chip-select decoding logic.
+
+If external chip-select logic is used to support multiple devices it is assumed
+that the devices use the same timing and so are probably the same type. It also
+assumes that they can fit in the 256MB address range. In this case only one
+child device is supported which represents the active chip-select line, see
+examples for more insight.
+
+The chip-select number is decoded from the child nodes second address cell of
+'ranges' property, if 'ranges' property is not present or empty chip-select will
+then be decoded from the first cell of the 'reg' property.
+
+Optional child cs node properties:
+
+ - nvidia,snor-data-width-32bit: Use 32bit data-bus, default is 16bit.
+ - nvidia,snor-mux-mode: Enable address/data MUX mode.
+ - nvidia,snor-rdy-active-before-data: Assert RDY signal one cycle before data.
+ If omitted it will be asserted with data.
+ - nvidia,snor-rdy-active-high: RDY signal is active high
+ - nvidia,snor-adv-active-high: ADV signal is active high
+ - nvidia,snor-oe-active-high: WE/OE signal is active high
+ - nvidia,snor-cs-active-high: CS signal is active high
+
+ Note that there is some special handling for the timing values.
+ From Tegra TRM:
+ Programming 0 means 1 clock cycle: actual cycle = programmed cycle + 1
+
+ - nvidia,snor-muxed-width: Number of cycles MUX address/data asserted on the
+ bus. Valid values are 0-15, default is 1
+ - nvidia,snor-hold-width: Number of cycles CE stays asserted after the
+ de-assertion of WR_N (in case of SLAVE/MASTER Request) or OE_N
+ (in case of MASTER Request). Valid values are 0-15, default is 1
+ - nvidia,snor-adv-width: Number of cycles during which ADV stays asserted.
+ Valid values are 0-15, default is 1.
+ - nvidia,snor-ce-width: Number of cycles before CE is asserted.
+ Valid values are 0-15, default is 4
+ - nvidia,snor-we-width: Number of cycles during which WE stays asserted.
+ Valid values are 0-15, default is 1
+ - nvidia,snor-oe-width: Number of cycles during which OE stays asserted.
+ Valid values are 0-255, default is 1
+ - nvidia,snor-wait-width: Number of cycles before READY is asserted.
+ Valid values are 0-255, default is 3
+
+Example with two SJA1000 CAN controllers connected to the GMI bus. We wrap the
+controllers with a simple-bus node since they are all connected to the same
+chip-select (CS4), in this example external address decoding is provided:
+
+gmi@70090000 {
+ compatible = "nvidia,tegra20-gmi";
+ reg = <0x70009000 0x1000>;
+ #address-cells = <2>;
+ #size-cells = <1>;
+ clocks = <&tegra_car TEGRA20_CLK_NOR>;
+ clock-names = "gmi";
+ resets = <&tegra_car 42>;
+ reset-names = "gmi";
+ ranges = <4 0 0xd0000000 0xfffffff>;
+
+ status = "okay";
+
+ bus@4,0 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 4 0 0x40100>;
+
+ nvidia,snor-mux-mode;
+ nvidia,snor-adv-active-high;
+
+ can@0 {
+ reg = <0 0x100>;
+ ...
+ };
+
+ can@40000 {
+ reg = <0x40000 0x100>;
+ ...
+ };
+ };
+};
+
+Example with one SJA1000 CAN controller connected to the GMI bus
+on CS4:
+
+gmi@70090000 {
+ compatible = "nvidia,tegra20-gmi";
+ reg = <0x70009000 0x1000>;
+ #address-cells = <2>;
+ #size-cells = <1>;
+ clocks = <&tegra_car TEGRA20_CLK_NOR>;
+ clock-names = "gmi";
+ resets = <&tegra_car 42>;
+ reset-names = "gmi";
+ ranges = <4 0 0xd0000000 0xfffffff>;
+
+ status = "okay";
+
+ can@4,0 {
+ reg = <4 0 0x100>;
+ nvidia,snor-mux-mode;
+ nvidia,snor-adv-active-high;
+ ...
+ };
+};
--
2.1.4

2016-11-07 08:30:22

by Mirza Krak

[permalink] [raw]
Subject: [PATCH V4 1/6] clk: tegra: add TEGRA20_CLK_NOR to init table

From: Mirza Krak <[email protected]>

Add TEGRA20_CLK_NOR to init table and set default rate to 92 MHz which
is max rate.

The maximum rate value of 92 MHz is pulled from the downstream L4T
kernel.

Signed-off-by: Mirza Krak <[email protected]>
Tested-by: Marcel Ziswiler <[email protected]>
Tested-on: Colibri T20/T30 on EvalBoard V3.x and GMI-Memory Board
Acked-by: Jon Hunter <[email protected]>
---

Changes in v2:
- no changes

Changes in v3:
- Added comment in commit message where I got the maximum rates from.

Changes in V4:
- no changes

drivers/clk/tegra/clk-tegra20.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/drivers/clk/tegra/clk-tegra20.c b/drivers/clk/tegra/clk-tegra20.c
index 837e5cb..13d3b5a 100644
--- a/drivers/clk/tegra/clk-tegra20.c
+++ b/drivers/clk/tegra/clk-tegra20.c
@@ -1047,6 +1047,7 @@ static struct tegra_clk_init_table init_table[] __initdata = {
{ TEGRA20_CLK_SDMMC3, TEGRA20_CLK_PLL_P, 48000000, 0 },
{ TEGRA20_CLK_SDMMC4, TEGRA20_CLK_PLL_P, 48000000, 0 },
{ TEGRA20_CLK_SPI, TEGRA20_CLK_PLL_P, 20000000, 0 },
+ { TEGRA20_CLK_NOR, TEGRA20_CLK_PLL_P, 92000000, 0 },
{ TEGRA20_CLK_SBC1, TEGRA20_CLK_PLL_P, 100000000, 0 },
{ TEGRA20_CLK_SBC2, TEGRA20_CLK_PLL_P, 100000000, 0 },
{ TEGRA20_CLK_SBC3, TEGRA20_CLK_PLL_P, 100000000, 0 },
--
2.1.4

2016-11-07 08:31:17

by Mirza Krak

[permalink] [raw]
Subject: [PATCH V4 6/6] bus: Add support for Tegra Generic Memory Interface

From: Mirza Krak <[email protected]>

The Generic Memory Interface bus can be used to connect high-speed
devices such as NOR flash, FPGAs, DSPs...

Signed-off-by: Mirza Krak <[email protected]>
Tested-by: Marcel Ziswiler <[email protected]>
Tested-on: Colibri T20/T30 on EvalBoard V3.x and GMI-Memory Board
---

Changes in v2:
- Fixed some checkpatch errors
- Re-ordered probe to get rid of local variables
- Moved of_platform_default_populate call to the end of probe
- Use the timing and configuration properties from the child device
- Added warning if more then 1 child device exist

Changes in v3:
- added helper function to disable the controller which is used in remove and
on error.
- Added logic to parse CS# from "ranges" property with fallback to "reg"
property

Changes in v4:
- added sanity check of chip-select property (fail if invalid)
- adjusted for device tree binding property name changes
- fail probe if there are no child nodes
- removed superfluous error message
- removed superfluous newline in Kconfig

drivers/bus/Kconfig | 7 ++
drivers/bus/Makefile | 1 +
drivers/bus/tegra-gmi.c | 275 ++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 283 insertions(+)
create mode 100644 drivers/bus/tegra-gmi.c

diff --git a/drivers/bus/Kconfig b/drivers/bus/Kconfig
index 4ed7d26..a9ebc4c 100644
--- a/drivers/bus/Kconfig
+++ b/drivers/bus/Kconfig
@@ -141,6 +141,13 @@ config TEGRA_ACONNECT
Driver for the Tegra ACONNECT bus which is used to interface with
the devices inside the Audio Processing Engine (APE) for Tegra210.

+config TEGRA_GMI
+ tristate "Tegra Generic Memory Interface bus driver"
+ depends on ARCH_TEGRA
+ help
+ Driver for the Tegra Generic Memory Interface bus which can be used
+ to attach devices such as NOR, UART, FPGA and more.
+
config UNIPHIER_SYSTEM_BUS
tristate "UniPhier System Bus driver"
depends on ARCH_UNIPHIER && OF
diff --git a/drivers/bus/Makefile b/drivers/bus/Makefile
index ac84cc4..34e2bab 100644
--- a/drivers/bus/Makefile
+++ b/drivers/bus/Makefile
@@ -18,5 +18,6 @@ obj-$(CONFIG_OMAP_OCP2SCP) += omap-ocp2scp.o
obj-$(CONFIG_SUNXI_RSB) += sunxi-rsb.o
obj-$(CONFIG_SIMPLE_PM_BUS) += simple-pm-bus.o
obj-$(CONFIG_TEGRA_ACONNECT) += tegra-aconnect.o
+obj-$(CONFIG_TEGRA_GMI) += tegra-gmi.o
obj-$(CONFIG_UNIPHIER_SYSTEM_BUS) += uniphier-system-bus.o
obj-$(CONFIG_VEXPRESS_CONFIG) += vexpress-config.o
diff --git a/drivers/bus/tegra-gmi.c b/drivers/bus/tegra-gmi.c
new file mode 100644
index 0000000..687e212
--- /dev/null
+++ b/drivers/bus/tegra-gmi.c
@@ -0,0 +1,275 @@
+/*
+ * Driver for NVIDIA Generic Memory Interface
+ *
+ * Copyright (C) 2016 Host Mobility AB. All rights reserved.
+ *
+ * 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/clk.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/reset.h>
+
+#define TEGRA_GMI_CONFIG 0x00
+#define TEGRA_GMI_CONFIG_GO BIT(31)
+#define TEGRA_GMI_BUS_WIDTH_32BIT BIT(30)
+#define TEGRA_GMI_MUX_MODE BIT(28)
+#define TEGRA_GMI_RDY_BEFORE_DATA BIT(24)
+#define TEGRA_GMI_RDY_ACTIVE_HIGH BIT(23)
+#define TEGRA_GMI_ADV_ACTIVE_HIGH BIT(22)
+#define TEGRA_GMI_OE_ACTIVE_HIGH BIT(21)
+#define TEGRA_GMI_CS_ACTIVE_HIGH BIT(20)
+#define TEGRA_GMI_CS_SELECT(x) ((x & 0x7) << 4)
+
+#define TEGRA_GMI_TIMING0 0x10
+#define TEGRA_GMI_MUXED_WIDTH(x) ((x & 0xf) << 12)
+#define TEGRA_GMI_HOLD_WIDTH(x) ((x & 0xf) << 8)
+#define TEGRA_GMI_ADV_WIDTH(x) ((x & 0xf) << 4)
+#define TEGRA_GMI_CE_WIDTH(x) (x & 0xf)
+
+#define TEGRA_GMI_TIMING1 0x14
+#define TEGRA_GMI_WE_WIDTH(x) ((x & 0xff) << 16)
+#define TEGRA_GMI_OE_WIDTH(x) ((x & 0xff) << 8)
+#define TEGRA_GMI_WAIT_WIDTH(x) (x & 0xff)
+
+#define TEGRA_GMI_MAX_CHIP_SELECT 8
+
+struct tegra_gmi_priv {
+ void __iomem *base;
+ struct reset_control *rst;
+ struct clk *clk;
+
+ u32 snor_config;
+ u32 snor_timing0;
+ u32 snor_timing1;
+};
+
+static void tegra_gmi_disable(struct tegra_gmi_priv *priv)
+{
+ u32 config;
+
+ /* stop GMI operation */
+ config = readl(priv->base + TEGRA_GMI_CONFIG);
+ config &= ~TEGRA_GMI_CONFIG_GO;
+ writel(config, priv->base + TEGRA_GMI_CONFIG);
+
+ reset_control_assert(priv->rst);
+ clk_disable_unprepare(priv->clk);
+}
+
+static void tegra_gmi_init(struct device *dev, struct tegra_gmi_priv *priv)
+{
+ writel(priv->snor_timing0, priv->base + TEGRA_GMI_TIMING0);
+ writel(priv->snor_timing1, priv->base + TEGRA_GMI_TIMING1);
+
+ priv->snor_config |= TEGRA_GMI_CONFIG_GO;
+ writel(priv->snor_config, priv->base + TEGRA_GMI_CONFIG);
+}
+
+static int tegra_gmi_parse_dt(struct device *dev, struct tegra_gmi_priv *priv)
+{
+ struct device_node *child = of_get_next_available_child(dev->of_node,
+ NULL);
+ u32 property, ranges[4];
+ int ret;
+
+ if (!child) {
+ dev_err(dev, "no child nodes found\n");
+ return -ENODEV;
+ }
+
+ /*
+ * We currently only support one child device due to lack of
+ * chip-select address decoding. Which means that we only have one
+ * chip-select line from the GMI controller.
+ */
+ if (of_get_child_count(dev->of_node) > 1)
+ dev_warn(dev, "only one child device is supported.");
+
+ if (of_property_read_bool(child, "nvidia,snor-data-width-32bit"))
+ priv->snor_config |= TEGRA_GMI_BUS_WIDTH_32BIT;
+
+ if (of_property_read_bool(child, "nvidia,snor-mux-mode"))
+ priv->snor_config |= TEGRA_GMI_MUX_MODE;
+
+ if (of_property_read_bool(child, "nvidia,snor-rdy-active-before-data"))
+ priv->snor_config |= TEGRA_GMI_RDY_BEFORE_DATA;
+
+ if (of_property_read_bool(child, "nvidia,snor-rdy-active-high"))
+ priv->snor_config |= TEGRA_GMI_RDY_ACTIVE_HIGH;
+
+ if (of_property_read_bool(child, "nvidia,snor-adv-active-high"))
+ priv->snor_config |= TEGRA_GMI_ADV_ACTIVE_HIGH;
+
+ if (of_property_read_bool(child, "nvidia,snor-oe-active-high"))
+ priv->snor_config |= TEGRA_GMI_OE_ACTIVE_HIGH;
+
+ if (of_property_read_bool(child, "nvidia,snor-cs-active-high"))
+ priv->snor_config |= TEGRA_GMI_CS_ACTIVE_HIGH;
+
+ /* Decode the CS# */
+ ret = of_property_read_u32_array(child, "ranges", ranges, 4);
+ if (ret < 0) {
+ /* Invalid binding */
+ if (ret == -EOVERFLOW) {
+ dev_err(dev,
+ "failed to decode CS: invalid ranges length\n");
+ goto error_cs;
+ }
+
+ /*
+ * If we reach here it means that the child node has an empty
+ * ranges or it does not exist at all. Attempt to decode the
+ * CS# from the reg property instead.
+ */
+ ret = of_property_read_u32(child, "reg", &property);
+ if (ret < 0) {
+ dev_err(dev,
+ "failed to decode CS: no reg property found\n");
+ goto error_cs;
+ }
+ } else {
+ property = ranges[1];
+ }
+
+ /* Valid chip selects are CS0-CS7 */
+ if (property >= TEGRA_GMI_MAX_CHIP_SELECT) {
+ dev_err(dev, "invalid chip select: %d", property);
+ ret = -EINVAL;
+ goto error_cs;
+ }
+
+ priv->snor_config |= TEGRA_GMI_CS_SELECT(property);
+
+ /* The default values that are provided below are reset values */
+ if (!of_property_read_u32(child, "nvidia,snor-muxed-width", &property))
+ priv->snor_timing0 |= TEGRA_GMI_MUXED_WIDTH(property);
+ else
+ priv->snor_timing0 |= TEGRA_GMI_MUXED_WIDTH(1);
+
+ if (!of_property_read_u32(child, "nvidia,snor-hold-width", &property))
+ priv->snor_timing0 |= TEGRA_GMI_HOLD_WIDTH(property);
+ else
+ priv->snor_timing0 |= TEGRA_GMI_HOLD_WIDTH(1);
+
+ if (!of_property_read_u32(child, "nvidia,snor-adv-width", &property))
+ priv->snor_timing0 |= TEGRA_GMI_ADV_WIDTH(property);
+ else
+ priv->snor_timing0 |= TEGRA_GMI_ADV_WIDTH(1);
+
+ if (!of_property_read_u32(child, "nvidia,snor-ce-width", &property))
+ priv->snor_timing0 |= TEGRA_GMI_CE_WIDTH(property);
+ else
+ priv->snor_timing0 |= TEGRA_GMI_CE_WIDTH(4);
+
+ if (!of_property_read_u32(child, "nvidia,snor-we-width", &property))
+ priv->snor_timing1 |= TEGRA_GMI_WE_WIDTH(property);
+ else
+ priv->snor_timing1 |= TEGRA_GMI_WE_WIDTH(1);
+
+ if (!of_property_read_u32(child, "nvidia,snor-oe-width", &property))
+ priv->snor_timing1 |= TEGRA_GMI_OE_WIDTH(property);
+ else
+ priv->snor_timing1 |= TEGRA_GMI_OE_WIDTH(1);
+
+ if (!of_property_read_u32(child, "nvidia,snor-wait-width", &property))
+ priv->snor_timing1 |= TEGRA_GMI_WAIT_WIDTH(property);
+ else
+ priv->snor_timing1 |= TEGRA_GMI_WAIT_WIDTH(3);
+
+error_cs:
+ of_node_put(child);
+ return ret;
+}
+
+static int tegra_gmi_probe(struct platform_device *pdev)
+{
+ struct resource *res;
+ struct device *dev = &pdev->dev;
+ struct tegra_gmi_priv *priv;
+ int ret;
+
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ priv->base = devm_ioremap_resource(dev, res);
+ if (IS_ERR(priv->base))
+ return PTR_ERR(priv->base);
+
+ priv->clk = devm_clk_get(dev, "gmi");
+ if (IS_ERR(priv->clk)) {
+ dev_err(dev, "can not get clock\n");
+ return PTR_ERR(priv->clk);
+ }
+
+ priv->rst = devm_reset_control_get(dev, "gmi");
+ if (IS_ERR(priv->rst)) {
+ dev_err(dev, "can not get reset\n");
+ return PTR_ERR(priv->rst);
+ }
+
+ ret = tegra_gmi_parse_dt(dev, priv);
+ if (ret)
+ return ret;
+
+ ret = clk_prepare_enable(priv->clk);
+ if (ret) {
+ dev_err(dev, "fail to enable clock.\n");
+ return ret;
+ }
+
+ reset_control_assert(priv->rst);
+ udelay(2);
+ reset_control_deassert(priv->rst);
+
+ tegra_gmi_init(dev, priv);
+
+ ret = of_platform_default_populate(dev->of_node, NULL, dev);
+ if (ret < 0) {
+ dev_err(dev, "fail to create devices.\n");
+ tegra_gmi_disable(priv);
+ return ret;
+ }
+
+ dev_set_drvdata(dev, priv);
+
+ return 0;
+}
+
+static int tegra_gmi_remove(struct platform_device *pdev)
+{
+ struct tegra_gmi_priv *priv = dev_get_drvdata(&pdev->dev);
+
+ of_platform_depopulate(&pdev->dev);
+
+ tegra_gmi_disable(priv);
+
+ return 0;
+}
+
+static const struct of_device_id tegra_gmi_id_table[] = {
+ { .compatible = "nvidia,tegra20-gmi", },
+ { .compatible = "nvidia,tegra30-gmi", },
+ { }
+};
+MODULE_DEVICE_TABLE(of, tegra_gmi_id_table);
+
+static struct platform_driver tegra_gmi_driver = {
+ .probe = tegra_gmi_probe,
+ .remove = tegra_gmi_remove,
+ .driver = {
+ .name = "tegra-gmi",
+ .of_match_table = tegra_gmi_id_table,
+ },
+};
+module_platform_driver(tegra_gmi_driver);
+
+MODULE_AUTHOR("Mirza Krak <[email protected]");
+MODULE_DESCRIPTION("NVIDIA Tegra GMI Bus Driver");
+MODULE_LICENSE("GPL v2");
--
2.1.4

2016-11-07 08:31:42

by Mirza Krak

[permalink] [raw]
Subject: [PATCH V4 2/6] clk: tegra: add TEGRA30_CLK_NOR to init table

From: Mirza Krak <[email protected]>

Add TEGRA30_CLK_NOR to init table and set default rate to 127 MHz which
is max rate.

The maximum rate value of 127 MHz is pulled from the downstream L4T
kernel.

Signed-off-by: Mirza Krak <[email protected]>
Tested-by: Marcel Ziswiler <[email protected]>
Tested-on: Colibri T20/T30 on EvalBoard V3.x and GMI-Memory Board
Acked-by: Jon Hunter <[email protected]>
---

Changes in v2:
- no changes

Changes in v3:
- Added comment in commit message where I got the maximum rates from.

Changes in V4:
- no changes

drivers/clk/tegra/clk-tegra30.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/drivers/clk/tegra/clk-tegra30.c b/drivers/clk/tegra/clk-tegra30.c
index 8e2db5e..67f1677 100644
--- a/drivers/clk/tegra/clk-tegra30.c
+++ b/drivers/clk/tegra/clk-tegra30.c
@@ -1252,6 +1252,7 @@ static struct tegra_clk_init_table init_table[] __initdata = {
{ TEGRA30_CLK_SDMMC1, TEGRA30_CLK_PLL_P, 48000000, 0 },
{ TEGRA30_CLK_SDMMC2, TEGRA30_CLK_PLL_P, 48000000, 0 },
{ TEGRA30_CLK_SDMMC3, TEGRA30_CLK_PLL_P, 48000000, 0 },
+ { TEGRA30_CLK_NOR, TEGRA30_CLK_PLL_P, 127000000, 0 },
{ TEGRA30_CLK_PLL_M, TEGRA30_CLK_CLK_MAX, 0, 1 },
{ TEGRA30_CLK_PCLK, TEGRA30_CLK_CLK_MAX, 0, 1 },
{ TEGRA30_CLK_CSITE, TEGRA30_CLK_CLK_MAX, 0, 1 },
--
2.1.4

2016-11-07 11:13:45

by Jon Hunter

[permalink] [raw]
Subject: Re: [PATCH V4 6/6] bus: Add support for Tegra Generic Memory Interface


On 07/11/16 08:30, Mirza Krak wrote:
> From: Mirza Krak <[email protected]>
>
> The Generic Memory Interface bus can be used to connect high-speed
> devices such as NOR flash, FPGAs, DSPs...
>
> Signed-off-by: Mirza Krak <[email protected]>
> Tested-by: Marcel Ziswiler <[email protected]>
> Tested-on: Colibri T20/T30 on EvalBoard V3.x and GMI-Memory Board

Thanks for the update.

Acked-by: Jon Hunter <[email protected]>

Cheers
Jon

--
nvpublic

2016-11-07 11:28:17

by Thierry Reding

[permalink] [raw]
Subject: Re: [PATCH V4 2/6] clk: tegra: add TEGRA30_CLK_NOR to init table

On Mon, Nov 07, 2016 at 09:30:01AM +0100, Mirza Krak wrote:
> From: Mirza Krak <[email protected]>
>
> Add TEGRA30_CLK_NOR to init table and set default rate to 127 MHz which
> is max rate.
>
> The maximum rate value of 127 MHz is pulled from the downstream L4T
> kernel.
>
> Signed-off-by: Mirza Krak <[email protected]>
> Tested-by: Marcel Ziswiler <[email protected]>
> Tested-on: Colibri T20/T30 on EvalBoard V3.x and GMI-Memory Board
> Acked-by: Jon Hunter <[email protected]>
> ---
>
> Changes in v2:
> - no changes
>
> Changes in v3:
> - Added comment in commit message where I got the maximum rates from.
>
> Changes in V4:
> - no changes
>
> drivers/clk/tegra/clk-tegra30.c | 1 +
> 1 file changed, 1 insertion(+)

Applied, thanks.

Thierry


Attachments:
(No filename) (777.00 B)
signature.asc (801.00 B)
Download all attachments

2016-11-07 11:35:58

by Thierry Reding

[permalink] [raw]
Subject: Re: [PATCH V4 3/6] dt/bindings: Add bindings for Tegra GMI controller

On Mon, Nov 07, 2016 at 09:30:02AM +0100, Mirza Krak wrote:
> From: Mirza Krak <[email protected]>
>
> Document the devicetree bindings for the Generic Memory Interface (GMI)
> bus driver found on Tegra SOCs.
>
> Signed-off-by: Mirza Krak <[email protected]>
> Tested-by: Marcel Ziswiler <[email protected]>
> Tested-on: Colibri T20/T30 on EvalBoard V3.x and GMI-Memory Board
> Acked-by: Rob Herring <[email protected]>
> ---
>
> Changes in v2:
> - Updated examples and some information based on comments from Jon Hunter.
>
> Changes in v3:
> - Updates ranges description based on comments from Rob Herring
>
> Changes in v4:
> - renamed snor-*-inv to snor-*-active-high
>
> .../devicetree/bindings/bus/nvidia,tegra20-gmi.txt | 132 +++++++++++++++++++++
> 1 file changed, 132 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/bus/nvidia,tegra20-gmi.txt

Applied, thanks.

Thierry


Attachments:
(No filename) (922.00 B)
signature.asc (801.00 B)
Download all attachments

2016-11-07 11:49:45

by Thierry Reding

[permalink] [raw]
Subject: Re: [PATCH V4 6/6] bus: Add support for Tegra Generic Memory Interface

On Mon, Nov 07, 2016 at 09:30:05AM +0100, Mirza Krak wrote:
> From: Mirza Krak <[email protected]>
>
> The Generic Memory Interface bus can be used to connect high-speed
> devices such as NOR flash, FPGAs, DSPs...
>
> Signed-off-by: Mirza Krak <[email protected]>
> Tested-by: Marcel Ziswiler <[email protected]>
> Tested-on: Colibri T20/T30 on EvalBoard V3.x and GMI-Memory Board
> ---
>
> Changes in v2:
> - Fixed some checkpatch errors
> - Re-ordered probe to get rid of local variables
> - Moved of_platform_default_populate call to the end of probe
> - Use the timing and configuration properties from the child device
> - Added warning if more then 1 child device exist
>
> Changes in v3:
> - added helper function to disable the controller which is used in remove and
> on error.
> - Added logic to parse CS# from "ranges" property with fallback to "reg"
> property
>
> Changes in v4:
> - added sanity check of chip-select property (fail if invalid)
> - adjusted for device tree binding property name changes
> - fail probe if there are no child nodes
> - removed superfluous error message
> - removed superfluous newline in Kconfig
>
> drivers/bus/Kconfig | 7 ++
> drivers/bus/Makefile | 1 +
> drivers/bus/tegra-gmi.c | 275 ++++++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 283 insertions(+)
> create mode 100644 drivers/bus/tegra-gmi.c

Applied with a bit of code reshuffling to make things more symmetric as
well as a couple of pedantic cleanups because I couldn't resist.

Thanks,
Thierry


Attachments:
(No filename) (1.53 kB)
signature.asc (801.00 B)
Download all attachments

2016-11-07 12:37:52

by Thierry Reding

[permalink] [raw]
Subject: Re: [PATCH V4 1/6] clk: tegra: add TEGRA20_CLK_NOR to init table

On Mon, Nov 07, 2016 at 09:30:00AM +0100, Mirza Krak wrote:
> From: Mirza Krak <[email protected]>
>
> Add TEGRA20_CLK_NOR to init table and set default rate to 92 MHz which
> is max rate.
>
> The maximum rate value of 92 MHz is pulled from the downstream L4T
> kernel.
>
> Signed-off-by: Mirza Krak <[email protected]>
> Tested-by: Marcel Ziswiler <[email protected]>
> Tested-on: Colibri T20/T30 on EvalBoard V3.x and GMI-Memory Board
> Acked-by: Jon Hunter <[email protected]>
> ---
>
> Changes in v2:
> - no changes
>
> Changes in v3:
> - Added comment in commit message where I got the maximum rates from.
>
> Changes in V4:
> - no changes

Applied, thanks.

Thierry


Attachments:
(No filename) (697.00 B)
signature.asc (801.00 B)
Download all attachments

2016-11-07 12:56:23

by Thierry Reding

[permalink] [raw]
Subject: Re: [PATCH V4 4/6] ARM: tegra: Add Tegra30 GMI support

On Mon, Nov 07, 2016 at 09:30:03AM +0100, Mirza Krak wrote:
> From: Mirza Krak <[email protected]>
>
> Add a device node for the GMI controller found on Tegra30.
>
> Signed-off-by: Mirza Krak <[email protected]>
> Tested-by: Marcel Ziswiler <[email protected]>
> Tested-on: Colibri T20/T30 on EvalBoard V3.x and GMI-Memory Board
> Acked-by: Jon Hunter <[email protected]>
> ---
>
> Changes in v2:
> - added address-cells, size-cells and ranges properties
>
> Changes in v3:
> - no changes
>
> Changes in v4:
> - no changes
>
> arch/arm/boot/dts/tegra30.dtsi | 13 +++++++++++++
> 1 file changed, 13 insertions(+)

Applied, thanks.

Thierry


Attachments:
(No filename) (666.00 B)
signature.asc (801.00 B)
Download all attachments

2016-11-07 12:56:41

by Thierry Reding

[permalink] [raw]
Subject: Re: [PATCH V4 5/6] ARM: tegra: Add Tegra20 GMI support

On Mon, Nov 07, 2016 at 09:30:04AM +0100, Mirza Krak wrote:
> From: Mirza Krak <[email protected]>
>
> Add a device node for the GMI controller found on Tegra20.
>
> Signed-off-by: Mirza Krak <[email protected]>
> Tested-by: Marcel Ziswiler <[email protected]>
> Tested-on: Colibri T20/T30 on EvalBoard V3.x and GMI-Memory Board
> Acked-by: Jon Hunter <[email protected]>
> ---
>
> Changes in v2:
> - added address-cells, size-cells and ranges properties
>
> Changes in v3:
> - fixed range address which is not the same as Tegra30.
>
> Changes in v4:
> - removed extra newline and a initial space in resets property.
>
> arch/arm/boot/dts/tegra20.dtsi | 13 +++++++++++++
> 1 file changed, 13 insertions(+)

Applied, thanks.

Thierry


Attachments:
(No filename) (760.00 B)
signature.asc (801.00 B)
Download all attachments