kmp204x: introduce QRIO GPIO functions
authorValentin Longchamp <valentin.longchamp@keymile.com>
Mon, 27 Jan 2014 10:49:05 +0000 (11:49 +0100)
committerYork Sun <yorksun@freescale.com>
Mon, 3 Feb 2014 16:38:49 +0000 (08:38 -0800)
The QRIO GPIO functions can be of general interest. They are thus added
to a qrio.c and their prototype are available from kmp204x.h. The QRIO
prst function are also included in this file, as well as the functions
required for the I2C deblocking support (open-drain).

Signed-off-by: Valentin Longchamp <valentin.longchamp@keymile.com>
[York Sun: Remove extra blank line in board/keymile/kmp204x/qrio.c]
Signed-off-by: York Sun <yorksun@freescale.com>
board/keymile/kmp204x/Makefile
board/keymile/kmp204x/kmp204x.c
board/keymile/kmp204x/kmp204x.h
board/keymile/kmp204x/qrio.c [new file with mode: 0644]

index 3e69ee2f15e18401fccbce16c3f0e6571ecbe1e9..c57ca08e1476ed276172b633f07691a00e8e10bf 100644 (file)
@@ -8,5 +8,5 @@
 # SPDX-License-Identifier:     GPL-2.0+
 #
 
-obj-y  := kmp204x.o ddr.o eth.o tlb.o pci.o law.o \
+obj-y  := kmp204x.o ddr.o eth.o tlb.o pci.o law.o qrio.o \
        ../common/common.o ../common/ivm.o
index 20a32642bbcb0e2706a12db3559f88303d6969e6..bbb24531557dcb0d54dbfaaaa1dcbf767b4d8010 100644 (file)
@@ -77,62 +77,6 @@ unsigned long get_board_sys_clk(unsigned long dummy)
        return 66666666;
 }
 
-#define WDMASK_OFF     0x16
-
-static void qrio_wdmask(u8 bit, bool wden)
-{
-       u16 wdmask;
-       void __iomem *qrio_base = (void *)CONFIG_SYS_QRIO_BASE;
-
-       wdmask = in_be16(qrio_base + WDMASK_OFF);
-
-       if (wden)
-               wdmask |= (1 << bit);
-       else
-               wdmask &= ~(1 << bit);
-
-       out_be16(qrio_base + WDMASK_OFF, wdmask);
-}
-
-#define PRST_OFF       0x1a
-
-void qrio_prst(u8 bit, bool en, bool wden)
-{
-       u16 prst;
-       void __iomem *qrio_base = (void *)CONFIG_SYS_QRIO_BASE;
-
-       qrio_wdmask(bit, wden);
-
-       prst = in_be16(qrio_base + PRST_OFF);
-
-       if (en)
-               prst &= ~(1 << bit);
-       else
-               prst |= (1 << bit);
-
-       out_be16(qrio_base + PRST_OFF, prst);
-}
-
-#define PRSTCFG_OFF    0x1c
-
-void qrio_prstcfg(u8 bit, u8 mode)
-{
-       u32 prstcfg;
-       u8 i;
-       void __iomem *qrio_base = (void *)CONFIG_SYS_QRIO_BASE;
-
-       prstcfg = in_be32(qrio_base + PRSTCFG_OFF);
-
-       for (i = 0; i < 2; i++) {
-               if (mode & (1<<i))
-                       set_bit(2*bit+i, &prstcfg);
-               else
-                       clear_bit(2*bit+i, &prstcfg);
-       }
-
-       out_be32(qrio_base + PRSTCFG_OFF, prstcfg);
-}
-
 #define NUM_SRDS_BANKS 2
 #define PHY_RST                15
 
index b6ba67241302ad4825bde46122b847a8ae7d20de..0267596e4e5eef26eabafa211a06d95e94a25334 100644 (file)
@@ -5,6 +5,16 @@
  * SPDX-License-Identifier:    GPL-2.0+
  */
 
+/* QRIO GPIO ports */
+#define GPIO_A                 0x40
+#define GPIO_B                 0x60
+
+int qrio_get_gpio(u8 port_off, u8 gpio_nr);
+void qrio_set_opendrain_gpio(u8 port_off, u8 gpio_nr, u8 val);
+void qrio_set_gpio(u8 port_off, u8 gpio_nr, bool value);
+void qrio_gpio_direction_output(u8 port_off, u8 gpio_nr, bool value);
+void qrio_gpio_direction_input(u8 port_off, u8 gpio_nr);
+
 #define PRSTCFG_POWUP_UNIT_CORE_RST    0x0
 #define PRSTCFG_POWUP_UNIT_RST         0x1
 #define PRSTCFG_POWUP_RST              0x3
diff --git a/board/keymile/kmp204x/qrio.c b/board/keymile/kmp204x/qrio.c
new file mode 100644 (file)
index 0000000..49f9aa2
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+ * (C) Copyright 2013 Keymile AG
+ * Valentin Longchamp <valentin.longchamp@keymile.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+
+#include "../common/common.h"
+#include "kmp204x.h"
+
+/* QRIO GPIO register offsets */
+#define DIRECT_OFF             0x18
+#define GPRT_OFF               0x1c
+
+int qrio_get_gpio(u8 port_off, u8 gpio_nr)
+{
+       u32 gprt;
+
+       void __iomem *qrio_base = (void *)CONFIG_SYS_QRIO_BASE;
+
+       gprt = in_be32(qrio_base + port_off + GPRT_OFF);
+
+       return (gprt >> gpio_nr) & 1U;
+}
+
+void qrio_set_gpio(u8 port_off, u8 gpio_nr, bool value)
+{
+       u32 gprt, mask;
+
+       void __iomem *qrio_base = (void *)CONFIG_SYS_QRIO_BASE;
+
+       mask = 1U << gpio_nr;
+
+       gprt = in_be32(qrio_base + port_off + GPRT_OFF);
+       if (value)
+               gprt |= mask;
+       else
+               gprt &= ~mask;
+
+       out_be32(qrio_base + port_off + GPRT_OFF, gprt);
+}
+
+void qrio_gpio_direction_output(u8 port_off, u8 gpio_nr, bool value)
+{
+       u32 direct, mask;
+
+       void __iomem *qrio_base = (void *)CONFIG_SYS_QRIO_BASE;
+
+       mask = 1U << gpio_nr;
+
+       direct = in_be32(qrio_base + port_off + DIRECT_OFF);
+       direct |= mask;
+       out_be32(qrio_base + port_off + DIRECT_OFF, direct);
+
+       qrio_set_gpio(port_off, gpio_nr, value);
+}
+
+void qrio_gpio_direction_input(u8 port_off, u8 gpio_nr)
+{
+       u32 direct, mask;
+
+       void __iomem *qrio_base = (void *)CONFIG_SYS_QRIO_BASE;
+
+       mask = 1U << gpio_nr;
+
+       direct = in_be32(qrio_base + port_off + DIRECT_OFF);
+       direct &= ~mask;
+       out_be32(qrio_base + port_off + DIRECT_OFF, direct);
+}
+
+void qrio_set_opendrain_gpio(u8 port_off, u8 gpio_nr, u8 val)
+{
+       u32 direct, mask;
+
+       void __iomem *qrio_base = (void *)CONFIG_SYS_QRIO_BASE;
+
+       mask = 1U << gpio_nr;
+
+       direct = in_be32(qrio_base + port_off + DIRECT_OFF);
+       if (val == 0)
+               /* set to output -> GPIO drives low */
+               direct |= mask;
+       else
+               /* set to input -> GPIO floating */
+               direct &= ~mask;
+
+       out_be32(qrio_base + port_off + DIRECT_OFF, direct);
+}
+
+#define WDMASK_OFF     0x16
+
+static void qrio_wdmask(u8 bit, bool wden)
+{
+       u16 wdmask;
+       void __iomem *qrio_base = (void *)CONFIG_SYS_QRIO_BASE;
+
+       wdmask = in_be16(qrio_base + WDMASK_OFF);
+
+       if (wden)
+               wdmask |= (1 << bit);
+       else
+               wdmask &= ~(1 << bit);
+
+       out_be16(qrio_base + WDMASK_OFF, wdmask);
+}
+
+#define PRST_OFF       0x1a
+
+void qrio_prst(u8 bit, bool en, bool wden)
+{
+       u16 prst;
+       void __iomem *qrio_base = (void *)CONFIG_SYS_QRIO_BASE;
+
+       qrio_wdmask(bit, wden);
+
+       prst = in_be16(qrio_base + PRST_OFF);
+
+       if (en)
+               prst &= ~(1 << bit);
+       else
+               prst |= (1 << bit);
+
+       out_be16(qrio_base + PRST_OFF, prst);
+}
+
+#define PRSTCFG_OFF    0x1c
+
+void qrio_prstcfg(u8 bit, u8 mode)
+{
+       u32 prstcfg;
+       u8 i;
+       void __iomem *qrio_base = (void *)CONFIG_SYS_QRIO_BASE;
+
+       prstcfg = in_be32(qrio_base + PRSTCFG_OFF);
+
+       for (i = 0; i < 2; i++) {
+               if (mode & (1<<i))
+                       set_bit(2*bit+i, &prstcfg);
+               else
+                       clear_bit(2*bit+i, &prstcfg);
+       }
+
+       out_be32(qrio_base + PRSTCFG_OFF, prstcfg);
+}