* [PATCH 01/17] serial: ns16550: Add device ids for omap
2013-11-22 14:48 Add devicetree support to OMAP drivers Sascha Hauer
@ 2013-11-22 14:48 ` Sascha Hauer
2013-11-22 14:48 ` [PATCH 02/17] pinctrl: Add pinctrl-single driver Sascha Hauer
` (15 subsequent siblings)
16 siblings, 0 replies; 18+ messages in thread
From: Sascha Hauer @ 2013-11-22 14:48 UTC (permalink / raw)
To: barebox
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
arch/arm/mach-omap/omap_devices.c | 4 +--
drivers/serial/serial_ns16550.c | 62 ++++++++++++++++++++++++++++++++++-----
drivers/serial/serial_ns16550.h | 4 ---
3 files changed, 56 insertions(+), 14 deletions(-)
diff --git a/arch/arm/mach-omap/omap_devices.c b/arch/arm/mach-omap/omap_devices.c
index 30cfdd0..9ed3dcf 100644
--- a/arch/arm/mach-omap/omap_devices.c
+++ b/arch/arm/mach-omap/omap_devices.c
@@ -21,6 +21,6 @@ static struct NS16550_plat serial_plat = {
struct device_d *omap_add_uart(int id, unsigned long base)
{
- return add_ns16550_device(id, base, 1024,
- IORESOURCE_MEM_8BIT, &serial_plat);
+ return add_generic_device("omap-uart", id, NULL, base, 1024,
+ IORESOURCE_MEM | IORESOURCE_MEM_8BIT, &serial_plat);
}
diff --git a/drivers/serial/serial_ns16550.c b/drivers/serial/serial_ns16550.c
index d3a5a81..a8487b0 100644
--- a/drivers/serial/serial_ns16550.c
+++ b/drivers/serial/serial_ns16550.c
@@ -55,6 +55,10 @@ static inline struct ns16550_priv *to_ns16550_priv(struct console_device *cdev)
return container_of(cdev, struct ns16550_priv, cdev);
}
+struct ns16550_drvdata {
+ void (*init_port)(struct console_device *cdev);
+};
+
/**
* @brief read register
*
@@ -178,14 +182,16 @@ static void ns16550_serial_init_port(struct console_device *cdev)
/* initializing the device for the first time */
ns16550_write(cdev, 0x00, lcr); /* select ier reg */
ns16550_write(cdev, 0x00, ier);
+}
-#ifdef CONFIG_DRIVER_SERIAL_NS16550_OMAP_EXTENSIONS
- ns16550_write(cdev, 0x07, mdr1); /* Disable */
-#endif
+#define omap_mdr1 8
-#ifdef CONFIG_DRIVER_SERIAL_NS16550_OMAP_EXTENSIONS
- ns16550_write(cdev, 0x00, mdr1);
-#endif
+static void ns16550_omap_init_port(struct console_device *cdev)
+{
+ ns16550_serial_init_port(cdev);
+
+ ns16550_write(cdev, 0x07, omap_mdr1); /* Disable */
+ ns16550_write(cdev, 0x00, omap_mdr1);
}
/*********** Exposed Functions **********************************/
@@ -239,6 +245,14 @@ static void ns16550_probe_dt(struct device_d *dev, struct ns16550_priv *priv)
of_property_read_u32(np, "reg-shift", &priv->plat.shift);
}
+static struct ns16550_drvdata ns16550_drvdata = {
+ .init_port = ns16550_serial_init_port,
+};
+
+static __maybe_unused struct ns16550_drvdata omap_drvdata = {
+ .init_port = ns16550_omap_init_port,
+};
+
/**
* @brief Probe entry point -called on the first match for device
*
@@ -253,8 +267,13 @@ static int ns16550_probe(struct device_d *dev)
struct ns16550_priv *priv;
struct console_device *cdev;
struct NS16550_plat *plat = (struct NS16550_plat *)dev->platform_data;
+ struct ns16550_drvdata *devtype;
int ret;
+ ret = dev_get_drvdata(dev, (unsigned long *)&devtype);
+ if (ret)
+ devtype = &ns16550_drvdata;
+
dev->priv = dev_request_mem_region(dev, 0);
priv = xzalloc(sizeof(*priv));
@@ -294,7 +313,7 @@ static int ns16550_probe(struct device_d *dev)
cdev->getc = ns16550_getc;
cdev->setbrg = ns16550_setbaudrate;
- ns16550_serial_init_port(cdev);
+ devtype->init_port(cdev);
return console_register(cdev);
@@ -307,8 +326,32 @@ err:
static struct of_device_id ns16550_serial_dt_ids[] = {
{
.compatible = "ns16550a",
- },{
+ .data = (unsigned long)&ns16550_drvdata,
+ }, {
.compatible = "snps,dw-apb-uart",
+ .data = (unsigned long)&ns16550_drvdata,
+ },
+#if IS_ENABLED(CONFIG_ARCH_OMAP)
+ {
+ .compatible = "ti,omap2-uart",
+ .data = (unsigned long)&omap_drvdata,
+ }, {
+ .compatible = "ti,omap3-uart",
+ .data = (unsigned long)&omap_drvdata,
+ }, {
+ .compatible = "ti,omap4-uart",
+ .data = (unsigned long)&omap_drvdata,
+ },
+#endif
+ {
+ /* sentinel */
+ },
+};
+
+static __maybe_unused struct platform_device_id ns16550_serial_ids[] = {
+ {
+ .name = "omap-uart",
+ .driver_data = (unsigned long)&omap_drvdata,
}, {
/* sentinel */
},
@@ -321,5 +364,8 @@ static struct driver_d ns16550_serial_driver = {
.name = "ns16550_serial",
.probe = ns16550_probe,
.of_compatible = DRV_OF_COMPAT(ns16550_serial_dt_ids),
+#if IS_ENABLED(CONFIG_ARCH_OMAP)
+ .id_table = ns16550_serial_ids,
+#endif
};
console_platform_driver(ns16550_serial_driver);
diff --git a/drivers/serial/serial_ns16550.h b/drivers/serial/serial_ns16550.h
index db8fe64..c37d63c 100644
--- a/drivers/serial/serial_ns16550.h
+++ b/drivers/serial/serial_ns16550.h
@@ -40,10 +40,6 @@
#define lsr 5
#define msr 6
#define scr 7
-#ifdef CONFIG_DRIVER_SERIAL_NS16550_OMAP_EXTENSIONS
-#define mdr1 8
-#define osc_12m_sel 9
-#endif
#define thr rbr
#define iir fcr
--
1.8.4.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 02/17] pinctrl: Add pinctrl-single driver
2013-11-22 14:48 Add devicetree support to OMAP drivers Sascha Hauer
2013-11-22 14:48 ` [PATCH 01/17] serial: ns16550: Add device ids for omap Sascha Hauer
@ 2013-11-22 14:48 ` Sascha Hauer
2013-11-22 14:48 ` [PATCH 03/17] spi: omap: encode register offset into device_id Sascha Hauer
` (14 subsequent siblings)
16 siblings, 0 replies; 18+ messages in thread
From: Sascha Hauer @ 2013-11-22 14:48 UTC (permalink / raw)
To: barebox
Based on the kernel pinctrl-single driver. This one is just enough
to make OMAP/AM33xx work.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/pinctrl/Kconfig | 3 +
drivers/pinctrl/Makefile | 1 +
drivers/pinctrl/pinctrl-single.c | 166 +++++++++++++++++++++++++++++++++++++++
3 files changed, 170 insertions(+)
create mode 100644 drivers/pinctrl/pinctrl-single.c
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index 58397a0..8257586 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -23,6 +23,9 @@ config PINCTRL_IMX_IOMUX_V3
help
This iomux controller is found on i.MX25,35,51,53,6.
+config PINCTRL_SINGLE
+ bool "pinctrl single"
+
config PINCTRL_TEGRA20
select PINCTRL
bool
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index 169ed18..b3b0fa9 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -2,4 +2,5 @@ obj-$(CONFIG_PINCTRL) += pinctrl.o
obj-$(CONFIG_PINCTRL_IMX_IOMUX_V1) += imx-iomux-v1.o
obj-$(CONFIG_PINCTRL_IMX_IOMUX_V2) += imx-iomux-v2.o
obj-$(CONFIG_PINCTRL_IMX_IOMUX_V3) += imx-iomux-v3.o
+obj-$(CONFIG_PINCTRL_SINGLE) += pinctrl-single.o
obj-$(CONFIG_PINCTRL_TEGRA20) += pinctrl-tegra20.o
diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c
new file mode 100644
index 0000000..5c60c70
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-single.c
@@ -0,0 +1,166 @@
+/*
+ * pinctrl-single - Generic device tree based pinctrl driver for one
+ * register per pin type pinmux controllers
+ *
+ * Copyright (c) 2013 Sascha Hauer <s.hauer@pengutronix.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * 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.
+ *
+ */
+
+#include <common.h>
+#include <init.h>
+#include <io.h>
+#include <pinctrl.h>
+#include <malloc.h>
+
+struct pinctrl_single {
+ void __iomem *base;
+ struct pinctrl_device pinctrl;
+ unsigned (*read)(void __iomem *reg);
+ void (*write)(unsigned val, void __iomem *reg);
+ unsigned width;
+};
+
+static unsigned __maybe_unused pcs_readb(void __iomem *reg)
+{
+ return readb(reg);
+}
+
+static unsigned __maybe_unused pcs_readw(void __iomem *reg)
+{
+ return readw(reg);
+}
+
+static unsigned __maybe_unused pcs_readl(void __iomem *reg)
+{
+ return readl(reg);
+}
+
+static void __maybe_unused pcs_writeb(unsigned val, void __iomem *reg)
+{
+ writeb(val, reg);
+}
+
+static void __maybe_unused pcs_writew(unsigned val, void __iomem *reg)
+{
+ writew(val, reg);
+}
+
+static void __maybe_unused pcs_writel(unsigned val, void __iomem *reg)
+{
+ writel(val, reg);
+}
+
+static int pcs_set_state(struct pinctrl_device *pdev, struct device_node *np)
+{
+ struct pinctrl_single *pcs = container_of(pdev, struct pinctrl_single, pinctrl);
+ unsigned size = 0, index = 0;
+ const __be32 *mux;
+
+ dev_dbg(pcs->pinctrl.dev, "set state: %s\n", np->full_name);
+
+ mux = of_get_property(np, "pinctrl-single,pins", &size);
+
+ size /= sizeof(*mux); /* Number of elements in array */
+
+ if (!mux || !size || (size & 1)) {
+ dev_err(pcs->pinctrl.dev, "bad data for mux %s\n",
+ np->full_name);
+ return -EINVAL;
+ }
+
+ while (index < size) {
+ unsigned offset, val;
+
+ offset = be32_to_cpup(mux + index++);
+ val = be32_to_cpup(mux + index++);
+
+ pcs->write(val, pcs->base + offset);
+ }
+
+ return 0;
+}
+
+static struct pinctrl_ops pcs_ops = {
+ .set_state = pcs_set_state,
+};
+
+static int pcs_probe(struct device_d *dev)
+{
+ struct pinctrl_single *pcs;
+ struct device_node *np = dev->device_node;
+ int ret = 0;
+
+ pcs = xzalloc(sizeof(*pcs));
+ pcs->base = dev_request_mem_region(dev, 0);
+ pcs->pinctrl.dev = dev;
+ pcs->pinctrl.ops = &pcs_ops;
+
+ ret = of_property_read_u32(np, "pinctrl-single,register-width",
+ &pcs->width);
+ if (ret) {
+ dev_dbg(dev, "no pinctrl-single,register-width property\n");
+ goto out;
+ }
+
+ switch (pcs->width) {
+ case 8:
+ pcs->read = pcs_readb;
+ pcs->write = pcs_writeb;
+ break;
+ case 16:
+ pcs->read = pcs_readw;
+ pcs->write = pcs_writew;
+ break;
+ case 32:
+ pcs->read = pcs_readl;
+ pcs->write = pcs_writel;
+ break;
+ default:
+ ret = -EINVAL;
+ dev_dbg(dev, "invalid register width: %d\n", pcs->width);
+ goto out;
+ }
+
+ ret = pinctrl_register(&pcs->pinctrl);
+ if (ret)
+ goto out;
+
+ return 0;
+
+out:
+ free(pcs);
+
+ return ret;
+}
+
+static __maybe_unused struct of_device_id pcs_dt_ids[] = {
+ {
+ .compatible = "pinctrl-single",
+ }, {
+ /* sentinel */
+ }
+};
+
+static struct driver_d pcs_driver = {
+ .name = "pinctrl-single",
+ .probe = pcs_probe,
+ .of_compatible = DRV_OF_COMPAT(pcs_dt_ids),
+};
+
+static int pcs_init(void)
+{
+ return platform_driver_register(&pcs_driver);
+}
+postcore_initcall(pcs_init);
--
1.8.4.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 03/17] spi: omap: encode register offset into device_id
2013-11-22 14:48 Add devicetree support to OMAP drivers Sascha Hauer
2013-11-22 14:48 ` [PATCH 01/17] serial: ns16550: Add device ids for omap Sascha Hauer
2013-11-22 14:48 ` [PATCH 02/17] pinctrl: Add pinctrl-single driver Sascha Hauer
@ 2013-11-22 14:48 ` Sascha Hauer
2013-11-22 14:48 ` [PATCH 04/17] spi: omap: Add devicetree probe support Sascha Hauer
` (13 subsequent siblings)
16 siblings, 0 replies; 18+ messages in thread
From: Sascha Hauer @ 2013-11-22 14:48 UTC (permalink / raw)
To: barebox
The omap3 and omap4/am33xx spi cores differ in the offset of the
registers in the address space. Instead of encoding this into the
resources use the platform_device_id mechanism. This is done in
preparation for devicetree probe support where the address space
is in the devicetree and can't be adjusted.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
arch/arm/mach-omap/include/mach/am33xx-devices.h | 2 +-
drivers/spi/omap3_spi.c | 38 ++++++++++++++++++++++--
drivers/spi/omap3_spi.h | 6 +++-
3 files changed, 42 insertions(+), 4 deletions(-)
diff --git a/arch/arm/mach-omap/include/mach/am33xx-devices.h b/arch/arm/mach-omap/include/mach/am33xx-devices.h
index 6691980..d2411a4 100644
--- a/arch/arm/mach-omap/include/mach/am33xx-devices.h
+++ b/arch/arm/mach-omap/include/mach/am33xx-devices.h
@@ -45,7 +45,7 @@ static inline struct device_d *am33xx_add_cpsw(struct cpsw_platform_data *cpsw_d
static inline struct device_d *am33xx_add_spi(int id, resource_size_t start)
{
- return add_generic_device("omap3_spi", id, NULL, start + 0x100, SZ_4K - 0x100,
+ return add_generic_device("omap4-spi", id, NULL, start, SZ_4K,
IORESOURCE_MEM, NULL);
}
diff --git a/drivers/spi/omap3_spi.c b/drivers/spi/omap3_spi.c
index 5c8cc88..136fc18 100644
--- a/drivers/spi/omap3_spi.c
+++ b/drivers/spi/omap3_spi.c
@@ -49,6 +49,10 @@
#define SPI_XFER_BEGIN 0x01 /* Assert CS before transfer */
#define SPI_XFER_END 0x02 /* Deassert CS after transfer */
+struct omap_spi_drvdata {
+ unsigned register_offset;
+};
+
static void spi_reset(struct spi_master *master)
{
struct omap3_spi_master *omap3_master = container_of(master, struct omap3_spi_master, master);
@@ -343,6 +347,12 @@ static int omap3_spi_probe(struct device_d *dev)
{
struct spi_master *master;
struct omap3_spi_master *omap3_master;
+ struct omap_spi_drvdata *devtype;
+ int ret;
+
+ ret = dev_get_drvdata(dev, (unsigned long *)&devtype);
+ if (ret)
+ return ret;
omap3_master = xzalloc(sizeof(*omap3_master));
@@ -374,7 +384,10 @@ static int omap3_spi_probe(struct device_d *dev)
master->setup = omap3_spi_setup;
master->transfer = omap3_spi_transfer;
- omap3_master->regs = dev_request_mem_region(dev, 0);
+ omap3_master->base = dev_request_mem_region(dev, 0);
+ omap3_master->regs = omap3_master->base;
+
+ omap3_master->regs += devtype->register_offset;
spi_reset(master);
@@ -383,8 +396,29 @@ static int omap3_spi_probe(struct device_d *dev)
return 0;
}
+static struct omap_spi_drvdata omap3_data = {
+ .register_offset = 0x0,
+};
+
+static struct omap_spi_drvdata omap4_data = {
+ .register_offset = 0x100,
+};
+
+static struct platform_device_id omap_spi_ids[] = {
+ {
+ .name = "omap3-spi",
+ .driver_data = (unsigned long)&omap3_data,
+ }, {
+ .name = "omap4-spi",
+ .driver_data = (unsigned long)&omap4_data,
+ }, {
+ /* sentinel */
+ },
+};
+
static struct driver_d omap3_spi_driver = {
- .name = "omap3_spi",
+ .name = "omap-spi",
.probe = omap3_spi_probe,
+ .id_table = omap_spi_ids,
};
device_platform_driver(omap3_spi_driver);
diff --git a/drivers/spi/omap3_spi.h b/drivers/spi/omap3_spi.h
index 55fd2fc..ce4a29b 100644
--- a/drivers/spi/omap3_spi.h
+++ b/drivers/spi/omap3_spi.h
@@ -88,7 +88,11 @@
struct omap3_spi_master {
struct spi_master master;
- void __iomem *regs;
+ void __iomem *base; /* base of address space */
+ void __iomem *regs; /* actual start of registers, omap4/am33xx have an
+ * offset of 0x100 between start of register space
+ * and registers
+ */
};
#endif /* _OMAP3_SPI_H_ */
--
1.8.4.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 04/17] spi: omap: Add devicetree probe support
2013-11-22 14:48 Add devicetree support to OMAP drivers Sascha Hauer
` (2 preceding siblings ...)
2013-11-22 14:48 ` [PATCH 03/17] spi: omap: encode register offset into device_id Sascha Hauer
@ 2013-11-22 14:48 ` Sascha Hauer
2013-11-22 14:48 ` [PATCH 05/17] i2c: omap: Add devicetree support Sascha Hauer
` (12 subsequent siblings)
16 siblings, 0 replies; 18+ messages in thread
From: Sascha Hauer @ 2013-11-22 14:48 UTC (permalink / raw)
To: barebox
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/spi/omap3_spi.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/drivers/spi/omap3_spi.c b/drivers/spi/omap3_spi.c
index 136fc18..073a98f 100644
--- a/drivers/spi/omap3_spi.c
+++ b/drivers/spi/omap3_spi.c
@@ -404,6 +404,18 @@ static struct omap_spi_drvdata omap4_data = {
.register_offset = 0x100,
};
+static __maybe_unused struct of_device_id omap_spi_dt_ids[] = {
+ {
+ .compatible = "ti,omap2-mcspi",
+ .data = (unsigned long)&omap3_data,
+ }, {
+ .compatible = "ti,omap4-mcspi",
+ .data = (unsigned long)&omap4_data,
+ }, {
+ /* sentinel */
+ }
+};
+
static struct platform_device_id omap_spi_ids[] = {
{
.name = "omap3-spi",
@@ -419,6 +431,7 @@ static struct platform_device_id omap_spi_ids[] = {
static struct driver_d omap3_spi_driver = {
.name = "omap-spi",
.probe = omap3_spi_probe,
+ .of_compatible = DRV_OF_COMPAT(omap_spi_dt_ids),
.id_table = omap_spi_ids,
};
device_platform_driver(omap3_spi_driver);
--
1.8.4.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 05/17] i2c: omap: Add devicetree support
2013-11-22 14:48 Add devicetree support to OMAP drivers Sascha Hauer
` (3 preceding siblings ...)
2013-11-22 14:48 ` [PATCH 04/17] spi: omap: Add devicetree probe support Sascha Hauer
@ 2013-11-22 14:48 ` Sascha Hauer
2013-11-22 14:48 ` [PATCH 06/17] net: cpsw: inline slave_data Sascha Hauer
` (11 subsequent siblings)
16 siblings, 0 replies; 18+ messages in thread
From: Sascha Hauer @ 2013-11-22 14:48 UTC (permalink / raw)
To: barebox
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/i2c/busses/i2c-omap.c | 28 +++++++++++++++++++++++++++-
1 file changed, 27 insertions(+), 1 deletion(-)
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index c45af92..f7108c2 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -151,6 +151,7 @@ struct omap_i2c_struct {
u8 reg_shift;
struct omap_i2c_driver_data *data;
struct resource *ioarea;
+ u32 fclk_rate;
u32 speed; /* Speed of bus in Khz */
u16 scheme;
u16 cmd_err;
@@ -271,6 +272,11 @@ static struct omap_i2c_driver_data am33xx_data = {
.fclk_rate = 48000,
};
+static struct omap_i2c_driver_data omap4_of_data = {
+ .flags = OMAP_I2C_FLAG_BUS_SHIFT_NONE,
+ .fclk_rate = 0,
+};
+
static inline void omap_i2c_write_reg(struct omap_i2c_struct *i2c_omap,
int reg, u16 val)
{
@@ -415,7 +421,7 @@ static int omap_i2c_init(struct omap_i2c_struct *i2c_omap)
internal_clk = 4000;
/* Compute prescaler divisor */
- psc = i2c_data->fclk_rate / internal_clk;
+ psc = i2c_omap->fclk_rate / internal_clk;
psc = psc - 1;
/* If configured for High Speed */
@@ -1074,6 +1080,12 @@ i2c_omap_probe(struct device_d *pdev)
i2c_omap->b_hw = 1; /* Enable hardware fixes */
}
+ i2c_omap->fclk_rate = i2c_data->fclk_rate;
+
+ if (!i2c_omap->fclk_rate)
+ of_property_read_u32(pdev->device_node, "clock-frequency",
+ &i2c_omap->fclk_rate);
+
/* reset ASAP, clearing any IRQs */
omap_i2c_init(i2c_omap);
@@ -1085,6 +1097,7 @@ i2c_omap_probe(struct device_d *pdev)
i2c_omap->adapter.master_xfer = omap_i2c_xfer,
i2c_omap->adapter.nr = pdev->id;
i2c_omap->adapter.dev.parent = pdev;
+ i2c_omap->adapter.dev.device_node = pdev->device_node;
/* i2c device drivers may be active on return from add_adapter() */
r = i2c_add_numbered_adapter(&i2c_omap->adapter);
@@ -1119,10 +1132,23 @@ static struct platform_device_id omap_i2c_ids[] = {
},
};
+static __maybe_unused struct of_device_id omap_spi_dt_ids[] = {
+ {
+ .compatible = "ti,omap3-i2c",
+ .data = (unsigned long)&omap3_data,
+ }, {
+ .compatible = "ti,omap4-i2c",
+ .data = (unsigned long)&omap4_of_data,
+ }, {
+ /* sentinel */
+ }
+};
+
static struct driver_d omap_i2c_driver = {
.probe = i2c_omap_probe,
.name = DRIVER_NAME,
.id_table = omap_i2c_ids,
+ .of_compatible = DRV_OF_COMPAT(omap_spi_dt_ids),
};
device_platform_driver(omap_i2c_driver);
--
1.8.4.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 06/17] net: cpsw: inline slave_data
2013-11-22 14:48 Add devicetree support to OMAP drivers Sascha Hauer
` (4 preceding siblings ...)
2013-11-22 14:48 ` [PATCH 05/17] i2c: omap: Add devicetree support Sascha Hauer
@ 2013-11-22 14:48 ` Sascha Hauer
2013-11-22 14:48 ` [PATCH 07/17] cpsw: Add devicetree probe support Sascha Hauer
` (10 subsequent siblings)
16 siblings, 0 replies; 18+ messages in thread
From: Sascha Hauer @ 2013-11-22 14:48 UTC (permalink / raw)
To: barebox
Devicetree probed cpsw devices won't have platform_data, so inline
the fields from slave_data instead of keeping a pointer.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/net/cpsw.c | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/drivers/net/cpsw.c b/drivers/net/cpsw.c
index e51a8b1..25ba3d9 100644
--- a/drivers/net/cpsw.c
+++ b/drivers/net/cpsw.c
@@ -175,7 +175,8 @@ struct cpsw_slave {
struct cpsw_sliver_regs *sliver;
int slave_num;
u32 mac_control;
- struct cpsw_slave_data *data;
+ int phy_id;
+ phy_interface_t phy_if;
};
struct cpdma_desc {
@@ -765,13 +766,13 @@ static int cpsw_init(struct eth_device *edev)
static int cpsw_open(struct eth_device *edev)
{
struct cpsw_priv *priv = edev->priv;
- struct cpsw_slave_data *slave_data = priv->data.slave_data;
+ struct cpsw_slave *slave = &priv->slaves[0];
int i, ret;
dev_dbg(priv->dev, "* %s\n", __func__);
- ret = phy_device_connect(edev, &priv->miibus, slave_data[0].phy_id,
- cpsw_adjust_link, 0, slave_data[0].phy_if);
+ ret = phy_device_connect(edev, &priv->miibus, slave->phy_id,
+ cpsw_adjust_link, 0, slave->phy_if);
if (ret)
return ret;
@@ -908,7 +909,8 @@ static void cpsw_slave_setup(struct cpsw_slave *slave, int slave_num,
dev_dbg(priv->dev, "* %s\n", __func__);
slave->slave_num = slave_num;
- slave->data = data;
+ slave->phy_id = data->phy_id;
+ slave->phy_if = data->phy_if;
slave->regs = regs + priv->slave_ofs + priv->slave_size * slave_num;
slave->sliver = regs + priv->sliver_ofs + SLIVER_SIZE * slave_num;
}
--
1.8.4.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 07/17] cpsw: Add devicetree probe support
2013-11-22 14:48 Add devicetree support to OMAP drivers Sascha Hauer
` (5 preceding siblings ...)
2013-11-22 14:48 ` [PATCH 06/17] net: cpsw: inline slave_data Sascha Hauer
@ 2013-11-22 14:48 ` Sascha Hauer
2013-11-22 14:48 ` [PATCH 08/17] net: cpsw: move eth_device into slave Sascha Hauer
` (9 subsequent siblings)
16 siblings, 0 replies; 18+ messages in thread
From: Sascha Hauer @ 2013-11-22 14:48 UTC (permalink / raw)
To: barebox
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/net/cpsw.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 81 insertions(+), 7 deletions(-)
diff --git a/drivers/net/cpsw.c b/drivers/net/cpsw.c
index 25ba3d9..f021f31 100644
--- a/drivers/net/cpsw.c
+++ b/drivers/net/cpsw.c
@@ -27,6 +27,8 @@
#include <linux/phy.h>
#include <errno.h>
#include <io.h>
+#include <of.h>
+#include <of_net.h>
#include <xfuncs.h>
#include <asm/mmu.h>
#include <asm/system.h>
@@ -900,17 +902,23 @@ static int cpsw_recv(struct eth_device *dev)
return 0;
}
+static void cpsw_slave_init_data(struct cpsw_slave *slave, int slave_num,
+ struct cpsw_priv *priv)
+{
+ struct cpsw_slave_data *data = priv->data.slave_data + slave_num;
+
+ slave->phy_id = data->phy_id;
+ slave->phy_if = data->phy_if;
+}
+
static void cpsw_slave_setup(struct cpsw_slave *slave, int slave_num,
struct cpsw_priv *priv)
{
void *regs = priv->regs;
- struct cpsw_slave_data *data = priv->data.slave_data + slave_num;
dev_dbg(priv->dev, "* %s\n", __func__);
slave->slave_num = slave_num;
- slave->phy_id = data->phy_id;
- slave->phy_if = data->phy_if;
slave->regs = regs + priv->slave_ofs + priv->slave_size * slave_num;
slave->sliver = regs + priv->sliver_ofs + SLIVER_SIZE * slave_num;
}
@@ -950,6 +958,54 @@ static struct cpsw_data cpsw2_data = {
.cppi_ram_ofs = 0x2000,
};
+static int cpsw_phy_sel_init(struct cpsw_priv *priv, struct device_node *np)
+{
+ dev_info(priv->dev, "%s\n", __func__);
+ return 0;
+}
+
+static int cpsw_probe_dt(struct cpsw_priv *priv)
+{
+ struct device_d *dev = priv->dev;
+ struct device_node *np = dev->device_node, *child;
+ int ret, i = 0;
+
+ ret = of_property_read_u32(np, "slaves", &priv->num_slaves);
+ if (ret)
+ return ret;
+
+ priv->slaves = xzalloc(sizeof(struct cpsw_slave) * priv->num_slaves);
+
+ for_each_child_of_node(np, child) {
+ if (of_device_is_compatible(child, "ti,am3352-cpsw-phy-sel")) {
+ ret = cpsw_phy_sel_init(priv, child);
+ if (ret)
+ return ret;
+ }
+
+ if (!strncmp(child->name, "slave", 5)) {
+ struct cpsw_slave *slave = &priv->slaves[i];
+ uint32_t phy_id[2];
+
+ dev_info(dev, "found slave\n");
+
+ ret = of_property_read_u32_array(child, "phy_id", phy_id, 2);
+ if (ret)
+ return ret;
+
+ slave->phy_id = phy_id[1];
+ slave->phy_if = of_get_phy_mode(child);
+
+ i++;
+ }
+ }
+
+ /* Only one slave supported by this driver */
+ priv->num_slaves = 1;
+
+ return 0;
+}
+
int cpsw_probe(struct device_d *dev)
{
struct cpsw_platform_data *data = (struct cpsw_platform_data *)dev->platform_data;
@@ -959,6 +1015,7 @@ int cpsw_probe(struct device_d *dev)
uint64_t start;
uint32_t phy_mask;
struct cpsw_data *cpsw_data;
+ int ret;
dev_dbg(dev, "* %s\n", __func__);
@@ -966,14 +1023,22 @@ int cpsw_probe(struct device_d *dev)
priv = xzalloc(sizeof(*priv));
priv->dev = dev;
- priv->data = *data;
+
+ if (dev->device_node) {
+ ret = cpsw_probe_dt(priv);
+ if (ret)
+ return ret;
+ } else {
+ priv->data = *data;
+ priv->num_slaves = data->num_slaves;
+ priv->slaves = xzalloc(sizeof(struct cpsw_slave) * priv->num_slaves);
+ for_each_slave(priv, cpsw_slave_init_data, idx, priv);
+ }
+
priv->channels = 8;
- priv->num_slaves = data->num_slaves;
priv->ale_entries = 1024;
edev = &priv->edev;
- priv->slaves = xzalloc(sizeof(struct cpsw_slave) * priv->num_slaves);
-
priv->host_port = 0;
priv->regs = regs;
@@ -1059,8 +1124,17 @@ int cpsw_probe(struct device_d *dev)
return 0;
}
+static __maybe_unused struct of_device_id cpsw_dt_ids[] = {
+ {
+ .compatible = "ti,cpsw",
+ }, {
+ /* sentinel */
+ }
+};
+
static struct driver_d cpsw_driver = {
.name = "cpsw",
.probe = cpsw_probe,
+ .of_compatible = DRV_OF_COMPAT(cpsw_dt_ids),
};
device_platform_driver(cpsw_driver);
--
1.8.4.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 08/17] net: cpsw: move eth_device into slave
2013-11-22 14:48 Add devicetree support to OMAP drivers Sascha Hauer
` (6 preceding siblings ...)
2013-11-22 14:48 ` [PATCH 07/17] cpsw: Add devicetree probe support Sascha Hauer
@ 2013-11-22 14:48 ` Sascha Hauer
2013-11-22 14:48 ` [PATCH 09/17] net: cpsw: drop for_each_slave Sascha Hauer
` (8 subsequent siblings)
16 siblings, 0 replies; 18+ messages in thread
From: Sascha Hauer @ 2013-11-22 14:48 UTC (permalink / raw)
To: barebox
An ethernet device is per slave, not per cpsw.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/net/cpsw.c | 33 ++++++++++++++++-----------------
1 file changed, 16 insertions(+), 17 deletions(-)
diff --git a/drivers/net/cpsw.c b/drivers/net/cpsw.c
index f021f31..d969654 100644
--- a/drivers/net/cpsw.c
+++ b/drivers/net/cpsw.c
@@ -179,6 +179,7 @@ struct cpsw_slave {
u32 mac_control;
int phy_id;
phy_interface_t phy_if;
+ struct eth_device edev;
};
struct cpdma_desc {
@@ -199,7 +200,6 @@ struct cpdma_chan {
struct cpsw_priv {
struct device_d *dev;
- struct eth_device edev;
struct mii_bus miibus;
u32 version;
@@ -575,7 +575,7 @@ static int cpsw_set_hwaddr(struct eth_device *edev, unsigned char *mac)
static void cpsw_slave_update_link(struct cpsw_slave *slave,
struct cpsw_priv *priv, int *link)
{
- struct phy_device *phydev = priv->edev.phydev;
+ struct phy_device *phydev = slave->edev.phydev;
u32 mac_control = 0;
dev_dbg(priv->dev, "* %s\n", __func__);
@@ -915,12 +915,25 @@ static void cpsw_slave_setup(struct cpsw_slave *slave, int slave_num,
struct cpsw_priv *priv)
{
void *regs = priv->regs;
+ struct eth_device *edev = &slave->edev;
dev_dbg(priv->dev, "* %s\n", __func__);
slave->slave_num = slave_num;
slave->regs = regs + priv->slave_ofs + priv->slave_size * slave_num;
slave->sliver = regs + priv->sliver_ofs + SLIVER_SIZE * slave_num;
+
+ edev->priv = priv;
+ edev->init = cpsw_init;
+ edev->open = cpsw_open;
+ edev->halt = cpsw_halt;
+ edev->send = cpsw_send;
+ edev->recv = cpsw_recv;
+ edev->get_ethaddr = cpsw_get_hwaddr;
+ edev->set_ethaddr = cpsw_set_hwaddr;
+ edev->parent = priv->dev;
+
+ eth_register(edev);
}
struct cpsw_data {
@@ -1011,7 +1024,6 @@ int cpsw_probe(struct device_d *dev)
struct cpsw_platform_data *data = (struct cpsw_platform_data *)dev->platform_data;
struct cpsw_priv *priv;
void __iomem *regs;
- struct eth_device *edev;
uint64_t start;
uint32_t phy_mask;
struct cpsw_data *cpsw_data;
@@ -1037,7 +1049,6 @@ int cpsw_probe(struct device_d *dev)
priv->channels = 8;
priv->ale_entries = 1024;
- edev = &priv->edev;
priv->host_port = 0;
priv->regs = regs;
@@ -1066,18 +1077,6 @@ int cpsw_probe(struct device_d *dev)
priv->slave_size = cpsw_data->slave_size;
priv->sliver_ofs = cpsw_data->sliver_ofs;
- for_each_slave(priv, cpsw_slave_setup, idx, priv);
-
- edev->priv = priv;
- edev->init = cpsw_init;
- edev->open = cpsw_open;
- edev->halt = cpsw_halt;
- edev->send = cpsw_send;
- edev->recv = cpsw_recv;
- edev->get_ethaddr = cpsw_get_hwaddr;
- edev->set_ethaddr = cpsw_set_hwaddr;
- edev->parent = dev;
-
priv->miibus.read = cpsw_mdio_read;
priv->miibus.write = cpsw_mdio_write;
priv->miibus.priv = priv;
@@ -1119,7 +1118,7 @@ int cpsw_probe(struct device_d *dev)
mdiobus_register(&priv->miibus);
- eth_register(edev);
+ for_each_slave(priv, cpsw_slave_setup, idx, priv);
return 0;
}
--
1.8.4.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 09/17] net: cpsw: drop for_each_slave
2013-11-22 14:48 Add devicetree support to OMAP drivers Sascha Hauer
` (7 preceding siblings ...)
2013-11-22 14:48 ` [PATCH 08/17] net: cpsw: move eth_device into slave Sascha Hauer
@ 2013-11-22 14:48 ` Sascha Hauer
2013-11-22 14:48 ` [PATCH 10/17] net: cpsw: attach slave to edev->priv Sascha Hauer
` (7 subsequent siblings)
16 siblings, 0 replies; 18+ messages in thread
From: Sascha Hauer @ 2013-11-22 14:48 UTC (permalink / raw)
To: barebox
We currently only use one slave, so drop for_each_slave and hardcode
slave[0] until we pass the proper context to the functions that makes
this hack unnecessary.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/net/cpsw.c | 40 ++++++++++++++--------------------------
1 file changed, 14 insertions(+), 26 deletions(-)
diff --git a/drivers/net/cpsw.c b/drivers/net/cpsw.c
index d969654..fcb1f66 100644
--- a/drivers/net/cpsw.c
+++ b/drivers/net/cpsw.c
@@ -226,12 +226,6 @@ struct cpsw_priv {
struct cpdma_chan rx_chan, tx_chan;
struct cpsw_slave *slaves;
-#define for_each_slave(priv, func, arg...) \
- do { \
- int idx; \
- for (idx = 0; idx < (priv)->num_slaves; idx++) \
- (func)((priv)->slaves + idx, ##arg); \
- } while (0)
};
static int cpsw_ale_get_field(u32 *ale_entry, u32 start, u32 bits)
@@ -540,16 +534,6 @@ static inline void soft_reset(struct cpsw_priv *priv, void *reg)
((mac)[2] << 16) | ((mac)[3] << 24))
#define mac_lo(mac) (((mac)[4] << 0) | ((mac)[5] << 8))
-static void cpsw_set_slave_mac(struct cpsw_slave *slave,
- struct cpsw_priv *priv,
- unsigned char *mac)
-{
- dev_dbg(priv->dev, "* %s\n", __func__);
-
- writel(mac_hi(mac), &slave->regs->sa_hi);
- writel(mac_lo(mac), &slave->regs->sa_lo);
-}
-
static int cpsw_get_hwaddr(struct eth_device *edev, unsigned char *mac)
{
struct cpsw_priv *priv = edev->priv;
@@ -562,12 +546,14 @@ static int cpsw_get_hwaddr(struct eth_device *edev, unsigned char *mac)
static int cpsw_set_hwaddr(struct eth_device *edev, unsigned char *mac)
{
struct cpsw_priv *priv = edev->priv;
+ struct cpsw_slave *slave = &priv->slaves[0];
dev_dbg(priv->dev, "* %s\n", __func__);
memcpy(&priv->mac_addr, mac, sizeof(priv->mac_addr));
- for_each_slave(priv, cpsw_set_slave_mac, priv, mac);
+ writel(mac_hi(mac), &slave->regs->sa_hi);
+ writel(mac_lo(mac), &slave->regs->sa_lo);
return 0;
}
@@ -615,22 +601,25 @@ static void cpsw_slave_update_link(struct cpsw_slave *slave,
slave->mac_control = mac_control;
}
-static int cpsw_update_link(struct cpsw_priv *priv)
+static int cpsw_update_link(struct cpsw_slave *slave, struct cpsw_priv *priv)
{
int link = 0;
dev_dbg(priv->dev, "* %s\n", __func__);
- for_each_slave(priv, cpsw_slave_update_link, priv, &link);
+ cpsw_slave_update_link(slave, priv, &link);
+
return link;
}
-static void cpsw_adjust_link(struct eth_device *edev) {
+static void cpsw_adjust_link(struct eth_device *edev)
+{
struct cpsw_priv *priv = edev->priv;
+ struct cpsw_slave *slave = &priv->slaves[0];
dev_dbg(priv->dev, "* %s\n", __func__);
- cpsw_update_link(priv);
+ cpsw_update_link(slave, priv);
}
static inline u32 cpsw_get_slave_port(struct cpsw_priv *priv, u32 slave_num)
@@ -803,9 +792,8 @@ static int cpsw_open(struct eth_device *edev)
ALE_SECURE);
cpsw_ale_add_mcast(priv, ethbdaddr, 1 << priv->host_port);
- for_each_slave(priv, cpsw_slave_init, priv);
-
- cpsw_update_link(priv);
+ cpsw_slave_init(&priv->slaves[0], priv);
+ cpsw_update_link(&priv->slaves[0], priv);
/* init descriptor pool */
for (i = 0; i < NUM_DESCS; i++) {
@@ -1044,7 +1032,7 @@ int cpsw_probe(struct device_d *dev)
priv->data = *data;
priv->num_slaves = data->num_slaves;
priv->slaves = xzalloc(sizeof(struct cpsw_slave) * priv->num_slaves);
- for_each_slave(priv, cpsw_slave_init_data, idx, priv);
+ cpsw_slave_init_data(&priv->slaves[0], 0, priv);
}
priv->channels = 8;
@@ -1118,7 +1106,7 @@ int cpsw_probe(struct device_d *dev)
mdiobus_register(&priv->miibus);
- for_each_slave(priv, cpsw_slave_setup, idx, priv);
+ cpsw_slave_setup(&priv->slaves[0], 0, priv);
return 0;
}
--
1.8.4.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 10/17] net: cpsw: attach slave to edev->priv
2013-11-22 14:48 Add devicetree support to OMAP drivers Sascha Hauer
` (8 preceding siblings ...)
2013-11-22 14:48 ` [PATCH 09/17] net: cpsw: drop for_each_slave Sascha Hauer
@ 2013-11-22 14:48 ` Sascha Hauer
2013-11-22 14:48 ` [PATCH 11/17] net: cpsw: straighten error path Sascha Hauer
` (6 subsequent siblings)
16 siblings, 0 replies; 18+ messages in thread
From: Sascha Hauer @ 2013-11-22 14:48 UTC (permalink / raw)
To: barebox
An ethernet device belongs to a slave, so set edev->priv to the slave
and not to the cpsw.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/net/cpsw.c | 34 ++++++++++++++++++++--------------
1 file changed, 20 insertions(+), 14 deletions(-)
diff --git a/drivers/net/cpsw.c b/drivers/net/cpsw.c
index fcb1f66..a79859b 100644
--- a/drivers/net/cpsw.c
+++ b/drivers/net/cpsw.c
@@ -180,6 +180,7 @@ struct cpsw_slave {
int phy_id;
phy_interface_t phy_if;
struct eth_device edev;
+ struct cpsw_priv *cpsw;
};
struct cpdma_desc {
@@ -536,7 +537,8 @@ static inline void soft_reset(struct cpsw_priv *priv, void *reg)
static int cpsw_get_hwaddr(struct eth_device *edev, unsigned char *mac)
{
- struct cpsw_priv *priv = edev->priv;
+ struct cpsw_slave *slave = edev->priv;
+ struct cpsw_priv *priv = slave->cpsw;
dev_dbg(priv->dev, "* %s\n", __func__);
@@ -545,8 +547,8 @@ static int cpsw_get_hwaddr(struct eth_device *edev, unsigned char *mac)
static int cpsw_set_hwaddr(struct eth_device *edev, unsigned char *mac)
{
- struct cpsw_priv *priv = edev->priv;
- struct cpsw_slave *slave = &priv->slaves[0];
+ struct cpsw_slave *slave = edev->priv;
+ struct cpsw_priv *priv = slave->cpsw;
dev_dbg(priv->dev, "* %s\n", __func__);
@@ -614,8 +616,8 @@ static int cpsw_update_link(struct cpsw_slave *slave, struct cpsw_priv *priv)
static void cpsw_adjust_link(struct eth_device *edev)
{
- struct cpsw_priv *priv = edev->priv;
- struct cpsw_slave *slave = &priv->slaves[0];
+ struct cpsw_slave *slave = edev->priv;
+ struct cpsw_priv *priv = slave->cpsw;
dev_dbg(priv->dev, "* %s\n", __func__);
@@ -756,8 +758,8 @@ static int cpsw_init(struct eth_device *edev)
static int cpsw_open(struct eth_device *edev)
{
- struct cpsw_priv *priv = edev->priv;
- struct cpsw_slave *slave = &priv->slaves[0];
+ struct cpsw_slave *slave = edev->priv;
+ struct cpsw_priv *priv = slave->cpsw;
int i, ret;
dev_dbg(priv->dev, "* %s\n", __func__);
@@ -841,9 +843,10 @@ static int cpsw_open(struct eth_device *edev)
return 0;
}
-static void cpsw_halt(struct eth_device *dev)
+static void cpsw_halt(struct eth_device *edev)
{
- struct cpsw_priv *priv = dev->priv;
+ struct cpsw_slave *slave = edev->priv;
+ struct cpsw_priv *priv = slave->cpsw;
writel(0, priv->dma_regs + CPDMA_TXCONTROL);
writel(0, priv->dma_regs + CPDMA_RXCONTROL);
@@ -855,9 +858,10 @@ static void cpsw_halt(struct eth_device *dev)
soft_reset(priv, priv->dma_regs + CPDMA_SOFTRESET);
}
-static int cpsw_send(struct eth_device *dev, void *packet, int length)
+static int cpsw_send(struct eth_device *edev, void *packet, int length)
{
- struct cpsw_priv *priv = dev->priv;
+ struct cpsw_slave *slave = edev->priv;
+ struct cpsw_priv *priv = slave->cpsw;
void *buffer;
int ret, len;
@@ -875,9 +879,10 @@ static int cpsw_send(struct eth_device *dev, void *packet, int length)
return ret;
}
-static int cpsw_recv(struct eth_device *dev)
+static int cpsw_recv(struct eth_device *edev)
{
- struct cpsw_priv *priv = dev->priv;
+ struct cpsw_slave *slave = edev->priv;
+ struct cpsw_priv *priv = slave->cpsw;
void *buffer;
int len;
@@ -910,8 +915,9 @@ static void cpsw_slave_setup(struct cpsw_slave *slave, int slave_num,
slave->slave_num = slave_num;
slave->regs = regs + priv->slave_ofs + priv->slave_size * slave_num;
slave->sliver = regs + priv->sliver_ofs + SLIVER_SIZE * slave_num;
+ slave->cpsw = priv;
- edev->priv = priv;
+ edev->priv = slave;
edev->init = cpsw_init;
edev->open = cpsw_open;
edev->halt = cpsw_halt;
--
1.8.4.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 11/17] net: cpsw: straighten error path
2013-11-22 14:48 Add devicetree support to OMAP drivers Sascha Hauer
` (9 preceding siblings ...)
2013-11-22 14:48 ` [PATCH 10/17] net: cpsw: attach slave to edev->priv Sascha Hauer
@ 2013-11-22 14:48 ` Sascha Hauer
2013-11-22 14:48 ` [PATCH 12/17] gpio: omap: move to drivers/gpio/ Sascha Hauer
` (5 subsequent siblings)
16 siblings, 0 replies; 18+ messages in thread
From: Sascha Hauer @ 2013-11-22 14:48 UTC (permalink / raw)
To: barebox
This mainly has the effect of checking the return value of eth_register.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/net/cpsw.c | 18 +++++++++++++-----
1 file changed, 13 insertions(+), 5 deletions(-)
diff --git a/drivers/net/cpsw.c b/drivers/net/cpsw.c
index a79859b..9f79bd9 100644
--- a/drivers/net/cpsw.c
+++ b/drivers/net/cpsw.c
@@ -904,7 +904,7 @@ static void cpsw_slave_init_data(struct cpsw_slave *slave, int slave_num,
slave->phy_if = data->phy_if;
}
-static void cpsw_slave_setup(struct cpsw_slave *slave, int slave_num,
+static int cpsw_slave_setup(struct cpsw_slave *slave, int slave_num,
struct cpsw_priv *priv)
{
void *regs = priv->regs;
@@ -927,7 +927,7 @@ static void cpsw_slave_setup(struct cpsw_slave *slave, int slave_num,
edev->set_ethaddr = cpsw_set_hwaddr;
edev->parent = priv->dev;
- eth_register(edev);
+ return eth_register(edev);
}
struct cpsw_data {
@@ -1033,7 +1033,7 @@ int cpsw_probe(struct device_d *dev)
if (dev->device_node) {
ret = cpsw_probe_dt(priv);
if (ret)
- return ret;
+ goto out;
} else {
priv->data = *data;
priv->num_slaves = data->num_slaves;
@@ -1057,7 +1057,8 @@ int cpsw_probe(struct device_d *dev)
cpsw_data = &cpsw2_data;
break;
default:
- return -EINVAL;
+ ret = -EINVAL;
+ goto out;
}
priv->descs = regs + cpsw_data->cppi_ram_ofs;
@@ -1112,9 +1113,16 @@ int cpsw_probe(struct device_d *dev)
mdiobus_register(&priv->miibus);
- cpsw_slave_setup(&priv->slaves[0], 0, priv);
+ ret = cpsw_slave_setup(&priv->slaves[0], 0, priv);
+ if (ret)
+ goto out;
return 0;
+out:
+ free(priv->slaves);
+ free(priv);
+
+ return ret;
}
static __maybe_unused struct of_device_id cpsw_dt_ids[] = {
--
1.8.4.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 12/17] gpio: omap: move to drivers/gpio/
2013-11-22 14:48 Add devicetree support to OMAP drivers Sascha Hauer
` (10 preceding siblings ...)
2013-11-22 14:48 ` [PATCH 11/17] net: cpsw: straighten error path Sascha Hauer
@ 2013-11-22 14:48 ` Sascha Hauer
2013-11-22 14:48 ` [PATCH 13/17] omap: gpmc: some refactoring Sascha Hauer
` (4 subsequent siblings)
16 siblings, 0 replies; 18+ messages in thread
From: Sascha Hauer @ 2013-11-22 14:48 UTC (permalink / raw)
To: barebox
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
arch/arm/mach-omap/Makefile | 1 -
drivers/gpio/Kconfig | 3 +++
drivers/gpio/Makefile | 1 +
arch/arm/mach-omap/gpio.c => drivers/gpio/gpio-omap.c | 0
4 files changed, 4 insertions(+), 1 deletion(-)
rename arch/arm/mach-omap/gpio.c => drivers/gpio/gpio-omap.c (100%)
diff --git a/arch/arm/mach-omap/Makefile b/arch/arm/mach-omap/Makefile
index cf2d5ee..06999b3 100644
--- a/arch/arm/mach-omap/Makefile
+++ b/arch/arm/mach-omap/Makefile
@@ -31,5 +31,4 @@ obj-$(CONFIG_SHELL_NONE) += xload.o
obj-$(CONFIG_MFD_TWL6030) += omap4_twl6030_mmc.o
obj-$(CONFIG_OMAP4_USBBOOT) += omap4_rom_usb.o
obj-$(CONFIG_CMD_BOOT_ORDER) += boot_order.o
-obj-y += gpio.o
obj-$(CONFIG_BAREBOX_UPDATE_AM33XX_SPI_NOR_MLO) += am33xx_bbu_spi_mlo.o
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 18d3135..7c42656 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -30,6 +30,9 @@ config GPIO_GENERIC_PLATFORM
config GPIO_IMX
def_bool ARCH_IMX
+config GPIO_OMAP
+ def_bool ARCH_OMAP
+
config GPIO_ORION
bool "GPIO support for Marvell Orion/MVEBU SoCs"
depends on ARCH_MVEBU
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index dc9fb13..b7c536d 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -5,6 +5,7 @@ obj-$(CONFIG_GPIO_CLPS711X) += gpio-clps711x.o
obj-$(CONFIG_GPIO_GENERIC) += gpio-generic.o
obj-$(CONFIG_GPIO_IMX) += gpio-imx.o
obj-$(CONFIG_GPIO_ORION) += gpio-orion.o
+obj-$(CONFIG_GPIO_OMAP) += gpio-omap.o
obj-$(CONFIG_GPIO_PL061) += gpio-pl061.o
obj-$(CONFIG_GPIO_STMPE) += gpio-stmpe.o
obj-$(CONFIG_GPIO_TEGRA) += gpio-tegra.o
diff --git a/arch/arm/mach-omap/gpio.c b/drivers/gpio/gpio-omap.c
similarity index 100%
rename from arch/arm/mach-omap/gpio.c
rename to drivers/gpio/gpio-omap.c
--
1.8.4.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 13/17] omap: gpmc: some refactoring
2013-11-22 14:48 Add devicetree support to OMAP drivers Sascha Hauer
` (11 preceding siblings ...)
2013-11-22 14:48 ` [PATCH 12/17] gpio: omap: move to drivers/gpio/ Sascha Hauer
@ 2013-11-22 14:48 ` Sascha Hauer
2013-11-22 14:48 ` [PATCH 14/17] gpio: omap: Add devicetree probe support Sascha Hauer
` (3 subsequent siblings)
16 siblings, 0 replies; 18+ messages in thread
From: Sascha Hauer @ 2013-11-22 14:48 UTC (permalink / raw)
To: barebox
- make debug messages more meaningful
- calculate value once and use it to print and configure instead
of calculating it twice
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
arch/arm/mach-omap/gpmc.c | 25 ++++++++++++++-----------
1 file changed, 14 insertions(+), 11 deletions(-)
diff --git a/arch/arm/mach-omap/gpmc.c b/arch/arm/mach-omap/gpmc.c
index bb84b38..dae7630 100644
--- a/arch/arm/mach-omap/gpmc.c
+++ b/arch/arm/mach-omap/gpmc.c
@@ -111,7 +111,10 @@ void gpmc_cs_config(char cs, struct gpmc_config *config)
{
void __iomem *reg = GPMC_REG(CONFIG1_0) + (cs * GPMC_CONFIG_CS_SIZE);
unsigned char x = 0;
- debug("gpmccs=0x%x cfg=0x%p\n", cs, config);
+ uint32_t config7;
+
+ debug("%s: cs=%d base=0x%08x size=0x%08x\n", __func__,
+ cs, config->base, config->size);
/* Disable the CS before reconfiguring */
writel(0x0, GPMC_REG(CONFIG7_0) + (cs * GPMC_CONFIG_CS_SIZE));
@@ -119,22 +122,22 @@ void gpmc_cs_config(char cs, struct gpmc_config *config)
/* Write the CFG1-6 regs */
while (x < 6) {
- debug("gpmccfg%d Reg:0x%p <-0x%08x\n",
- x, reg, config->cfg[x]);
+ debug("gpmccfg%d Reg:0x%p <-0x%08x, old 0x%08x\n",
+ x, reg, config->cfg[x], readl(reg));
writel(config->cfg[x], reg);
reg += GPMC_CONFIG_REG_OFF;
x++;
}
- /* reg now points to CFG7 */
- debug("gpmccfg%d Reg:0x%p <-0x%08x\n",
- x, reg, (0x1 << 6) | /* CS enable */
- ((config->size & 0xF) << 8) | /* Size */
- ((config->base >> 24) & 0x3F));
- writel((0x1 << 6) | /* CS enable */
+ config7 = (0x1 << 6) | /* CS enable */
((config->size & 0xF) << 8) | /* Size */
- ((config->base >> 24) & 0x3F), /* Address */
- reg);
+ ((config->base >> 24) & 0x3F);
+
+ debug("gpmccfg%d Reg:0x%p <-0x%08x, old 0x%08x\n",
+ x, reg, config7, readl(reg));
+
+ writel(config7, reg);
+
mdelay(1); /* Settling time */
}
EXPORT_SYMBOL(gpmc_cs_config);
--
1.8.4.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 14/17] gpio: omap: Add devicetree probe support
2013-11-22 14:48 Add devicetree support to OMAP drivers Sascha Hauer
` (12 preceding siblings ...)
2013-11-22 14:48 ` [PATCH 13/17] omap: gpmc: some refactoring Sascha Hauer
@ 2013-11-22 14:48 ` Sascha Hauer
2013-11-22 14:48 ` [PATCH 15/17] mtd: omap gpmc: Use dev_add_param_enum Sascha Hauer
` (2 subsequent siblings)
16 siblings, 0 replies; 18+ messages in thread
From: Sascha Hauer @ 2013-11-22 14:48 UTC (permalink / raw)
To: barebox
This adds devicetree probe support for the OMAP gpio ports and
also makes sure the corresponding platform_devices don't get
registered when they are already present from devicetree.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/gpio/gpio-omap.c | 39 ++++++++++++++++++++++++++++++++++++++-
1 file changed, 38 insertions(+), 1 deletion(-)
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
index 49ffbda..e66a614 100644
--- a/drivers/gpio/gpio-omap.c
+++ b/drivers/gpio/gpio-omap.c
@@ -48,6 +48,18 @@ struct omap_gpio_chip {
struct gpio_chip chip;
};
+struct omap_gpio_drvdata {
+ unsigned int regofs;
+};
+
+static struct omap_gpio_drvdata gpio_omap3_drvdata = {
+ .regofs = 0x0,
+};
+
+static struct omap_gpio_drvdata gpio_omap4_drvdata = {
+ .regofs = 0x100,
+};
+
static inline int omap_get_gpio_index(int gpio)
{
return gpio & 0x1f;
@@ -129,11 +141,24 @@ static struct gpio_ops omap_gpio_ops = {
static int omap_gpio_probe(struct device_d *dev)
{
struct omap_gpio_chip *omapgpio;
+ struct omap_gpio_drvdata *drvdata = NULL;
+
+ dev_get_drvdata(dev, (unsigned long *)&drvdata);
omapgpio = xzalloc(sizeof(*omapgpio));
omapgpio->base = dev_request_mem_region(dev, 0);
+ if (drvdata)
+ omapgpio->base += drvdata->regofs;
+
omapgpio->chip.ops = &omap_gpio_ops;
- omapgpio->chip.base = dev->id * 32;
+ if (dev->id < 0) {
+ omapgpio->chip.base = of_alias_get_id(dev->device_node, "gpio");
+ if (omapgpio->chip.base < 0)
+ return omapgpio->chip.base;
+ omapgpio->chip.base *= 32;
+ } else {
+ omapgpio->chip.base = dev->id * 32;
+ }
omapgpio->chip.ngpio = 32;
omapgpio->chip.dev = dev;
gpiochip_add(&omapgpio->chip);
@@ -144,9 +169,21 @@ static int omap_gpio_probe(struct device_d *dev)
return 0;
}
+static __maybe_unused struct of_device_id omap_gpio_dt_ids[] = {
+ {
+ .compatible = "ti,omap4-gpio",
+ .data = (unsigned long)&gpio_omap4_drvdata,
+ }, {
+ .compatible = "ti,omap3-gpio",
+ .data = (unsigned long)&gpio_omap3_drvdata,
+ }, {
+ }
+};
+
static struct driver_d omap_gpio_driver = {
.name = "omap-gpio",
.probe = omap_gpio_probe,
+ .of_compatible = DRV_OF_COMPAT(omap_gpio_dt_ids),
};
static int omap_gpio_add(void)
--
1.8.4.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 15/17] mtd: omap gpmc: Use dev_add_param_enum
2013-11-22 14:48 Add devicetree support to OMAP drivers Sascha Hauer
` (13 preceding siblings ...)
2013-11-22 14:48 ` [PATCH 14/17] gpio: omap: Add devicetree probe support Sascha Hauer
@ 2013-11-22 14:48 ` Sascha Hauer
2013-11-22 14:49 ` [PATCH 16/17] bus: Add omap gpmc driver Sascha Hauer
2013-11-22 14:49 ` [PATCH 17/17] mmc: omap: Add devicetree support Sascha Hauer
16 siblings, 0 replies; 18+ messages in thread
From: Sascha Hauer @ 2013-11-22 14:48 UTC (permalink / raw)
To: barebox
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/mtd/nand/nand_omap_gpmc.c | 36 ++++++++++--------------------------
1 file changed, 10 insertions(+), 26 deletions(-)
diff --git a/drivers/mtd/nand/nand_omap_gpmc.c b/drivers/mtd/nand/nand_omap_gpmc.c
index 448e7b9..3053a8e 100644
--- a/drivers/mtd/nand/nand_omap_gpmc.c
+++ b/drivers/mtd/nand/nand_omap_gpmc.c
@@ -90,7 +90,7 @@
int omap_gpmc_decode_bch(int select_4_8, unsigned char *ecc, unsigned int *err_loc);
-static char *ecc_mode_strings[] = {
+static const char *ecc_mode_strings[] = {
"software",
"hamming_hw_romcode",
"bch4_hw",
@@ -861,29 +861,11 @@ static int omap_gpmc_eccmode(struct gpmc_nand_info *oinfo,
return 0;
}
-static int omap_gpmc_eccmode_set(struct device_d *dev, struct param_d *param, const char *val)
+static int omap_gpmc_eccmode_set(struct param_d *param, void *priv)
{
- struct gpmc_nand_info *oinfo = dev->priv;
- int i;
-
- if (!val)
- return 0;
-
- for (i = 0; i < ARRAY_SIZE(ecc_mode_strings); i++)
- if (!strcmp(ecc_mode_strings[i], val))
- break;
+ struct gpmc_nand_info *oinfo = priv;
- if (i == ARRAY_SIZE(ecc_mode_strings)) {
- dev_err(dev, "invalid ecc mode '%s'\n", val);
- printf("valid modes:\n");
- for (i = 0; i < ARRAY_SIZE(ecc_mode_strings); i++)
- printf("%s\n", ecc_mode_strings[i]);
- return -EINVAL;
- }
-
- dev_param_set_generic(dev, param, ecc_mode_strings[i]);
-
- return omap_gpmc_eccmode(oinfo, i);
+ return omap_gpmc_eccmode(oinfo, oinfo->ecc_mode);
}
static int gpmc_set_buswidth(struct nand_chip *chip, int buswidth)
@@ -1062,11 +1044,13 @@ static int gpmc_nand_probe(struct device_d *pdev)
nand->options |= NAND_SKIP_BBTSCAN;
- dev_add_param(pdev, "eccmode", omap_gpmc_eccmode_set, NULL, 0);
- dev_set_param(pdev, "eccmode", ecc_mode_strings[pdata->ecc_mode]);
+ oinfo->ecc_mode = pdata->ecc_mode;
+
+ dev_add_param_enum(pdev, "eccmode",
+ omap_gpmc_eccmode_set, NULL, (int *)&oinfo->ecc_mode,
+ ecc_mode_strings, ARRAY_SIZE(ecc_mode_strings), oinfo);
- if (! IS_ENABLED(CONFIG_PARAMETER))
- omap_gpmc_eccmode(oinfo, pdata->ecc_mode);
+ omap_gpmc_eccmode(oinfo, oinfo->ecc_mode);
/* We are all set to register with the system now! */
err = add_mtd_nand_device(minfo, "nand");
--
1.8.4.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 16/17] bus: Add omap gpmc driver
2013-11-22 14:48 Add devicetree support to OMAP drivers Sascha Hauer
` (14 preceding siblings ...)
2013-11-22 14:48 ` [PATCH 15/17] mtd: omap gpmc: Use dev_add_param_enum Sascha Hauer
@ 2013-11-22 14:49 ` Sascha Hauer
2013-11-22 14:49 ` [PATCH 17/17] mmc: omap: Add devicetree support Sascha Hauer
16 siblings, 0 replies; 18+ messages in thread
From: Sascha Hauer @ 2013-11-22 14:49 UTC (permalink / raw)
To: barebox
This adds a devicetree-only driver for to configure the gpmc and its
child devices from dt. Currently only NAND is supported.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
arch/arm/mach-omap/include/mach/gpmc_nand.h | 3 +
drivers/bus/Kconfig | 6 +
drivers/bus/Makefile | 1 +
drivers/bus/omap-gpmc.c | 481 ++++++++++++++++++++++++++++
4 files changed, 491 insertions(+)
create mode 100644 drivers/bus/omap-gpmc.c
diff --git a/arch/arm/mach-omap/include/mach/gpmc_nand.h b/arch/arm/mach-omap/include/mach/gpmc_nand.h
index 8d138ec..8839486 100644
--- a/arch/arm/mach-omap/include/mach/gpmc_nand.h
+++ b/arch/arm/mach-omap/include/mach/gpmc_nand.h
@@ -59,6 +59,9 @@ struct gpmc_nand_platform_data {
struct nand_ecclayout *oob;
/** gpmc config for nand */
struct gpmc_config *nand_cfg;
+
+ struct device_node *of_node;
+ struct device_node *elm_of_node;
};
int omap_add_gpmc_nand_device(struct gpmc_nand_platform_data *pdata);
diff --git a/drivers/bus/Kconfig b/drivers/bus/Kconfig
index 5938d3f..b0d3c1f 100644
--- a/drivers/bus/Kconfig
+++ b/drivers/bus/Kconfig
@@ -4,4 +4,10 @@ config IMX_WEIM
depends on ARCH_IMX
bool "i.MX WEIM driver"
+config BUS_OMAP_GPMC
+ depends on ARCH_OMAP
+ depends on OFDEVICE
+ depends on OMAP_GPMC
+ bool "TI OMAP/AM33xx GPMC support"
+
endmenu
diff --git a/drivers/bus/Makefile b/drivers/bus/Makefile
index 42a8d49..f1c5ac7 100644
--- a/drivers/bus/Makefile
+++ b/drivers/bus/Makefile
@@ -1 +1,2 @@
obj-$(CONFIG_IMX_WEIM) += imx-weim.o
+obj-$(CONFIG_BUS_OMAP_GPMC) += omap-gpmc.o
diff --git a/drivers/bus/omap-gpmc.c b/drivers/bus/omap-gpmc.c
new file mode 100644
index 0000000..6fdaeb0
--- /dev/null
+++ b/drivers/bus/omap-gpmc.c
@@ -0,0 +1,481 @@
+/*
+ * OMAP GPMC driver. Based upon the corresponding Linux Code
+ *
+ * Copyright (C) 2013 Sascha Hauer, Pengutronix, <s.hauer@pengutronix.de>
+ *
+ * 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 <common.h>
+#include <driver.h>
+#include <malloc.h>
+#include <init.h>
+#include <io.h>
+#include <of.h>
+#include <of_address.h>
+#include <of_mtd.h>
+#include <linux/clk.h>
+#include <mach/gpmc_nand.h>
+#include <mach/gpmc.h>
+
+#define GPMC_CS_NUM 8
+#define GPMC_NR_WAITPINS 4
+
+#define GPMC_CONFIG1_WRAPBURST_SUPP (1 << 31)
+#define GPMC_CONFIG1_READMULTIPLE_SUPP (1 << 30)
+#define GPMC_CONFIG1_READTYPE_ASYNC (0 << 29)
+#define GPMC_CONFIG1_READTYPE_SYNC (1 << 29)
+#define GPMC_CONFIG1_WRITEMULTIPLE_SUPP (1 << 28)
+#define GPMC_CONFIG1_WRITETYPE_ASYNC (0 << 27)
+#define GPMC_CONFIG1_WRITETYPE_SYNC (1 << 27)
+#define GPMC_CONFIG1_CLKACTIVATIONTIME(val) ((val & 3) << 25)
+#define GPMC_CONFIG1_PAGE_LEN(val) ((val & 3) << 23)
+#define GPMC_CONFIG1_WAIT_READ_MON (1 << 22)
+#define GPMC_CONFIG1_WAIT_WRITE_MON (1 << 21)
+#define GPMC_CONFIG1_WAIT_MON_IIME(val) ((val & 3) << 18)
+#define GPMC_CONFIG1_WAIT_PIN_SEL(val) ((val & 3) << 16)
+#define GPMC_CONFIG1_DEVICESIZE(val) ((val & 3) << 12)
+#define GPMC_CONFIG1_DEVICESIZE_16 GPMC_CONFIG1_DEVICESIZE(1)
+#define GPMC_CONFIG1_DEVICETYPE(val) ((val & 3) << 10)
+#define GPMC_CONFIG1_DEVICETYPE_NOR GPMC_CONFIG1_DEVICETYPE(0)
+#define GPMC_CONFIG1_MUXTYPE(val) ((val & 3) << 8)
+#define GPMC_CONFIG1_TIME_PARA_GRAN (1 << 4)
+#define GPMC_CONFIG1_FCLK_DIV(val) (val & 3)
+#define GPMC_CONFIG1_FCLK_DIV2 (GPMC_CONFIG1_FCLK_DIV(1))
+#define GPMC_CONFIG1_FCLK_DIV3 (GPMC_CONFIG1_FCLK_DIV(2))
+#define GPMC_CONFIG1_FCLK_DIV4 (GPMC_CONFIG1_FCLK_DIV(3))
+#define GPMC_CONFIG2_CSEXTRADELAY (1 << 7)
+#define GPMC_CONFIG3_ADVEXTRADELAY (1 << 7)
+#define GPMC_CONFIG4_OEEXTRADELAY (1 << 7)
+#define GPMC_CONFIG4_WEEXTRADELAY (1 << 23)
+#define GPMC_CONFIG6_CYCLE2CYCLEDIFFCSEN (1 << 6)
+#define GPMC_CONFIG6_CYCLE2CYCLESAMECSEN (1 << 7)
+#define GPMC_CONFIG7_CSVALID (1 << 6)
+
+static unsigned int gpmc_cs_num = GPMC_CS_NUM;
+static unsigned int gpmc_nr_waitpins;
+static unsigned long gpmc_l3_clk = 100000000; /* This should be a proper clock */
+static void __iomem *gpmc_base;
+
+/* bool type time settings */
+struct gpmc_bool_timings {
+ bool cycle2cyclediffcsen;
+ bool cycle2cyclesamecsen;
+ bool we_extra_delay;
+ bool oe_extra_delay;
+ bool adv_extra_delay;
+ bool cs_extra_delay;
+ bool time_para_granularity;
+};
+
+/*
+ * Note that all values in this struct are in nanoseconds except sync_clk
+ * (which is in picoseconds), while the register values are in gpmc_fck cycles.
+ */
+struct gpmc_timings {
+ /* Minimum clock period for synchronous mode (in picoseconds) */
+ u32 sync_clk;
+
+ /* Chip-select signal timings corresponding to 1 */
+ u32 cs_on; /* Assertion time */
+ u32 cs_rd_off; /* Read deassertion time */
+ u32 cs_wr_off; /* Write deassertion time */
+
+ /* ADV signal timings corresponding to GPMC_CONFIG3 */
+ u32 adv_on; /* Assertion time */
+ u32 adv_rd_off; /* Read deassertion time */
+ u32 adv_wr_off; /* Write deassertion time */
+
+ /* WE signals timings corresponding to GPMC_CONFIG4 */
+ u32 we_on; /* WE assertion time */
+ u32 we_off; /* WE deassertion time */
+
+ /* OE signals timings corresponding to GPMC_CONFIG4 */
+ u32 oe_on; /* OE assertion time */
+ u32 oe_off; /* OE deassertion time */
+
+ /* Access time and cycle time timings corresponding to GPMC_CONFIG5 */
+ u32 page_burst_access; /* Multiple access word delay */
+ u32 access; /* Start-cycle to first data valid delay */
+ u32 rd_cycle; /* Total read cycle time */
+ u32 wr_cycle; /* Total write cycle time */
+
+ u32 bus_turnaround;
+ u32 cycle2cycle_delay;
+
+ u32 wait_monitoring;
+ u32 clk_activation;
+
+ /* The following are only on OMAP3430 */
+ u32 wr_access; /* WRACCESSTIME */
+ u32 wr_data_mux_bus; /* WRDATAONADMUXBUS */
+
+ struct gpmc_bool_timings bool_timings;
+};
+
+struct gpmc_settings {
+ bool burst_wrap; /* enables wrap bursting */
+ bool burst_read; /* enables read page/burst mode */
+ bool burst_write; /* enables write page/burst mode */
+ bool device_nand; /* device is NAND */
+ bool sync_read; /* enables synchronous reads */
+ bool sync_write; /* enables synchronous writes */
+ bool wait_on_read; /* monitor wait on reads */
+ bool wait_on_write; /* monitor wait on writes */
+ u32 burst_len; /* page/burst length */
+ u32 device_width; /* device bus width (8 or 16 bit) */
+ u32 mux_add_data; /* multiplex address & data */
+ u32 wait_pin; /* wait-pin to be used */
+};
+
+struct imx_gpmc {
+ struct device_d *dev;
+ void __iomem *base;
+ struct imx_gpmc_devtype *devtype;
+};
+
+static void gpmc_cs_bool_timings(struct gpmc_config *gpmc_config, const struct gpmc_bool_timings *p)
+{
+ if (p->time_para_granularity)
+ gpmc_config->cfg[0] |= GPMC_CONFIG1_TIME_PARA_GRAN;
+
+ if (p->cs_extra_delay)
+ gpmc_config->cfg[1] |= GPMC_CONFIG2_CSEXTRADELAY;
+ if (p->adv_extra_delay)
+ gpmc_config->cfg[2] |= GPMC_CONFIG3_ADVEXTRADELAY;
+ if (p->oe_extra_delay)
+ gpmc_config->cfg[3] |= GPMC_CONFIG4_OEEXTRADELAY;
+ if (p->we_extra_delay)
+ gpmc_config->cfg[3] |= GPMC_CONFIG4_OEEXTRADELAY;
+ if (p->cycle2cyclesamecsen)
+ gpmc_config->cfg[5] |= GPMC_CONFIG6_CYCLE2CYCLESAMECSEN;
+ if (p->cycle2cyclediffcsen)
+ gpmc_config->cfg[5] |= GPMC_CONFIG6_CYCLE2CYCLEDIFFCSEN;
+}
+
+static unsigned long gpmc_get_fclk_period(void)
+{
+ unsigned long rate = gpmc_l3_clk;
+
+ rate /= 1000;
+ rate = 1000000000 / rate; /* In picoseconds */
+
+ return rate;
+}
+
+static unsigned int gpmc_ns_to_ticks(unsigned int time_ns)
+{
+ unsigned long tick_ps;
+
+ /* Calculate in picosecs to yield more exact results */
+ tick_ps = gpmc_get_fclk_period();
+
+ return (time_ns * 1000 + tick_ps - 1) / tick_ps;
+}
+
+int gpmc_calc_divider(unsigned int sync_clk)
+{
+ int div;
+ u32 l;
+
+ l = sync_clk + (gpmc_get_fclk_period() - 1);
+ div = l / gpmc_get_fclk_period();
+ if (div > 4)
+ return -1;
+ if (div <= 0)
+ div = 1;
+
+ return div;
+}
+
+static int set_cfg(struct gpmc_config *gpmc_config, int reg,
+ int st_bit, int end_bit, int time)
+{
+ int ticks, mask, nr_bits;
+
+ if (time == 0)
+ ticks = 0;
+ else
+ ticks = gpmc_ns_to_ticks(time);
+
+ nr_bits = end_bit - st_bit + 1;
+ if (ticks >= 1 << nr_bits)
+ return -EINVAL;
+
+ mask = (1 << nr_bits) - 1;
+ gpmc_config->cfg[reg] &= ~(mask << st_bit);
+ gpmc_config->cfg[reg] |= ticks << st_bit;
+
+ return 0;
+}
+
+static int gpmc_timings_to_config(struct gpmc_config *gpmc_config, const struct gpmc_timings *t)
+{
+ int div, ret = 0;
+
+ div = gpmc_calc_divider(t->sync_clk);
+ if (div < 0)
+ return div;
+
+ ret |= set_cfg(gpmc_config, 0, 18, 19, t->wait_monitoring);
+ ret |= set_cfg(gpmc_config, 0, 25, 26, t->clk_activation);
+
+ ret |= set_cfg(gpmc_config, 1, 0, 3, t->cs_on);
+ ret |= set_cfg(gpmc_config, 1, 8, 12, t->cs_rd_off);
+ ret |= set_cfg(gpmc_config, 1, 16, 20, t->cs_wr_off);
+
+ ret |= set_cfg(gpmc_config, 2, 0, 3, t->adv_on);
+ ret |= set_cfg(gpmc_config, 2, 8, 12, t->adv_rd_off);
+ ret |= set_cfg(gpmc_config, 2, 16, 20, t->adv_wr_off);
+
+ ret |= set_cfg(gpmc_config, 3, 0, 3, t->oe_on);
+ ret |= set_cfg(gpmc_config, 3, 8, 12, t->oe_off);
+ ret |= set_cfg(gpmc_config, 3, 16, 19, t->we_on);
+ ret |= set_cfg(gpmc_config, 3, 24, 28, t->we_off);
+
+ ret |= set_cfg(gpmc_config, 4, 0, 4, t->rd_cycle);
+ ret |= set_cfg(gpmc_config, 4, 8, 12, t->wr_cycle);
+ ret |= set_cfg(gpmc_config, 4, 16, 20, t->access);
+
+ ret |= set_cfg(gpmc_config, 4, 24, 27, t->page_burst_access);
+
+ ret |= set_cfg(gpmc_config, 5, 0, 3, t->bus_turnaround);
+ ret |= set_cfg(gpmc_config, 5, 8, 11, t->cycle2cycle_delay);
+ ret |= set_cfg(gpmc_config, 5, 16, 19, t->wr_data_mux_bus);
+ ret |= set_cfg(gpmc_config, 5, 24, 28, t->wr_access);
+
+ if (ret)
+ return ret;
+
+ gpmc_cs_bool_timings(gpmc_config, &t->bool_timings);
+
+ return 0;
+}
+
+static void gpmc_read_timings_dt(struct device_node *np,
+ struct gpmc_timings *gpmc_t)
+{
+ struct gpmc_bool_timings *p;
+
+ if (!np || !gpmc_t)
+ return;
+
+ memset(gpmc_t, 0, sizeof(*gpmc_t));
+
+ /* minimum clock period for syncronous mode */
+ of_property_read_u32(np, "gpmc,sync-clk-ps", &gpmc_t->sync_clk);
+
+ /* chip select timtings */
+ of_property_read_u32(np, "gpmc,cs-on-ns", &gpmc_t->cs_on);
+ of_property_read_u32(np, "gpmc,cs-rd-off-ns", &gpmc_t->cs_rd_off);
+ of_property_read_u32(np, "gpmc,cs-wr-off-ns", &gpmc_t->cs_wr_off);
+
+ /* ADV signal timings */
+ of_property_read_u32(np, "gpmc,adv-on-ns", &gpmc_t->adv_on);
+ of_property_read_u32(np, "gpmc,adv-rd-off-ns", &gpmc_t->adv_rd_off);
+ of_property_read_u32(np, "gpmc,adv-wr-off-ns", &gpmc_t->adv_wr_off);
+
+ /* WE signal timings */
+ of_property_read_u32(np, "gpmc,we-on-ns", &gpmc_t->we_on);
+ of_property_read_u32(np, "gpmc,we-off-ns", &gpmc_t->we_off);
+
+ /* OE signal timings */
+ of_property_read_u32(np, "gpmc,oe-on-ns", &gpmc_t->oe_on);
+ of_property_read_u32(np, "gpmc,oe-off-ns", &gpmc_t->oe_off);
+
+ /* access and cycle timings */
+ of_property_read_u32(np, "gpmc,page-burst-access-ns",
+ &gpmc_t->page_burst_access);
+ of_property_read_u32(np, "gpmc,access-ns", &gpmc_t->access);
+ of_property_read_u32(np, "gpmc,rd-cycle-ns", &gpmc_t->rd_cycle);
+ of_property_read_u32(np, "gpmc,wr-cycle-ns", &gpmc_t->wr_cycle);
+ of_property_read_u32(np, "gpmc,bus-turnaround-ns",
+ &gpmc_t->bus_turnaround);
+ of_property_read_u32(np, "gpmc,cycle2cycle-delay-ns",
+ &gpmc_t->cycle2cycle_delay);
+ of_property_read_u32(np, "gpmc,wait-monitoring-ns",
+ &gpmc_t->wait_monitoring);
+ of_property_read_u32(np, "gpmc,clk-activation-ns",
+ &gpmc_t->clk_activation);
+
+ /* only applicable to OMAP3+ */
+ of_property_read_u32(np, "gpmc,wr-access-ns", &gpmc_t->wr_access);
+ of_property_read_u32(np, "gpmc,wr-data-mux-bus-ns",
+ &gpmc_t->wr_data_mux_bus);
+
+ /* bool timing parameters */
+ p = &gpmc_t->bool_timings;
+
+ p->cycle2cyclediffcsen =
+ of_property_read_bool(np, "gpmc,cycle2cycle-diffcsen");
+ p->cycle2cyclesamecsen =
+ of_property_read_bool(np, "gpmc,cycle2cycle-samecsen");
+ p->we_extra_delay = of_property_read_bool(np, "gpmc,we-extra-delay");
+ p->oe_extra_delay = of_property_read_bool(np, "gpmc,oe-extra-delay");
+ p->adv_extra_delay = of_property_read_bool(np, "gpmc,adv-extra-delay");
+ p->cs_extra_delay = of_property_read_bool(np, "gpmc,cs-extra-delay");
+ p->time_para_granularity =
+ of_property_read_bool(np, "gpmc,time-para-granularity");
+}
+
+struct dt_eccmode {
+ const char *name;
+ enum gpmc_ecc_mode mode;
+};
+
+static struct dt_eccmode modes[] = {
+ {
+ .name = "ham1",
+ .mode = OMAP_ECC_HAMMING_CODE_HW_ROMCODE,
+ }, {
+ .name = "sw",
+ .mode = OMAP_ECC_HAMMING_CODE_HW_ROMCODE,
+ }, {
+ .name = "hw",
+ .mode = OMAP_ECC_HAMMING_CODE_HW_ROMCODE,
+ }, {
+ .name = "hw-romcode",
+ .mode = OMAP_ECC_HAMMING_CODE_HW_ROMCODE,
+ }, {
+ .name = "bch4",
+ .mode = OMAP_ECC_BCH4_CODE_HW,
+ }, {
+ .name = "bch8",
+ .mode = OMAP_ECC_BCH8_CODE_HW,
+ }, {
+ .name = "bch8-romcode",
+ .mode = OMAP_ECC_BCH8_CODE_HW_ROMCODE,
+ },
+};
+
+static int gpmc_probe_nand_child(struct device_d *dev,
+ struct device_node *child)
+{
+ u32 val;
+ const char *s;
+ struct gpmc_timings gpmc_t;
+ struct gpmc_nand_platform_data *gpmc_nand_data;
+ struct resource res;
+ int ret, i;
+
+ if (of_property_read_u32(child, "reg", &val) < 0) {
+ dev_err(dev, "%s has no 'reg' property\n",
+ child->full_name);
+ return -ENODEV;
+ }
+
+ gpmc_nand_data = xzalloc(sizeof(*gpmc_nand_data));
+ if (!gpmc_nand_data)
+ return -ENOMEM;
+
+ gpmc_base = dev_get_mem_region(dev, 0);
+ if (!gpmc_base)
+ return -ENODEV;
+
+ gpmc_nand_data->cs = val;
+ gpmc_nand_data->of_node = child;
+
+ /* Detect availability of ELM module */
+ gpmc_nand_data->elm_of_node = of_parse_phandle(child, "ti,elm-id", 0);
+ if (gpmc_nand_data->elm_of_node == NULL)
+ gpmc_nand_data->elm_of_node =
+ of_parse_phandle(child, "elm_id", 0);
+ if (gpmc_nand_data->elm_of_node == NULL)
+ pr_warn("%s: ti,elm-id property not found\n", __func__);
+
+ /* select ecc-scheme for NAND */
+ if (of_property_read_string(child, "ti,nand-ecc-opt", &s)) {
+ pr_err("%s: ti,nand-ecc-opt not found\n", __func__);
+ return -ENODEV;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(modes); i++) {
+ struct dt_eccmode *mode = &modes[i];
+ if (!strcmp(s, mode->name))
+ gpmc_nand_data->ecc_mode = mode->mode;
+ }
+
+ val = of_get_nand_bus_width(child);
+ if (val == 16)
+ gpmc_nand_data->device_width = NAND_BUSWIDTH_16;
+
+ gpmc_read_timings_dt(child, &gpmc_t);
+
+ gpmc_nand_data->nand_cfg = xzalloc(sizeof(*gpmc_nand_data->nand_cfg));
+
+ gpmc_timings_to_config(gpmc_nand_data->nand_cfg, &gpmc_t);
+
+ gpmc_nand_data->nand_cfg->cfg[0] |= 2 << 10;
+
+ ret = of_address_to_resource(child, 0, &res);
+ if (ret)
+ pr_err("of_address_to_resource failed\n");
+
+ gpmc_nand_data->nand_cfg->base = res.start;
+ gpmc_nand_data->nand_cfg->size = GPMC_SIZE_16M;
+ printf("%s: 0x%08x 0x%08x\n", __func__, res.start, res.end);
+
+ gpmc_cs_config(gpmc_nand_data->cs, gpmc_nand_data->nand_cfg);
+
+ add_generic_device("gpmc_nand", DEVICE_ID_DYNAMIC, NULL, (resource_size_t)gpmc_base,
+ 1024 * 4, IORESOURCE_MEM, gpmc_nand_data);
+
+ return 0;
+}
+
+static int gpmc_probe(struct device_d *dev)
+{
+ struct device_node *child, *node = dev->device_node;
+ int ret;
+
+ gpmc_generic_init(0x12);
+
+ ret = of_property_read_u32(node, "gpmc,num-cs",
+ &gpmc_cs_num);
+ if (ret < 0)
+ return ret;
+
+ ret = of_property_read_u32(node, "gpmc,num-waitpins",
+ &gpmc_nr_waitpins);
+ if (ret < 0)
+ return ret;
+
+ for_each_child_of_node(node, child) {
+
+ if (!child->name)
+ continue;
+
+ if (!strncmp(child->name, "nand", 4))
+ ret = gpmc_probe_nand_child(dev, child);
+ else
+ dev_warn(dev, "unhandled child %s\n", child->name);
+
+ if (ret)
+ break;
+ }
+
+ if (ret)
+ goto gpmc_err;
+
+ return 0;
+
+gpmc_err:
+ return ret;
+}
+
+static struct of_device_id gpmc_id_table[] = {
+ { .compatible = "ti,omap2420-gpmc" },
+ { .compatible = "ti,omap2430-gpmc" },
+ { .compatible = "ti,omap3430-gpmc" }, /* omap3430 & omap3630 */
+ { .compatible = "ti,omap4430-gpmc" }, /* omap4430 & omap4460 & omap543x */
+ { .compatible = "ti,am3352-gpmc" }, /* am335x devices */
+ { }
+};
+
+static struct driver_d gpmc_driver = {
+ .name = "omap-gpmc",
+ .of_compatible = DRV_OF_COMPAT(gpmc_id_table),
+ .probe = gpmc_probe,
+};
+device_platform_driver(gpmc_driver);
--
1.8.4.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 17/17] mmc: omap: Add devicetree support
2013-11-22 14:48 Add devicetree support to OMAP drivers Sascha Hauer
` (15 preceding siblings ...)
2013-11-22 14:49 ` [PATCH 16/17] bus: Add omap gpmc driver Sascha Hauer
@ 2013-11-22 14:49 ` Sascha Hauer
16 siblings, 0 replies; 18+ messages in thread
From: Sascha Hauer @ 2013-11-22 14:49 UTC (permalink / raw)
To: barebox
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/mci/omap_hsmmc.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/drivers/mci/omap_hsmmc.c b/drivers/mci/omap_hsmmc.c
index 19db461..2e736e1 100644
--- a/drivers/mci/omap_hsmmc.c
+++ b/drivers/mci/omap_hsmmc.c
@@ -640,9 +640,22 @@ static struct platform_device_id omap_mmc_ids[] = {
},
};
+static __maybe_unused struct of_device_id omap_mmc_dt_ids[] = {
+ {
+ .compatible = "ti,omap3-hsmmc",
+ .data = (unsigned long)&omap3_data,
+ }, {
+ .compatible = "ti,omap4-hsmmc",
+ .data = (unsigned long)&omap4_data,
+ }, {
+ /* sentinel */
+ }
+};
+
static struct driver_d omap_mmc_driver = {
.name = "omap-hsmmc",
.probe = omap_mmc_probe,
.id_table = omap_mmc_ids,
+ .of_compatible = DRV_OF_COMPAT(omap_mmc_dt_ids),
};
device_platform_driver(omap_mmc_driver);
--
1.8.4.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 18+ messages in thread