mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2026-01-08 16:41:55 +00:00
haswell: fix RCIN_L leakage
It's still unclear why the PL6 pin which is used for RCIN_L does not behave properly when configured as open drain. Work around the misbehavior by configuring the PL6 pin as an input. When it is required to be driven low the pin is reconfigured to an output and subsequently made an input again. This provides the open drain semantics that are required to eliminate leakage. BUG=chrome-os-partner:19811 BUG=chrome-os-partner:20054 BUG=chrome-os-partner:20173 BUG=chrome-os-partner:20175 BRANCH=None TEST=manual 'apreset warm' causes reset as expected. The pin is configured as an input by default without open drain or a pullup resistor: > rw 0x40062400 (GPIODIR) read 0x40062400 = 0x00000000 > rw 0x4006250c (GPIOODR) read 0x4006250c = 0x00000000 > rw 0x40062510 (GPIOPUR) read 0x40062510 = 0x00000000 Change-Id: Ia3ad6fa7fec06be1cbff6854d9341722d8617408 Signed-off-by: Aaron Durbin <adurbin@chromium.org> Reviewed-on: https://gerrit.chromium.org/gerrit/60780 Reviewed-by: Sameer Nanda <snanda@chromium.org>
This commit is contained in:
@@ -98,9 +98,11 @@ const struct gpio_info gpio_list[GPIO_COUNT] = {
|
||||
{"PCH_NMI_L", LM4_GPIO_F, (1<<2), GPIO_OUT_HIGH, NULL},
|
||||
{"PCH_PWRBTN_L", LM4_GPIO_H, (1<<0), GPIO_OUT_HIGH, NULL},
|
||||
{"PCH_PWROK", LM4_GPIO_F, (1<<5), GPIO_OUT_LOW, NULL},
|
||||
/* FIXME: Why is PL6 act like it is inverted. Setting value to
|
||||
* 0 makes the signal high, and setting it to 1 makes the signal low. */
|
||||
{"PCH_RCIN_L", LM4_GPIO_L, (1<<6), GPIO_ODR_LOW, NULL},
|
||||
/* FIXME: Why does PL6 not honor open drain semantics? Setting it to 1
|
||||
* drives the pin low while setting it to 0 drives the pin high. To
|
||||
* work around this PCH_RCIN_L is set to an input. It will only
|
||||
* be set to an output when it needs to be driven to 0. */
|
||||
{"PCH_RCIN_L", LM4_GPIO_L, (1<<6), GPIO_INPUT, NULL},
|
||||
{"PCH_RSMRST_L", LM4_GPIO_F, (1<<1), GPIO_OUT_LOW, NULL},
|
||||
{"PCH_SMI_L", LM4_GPIO_F, (1<<4), GPIO_ODR_HIGH, NULL},
|
||||
{"TOUCHSCREEN_RESET_L", LM4_GPIO_N, (1<<7), GPIO_OUT_LOW, NULL},
|
||||
|
||||
@@ -98,9 +98,11 @@ const struct gpio_info gpio_list[GPIO_COUNT] = {
|
||||
{"PCH_NMI_L", LM4_GPIO_F, (1<<2), GPIO_OUT_HIGH, NULL},
|
||||
{"PCH_PWRBTN_L", LM4_GPIO_H, (1<<0), GPIO_OUT_HIGH, NULL},
|
||||
{"PCH_PWROK", LM4_GPIO_F, (1<<5), GPIO_OUT_LOW, NULL},
|
||||
/* FIXME: Why is PL6 act like it is inverted. Setting value to
|
||||
* 0 makes the signal high, and setting it to 1 makes the signal low. */
|
||||
{"PCH_RCIN_L", LM4_GPIO_L, (1<<6), GPIO_ODR_LOW, NULL},
|
||||
/* FIXME: Why does PL6 not honor open drain semantics? Setting it to 1
|
||||
* drives the pin low while setting it to 0 drives the pin high. To
|
||||
* work around this PCH_RCIN_L is set to an input. It will only
|
||||
* be set to an output when it needs to be driven to 0. */
|
||||
{"PCH_RCIN_L", LM4_GPIO_L, (1<<6), GPIO_INPUT, NULL},
|
||||
{"PCH_RSMRST_L", LM4_GPIO_F, (1<<1), GPIO_OUT_LOW, NULL},
|
||||
{"PCH_SMI_L", LM4_GPIO_F, (1<<4), GPIO_ODR_HIGH, NULL},
|
||||
{"TOUCHSCREEN_RESET_L", LM4_GPIO_N, (1<<7), GPIO_OUT_LOW, NULL},
|
||||
|
||||
@@ -98,9 +98,11 @@ const struct gpio_info gpio_list[GPIO_COUNT] = {
|
||||
{"PCH_NMI_L", LM4_GPIO_F, (1<<2), GPIO_OUT_HIGH, NULL},
|
||||
{"PCH_PWRBTN_L", LM4_GPIO_H, (1<<0), GPIO_OUT_HIGH, NULL},
|
||||
{"PCH_PWROK", LM4_GPIO_F, (1<<5), GPIO_OUT_LOW, NULL},
|
||||
/* FIXME: Why is PL6 act like it is inverted. Setting value to
|
||||
* 0 makes the signal high, and setting it to 1 makes the signal low. */
|
||||
{"PCH_RCIN_L", LM4_GPIO_L, (1<<6), GPIO_ODR_LOW, NULL},
|
||||
/* FIXME: Why does PL6 not honor open drain semantics? Setting it to 1
|
||||
* drives the pin low while setting it to 0 drives the pin high. To
|
||||
* work around this PCH_RCIN_L is set to an input. It will only
|
||||
* be set to an output when it needs to be driven to 0. */
|
||||
{"PCH_RCIN_L", LM4_GPIO_L, (1<<6), GPIO_INPUT, NULL},
|
||||
{"PCH_RSMRST_L", LM4_GPIO_F, (1<<1), GPIO_OUT_LOW, NULL},
|
||||
{"PCH_SMI_L", LM4_GPIO_F, (1<<4), GPIO_ODR_HIGH, NULL},
|
||||
{"TOUCHSCREEN_RESET_L", LM4_GPIO_N, (1<<7), GPIO_OUT_LOW, NULL},
|
||||
|
||||
@@ -239,13 +239,14 @@ void chipset_reset(int cold_reset)
|
||||
|
||||
/*
|
||||
* Pulse must be at least 16 PCI clocks long = 500 ns. The gpio
|
||||
* pin used by the EC is configured as open drain. However,
|
||||
* empirically it was deteremined the polarity of the pin is
|
||||
* inverted. No idea why. Therefore, the driving RCIN# low
|
||||
* needs to be set to level 1. FIXME: why? */
|
||||
gpio_set_level(GPIO_PCH_RCIN_L, 1);
|
||||
* pin used by the EC (PL6) does not behave in the correct
|
||||
* manner when configured as open drain. In order to mimic
|
||||
* open drain, the pin is initially configured as an input.
|
||||
* When it is needed to drive low, the flags are updated which
|
||||
* changes the pin to an output and drives the pin low. */
|
||||
gpio_set_flags(GPIO_PCH_RCIN_L, GPIO_OUT_LOW);
|
||||
udelay(10);
|
||||
gpio_set_level(GPIO_PCH_RCIN_L, 0);
|
||||
gpio_set_flags(GPIO_PCH_RCIN_L, GPIO_INPUT);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user