diff options
author | Ruilin Hao <rlhao@marvell.com> | 2015-11-10 00:17:09 -0800 |
---|---|---|
committer | Patrick Georgi <pgeorgi@google.com> | 2016-02-04 11:31:25 +0100 |
commit | c1b9e7934c0b100b8ce558669df8b57a03b2271f (patch) | |
tree | bf26dda0d0df31be652be5e661226c6e71550f19 /src/soc/marvell/armada38x/gpio.c | |
parent | 5b429ac2b26cdd487841ef6c45d03ffe7b048f04 (diff) |
soc/marvell/armada38x: Add gpio driver for armada38x
Port gpio driver from uboot to coreboot
BUG=chrome-os-partner:47462
TEST=None
BRANCH=tot
Change-Id: Ib6cfbb6e44cb642c7af937778076a51d405ff4a2
Signed-off-by: Patrick Georgi <pgeorgi@chromium.org>
Original-Commit-Id: 5cf94502faad96147d4a4adb42eb13edb64a6439
Original-Change-Id: Ia2e081a85347e2fc8bb365ca527ee2ee32af86f1
Original-Signed-off-by: Ruilin Hao <rlhao@marvell.com>
Original-Reviewed-on: https://chromium-review.googlesource.com/313341
Original-Commit-Ready: Kan Yan <kyan@google.com>
Original-Tested-by: Kan Yan <kyan@google.com>
Original-Reviewed-by: Furquan Shaikh <furquan@chromium.org>
Original-Reviewed-by: Kan Yan <kyan@google.com>
Original-Reviewed-by: Yuji Sasaki <sasakiy@chromium.org>
Reviewed-on: https://review.coreboot.org/13112
Tested-by: build bot (Jenkins)
Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
Diffstat (limited to 'src/soc/marvell/armada38x/gpio.c')
-rw-r--r-- | src/soc/marvell/armada38x/gpio.c | 113 |
1 files changed, 113 insertions, 0 deletions
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)); +} |