* [U-Boot] [PATCH] nios2 : convert altera_pio to driver model
@ 2015-09-24 9:15 Thomas Chou
2015-09-24 18:04 ` Marek Vasut
` (3 more replies)
0 siblings, 4 replies; 9+ messages in thread
From: Thomas Chou @ 2015-09-24 9:15 UTC (permalink / raw)
To: u-boot
Convert altera_pio to driver model.
Signed-off-by: Thomas Chou <thomas@wytron.com.tw>
---
arch/nios2/dts/3c120_devboard.dts | 38 ++++
arch/nios2/include/asm/gpio.h | 80 +-------
board/altera/nios2-generic/nios2-generic.c | 7 -
configs/nios2-generic_defconfig | 2 +
drivers/gpio/Kconfig | 7 +
drivers/gpio/altera_pio.c | 316 +++++++----------------------
include/configs/nios2-generic.h | 20 --
7 files changed, 124 insertions(+), 346 deletions(-)
diff --git a/arch/nios2/dts/3c120_devboard.dts b/arch/nios2/dts/3c120_devboard.dts
index a35f5fe..f6ac273 100644
--- a/arch/nios2/dts/3c120_devboard.dts
+++ b/arch/nios2/dts/3c120_devboard.dts
@@ -132,6 +132,44 @@
clock-frequency = <62500000>;
u-boot,dm-pre-reloc;
};
+
+ user_led_pio_8out: gpio at 0x4cc0 {
+ compatible = "altr,pio-1.0";
+ reg = <0x00004cc0 0x00000010>;
+ resetvalue = <255>;
+ width = <8>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-bank-name = "led";
+ };
+
+ user_dipsw_pio_8in: gpio at 0x4ce0 {
+ compatible = "altr,pio-1.0";
+ reg = <0x00004ce0 0x00000010>;
+ interrupt-parent = <&cpu>;
+ interrupts = <8>;
+ edge_type = <2>;
+ level_trigger = <0>;
+ resetvalue = <0>;
+ width = <8>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-bank-name = "dipsw";
+ };
+
+ user_pb_pio_4in: gpio at 0x4d00 {
+ compatible = "altr,pio-1.0";
+ reg = <0x00004d00 0x00000010>;
+ interrupt-parent = <&cpu>;
+ interrupts = <9>;
+ edge_type = <2>;
+ level_trigger = <0>;
+ resetvalue = <0>;
+ width = <4>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-bank-name = "pb";
+ };
};
cfi_flash_64m: flash at 0x0 {
diff --git a/arch/nios2/include/asm/gpio.h b/arch/nios2/include/asm/gpio.h
index 908381f..306ab4c 100644
--- a/arch/nios2/include/asm/gpio.h
+++ b/arch/nios2/include/asm/gpio.h
@@ -1,79 +1 @@
-/*
- * nios2 gpio driver
- *
- * This gpio core is described in http://nioswiki.com/GPIO
- * bit[0] data
- * bit[1] output enable
- *
- * When CONFIG_SYS_GPIO_BASE is not defined, the board may either
- * provide its own driver or the altera_pio driver may be used.
- *
- * Copyright (C) 2010 Thomas Chou <thomas@wytron.com.tw>
- *
- * 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.
- */
-
-#ifndef _ASM_NIOS2_GPIO_H_
-#define _ASM_NIOS2_GPIO_H_
-
-#ifdef CONFIG_SYS_GPIO_BASE
-#include <asm/io.h>
-
-static inline int gpio_request(unsigned gpio, const char *label)
-{
- return 0;
-}
-
-static inline int gpio_free(unsigned gpio)
-{
- return 0;
-}
-
-static inline int gpio_direction_input(unsigned gpio)
-{
- writel(1, CONFIG_SYS_GPIO_BASE + (gpio << 2));
- return 0;
-}
-
-static inline int gpio_direction_output(unsigned gpio, int value)
-{
- writel(value ? 3 : 2, CONFIG_SYS_GPIO_BASE + (gpio << 2));
- return 0;
-}
-
-static inline int gpio_get_value(unsigned gpio)
-{
- return readl(CONFIG_SYS_GPIO_BASE + (gpio << 2));
-}
-
-static inline void gpio_set_value(unsigned gpio, int value)
-{
- writel(value ? 3 : 2, CONFIG_SYS_GPIO_BASE + (gpio << 2));
-}
-
-static inline int gpio_is_valid(int number)
-{
- return ((unsigned)number) < CONFIG_SYS_GPIO_WIDTH;
-}
-#else
-#ifdef CONFIG_ALTERA_PIO
-extern int altera_pio_init(u32 base, u8 width, char iot,
- u32 rstval, u32 negmask,
- const char *label);
-
-extern void altera_pio_info(void);
-#define gpio_status() altera_pio_info()
-#endif
-
-extern int gpio_request(unsigned gpio, const char *label);
-extern int gpio_free(unsigned gpio);
-extern int gpio_direction_input(unsigned gpio);
-extern int gpio_direction_output(unsigned gpio, int value);
-extern int gpio_get_value(unsigned gpio);
-extern void gpio_set_value(unsigned gpio, int value);
-extern int gpio_is_valid(int number);
-#endif /* CONFIG_SYS_GPIO_BASE */
-
-#endif /* _ASM_NIOS2_GPIO_H_ */
+#include <asm-generic/gpio.h>
diff --git a/board/altera/nios2-generic/nios2-generic.c b/board/altera/nios2-generic/nios2-generic.c
index 384fee9..61d32c7 100644
--- a/board/altera/nios2-generic/nios2-generic.c
+++ b/board/altera/nios2-generic/nios2-generic.c
@@ -37,13 +37,6 @@ int board_early_init_f(void)
int board_early_init_r(void)
{
-#ifdef CONFIG_ALTERA_PIO
-#ifdef LED_PIO_BASE
- altera_pio_init(LED_PIO_BASE, LED_PIO_WIDTH, 'o',
- LED_PIO_RSTVAL, (1 << LED_PIO_WIDTH) - 1,
- "led");
-#endif
-#endif
return 0;
}
diff --git a/configs/nios2-generic_defconfig b/configs/nios2-generic_defconfig
index 9dc6a72..ad72272 100644
--- a/configs/nios2-generic_defconfig
+++ b/configs/nios2-generic_defconfig
@@ -1,5 +1,6 @@
CONFIG_NIOS2=y
CONFIG_DM_SERIAL=y
+CONFIG_DM_GPIO=y
CONFIG_TARGET_NIOS2_GENERIC=y
CONFIG_DEFAULT_DEVICE_TREE="3c120_devboard"
CONFIG_HUSH_PARSER=y
@@ -15,5 +16,6 @@ CONFIG_CMD_PING=y
CONFIG_OF_CONTROL=y
CONFIG_NET_RANDOM_ETHADDR=y
CONFIG_DM=y
+CONFIG_ALTERA_PIO=y
CONFIG_ALTERA_JTAG_UART=y
CONFIG_ALTERA_JTAG_UART_BYPASS=y
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index ef57a89..9e49471 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -14,6 +14,13 @@ config DM_GPIO
particular GPIOs that they provide. The uclass interface
is defined in include/asm-generic/gpio.h.
+config ALTERA_PIO
+ bool "Altera PIO driver"
+ depends on DM_GPIO
+ help
+ Select this to enable PIO for Altera devices. Please find
+ details on the "Embedded Peripherals IP User Guide" of Altera.
+
config DWAPB_GPIO
bool "DWAPB GPIO driver"
depends on DM && DM_GPIO
diff --git a/drivers/gpio/altera_pio.c b/drivers/gpio/altera_pio.c
index 3ca5907..14a922b 100644
--- a/drivers/gpio/altera_pio.c
+++ b/drivers/gpio/altera_pio.c
@@ -1,286 +1,122 @@
/*
- * Driver for Altera's PIO ip core
- *
+ * Copyright (C) 2015 Thomas Chou <thomas@wytron.com.tw>
* Copyright (C) 2011 Missing Link Electronics
* Joachim Foerster <joachim@missinglinkelectronics.com>
*
* SPDX-License-Identifier: GPL-2.0+
- *
- * To use this driver, in your board's config. header:
- * #define CONFIG_ALTERA_PIO
- * #define CONFIG_SYS_ALTERA_PIO_NUM <number-of-pio-cores>
- * #define CONFIG_SYS_ALTERA_PIO_GPIO_NUM <total-number-of-gpios>
- * And in your board's early setup routine:
- * altera_pio_init(<baseaddr>, <width>, 'i'|'o'|'t',
- * <reset-value>, <neg-mask>, "label");
- * - 'i'|'o'|'t': PIO is input-only/output-only/tri-state
- * - <reset-value>: for correct initial status display, output-only
- * - <neg-mask> is meant to be used to in cases of active-low
- * GPIOs, such as LEDs and buttons (on/pressed == 0). Each bit
- * which is 1 in <neg-mask> inverts the corresponding GPIO's value
- * before set/after get. So: gpio_set_value(gpio, 1) => LED on .
- *
- * Do NOT define CONFIG_SYS_GPIO_BASE !
- *
- * Optionally, in your board's config. header:
- * - To force a GPIO numbering scheme like in Linux ...
- * #define CONFIG_GPIO_DOWNTO_NUMBERING
- * ... starting with 255 (default)
- * #define CONFIG_GPIO_DOWNTO_MAX 255
*/
#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <malloc.h>
+#include <fdtdec.h>
#include <asm/io.h>
#include <asm/gpio.h>
-#ifdef CONFIG_GPIO_DOWNTO_NUMBERING
-#ifndef CONFIG_GPIO_DOWNTO_MAX
-#define CONFIG_GPIO_DOWNTO_MAX 255
-#endif
-#endif
-
-#define ALTERA_PIO_DATA 0x0
-#define ALTERA_PIO_DIR 0x4
-
-#define GPIO_LABEL_SIZE 9
+DECLARE_GLOBAL_DATA_PTR;
+struct altera_pio_regs {
+ u32 data; /* Data register */
+ u32 direction; /* Direction register */
+};
-static struct altera_pio {
- u32 base;
- u8 width;
- char iot;
- u32 negmask;
- u32 sh_data;
- u32 sh_dir;
- int gidx;
- char label[GPIO_LABEL_SIZE];
-} pios[CONFIG_SYS_ALTERA_PIO_NUM];
+struct altera_pio_platdata {
+ struct altera_pio_regs *regs;
+ int gpio_count;
+ const char *bank_name;
+};
-static int pio_num;
-
-static struct altera_pio_gpio {
- unsigned num;
- struct altera_pio *pio;
- char reqlabel[GPIO_LABEL_SIZE];
-} gpios[CONFIG_SYS_ALTERA_PIO_GPIO_NUM];
-
-static int pio_gpio_num;
-
-
-static int altera_pio_gidx(unsigned gpio)
+static int altera_pio_direction_input(struct udevice *dev, unsigned pin)
{
- int i;
+ struct altera_pio_platdata *plat = dev_get_platdata(dev);
+ struct altera_pio_regs *const regs = plat->regs;
- for (i = 0; i < pio_gpio_num; ++i) {
- if (gpio == gpios[i].num)
- break;
- }
- if (i >= pio_gpio_num)
- return -1;
- return i;
-}
+ clrbits_le32(®s->direction, 1 << pin);
-static struct altera_pio *altera_pio_get_and_mask(unsigned gpio, u32 *mask)
-{
- int gidx = altera_pio_gidx(gpio);
- if (gidx < 0)
- return NULL;
- if (mask)
- *mask = 1 << (gidx - gpios[gidx].pio->gidx);
- return gpios[gidx].pio;
+ return 0;
}
-#define altera_pio_use_gidx(_gidx, _reqlabel) \
- { strncpy(gpios[_gidx].reqlabel, _reqlabel, GPIO_LABEL_SIZE); }
-#define altera_pio_unuse_gidx(_gidx) { gpios[_gidx].reqlabel[0] = '\0'; }
-#define altera_pio_is_gidx_used(_gidx) (gpios[_gidx].reqlabel[0] != '\0')
-
-static int altera_pio_gpio_init(struct altera_pio *pio, u8 width)
+static int altera_pio_direction_output(struct udevice *dev, unsigned pin,
+ int val)
{
- u8 gidx = pio_gpio_num;
- int i;
-
- if (!width)
- return -1;
- if ((pio_gpio_num + width) > CONFIG_SYS_ALTERA_PIO_GPIO_NUM)
- return -1;
-
- for (i = 0; i < width; ++i) {
-#ifdef CONFIG_GPIO_DOWNTO_NUMBERING
- gpios[pio_gpio_num + i].num = \
- CONFIG_GPIO_DOWNTO_MAX + 1 - gidx - width + i;
-#else
- gpios[pio_gpio_num + i].num = pio_gpio_num + i;
-#endif
- gpios[pio_gpio_num + i].pio = pio;
- altera_pio_unuse_gidx(pio_gpio_num + i);
- }
- pio_gpio_num += width;
- return gidx;
-}
+ struct altera_pio_platdata *plat = dev_get_platdata(dev);
+ struct altera_pio_regs *const regs = plat->regs;
-int altera_pio_init(u32 base, u8 width, char iot, u32 rstval, u32 negmask,
- const char *label)
-{
- if (pio_num >= CONFIG_SYS_ALTERA_PIO_NUM)
- return -1;
+ if (val)
+ setbits_le32(®s->data, 1 << pin);
+ else
+ clrbits_le32(®s->data, 1 << pin);
+ /* change the data first, then the direction. to avoid glitch */
+ setbits_le32(®s->direction, 1 << pin);
- pios[pio_num].base = base;
- pios[pio_num].width = width;
- pios[pio_num].iot = iot;
- switch (iot) {
- case 'i':
- /* input only */
- pios[pio_num].sh_dir = 0;
- pios[pio_num].sh_data = readl(base + ALTERA_PIO_DATA);
- break;
- case 'o':
- /* output only */
- pios[pio_num].sh_dir = 0xffffffff & ((1 << width) - 1);
- pios[pio_num].sh_data = rstval;
- break;
- case 't':
- /* bidir, tri-state */
- pios[pio_num].sh_dir = readl(base + ALTERA_PIO_DIR);
- pios[pio_num].sh_data = readl(base + ALTERA_PIO_DATA);
- break;
- default:
- return -1;
- }
- pios[pio_num].negmask = negmask & ((1 << width) - 1);
- pios[pio_num].gidx = altera_pio_gpio_init(&pios[pio_num], width);
- if (pios[pio_num].gidx < 0)
- return -1;
- strncpy(pios[pio_num].label, label, GPIO_LABEL_SIZE);
- return pio_num++;
+ return 0;
}
-void altera_pio_info(void)
+static int altera_pio_get_value(struct udevice *dev, unsigned pin)
{
- int i;
- int j;
- int gidx;
- u32 mask;
+ struct altera_pio_platdata *plat = dev_get_platdata(dev);
+ struct altera_pio_regs *const regs = plat->regs;
- for (i = 0; i < pio_num; ++i) {
- printf("Altera PIO % 2d, @0x%08x, "
- "width: %u, label: %s\n",
- i, pios[i].base, pios[i].width, pios[i].label);
- gidx = pios[i].gidx;
- for (j = gidx; j < (gidx + pios[i].width); ++j) {
- mask = 1 << (j - gidx);
- printf("\tGPIO % 4d: %s %s [%c] %s\n",
- gpios[j].num,
- gpios[j].pio->sh_dir & mask ? "out" : " in",
- gpio_get_value(gpios[j].num) ? "set" : "clr",
- altera_pio_is_gidx_used(j) ? 'x' : ' ',
- gpios[j].reqlabel);
- }
- }
+ return !!(readl(®s->data) & (1 << pin));
}
-int gpio_request(unsigned gpio, const char *label)
+static int altera_pio_set_value(struct udevice *dev, unsigned pin, int val)
{
- int gidx = altera_pio_gidx(gpio);
- if (gidx < 0)
- return gidx;
- if (altera_pio_is_gidx_used(gidx))
- return -1;
-
- altera_pio_use_gidx(gidx, label);
- return 0;
-}
+ struct altera_pio_platdata *plat = dev_get_platdata(dev);
+ struct altera_pio_regs *const regs = plat->regs;
-int gpio_free(unsigned gpio)
-{
- int gidx = altera_pio_gidx(gpio);
- if (gidx < 0)
- return gidx;
- if (!altera_pio_is_gidx_used(gidx))
- return -1;
+ if (val)
+ setbits_le32(®s->data, 1 << pin);
+ else
+ clrbits_le32(®s->data, 1 << pin);
- altera_pio_unuse_gidx(gidx);
return 0;
}
-int gpio_direction_input(unsigned gpio)
+static int altera_pio_probe(struct udevice *dev)
{
- u32 mask;
- struct altera_pio *pio;
+ struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
+ struct altera_pio_platdata *plat = dev_get_platdata(dev);
- pio = altera_pio_get_and_mask(gpio, &mask);
- if (!pio)
- return -1;
- if (pio->iot == 'o')
- return -1;
+ uc_priv->gpio_count = plat->gpio_count;
+ uc_priv->bank_name = plat->bank_name;
- writel(pio->sh_dir &= ~mask, pio->base + ALTERA_PIO_DIR);
return 0;
}
-int gpio_direction_output(unsigned gpio, int value)
+static int altera_pio_ofdata_to_platdata(struct udevice *dev)
{
- u32 mask;
- struct altera_pio *pio;
+ struct altera_pio_platdata *plat = dev_get_platdata(dev);
- pio = altera_pio_get_and_mask(gpio, &mask);
- if (!pio)
- return -1;
- if (pio->iot == 'i')
- return -1;
+ plat->regs = ioremap(dev_get_addr(dev),
+ sizeof(struct altera_pio_regs));
+ plat->gpio_count = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
+ "width", 0);
+ plat->bank_name = fdt_getprop(gd->fdt_blob, dev->of_offset,
+ "gpio-bank-name", NULL);
- value = (pio->negmask & mask) ? !value : value;
- if (value)
- pio->sh_data |= mask;
- else
- pio->sh_data &= ~mask;
- writel(pio->sh_data, pio->base + ALTERA_PIO_DATA);
- writel(pio->sh_dir |= mask, pio->base + ALTERA_PIO_DIR);
return 0;
}
-int gpio_get_value(unsigned gpio)
-{
- u32 mask;
- struct altera_pio *pio;
- u32 val;
-
- pio = altera_pio_get_and_mask(gpio, &mask);
- if (!pio)
- return -1;
-
- if ((pio->sh_dir & mask) || (pio->iot == 'o'))
- val = pio->sh_data & mask;
- else
- val = readl(pio->base + ALTERA_PIO_DATA) & mask;
- return (pio->negmask & mask) ? !val : val;
-}
-
-void gpio_set_value(unsigned gpio, int value)
-{
- u32 mask;
- struct altera_pio *pio;
-
- pio = altera_pio_get_and_mask(gpio, &mask);
- if (!pio)
- return;
- if (pio->iot == 'i')
- return;
-
- value = (pio->negmask & mask) ? !value : value;
- if (value)
- pio->sh_data |= mask;
- else
- pio->sh_data &= ~mask;
- writel(pio->sh_data, pio->base + ALTERA_PIO_DATA);
- return;
-}
-
-int gpio_is_valid(int number)
-{
- int gidx = altera_pio_gidx(number);
-
- if (gidx < 0)
- return 1;
- return 0;
-}
+static const struct dm_gpio_ops altera_pio_ops = {
+ .direction_input = altera_pio_direction_input,
+ .direction_output = altera_pio_direction_output,
+ .get_value = altera_pio_get_value,
+ .set_value = altera_pio_set_value,
+};
+
+static const struct udevice_id altera_pio_ids[] = {
+ { .compatible = "altr,pio-1.0" },
+ { }
+};
+
+U_BOOT_DRIVER(altera_pio) = {
+ .name = "altera_pio",
+ .id = UCLASS_GPIO,
+ .of_match = altera_pio_ids,
+ .ops = &altera_pio_ops,
+ .ofdata_to_platdata = altera_pio_ofdata_to_platdata,
+ .platdata_auto_alloc_size = sizeof(struct altera_pio_platdata),
+ .probe = altera_pio_probe,
+};
diff --git a/include/configs/nios2-generic.h b/include/configs/nios2-generic.h
index dcb90de..90ccbd1 100644
--- a/include/configs/nios2-generic.h
+++ b/include/configs/nios2-generic.h
@@ -33,26 +33,6 @@
#define CONFIG_SYS_TIMER_RATE CONFIG_SYS_TIMER_FREQ
/*
- * STATUS LED
- */
-#define CONFIG_ALTERA_PIO
-#define CONFIG_SYS_ALTERA_PIO_NUM 1
-#define CONFIG_SYS_ALTERA_PIO_GPIO_NUM LED_PIO_WIDTH
-
-#define CONFIG_STATUS_LED /* Enable status driver */
-#define CONFIG_BOARD_SPECIFIC_LED
-#define CONFIG_GPIO_LED /* Enable GPIO LED driver */
-#define CONFIG_GPIO /* Enable GPIO driver */
-#define LED_PIO_BASE USER_LED_PIO_8OUT_BASE
-#define LED_PIO_WIDTH 8
-#define LED_PIO_RSTVAL 0xff
-
-#define STATUS_LED_BIT 0 /* Bit-0 on GPIO */
-#define STATUS_LED_STATE STATUS_LED_ON
-#define STATUS_LED_PERIOD (CONFIG_SYS_HZ / 2) /* 500 msec */
-#define STATUS_LED_BOOT STATUS_LED_BIT
-
-/*
* BOOTP options
*/
#define CONFIG_BOOTP_BOOTFILESIZE
--
2.1.4
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [U-Boot] [PATCH] nios2 : convert altera_pio to driver model
2015-09-24 9:15 [U-Boot] [PATCH] nios2 : convert altera_pio to driver model Thomas Chou
@ 2015-09-24 18:04 ` Marek Vasut
2015-09-25 8:05 ` [U-Boot] [PATCH v2] " Thomas Chou
` (2 subsequent siblings)
3 siblings, 0 replies; 9+ messages in thread
From: Marek Vasut @ 2015-09-24 18:04 UTC (permalink / raw)
To: u-boot
On Thursday, September 24, 2015 at 11:15:05 AM, Thomas Chou wrote:
> Convert altera_pio to driver model.
>
> Signed-off-by: Thomas Chou <thomas@wytron.com.tw>
Hi,
now this is quite a nice patch :-)
> ---
> arch/nios2/dts/3c120_devboard.dts | 38 ++++
> arch/nios2/include/asm/gpio.h | 80 +-------
> board/altera/nios2-generic/nios2-generic.c | 7 -
> configs/nios2-generic_defconfig | 2 +
> drivers/gpio/Kconfig | 7 +
> drivers/gpio/altera_pio.c | 316
> +++++++---------------------- include/configs/nios2-generic.h |
> 20 --
> 7 files changed, 124 insertions(+), 346 deletions(-)
>
[...]
> +static int altera_pio_get_value(struct udevice *dev, unsigned pin)
> {
> - int i;
> - int j;
> - int gidx;
> - u32 mask;
> + struct altera_pio_platdata *plat = dev_get_platdata(dev);
> + struct altera_pio_regs *const regs = plat->regs;
>
> - for (i = 0; i < pio_num; ++i) {
> - printf("Altera PIO % 2d, @0x%08x, "
> - "width: %u, label: %s\n",
> - i, pios[i].base, pios[i].width, pios[i].label);
> - gidx = pios[i].gidx;
> - for (j = gidx; j < (gidx + pios[i].width); ++j) {
> - mask = 1 << (j - gidx);
> - printf("\tGPIO % 4d: %s %s [%c] %s\n",
> - gpios[j].num,
> - gpios[j].pio->sh_dir & mask ? "out" : " in",
> - gpio_get_value(gpios[j].num) ? "set" : "clr",
> - altera_pio_is_gidx_used(j) ? 'x' : ' ',
> - gpios[j].reqlabel);
> - }
> - }
> + return !!(readl(®s->data) & (1 << pin));
You can drop the double negation here, the API design is done such that
0 is log. low and non-zero is log. high .
[...]
Thanks!
^ permalink raw reply [flat|nested] 9+ messages in thread
* [U-Boot] [PATCH v2] nios2 : convert altera_pio to driver model
2015-09-24 9:15 [U-Boot] [PATCH] nios2 : convert altera_pio to driver model Thomas Chou
2015-09-24 18:04 ` Marek Vasut
@ 2015-09-25 8:05 ` Thomas Chou
2015-09-26 9:07 ` [U-Boot] [PATCH v3] " Thomas Chou
2015-09-30 13:37 ` [U-Boot] [PATCH v4] " Thomas Chou
3 siblings, 0 replies; 9+ messages in thread
From: Thomas Chou @ 2015-09-25 8:05 UTC (permalink / raw)
To: u-boot
Convert altera_pio to driver model.
Signed-off-by: Thomas Chou <thomas@wytron.com.tw>
---
v2
fix ranges of pio in dts
fix coding style as Marek suggested.
arch/nios2/dts/3c120_devboard.dts | 41 ++++
arch/nios2/include/asm/gpio.h | 80 +-------
board/altera/nios2-generic/nios2-generic.c | 7 -
configs/nios2-generic_defconfig | 2 +
drivers/gpio/Kconfig | 7 +
drivers/gpio/altera_pio.c | 316 +++++++----------------------
include/configs/nios2-generic.h | 20 --
7 files changed, 127 insertions(+), 346 deletions(-)
diff --git a/arch/nios2/dts/3c120_devboard.dts b/arch/nios2/dts/3c120_devboard.dts
index a35f5fe..06c9422 100644
--- a/arch/nios2/dts/3c120_devboard.dts
+++ b/arch/nios2/dts/3c120_devboard.dts
@@ -68,6 +68,9 @@
<0x00004400 0x08004400 0x00000040>,
<0x00004800 0x08004800 0x00000040>,
<0x00004c80 0x08004c80 0x00000020>,
+ <0x00004cc0 0x08004cc0 0x00000010>,
+ <0x00004ce0 0x08004ce0 0x00000010>,
+ <0x00004d00 0x08004d00 0x00000010>,
<0x00004d50 0x08004d50 0x00000008>,
<0x00008000 0x08008000 0x00000020>,
<0x00400000 0x08400000 0x00000020>;
@@ -132,6 +135,44 @@
clock-frequency = <62500000>;
u-boot,dm-pre-reloc;
};
+
+ user_led_pio_8out: gpio at 0x4cc0 {
+ compatible = "altr,pio-1.0";
+ reg = <0x00004cc0 0x00000010>;
+ resetvalue = <255>;
+ width = <8>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-bank-name = "led";
+ };
+
+ user_dipsw_pio_8in: gpio at 0x4ce0 {
+ compatible = "altr,pio-1.0";
+ reg = <0x00004ce0 0x00000010>;
+ interrupt-parent = <&cpu>;
+ interrupts = <8>;
+ edge_type = <2>;
+ level_trigger = <0>;
+ resetvalue = <0>;
+ width = <8>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-bank-name = "dipsw";
+ };
+
+ user_pb_pio_4in: gpio at 0x4d00 {
+ compatible = "altr,pio-1.0";
+ reg = <0x00004d00 0x00000010>;
+ interrupt-parent = <&cpu>;
+ interrupts = <9>;
+ edge_type = <2>;
+ level_trigger = <0>;
+ resetvalue = <0>;
+ width = <4>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-bank-name = "pb";
+ };
};
cfi_flash_64m: flash at 0x0 {
diff --git a/arch/nios2/include/asm/gpio.h b/arch/nios2/include/asm/gpio.h
index 908381f..306ab4c 100644
--- a/arch/nios2/include/asm/gpio.h
+++ b/arch/nios2/include/asm/gpio.h
@@ -1,79 +1 @@
-/*
- * nios2 gpio driver
- *
- * This gpio core is described in http://nioswiki.com/GPIO
- * bit[0] data
- * bit[1] output enable
- *
- * When CONFIG_SYS_GPIO_BASE is not defined, the board may either
- * provide its own driver or the altera_pio driver may be used.
- *
- * Copyright (C) 2010 Thomas Chou <thomas@wytron.com.tw>
- *
- * 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.
- */
-
-#ifndef _ASM_NIOS2_GPIO_H_
-#define _ASM_NIOS2_GPIO_H_
-
-#ifdef CONFIG_SYS_GPIO_BASE
-#include <asm/io.h>
-
-static inline int gpio_request(unsigned gpio, const char *label)
-{
- return 0;
-}
-
-static inline int gpio_free(unsigned gpio)
-{
- return 0;
-}
-
-static inline int gpio_direction_input(unsigned gpio)
-{
- writel(1, CONFIG_SYS_GPIO_BASE + (gpio << 2));
- return 0;
-}
-
-static inline int gpio_direction_output(unsigned gpio, int value)
-{
- writel(value ? 3 : 2, CONFIG_SYS_GPIO_BASE + (gpio << 2));
- return 0;
-}
-
-static inline int gpio_get_value(unsigned gpio)
-{
- return readl(CONFIG_SYS_GPIO_BASE + (gpio << 2));
-}
-
-static inline void gpio_set_value(unsigned gpio, int value)
-{
- writel(value ? 3 : 2, CONFIG_SYS_GPIO_BASE + (gpio << 2));
-}
-
-static inline int gpio_is_valid(int number)
-{
- return ((unsigned)number) < CONFIG_SYS_GPIO_WIDTH;
-}
-#else
-#ifdef CONFIG_ALTERA_PIO
-extern int altera_pio_init(u32 base, u8 width, char iot,
- u32 rstval, u32 negmask,
- const char *label);
-
-extern void altera_pio_info(void);
-#define gpio_status() altera_pio_info()
-#endif
-
-extern int gpio_request(unsigned gpio, const char *label);
-extern int gpio_free(unsigned gpio);
-extern int gpio_direction_input(unsigned gpio);
-extern int gpio_direction_output(unsigned gpio, int value);
-extern int gpio_get_value(unsigned gpio);
-extern void gpio_set_value(unsigned gpio, int value);
-extern int gpio_is_valid(int number);
-#endif /* CONFIG_SYS_GPIO_BASE */
-
-#endif /* _ASM_NIOS2_GPIO_H_ */
+#include <asm-generic/gpio.h>
diff --git a/board/altera/nios2-generic/nios2-generic.c b/board/altera/nios2-generic/nios2-generic.c
index 384fee9..61d32c7 100644
--- a/board/altera/nios2-generic/nios2-generic.c
+++ b/board/altera/nios2-generic/nios2-generic.c
@@ -37,13 +37,6 @@ int board_early_init_f(void)
int board_early_init_r(void)
{
-#ifdef CONFIG_ALTERA_PIO
-#ifdef LED_PIO_BASE
- altera_pio_init(LED_PIO_BASE, LED_PIO_WIDTH, 'o',
- LED_PIO_RSTVAL, (1 << LED_PIO_WIDTH) - 1,
- "led");
-#endif
-#endif
return 0;
}
diff --git a/configs/nios2-generic_defconfig b/configs/nios2-generic_defconfig
index 9dc6a72..ad72272 100644
--- a/configs/nios2-generic_defconfig
+++ b/configs/nios2-generic_defconfig
@@ -1,5 +1,6 @@
CONFIG_NIOS2=y
CONFIG_DM_SERIAL=y
+CONFIG_DM_GPIO=y
CONFIG_TARGET_NIOS2_GENERIC=y
CONFIG_DEFAULT_DEVICE_TREE="3c120_devboard"
CONFIG_HUSH_PARSER=y
@@ -15,5 +16,6 @@ CONFIG_CMD_PING=y
CONFIG_OF_CONTROL=y
CONFIG_NET_RANDOM_ETHADDR=y
CONFIG_DM=y
+CONFIG_ALTERA_PIO=y
CONFIG_ALTERA_JTAG_UART=y
CONFIG_ALTERA_JTAG_UART_BYPASS=y
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index ef57a89..9e49471 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -14,6 +14,13 @@ config DM_GPIO
particular GPIOs that they provide. The uclass interface
is defined in include/asm-generic/gpio.h.
+config ALTERA_PIO
+ bool "Altera PIO driver"
+ depends on DM_GPIO
+ help
+ Select this to enable PIO for Altera devices. Please find
+ details on the "Embedded Peripherals IP User Guide" of Altera.
+
config DWAPB_GPIO
bool "DWAPB GPIO driver"
depends on DM && DM_GPIO
diff --git a/drivers/gpio/altera_pio.c b/drivers/gpio/altera_pio.c
index 3ca5907..a64d5f5 100644
--- a/drivers/gpio/altera_pio.c
+++ b/drivers/gpio/altera_pio.c
@@ -1,286 +1,122 @@
/*
- * Driver for Altera's PIO ip core
- *
+ * Copyright (C) 2015 Thomas Chou <thomas@wytron.com.tw>
* Copyright (C) 2011 Missing Link Electronics
* Joachim Foerster <joachim@missinglinkelectronics.com>
*
* SPDX-License-Identifier: GPL-2.0+
- *
- * To use this driver, in your board's config. header:
- * #define CONFIG_ALTERA_PIO
- * #define CONFIG_SYS_ALTERA_PIO_NUM <number-of-pio-cores>
- * #define CONFIG_SYS_ALTERA_PIO_GPIO_NUM <total-number-of-gpios>
- * And in your board's early setup routine:
- * altera_pio_init(<baseaddr>, <width>, 'i'|'o'|'t',
- * <reset-value>, <neg-mask>, "label");
- * - 'i'|'o'|'t': PIO is input-only/output-only/tri-state
- * - <reset-value>: for correct initial status display, output-only
- * - <neg-mask> is meant to be used to in cases of active-low
- * GPIOs, such as LEDs and buttons (on/pressed == 0). Each bit
- * which is 1 in <neg-mask> inverts the corresponding GPIO's value
- * before set/after get. So: gpio_set_value(gpio, 1) => LED on .
- *
- * Do NOT define CONFIG_SYS_GPIO_BASE !
- *
- * Optionally, in your board's config. header:
- * - To force a GPIO numbering scheme like in Linux ...
- * #define CONFIG_GPIO_DOWNTO_NUMBERING
- * ... starting with 255 (default)
- * #define CONFIG_GPIO_DOWNTO_MAX 255
*/
#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <malloc.h>
+#include <fdtdec.h>
#include <asm/io.h>
#include <asm/gpio.h>
-#ifdef CONFIG_GPIO_DOWNTO_NUMBERING
-#ifndef CONFIG_GPIO_DOWNTO_MAX
-#define CONFIG_GPIO_DOWNTO_MAX 255
-#endif
-#endif
-
-#define ALTERA_PIO_DATA 0x0
-#define ALTERA_PIO_DIR 0x4
-
-#define GPIO_LABEL_SIZE 9
+DECLARE_GLOBAL_DATA_PTR;
+struct altera_pio_regs {
+ u32 data; /* Data register */
+ u32 direction; /* Direction register */
+};
-static struct altera_pio {
- u32 base;
- u8 width;
- char iot;
- u32 negmask;
- u32 sh_data;
- u32 sh_dir;
- int gidx;
- char label[GPIO_LABEL_SIZE];
-} pios[CONFIG_SYS_ALTERA_PIO_NUM];
+struct altera_pio_platdata {
+ struct altera_pio_regs *regs;
+ int gpio_count;
+ const char *bank_name;
+};
-static int pio_num;
-
-static struct altera_pio_gpio {
- unsigned num;
- struct altera_pio *pio;
- char reqlabel[GPIO_LABEL_SIZE];
-} gpios[CONFIG_SYS_ALTERA_PIO_GPIO_NUM];
-
-static int pio_gpio_num;
-
-
-static int altera_pio_gidx(unsigned gpio)
+static int altera_pio_direction_input(struct udevice *dev, unsigned pin)
{
- int i;
+ struct altera_pio_platdata *plat = dev_get_platdata(dev);
+ struct altera_pio_regs *const regs = plat->regs;
- for (i = 0; i < pio_gpio_num; ++i) {
- if (gpio == gpios[i].num)
- break;
- }
- if (i >= pio_gpio_num)
- return -1;
- return i;
-}
+ clrbits_le32(®s->direction, 1 << pin);
-static struct altera_pio *altera_pio_get_and_mask(unsigned gpio, u32 *mask)
-{
- int gidx = altera_pio_gidx(gpio);
- if (gidx < 0)
- return NULL;
- if (mask)
- *mask = 1 << (gidx - gpios[gidx].pio->gidx);
- return gpios[gidx].pio;
+ return 0;
}
-#define altera_pio_use_gidx(_gidx, _reqlabel) \
- { strncpy(gpios[_gidx].reqlabel, _reqlabel, GPIO_LABEL_SIZE); }
-#define altera_pio_unuse_gidx(_gidx) { gpios[_gidx].reqlabel[0] = '\0'; }
-#define altera_pio_is_gidx_used(_gidx) (gpios[_gidx].reqlabel[0] != '\0')
-
-static int altera_pio_gpio_init(struct altera_pio *pio, u8 width)
+static int altera_pio_direction_output(struct udevice *dev, unsigned pin,
+ int val)
{
- u8 gidx = pio_gpio_num;
- int i;
-
- if (!width)
- return -1;
- if ((pio_gpio_num + width) > CONFIG_SYS_ALTERA_PIO_GPIO_NUM)
- return -1;
-
- for (i = 0; i < width; ++i) {
-#ifdef CONFIG_GPIO_DOWNTO_NUMBERING
- gpios[pio_gpio_num + i].num = \
- CONFIG_GPIO_DOWNTO_MAX + 1 - gidx - width + i;
-#else
- gpios[pio_gpio_num + i].num = pio_gpio_num + i;
-#endif
- gpios[pio_gpio_num + i].pio = pio;
- altera_pio_unuse_gidx(pio_gpio_num + i);
- }
- pio_gpio_num += width;
- return gidx;
-}
+ struct altera_pio_platdata *plat = dev_get_platdata(dev);
+ struct altera_pio_regs *const regs = plat->regs;
-int altera_pio_init(u32 base, u8 width, char iot, u32 rstval, u32 negmask,
- const char *label)
-{
- if (pio_num >= CONFIG_SYS_ALTERA_PIO_NUM)
- return -1;
+ if (val)
+ setbits_le32(®s->data, 1 << pin);
+ else
+ clrbits_le32(®s->data, 1 << pin);
+ /* change the data first, then the direction. to avoid glitch */
+ setbits_le32(®s->direction, 1 << pin);
- pios[pio_num].base = base;
- pios[pio_num].width = width;
- pios[pio_num].iot = iot;
- switch (iot) {
- case 'i':
- /* input only */
- pios[pio_num].sh_dir = 0;
- pios[pio_num].sh_data = readl(base + ALTERA_PIO_DATA);
- break;
- case 'o':
- /* output only */
- pios[pio_num].sh_dir = 0xffffffff & ((1 << width) - 1);
- pios[pio_num].sh_data = rstval;
- break;
- case 't':
- /* bidir, tri-state */
- pios[pio_num].sh_dir = readl(base + ALTERA_PIO_DIR);
- pios[pio_num].sh_data = readl(base + ALTERA_PIO_DATA);
- break;
- default:
- return -1;
- }
- pios[pio_num].negmask = negmask & ((1 << width) - 1);
- pios[pio_num].gidx = altera_pio_gpio_init(&pios[pio_num], width);
- if (pios[pio_num].gidx < 0)
- return -1;
- strncpy(pios[pio_num].label, label, GPIO_LABEL_SIZE);
- return pio_num++;
+ return 0;
}
-void altera_pio_info(void)
+static int altera_pio_get_value(struct udevice *dev, unsigned pin)
{
- int i;
- int j;
- int gidx;
- u32 mask;
+ struct altera_pio_platdata *plat = dev_get_platdata(dev);
+ struct altera_pio_regs *const regs = plat->regs;
- for (i = 0; i < pio_num; ++i) {
- printf("Altera PIO % 2d, @0x%08x, "
- "width: %u, label: %s\n",
- i, pios[i].base, pios[i].width, pios[i].label);
- gidx = pios[i].gidx;
- for (j = gidx; j < (gidx + pios[i].width); ++j) {
- mask = 1 << (j - gidx);
- printf("\tGPIO % 4d: %s %s [%c] %s\n",
- gpios[j].num,
- gpios[j].pio->sh_dir & mask ? "out" : " in",
- gpio_get_value(gpios[j].num) ? "set" : "clr",
- altera_pio_is_gidx_used(j) ? 'x' : ' ',
- gpios[j].reqlabel);
- }
- }
+ return readl(®s->data) & (1 << pin);
}
-int gpio_request(unsigned gpio, const char *label)
+static int altera_pio_set_value(struct udevice *dev, unsigned pin, int val)
{
- int gidx = altera_pio_gidx(gpio);
- if (gidx < 0)
- return gidx;
- if (altera_pio_is_gidx_used(gidx))
- return -1;
-
- altera_pio_use_gidx(gidx, label);
- return 0;
-}
+ struct altera_pio_platdata *plat = dev_get_platdata(dev);
+ struct altera_pio_regs *const regs = plat->regs;
-int gpio_free(unsigned gpio)
-{
- int gidx = altera_pio_gidx(gpio);
- if (gidx < 0)
- return gidx;
- if (!altera_pio_is_gidx_used(gidx))
- return -1;
+ if (val)
+ setbits_le32(®s->data, 1 << pin);
+ else
+ clrbits_le32(®s->data, 1 << pin);
- altera_pio_unuse_gidx(gidx);
return 0;
}
-int gpio_direction_input(unsigned gpio)
+static int altera_pio_probe(struct udevice *dev)
{
- u32 mask;
- struct altera_pio *pio;
+ struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
+ struct altera_pio_platdata *plat = dev_get_platdata(dev);
- pio = altera_pio_get_and_mask(gpio, &mask);
- if (!pio)
- return -1;
- if (pio->iot == 'o')
- return -1;
+ uc_priv->gpio_count = plat->gpio_count;
+ uc_priv->bank_name = plat->bank_name;
- writel(pio->sh_dir &= ~mask, pio->base + ALTERA_PIO_DIR);
return 0;
}
-int gpio_direction_output(unsigned gpio, int value)
+static int altera_pio_ofdata_to_platdata(struct udevice *dev)
{
- u32 mask;
- struct altera_pio *pio;
+ struct altera_pio_platdata *plat = dev_get_platdata(dev);
- pio = altera_pio_get_and_mask(gpio, &mask);
- if (!pio)
- return -1;
- if (pio->iot == 'i')
- return -1;
+ plat->regs = ioremap(dev_get_addr(dev),
+ sizeof(struct altera_pio_regs));
+ plat->gpio_count = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
+ "width", 0);
+ plat->bank_name = fdt_getprop(gd->fdt_blob, dev->of_offset,
+ "gpio-bank-name", NULL);
- value = (pio->negmask & mask) ? !value : value;
- if (value)
- pio->sh_data |= mask;
- else
- pio->sh_data &= ~mask;
- writel(pio->sh_data, pio->base + ALTERA_PIO_DATA);
- writel(pio->sh_dir |= mask, pio->base + ALTERA_PIO_DIR);
return 0;
}
-int gpio_get_value(unsigned gpio)
-{
- u32 mask;
- struct altera_pio *pio;
- u32 val;
-
- pio = altera_pio_get_and_mask(gpio, &mask);
- if (!pio)
- return -1;
-
- if ((pio->sh_dir & mask) || (pio->iot == 'o'))
- val = pio->sh_data & mask;
- else
- val = readl(pio->base + ALTERA_PIO_DATA) & mask;
- return (pio->negmask & mask) ? !val : val;
-}
-
-void gpio_set_value(unsigned gpio, int value)
-{
- u32 mask;
- struct altera_pio *pio;
-
- pio = altera_pio_get_and_mask(gpio, &mask);
- if (!pio)
- return;
- if (pio->iot == 'i')
- return;
-
- value = (pio->negmask & mask) ? !value : value;
- if (value)
- pio->sh_data |= mask;
- else
- pio->sh_data &= ~mask;
- writel(pio->sh_data, pio->base + ALTERA_PIO_DATA);
- return;
-}
-
-int gpio_is_valid(int number)
-{
- int gidx = altera_pio_gidx(number);
-
- if (gidx < 0)
- return 1;
- return 0;
-}
+static const struct dm_gpio_ops altera_pio_ops = {
+ .direction_input = altera_pio_direction_input,
+ .direction_output = altera_pio_direction_output,
+ .get_value = altera_pio_get_value,
+ .set_value = altera_pio_set_value,
+};
+
+static const struct udevice_id altera_pio_ids[] = {
+ { .compatible = "altr,pio-1.0" },
+ { }
+};
+
+U_BOOT_DRIVER(altera_pio) = {
+ .name = "altera_pio",
+ .id = UCLASS_GPIO,
+ .of_match = altera_pio_ids,
+ .ops = &altera_pio_ops,
+ .ofdata_to_platdata = altera_pio_ofdata_to_platdata,
+ .platdata_auto_alloc_size = sizeof(struct altera_pio_platdata),
+ .probe = altera_pio_probe,
+};
diff --git a/include/configs/nios2-generic.h b/include/configs/nios2-generic.h
index dcb90de..90ccbd1 100644
--- a/include/configs/nios2-generic.h
+++ b/include/configs/nios2-generic.h
@@ -33,26 +33,6 @@
#define CONFIG_SYS_TIMER_RATE CONFIG_SYS_TIMER_FREQ
/*
- * STATUS LED
- */
-#define CONFIG_ALTERA_PIO
-#define CONFIG_SYS_ALTERA_PIO_NUM 1
-#define CONFIG_SYS_ALTERA_PIO_GPIO_NUM LED_PIO_WIDTH
-
-#define CONFIG_STATUS_LED /* Enable status driver */
-#define CONFIG_BOARD_SPECIFIC_LED
-#define CONFIG_GPIO_LED /* Enable GPIO LED driver */
-#define CONFIG_GPIO /* Enable GPIO driver */
-#define LED_PIO_BASE USER_LED_PIO_8OUT_BASE
-#define LED_PIO_WIDTH 8
-#define LED_PIO_RSTVAL 0xff
-
-#define STATUS_LED_BIT 0 /* Bit-0 on GPIO */
-#define STATUS_LED_STATE STATUS_LED_ON
-#define STATUS_LED_PERIOD (CONFIG_SYS_HZ / 2) /* 500 msec */
-#define STATUS_LED_BOOT STATUS_LED_BIT
-
-/*
* BOOTP options
*/
#define CONFIG_BOOTP_BOOTFILESIZE
--
2.1.4
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [U-Boot] [PATCH v3] nios2 : convert altera_pio to driver model
2015-09-24 9:15 [U-Boot] [PATCH] nios2 : convert altera_pio to driver model Thomas Chou
2015-09-24 18:04 ` Marek Vasut
2015-09-25 8:05 ` [U-Boot] [PATCH v2] " Thomas Chou
@ 2015-09-26 9:07 ` Thomas Chou
2015-09-30 1:18 ` Chin Liang See
2015-09-30 18:29 ` Simon Glass
2015-09-30 13:37 ` [U-Boot] [PATCH v4] " Thomas Chou
3 siblings, 2 replies; 9+ messages in thread
From: Thomas Chou @ 2015-09-26 9:07 UTC (permalink / raw)
To: u-boot
Convert altera_pio to driver model.
Signed-off-by: Thomas Chou <thomas@wytron.com.tw>
---
v2
fix ranges of pio in dts
fix coding style as Marek suggested.
v3
change gpio_count device tree binding.
arch/nios2/dts/3c120_devboard.dts | 41 ++++
arch/nios2/include/asm/gpio.h | 80 +-------
board/altera/nios2-generic/nios2-generic.c | 7 -
configs/nios2-generic_defconfig | 2 +
drivers/gpio/Kconfig | 7 +
drivers/gpio/altera_pio.c | 316 +++++++----------------------
include/configs/nios2-generic.h | 20 --
7 files changed, 127 insertions(+), 346 deletions(-)
diff --git a/arch/nios2/dts/3c120_devboard.dts b/arch/nios2/dts/3c120_devboard.dts
index a35f5fe..781a652 100644
--- a/arch/nios2/dts/3c120_devboard.dts
+++ b/arch/nios2/dts/3c120_devboard.dts
@@ -68,6 +68,9 @@
<0x00004400 0x08004400 0x00000040>,
<0x00004800 0x08004800 0x00000040>,
<0x00004c80 0x08004c80 0x00000020>,
+ <0x00004cc0 0x08004cc0 0x00000010>,
+ <0x00004ce0 0x08004ce0 0x00000010>,
+ <0x00004d00 0x08004d00 0x00000010>,
<0x00004d50 0x08004d50 0x00000008>,
<0x00008000 0x08008000 0x00000020>,
<0x00400000 0x08400000 0x00000020>;
@@ -132,6 +135,44 @@
clock-frequency = <62500000>;
u-boot,dm-pre-reloc;
};
+
+ user_led_pio_8out: gpio at 0x4cc0 {
+ compatible = "altr,pio-1.0";
+ reg = <0x00004cc0 0x00000010>;
+ resetvalue = <255>;
+ altr,gpio-bank-width = <8>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-bank-name = "led";
+ };
+
+ user_dipsw_pio_8in: gpio at 0x4ce0 {
+ compatible = "altr,pio-1.0";
+ reg = <0x00004ce0 0x00000010>;
+ interrupt-parent = <&cpu>;
+ interrupts = <8>;
+ edge_type = <2>;
+ level_trigger = <0>;
+ resetvalue = <0>;
+ altr,gpio-bank-width = <8>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-bank-name = "dipsw";
+ };
+
+ user_pb_pio_4in: gpio at 0x4d00 {
+ compatible = "altr,pio-1.0";
+ reg = <0x00004d00 0x00000010>;
+ interrupt-parent = <&cpu>;
+ interrupts = <9>;
+ edge_type = <2>;
+ level_trigger = <0>;
+ resetvalue = <0>;
+ altr,gpio-bank-width = <4>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-bank-name = "pb";
+ };
};
cfi_flash_64m: flash at 0x0 {
diff --git a/arch/nios2/include/asm/gpio.h b/arch/nios2/include/asm/gpio.h
index 908381f..306ab4c 100644
--- a/arch/nios2/include/asm/gpio.h
+++ b/arch/nios2/include/asm/gpio.h
@@ -1,79 +1 @@
-/*
- * nios2 gpio driver
- *
- * This gpio core is described in http://nioswiki.com/GPIO
- * bit[0] data
- * bit[1] output enable
- *
- * When CONFIG_SYS_GPIO_BASE is not defined, the board may either
- * provide its own driver or the altera_pio driver may be used.
- *
- * Copyright (C) 2010 Thomas Chou <thomas@wytron.com.tw>
- *
- * 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.
- */
-
-#ifndef _ASM_NIOS2_GPIO_H_
-#define _ASM_NIOS2_GPIO_H_
-
-#ifdef CONFIG_SYS_GPIO_BASE
-#include <asm/io.h>
-
-static inline int gpio_request(unsigned gpio, const char *label)
-{
- return 0;
-}
-
-static inline int gpio_free(unsigned gpio)
-{
- return 0;
-}
-
-static inline int gpio_direction_input(unsigned gpio)
-{
- writel(1, CONFIG_SYS_GPIO_BASE + (gpio << 2));
- return 0;
-}
-
-static inline int gpio_direction_output(unsigned gpio, int value)
-{
- writel(value ? 3 : 2, CONFIG_SYS_GPIO_BASE + (gpio << 2));
- return 0;
-}
-
-static inline int gpio_get_value(unsigned gpio)
-{
- return readl(CONFIG_SYS_GPIO_BASE + (gpio << 2));
-}
-
-static inline void gpio_set_value(unsigned gpio, int value)
-{
- writel(value ? 3 : 2, CONFIG_SYS_GPIO_BASE + (gpio << 2));
-}
-
-static inline int gpio_is_valid(int number)
-{
- return ((unsigned)number) < CONFIG_SYS_GPIO_WIDTH;
-}
-#else
-#ifdef CONFIG_ALTERA_PIO
-extern int altera_pio_init(u32 base, u8 width, char iot,
- u32 rstval, u32 negmask,
- const char *label);
-
-extern void altera_pio_info(void);
-#define gpio_status() altera_pio_info()
-#endif
-
-extern int gpio_request(unsigned gpio, const char *label);
-extern int gpio_free(unsigned gpio);
-extern int gpio_direction_input(unsigned gpio);
-extern int gpio_direction_output(unsigned gpio, int value);
-extern int gpio_get_value(unsigned gpio);
-extern void gpio_set_value(unsigned gpio, int value);
-extern int gpio_is_valid(int number);
-#endif /* CONFIG_SYS_GPIO_BASE */
-
-#endif /* _ASM_NIOS2_GPIO_H_ */
+#include <asm-generic/gpio.h>
diff --git a/board/altera/nios2-generic/nios2-generic.c b/board/altera/nios2-generic/nios2-generic.c
index 384fee9..61d32c7 100644
--- a/board/altera/nios2-generic/nios2-generic.c
+++ b/board/altera/nios2-generic/nios2-generic.c
@@ -37,13 +37,6 @@ int board_early_init_f(void)
int board_early_init_r(void)
{
-#ifdef CONFIG_ALTERA_PIO
-#ifdef LED_PIO_BASE
- altera_pio_init(LED_PIO_BASE, LED_PIO_WIDTH, 'o',
- LED_PIO_RSTVAL, (1 << LED_PIO_WIDTH) - 1,
- "led");
-#endif
-#endif
return 0;
}
diff --git a/configs/nios2-generic_defconfig b/configs/nios2-generic_defconfig
index 9dc6a72..ad72272 100644
--- a/configs/nios2-generic_defconfig
+++ b/configs/nios2-generic_defconfig
@@ -1,5 +1,6 @@
CONFIG_NIOS2=y
CONFIG_DM_SERIAL=y
+CONFIG_DM_GPIO=y
CONFIG_TARGET_NIOS2_GENERIC=y
CONFIG_DEFAULT_DEVICE_TREE="3c120_devboard"
CONFIG_HUSH_PARSER=y
@@ -15,5 +16,6 @@ CONFIG_CMD_PING=y
CONFIG_OF_CONTROL=y
CONFIG_NET_RANDOM_ETHADDR=y
CONFIG_DM=y
+CONFIG_ALTERA_PIO=y
CONFIG_ALTERA_JTAG_UART=y
CONFIG_ALTERA_JTAG_UART_BYPASS=y
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index ef57a89..9e49471 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -14,6 +14,13 @@ config DM_GPIO
particular GPIOs that they provide. The uclass interface
is defined in include/asm-generic/gpio.h.
+config ALTERA_PIO
+ bool "Altera PIO driver"
+ depends on DM_GPIO
+ help
+ Select this to enable PIO for Altera devices. Please find
+ details on the "Embedded Peripherals IP User Guide" of Altera.
+
config DWAPB_GPIO
bool "DWAPB GPIO driver"
depends on DM && DM_GPIO
diff --git a/drivers/gpio/altera_pio.c b/drivers/gpio/altera_pio.c
index 3ca5907..2590017 100644
--- a/drivers/gpio/altera_pio.c
+++ b/drivers/gpio/altera_pio.c
@@ -1,286 +1,122 @@
/*
- * Driver for Altera's PIO ip core
- *
+ * Copyright (C) 2015 Thomas Chou <thomas@wytron.com.tw>
* Copyright (C) 2011 Missing Link Electronics
* Joachim Foerster <joachim@missinglinkelectronics.com>
*
* SPDX-License-Identifier: GPL-2.0+
- *
- * To use this driver, in your board's config. header:
- * #define CONFIG_ALTERA_PIO
- * #define CONFIG_SYS_ALTERA_PIO_NUM <number-of-pio-cores>
- * #define CONFIG_SYS_ALTERA_PIO_GPIO_NUM <total-number-of-gpios>
- * And in your board's early setup routine:
- * altera_pio_init(<baseaddr>, <width>, 'i'|'o'|'t',
- * <reset-value>, <neg-mask>, "label");
- * - 'i'|'o'|'t': PIO is input-only/output-only/tri-state
- * - <reset-value>: for correct initial status display, output-only
- * - <neg-mask> is meant to be used to in cases of active-low
- * GPIOs, such as LEDs and buttons (on/pressed == 0). Each bit
- * which is 1 in <neg-mask> inverts the corresponding GPIO's value
- * before set/after get. So: gpio_set_value(gpio, 1) => LED on .
- *
- * Do NOT define CONFIG_SYS_GPIO_BASE !
- *
- * Optionally, in your board's config. header:
- * - To force a GPIO numbering scheme like in Linux ...
- * #define CONFIG_GPIO_DOWNTO_NUMBERING
- * ... starting with 255 (default)
- * #define CONFIG_GPIO_DOWNTO_MAX 255
*/
#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <malloc.h>
+#include <fdtdec.h>
#include <asm/io.h>
#include <asm/gpio.h>
-#ifdef CONFIG_GPIO_DOWNTO_NUMBERING
-#ifndef CONFIG_GPIO_DOWNTO_MAX
-#define CONFIG_GPIO_DOWNTO_MAX 255
-#endif
-#endif
-
-#define ALTERA_PIO_DATA 0x0
-#define ALTERA_PIO_DIR 0x4
-
-#define GPIO_LABEL_SIZE 9
+DECLARE_GLOBAL_DATA_PTR;
+struct altera_pio_regs {
+ u32 data; /* Data register */
+ u32 direction; /* Direction register */
+};
-static struct altera_pio {
- u32 base;
- u8 width;
- char iot;
- u32 negmask;
- u32 sh_data;
- u32 sh_dir;
- int gidx;
- char label[GPIO_LABEL_SIZE];
-} pios[CONFIG_SYS_ALTERA_PIO_NUM];
+struct altera_pio_platdata {
+ struct altera_pio_regs *regs;
+ int gpio_count;
+ const char *bank_name;
+};
-static int pio_num;
-
-static struct altera_pio_gpio {
- unsigned num;
- struct altera_pio *pio;
- char reqlabel[GPIO_LABEL_SIZE];
-} gpios[CONFIG_SYS_ALTERA_PIO_GPIO_NUM];
-
-static int pio_gpio_num;
-
-
-static int altera_pio_gidx(unsigned gpio)
+static int altera_pio_direction_input(struct udevice *dev, unsigned pin)
{
- int i;
+ struct altera_pio_platdata *plat = dev_get_platdata(dev);
+ struct altera_pio_regs *const regs = plat->regs;
- for (i = 0; i < pio_gpio_num; ++i) {
- if (gpio == gpios[i].num)
- break;
- }
- if (i >= pio_gpio_num)
- return -1;
- return i;
-}
+ clrbits_le32(®s->direction, 1 << pin);
-static struct altera_pio *altera_pio_get_and_mask(unsigned gpio, u32 *mask)
-{
- int gidx = altera_pio_gidx(gpio);
- if (gidx < 0)
- return NULL;
- if (mask)
- *mask = 1 << (gidx - gpios[gidx].pio->gidx);
- return gpios[gidx].pio;
+ return 0;
}
-#define altera_pio_use_gidx(_gidx, _reqlabel) \
- { strncpy(gpios[_gidx].reqlabel, _reqlabel, GPIO_LABEL_SIZE); }
-#define altera_pio_unuse_gidx(_gidx) { gpios[_gidx].reqlabel[0] = '\0'; }
-#define altera_pio_is_gidx_used(_gidx) (gpios[_gidx].reqlabel[0] != '\0')
-
-static int altera_pio_gpio_init(struct altera_pio *pio, u8 width)
+static int altera_pio_direction_output(struct udevice *dev, unsigned pin,
+ int val)
{
- u8 gidx = pio_gpio_num;
- int i;
-
- if (!width)
- return -1;
- if ((pio_gpio_num + width) > CONFIG_SYS_ALTERA_PIO_GPIO_NUM)
- return -1;
-
- for (i = 0; i < width; ++i) {
-#ifdef CONFIG_GPIO_DOWNTO_NUMBERING
- gpios[pio_gpio_num + i].num = \
- CONFIG_GPIO_DOWNTO_MAX + 1 - gidx - width + i;
-#else
- gpios[pio_gpio_num + i].num = pio_gpio_num + i;
-#endif
- gpios[pio_gpio_num + i].pio = pio;
- altera_pio_unuse_gidx(pio_gpio_num + i);
- }
- pio_gpio_num += width;
- return gidx;
-}
+ struct altera_pio_platdata *plat = dev_get_platdata(dev);
+ struct altera_pio_regs *const regs = plat->regs;
-int altera_pio_init(u32 base, u8 width, char iot, u32 rstval, u32 negmask,
- const char *label)
-{
- if (pio_num >= CONFIG_SYS_ALTERA_PIO_NUM)
- return -1;
+ if (val)
+ setbits_le32(®s->data, 1 << pin);
+ else
+ clrbits_le32(®s->data, 1 << pin);
+ /* change the data first, then the direction. to avoid glitch */
+ setbits_le32(®s->direction, 1 << pin);
- pios[pio_num].base = base;
- pios[pio_num].width = width;
- pios[pio_num].iot = iot;
- switch (iot) {
- case 'i':
- /* input only */
- pios[pio_num].sh_dir = 0;
- pios[pio_num].sh_data = readl(base + ALTERA_PIO_DATA);
- break;
- case 'o':
- /* output only */
- pios[pio_num].sh_dir = 0xffffffff & ((1 << width) - 1);
- pios[pio_num].sh_data = rstval;
- break;
- case 't':
- /* bidir, tri-state */
- pios[pio_num].sh_dir = readl(base + ALTERA_PIO_DIR);
- pios[pio_num].sh_data = readl(base + ALTERA_PIO_DATA);
- break;
- default:
- return -1;
- }
- pios[pio_num].negmask = negmask & ((1 << width) - 1);
- pios[pio_num].gidx = altera_pio_gpio_init(&pios[pio_num], width);
- if (pios[pio_num].gidx < 0)
- return -1;
- strncpy(pios[pio_num].label, label, GPIO_LABEL_SIZE);
- return pio_num++;
+ return 0;
}
-void altera_pio_info(void)
+static int altera_pio_get_value(struct udevice *dev, unsigned pin)
{
- int i;
- int j;
- int gidx;
- u32 mask;
+ struct altera_pio_platdata *plat = dev_get_platdata(dev);
+ struct altera_pio_regs *const regs = plat->regs;
- for (i = 0; i < pio_num; ++i) {
- printf("Altera PIO % 2d, @0x%08x, "
- "width: %u, label: %s\n",
- i, pios[i].base, pios[i].width, pios[i].label);
- gidx = pios[i].gidx;
- for (j = gidx; j < (gidx + pios[i].width); ++j) {
- mask = 1 << (j - gidx);
- printf("\tGPIO % 4d: %s %s [%c] %s\n",
- gpios[j].num,
- gpios[j].pio->sh_dir & mask ? "out" : " in",
- gpio_get_value(gpios[j].num) ? "set" : "clr",
- altera_pio_is_gidx_used(j) ? 'x' : ' ',
- gpios[j].reqlabel);
- }
- }
+ return readl(®s->data) & (1 << pin);
}
-int gpio_request(unsigned gpio, const char *label)
+static int altera_pio_set_value(struct udevice *dev, unsigned pin, int val)
{
- int gidx = altera_pio_gidx(gpio);
- if (gidx < 0)
- return gidx;
- if (altera_pio_is_gidx_used(gidx))
- return -1;
-
- altera_pio_use_gidx(gidx, label);
- return 0;
-}
+ struct altera_pio_platdata *plat = dev_get_platdata(dev);
+ struct altera_pio_regs *const regs = plat->regs;
-int gpio_free(unsigned gpio)
-{
- int gidx = altera_pio_gidx(gpio);
- if (gidx < 0)
- return gidx;
- if (!altera_pio_is_gidx_used(gidx))
- return -1;
+ if (val)
+ setbits_le32(®s->data, 1 << pin);
+ else
+ clrbits_le32(®s->data, 1 << pin);
- altera_pio_unuse_gidx(gidx);
return 0;
}
-int gpio_direction_input(unsigned gpio)
+static int altera_pio_probe(struct udevice *dev)
{
- u32 mask;
- struct altera_pio *pio;
+ struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
+ struct altera_pio_platdata *plat = dev_get_platdata(dev);
- pio = altera_pio_get_and_mask(gpio, &mask);
- if (!pio)
- return -1;
- if (pio->iot == 'o')
- return -1;
+ uc_priv->gpio_count = plat->gpio_count;
+ uc_priv->bank_name = plat->bank_name;
- writel(pio->sh_dir &= ~mask, pio->base + ALTERA_PIO_DIR);
return 0;
}
-int gpio_direction_output(unsigned gpio, int value)
+static int altera_pio_ofdata_to_platdata(struct udevice *dev)
{
- u32 mask;
- struct altera_pio *pio;
+ struct altera_pio_platdata *plat = dev_get_platdata(dev);
- pio = altera_pio_get_and_mask(gpio, &mask);
- if (!pio)
- return -1;
- if (pio->iot == 'i')
- return -1;
+ plat->regs = ioremap(dev_get_addr(dev),
+ sizeof(struct altera_pio_regs));
+ plat->gpio_count = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
+ "altr,gpio-bank-width", 0);
+ plat->bank_name = fdt_getprop(gd->fdt_blob, dev->of_offset,
+ "gpio-bank-name", NULL);
- value = (pio->negmask & mask) ? !value : value;
- if (value)
- pio->sh_data |= mask;
- else
- pio->sh_data &= ~mask;
- writel(pio->sh_data, pio->base + ALTERA_PIO_DATA);
- writel(pio->sh_dir |= mask, pio->base + ALTERA_PIO_DIR);
return 0;
}
-int gpio_get_value(unsigned gpio)
-{
- u32 mask;
- struct altera_pio *pio;
- u32 val;
-
- pio = altera_pio_get_and_mask(gpio, &mask);
- if (!pio)
- return -1;
-
- if ((pio->sh_dir & mask) || (pio->iot == 'o'))
- val = pio->sh_data & mask;
- else
- val = readl(pio->base + ALTERA_PIO_DATA) & mask;
- return (pio->negmask & mask) ? !val : val;
-}
-
-void gpio_set_value(unsigned gpio, int value)
-{
- u32 mask;
- struct altera_pio *pio;
-
- pio = altera_pio_get_and_mask(gpio, &mask);
- if (!pio)
- return;
- if (pio->iot == 'i')
- return;
-
- value = (pio->negmask & mask) ? !value : value;
- if (value)
- pio->sh_data |= mask;
- else
- pio->sh_data &= ~mask;
- writel(pio->sh_data, pio->base + ALTERA_PIO_DATA);
- return;
-}
-
-int gpio_is_valid(int number)
-{
- int gidx = altera_pio_gidx(number);
-
- if (gidx < 0)
- return 1;
- return 0;
-}
+static const struct dm_gpio_ops altera_pio_ops = {
+ .direction_input = altera_pio_direction_input,
+ .direction_output = altera_pio_direction_output,
+ .get_value = altera_pio_get_value,
+ .set_value = altera_pio_set_value,
+};
+
+static const struct udevice_id altera_pio_ids[] = {
+ { .compatible = "altr,pio-1.0" },
+ { }
+};
+
+U_BOOT_DRIVER(altera_pio) = {
+ .name = "altera_pio",
+ .id = UCLASS_GPIO,
+ .of_match = altera_pio_ids,
+ .ops = &altera_pio_ops,
+ .ofdata_to_platdata = altera_pio_ofdata_to_platdata,
+ .platdata_auto_alloc_size = sizeof(struct altera_pio_platdata),
+ .probe = altera_pio_probe,
+};
diff --git a/include/configs/nios2-generic.h b/include/configs/nios2-generic.h
index dcb90de..90ccbd1 100644
--- a/include/configs/nios2-generic.h
+++ b/include/configs/nios2-generic.h
@@ -33,26 +33,6 @@
#define CONFIG_SYS_TIMER_RATE CONFIG_SYS_TIMER_FREQ
/*
- * STATUS LED
- */
-#define CONFIG_ALTERA_PIO
-#define CONFIG_SYS_ALTERA_PIO_NUM 1
-#define CONFIG_SYS_ALTERA_PIO_GPIO_NUM LED_PIO_WIDTH
-
-#define CONFIG_STATUS_LED /* Enable status driver */
-#define CONFIG_BOARD_SPECIFIC_LED
-#define CONFIG_GPIO_LED /* Enable GPIO LED driver */
-#define CONFIG_GPIO /* Enable GPIO driver */
-#define LED_PIO_BASE USER_LED_PIO_8OUT_BASE
-#define LED_PIO_WIDTH 8
-#define LED_PIO_RSTVAL 0xff
-
-#define STATUS_LED_BIT 0 /* Bit-0 on GPIO */
-#define STATUS_LED_STATE STATUS_LED_ON
-#define STATUS_LED_PERIOD (CONFIG_SYS_HZ / 2) /* 500 msec */
-#define STATUS_LED_BOOT STATUS_LED_BIT
-
-/*
* BOOTP options
*/
#define CONFIG_BOOTP_BOOTFILESIZE
--
2.1.4
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [U-Boot] [PATCH v3] nios2 : convert altera_pio to driver model
2015-09-26 9:07 ` [U-Boot] [PATCH v3] " Thomas Chou
@ 2015-09-30 1:18 ` Chin Liang See
2015-09-30 18:29 ` Simon Glass
1 sibling, 0 replies; 9+ messages in thread
From: Chin Liang See @ 2015-09-30 1:18 UTC (permalink / raw)
To: u-boot
Hi Thomas,
On Sat, 2015-09-26 at 17:07 +0800, thomas at wytron.com.tw wrote:
> Convert altera_pio to driver model.
>
> Signed-off-by: Thomas Chou <thomas@wytron.com.tw>
> ---
> v2
> fix ranges of pio in dts
> fix coding style as Marek suggested.
>
> v3
> change gpio_count device tree binding.
>
> arch/nios2/dts/3c120_devboard.dts | 41 ++++
> arch/nios2/include/asm/gpio.h | 80 +-------
> board/altera/nios2-generic/nios2-generic.c | 7 -
> configs/nios2-generic_defconfig | 2 +
> drivers/gpio/Kconfig | 7 +
> drivers/gpio/altera_pio.c | 316 +++++++----------------------
> include/configs/nios2-generic.h | 20 --
> 7 files changed, 127 insertions(+), 346 deletions(-)
>
Acked-by: Chin Liang See <clsee@altera.com>
Thanks
Chin Liang
^ permalink raw reply [flat|nested] 9+ messages in thread
* [U-Boot] [PATCH v4] nios2 : convert altera_pio to driver model
2015-09-24 9:15 [U-Boot] [PATCH] nios2 : convert altera_pio to driver model Thomas Chou
` (2 preceding siblings ...)
2015-09-26 9:07 ` [U-Boot] [PATCH v3] " Thomas Chou
@ 2015-09-30 13:37 ` Thomas Chou
2015-10-03 13:10 ` Thomas Chou
3 siblings, 1 reply; 9+ messages in thread
From: Thomas Chou @ 2015-09-30 13:37 UTC (permalink / raw)
To: u-boot
Convert altera_pio to driver model.
Signed-off-by: Thomas Chou <thomas@wytron.com.tw>
Acked-by: Chin Liang See <clsee@altera.com>
---
v2
fix ranges of pio in dts
fix coding style as Marek suggested.
v3
change gpio_count device tree binding.
v4
change gpio width default to 32.
doc dts binding.
arch/nios2/dts/3c120_devboard.dts | 41 ++++
arch/nios2/include/asm/gpio.h | 80 +------
board/altera/nios2-generic/nios2-generic.c | 7 -
configs/nios2-generic_defconfig | 2 +
doc/device-tree-bindings/gpio/altera_pio.txt | 28 +++
drivers/gpio/Kconfig | 7 +
drivers/gpio/altera_pio.c | 316 +++++++--------------------
include/configs/nios2-generic.h | 20 --
8 files changed, 155 insertions(+), 346 deletions(-)
create mode 100644 doc/device-tree-bindings/gpio/altera_pio.txt
diff --git a/arch/nios2/dts/3c120_devboard.dts b/arch/nios2/dts/3c120_devboard.dts
index a35f5fe..781a652 100644
--- a/arch/nios2/dts/3c120_devboard.dts
+++ b/arch/nios2/dts/3c120_devboard.dts
@@ -68,6 +68,9 @@
<0x00004400 0x08004400 0x00000040>,
<0x00004800 0x08004800 0x00000040>,
<0x00004c80 0x08004c80 0x00000020>,
+ <0x00004cc0 0x08004cc0 0x00000010>,
+ <0x00004ce0 0x08004ce0 0x00000010>,
+ <0x00004d00 0x08004d00 0x00000010>,
<0x00004d50 0x08004d50 0x00000008>,
<0x00008000 0x08008000 0x00000020>,
<0x00400000 0x08400000 0x00000020>;
@@ -132,6 +135,44 @@
clock-frequency = <62500000>;
u-boot,dm-pre-reloc;
};
+
+ user_led_pio_8out: gpio at 0x4cc0 {
+ compatible = "altr,pio-1.0";
+ reg = <0x00004cc0 0x00000010>;
+ resetvalue = <255>;
+ altr,gpio-bank-width = <8>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-bank-name = "led";
+ };
+
+ user_dipsw_pio_8in: gpio at 0x4ce0 {
+ compatible = "altr,pio-1.0";
+ reg = <0x00004ce0 0x00000010>;
+ interrupt-parent = <&cpu>;
+ interrupts = <8>;
+ edge_type = <2>;
+ level_trigger = <0>;
+ resetvalue = <0>;
+ altr,gpio-bank-width = <8>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-bank-name = "dipsw";
+ };
+
+ user_pb_pio_4in: gpio at 0x4d00 {
+ compatible = "altr,pio-1.0";
+ reg = <0x00004d00 0x00000010>;
+ interrupt-parent = <&cpu>;
+ interrupts = <9>;
+ edge_type = <2>;
+ level_trigger = <0>;
+ resetvalue = <0>;
+ altr,gpio-bank-width = <4>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-bank-name = "pb";
+ };
};
cfi_flash_64m: flash at 0x0 {
diff --git a/arch/nios2/include/asm/gpio.h b/arch/nios2/include/asm/gpio.h
index 908381f..306ab4c 100644
--- a/arch/nios2/include/asm/gpio.h
+++ b/arch/nios2/include/asm/gpio.h
@@ -1,79 +1 @@
-/*
- * nios2 gpio driver
- *
- * This gpio core is described in http://nioswiki.com/GPIO
- * bit[0] data
- * bit[1] output enable
- *
- * When CONFIG_SYS_GPIO_BASE is not defined, the board may either
- * provide its own driver or the altera_pio driver may be used.
- *
- * Copyright (C) 2010 Thomas Chou <thomas@wytron.com.tw>
- *
- * 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.
- */
-
-#ifndef _ASM_NIOS2_GPIO_H_
-#define _ASM_NIOS2_GPIO_H_
-
-#ifdef CONFIG_SYS_GPIO_BASE
-#include <asm/io.h>
-
-static inline int gpio_request(unsigned gpio, const char *label)
-{
- return 0;
-}
-
-static inline int gpio_free(unsigned gpio)
-{
- return 0;
-}
-
-static inline int gpio_direction_input(unsigned gpio)
-{
- writel(1, CONFIG_SYS_GPIO_BASE + (gpio << 2));
- return 0;
-}
-
-static inline int gpio_direction_output(unsigned gpio, int value)
-{
- writel(value ? 3 : 2, CONFIG_SYS_GPIO_BASE + (gpio << 2));
- return 0;
-}
-
-static inline int gpio_get_value(unsigned gpio)
-{
- return readl(CONFIG_SYS_GPIO_BASE + (gpio << 2));
-}
-
-static inline void gpio_set_value(unsigned gpio, int value)
-{
- writel(value ? 3 : 2, CONFIG_SYS_GPIO_BASE + (gpio << 2));
-}
-
-static inline int gpio_is_valid(int number)
-{
- return ((unsigned)number) < CONFIG_SYS_GPIO_WIDTH;
-}
-#else
-#ifdef CONFIG_ALTERA_PIO
-extern int altera_pio_init(u32 base, u8 width, char iot,
- u32 rstval, u32 negmask,
- const char *label);
-
-extern void altera_pio_info(void);
-#define gpio_status() altera_pio_info()
-#endif
-
-extern int gpio_request(unsigned gpio, const char *label);
-extern int gpio_free(unsigned gpio);
-extern int gpio_direction_input(unsigned gpio);
-extern int gpio_direction_output(unsigned gpio, int value);
-extern int gpio_get_value(unsigned gpio);
-extern void gpio_set_value(unsigned gpio, int value);
-extern int gpio_is_valid(int number);
-#endif /* CONFIG_SYS_GPIO_BASE */
-
-#endif /* _ASM_NIOS2_GPIO_H_ */
+#include <asm-generic/gpio.h>
diff --git a/board/altera/nios2-generic/nios2-generic.c b/board/altera/nios2-generic/nios2-generic.c
index 384fee9..61d32c7 100644
--- a/board/altera/nios2-generic/nios2-generic.c
+++ b/board/altera/nios2-generic/nios2-generic.c
@@ -37,13 +37,6 @@ int board_early_init_f(void)
int board_early_init_r(void)
{
-#ifdef CONFIG_ALTERA_PIO
-#ifdef LED_PIO_BASE
- altera_pio_init(LED_PIO_BASE, LED_PIO_WIDTH, 'o',
- LED_PIO_RSTVAL, (1 << LED_PIO_WIDTH) - 1,
- "led");
-#endif
-#endif
return 0;
}
diff --git a/configs/nios2-generic_defconfig b/configs/nios2-generic_defconfig
index 9dc6a72..ad72272 100644
--- a/configs/nios2-generic_defconfig
+++ b/configs/nios2-generic_defconfig
@@ -1,5 +1,6 @@
CONFIG_NIOS2=y
CONFIG_DM_SERIAL=y
+CONFIG_DM_GPIO=y
CONFIG_TARGET_NIOS2_GENERIC=y
CONFIG_DEFAULT_DEVICE_TREE="3c120_devboard"
CONFIG_HUSH_PARSER=y
@@ -15,5 +16,6 @@ CONFIG_CMD_PING=y
CONFIG_OF_CONTROL=y
CONFIG_NET_RANDOM_ETHADDR=y
CONFIG_DM=y
+CONFIG_ALTERA_PIO=y
CONFIG_ALTERA_JTAG_UART=y
CONFIG_ALTERA_JTAG_UART_BYPASS=y
diff --git a/doc/device-tree-bindings/gpio/altera_pio.txt b/doc/device-tree-bindings/gpio/altera_pio.txt
new file mode 100644
index 0000000..cf71eb2
--- /dev/null
+++ b/doc/device-tree-bindings/gpio/altera_pio.txt
@@ -0,0 +1,28 @@
+Altera GPIO controller bindings
+
+Required properties:
+- compatible:
+ - "altr,pio-1.0"
+- reg: Physical base address and length of the controller's registers.
+
+Optional properties:
+- altr,gpio-bank-width: Width of the GPIO bank. This defines how many pins the
+ GPIO device has. Ranges between 1-32. Optional and defaults to 32 if not
+ specified.
+- gpio-bank-name: bank name attached to this device.
+
+Example:
+
+user_led_pio_8out: gpio@0x4cc0 {
+ compatible = "altr,pio-1.0";
+ reg = <0x00004cc0 0x00000010>;
+ resetvalue = <255>;
+ altr,gpio-bank-width = <8>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-bank-name = "led";
+};
+
+In this example, the gpio can be accessed as led[0..7] using gpio command of
+u-boot.
+==> gpio clear led0
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index ef57a89..9e49471 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -14,6 +14,13 @@ config DM_GPIO
particular GPIOs that they provide. The uclass interface
is defined in include/asm-generic/gpio.h.
+config ALTERA_PIO
+ bool "Altera PIO driver"
+ depends on DM_GPIO
+ help
+ Select this to enable PIO for Altera devices. Please find
+ details on the "Embedded Peripherals IP User Guide" of Altera.
+
config DWAPB_GPIO
bool "DWAPB GPIO driver"
depends on DM && DM_GPIO
diff --git a/drivers/gpio/altera_pio.c b/drivers/gpio/altera_pio.c
index 3ca5907..7ceb80e 100644
--- a/drivers/gpio/altera_pio.c
+++ b/drivers/gpio/altera_pio.c
@@ -1,286 +1,122 @@
/*
- * Driver for Altera's PIO ip core
- *
+ * Copyright (C) 2015 Thomas Chou <thomas@wytron.com.tw>
* Copyright (C) 2011 Missing Link Electronics
* Joachim Foerster <joachim@missinglinkelectronics.com>
*
* SPDX-License-Identifier: GPL-2.0+
- *
- * To use this driver, in your board's config. header:
- * #define CONFIG_ALTERA_PIO
- * #define CONFIG_SYS_ALTERA_PIO_NUM <number-of-pio-cores>
- * #define CONFIG_SYS_ALTERA_PIO_GPIO_NUM <total-number-of-gpios>
- * And in your board's early setup routine:
- * altera_pio_init(<baseaddr>, <width>, 'i'|'o'|'t',
- * <reset-value>, <neg-mask>, "label");
- * - 'i'|'o'|'t': PIO is input-only/output-only/tri-state
- * - <reset-value>: for correct initial status display, output-only
- * - <neg-mask> is meant to be used to in cases of active-low
- * GPIOs, such as LEDs and buttons (on/pressed == 0). Each bit
- * which is 1 in <neg-mask> inverts the corresponding GPIO's value
- * before set/after get. So: gpio_set_value(gpio, 1) => LED on .
- *
- * Do NOT define CONFIG_SYS_GPIO_BASE !
- *
- * Optionally, in your board's config. header:
- * - To force a GPIO numbering scheme like in Linux ...
- * #define CONFIG_GPIO_DOWNTO_NUMBERING
- * ... starting with 255 (default)
- * #define CONFIG_GPIO_DOWNTO_MAX 255
*/
#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <malloc.h>
+#include <fdtdec.h>
#include <asm/io.h>
#include <asm/gpio.h>
-#ifdef CONFIG_GPIO_DOWNTO_NUMBERING
-#ifndef CONFIG_GPIO_DOWNTO_MAX
-#define CONFIG_GPIO_DOWNTO_MAX 255
-#endif
-#endif
-
-#define ALTERA_PIO_DATA 0x0
-#define ALTERA_PIO_DIR 0x4
-
-#define GPIO_LABEL_SIZE 9
+DECLARE_GLOBAL_DATA_PTR;
+struct altera_pio_regs {
+ u32 data; /* Data register */
+ u32 direction; /* Direction register */
+};
-static struct altera_pio {
- u32 base;
- u8 width;
- char iot;
- u32 negmask;
- u32 sh_data;
- u32 sh_dir;
- int gidx;
- char label[GPIO_LABEL_SIZE];
-} pios[CONFIG_SYS_ALTERA_PIO_NUM];
+struct altera_pio_platdata {
+ struct altera_pio_regs *regs;
+ int gpio_count;
+ const char *bank_name;
+};
-static int pio_num;
-
-static struct altera_pio_gpio {
- unsigned num;
- struct altera_pio *pio;
- char reqlabel[GPIO_LABEL_SIZE];
-} gpios[CONFIG_SYS_ALTERA_PIO_GPIO_NUM];
-
-static int pio_gpio_num;
-
-
-static int altera_pio_gidx(unsigned gpio)
+static int altera_pio_direction_input(struct udevice *dev, unsigned pin)
{
- int i;
+ struct altera_pio_platdata *plat = dev_get_platdata(dev);
+ struct altera_pio_regs *const regs = plat->regs;
- for (i = 0; i < pio_gpio_num; ++i) {
- if (gpio == gpios[i].num)
- break;
- }
- if (i >= pio_gpio_num)
- return -1;
- return i;
-}
+ clrbits_le32(®s->direction, 1 << pin);
-static struct altera_pio *altera_pio_get_and_mask(unsigned gpio, u32 *mask)
-{
- int gidx = altera_pio_gidx(gpio);
- if (gidx < 0)
- return NULL;
- if (mask)
- *mask = 1 << (gidx - gpios[gidx].pio->gidx);
- return gpios[gidx].pio;
+ return 0;
}
-#define altera_pio_use_gidx(_gidx, _reqlabel) \
- { strncpy(gpios[_gidx].reqlabel, _reqlabel, GPIO_LABEL_SIZE); }
-#define altera_pio_unuse_gidx(_gidx) { gpios[_gidx].reqlabel[0] = '\0'; }
-#define altera_pio_is_gidx_used(_gidx) (gpios[_gidx].reqlabel[0] != '\0')
-
-static int altera_pio_gpio_init(struct altera_pio *pio, u8 width)
+static int altera_pio_direction_output(struct udevice *dev, unsigned pin,
+ int val)
{
- u8 gidx = pio_gpio_num;
- int i;
-
- if (!width)
- return -1;
- if ((pio_gpio_num + width) > CONFIG_SYS_ALTERA_PIO_GPIO_NUM)
- return -1;
-
- for (i = 0; i < width; ++i) {
-#ifdef CONFIG_GPIO_DOWNTO_NUMBERING
- gpios[pio_gpio_num + i].num = \
- CONFIG_GPIO_DOWNTO_MAX + 1 - gidx - width + i;
-#else
- gpios[pio_gpio_num + i].num = pio_gpio_num + i;
-#endif
- gpios[pio_gpio_num + i].pio = pio;
- altera_pio_unuse_gidx(pio_gpio_num + i);
- }
- pio_gpio_num += width;
- return gidx;
-}
+ struct altera_pio_platdata *plat = dev_get_platdata(dev);
+ struct altera_pio_regs *const regs = plat->regs;
-int altera_pio_init(u32 base, u8 width, char iot, u32 rstval, u32 negmask,
- const char *label)
-{
- if (pio_num >= CONFIG_SYS_ALTERA_PIO_NUM)
- return -1;
+ if (val)
+ setbits_le32(®s->data, 1 << pin);
+ else
+ clrbits_le32(®s->data, 1 << pin);
+ /* change the data first, then the direction. to avoid glitch */
+ setbits_le32(®s->direction, 1 << pin);
- pios[pio_num].base = base;
- pios[pio_num].width = width;
- pios[pio_num].iot = iot;
- switch (iot) {
- case 'i':
- /* input only */
- pios[pio_num].sh_dir = 0;
- pios[pio_num].sh_data = readl(base + ALTERA_PIO_DATA);
- break;
- case 'o':
- /* output only */
- pios[pio_num].sh_dir = 0xffffffff & ((1 << width) - 1);
- pios[pio_num].sh_data = rstval;
- break;
- case 't':
- /* bidir, tri-state */
- pios[pio_num].sh_dir = readl(base + ALTERA_PIO_DIR);
- pios[pio_num].sh_data = readl(base + ALTERA_PIO_DATA);
- break;
- default:
- return -1;
- }
- pios[pio_num].negmask = negmask & ((1 << width) - 1);
- pios[pio_num].gidx = altera_pio_gpio_init(&pios[pio_num], width);
- if (pios[pio_num].gidx < 0)
- return -1;
- strncpy(pios[pio_num].label, label, GPIO_LABEL_SIZE);
- return pio_num++;
+ return 0;
}
-void altera_pio_info(void)
+static int altera_pio_get_value(struct udevice *dev, unsigned pin)
{
- int i;
- int j;
- int gidx;
- u32 mask;
+ struct altera_pio_platdata *plat = dev_get_platdata(dev);
+ struct altera_pio_regs *const regs = plat->regs;
- for (i = 0; i < pio_num; ++i) {
- printf("Altera PIO % 2d, @0x%08x, "
- "width: %u, label: %s\n",
- i, pios[i].base, pios[i].width, pios[i].label);
- gidx = pios[i].gidx;
- for (j = gidx; j < (gidx + pios[i].width); ++j) {
- mask = 1 << (j - gidx);
- printf("\tGPIO % 4d: %s %s [%c] %s\n",
- gpios[j].num,
- gpios[j].pio->sh_dir & mask ? "out" : " in",
- gpio_get_value(gpios[j].num) ? "set" : "clr",
- altera_pio_is_gidx_used(j) ? 'x' : ' ',
- gpios[j].reqlabel);
- }
- }
+ return readl(®s->data) & (1 << pin);
}
-int gpio_request(unsigned gpio, const char *label)
+static int altera_pio_set_value(struct udevice *dev, unsigned pin, int val)
{
- int gidx = altera_pio_gidx(gpio);
- if (gidx < 0)
- return gidx;
- if (altera_pio_is_gidx_used(gidx))
- return -1;
-
- altera_pio_use_gidx(gidx, label);
- return 0;
-}
+ struct altera_pio_platdata *plat = dev_get_platdata(dev);
+ struct altera_pio_regs *const regs = plat->regs;
-int gpio_free(unsigned gpio)
-{
- int gidx = altera_pio_gidx(gpio);
- if (gidx < 0)
- return gidx;
- if (!altera_pio_is_gidx_used(gidx))
- return -1;
+ if (val)
+ setbits_le32(®s->data, 1 << pin);
+ else
+ clrbits_le32(®s->data, 1 << pin);
- altera_pio_unuse_gidx(gidx);
return 0;
}
-int gpio_direction_input(unsigned gpio)
+static int altera_pio_probe(struct udevice *dev)
{
- u32 mask;
- struct altera_pio *pio;
+ struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
+ struct altera_pio_platdata *plat = dev_get_platdata(dev);
- pio = altera_pio_get_and_mask(gpio, &mask);
- if (!pio)
- return -1;
- if (pio->iot == 'o')
- return -1;
+ uc_priv->gpio_count = plat->gpio_count;
+ uc_priv->bank_name = plat->bank_name;
- writel(pio->sh_dir &= ~mask, pio->base + ALTERA_PIO_DIR);
return 0;
}
-int gpio_direction_output(unsigned gpio, int value)
+static int altera_pio_ofdata_to_platdata(struct udevice *dev)
{
- u32 mask;
- struct altera_pio *pio;
+ struct altera_pio_platdata *plat = dev_get_platdata(dev);
- pio = altera_pio_get_and_mask(gpio, &mask);
- if (!pio)
- return -1;
- if (pio->iot == 'i')
- return -1;
+ plat->regs = ioremap(dev_get_addr(dev),
+ sizeof(struct altera_pio_regs));
+ plat->gpio_count = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
+ "altr,gpio-bank-width", 32);
+ plat->bank_name = fdt_getprop(gd->fdt_blob, dev->of_offset,
+ "gpio-bank-name", NULL);
- value = (pio->negmask & mask) ? !value : value;
- if (value)
- pio->sh_data |= mask;
- else
- pio->sh_data &= ~mask;
- writel(pio->sh_data, pio->base + ALTERA_PIO_DATA);
- writel(pio->sh_dir |= mask, pio->base + ALTERA_PIO_DIR);
return 0;
}
-int gpio_get_value(unsigned gpio)
-{
- u32 mask;
- struct altera_pio *pio;
- u32 val;
-
- pio = altera_pio_get_and_mask(gpio, &mask);
- if (!pio)
- return -1;
-
- if ((pio->sh_dir & mask) || (pio->iot == 'o'))
- val = pio->sh_data & mask;
- else
- val = readl(pio->base + ALTERA_PIO_DATA) & mask;
- return (pio->negmask & mask) ? !val : val;
-}
-
-void gpio_set_value(unsigned gpio, int value)
-{
- u32 mask;
- struct altera_pio *pio;
-
- pio = altera_pio_get_and_mask(gpio, &mask);
- if (!pio)
- return;
- if (pio->iot == 'i')
- return;
-
- value = (pio->negmask & mask) ? !value : value;
- if (value)
- pio->sh_data |= mask;
- else
- pio->sh_data &= ~mask;
- writel(pio->sh_data, pio->base + ALTERA_PIO_DATA);
- return;
-}
-
-int gpio_is_valid(int number)
-{
- int gidx = altera_pio_gidx(number);
-
- if (gidx < 0)
- return 1;
- return 0;
-}
+static const struct dm_gpio_ops altera_pio_ops = {
+ .direction_input = altera_pio_direction_input,
+ .direction_output = altera_pio_direction_output,
+ .get_value = altera_pio_get_value,
+ .set_value = altera_pio_set_value,
+};
+
+static const struct udevice_id altera_pio_ids[] = {
+ { .compatible = "altr,pio-1.0" },
+ { }
+};
+
+U_BOOT_DRIVER(altera_pio) = {
+ .name = "altera_pio",
+ .id = UCLASS_GPIO,
+ .of_match = altera_pio_ids,
+ .ops = &altera_pio_ops,
+ .ofdata_to_platdata = altera_pio_ofdata_to_platdata,
+ .platdata_auto_alloc_size = sizeof(struct altera_pio_platdata),
+ .probe = altera_pio_probe,
+};
diff --git a/include/configs/nios2-generic.h b/include/configs/nios2-generic.h
index dcb90de..90ccbd1 100644
--- a/include/configs/nios2-generic.h
+++ b/include/configs/nios2-generic.h
@@ -33,26 +33,6 @@
#define CONFIG_SYS_TIMER_RATE CONFIG_SYS_TIMER_FREQ
/*
- * STATUS LED
- */
-#define CONFIG_ALTERA_PIO
-#define CONFIG_SYS_ALTERA_PIO_NUM 1
-#define CONFIG_SYS_ALTERA_PIO_GPIO_NUM LED_PIO_WIDTH
-
-#define CONFIG_STATUS_LED /* Enable status driver */
-#define CONFIG_BOARD_SPECIFIC_LED
-#define CONFIG_GPIO_LED /* Enable GPIO LED driver */
-#define CONFIG_GPIO /* Enable GPIO driver */
-#define LED_PIO_BASE USER_LED_PIO_8OUT_BASE
-#define LED_PIO_WIDTH 8
-#define LED_PIO_RSTVAL 0xff
-
-#define STATUS_LED_BIT 0 /* Bit-0 on GPIO */
-#define STATUS_LED_STATE STATUS_LED_ON
-#define STATUS_LED_PERIOD (CONFIG_SYS_HZ / 2) /* 500 msec */
-#define STATUS_LED_BOOT STATUS_LED_BIT
-
-/*
* BOOTP options
*/
#define CONFIG_BOOTP_BOOTFILESIZE
--
2.1.4
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [U-Boot] [PATCH v3] nios2 : convert altera_pio to driver model
2015-09-26 9:07 ` [U-Boot] [PATCH v3] " Thomas Chou
2015-09-30 1:18 ` Chin Liang See
@ 2015-09-30 18:29 ` Simon Glass
2015-10-01 0:38 ` Thomas Chou
1 sibling, 1 reply; 9+ messages in thread
From: Simon Glass @ 2015-09-30 18:29 UTC (permalink / raw)
To: u-boot
On 26 September 2015 at 03:07, Thomas Chou <thomas@wytron.com.tw> wrote:
> Convert altera_pio to driver model.
>
> Signed-off-by: Thomas Chou <thomas@wytron.com.tw>
> ---
> v2
> fix ranges of pio in dts
> fix coding style as Marek suggested.
>
> v3
> change gpio_count device tree binding.
>
> arch/nios2/dts/3c120_devboard.dts | 41 ++++
> arch/nios2/include/asm/gpio.h | 80 +-------
> board/altera/nios2-generic/nios2-generic.c | 7 -
> configs/nios2-generic_defconfig | 2 +
> drivers/gpio/Kconfig | 7 +
> drivers/gpio/altera_pio.c | 316 +++++++----------------------
> include/configs/nios2-generic.h | 20 --
> 7 files changed, 127 insertions(+), 346 deletions(-)
Reviewed-by: Simon Glass <sjg@chromium.org>
See question below.
[snip]
> -int gpio_direction_output(unsigned gpio, int value)
> +static int altera_pio_ofdata_to_platdata(struct udevice *dev)
> {
> - u32 mask;
> - struct altera_pio *pio;
> + struct altera_pio_platdata *plat = dev_get_platdata(dev);
>
> - pio = altera_pio_get_and_mask(gpio, &mask);
> - if (!pio)
> - return -1;
> - if (pio->iot == 'i')
> - return -1;
> + plat->regs = ioremap(dev_get_addr(dev),
> + sizeof(struct altera_pio_regs));
Do we need the ioremap() or can we rely on the 'ranges' handling?
[snip]
^ permalink raw reply [flat|nested] 9+ messages in thread
* [U-Boot] [PATCH v3] nios2 : convert altera_pio to driver model
2015-09-30 18:29 ` Simon Glass
@ 2015-10-01 0:38 ` Thomas Chou
0 siblings, 0 replies; 9+ messages in thread
From: Thomas Chou @ 2015-10-01 0:38 UTC (permalink / raw)
To: u-boot
Hi Simon,
On 10/01/2015 02:29 AM, Simon Glass wrote:
> Do we need the ioremap() or can we rely on the 'ranges' handling?
Yes, we do need ioremap() at least for mips, nios2 and alike. For these
archs, the virtual address that CPU sees is not the same as physical
address on bus. The virtual address space of these CPus are divided to
cached kernel space, uncached kernel space, and managed user space. For
main memory, we would use cached kernel space to run u-boot. While for
peripheral access, we would use uncached kernel space. The device tree
describes hardware, and the reg address have to be physical address. We
need to map the reg address to uncached kernel virtual address. This is
what ioremap() for. It is not related to ranges translation. Though we
do need the range translation patch from Stefan as there might be
bridges between the buses.
Thanks a lot for your review.
Best regards,
Thomas Chou
^ permalink raw reply [flat|nested] 9+ messages in thread
* [U-Boot] [PATCH v4] nios2 : convert altera_pio to driver model
2015-09-30 13:37 ` [U-Boot] [PATCH v4] " Thomas Chou
@ 2015-10-03 13:10 ` Thomas Chou
0 siblings, 0 replies; 9+ messages in thread
From: Thomas Chou @ 2015-10-03 13:10 UTC (permalink / raw)
To: u-boot
On 09/30/2015 09:37 PM, Thomas Chou wrote:
> Convert altera_pio to driver model.
>
> Signed-off-by: Thomas Chou <thomas@wytron.com.tw>
> Acked-by: Chin Liang See <clsee@altera.com>
> ---
> v2
> fix ranges of pio in dts
> fix coding style as Marek suggested.
> v3
> change gpio_count device tree binding.
> v4
> change gpio width default to 32.
> doc dts binding.
>
Applied to u-boot-nios.
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2015-10-03 13:10 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-09-24 9:15 [U-Boot] [PATCH] nios2 : convert altera_pio to driver model Thomas Chou
2015-09-24 18:04 ` Marek Vasut
2015-09-25 8:05 ` [U-Boot] [PATCH v2] " Thomas Chou
2015-09-26 9:07 ` [U-Boot] [PATCH v3] " Thomas Chou
2015-09-30 1:18 ` Chin Liang See
2015-09-30 18:29 ` Simon Glass
2015-10-01 0:38 ` Thomas Chou
2015-09-30 13:37 ` [U-Boot] [PATCH v4] " Thomas Chou
2015-10-03 13:10 ` Thomas Chou
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox