static int reset_count;
static int rdma_watchdog_count;
static int rdma_force_reset = -1;
-static u16 trace_reg;
#define RDMA_NUM 8
#define RDMA_TABLE_SIZE (8 * (PAGE_SIZE))
+#define MAX_TRACE_NUM 16
+#define RDMA_MGR_CLASS_NAME "rdma_mgr"
+static int rdma_trace_num;
+static int rdma_trace_enable;
+static u32 rdma_trace_reg[MAX_TRACE_NUM];
struct rdma_regadr_s {
u32 rdma_ahb_start_addr;
struct rdma_device_info {
const char *device_name;
struct platform_device *rdma_dev;
+ struct class *clsp;
struct rdma_instance_s rdma_ins[RDMA_NUM];
};
u32 rdma_read_reg(int handle, u32 adr)
{
- int i;
+ int i, j = 0;
u32 *write_table;
int match = 0;
int read_from = 0;
}
}
}
- if (adr == trace_reg) {
- if (read_from == 2)
- pr_info("(%s) handle %d, %04x=0x%08x from write table(%d)\n",
- __func__,
- handle, adr,
- read_val,
- ins->rdma_write_count);
- else if (read_from == 1)
- pr_info("(%s) handle %d, %04x=0x%08x from item table(%d)\n",
- __func__,
- handle, adr,
- read_val,
- ins->rdma_item_count);
- else
- pr_info("(%s) handle %d, %04x=0x%08x from real reg\n",
- __func__,
- handle, adr,
- read_val);
+ if (rdma_trace_enable) {
+ for (j = 0; j < rdma_trace_num; j++) {
+ if (adr == rdma_trace_reg[j]) {
+ if (read_from == 2)
+ pr_info("(%s) handle %d, %04x=0x%08x from write table(%d)\n",
+ __func__,
+ handle, adr,
+ read_val,
+ ins->rdma_write_count);
+ else if (read_from == 1)
+ pr_info("(%s) handle %d, %04x=0x%08x from item table(%d)\n",
+ __func__,
+ handle, adr,
+ read_val,
+ ins->rdma_item_count);
+ else
+ pr_info("(%s) handle %d, %04x=0x%08x from real reg\n",
+ __func__,
+ handle, adr,
+ read_val);
+ }
+
+ }
}
return read_val;
}
{
struct rdma_device_info *info = &rdma_info;
struct rdma_instance_s *ins = &info->rdma_ins[handle];
+ int j = 0;
if (ins->rdma_table_size == 0)
return -1;
ins->reg_buf[(ins->rdma_item_count << 1) + 1] = val;
ins->rdma_item_count++;
}
- if (adr == trace_reg)
- pr_info("(%s) handle %d, %04x=0x%08x (%d)\n",
- __func__,
- handle, adr,
- val,
- ins->rdma_item_count);
+ if (rdma_trace_enable) {
+ for (j = 0; j < rdma_trace_num; j++) {
+ if (adr == rdma_trace_reg[j]) {
+ pr_info("(%s) handle %d, %04x=0x%08x (%d)\n",
+ __func__,
+ handle, adr,
+ val,
+ ins->rdma_item_count);
+ }
+ }
+ }
return 0;
}
EXPORT_SYMBOL(rdma_write_reg);
int rdma_write_reg_bits(int handle, u32 adr, u32 val, u32 start, u32 len)
{
- int i;
+ int i, j = 0;
u32 *write_table;
int match = 0;
int read_from = 0;
write_val = (read_val & ~(((1L<<(len))-1)<<(start)))
|((unsigned int)(val) << (start));
- if (adr == trace_reg) {
- if (read_from == 2)
- pr_info("(%s) handle %d, %04x=0x%08x->0x%08x from write table(%d)\n",
- __func__,
- handle, adr,
- read_val,
- write_val,
- ins->rdma_write_count);
- else if (read_from == 1)
- pr_info("(%s) handle %d, %04x=0x%08x->0x%08x from item table(%d)\n",
- __func__,
- handle, adr,
- read_val,
- write_val,
- ins->rdma_item_count);
- else
- pr_info("(%s) handle %d, %04x=0x%08x->0x%08x from real reg\n",
- __func__,
- handle, adr,
- read_val,
- write_val);
+ if (rdma_trace_enable) {
+ for (j = 0; j < rdma_trace_num; j++) {
+ if (adr == rdma_trace_reg[j]) {
+ if (read_from == 2)
+ pr_info("(%s) handle %d, %04x=0x%08x->0x%08x from write table(%d)\n",
+ __func__,
+ handle, adr,
+ read_val,
+ write_val,
+ ins->rdma_write_count);
+ else if (read_from == 1)
+ pr_info("(%s) handle %d, %04x=0x%08x->0x%08x from item table(%d)\n",
+ __func__,
+ handle, adr,
+ read_val,
+ write_val,
+ ins->rdma_item_count);
+ else
+ pr_info("(%s) handle %d, %04x=0x%08x->0x%08x from real reg\n",
+ __func__,
+ handle, adr,
+ read_val,
+ write_val);
+ }
+ }
}
if (match) {
ins->reg_buf[(i << 1) + 1] = write_val;
MODULE_PARM_DESC(ctrl_ahb_wr_burst_size, "\n ctrl_ahb_wr_burst_size\n");
module_param(ctrl_ahb_wr_burst_size, uint, 0664);
-MODULE_PARM_DESC(trace_reg, "\n trace_addr\n");
-module_param(trace_reg, ushort, 0664);
-
static struct rdma_device_data_s rdma_meson = {
.cpu_type = CPU_NORMAL,
.rdma_ver = RDMA_VER_1,
{},
};
+static int parse_para(const char *para, int para_num, int *result)
+{
+ char *token = NULL;
+ char *params, *params_base;
+ int *out = result;
+ int len = 0, count = 0;
+ int res = 0;
+ int ret = 0;
+
+ if (!para)
+ return 0;
+
+ params = kstrdup(para, GFP_KERNEL);
+ params_base = params;
+ token = params;
+ if (!token)
+ return 0;
+ len = strlen(token);
+ do {
+ token = strsep(¶ms, " ");
+ while (token && (isspace(*token)
+ || !isgraph(*token)) && len) {
+ token++;
+ len--;
+ }
+ if ((len == 0) || (!token))
+ break;
+ ret = kstrtoint(token, 0, &res);
+ if (ret < 0)
+ break;
+ len = strlen(token);
+ *out++ = res;
+ count++;
+ } while ((token) && (count < para_num) && (len > 0));
+
+ kfree(params_base);
+ return count;
+}
+
+static ssize_t rdma_mgr_trace_enable_show(struct class *cla,
+ struct class_attribute *attr, char *buf)
+{
+ return snprintf(buf, PAGE_SIZE, "%x\n", rdma_trace_enable);
+}
+
+static ssize_t rdma_mgr_trace_enable_stroe(struct class *cla,
+ struct class_attribute *attr,
+ const char *buf, size_t count)
+{
+ int ret = 0;
+
+ ret = kstrtoint(buf, 0, &rdma_trace_enable);
+ if (ret < 0)
+ return -EINVAL;
+ return count;
+}
+
+static ssize_t rdma_mgr_trace_reg_show(struct class *cla,
+ struct class_attribute *attr, char *buf)
+{
+ int i;
+ char reg_info[16];
+ char *trace_info = NULL;
+
+ trace_info = kmalloc(rdma_trace_num * 16 + 1, GFP_KERNEL);
+ if (!trace_info)
+ return 0;
+ for (i = 0; i < rdma_trace_num; i++) {
+ sprintf(reg_info, "0x%x", rdma_trace_reg[i]);
+ strcat(trace_info, reg_info);
+ strcat(trace_info, " ");
+ }
+ i = snprintf(buf, PAGE_SIZE, "%s\n", trace_info);
+ kfree(trace_info);
+ trace_info = NULL;
+ return i;
+}
+
+static ssize_t rdma_mgr_trace_reg_stroe(struct class *cla,
+ struct class_attribute *attr,
+ const char *buf, size_t count)
+{
+ int parsed[MAX_TRACE_NUM];
+ int i = 0, num = 0;
+
+ for (i = 0; i < MAX_TRACE_NUM; i++)
+ rdma_trace_reg[i] = 0;
+ num = parse_para(buf, MAX_TRACE_NUM, parsed);
+ if (num <= MAX_TRACE_NUM) {
+ rdma_trace_num = num;
+ for (i = 0; i < num; i++) {
+ rdma_trace_reg[i] = parsed[i];
+ pr_info("trace reg:0x%x\n", rdma_trace_reg[i]);
+ }
+ }
+ return count;
+}
+
+static struct class_attribute rdma_attrs[] = {
+ __ATTR(trace_enable, 0664,
+ rdma_mgr_trace_enable_show, rdma_mgr_trace_enable_stroe),
+ __ATTR(trace_reg, 0664,
+ rdma_mgr_trace_reg_show, rdma_mgr_trace_reg_stroe),
+
+};
+
u32 is_meson_g12b_revb(void)
{
if (rdma_meson_dev.cpu_type == CPU_G12B &&
/* static int __devinit rdma_probe(struct platform_device *pdev) */
static int rdma_probe(struct platform_device *pdev)
{
- int i;
+ int i, ret = 0;
u32 data32;
int int_rdma;
int handle;
WRITE_VCBUS_REG(VPU_VPUARB2_ASYNC_HOLD_CTRL, 0x18101810);
rdma_mgr_irq_request = 0;
- trace_reg = 0;
for (i = 0; i < RDMA_NUM; i++) {
info->rdma_ins[i].rdma_table_size = 0;
NULL, RDMA_TABLE_SIZE);
set_rdma_handle(LINE_N_INT_RDMA, handle);
}
+ info->clsp = class_create(THIS_MODULE,
+ RDMA_MGR_CLASS_NAME);
+ if (IS_ERR(info->clsp)) {
+ ret = PTR_ERR(info->clsp);
+ pr_err("fail to create class\n");
+ goto fail_create_class;
+ }
+ pr_info("classs created ok\n");
+ for (i = 0; i < ARRAY_SIZE(rdma_attrs); i++) {
+ if (class_create_file
+ (info->clsp,
+ &rdma_attrs[i]) < 0) {
+ pr_err("fail to class_create_file\n");
+ goto fail_class_create_file;
+ }
+ }
+ pr_info("classs file created ok\n");
return 0;
-
+fail_class_create_file:
+ for (i = 0; i < ARRAY_SIZE(rdma_attrs); i++)
+ class_remove_file(
+ info->clsp, &rdma_attrs[i]);
+ class_destroy(info->clsp);
+ info->clsp = NULL;
+ rdma_trace_num = 0;
+ rdma_trace_enable = 0;
+fail_create_class:
+ return ret;
}
/* static int __devexit rdma_remove(struct platform_device *pdev) */
static int rdma_remove(struct platform_device *pdev)
{
+ int i;
+ struct rdma_device_info *info = &rdma_info;
+
pr_error("RDMA driver removed.\n");
switch_vpu_mem_pd_vmod(VPU_RDMA, VPU_MEM_POWER_DOWN);
+ for (i = 0; i < ARRAY_SIZE(rdma_attrs); i++)
+ class_remove_file(
+ info->clsp, &rdma_attrs[i]);
+ class_destroy(info->clsp);
+ info->clsp = NULL;
return 0;
}
#define KEYCOLOR_FLAG_ONHOLD 2
#define KEYCOLOR_FLAG_CURRENT 4
-#define HW_OSD_COUNT 4
+#define HW_OSD_COUNT 4
#define OSD_BLEND_LAYERS 4
-#define VIU_COUNT 2
+#define VIU_COUNT 2
+#define MAX_TRACE_NUM 16
/* OSD block definition */
#define HW_OSD_BLOCK_COUNT 4
u32 afbc_err_cnt;
u32 viu_type;
u32 line_n_rdma;
+ u32 rdma_trace_enable;
+ u32 rdma_trace_num;
+ u32 rdma_trace_reg[MAX_TRACE_NUM];
struct hw_debug_s osd_debug;
int out_fence_fd[VIU_COUNT];
int in_fd[HW_OSD_COUNT];
reg_val = val;
osd_reg_write(reg_addr, reg_val);
}
+ kfree(buf_orig);
+ buf_orig = NULL;
return count;
}
return count;
}
+static ssize_t show_rdma_trace_enable(
+ struct device *device, struct device_attribute *attr,
+ char *buf)
+{
+ return snprintf(buf, PAGE_SIZE, "%x\n", osd_hw.rdma_trace_enable);
+}
+
+static ssize_t store_rdma_trace_enable(
+ struct device *device, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int trace_enable;
+ int ret = 0;
+
+ ret = kstrtoint(buf, 0, &trace_enable);
+ if (ret < 0)
+ return -EINVAL;
+ osd_hw.rdma_trace_enable = trace_enable;
+ return count;
+}
+
+static ssize_t show_rdma_trace_reg(
+ struct device *device, struct device_attribute *attr,
+ char *buf)
+{
+ int i;
+ char reg_info[16];
+ char *trace_info = NULL;
+
+ trace_info = kmalloc(osd_hw.rdma_trace_num * 16 + 1, GFP_KERNEL);
+ if (!trace_info)
+ return 0;
+ for (i = 0; i < osd_hw.rdma_trace_num; i++) {
+ sprintf(reg_info, "0x%x", osd_hw.rdma_trace_reg[i]);
+ strcat(trace_info, reg_info);
+ strcat(trace_info, " ");
+ }
+ i = snprintf(buf, PAGE_SIZE, "%s\n", trace_info);
+ kfree(trace_info);
+ trace_info = NULL;
+ return i;
+}
+
+static ssize_t store_rdma_trace_reg(
+ struct device *device, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int parsed[MAX_TRACE_NUM];
+ int i = 0, num = 0;
+
+ for (i = 0; i < MAX_TRACE_NUM; i++)
+ osd_hw.rdma_trace_reg[i] = 0;
+ num = parse_para(buf, MAX_TRACE_NUM, parsed);
+ if (num <= MAX_TRACE_NUM) {
+ osd_hw.rdma_trace_num = num;
+ for (i = 0; i < num; i++) {
+ osd_hw.rdma_trace_reg[i] = parsed[i];
+ pr_info("trace reg:0x%x\n", osd_hw.rdma_trace_reg[i]);
+ }
+ }
+ return count;
+}
static inline int str2lower(char *str)
{
show_osd_hold_line, store_osd_hold_line),
__ATTR(osd_blend_bypass, 0644,
show_osd_blend_bypass, store_osd_blend_bypass),
+ __ATTR(trace_enable, 0644,
+ show_rdma_trace_enable, store_rdma_trace_enable),
+ __ATTR(trace_reg, 0644,
+ show_rdma_trace_reg, store_rdma_trace_reg),
};
static struct device_attribute osd_attrs_viu2[] = {
unsigned long flags;
u32 old_count;
u32 end_addr;
- int i, j = 0;
+ int i, j = 0, k = 0, trace_num = 0;
struct rdma_table_item reset_item[2] = {
{
.addr = OSD_RDMA_FLAG_REG,
}
};
+ if (osd_hw.rdma_trace_enable)
+ trace_num = osd_hw.rdma_trace_num;
+ else
+ trace_num = 0;
spin_lock_irqsave(&rdma_lock, flags);
if (!OSD_RDMA_STATUS_IS_REJECT) {
u32 val, mask;
osd_rdma_mem_cpy(
&rdma_temp_tbl[j], &request_item, 8);
j++;
- pr_debug(
- "recovery -- 0x%04x:0x%08x, mask:0x%08x\n",
- rdma_table[i].addr,
- val, mask);
+
+ for (k = 0; k < trace_num; k++) {
+ if (osd_hw.rdma_trace_reg[k] & 0x10000)
+ pr_info(
+ "recovery -- 0x%04x:0x%08x, mask:0x%08x\n",
+ rdma_table[i].addr,
+ val, mask);
+ }
rdma_recovery_count++;
} else if ((iret < 0) && (i >= old_count)) {
request_item.addr =
osd_rdma_mem_cpy(
&rdma_temp_tbl[j], &request_item, 8);
j++;
- pr_debug(
- "recovery -- 0x%04x:0x%08x, mask:0x%08x\n",
- rdma_table[i].addr,
- rdma_table[i].val,
- mask);
- pr_debug(
- "recovery -- i:%d, item_count:%d, old_count:%d\n",
- i, item_count, old_count);
+ for (k = 0; k < trace_num; k++) {
+ if (osd_hw.rdma_trace_reg[k] & 0x10000)
+ pr_info(
+ "recovery -- 0x%04x:0x%08x, mask:0x%08x\n",
+ rdma_table[i].addr,
+ rdma_table[i].val,
+ mask);
+ pr_info(
+ "recovery -- i:%d,item_count:%d,old_count:%d\n",
+ i,
+ item_count,
+ old_count);
+ }
rdma_recovery_count++;
}
}
int VSYNCOSD_WR_MPEG_REG(u32 addr, u32 val)
{
- int ret = 0;
- u32 rdma_en = 0;
+ int ret = 0, k = 0;
+ u32 rdma_en = 0, trace_num = 0;
if (!is_rdma_reg(addr))
rdma_en = 0;
ret = update_table_item(addr, val, 0);
else
osd_reg_write(addr, val);
+ if (osd_hw.rdma_trace_enable)
+ trace_num = osd_hw.rdma_trace_num;
+ else
+ trace_num = 0;
+ for (k = 0; k < trace_num; k++) {
+ if (addr == (osd_hw.rdma_trace_reg[k] & 0xffff))
+ pr_info("(%s), %04x=0x%08x, rdma_en=%d, ret=%d\n",
+ __func__,
+ addr, val,
+ rdma_en, ret);
+ }
return ret;
}
EXPORT_SYMBOL(VSYNCOSD_WR_MPEG_REG);
int VSYNCOSD_WR_MPEG_REG_BITS(u32 addr, u32 val, u32 start, u32 len)
{
- unsigned long read_val;
- unsigned long write_val;
- int ret = 0;
- u32 rdma_en = 0;
+ u32 read_val;
+ u32 write_val;
+ int ret = 0, k = 0;
+ u32 rdma_en = 0, trace_num = 0;
if (!is_rdma_reg(addr))
rdma_en = 0;
ret = update_table_item(addr, write_val, 0);
} else
osd_reg_set_bits(addr, val, start, len);
+ if (osd_hw.rdma_trace_enable)
+ trace_num = osd_hw.rdma_trace_num;
+ else
+ trace_num = 0;
+ for (k = 0; k < trace_num; k++) {
+ if (addr == (osd_hw.rdma_trace_reg[k] & 0xffff))
+ pr_info("(%s), %04x=0x%08x, rdma_en=%d, ret=%d\n",
+ __func__,
+ addr, val,
+ rdma_en, ret);
+ }
return ret;
}
EXPORT_SYMBOL(VSYNCOSD_WR_MPEG_REG_BITS);
int VSYNCOSD_SET_MPEG_REG_MASK(u32 addr, u32 _mask)
{
- unsigned long read_val;
- unsigned long write_val;
- int ret = 0;
- u32 rdma_en = 0;
+ u32 read_val = 0;
+ u32 write_val = 0;
+ int ret = 0, k = 0;
+ u32 rdma_en = 0, trace_num = 0;
if (!is_rdma_reg(addr))
rdma_en = 0;
ret = update_table_item(addr, write_val, 0);
} else
osd_reg_set_mask(addr, _mask);
+ if (osd_hw.rdma_trace_enable)
+ trace_num = osd_hw.rdma_trace_num;
+ else
+ trace_num = 0;
+ for (k = 0; k < trace_num; k++) {
+ if (addr == (osd_hw.rdma_trace_reg[k] & 0xffff))
+ pr_info("(%s) %04x=0x%08x->0x%08x, mask=0x%08x, rdma_en=%d, ret=%d\n",
+ __func__,
+ addr, read_val, write_val,
+ _mask, rdma_en, ret);
+ }
return ret;
}
EXPORT_SYMBOL(VSYNCOSD_SET_MPEG_REG_MASK);
int VSYNCOSD_CLR_MPEG_REG_MASK(u32 addr, u32 _mask)
{
- unsigned long read_val;
- unsigned long write_val;
- int ret = 0;
- u32 rdma_en = 0;
+ u32 read_val = 0;
+ u32 write_val = 0;
+ int ret = 0, k = 0;
+ u32 rdma_en = 0, trace_num = 0;
if (!is_rdma_reg(addr))
rdma_en = 0;
ret = update_table_item(addr, write_val, 0);
} else
osd_reg_clr_mask(addr, _mask);
+ if (osd_hw.rdma_trace_enable)
+ trace_num = osd_hw.rdma_trace_num;
+ else
+ trace_num = 0;
+ for (k = 0; k < trace_num; k++) {
+ if (addr == (osd_hw.rdma_trace_reg[k] & 0xffff))
+ pr_info("(%s) %04x=0x%08x->0x%08x, mask=0x%08x, rdma_en=%d, ret=%d\n",
+ __func__,
+ addr, read_val, write_val,
+ _mask, rdma_en, ret);
+ }
return ret;
}
EXPORT_SYMBOL(VSYNCOSD_CLR_MPEG_REG_MASK);
int VSYNCOSD_IRQ_WR_MPEG_REG(u32 addr, u32 val)
{
- int ret = 0;
- u32 rdma_en = 0;
+ int ret = 0, k = 0;
+ u32 rdma_en = 0, trace_num = 0;
if (!is_rdma_reg(addr))
rdma_en = 0;
ret = update_table_item(addr, val, 1);
else
osd_reg_write(addr, val);
+ if (osd_hw.rdma_trace_enable)
+ trace_num = osd_hw.rdma_trace_num;
+ else
+ trace_num = 0;
+ for (k = 0; k < trace_num; k++) {
+ if (addr == (osd_hw.rdma_trace_reg[k] & 0xffff))
+ pr_info("(%s), %04x=0x%08x, rdma_en=%d, ret=%d\n",
+ __func__,
+ addr, val,
+ rdma_en, ret);
+ }
return ret;
}
EXPORT_SYMBOL(VSYNCOSD_IRQ_WR_MPEG_REG);