mirror of
https://github.com/hardkernel/kernel_common_drivers.git
synced 2026-06-25 12:03:48 +09:00
d30cc6178f
PD#SWPL-101847 Problem: drm write registers to rdma table one by one, due to rdma table update and rdma manager flush to real register are out of sync, so we want to creat a fake table, the fake table will copy to rdma table after pipeline register write done, and then config rdma vsync Solution: add rdma table for drm osd registers, and it can dynamic switching by this node /sys/class/drm/card0/crtc0/rdma_table_switch. echo 1 > /sys/class/drm/card0/crtc0/rdma_table_switch switch off echo 0 > /sys/class/drm/card0/crtc0/rdma_table_switch switch on Verify: T3x s7 s5 Test: DRM-OSD-33 Change-Id: I053daa7daaab672f8b1e9fc2c38a2d60552d6288 Signed-off-by: wenlong.zhang <wenlong.zhang@amlogic.com>
165 lines
3.2 KiB
C
165 lines
3.2 KiB
C
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
|
|
/*
|
|
* Copyright (c) 2019 Amlogic, Inc. All rights reserved.
|
|
*/
|
|
|
|
#include <linux/module.h>
|
|
|
|
#include <trace/events/meson_atrace.h>
|
|
#include <linux/device/class.h>
|
|
|
|
static u64 atrace_tag;
|
|
|
|
#define TAG_INFO(name) \
|
|
{ #name, KERNEL_ATRACE_TAG_ ## name }
|
|
|
|
struct {
|
|
char *name;
|
|
int tag;
|
|
} tag_info[] = {
|
|
TAG_INFO(VIDEO),
|
|
TAG_INFO(CODEC_MM),
|
|
TAG_INFO(VDEC),
|
|
TAG_INFO(TSYNC),
|
|
TAG_INFO(IONVIDEO),
|
|
TAG_INFO(AMLVIDEO),
|
|
TAG_INFO(VIDEO_COMPOSER),
|
|
TAG_INFO(V4L2),
|
|
TAG_INFO(CPUFREQ),
|
|
TAG_INFO(MSYNC),
|
|
TAG_INFO(DEMUX),
|
|
TAG_INFO(MEDIA_SYNC),
|
|
TAG_INFO(DDR_BW),
|
|
TAG_INFO(DIM),
|
|
TAG_INFO(DRM),
|
|
{ NULL, 0 }
|
|
};
|
|
|
|
int get_atrace_tag_enabled(unsigned short tag)
|
|
{
|
|
if (tag == KERNEL_ATRACE_TAG_ALL)
|
|
return 1;
|
|
return atrace_tag & (1 << tag);
|
|
}
|
|
EXPORT_SYMBOL(get_atrace_tag_enabled);
|
|
|
|
void set_atrace_tag_enabled(unsigned short tag, int enable)
|
|
{
|
|
if (enable)
|
|
atrace_tag |= (u64)1 << tag;
|
|
else
|
|
atrace_tag &= ~((u64)1 << tag);
|
|
}
|
|
EXPORT_SYMBOL(set_atrace_tag_enabled);
|
|
|
|
static ssize_t show_atrace_tag(struct class *class,
|
|
struct class_attribute *attr, char *buf)
|
|
{
|
|
ssize_t size = 0;
|
|
int i;
|
|
|
|
for (i = 0; i < ARRAY_SIZE(tag_info) && tag_info[i].name; i++) {
|
|
size += sprintf(buf + size, "%2d %s %s\n",
|
|
tag_info[i].tag, tag_info[i].name,
|
|
get_atrace_tag_enabled(tag_info[i].tag) ? "ON" : "OFF");
|
|
}
|
|
|
|
return size;
|
|
}
|
|
|
|
static ssize_t store_atrace_tag(struct class *class,
|
|
struct class_attribute *attr,
|
|
const char *buf, size_t size)
|
|
{
|
|
unsigned int tag;
|
|
ssize_t r;
|
|
|
|
r = kstrtouint(buf, 0, &tag);
|
|
|
|
if (r != 0)
|
|
return -EINVAL;
|
|
if (tag < KERNEL_ATRACE_TAG_MAX)
|
|
set_atrace_tag_enabled(tag, !get_atrace_tag_enabled(tag));
|
|
|
|
return size;
|
|
}
|
|
|
|
static struct class_attribute debug_attrs[] = {
|
|
__ATTR(atrace_tag, 0664, show_atrace_tag, store_atrace_tag),
|
|
__ATTR_NULL
|
|
};
|
|
|
|
static struct attribute *debug_class_attrs[] = {
|
|
&debug_attrs[0].attr,
|
|
NULL
|
|
};
|
|
|
|
ATTRIBUTE_GROUPS(debug_class);
|
|
|
|
static struct class debug_class = {
|
|
.name = "debug",
|
|
.class_groups = debug_class_groups,
|
|
};
|
|
|
|
int meson_atrace_init(void)
|
|
{
|
|
int r;
|
|
|
|
r = class_register(&debug_class);
|
|
|
|
if (r) {
|
|
pr_err("debug class create fail.\n");
|
|
return r;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static char *print_flags_type(unsigned int flags)
|
|
{
|
|
if (flags & 1UL << KERNEL_ATRACE_COUNTER)
|
|
return "C";
|
|
else if (flags & 1UL << KERNEL_ATRACE_BEGIN)
|
|
return "B";
|
|
else if (flags & 1UL << KERNEL_ATRACE_END)
|
|
return "E";
|
|
else if (flags & 1UL << KERNEL_ATRACE_ASYNC_BEGIN)
|
|
return "S";
|
|
else if (flags & 1UL << KERNEL_ATRACE_ASYNC_END)
|
|
return "F";
|
|
|
|
return NULL;
|
|
}
|
|
|
|
static noinline void tracing_mark_write(char *buf)
|
|
{
|
|
__trace_puts(_THIS_IP_, buf, strlen(buf));
|
|
}
|
|
|
|
void meson_atrace(int tag, const char *name, unsigned int flags,
|
|
unsigned long value)
|
|
{
|
|
char buf[256];
|
|
|
|
if (get_atrace_tag_enabled(tag)) {
|
|
snprintf(buf, sizeof(buf), "%s|1|%s|%lu\n",
|
|
print_flags_type(flags), name, value);
|
|
tracing_mark_write(buf);
|
|
}
|
|
}
|
|
EXPORT_SYMBOL(meson_atrace);
|
|
|
|
void __aml_trace_printk(unsigned long ip, const char *fmt, ...)
|
|
{
|
|
int len = 0;
|
|
char buf[1024];
|
|
va_list ap;
|
|
|
|
va_start(ap, fmt);
|
|
len = vscnprintf(buf, sizeof(buf), fmt, ap);
|
|
if (len > 0)
|
|
__trace_puts(ip, buf, strlen(buf));
|
|
va_end(ap);
|
|
}
|
|
EXPORT_SYMBOL(__aml_trace_printk);
|