From f6b68490f1014321f3c482e91f1773e3f78a9d89 Mon Sep 17 00:00:00 2001 From: Scott Worley Date: Wed, 24 Feb 2021 21:56:26 -0500 Subject: mchp: Disable BGPO on pin used in GPIO list Microchip MEC parts have a small number of GPIO pins that default to a mode controlled by VBAT powered logic. When configured for VBAT operation the GPIO control register is bypassed. This change switches any of these pins in the GPIO list back to GPIO control. BRANCH=none BUG=none TEST=Manually check pins are no longer controlled by VBAT logic. Signed-off-by: Scott Worley Change-Id: I2d78365b61616ccce568810aecd81fe882e90200 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2717742 Reviewed-by: Ravin Kumar Reviewed-by: Vijay P Hiremath Reviewed-by: Poornima Tom Reviewed-by: Aseda Aboagye Tested-by: Poornima Tom Commit-Queue: Aseda Aboagye --- chip/mchp/gpio.c | 51 +++++++++++++++++++++++++++++++++++++++++++ chip/mchp/registers-mec152x.h | 1 + chip/mchp/registers-mec1701.h | 1 + chip/mchp/registers.h | 12 ++++++++++ 4 files changed, 65 insertions(+) diff --git a/chip/mchp/gpio.c b/chip/mchp/gpio.c index 32a9e36c79..611ced1019 100644 --- a/chip/mchp/gpio.c +++ b/chip/mchp/gpio.c @@ -44,6 +44,55 @@ static const struct gpio_int_mapping int_map[] = { }; BUILD_ASSERT(ARRAY_SIZE(int_map) == MCHP_GPIO_MAX_PORT); +/* + * These pins default to BGPO functionality. BGPO overrides GPIO Control + * register programming. If the pin is in the GPIO list the user wants to + * use the pin as GPIO and we must disable BGPIO functionality for this pin. + */ +struct bgpo_pin { + uint16_t pin; + uint8_t bgpo_pos; +}; + +static const struct bgpo_pin bgpo_list[] = { + { 0101, 1 }, /* GPIO 0101 */ + { 0102, 2 }, /* GPIO 0102 */ +#if defined(CHIP_FAMILY_MEC152X) + { 0253, 0 }, /* GPIO 0253 */ +#elif defined(CHIP_FAMILY_MEC170X) + { 0172, 3 }, /* GPIO 0172 */ +#endif +}; + +static const uint32_t bgpo_map[] = { +#if defined(CHIP_FAMILY_MEC152X) + 0, 0, (BIT(1) | BIT(2)), 0, 0, BIT(11) +#elif defined(CHIP_FAMILY_MEC170X) + 0, 0, (BIT(1) | BIT(2)), BIT(26), 0, 0 +#else + 0, 0, 0, 0, 0, 0 +#endif +}; +BUILD_ASSERT(ARRAY_SIZE(bgpo_map) == MCHP_GPIO_MAX_PORT); + +/* Check for BGPO capable pins on this port and disable BGPO feature */ +static void disable_bgpo(uint32_t port, uint32_t mask) +{ + int i, n; + uint32_t gpnum; + uint32_t m = bgpo_map[port] & mask; + + while (m) { + i = __builtin_ffs(m) - 1; + gpnum = (port * 32U) + i; + for (n = 0; n < ARRAY_SIZE(bgpo_list); n++) + if (gpnum == bgpo_list[n].pin) + MCHP_WKTIMER_BGPO_POWER &= + ~BIT(bgpo_list[n].bgpo_pos); + m &= ~BIT(i); + } +} + /* * NOTE: GCC __builtin_ffs(val) returns (index + 1) of least significant * 1-bit of val or if val == 0 returns 0 @@ -334,6 +383,8 @@ void gpio_pre_init(void) if (is_warm) flags &= ~(GPIO_LOW | GPIO_HIGH); + disable_bgpo(g->port, g->mask); + gpio_set_flags_by_mask(g->port, g->mask, flags); /* Use as GPIO, not alternate function */ diff --git a/chip/mchp/registers-mec152x.h b/chip/mchp/registers-mec152x.h index cbea8a2d4e..0448632805 100644 --- a/chip/mchp/registers-mec152x.h +++ b/chip/mchp/registers-mec152x.h @@ -181,6 +181,7 @@ #define MCHP_KEYSCAN_BASE 0x40009c00 #define MCHP_VBAT_BASE 0x4000a400 #define MCHP_VBAT_RAM_BASE 0x4000a800 +#define MCHP_WKTIMER_BASE 0x4000ac80 #define MCHP_BBLED_0_BASE 0x4000B800 #define MCHP_INT_BASE 0x4000e000 #define MCHP_EC_BASE 0x4000fc00 diff --git a/chip/mchp/registers-mec1701.h b/chip/mchp/registers-mec1701.h index 4d8ef775df..bbbef6159a 100644 --- a/chip/mchp/registers-mec1701.h +++ b/chip/mchp/registers-mec1701.h @@ -203,6 +203,7 @@ #define MCHP_RPM2PWM1_BASE 0x4000a080 #define MCHP_VBAT_BASE 0x4000a400 #define MCHP_VBAT_RAM_BASE 0x4000a800 +#define MCHP_WKTIMER_BASE 0x4000ac80 #define MCHP_BBLED_0_BASE 0x4000B800 #define MCHP_INT_BASE 0x4000e000 #define MCHP_EC_BASE 0x4000fc00 diff --git a/chip/mchp/registers.h b/chip/mchp/registers.h index 92da981b96..a15dedf61f 100644 --- a/chip/mchp/registers.h +++ b/chip/mchp/registers.h @@ -305,6 +305,18 @@ #define MCHP_HTIMER_CONTROL(x) REG16(MCHP_HTIMER_ADDR(x) + 0x4) #define MCHP_HTIMER_COUNT(x) REG16(MCHP_HTIMER_ADDR(x) + 0x8) +/* Week timer and BGPO control */ +#define MCHP_WKTIMER_CTRL REG32(MCHP_WKTIMER_BASE + 0) +#define MCHP_WKTIMER_ALARM_CNT REG32(MCHP_WKTIMER_BASE + 0x04) +#define MCHP_WKTIMER_COMPARE REG32(MCHP_WKTIMER_BASE + 0x08) +#define MCHP_WKTIMER_CLK_DIV REG32(MCHP_WKTIMER_BASE + 0x0c) +#define MCHP_WKTIMER_SUBSEC_ISEL REG32(MCHP_WKTIMER_BASE + 0x10) +#define MCHP_WKTIMER_SUBWK_CTRL REG32(MCHP_WKTIMER_BASE + 0x14) +#define MCHP_WKTIMER_SUBWK_ALARM REG32(MCHP_WKTIMER_BASE + 0x18) +#define MCHP_WKTIMER_BGPO_DATA REG32(MCHP_WKTIMER_BASE + 0x1c) +#define MCHP_WKTIMER_BGPO_POWER REG32(MCHP_WKTIMER_BASE + 0x20) +#define MCHP_WKTIMER_BGPO_RESET REG32(MCHP_WKTIMER_BASE + 0x24) + /* Quad Master SPI (QMSPI) */ #define MCHP_QMSPI0_MODE REG32(MCHP_QMSPI0_BASE + 0x00) #define MCHP_QMSPI0_MODE_ACT_SRST REG8(MCHP_QMSPI0_BASE + 0x00) -- cgit v1.2.1