mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-12-30 18:41:11 +00:00
Refactor HIBDATA access so we can use multiple hibernate regs
BUG=chrome-os-partner:11368 TEST=none Change-Id: I33ba317ce1cff957add7ebe34860fa4a3c686ca0 Signed-off-by: Randall Spangler <rspangler@chromium.org> Reviewed-on: https://gerrit.chromium.org/gerrit/27380
This commit is contained in:
@@ -120,7 +120,7 @@ static inline int lm4_lpc_addr(int ch, int offset)
|
||||
#define LM4_LPC_ST(ch) LM4LPCREG(ch, 0x004)
|
||||
#define LM4_LPC_ADR(ch) LM4LPCREG(ch, 0x008)
|
||||
#define LM4_LPC_POOL_BYTES 1024 /* Size of LPCPOOL in bytes */
|
||||
#define LM4_LPC_LPCPOOL ((volatile unsigned char*)0x40080400)
|
||||
#define LM4_LPC_LPCPOOL ((volatile unsigned char *)0x40080400)
|
||||
|
||||
#define LM4_FAN_FANSTS LM4REG(0x40084000)
|
||||
#define LM4_FAN_FANCTL LM4REG(0x40084004)
|
||||
@@ -187,7 +187,8 @@ static inline int lm4_fan_addr(int ch, int offset)
|
||||
#define LM4_HIBERNATE_HIBIC LM4REG(0x400fc020)
|
||||
#define LM4_HIBERNATE_HIBRTCT LM4REG(0x400fc024)
|
||||
#define LM4_HIBERNATE_HIBRTCSS LM4REG(0x400fc028)
|
||||
#define LM4_HIBERNATE_HIBDATA LM4REG(0x400fc030)
|
||||
#define LM4_HIBERNATE_HIBDATA_ENTRIES 16 /* Number of entries in HIBDATA[] */
|
||||
#define LM4_HIBERNATE_HIBDATA ((volatile uint32_t *)0x400fc030)
|
||||
|
||||
#define LM4_FLASH_FMA LM4REG(0x400fd000)
|
||||
#define LM4_FLASH_FMD LM4REG(0x400fd004)
|
||||
|
||||
@@ -3,14 +3,18 @@
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
/* System module for Chrome EC : hardware specific implementation */
|
||||
/* System module for Chrome EC : LM4 hardware specific implementation */
|
||||
|
||||
#include "board.h"
|
||||
#include "common.h"
|
||||
#include "cpu.h"
|
||||
#include "registers.h"
|
||||
#include "system.h"
|
||||
#include "task.h"
|
||||
|
||||
/* Indices for hibernate data registers */
|
||||
enum hibdata_index {
|
||||
HIBDATA_INDEX_SCRATCHPAD, /* General-purpose scratchpad */
|
||||
};
|
||||
|
||||
static int wait_for_hibctl_wc(void)
|
||||
{
|
||||
@@ -23,6 +27,42 @@ static int wait_for_hibctl_wc(void)
|
||||
return EC_ERROR_UNKNOWN;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read hibernate register at specified index.
|
||||
*
|
||||
* @return The value of the register or 0 if invalid index.
|
||||
*/
|
||||
static uint32_t hibdata_read(enum hibdata_index index)
|
||||
{
|
||||
if (index < 0 || index >= LM4_HIBERNATE_HIBDATA_ENTRIES)
|
||||
return 0;
|
||||
|
||||
return LM4_HIBERNATE_HIBDATA[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* Write hibernate register at specified index.
|
||||
*
|
||||
* @return nonzero if error.
|
||||
*/
|
||||
static int hibdata_write(enum hibdata_index index, uint32_t value)
|
||||
{
|
||||
int rv;
|
||||
|
||||
if (index < 0 || index >= LM4_HIBERNATE_HIBDATA_ENTRIES)
|
||||
return EC_ERROR_INVAL;
|
||||
|
||||
/* Wait for ok-to-write */
|
||||
rv = wait_for_hibctl_wc();
|
||||
if (rv != EC_SUCCESS)
|
||||
return rv;
|
||||
|
||||
/* Write register */
|
||||
LM4_HIBERNATE_HIBDATA[index] = value;
|
||||
|
||||
/* Wait for write-complete */
|
||||
return wait_for_hibctl_wc();
|
||||
}
|
||||
|
||||
static void check_reset_cause(void)
|
||||
{
|
||||
@@ -65,12 +105,13 @@ static void check_reset_cause(void)
|
||||
system_set_reset_cause(reset_cause);
|
||||
}
|
||||
|
||||
|
||||
/* A3 and earlier chip stepping has a problem accessing flash during shutdown.
|
||||
/*
|
||||
* A3 and earlier chip stepping has a problem accessing flash during shutdown.
|
||||
* To work around that, we jump to RAM before hibernating. This function must
|
||||
* live in RAM. It must be called with interrupts disabled, cannot call other
|
||||
* functions, and can't be declared static (or else the compiler optimizes it
|
||||
* into the main hibernate function. */
|
||||
* into the main hibernate function.
|
||||
*/
|
||||
void __attribute__((section(".iram.text"))) __enter_hibernate(int hibctl)
|
||||
{
|
||||
LM4_HIBERNATE_HIBCTL = hibctl;
|
||||
@@ -78,7 +119,6 @@ void __attribute__((section(".iram.text"))) __enter_hibernate(int hibctl)
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
void system_hibernate(uint32_t seconds, uint32_t microseconds)
|
||||
{
|
||||
/* Clear pending interrupt */
|
||||
@@ -100,7 +140,6 @@ void system_hibernate(uint32_t seconds, uint32_t microseconds)
|
||||
__enter_hibernate(0x5B);
|
||||
}
|
||||
|
||||
|
||||
int system_pre_init(void)
|
||||
{
|
||||
volatile uint32_t scratch __attribute__((unused));
|
||||
@@ -110,8 +149,10 @@ int system_pre_init(void)
|
||||
/* Wait 3 clock cycles before using the module */
|
||||
scratch = LM4_SYSTEM_RCGCHIB;
|
||||
|
||||
/* Enable the hibernation oscillator, if it's not already enabled. We
|
||||
* use this to hold our scratchpad value across reboots. */
|
||||
/*
|
||||
* Enable the hibernation oscillator, if it's not already enabled. We
|
||||
* use this to hold our scratchpad value across reboots.
|
||||
*/
|
||||
if (!(LM4_HIBERNATE_HIBCTL & 0x40)) {
|
||||
int rv, i;
|
||||
rv = wait_for_hibctl_wc();
|
||||
@@ -153,7 +194,6 @@ int system_pre_init(void)
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
void system_reset(int is_hard)
|
||||
{
|
||||
/* Disable interrupts to avoid task swaps during reboot */
|
||||
@@ -172,40 +212,21 @@ void system_reset(int is_hard)
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
int system_set_scratchpad(uint32_t value)
|
||||
{
|
||||
int rv;
|
||||
|
||||
/* Wait for ok-to-write */
|
||||
rv = wait_for_hibctl_wc();
|
||||
if (rv != EC_SUCCESS)
|
||||
return rv;
|
||||
|
||||
/* Write scratchpad */
|
||||
/* TODO: (crosbug.com/p/7472) might be more elegant to have a
|
||||
* write_hibernate_reg() method which takes an address and
|
||||
* data and does the delays. Then we could move the hibernate
|
||||
* register accesses to a separate module. */
|
||||
LM4_HIBERNATE_HIBDATA = value;
|
||||
|
||||
/* Wait for write-complete */
|
||||
return wait_for_hibctl_wc();
|
||||
return hibdata_write(HIBDATA_INDEX_SCRATCHPAD, value);
|
||||
}
|
||||
|
||||
|
||||
uint32_t system_get_scratchpad(void)
|
||||
{
|
||||
return LM4_HIBERNATE_HIBDATA;
|
||||
return hibdata_read(HIBDATA_INDEX_SCRATCHPAD);
|
||||
}
|
||||
|
||||
|
||||
const char *system_get_chip_vendor(void)
|
||||
{
|
||||
return "ti";
|
||||
}
|
||||
|
||||
|
||||
const char *system_get_chip_name(void)
|
||||
{
|
||||
if ((LM4_SYSTEM_DID1 & 0xffff0000) == 0x10e20000) {
|
||||
@@ -223,7 +244,6 @@ const char *system_get_chip_name(void)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const char *system_get_chip_revision(void)
|
||||
{
|
||||
static char rev[3];
|
||||
|
||||
Reference in New Issue
Block a user