255 lines
6.8 KiB
C
255 lines
6.8 KiB
C
/*
|
|
* drivers/arisc/arisc.c
|
|
*
|
|
* Copyright (c) 2012 Allwinner.
|
|
* 2012-05-01 Written by sunny (sunny@allwinnertech.com).
|
|
* 2012-10-01 Written by superm (superm@allwinnertech.com).
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* 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 <linux/sunxi-sid.h>
|
|
#include "arisc_i.h"
|
|
|
|
#ifdef CONFIG_PM
|
|
static unsigned int arisc_debug_baudrate = 115200;
|
|
unsigned int arisc_debug_dram_crc_en;
|
|
unsigned int arisc_debug_dram_crc_srcaddr = 0x40000000;
|
|
unsigned int arisc_debug_dram_crc_len = (1024 * 1024);
|
|
unsigned int arisc_debug_dram_crc_error;
|
|
unsigned int arisc_debug_dram_crc_total_count;
|
|
unsigned int arisc_debug_dram_crc_error_count;
|
|
unsigned int arisc_debug_level = 2;
|
|
|
|
static ssize_t debug_mask_show(struct kobject *kobj,
|
|
struct kobj_attribute *attr, char *buf)
|
|
{
|
|
ssize_t size = 0;
|
|
|
|
size = sprintf(buf, "%u\n", arisc_debug_level);
|
|
|
|
return size;
|
|
}
|
|
|
|
static ssize_t debug_mask_store(struct kobject *dev,
|
|
struct kobj_attribute *attr, const char *buf, size_t size)
|
|
{
|
|
u32 value = 0;
|
|
|
|
sscanf(buf, "%u", &value);
|
|
if ((value < 0) || (value > 3)) {
|
|
pr_warn("invalid arisc debug mask [%d] to set\n", value);
|
|
return size;
|
|
}
|
|
|
|
arisc_debug_level = value;
|
|
arisc_set_debug_level(arisc_debug_level);
|
|
pr_info("debug_mask change to %d\n", arisc_debug_level);
|
|
|
|
return size;
|
|
}
|
|
|
|
static ssize_t debug_baudrate_show(struct kobject *kobj,
|
|
struct kobj_attribute *attr, char *buf)
|
|
{
|
|
ssize_t size = 0;
|
|
|
|
size = sprintf(buf, "%u\n", arisc_debug_baudrate);
|
|
|
|
return size;
|
|
}
|
|
|
|
static ssize_t debug_baudrate_store(struct kobject *dev,
|
|
struct kobj_attribute *attr, const char *buf, size_t size)
|
|
{
|
|
u32 value = 0;
|
|
|
|
sscanf(buf, "%u", &value);
|
|
if ((value != 115200) && (value != 57600) && (value != 9600)) {
|
|
pr_warn("invalid arisc uart baudrate [%d] to set\n", value);
|
|
return size;
|
|
}
|
|
|
|
arisc_debug_baudrate = value;
|
|
arisc_set_uart_baudrate(arisc_debug_baudrate);
|
|
pr_info("debug_baudrate change to %d\n", arisc_debug_baudrate);
|
|
|
|
return size;
|
|
}
|
|
static u32 time_to_wakeup_ms;
|
|
|
|
static ssize_t time_to_wakeup_ms_show(struct kobject *kobj,
|
|
struct kobj_attribute *attr, char *buf)
|
|
{
|
|
ssize_t size = 0;
|
|
|
|
size = sprintf(buf, "%u\n", time_to_wakeup_ms);
|
|
|
|
return size;
|
|
}
|
|
|
|
static ssize_t time_to_wakeup_ms_store(struct kobject *dev,
|
|
struct kobj_attribute *attr, const char *buf, size_t size)
|
|
{
|
|
u32 value = 0;
|
|
|
|
sscanf(buf, "%u", &value);
|
|
|
|
time_to_wakeup_ms = value;
|
|
arisc_set_wakeup_source(SET_WAKEUP_TIME_MS(time_to_wakeup_ms));
|
|
pr_info("debug_baudrate change to %d\n", arisc_debug_baudrate);
|
|
|
|
return size;
|
|
}
|
|
|
|
static ssize_t dram_crc_paras_show(struct kobject *kobj,
|
|
struct kobj_attribute *attr, char *buf)
|
|
{
|
|
ssize_t size = 0;
|
|
|
|
size = sprintf(buf, "enable:0x%x srcaddr:0x%x lenght:0x%x\n", arisc_debug_dram_crc_en,
|
|
arisc_debug_dram_crc_srcaddr, arisc_debug_dram_crc_len);
|
|
|
|
return size;
|
|
}
|
|
|
|
static ssize_t dram_crc_paras_store(struct kobject *dev,
|
|
struct kobj_attribute *attr, const char *buf, size_t size)
|
|
{
|
|
u32 dram_crc_en = 0;
|
|
u32 dram_crc_srcaddr = 0;
|
|
u32 dram_crc_len = 0;
|
|
|
|
sscanf(buf, "%x %x %x\n", &dram_crc_en, &dram_crc_srcaddr, &dram_crc_len);
|
|
|
|
if ((dram_crc_en != 0) && (dram_crc_en != 1)) {
|
|
pr_warn("invalid arisc debug dram crc paras [%x] [%x] [%x] to set\n",
|
|
dram_crc_en, dram_crc_srcaddr, dram_crc_len);
|
|
|
|
return size;
|
|
}
|
|
|
|
arisc_debug_dram_crc_en = dram_crc_en;
|
|
arisc_debug_dram_crc_srcaddr = dram_crc_srcaddr;
|
|
arisc_debug_dram_crc_len = dram_crc_len;
|
|
arisc_set_dram_crc_paras(arisc_debug_dram_crc_en,
|
|
arisc_debug_dram_crc_srcaddr,
|
|
arisc_debug_dram_crc_len);
|
|
pr_info("dram_crc_en=0x%x, dram_crc_srcaddr=0x%x, dram_crc_len=0x%x\n",
|
|
arisc_debug_dram_crc_en, arisc_debug_dram_crc_srcaddr, arisc_debug_dram_crc_len);
|
|
|
|
return size;
|
|
}
|
|
|
|
static ssize_t dram_crc_result_show(struct kobject *kobj,
|
|
struct kobj_attribute *attr, char *buf)
|
|
{
|
|
arisc_query_dram_crc_result((unsigned long *)&arisc_debug_dram_crc_error,
|
|
(unsigned long *)&arisc_debug_dram_crc_total_count,
|
|
(unsigned long *)&arisc_debug_dram_crc_error_count);
|
|
return sprintf(buf, "dram info:\n" \
|
|
" enable %u\n" \
|
|
" error %u\n" \
|
|
" total count %u\n" \
|
|
" error count %u\n" \
|
|
" src:%x\n" \
|
|
" len:0x%x\n", \
|
|
arisc_debug_dram_crc_en,
|
|
arisc_debug_dram_crc_error,
|
|
arisc_debug_dram_crc_total_count,
|
|
arisc_debug_dram_crc_error_count,
|
|
arisc_debug_dram_crc_srcaddr,
|
|
arisc_debug_dram_crc_len);
|
|
}
|
|
|
|
static ssize_t dram_crc_result_store(struct kobject *dev,
|
|
struct kobj_attribute *attr, const char *buf, size_t size)
|
|
{
|
|
u32 error = 0;
|
|
u32 total_count = 0;
|
|
u32 error_count = 0;
|
|
|
|
sscanf(buf, "%u %u %u", &error, &total_count, &error_count);
|
|
if ((error != 0) && (error != 1)) {
|
|
pr_warn("invalid arisc dram crc result [%d] [%d] [%d] to set\n",
|
|
error, total_count, error_count);
|
|
return size;
|
|
}
|
|
|
|
arisc_debug_dram_crc_error = error;
|
|
arisc_debug_dram_crc_total_count = total_count;
|
|
arisc_debug_dram_crc_error_count = error_count;
|
|
arisc_set_dram_crc_result((unsigned long)arisc_debug_dram_crc_error,
|
|
(unsigned long)arisc_debug_dram_crc_total_count,
|
|
(unsigned long)arisc_debug_dram_crc_error_count);
|
|
pr_info("debug_dram_crc_result change to error:%u total count:%u error count:%u\n",
|
|
arisc_debug_dram_crc_error,
|
|
arisc_debug_dram_crc_total_count,
|
|
arisc_debug_dram_crc_error_count);
|
|
|
|
return size;
|
|
}
|
|
|
|
#define SUNXI_DEBUG_FILE(_name) \
|
|
static struct kobj_attribute _name##_attr = \
|
|
__ATTR(_name, 0644, _name##_show, _name##_store)
|
|
|
|
SUNXI_DEBUG_FILE(debug_mask);
|
|
SUNXI_DEBUG_FILE(debug_baudrate);
|
|
SUNXI_DEBUG_FILE(time_to_wakeup_ms);
|
|
SUNXI_DEBUG_FILE(dram_crc_paras);
|
|
SUNXI_DEBUG_FILE(dram_crc_result);
|
|
|
|
static struct attribute *sunxi_debug_attrs[] = {
|
|
&debug_mask_attr.attr,
|
|
&debug_baudrate_attr.attr,
|
|
&time_to_wakeup_ms_attr.attr,
|
|
&dram_crc_paras_attr.attr,
|
|
&dram_crc_result_attr.attr,
|
|
NULL
|
|
};
|
|
|
|
static struct attribute_group sunxi_debug_group = {
|
|
.attrs = sunxi_debug_attrs,
|
|
};
|
|
|
|
static int __init arisc_init(void)
|
|
{
|
|
struct kobject *apm_kobj;
|
|
int rc;
|
|
|
|
pr_info("sunxi-pm debug v%s\n", DRV_VERSION);
|
|
|
|
apm_kobj = kobject_create_and_add("sunxi_debug", power_kobj);
|
|
if (!apm_kobj)
|
|
return -ENOMEM;
|
|
|
|
rc = sysfs_create_group(apm_kobj, &sunxi_debug_group);
|
|
if (rc)
|
|
kobject_put(apm_kobj);
|
|
|
|
return rc;
|
|
}
|
|
#else
|
|
static int __init arisc_init(void)
|
|
{
|
|
return 0;
|
|
}
|
|
#endif /* CONFIG_PM */
|
|
|
|
subsys_initcall(arisc_init);
|
|
|
|
MODULE_DESCRIPTION("SUNXI POWER MANAGEMENT");
|
|
MODULE_AUTHOR("Superm Wu <superm@allwinnertech.com>");
|
|
MODULE_LICENSE("GPL");
|
|
MODULE_VERSION(DRV_VERSION);
|