diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/soc/marvell/armada38x/Makefile.inc | 4 | ||||
-rw-r--r-- | src/soc/marvell/armada38x/gpio.c | 113 | ||||
-rw-r--r-- | src/soc/marvell/armada38x/include/soc/gpio.h | 23 |
3 files changed, 140 insertions, 0 deletions
diff --git a/src/soc/marvell/armada38x/Makefile.inc b/src/soc/marvell/armada38x/Makefile.inc index 18f5491d53..bc72d10dc9 100644 --- a/src/soc/marvell/armada38x/Makefile.inc +++ b/src/soc/marvell/armada38x/Makefile.inc @@ -3,6 +3,7 @@ ifeq ($(CONFIG_SOC_MARVELL_ARMADA38X),y) bootblock-y += bootblock.c bootblock-y += bootblock_asm.S bootblock-y += spi.c +bootblock-y += gpio.c bootblock-y += monotonic_timer.c ifeq ($(CONFIG_BOOTBLOCK_CONSOLE),y) bootblock-$(CONFIG_DRIVERS_UART) += uart.c @@ -11,13 +12,16 @@ endif verstage-$(CONFIG_DRIVERS_UART) += uart.c verstage-y += monotonic_timer.c verstage-y += spi.c +verstage-y += gpio.c romstage-y += spi.c +romstage-y += gpio.c romstage-y += cbmem.c romstage-y += monotonic_timer.c romstage-$(CONFIG_DRIVERS_UART) += uart.c ramstage-y += spi.c +ramstage-y += gpio.c ramstage-y += cbmem.c ramstage-y += monotonic_timer.c ramstage-y += soc.c diff --git a/src/soc/marvell/armada38x/gpio.c b/src/soc/marvell/armada38x/gpio.c new file mode 100644 index 0000000000..1c5a4c78c6 --- /dev/null +++ b/src/soc/marvell/armada38x/gpio.c @@ -0,0 +1,113 @@ +/* + * This file is part of the coreboot project. + * + * Copyright 2015 Marvell Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * 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 <arch/io.h> +#include <gpio.h> +#include <soc/common.h> +#include <console/console.h> + +#define MV_GPIO_MAX_NUM 59 + +#define MV_GPP_IN 0xFFFFFFFF /* GPP input */ +#define MV_GPP_OUT 0 /* GPP output */ + +#define MV_GPP_REGS_BASE(unit) (0x18100 + ((unit)*0x40)) +#define GPP_DATA_OUT_EN_REG(grp) (MV_GPP_REGS_BASE(grp) + 0x04) +#define GPP_DATA_IN_REG(grp) (MV_GPP_REGS_BASE(grp) + 0x10) +#define GPP_DATA_OUT_REG(grp) (MV_GPP_REGS_BASE(grp) + 0x00) + +static void gpp_reg_set(u32 group, u32 reg_offs, u32 mask, u32 value); +static int mv_gpp_type_set(u32 group, u32 mask, u32 value); +static u32 mv_gpp_value_get(u32 group, u32 mask); +static int mv_gpp_value_set(u32 group, u32 mask, u32 value); + +void gpp_reg_set(u32 group, u32 reg_offs, u32 mask, u32 value) +{ + u32 gpp_data; + + gpp_data = mrvl_reg_read(reg_offs); + gpp_data &= ~mask; + gpp_data |= (value & mask); + mrvl_reg_write(reg_offs, gpp_data); +} + +int mv_gpp_type_set(u32 group, u32 mask, u32 value) +{ + gpp_reg_set(group, GPP_DATA_OUT_EN_REG(group), mask, value); + return MV_OK; +} + +u32 mv_gpp_value_get(u32 group, u32 mask) +{ + u32 gpp_data; + + gpp_data = mrvl_reg_read(GPP_DATA_IN_REG(group)); + gpp_data &= mask; + return gpp_data; +} + +int mv_gpp_value_set(u32 group, u32 mask, u32 value) +{ + u32 out_enable; + + /* verify that the gpp pin is configured as output*/ + /* Note that in the register out enabled -> bit = '0'.*/ + out_enable = ~(mrvl_reg_read(GPP_DATA_OUT_EN_REG(group))); + if ((out_enable & mask) != mask) { + printk(BIOS_ERR, + "Mask and out_enable mismatch(mask:0x%x, out_enable:0x%x).\n", + mask, (out_enable & mask)); + return MV_ERROR; + } + gpp_reg_set(group, GPP_DATA_OUT_REG(group), mask, value); + return MV_OK; +} + +static inline int gpio_not_valid(gpio_t gpio) +{ + return (gpio > MV_GPIO_MAX_NUM); +} + +int gpio_get(gpio_t gpio) +{ + u32 group = 0; + u32 gpp_data; + + if (gpio_not_valid(gpio)) + return MV_BAD_PARAM; + if (gpio >= 32) { + group = 1; + gpio -= 32; + } + + mv_gpp_type_set(group, (1 << gpio), MV_GPP_IN & (1 << gpio)); + gpp_data = mv_gpp_value_get(group, (1 << gpio)); + return (gpp_data != 0); +} + +void gpio_set(gpio_t gpio, int value) +{ + u32 group = 0; + + if (gpio_not_valid(gpio)) + return; + if (gpio >= 32) { + group = 1; + gpio -= 32; + } + + mv_gpp_type_set(group, (1 << gpio), MV_GPP_OUT & (1 << gpio)); + mv_gpp_value_set(group, (1 << gpio), (value ? (1 << gpio) : 0)); +} diff --git a/src/soc/marvell/armada38x/include/soc/gpio.h b/src/soc/marvell/armada38x/include/soc/gpio.h new file mode 100644 index 0000000000..e3cd7c0602 --- /dev/null +++ b/src/soc/marvell/armada38x/include/soc/gpio.h @@ -0,0 +1,23 @@ +/* + * This file is part of the coreboot project. + * + * Copyright 2015 Google Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * 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. + */ + +#ifndef __SOC_MARVELL_ARMADA38X_GPIO_H_ +#define __SOC_MARVELL_ARMADA38X_GPIO_H_ + +#include <types.h> + +typedef u32 gpio_t; + +#endif // __SOC_MARVELL_ARMADA38X_GPIO_H__ |