rockchip: support disable/enable specific gpio when suspend/resume
some specific board need to disable/enable specific gpio when suspend/resume, so we add this function, bootloader can pass the specific gpio, and we can handle these gpios in bl31 suspend/resuem function. Change-Id: I373b03ef9202ee4a05a2b9caacdfa01b47ee2177
This commit is contained in:
parent
536c249245
commit
e550c63101
|
@ -63,11 +63,22 @@
|
|||
* alignment fault will occur during accessing its data member.
|
||||
*/
|
||||
|
||||
#define BL31_GPIO_DIR_OUT 0
|
||||
#define BL31_GPIO_DIR_IN 1
|
||||
|
||||
#define BL31_GPIO_LEVEL_LOW 0
|
||||
#define BL31_GPIO_LEVEL_HIGH 1
|
||||
|
||||
#define BL31_GPIO_PULL_NONE 0
|
||||
#define BL31_GPIO_PULL_UP 1
|
||||
#define BL31_GPIO_PULL_DOWN 2
|
||||
|
||||
/* param type */
|
||||
enum {
|
||||
PARAM_NONE = 0,
|
||||
PARAM_RESET,
|
||||
PARAM_POWEROFF,
|
||||
PARAM_SUSPEND_GPIO,
|
||||
};
|
||||
|
||||
struct gpio_info {
|
||||
|
|
|
@ -121,8 +121,9 @@ uintptr_t plat_get_sec_entrypoint(void);
|
|||
|
||||
void platform_cpu_warmboot(void);
|
||||
|
||||
void *plat_get_rockchip_gpio_reset(void);
|
||||
void *plat_get_rockchip_gpio_poweroff(void);
|
||||
struct gpio_info *plat_get_rockchip_gpio_reset(void);
|
||||
struct gpio_info *plat_get_rockchip_gpio_poweroff(void);
|
||||
struct gpio_info *plat_get_rockchip_suspend_gpio(uint32_t *count);
|
||||
void plat_rockchip_gpio_init(void);
|
||||
|
||||
extern const unsigned char rockchip_power_domain_tree_desc[];
|
||||
|
|
|
@ -40,25 +40,32 @@
|
|||
#include <plat_private.h>
|
||||
#include <string.h>
|
||||
|
||||
static struct bl31_plat_param *bl31_params_head;
|
||||
static struct bl31_gpio_param param_reset;
|
||||
static struct bl31_gpio_param param_poweroff;
|
||||
static struct gpio_info param_reset;
|
||||
static struct gpio_info param_poweroff;
|
||||
static struct gpio_info *rst_gpio;
|
||||
static struct gpio_info *poweroff_gpio;
|
||||
static struct gpio_info suspend_gpio[10];
|
||||
uint32_t suspend_gpio_cnt;
|
||||
|
||||
void *plat_get_rockchip_gpio_reset(void)
|
||||
struct gpio_info *plat_get_rockchip_gpio_reset(void)
|
||||
{
|
||||
return rst_gpio;
|
||||
}
|
||||
|
||||
void *plat_get_rockchip_gpio_poweroff(void)
|
||||
struct gpio_info *plat_get_rockchip_gpio_poweroff(void)
|
||||
{
|
||||
return poweroff_gpio;
|
||||
}
|
||||
|
||||
struct gpio_info *plat_get_rockchip_suspend_gpio(uint32_t *count)
|
||||
{
|
||||
*count = suspend_gpio_cnt;
|
||||
|
||||
return &suspend_gpio[0];
|
||||
}
|
||||
|
||||
void params_early_setup(void *plat_param_from_bl2)
|
||||
{
|
||||
struct bl31_plat_param *param;
|
||||
struct bl31_plat_param *bl2_param;
|
||||
struct bl31_gpio_param *gpio_param;
|
||||
|
||||
|
@ -67,25 +74,33 @@ void params_early_setup(void *plat_param_from_bl2)
|
|||
while (bl2_param) {
|
||||
switch (bl2_param->type) {
|
||||
case PARAM_RESET:
|
||||
param = (struct bl31_plat_param *)¶m_reset;
|
||||
memcpy((void *)param, (void *)bl2_param,
|
||||
sizeof(struct bl31_gpio_param));
|
||||
gpio_param = (struct bl31_gpio_param *)param;
|
||||
rst_gpio = &gpio_param->gpio;
|
||||
gpio_param = (struct bl31_gpio_param *)bl2_param;
|
||||
memcpy(¶m_reset, &gpio_param->gpio,
|
||||
sizeof(struct gpio_info));
|
||||
rst_gpio = ¶m_reset;
|
||||
break;
|
||||
case PARAM_POWEROFF:
|
||||
param = (struct bl31_plat_param *)¶m_poweroff;
|
||||
memcpy((void *)param, (void *)bl2_param,
|
||||
sizeof(struct bl31_gpio_param));
|
||||
gpio_param = (struct bl31_gpio_param *)param;
|
||||
poweroff_gpio = &gpio_param->gpio;
|
||||
gpio_param = (struct bl31_gpio_param *)bl2_param;
|
||||
memcpy(¶m_poweroff, &gpio_param->gpio,
|
||||
sizeof(struct gpio_info));
|
||||
poweroff_gpio = ¶m_poweroff;
|
||||
break;
|
||||
case PARAM_SUSPEND_GPIO:
|
||||
if (suspend_gpio_cnt >= ARRAY_SIZE(suspend_gpio)) {
|
||||
ERROR("exceed support suspend gpio number\n");
|
||||
break;
|
||||
}
|
||||
gpio_param = (struct bl31_gpio_param *)bl2_param;
|
||||
memcpy(&suspend_gpio[suspend_gpio_cnt],
|
||||
&gpio_param->gpio,
|
||||
sizeof(struct gpio_info));
|
||||
suspend_gpio_cnt++;
|
||||
break;
|
||||
default:
|
||||
NOTICE("not expected type found\n");
|
||||
return; /* don't continue if unexpected type found */
|
||||
ERROR("not expected type found %ld\n",
|
||||
bl2_param->type);
|
||||
break;
|
||||
}
|
||||
param->next = bl31_params_head;
|
||||
bl31_params_head = param;
|
||||
bl2_param = bl2_param->next;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -874,6 +874,37 @@ static void clr_hw_idle(uint32_t hw_idle)
|
|||
mmio_clrbits_32(PMU_BASE + PMU_BUS_CLR, hw_idle);
|
||||
}
|
||||
|
||||
static void suspend_gpio(void)
|
||||
{
|
||||
struct gpio_info *suspend_gpio;
|
||||
uint32_t count;
|
||||
int i;
|
||||
|
||||
suspend_gpio = plat_get_rockchip_suspend_gpio(&count);
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
gpio_set_value(suspend_gpio[i].index, suspend_gpio[i].polarity);
|
||||
gpio_set_direction(suspend_gpio[i].index, GPIO_DIR_OUT);
|
||||
udelay(1);
|
||||
}
|
||||
}
|
||||
|
||||
static void resume_gpio(void)
|
||||
{
|
||||
struct gpio_info *suspend_gpio;
|
||||
uint32_t count;
|
||||
int i;
|
||||
|
||||
suspend_gpio = plat_get_rockchip_suspend_gpio(&count);
|
||||
|
||||
for (i = count - 1; i >= 0; i--) {
|
||||
gpio_set_value(suspend_gpio[i].index,
|
||||
!suspend_gpio[i].polarity);
|
||||
gpio_set_direction(suspend_gpio[i].index, GPIO_DIR_OUT);
|
||||
udelay(1);
|
||||
}
|
||||
}
|
||||
|
||||
static int sys_pwr_domain_suspend(void)
|
||||
{
|
||||
uint32_t wait_cnt = 0;
|
||||
|
@ -928,6 +959,7 @@ static int sys_pwr_domain_suspend(void)
|
|||
disable_dvfs_plls();
|
||||
disable_pwms();
|
||||
disable_nodvfs_plls();
|
||||
suspend_gpio();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -937,6 +969,8 @@ static int sys_pwr_domain_resume(void)
|
|||
uint32_t wait_cnt = 0;
|
||||
uint32_t status = 0;
|
||||
|
||||
|
||||
resume_gpio();
|
||||
enable_nodvfs_plls();
|
||||
enable_pwms();
|
||||
/* PWM regulators take time to come up; give 300us to be safe. */
|
||||
|
@ -1010,7 +1044,7 @@ void __dead2 soc_soft_reset(void)
|
|||
{
|
||||
struct gpio_info *rst_gpio;
|
||||
|
||||
rst_gpio = (struct gpio_info *)plat_get_rockchip_gpio_reset();
|
||||
rst_gpio = plat_get_rockchip_gpio_reset();
|
||||
|
||||
if (rst_gpio) {
|
||||
gpio_set_direction(rst_gpio->index, GPIO_DIR_OUT);
|
||||
|
@ -1027,7 +1061,7 @@ void __dead2 soc_system_off(void)
|
|||
{
|
||||
struct gpio_info *poweroff_gpio;
|
||||
|
||||
poweroff_gpio = (struct gpio_info *)plat_get_rockchip_gpio_poweroff();
|
||||
poweroff_gpio = plat_get_rockchip_gpio_poweroff();
|
||||
|
||||
if (poweroff_gpio) {
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue