133 lines
2.7 KiB
C
133 lines
2.7 KiB
C
/*
|
|
* Copyright (c) 2007-2017 Allwinnertech Co., Ltd.
|
|
*
|
|
* This software is licensed under the terms of the GNU General Public
|
|
* License version 2, as published by the Free Software Foundation, and
|
|
* may be copied, distributed, and modified under those terms.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
*/
|
|
|
|
#include "pm_i.h"
|
|
|
|
#define CPUX_STATUS_CODE_INDEX (1)
|
|
#define CPUX_IRQ_STATUS_CODE_INDEX (2)
|
|
#define CPUS_STATUS_CODE_INDEX (3)
|
|
static u32 *base;
|
|
static u32 len;
|
|
static u32 mem_status_init_done;
|
|
void mem_status_init(char *name)
|
|
{
|
|
u32 gpr_offset;
|
|
struct device_node *np;
|
|
|
|
pm_get_dev_info(name, 0, &base, &len);
|
|
np = of_find_node_by_type(NULL, name);
|
|
if (NULL == np) {
|
|
printk(KERN_ERR "can not find np for %s. \n", name);
|
|
} else {
|
|
printk(KERN_INFO "np name = %s. \n", np->full_name);
|
|
if (!of_property_read_u32(np, "gpr_offset", &gpr_offset)) {
|
|
if (!of_property_read_u32(np, "gpr_len", &len)) {
|
|
base = (gpr_offset / sizeof(u32) + base);
|
|
printk("base = %p, len = %x.\n", base, len);
|
|
|
|
}
|
|
}
|
|
}
|
|
mem_status_init_done = 1;
|
|
return;
|
|
}
|
|
|
|
void mem_status_init_nommu(void)
|
|
{
|
|
return;
|
|
}
|
|
|
|
void mem_status_clear(void)
|
|
{
|
|
int i = 0;
|
|
|
|
while (i < len) {
|
|
*(volatile int *)((phys_addr_t) (base + i)) = 0x0;
|
|
i++;
|
|
}
|
|
return;
|
|
|
|
}
|
|
|
|
void mem_status_exit(void)
|
|
{
|
|
return;
|
|
}
|
|
|
|
void save_irq_status(volatile __u32 val)
|
|
{
|
|
if (likely(1 == mem_status_init_done)) {
|
|
*(volatile __u32
|
|
*)((phys_addr_t) (base + CPUX_IRQ_STATUS_CODE_INDEX)) = val;
|
|
/* asm volatile ("dsb"); */
|
|
/* asm volatile ("isb"); */
|
|
}
|
|
return;
|
|
}
|
|
|
|
void save_mem_status(volatile __u32 val)
|
|
{
|
|
*(volatile __u32 *)((phys_addr_t) (base + CPUX_STATUS_CODE_INDEX))
|
|
= val;
|
|
/* asm volatile ("dsb");*/
|
|
/* asm volatile ("isb");*/
|
|
return;
|
|
}
|
|
|
|
__u32 get_mem_status(void)
|
|
{
|
|
return *(volatile __u32
|
|
*)((phys_addr_t) (base + CPUX_STATUS_CODE_INDEX));
|
|
}
|
|
|
|
void parse_cpux_status_code(__u32 code)
|
|
{
|
|
printk("%s. \n", pm_errstr(code));
|
|
|
|
}
|
|
|
|
void parse_cpus_status_code(__u32 code)
|
|
{
|
|
|
|
}
|
|
|
|
void parse_status_code(__u32 code, __u32 index)
|
|
{
|
|
switch (index) {
|
|
case CPUX_STATUS_CODE_INDEX:
|
|
parse_cpux_status_code(code);
|
|
break;
|
|
case CPUS_STATUS_CODE_INDEX:
|
|
parse_cpus_status_code(code);
|
|
break;
|
|
default:
|
|
printk(KERN_INFO "notice: para err, index = %x.\n", index);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
void show_mem_status(void)
|
|
{
|
|
int i = 0;
|
|
__u32 status_code = 0;
|
|
|
|
while (i < len) {
|
|
status_code = *(volatile int *)((phys_addr_t) (base + i));
|
|
printk(KERN_INFO "addr %p, value = %x. \n", (base + i),
|
|
status_code);
|
|
parse_status_code(status_code, i);
|
|
i++;
|
|
}
|
|
}
|