297 lines
6.1 KiB
C
Executable File
297 lines
6.1 KiB
C
Executable File
#include "pm_i.h"
|
|
|
|
//for io-measure time
|
|
#define PORT_E_CONFIG (0xf1c20890)
|
|
#define PORT_E_DATA (0xf1c208a0)
|
|
#define PORT_CONFIG PORT_E_CONFIG
|
|
#define PORT_DATA PORT_E_DATA
|
|
|
|
volatile int print_flag = 0;
|
|
|
|
void busy_waiting(void)
|
|
{
|
|
#if 1
|
|
volatile __u32 loop_flag = 1;
|
|
while(1 == loop_flag);
|
|
|
|
#endif
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* notice: when resume, boot0 need to clear the flag,
|
|
* in case the data in dram be destoryed result in the system is re-resume in cycle.
|
|
*/
|
|
void save_mem_flag(void)
|
|
{
|
|
#if 0
|
|
__u32 saved_flag = *(volatile __u32 *)(PERMANENT_REG);
|
|
saved_flag &= 0xfffffffe;
|
|
saved_flag |= 0x00000001;
|
|
*(volatile __u32 *)(PERMANENT_REG) = saved_flag;
|
|
#endif
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* before enter suspend, need to clear mem flag,
|
|
* in case the flag is failed to clear by resume code
|
|
*
|
|
*/
|
|
void clear_mem_flag(void)
|
|
{
|
|
#if 0
|
|
__u32 saved_flag = *(volatile __u32 *)(PERMANENT_REG);
|
|
saved_flag &= 0xfffffffe;
|
|
*(volatile __u32 *)(PERMANENT_REG) = saved_flag;
|
|
#endif
|
|
return ;
|
|
}
|
|
|
|
#if defined(CONFIG_ARCH_SUN8IW6P1) || defined(CONFIG_ARCH_SUN9IW1P1)
|
|
static volatile __r_prcm_pio_pad_hold *status_reg;
|
|
static __r_prcm_pio_pad_hold status_reg_tmp;
|
|
static volatile __r_prcm_pio_pad_hold *status_reg_pa;
|
|
static __r_prcm_pio_pad_hold status_reg_pa_tmp;
|
|
void mem_status_init(void)
|
|
{
|
|
status_reg = (volatile __r_prcm_pio_pad_hold *)(STANDBY_STATUS_REG);
|
|
status_reg_pa = (volatile __r_prcm_pio_pad_hold *)(STANDBY_STATUS_REG_PA);
|
|
|
|
//init spinlock for sync
|
|
hwspinlock_init(1);
|
|
}
|
|
|
|
void mem_status_init_nommu(void)
|
|
{
|
|
status_reg = (volatile __r_prcm_pio_pad_hold *)(STANDBY_STATUS_REG);
|
|
status_reg_pa = (volatile __r_prcm_pio_pad_hold *)(STANDBY_STATUS_REG_PA);
|
|
|
|
//init spinlock for sync
|
|
hwspinlock_init(0);
|
|
}
|
|
|
|
void mem_status_clear(void)
|
|
{
|
|
int i = 1;
|
|
|
|
status_reg_tmp.dwval = (*status_reg).dwval;
|
|
if (!hwspin_lock_timeout(MEM_RTC_REG_HWSPINLOCK, 20000)) {
|
|
while(i < STANDBY_STATUS_REG_NUM){
|
|
status_reg_tmp.bits.reg_sel = i;
|
|
status_reg_tmp.bits.data_wr = 0;
|
|
(*status_reg).dwval = status_reg_tmp.dwval;
|
|
status_reg_tmp.bits.wr_pulse = 0;
|
|
(*status_reg).dwval = status_reg_tmp.dwval;
|
|
status_reg_tmp.bits.wr_pulse = 1;
|
|
(*status_reg).dwval = status_reg_tmp.dwval;
|
|
status_reg_tmp.bits.wr_pulse = 0;
|
|
(*status_reg).dwval = status_reg_tmp.dwval;
|
|
i++;
|
|
}
|
|
hwspin_unlock(MEM_RTC_REG_HWSPINLOCK);
|
|
}
|
|
}
|
|
|
|
void mem_status_exit(void)
|
|
{
|
|
return ;
|
|
}
|
|
|
|
void save_mem_status(volatile __u32 val)
|
|
{
|
|
if (!hwspin_lock_timeout(MEM_RTC_REG_HWSPINLOCK, 20000)) {
|
|
status_reg_tmp.bits.reg_sel = 1;
|
|
status_reg_tmp.bits.data_wr = val;
|
|
(*status_reg).dwval = status_reg_tmp.dwval;
|
|
status_reg_tmp.bits.wr_pulse = 0;
|
|
(*status_reg).dwval = status_reg_tmp.dwval;
|
|
status_reg_tmp.bits.wr_pulse = 1;
|
|
(*status_reg).dwval = status_reg_tmp.dwval;
|
|
status_reg_tmp.bits.wr_pulse = 0;
|
|
(*status_reg).dwval = status_reg_tmp.dwval;
|
|
hwspin_unlock(MEM_RTC_REG_HWSPINLOCK);
|
|
}
|
|
|
|
asm volatile ("dsb");
|
|
asm volatile ("isb");
|
|
return;
|
|
}
|
|
|
|
__u32 get_mem_status(void)
|
|
{
|
|
int val = 0;
|
|
status_reg_tmp.bits.reg_sel = 1;
|
|
|
|
if (!hwspin_lock_timeout(MEM_RTC_REG_HWSPINLOCK, 20000)) {
|
|
(*status_reg).dwval = status_reg_tmp.dwval;
|
|
//read
|
|
status_reg_tmp.dwval = (*status_reg).dwval;
|
|
hwspin_unlock(MEM_RTC_REG_HWSPINLOCK);
|
|
}
|
|
|
|
val = status_reg_tmp.bits.data_rd;
|
|
return (val);
|
|
}
|
|
|
|
void show_mem_status(void)
|
|
{
|
|
int i = 1;
|
|
int val = 0;
|
|
while(i < STANDBY_STATUS_REG_NUM) {
|
|
status_reg_tmp.bits.reg_sel = i;
|
|
|
|
//write
|
|
if (!hwspin_lock_timeout(MEM_RTC_REG_HWSPINLOCK, 20000)) {
|
|
(*status_reg).dwval = status_reg_tmp.dwval;
|
|
//read
|
|
status_reg_tmp.dwval = (*status_reg).dwval;
|
|
hwspin_unlock(MEM_RTC_REG_HWSPINLOCK);
|
|
}
|
|
|
|
val = status_reg_tmp.bits.data_rd;
|
|
printk("addr %x, value = %x. \n", \
|
|
(i), val);
|
|
i++;
|
|
}
|
|
}
|
|
|
|
void save_mem_status_nommu(volatile __u32 val)
|
|
{
|
|
if (!hwspin_lock_timeout_nommu(MEM_RTC_REG_HWSPINLOCK, 20000)) {
|
|
status_reg_pa_tmp.bits.reg_sel = 1;
|
|
status_reg_pa_tmp.bits.data_wr = val;
|
|
(*status_reg_pa).dwval = status_reg_pa_tmp.dwval;
|
|
status_reg_pa_tmp.bits.wr_pulse = 0;
|
|
(*status_reg_pa).dwval = status_reg_pa_tmp.dwval;
|
|
status_reg_pa_tmp.bits.wr_pulse = 1;
|
|
(*status_reg_pa).dwval = status_reg_pa_tmp.dwval;
|
|
status_reg_pa_tmp.bits.wr_pulse = 0;
|
|
(*status_reg_pa).dwval = status_reg_pa_tmp.dwval;
|
|
hwspin_unlock_nommu(MEM_RTC_REG_HWSPINLOCK);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
#elif defined(CONFIG_ARCH_SUN8I)
|
|
void mem_status_init(void)
|
|
{
|
|
return ;
|
|
}
|
|
|
|
void mem_status_init_nommu(void)
|
|
{
|
|
return ;
|
|
}
|
|
|
|
void mem_status_clear(void)
|
|
{
|
|
int i = 0;
|
|
|
|
while(i < STANDBY_STATUS_REG_NUM){
|
|
*(volatile int *)(STANDBY_STATUS_REG + i*4) = 0x0;
|
|
i++;
|
|
}
|
|
return ;
|
|
|
|
}
|
|
|
|
void mem_status_exit(void)
|
|
{
|
|
return ;
|
|
}
|
|
|
|
void save_mem_status(volatile __u32 val)
|
|
{
|
|
*(volatile __u32 *)(STANDBY_STATUS_REG + 0x04) = val;
|
|
asm volatile ("dsb");
|
|
asm volatile ("isb");
|
|
return;
|
|
}
|
|
|
|
__u32 get_mem_status(void)
|
|
{
|
|
return *(volatile __u32 *)(STANDBY_STATUS_REG + 0x04);
|
|
}
|
|
|
|
void show_mem_status(void)
|
|
{
|
|
int i = 0;
|
|
|
|
while(i < STANDBY_STATUS_REG_NUM){
|
|
printk("addr %x, value = %x. \n", \
|
|
(STANDBY_STATUS_REG + i*4), *(volatile int *)(STANDBY_STATUS_REG + i*4));
|
|
i++;
|
|
}
|
|
}
|
|
|
|
void save_mem_status_nommu(volatile __u32 val)
|
|
{
|
|
*(volatile __u32 *)(STANDBY_STATUS_REG_PA + 0x04) = val;
|
|
return;
|
|
}
|
|
|
|
void save_cpux_mem_status_nommu(volatile __u32 val)
|
|
{
|
|
*(volatile __u32 *)(STANDBY_STATUS_REG_PA + 0x00) = val;
|
|
return;
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
/*
|
|
* notice: dependant with perf counter to delay.
|
|
*/
|
|
void io_init(void)
|
|
{
|
|
//config port output
|
|
*(volatile unsigned int *)(PORT_CONFIG) = 0x111111;
|
|
|
|
return;
|
|
}
|
|
|
|
void io_init_high(void)
|
|
{
|
|
__u32 data;
|
|
|
|
//set port to high
|
|
data = *(volatile unsigned int *)(PORT_DATA);
|
|
data |= 0x3f;
|
|
*(volatile unsigned int *)(PORT_DATA) = data;
|
|
|
|
return;
|
|
}
|
|
|
|
void io_init_low(void)
|
|
{
|
|
__u32 data;
|
|
|
|
data = *(volatile unsigned int *)(PORT_DATA);
|
|
//set port to low
|
|
data &= 0xffffffc0;
|
|
*(volatile unsigned int *)(PORT_DATA) = data;
|
|
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* set pa port to high, num range is 0-7;
|
|
*/
|
|
void io_high(int num)
|
|
{
|
|
__u32 data;
|
|
data = *(volatile unsigned int *)(PORT_DATA);
|
|
//pull low 10ms
|
|
data &= (~(1<<num));
|
|
*(volatile unsigned int *)(PORT_DATA) = data;
|
|
delay_us(10000);
|
|
//pull high
|
|
data |= (1<<num);
|
|
*(volatile unsigned int *)(PORT_DATA) = data;
|
|
|
|
return;
|
|
}
|
|
|