author | Ao Xu <ao.xu@amlogic.com> | 2019-08-13 03:17:40 (GMT) |
---|---|---|
committer | Tao Zeng <tao.zeng@amlogic.com> | 2019-08-22 09:18:31 (GMT) |
commit | ecb30a523105c4e17c1e4b7b7f96cabccda9de77 (patch) | |
tree | f29dd9a412bf58871b1e2752a3d812485e404f9b | |
parent | ebe37655606e87817f55d34ed4b8f6e3b215399c (diff) | |
download | common-ecb30a523105c4e17c1e4b7b7f96cabccda9de77.zip common-ecb30a523105c4e17c1e4b7b7f96cabccda9de77.tar.gz common-ecb30a523105c4e17c1e4b7b7f96cabccda9de77.tar.bz2 |
drm: add meson drm debugfs node [1/1]
PD#SWPL-12289
Problem:
drm driver has no debug sysfs file
Solution:
add follow sysfs node
1. dump the osd register
/sys/kernel/debug/dri/%minor%/vpu/reg_dump
2. dump the gem buffer image
/sys/kernel/debug/dri/%minor%/vpu/dump
3. set the gem buffer image store path
/sys/kernel/debug/dri/%minor%/vpu/imgpath
4. set 1 to disable the osd plane
/sys/kernel/debug/dri/%minor%/vpu/blank
Verify:
g12a-u200
Change-Id: I10746d65b09d3b530dc22720b8cee669fa120dde
Signed-off-by: Ao Xu <ao.xu@amlogic.com>
-rw-r--r-- | MAINTAINERS | 5 | ||||
-rw-r--r-- | drivers/amlogic/drm/Makefile | 1 | ||||
-rw-r--r-- | drivers/amlogic/drm/meson_crtc.c | 5 | ||||
-rw-r--r-- | drivers/amlogic/drm/meson_crtc.h | 6 | ||||
-rw-r--r-- | drivers/amlogic/drm/meson_debugfs.c | 294 | ||||
-rw-r--r-- | drivers/amlogic/drm/meson_drv.c | 5 | ||||
-rw-r--r-- | drivers/amlogic/drm/meson_drv.h | 5 | ||||
-rw-r--r-- | drivers/amlogic/drm/meson_plane.c | 5 | ||||
-rw-r--r-- | drivers/amlogic/drm/meson_vpu_pipeline.c | 2 | ||||
-rw-r--r-- | drivers/amlogic/drm/meson_vpu_pipeline.h | 8 | ||||
-rw-r--r-- | drivers/amlogic/drm/meson_vpu_util.c | 46 | ||||
-rw-r--r-- | drivers/amlogic/drm/meson_vpu_util.h | 10 | ||||
-rw-r--r-- | drivers/amlogic/drm/vpu-hw/meson_osd_afbc.c | 69 | ||||
-rw-r--r-- | drivers/amlogic/drm/vpu-hw/meson_osd_scaler.c | 50 | ||||
-rw-r--r-- | drivers/amlogic/drm/vpu-hw/meson_vpu_osd_mif.c | 97 | ||||
-rw-r--r-- | drivers/amlogic/drm/vpu-hw/meson_vpu_osdblend.c | 66 | ||||
-rw-r--r-- | drivers/amlogic/drm/vpu-hw/meson_vpu_postblend.c | 55 |
17 files changed, 679 insertions, 50 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index d688667..14136f0 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -15113,3 +15113,8 @@ F: drivers/amlogic/media/di_local/* AMLOGIC ADD DI_MULTI DRIVER M: Jihong Sui <jihong.sui@amlogic.com> F: drivers/amlogic/media/di_multi/* + +AMLOGIC DRM +M: Ao Xu <ao.xu@amlogic.com> +F: drivers/amlogic/drm/meson_debugfs.c + diff --git a/drivers/amlogic/drm/Makefile b/drivers/amlogic/drm/Makefile index bdbcd79..022ca0b 100644 --- a/drivers/amlogic/drm/Makefile +++ b/drivers/amlogic/drm/Makefile @@ -21,6 +21,7 @@ endif meson-drm-y += meson_drv.o meson_plane.o meson_vpu_pipeline_traverse.o \ meson_crtc.o meson_vpu_pipeline.o meson_vpu_pipeline_private.o \ + meson_debugfs.o meson_vpu_util.o \ meson-drm-y += \ vpu-hw/meson_vpu_osd_mif.o \ diff --git a/drivers/amlogic/drm/meson_crtc.c b/drivers/amlogic/drm/meson_crtc.c index f9a24d6..1021e1a 100644 --- a/drivers/amlogic/drm/meson_crtc.c +++ b/drivers/amlogic/drm/meson_crtc.c @@ -19,6 +19,8 @@ #include "meson_vpu_pipeline.h" #include "osd_drm.h" +#define OSD_DUMP_PATH "/tmp/osd_dump/" + static int meson_crtc_set_mode(struct drm_mode_set *set) { struct am_meson_crtc *amcrtc; @@ -263,8 +265,11 @@ int am_meson_crtc_create(struct am_meson_crtc *amcrtc) #endif amcrtc->pipeline = pipeline; + pipeline->crtc = crtc; + strcpy(amcrtc->osddump_path, OSD_DUMP_PATH); priv->crtc = crtc; priv->crtcs[priv->num_crtcs++] = amcrtc; + return 0; } diff --git a/drivers/amlogic/drm/meson_crtc.h b/drivers/amlogic/drm/meson_crtc.h index c02ff85..d97dd7b 100644 --- a/drivers/amlogic/drm/meson_crtc.h +++ b/drivers/amlogic/drm/meson_crtc.h @@ -53,6 +53,12 @@ struct am_meson_crtc { struct dentry *crtc_debugfs_dir; struct meson_vpu_pipeline *pipeline; + + int dump_enable; + int blank_enable; + int dump_counts; + int dump_index; + char osddump_path[64]; }; #define to_am_meson_crtc(x) container_of(x, \ diff --git a/drivers/amlogic/drm/meson_debugfs.c b/drivers/amlogic/drm/meson_debugfs.c new file mode 100644 index 0000000..dbab11f --- a/dev/null +++ b/drivers/amlogic/drm/meson_debugfs.c @@ -0,0 +1,294 @@ +/* + * drivers/amlogic/drm/meson_debugfs.c + * + * Copyright (C) 2017 Amlogic, Inc. All rights reserved. + * + * 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. + * + */ + +#ifdef CONFIG_DEBUG_FS +#include <linux/debugfs.h> +#include <linux/seq_file.h> +#endif + +#include "meson_drv.h" +#include "meson_crtc.h" +#include "meson_vpu_pipeline.h" + +#ifdef CONFIG_DEBUG_FS + +static int meson_dump_show(struct seq_file *sf, void *data) +{ + struct drm_crtc *crtc = sf->private; + struct am_meson_crtc *amc = to_am_meson_crtc(crtc); + + seq_puts(sf, "echo 1 > dump to enable the osd dump func\n"); + seq_puts(sf, "echo 0 > dump to disable the osd dump func\n"); + seq_printf(sf, "dump_enable: %d\n", amc->dump_enable); + seq_printf(sf, "dump_counts: %d\n", amc->dump_counts); + return 0; +} + +static int meson_dump_open(struct inode *inode, struct file *file) +{ + struct drm_crtc *crtc = inode->i_private; + + return single_open(file, meson_dump_show, crtc); +} + +static ssize_t meson_dump_write(struct file *file, const char __user *ubuf, + size_t len, loff_t *offp) +{ + char buf[8]; + int counts = 0; + struct seq_file *sf = file->private_data; + struct drm_crtc *crtc = sf->private; + struct am_meson_crtc *amc = to_am_meson_crtc(crtc); + + if (len > sizeof(buf) - 1) + return -EINVAL; + + if (copy_from_user(buf, ubuf, len)) + return -EFAULT; + buf[len - 1] = '\0'; + + if (strncmp(buf, "0", 1) == 0) { + amc->dump_enable = 0; + DRM_INFO("disable the osd dump\n"); + } else { + if (kstrtoint(buf, 0, &counts) == 0) { + amc->dump_counts = (counts > 0) ? counts : 0; + amc->dump_enable = (counts > 0) ? 1 : 0; + } + } + + return len; +} + +static const struct file_operations meson_dump_fops = { + .owner = THIS_MODULE, + .open = meson_dump_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .write = meson_dump_write, +}; + +static int meson_regdump_show(struct seq_file *sf, void *data) +{ + int i; + struct meson_vpu_block *mvb; + struct drm_crtc *crtc = sf->private; + struct am_meson_crtc *amc = to_am_meson_crtc(crtc); + struct meson_vpu_pipeline *mvp1 = amc->pipeline; + + for (i = 0; i < mvp1->num_blocks; i++) { + mvb = mvp1->mvbs[i]; + if (!mvb) + continue; + + seq_printf(sf, "*************%s*************\n", mvb->name); + if (mvb->ops && mvb->ops->dump_register) + mvb->ops->dump_register(mvb, sf); + } + return 0; +} + +static int meson_regdump_open(struct inode *inode, struct file *file) +{ + struct drm_crtc *crtc = inode->i_private; + + return single_open(file, meson_regdump_show, crtc); +} + +static const struct file_operations meson_regdump_fops = { + .owner = THIS_MODULE, + .open = meson_regdump_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int meson_imgpath_show(struct seq_file *sf, void *data) +{ + struct drm_crtc *crtc = sf->private; + struct am_meson_crtc *amc = to_am_meson_crtc(crtc); + + seq_puts(sf, "echo /tmp/osd_path > imgpath to store the osd dump path\n"); + seq_printf(sf, "imgpath: %s\n", amc->osddump_path); + return 0; +} + +static int meson_imgpath_open(struct inode *inode, struct file *file) +{ + struct drm_crtc *crtc = inode->i_private; + + return single_open(file, meson_imgpath_show, crtc); +} + +static ssize_t meson_imgpath_write(struct file *file, const char __user *ubuf, + size_t len, loff_t *offp) +{ + struct seq_file *sf = file->private_data; + struct drm_crtc *crtc = sf->private; + struct am_meson_crtc *amc = to_am_meson_crtc(crtc); + + if (len > sizeof(amc->osddump_path) - 1) + return -EINVAL; + + if (copy_from_user(amc->osddump_path, ubuf, len)) + return -EFAULT; + amc->osddump_path[len - 1] = '\0'; + + return len; +} + +static const struct file_operations meson_imgpath_fops = { + .owner = THIS_MODULE, + .open = meson_imgpath_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .write = meson_imgpath_write, +}; + +static int meson_blank_show(struct seq_file *sf, void *data) +{ + struct drm_crtc *crtc = sf->private; + struct am_meson_crtc *amc = to_am_meson_crtc(crtc); + + seq_puts(sf, "echo 1 > blank to blank the osd plane\n"); + seq_puts(sf, "echo 0 > blank to unblank the osd plane\n"); + seq_printf(sf, "blank_enable: %d\n", amc->blank_enable); + return 0; +} + +static int meson_blank_open(struct inode *inode, struct file *file) +{ + struct drm_crtc *crtc = inode->i_private; + + return single_open(file, meson_blank_show, crtc); +} + +static ssize_t meson_blank_write(struct file *file, const char __user *ubuf, + size_t len, loff_t *offp) +{ + char buf[4]; + struct seq_file *sf = file->private_data; + struct drm_crtc *crtc = sf->private; + struct am_meson_crtc *amc = to_am_meson_crtc(crtc); + + + if (len > sizeof(buf) - 1) + return -EINVAL; + + if (copy_from_user(buf, ubuf, len)) + return -EFAULT; + buf[len - 1] = '\0'; + + if (strncmp(buf, "1", 1) == 0) { + amc->blank_enable = 1; + DRM_INFO("enable the osd blank\n"); + } else if (strncmp(buf, "0", 1) == 0) { + amc->blank_enable = 0; + DRM_INFO("disable the osd blank\n"); + } + + return len; +} + +static const struct file_operations meson_blank_fops = { + .owner = THIS_MODULE, + .open = meson_blank_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .write = meson_blank_write, +}; + +int meson_crtc_debugfs_init(struct drm_crtc *crtc, struct dentry *root) +{ + struct dentry *meson_vpu_root; + struct dentry *entry; + + meson_vpu_root = debugfs_create_dir("vpu", root); + + entry = debugfs_create_file("dump", 0644, meson_vpu_root, crtc, + &meson_dump_fops); + if (!entry) { + DRM_ERROR("create dump node error\n"); + debugfs_remove_recursive(meson_vpu_root); + } + + entry = debugfs_create_file("reg_dump", 0400, meson_vpu_root, crtc, + &meson_regdump_fops); + if (!entry) { + DRM_ERROR("create reg_dump node error\n"); + debugfs_remove_recursive(meson_vpu_root); + } + + entry = debugfs_create_file("imgpath", 0644, meson_vpu_root, crtc, + &meson_imgpath_fops); + if (!entry) { + DRM_ERROR("create imgpath node error\n"); + debugfs_remove_recursive(meson_vpu_root); + } + + entry = debugfs_create_file("blank", 0644, meson_vpu_root, crtc, + &meson_blank_fops); + if (!entry) { + DRM_ERROR("create blank node error\n"); + debugfs_remove_recursive(meson_vpu_root); + } + + return 0; +} + +static int mm_show(struct seq_file *sf, void *arg) +{ + struct drm_info_node *node = (struct drm_info_node *) sf->private; + struct drm_device *dev = node->minor->dev; + + return drm_mm_dump_table(sf, + &dev->vma_offset_manager->vm_addr_space_mm); +} + +static struct drm_info_list meson_debugfs_list[] = { + {"mm", mm_show, 0}, +}; + +int meson_debugfs_init(struct drm_minor *minor) +{ + int ret; + struct drm_crtc *crtc; + struct drm_device *dev = minor->dev; + + ret = drm_debugfs_create_files(meson_debugfs_list, + ARRAY_SIZE(meson_debugfs_list), + minor->debugfs_root, minor); + if (ret) { + DRM_ERROR("could not install meson_debugfs_list\n"); + return ret; + } + + drm_for_each_crtc(crtc, dev) { + meson_crtc_debugfs_init(crtc, minor->debugfs_root); + } + return ret; +} + +void meson_debugfs_cleanup(struct drm_minor *minor) +{ + drm_debugfs_remove_files(meson_debugfs_list, + ARRAY_SIZE(meson_debugfs_list), minor); +} +#endif diff --git a/drivers/amlogic/drm/meson_drv.c b/drivers/amlogic/drm/meson_drv.c index eecde0e..be96432 100644 --- a/drivers/amlogic/drm/meson_drv.c +++ b/drivers/amlogic/drm/meson_drv.c @@ -159,7 +159,10 @@ static struct drm_driver meson_driver = { .enable_vblank = am_meson_enable_vblank, .disable_vblank = am_meson_disable_vblank, .get_vblank_counter = drm_vblank_no_hw_counter, - +#ifdef CONFIG_DEBUG_FS + .debugfs_init = meson_debugfs_init, + .debugfs_cleanup = meson_debugfs_cleanup, +#endif #ifdef CONFIG_DRM_MESON_USE_ION /* PRIME Ops */ .prime_handle_to_fd = drm_gem_prime_handle_to_fd, diff --git a/drivers/amlogic/drm/meson_drv.h b/drivers/amlogic/drm/meson_drv.h index 40ca261..331e06f 100644 --- a/drivers/amlogic/drm/meson_drv.h +++ b/drivers/amlogic/drm/meson_drv.h @@ -76,4 +76,9 @@ extern int am_meson_register_crtc_funcs(struct drm_crtc *crtc, const struct meson_crtc_funcs *crtc_funcs); extern void am_meson_unregister_crtc_funcs(struct drm_crtc *crtc); +#ifdef CONFIG_DEBUG_FS +int meson_debugfs_init(struct drm_minor *minor); +void meson_debugfs_cleanup(struct drm_minor *minor); +#endif + #endif /* __AM_MESON_DRV_H */ diff --git a/drivers/amlogic/drm/meson_plane.c b/drivers/amlogic/drm/meson_plane.c index 4e84a69..c7a2d07 100644 --- a/drivers/amlogic/drm/meson_plane.c +++ b/drivers/amlogic/drm/meson_plane.c @@ -207,6 +207,7 @@ static int meson_plane_get_fb_info(struct drm_plane *plane, phyaddr = am_meson_gem_object_get_phyaddr(drv, meson_fb->bufp); if (meson_fb->bufp->bscatter) DRM_ERROR("ERROR:am_meson_plane meet a scatter framebuffer.\n"); + plane_info->fb_size = meson_fb->bufp->base.size; #else if (!fb) { DRM_INFO("fb is NULL!\n"); @@ -250,7 +251,8 @@ static int meson_plane_get_fb_info(struct drm_plane *plane, DRM_DEBUG("phy_addr=0x%x,byte_stride=%d,pixel_format=%d\n", plane_info->phy_addr, plane_info->byte_stride, plane_info->pixel_format); - DRM_DEBUG("plane_index %d.\n", osd_plane->plane_index); + DRM_DEBUG("plane_index %d, size %d.\n", osd_plane->plane_index, + plane_info->fb_size); return 0; } @@ -359,6 +361,7 @@ static void meson_plane_cleanup_fb(struct drm_plane *plane, static void meson_plane_atomic_update(struct drm_plane *plane, struct drm_plane_state *old_state) { + DRM_DEBUG("plane atomic_update.\n"); } diff --git a/drivers/amlogic/drm/meson_vpu_pipeline.c b/drivers/amlogic/drm/meson_vpu_pipeline.c index aef3b8d..d988928 100644 --- a/drivers/amlogic/drm/meson_vpu_pipeline.c +++ b/drivers/amlogic/drm/meson_vpu_pipeline.c @@ -275,6 +275,8 @@ static int populate_vpu_pipeline(struct device_node *vpu_block_node, return -ENOMEM; vpu_blocks[mvb->id] = mvb; } + pipeline->mvbs = vpu_blocks; + pipeline->num_blocks = num_blocks; populate_block_link(); diff --git a/drivers/amlogic/drm/meson_vpu_pipeline.h b/drivers/amlogic/drm/meson_vpu_pipeline.h index 68e7a44..8b26bbd 100644 --- a/drivers/amlogic/drm/meson_vpu_pipeline.h +++ b/drivers/amlogic/drm/meson_vpu_pipeline.h @@ -98,6 +98,8 @@ struct meson_vpu_block_ops { struct meson_vpu_block_state *state); void (*enable)(struct meson_vpu_block *vblk); void (*disable)(struct meson_vpu_block *vblk); + void (*dump_register)(struct meson_vpu_block *vblk, + struct seq_file *seq); void (*init)(struct meson_vpu_block *vblk); }; @@ -166,6 +168,7 @@ struct meson_vpu_osd_layer_info { u32 ratio_x;/*input_w/output_w*/ u32 afbc_inter_format; u32 afbc_en; + u32 fb_size; }; struct meson_vpu_osd { @@ -201,6 +204,7 @@ struct meson_vpu_osd_state { int s_mode; int r_mode; u32 plane_index; + u32 fb_size; }; struct meson_vpu_afbc { @@ -339,6 +343,10 @@ struct meson_vpu_pipeline { u32 num_afbc_osds; u32 num_scalers; u8 osd_version; + + struct drm_crtc *crtc; + struct meson_vpu_block **mvbs; + int num_blocks; }; struct meson_vpu_common_state { diff --git a/drivers/amlogic/drm/meson_vpu_util.c b/drivers/amlogic/drm/meson_vpu_util.c index 652af8f..9ad172c 100644 --- a/drivers/amlogic/drm/meson_vpu_util.c +++ b/drivers/amlogic/drm/meson_vpu_util.c @@ -31,7 +31,7 @@ int meson_drm_rdma_write_reg(u32 addr, u32 val) int meson_drm_rdma_write_reg_bits(u32 addr, u32 val, u32 start, u32 len) { - return VSYNCOSD_WR_MPEG_REG(addr, val, start, len); + return VSYNCOSD_WR_MPEG_REG_BITS(addr, val, start, len); } int meson_drm_rdma_set_reg_mask(u32 addr, u32 mask) @@ -53,31 +53,18 @@ int meson_drm_rdma_irq_write_reg(u32 addr, u32 val) u32 meson_drm_read_reg(u32 addr) { - int ret; u32 val; - ret = aml_reg_read(IO_VAPB_BUS_BASE, addr << 2, &val); + val = aml_read_vcbus(addr); - if (ret) { - pr_err("read vcbus reg %x error %d\n", addr, ret); - return -1; - } return val; } -int meson_drm_write_reg(u32 addr, u32 val) +void meson_drm_write_reg(u32 addr, u32 val) { - int ret; - - ret = aml_reg_write(IO_VAPB_BUS_BASE, addr << 2, val); - - if (ret) { - pr_err("write vcbus reg %x error %d\n", addr, ret); - return -1; - } - return 0; + aml_write_vcbus(addr, val); } - +#if 0 int meson_drm_write_reg_bits(u32 addr, u32 val, u32 start, u32 len) { int ret; @@ -140,13 +127,14 @@ int meson_drm_clr_reg_mask(u32 addr, u32 mask) } return 0; } +#endif /** canvas config **/ void meson_drm_canvas_config(u32 index, unsigned long addr, u32 width, u32 height, u32 wrap, u32 blkmode) { - canvas_config(index, addr, width, height, wrap, blkmode, 0); + canvas_config(index, addr, width, height, wrap, blkmode); } int meson_drm_canvas_pool_alloc_table(const char *owner, u32 *table, int size, @@ -155,23 +143,3 @@ int meson_drm_canvas_pool_alloc_table(const char *owner, u32 *table, int size, return canvas_pool_alloc_canvas_table(owner, table, size, type); } -/** vpu clk and block power domain **/ -unsigned int meson_drm_vpu_get_clk(void) -{ - return get_vpu_clk(); -} - -unsigned int meson_drm_vpu_get_hwblk_clk(unsigned int vmode) -{ - return get_vpu_clk_vmode(vmode); -} - -void meson_drm_vpu_set_hwblk_pd(unsigned int vmode, int flag) -{ - switch_vpu_mem_pd_vmode(vmode, flag); -} - -int meson_drm_vpu_get_hwblk_pd(unsigned int vmode) -{ - return get_vpu_mem_pd_vmode(vmode); -} diff --git a/drivers/amlogic/drm/meson_vpu_util.h b/drivers/amlogic/drm/meson_vpu_util.h index 8c52df5..764bcc3 100644 --- a/drivers/amlogic/drm/meson_vpu_util.h +++ b/drivers/amlogic/drm/meson_vpu_util.h @@ -22,8 +22,8 @@ #include <linux/amlogic/media/canvas/canvas.h> #include <linux/amlogic/media/canvas/canvas_mgr.h> #include <linux/amlogic/media/vpu/vpu.h> +#include <linux/amlogic/iomap.h> #include "osd_rdma.h" -#include "osd.h" /*osd internal channel*/ enum din_channel_e { @@ -46,17 +46,11 @@ int meson_util_rdma_write_reg_bits(u32 addr, u32 val, u32 start, u32 len); int meson_util_rdma_set_reg_mask(u32 addr, u32 mask); int meson_util_rdma_clr_reg_mask(u32 addr, u32 mask); int meson_util_rdma_irq_write_reg(u32 addr, u32 val); +u32 meson_drm_read_reg(u32 addr); void meson_util_canvas_config(u32 index, unsigned long addr, u32 width, u32 height, u32 wrap, u32 blkmode); int meson_util_canvas_pool_alloc_table(const char *owner, u32 *table, int size, enum canvas_map_type_e type); -unsigned int meson_util_vpu_get_clk(void); -unsigned int meson_util_vpu_get_hwblk_clk(unsigned int vmode); -void meson_util_vpu_set_hwblk_pd(unsigned int vmode, int flag); -int meson_util_vpu_get_hwblk_pd(unsigned int vmode); - -extern const struct color_bit_define_s default_color_format_array_1[]; - #endif diff --git a/drivers/amlogic/drm/vpu-hw/meson_osd_afbc.c b/drivers/amlogic/drm/vpu-hw/meson_osd_afbc.c index 5d7537b..af353e5 100644 --- a/drivers/amlogic/drm/vpu-hw/meson_osd_afbc.c +++ b/drivers/amlogic/drm/vpu-hw/meson_osd_afbc.c @@ -328,6 +328,74 @@ static void osd_afbc_set_state(struct meson_vpu_block *vblk, DRM_DEBUG("%s set_state called.\n", afbc->base.name); } +static void osd_afbc_dump_register(struct meson_vpu_block *vblk, + struct seq_file *seq) +{ + int osd_index; + u32 value; + char buff[8]; + struct meson_vpu_afbc *afbc; + struct afbc_osd_reg_s *reg; + + osd_index = vblk->index; + afbc = to_afbc_block(vblk); + reg = afbc->afbc_regs; + + snprintf(buff, 8, "OSD%d", osd_index + 1); + + value = meson_drm_read_reg(reg->vpu_mafbc_header_buf_addr_low_s); + seq_printf(seq, "%s_%-35s\t0x%08X\n", buff, "AFBC_HEADER_BUF_ADDR_LOW:", + value); + + value = meson_drm_read_reg(reg->vpu_mafbc_header_buf_addr_high_s); + seq_printf(seq, "%s_%-35s\t0x%08X\n", buff, + "AFBC_HEADER_BUF_ADDR_HIGH:", value); + + value = meson_drm_read_reg(reg->vpu_mafbc_format_specifier_s); + seq_printf(seq, "%s_%-35s\t0x%08X\n", buff, "AFBC_FORMAT_SPECIFIER:", + value); + + value = meson_drm_read_reg(reg->vpu_mafbc_buffer_width_s); + seq_printf(seq, "%s_%-35s\t0x%08X\n", buff, "AFBC_BUFFER_WIDTH:", + value); + + value = meson_drm_read_reg(reg->vpu_mafbc_buffer_height_s); + seq_printf(seq, "%s_%-35s\t0x%08X\n", buff, "AFBC_BUFFER_HEIGHT:", + value); + + value = meson_drm_read_reg(reg->vpu_mafbc_bounding_box_x_start_s); + seq_printf(seq, "%s_%-35s\t0x%08X\n", buff, + "AFBC_BOUNDINGS_BOX_X_START:", value); + + value = meson_drm_read_reg(reg->vpu_mafbc_bounding_box_x_end_s); + seq_printf(seq, "%s_%-35s\t0x%08X\n", buff, "AFBC_BOUNDINGS_BOX_X_END:", + value); + + value = meson_drm_read_reg(reg->vpu_mafbc_bounding_box_y_start_s); + seq_printf(seq, "%s_%-35s\t0x%08X\n", buff, + "AFBC_BOUNDINGS_BOX_Y_START:", value); + + value = meson_drm_read_reg(reg->vpu_mafbc_bounding_box_y_end_s); + seq_printf(seq, "%s_%-35s\t0x%08X\n", buff, + "AFBC_BOUNDINGS_BOX_Y_END:", value); + + value = meson_drm_read_reg(reg->vpu_mafbc_output_buf_addr_low_s); + seq_printf(seq, "%s_%-35s\t0x%08X\n", buff, + "AFBC_OUTPUT_BUF_ADDR_LOW:", value); + + value = meson_drm_read_reg(reg->vpu_mafbc_output_buf_addr_high_s); + seq_printf(seq, "%s_%-35s\t0x%08X\n", buff, + "AFBC_OUTPUT_BUF_ADDR_HIGH:", value); + + value = meson_drm_read_reg(reg->vpu_mafbc_output_buf_stride_s); + seq_printf(seq, "%s_%-35s\t0x%08X\n", buff, + "AFBC_OUTPUT_BUF_STRIDE:", value); + + value = meson_drm_read_reg(reg->vpu_mafbc_prefetch_cfg_s); + seq_printf(seq, "%s_%-35s\t0x%08X\n", buff, "AFBC_PREFETCH_CFG:", + value); +} + static void osd_afbc_hw_enable(struct meson_vpu_block *vblk) { struct meson_vpu_afbc *afbc = to_afbc_block(vblk); @@ -368,5 +436,6 @@ struct meson_vpu_block_ops afbc_ops = { .update_state = osd_afbc_set_state, .enable = osd_afbc_hw_enable, .disable = osd_afbc_hw_disable, + .dump_register = osd_afbc_dump_register, .init = osd_afbc_hw_init, }; diff --git a/drivers/amlogic/drm/vpu-hw/meson_osd_scaler.c b/drivers/amlogic/drm/vpu-hw/meson_osd_scaler.c index 64eadf8..96c2579 100644 --- a/drivers/amlogic/drm/vpu-hw/meson_osd_scaler.c +++ b/drivers/amlogic/drm/vpu-hw/meson_osd_scaler.c @@ -594,6 +594,55 @@ static void scaler_hw_disable(struct meson_vpu_block *vblk) DRM_DEBUG("%s disable called.\n", scaler->base.name); } +static void scaler_dump_register(struct meson_vpu_block *vblk, + struct seq_file *seq) +{ + int osd_index; + u32 value; + char buff[8]; + struct meson_vpu_scaler *scaler; + struct osd_scaler_reg_s *reg; + + osd_index = vblk->index; + scaler = to_scaler_block(vblk); + reg = scaler->reg; + + snprintf(buff, 8, "OSD%d", osd_index + 1); + + value = meson_drm_read_reg(reg->vpp_osd_vsc_phase_step); + seq_printf(seq, "%s_%-35s\t0x%08X\n", buff, "VSC_PHASE_STEP:", value); + + value = meson_drm_read_reg(reg->vpp_osd_vsc_ini_phase); + seq_printf(seq, "%s_%-35s\t0x%08X\n", buff, "VSC_INIT_PHASE:", value); + + value = meson_drm_read_reg(reg->vpp_osd_vsc_ctrl0); + seq_printf(seq, "%s_%-35s\t0x%08X\n", buff, "VSC_CTRL0:", value); + + value = meson_drm_read_reg(reg->vpp_osd_hsc_phase_step); + seq_printf(seq, "%s_%-35s\t0x%08X\n", buff, "HSC_PHASE_STEP:", value); + + value = meson_drm_read_reg(reg->vpp_osd_hsc_ini_phase); + seq_printf(seq, "%s_%-35s\t0x%08X\n", buff, "HSC_INIT_PHASE:", value); + + value = meson_drm_read_reg(reg->vpp_osd_hsc_ctrl0); + seq_printf(seq, "%s_%-35s\t0x%08X\n", buff, "HSC_CTRL0:", value); + + value = meson_drm_read_reg(reg->vpp_osd_sc_dummy_data); + seq_printf(seq, "%s_%-35s\t0x%08X\n", buff, "SC_DUMMY_DATA:", value); + + value = meson_drm_read_reg(reg->vpp_osd_sc_ctrl0); + seq_printf(seq, "%s_%-35s\t0x%08X\n", buff, "SC_CTRL0:", value); + + value = meson_drm_read_reg(reg->vpp_osd_sci_wh_m1); + seq_printf(seq, "%s_%-35s\t0x%08X\n", buff, "SCI_WH_M1:", value); + + value = meson_drm_read_reg(reg->vpp_osd_sco_h_start_end); + seq_printf(seq, "%s_%-35s\t0x%08X\n", buff, "SCO_H_START_END:", value); + + value = meson_drm_read_reg(reg->vpp_osd_sco_v_start_end); + seq_printf(seq, "%s_%-35s\t0x%08X\n", buff, "SCO_V_START_END:", value); +} + static void scaler_hw_init(struct meson_vpu_block *vblk) { struct meson_vpu_scaler *scaler = to_scaler_block(vblk); @@ -612,5 +661,6 @@ struct meson_vpu_block_ops scaler_ops = { .update_state = scaler_set_state, .enable = scaler_hw_enable, .disable = scaler_hw_disable, + .dump_register = scaler_dump_register, .init = scaler_hw_init, }; diff --git a/drivers/amlogic/drm/vpu-hw/meson_vpu_osd_mif.c b/drivers/amlogic/drm/vpu-hw/meson_vpu_osd_mif.c index ddc9bc2..487dfe0 100644 --- a/drivers/amlogic/drm/vpu-hw/meson_vpu_osd_mif.c +++ b/drivers/amlogic/drm/vpu-hw/meson_vpu_osd_mif.c @@ -15,11 +15,17 @@ * */ +#include <linux/module.h> +#include <linux/init.h> +#include <linux/fs.h> +#include <linux/uaccess.h> + #ifdef CONFIG_AMLOGIC_MEDIA_CANVAS #include <linux/amlogic/media/canvas/canvas.h> #include <linux/amlogic/media/canvas/canvas_mgr.h> #endif #include "meson_vpu_pipeline.h" +#include "meson_crtc.h" #include "meson_vpu_reg.h" #include "meson_vpu_util.h" @@ -347,18 +353,28 @@ static int osd_check_state(struct meson_vpu_block *vblk, mvos->byte_stride = plane_info->byte_stride; mvos->phy_addr = plane_info->phy_addr; mvos->pixel_format = plane_info->pixel_format; + mvos->fb_size = plane_info->fb_size; return 0; } static void osd_set_state(struct meson_vpu_block *vblk, struct meson_vpu_block_state *state) { + struct file *fp; + mm_segment_t fs; + loff_t pos; + char name_buf[64]; + struct drm_crtc *crtc; + struct am_meson_crtc *amc; struct meson_vpu_osd *osd = to_osd_block(vblk); struct meson_vpu_osd_state *mvos = to_osd_state(state); u32 pixel_format, canvas_index, src_h, byte_stride, phy_addr; struct osd_scope_s scope_src = {0, 1919, 0, 1079}; struct osd_mif_reg_s *reg = osd->reg; + crtc = vblk->pipeline->crtc; + amc = to_am_meson_crtc(crtc); + if (!vblk) { DRM_DEBUG("set_state break for NULL.\n"); return; @@ -386,6 +402,31 @@ static void osd_set_state(struct meson_vpu_block *vblk, scope_src.h_start, scope_src.h_end, scope_src.v_start, scope_src.v_end); DRM_DEBUG("%s set_state done.\n", osd->base.name); + + if (amc->dump_enable) { + DRM_DEBUG("start to dump gem buff %d.\n", amc->dump_index); + memset(name_buf, 0, sizeof(name_buf)); + amc->dump_index %= amc->dump_counts; + snprintf(name_buf, sizeof(name_buf), "%s/plane%d.dump.%d", + amc->osddump_path, mvos->plane_index, + amc->dump_index++); + + if (amc->dump_index >= amc->dump_counts) + amc->dump_index = 0; + + fs = get_fs(); + set_fs(KERNEL_DS); + pos = 0; + fp = filp_open(name_buf, O_CREAT | O_RDWR, 0644); + if (IS_ERR(fp)) { + DRM_ERROR("create %s osd_dump fail.\n", name_buf); + } else { + vfs_write(fp, phys_to_virt(phy_addr), + mvos->fb_size, &pos); + filp_close(fp, NULL); + } + set_fs(fs); + } } static void osd_hw_enable(struct meson_vpu_block *vblk) @@ -414,6 +455,61 @@ static void osd_hw_disable(struct meson_vpu_block *vblk) DRM_DEBUG("%s disable done.\n", osd->base.name); } +static void osd_dump_register(struct meson_vpu_block *vblk, + struct seq_file *seq) +{ + int osd_index; + u32 value; + char buff[8]; + struct meson_vpu_osd *osd; + struct osd_mif_reg_s *reg; + + osd_index = vblk->index; + osd = to_osd_block(vblk); + reg = osd->reg; + + snprintf(buff, 8, "OSD%d", osd_index + 1); + + value = meson_drm_read_reg(reg->viu_osd_fifo_ctrl_stat); + seq_printf(seq, "%s_%-35s\t0x%08X\n", buff, "FIFO_CTRL_STAT:", value); + + value = meson_drm_read_reg(reg->viu_osd_ctrl_stat); + seq_printf(seq, "%s_%-35s\t0x%08X\n", buff, "CTRL_STAT:", value); + + value = meson_drm_read_reg(reg->viu_osd_ctrl_stat2); + seq_printf(seq, "%s_%-35s\t0x%08X\n", buff, "CTRL_STAT2:", value); + + value = meson_drm_read_reg(reg->viu_osd_blk0_cfg_w0); + seq_printf(seq, "%s_%-35s\t0x%08X\n", buff, "BLK0_CFG_W0:", value); + + value = meson_drm_read_reg(reg->viu_osd_blk0_cfg_w1); + seq_printf(seq, "%s_%-35s\t0x%08X\n", buff, "BLK0_CFG_W1:", value); + + value = meson_drm_read_reg(reg->viu_osd_blk0_cfg_w2); + seq_printf(seq, "%s_%-35s\t0x%08X\n", buff, "BLK0_CFG_W2:", value); + + value = meson_drm_read_reg(reg->viu_osd_blk0_cfg_w3); + seq_printf(seq, "%s_%-35s\t0x%08X\n", buff, "BLK0_CFG_W3:", value); + + value = meson_drm_read_reg(reg->viu_osd_blk0_cfg_w4); + seq_printf(seq, "%s_%-35s\t0x%08X\n", buff, "BLK0_CFG_W4:", value); + + value = meson_drm_read_reg(reg->viu_osd_blk1_cfg_w4); + seq_printf(seq, "%s_%-35s\t0x%08X\n", buff, "BLK1_CFG_W4:", value); + + value = meson_drm_read_reg(reg->viu_osd_blk2_cfg_w4); + seq_printf(seq, "%s_%-35s\t0x%08X\n", buff, "BLK2_CFG_W4:", value); + + value = meson_drm_read_reg(reg->viu_osd_prot_ctrl); + seq_printf(seq, "%s_%-35s\t0x%08X\n", buff, "PROT_CTRL:", value); + + value = meson_drm_read_reg(reg->viu_osd_mali_unpack_ctrl); + seq_printf(seq, "%s_%-35s\t0x%08X\n", buff, "MALI_UNPACK_CTRL:", value); + + value = meson_drm_read_reg(reg->viu_osd_dimm_ctrl); + seq_printf(seq, "%s_%-35s\t0x%08X\n", buff, "DIMM_CTRL:", value); +} + static void osd_hw_init(struct meson_vpu_block *vblk) { struct meson_vpu_osd *osd = to_osd_block(vblk); @@ -432,5 +528,6 @@ struct meson_vpu_block_ops osd_ops = { .update_state = osd_set_state, .enable = osd_hw_enable, .disable = osd_hw_disable, + .dump_register = osd_dump_register, .init = osd_hw_init, }; diff --git a/drivers/amlogic/drm/vpu-hw/meson_vpu_osdblend.c b/drivers/amlogic/drm/vpu-hw/meson_vpu_osdblend.c index f6aa7e8..5adbc98 100644 --- a/drivers/amlogic/drm/vpu-hw/meson_vpu_osdblend.c +++ b/drivers/amlogic/drm/vpu-hw/meson_vpu_osdblend.c @@ -502,6 +502,71 @@ static void osdblend_hw_disable(struct meson_vpu_block *vblk) DRM_DEBUG("%s disable called.\n", osdblend->base.name); } +static void osdblend_dump_register(struct meson_vpu_block *vblk, + struct seq_file *seq) +{ + u32 value; + struct meson_vpu_osdblend *osdblend; + struct osdblend_reg_s *reg; + + osdblend = to_osdblend_block(vblk); + reg = osdblend->reg; + + value = meson_drm_read_reg(reg->viu_osd_blend_ctrl); + seq_printf(seq, "%-35s\t\t0x%08X\n", "VIU_OSD_BLEND_CTRL:", value); + + value = meson_drm_read_reg(reg->viu_osd_blend_din0_scope_h); + seq_printf(seq, "%-35s\t\t0x%08X\n", "VIU_OSD_BLEND_DIN0_SCOPE_H:", + value); + + value = meson_drm_read_reg(reg->viu_osd_blend_din0_scope_v); + seq_printf(seq, "%-35s\t\t0x%08X\n", "VIU_OSD_BLEND_DIN0_SCOPE_V:", + value); + + value = meson_drm_read_reg(reg->viu_osd_blend_din1_scope_h); + seq_printf(seq, "%-35s\t\t0x%08X\n", "VIU_OSD_BLEND_DIN1_SCOPE_H:", + value); + + value = meson_drm_read_reg(reg->viu_osd_blend_din1_scope_v); + seq_printf(seq, "%-35s\t\t0x%08X\n", "VIU_OSD_BLEND_DIN1_SCOPE_V:", + value); + + value = meson_drm_read_reg(reg->viu_osd_blend_din2_scope_h); + seq_printf(seq, "%-35s\t\t0x%08X\n", "VIU_OSD_BLEND_DIN2_SCOPE_H:", + value); + + value = meson_drm_read_reg(reg->viu_osd_blend_din2_scope_v); + seq_printf(seq, "%-35s\t\t0x%08X\n", "VIU_OSD_BLEND_DIN2_SCOPE_V:", + value); + + value = meson_drm_read_reg(reg->viu_osd_blend_din3_scope_h); + seq_printf(seq, "%-35s\t\t0x%08X\n", "VIU_OSD_BLEND_DIN3_SCOPE_H:", + value); + + value = meson_drm_read_reg(reg->viu_osd_blend_din3_scope_v); + seq_printf(seq, "%-35s\t\t0x%08X\n", "VIU_OSD_BLEND_DIN3_SCOPE_V:", + value); + + value = meson_drm_read_reg(reg->viu_osd_blend_dummy_data0); + seq_printf(seq, "%-35s\t\t0x%08X\n", "VIU_OSD_BLEND_DUMMY_DATA0:", + value); + + value = meson_drm_read_reg(reg->viu_osd_blend_dummy_alpha); + seq_printf(seq, "%-35s\t\t0x%08X\n", "VIU_OSD_BLEND_DUMMY_ALPHA:", + value); + + value = meson_drm_read_reg(reg->viu_osd_blend0_size); + seq_printf(seq, "%-35s\t\t0x%08X\n", "VIU_OSD_BLEND_BLEND0_SIZE:", + value); + + value = meson_drm_read_reg(reg->viu_osd_blend1_size); + seq_printf(seq, "%-35s\t\t0x%08X\n", "VIU_OSD_BLEND_BLEND1_SIZE:", + value); + + value = meson_drm_read_reg(reg->viu_osd_blend_ctrl1); + seq_printf(seq, "%-35s\t\t0x%08X\n", "VIU_OSD_BLEND_CTRL1:", value); +} + static void osdblend_hw_init(struct meson_vpu_block *vblk) { struct meson_vpu_osdblend *osdblend = to_osdblend_block(vblk); @@ -515,6 +580,7 @@ struct meson_vpu_block_ops osdblend_ops = { .update_state = osdblend_set_state, .enable = osdblend_hw_enable, .disable = osdblend_hw_disable, + .dump_register = osdblend_dump_register, .init = osdblend_hw_init, }; diff --git a/drivers/amlogic/drm/vpu-hw/meson_vpu_postblend.c b/drivers/amlogic/drm/vpu-hw/meson_vpu_postblend.c index 71ea0aa..14511e4 100644 --- a/drivers/amlogic/drm/vpu-hw/meson_vpu_postblend.c +++ b/drivers/amlogic/drm/vpu-hw/meson_vpu_postblend.c @@ -18,6 +18,7 @@ /* Amlogic Headers */ #include <linux/amlogic/media/vout/vout_notify.h> +#include "meson_crtc.h" #include "meson_vpu_pipeline.h" #include "meson_vpu_util.h" #include "meson_vpu_postblend.h" @@ -31,6 +32,7 @@ static struct postblend_reg_s postblend_reg = { VD2_BLEND_SRC_CTRL, OSD1_BLEND_SRC_CTRL, OSD2_BLEND_SRC_CTRL, + VPP_OSD1_IN_SIZE, }; /*vpp post&post blend for osd1 premult flag config as 0 default*/ @@ -124,11 +126,17 @@ static int postblend_check_state(struct meson_vpu_block *vblk, static void postblend_set_state(struct meson_vpu_block *vblk, struct meson_vpu_block_state *state) { + struct drm_crtc *crtc; + struct am_meson_crtc *amc; + struct meson_vpu_pipeline_state *mvps; + struct meson_vpu_postblend *postblend = to_postblend_block(vblk); struct osd_scope_s scope = {0, 1919, 0, 1079}; struct meson_vpu_pipeline *pipeline = postblend->base.pipeline; struct postblend_reg_s *reg = postblend->reg; - struct meson_vpu_pipeline_state *mvps; + + crtc = vblk->pipeline->crtc; + amc = to_am_meson_crtc(crtc); DRM_DEBUG("%s set_state called.\n", postblend->base.name); mvps = priv_to_pipeline_state(pipeline->obj.state); @@ -139,6 +147,12 @@ static void postblend_set_state(struct meson_vpu_block *vblk, vpp_osd1_blend_scope_set(reg, scope); if (0) vpp_osd2_blend_scope_set(reg, scope); + + if (amc->blank_enable) + vpp_osd1_postblend_mux_set(postblend->reg, VPP_NULL); + else + vpp_osd1_postblend_mux_set(postblend->reg, VPP_OSD1); + osd1_blend_premult_set(reg); osd2_blend_premult_set(reg); DRM_DEBUG("scope h/v start/end [%d,%d,%d,%d].\n", @@ -159,6 +173,44 @@ static void postblend_hw_disable(struct meson_vpu_block *vblk) DRM_DEBUG("%s disable called.\n", postblend->base.name); } +static void postblend_dump_register(struct meson_vpu_block *vblk, + struct seq_file *seq) +{ + u32 value; + struct meson_vpu_postblend *postblend; + struct postblend_reg_s *reg; + + postblend = to_postblend_block(vblk); + reg = postblend->reg; + + value = meson_drm_read_reg(reg->osd1_blend_src_ctrl); + seq_printf(seq, "%-35s\t\t0x%08X\n", "OSD1_BLEND_SRC_CTRL:", value); + + value = meson_drm_read_reg(reg->osd2_blend_src_ctrl); + seq_printf(seq, "%-35s\t\t0x%08X\n", "OSD2_BLEND_SRC_CTRL:", value); + + value = meson_drm_read_reg(reg->vd1_blend_src_ctrl); + seq_printf(seq, "%-35s\t\t0x%08X\n", "VD1_BLEND_SRC_CTRL:", value); + + value = meson_drm_read_reg(reg->vd2_blend_src_ctrl); + seq_printf(seq, "%-35s\t\t0x%08X\n", "VD2_BLEND_SRC_CTRL:", value); + + value = meson_drm_read_reg(reg->vpp_osd1_in_size); + seq_printf(seq, "%-35s\t\t0x%08X\n", "VPP_OSD1_IN_SIZE:", value); + + value = meson_drm_read_reg(reg->vpp_osd1_bld_h_scope); + seq_printf(seq, "%-35s\t\t0x%08X\n", "VPP_OSD1_BLD_H_SCOPE:", value); + + value = meson_drm_read_reg(reg->vpp_osd1_bld_v_scope); + seq_printf(seq, "%-35s\t\t0x%08X\n", "VPP_OSD1_BLD_V_SCOPE:", value); + + value = meson_drm_read_reg(reg->vpp_osd2_bld_h_scope); + seq_printf(seq, "%-35s\t\t0x%08X\n", "VPP_OSD2_BLD_H_SCOPE:", value); + + value = meson_drm_read_reg(reg->vpp_osd2_bld_v_scope); + seq_printf(seq, "%-35s\t\t0x%08X\n", "VPP_OSD2_BLD_V_SCOPE:", value); +} + static void postblend_hw_init(struct meson_vpu_block *vblk) { struct meson_vpu_postblend *postblend = to_postblend_block(vblk); @@ -180,5 +232,6 @@ struct meson_vpu_block_ops postblend_ops = { .update_state = postblend_set_state, .enable = postblend_hw_enable, .disable = postblend_hw_disable, + .dump_register = postblend_dump_register, .init = postblend_hw_init, }; |