summaryrefslogtreecommitdiff
path: root/chip/lm4/clock.c
diff options
context:
space:
mode:
authorAlec Berg <alecaberg@chromium.org>2013-10-08 16:46:58 -0700
committerchrome-internal-fetch <chrome-internal-fetch@google.com>2013-10-10 23:14:20 +0000
commit27e063ea100086a913ed655b611c88e077de5b00 (patch)
tree701999fd9367e30d008179243a0fc95fc51c5175 /chip/lm4/clock.c
parentf7e69a211ce0121ec06c79f6d82574d3347dec2f (diff)
downloadchrome-ec-27e063ea100086a913ed655b611c88e077de5b00.tar.gz
lm4: Modified clock gating to allow easy expansion to low power.
Created a new function to enable or disable clocks to various peripherals. This new function makes it easy to specify if you want the clock enabled in run mode, sleep mode, and/or deep sleep mode. Added infrastructure to specify which GPIOs should interrupt the EC from deep sleep. BUG=none BRANCH=none TEST=Passes all unit tests. Ran on a peppy and verified that the clock gate control registers in run mode (LM4_RCGC regs) were the same before and after this change. Change-Id: Ia5009ac8c837f61dca52fe86ebdeede2e1a7fe4d Signed-off-by: Alec Berg <alecaberg@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/172454 Reviewed-by: Randall Spangler <rspangler@chromium.org>
Diffstat (limited to 'chip/lm4/clock.c')
-rw-r--r--chip/lm4/clock.c132
1 files changed, 126 insertions, 6 deletions
diff --git a/chip/lm4/clock.c b/chip/lm4/clock.c
index 02f955776e..2d7365f9ab 100644
--- a/chip/lm4/clock.c
+++ b/chip/lm4/clock.c
@@ -128,6 +128,33 @@ void clock_init(void)
disable_pll();
}
+void clock_enable_peripheral(uint32_t offset, uint32_t mask, uint32_t mode)
+{
+ if (mode & CGC_MODE_RUN)
+ *(LM4_SYSTEM_RCGC_BASE + offset) |= mask;
+
+ if (mode & CGC_MODE_SLEEP)
+ *(LM4_SYSTEM_SCGC_BASE + offset) |= mask;
+
+ if (mode & CGC_MODE_DSLEEP)
+ *(LM4_SYSTEM_DCGC_BASE + offset) |= mask;
+
+ /* Wait for clock change to take affect. */
+ clock_wait_cycles(3);
+}
+
+void clock_disable_peripheral(uint32_t offset, uint32_t mask, uint32_t mode)
+{
+ if (mode & CGC_MODE_RUN)
+ *(LM4_SYSTEM_RCGC_BASE + offset) &= ~mask;
+
+ if (mode & CGC_MODE_SLEEP)
+ *(LM4_SYSTEM_SCGC_BASE + offset) &= ~mask;
+
+ if (mode & CGC_MODE_DSLEEP)
+ *(LM4_SYSTEM_DCGC_BASE + offset) &= ~mask;
+}
+
/*****************************************************************************/
/* Console commands */
@@ -218,12 +245,18 @@ static int command_sleep(int argc, char **argv)
/* gate peripheral clocks */
if (level & 1) {
- LM4_SYSTEM_RCGCTIMER = 0;
- LM4_SYSTEM_RCGCGPIO = 0;
- LM4_SYSTEM_RCGCDMA = 0;
- LM4_SYSTEM_RCGCUART = 0;
- LM4_SYSTEM_RCGCLPC = 0;
- LM4_SYSTEM_RCGCWTIMER = 0;
+ clock_disable_peripheral(CGC_OFFSET_TIMER, 0xffffffff,
+ CGC_MODE_ALL);
+ clock_disable_peripheral(CGC_OFFSET_GPIO, 0xffffffff,
+ CGC_MODE_ALL);
+ clock_disable_peripheral(CGC_OFFSET_DMA, 0xffffffff,
+ CGC_MODE_ALL);
+ clock_disable_peripheral(CGC_OFFSET_UART, 0xffffffff,
+ CGC_MODE_ALL);
+ clock_disable_peripheral(CGC_OFFSET_LPC, 0xffffffff,
+ CGC_MODE_ALL);
+ clock_disable_peripheral(CGC_OFFSET_WTIMER, 0xffffffff,
+ CGC_MODE_ALL);
}
/* set deep sleep bit */
if (level >= 4)
@@ -289,3 +322,90 @@ DECLARE_CONSOLE_COMMAND(pll, command_pll,
NULL);
#endif /* CONFIG_CMD_PLL */
+
+#ifdef CONFIG_CMD_CLOCKGATES
+/**
+ * Print all clock gating registers
+ */
+static int command_clock_gating(int argc, char **argv)
+{
+ ccprintf(" Run , Sleep , Deep Sleep\n");
+
+ ccprintf("WD: 0x%08x, ",
+ *(LM4_SYSTEM_RCGC_BASE + CGC_OFFSET_WD));
+ ccprintf("0x%08x, ", *(LM4_SYSTEM_SCGC_BASE + CGC_OFFSET_WD));
+ ccprintf("0x%08x\n", *(LM4_SYSTEM_DCGC_BASE + CGC_OFFSET_WD));
+
+ ccprintf("TIMER: 0x%08x, ",
+ *(LM4_SYSTEM_RCGC_BASE + CGC_OFFSET_TIMER));
+ ccprintf("0x%08x, ", *(LM4_SYSTEM_SCGC_BASE + CGC_OFFSET_TIMER));
+ ccprintf("0x%08x\n", *(LM4_SYSTEM_DCGC_BASE + CGC_OFFSET_TIMER));
+
+ ccprintf("GPIO: 0x%08x, ",
+ *(LM4_SYSTEM_RCGC_BASE + CGC_OFFSET_GPIO));
+ ccprintf("0x%08x, ", *(LM4_SYSTEM_SCGC_BASE + CGC_OFFSET_GPIO));
+ ccprintf("0x%08x\n", *(LM4_SYSTEM_DCGC_BASE + CGC_OFFSET_GPIO));
+
+ ccprintf("DMA: 0x%08x, ",
+ *(LM4_SYSTEM_RCGC_BASE + CGC_OFFSET_DMA));
+ ccprintf("0x%08x, ", *(LM4_SYSTEM_SCGC_BASE + CGC_OFFSET_DMA));
+ ccprintf("0x%08x\n", *(LM4_SYSTEM_DCGC_BASE + CGC_OFFSET_DMA));
+
+ ccprintf("HIB: 0x%08x, ",
+ *(LM4_SYSTEM_RCGC_BASE + CGC_OFFSET_HIB));
+ ccprintf("0x%08x, ", *(LM4_SYSTEM_SCGC_BASE + CGC_OFFSET_HIB));
+ ccprintf("0x%08x\n", *(LM4_SYSTEM_DCGC_BASE + CGC_OFFSET_HIB));
+
+ ccprintf("UART: 0x%08x, ",
+ *(LM4_SYSTEM_RCGC_BASE + CGC_OFFSET_UART));
+ ccprintf("0x%08x, ", *(LM4_SYSTEM_SCGC_BASE + CGC_OFFSET_UART));
+ ccprintf("0x%08x\n", *(LM4_SYSTEM_DCGC_BASE + CGC_OFFSET_UART));
+
+ ccprintf("SSI: 0x%08x, ",
+ *(LM4_SYSTEM_RCGC_BASE + CGC_OFFSET_SSI));
+ ccprintf("0x%08x, ", *(LM4_SYSTEM_SCGC_BASE + CGC_OFFSET_SSI));
+ ccprintf("0x%08x\n", *(LM4_SYSTEM_DCGC_BASE + CGC_OFFSET_SSI));
+
+ ccprintf("I2C: 0x%08x, ",
+ *(LM4_SYSTEM_RCGC_BASE + CGC_OFFSET_I2C));
+ ccprintf("0x%08x, ", *(LM4_SYSTEM_SCGC_BASE + CGC_OFFSET_I2C));
+ ccprintf("0x%08x\n", *(LM4_SYSTEM_DCGC_BASE + CGC_OFFSET_I2C));
+
+ ccprintf("ADC: 0x%08x, ",
+ *(LM4_SYSTEM_RCGC_BASE + CGC_OFFSET_ADC));
+ ccprintf("0x%08x, ", *(LM4_SYSTEM_SCGC_BASE + CGC_OFFSET_ADC));
+ ccprintf("0x%08x\n", *(LM4_SYSTEM_DCGC_BASE + CGC_OFFSET_ADC));
+
+ ccprintf("LPC: 0x%08x, ",
+ *(LM4_SYSTEM_RCGC_BASE + CGC_OFFSET_LPC));
+ ccprintf("0x%08x, ", *(LM4_SYSTEM_SCGC_BASE + CGC_OFFSET_LPC));
+ ccprintf("0x%08x\n", *(LM4_SYSTEM_DCGC_BASE + CGC_OFFSET_LPC));
+
+ ccprintf("PECI: 0x%08x, ",
+ *(LM4_SYSTEM_RCGC_BASE + CGC_OFFSET_PECI));
+ ccprintf("0x%08x, ", *(LM4_SYSTEM_SCGC_BASE + CGC_OFFSET_PECI));
+ ccprintf("0x%08x\n", *(LM4_SYSTEM_DCGC_BASE + CGC_OFFSET_PECI));
+
+ ccprintf("FAN: 0x%08x, ",
+ *(LM4_SYSTEM_RCGC_BASE + CGC_OFFSET_FAN));
+ ccprintf("0x%08x, ", *(LM4_SYSTEM_SCGC_BASE + CGC_OFFSET_FAN));
+ ccprintf("0x%08x\n", *(LM4_SYSTEM_DCGC_BASE + CGC_OFFSET_FAN));
+
+ ccprintf("EEPROM: 0x%08x, ",
+ *(LM4_SYSTEM_RCGC_BASE + CGC_OFFSET_EEPROM));
+ ccprintf("0x%08x, ", *(LM4_SYSTEM_SCGC_BASE + CGC_OFFSET_EEPROM));
+ ccprintf("0x%08x\n", *(LM4_SYSTEM_DCGC_BASE + CGC_OFFSET_EEPROM));
+
+ ccprintf("WTIMER: 0x%08x, ",
+ *(LM4_SYSTEM_RCGC_BASE + CGC_OFFSET_WTIMER));
+ ccprintf("0x%08x, ", *(LM4_SYSTEM_SCGC_BASE + CGC_OFFSET_WTIMER));
+ ccprintf("0x%08x\n", *(LM4_SYSTEM_DCGC_BASE + CGC_OFFSET_WTIMER));
+
+ return EC_SUCCESS;
+}
+DECLARE_CONSOLE_COMMAND(clockgates, command_clock_gating,
+ "",
+ "Get state of the clock gating controls regs",
+ NULL);
+#endif /* CONFIG_CMD_CLOCKGATES */
+