diff options
-rw-r--r-- | board/keymile/kmp204x/Makefile | 2 | ||||
-rw-r--r-- | board/keymile/kmp204x/kmp204x.c | 56 | ||||
-rw-r--r-- | board/keymile/kmp204x/kmp204x.h | 10 | ||||
-rw-r--r-- | board/keymile/kmp204x/qrio.c | 146 |
4 files changed, 157 insertions, 57 deletions
diff --git a/board/keymile/kmp204x/Makefile b/board/keymile/kmp204x/Makefile index 3e69ee2f15..c57ca08e14 100644 --- a/board/keymile/kmp204x/Makefile +++ b/board/keymile/kmp204x/Makefile @@ -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 diff --git a/board/keymile/kmp204x/kmp204x.c b/board/keymile/kmp204x/kmp204x.c index 20a32642bb..bbb2453155 100644 --- a/board/keymile/kmp204x/kmp204x.c +++ b/board/keymile/kmp204x/kmp204x.c @@ -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 diff --git a/board/keymile/kmp204x/kmp204x.h b/board/keymile/kmp204x/kmp204x.h index b6ba672413..0267596e4e 100644 --- a/board/keymile/kmp204x/kmp204x.h +++ b/board/keymile/kmp204x/kmp204x.h @@ -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 index 0000000000..49f9aa2546 --- /dev/null +++ b/board/keymile/kmp204x/qrio.c @@ -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); +} |