From: Jeonghee Kim Date: Tue, 17 Apr 2018 07:54:49 +0000 (+0900) Subject: media: mfc: add MMCache handling for MFC only X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=3277bb28db9ec417c7d7914b15d5dd918e8c7165;p=GitHub%2FLineageOS%2Fandroid_kernel_motorola_exynos9610.git media: mfc: add MMCache handling for MFC only Change-Id: I4c5368ad277013df30110774a4a445f25de89071 Signed-off-by: Jiho Chang Signed-off-by: Jeonghee Kim --- diff --git a/drivers/media/platform/exynos/mfc/Makefile b/drivers/media/platform/exynos/mfc/Makefile index 36de58256e30..428674d17dd1 100644 --- a/drivers/media/platform/exynos/mfc/Makefile +++ b/drivers/media/platform/exynos/mfc/Makefile @@ -5,3 +5,4 @@ s5p-mfc-y += s5p_mfc_pm.o s5p_mfc_inst.o s5p_mfc_cmd.o s5p_mfc_cal.o s5p_mfc_reg s5p-mfc-y += s5p_mfc_dec_ops.o s5p_mfc_enc_ops.o s5p_mfc_enc_param.o s5p-mfc-y += s5p_mfc_queue.o s5p_mfc_buf.o s5p_mfc_utils.o s5p_mfc_qos.o s5p_mfc_mem.o s5p-mfc-y += s5p_mfc_debugfs.o s5p_mfc_otf.o +s5p-mfc-y += s5p_mfc_mmcache.o diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc.c b/drivers/media/platform/exynos/mfc/s5p_mfc.c index 942e4f126bd1..705ac511f272 100644 --- a/drivers/media/platform/exynos/mfc/s5p_mfc.c +++ b/drivers/media/platform/exynos/mfc/s5p_mfc.c @@ -40,6 +40,7 @@ #include "s5p_mfc_cal.h" #include "s5p_mfc_perf_measure.h" #include "s5p_mfc_reg.h" +#include "s5p_mfc_mmcache.h" #include "s5p_mfc_qos.h" #include "s5p_mfc_queue.h" @@ -385,6 +386,10 @@ static int mfc_init_instance(struct s5p_mfc_dev *dev, struct s5p_mfc_ctx *ctx) goto err_hw_init; } + if (dev->has_mmcache && (dev->mmcache.is_on_status == 0)) + s5p_mfc_mmcache_enable(dev); + + s5p_mfc_release_hwlock_dev(dev); #ifdef NAL_Q_ENABLE @@ -743,6 +748,13 @@ static int s5p_mfc_release(struct file *file) s5p_mfc_qos_off(ctx); + if (dev->has_mmcache && dev->mmcache.is_on_status) { + s5p_mfc_invalidate_mmcache(dev); + + if (dev->num_inst == 0) + s5p_mfc_mmcache_disable(dev); + } + s5p_mfc_release_codec_buffers(ctx); s5p_mfc_release_instance_context(ctx); @@ -992,6 +1004,7 @@ static int mfc_register_resource(struct platform_device *pdev, struct s5p_mfc_de struct device_node *np = dev->device->of_node; struct device_node *iommu; struct device_node *hwfc; + struct device_node *mmcache; struct resource *res; int ret; @@ -1038,12 +1051,24 @@ static int mfc_register_resource(struct platform_device *pdev, struct s5p_mfc_de if (dev->hwfc_base == NULL) { dev->has_hwfc = 0; dev_err(&pdev->dev, "failed to iomap hwfc address region\n"); - goto err_res_hwfc; + goto err_ioremap_hwfc; } else { dev->has_hwfc = 1; } } + mmcache = of_get_child_by_name(np, "mmcache"); + if (mmcache) { + dev->mmcache.base = of_iomap(mmcache, 0); + if (dev->mmcache.base == NULL) { + dev->has_mmcache = 0; + dev_err(&pdev->dev, "failed to iomap mmcache address region\n"); + goto err_ioremap_mmcache; + } else { + dev->has_mmcache = 1; + } + } + res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (res == NULL) { dev_err(&pdev->dev, "failed to get irq resource\n"); @@ -1060,9 +1085,12 @@ static int mfc_register_resource(struct platform_device *pdev, struct s5p_mfc_de return 0; err_res_irq: + if (dev->has_mmcache) + iounmap(dev->mmcache.base); +err_ioremap_mmcache: if (dev->has_hwfc) iounmap(dev->hwfc_base); -err_res_hwfc: +err_ioremap_hwfc: if (dev->has_2sysmmu) iounmap(dev->sysmmu1_base); iounmap(dev->sysmmu0_base); @@ -1278,6 +1306,8 @@ alloc_vdev_dec: err_v4l2_dev: mutex_destroy(&dev->mfc_mutex); free_irq(dev->irq, dev); + if (dev->has_mmcache) + iounmap(dev->mmcache.base); if (dev->has_hwfc) iounmap(dev->hwfc_base); if (dev->has_2sysmmu) @@ -1319,6 +1349,8 @@ static int s5p_mfc_remove(struct platform_device *pdev) mfc_debug(2, "Will now deinit HW\n"); s5p_mfc_deinit_hw(dev); free_irq(dev->irq, dev); + if (dev->has_mmcache) + iounmap(dev->mmcache.base); if (dev->has_hwfc) iounmap(dev->hwfc_base); if (dev->has_2sysmmu) diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_cmd.c b/drivers/media/platform/exynos/mfc/s5p_mfc_cmd.c index 0d7e5c8a2a01..3d2614c8c83a 100644 --- a/drivers/media/platform/exynos/mfc/s5p_mfc_cmd.c +++ b/drivers/media/platform/exynos/mfc/s5p_mfc_cmd.c @@ -16,6 +16,7 @@ #include "s5p_mfc_cal.h" #include "s5p_mfc_reg.h" +#include "s5p_mfc_mmcache.h" #include "s5p_mfc_utils.h" #include "s5p_mfc_buf.h" @@ -225,6 +226,10 @@ int s5p_mfc_cmd_dec_init_buffers(struct s5p_mfc_ctx *ctx) ret = s5p_mfc_set_dec_codec_buffers(ctx); if (ret) { mfc_info_ctx("isn't enough codec buffer size, re-alloc!\n"); + + if (dev->has_mmcache && dev->mmcache.is_on_status) + s5p_mfc_invalidate_mmcache(dev); + s5p_mfc_release_codec_buffers(ctx); ret = s5p_mfc_alloc_codec_buffers(ctx); if (ret) { @@ -275,6 +280,10 @@ int s5p_mfc_cmd_enc_init_buffers(struct s5p_mfc_ctx *ctx) ret = s5p_mfc_set_enc_codec_buffers(ctx); if (ret) { mfc_info_ctx("isn't enough codec buffer size, re-alloc!\n"); + + if (dev->has_mmcache && dev->mmcache.is_on_status) + s5p_mfc_invalidate_mmcache(dev); + s5p_mfc_release_codec_buffers(ctx); ret = s5p_mfc_alloc_codec_buffers(ctx); if (ret) { diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_common.h b/drivers/media/platform/exynos/mfc/s5p_mfc_common.h index 5d9b5c24cbb1..2d6b28fde6fe 100644 --- a/drivers/media/platform/exynos/mfc/s5p_mfc_common.h +++ b/drivers/media/platform/exynos/mfc/s5p_mfc_common.h @@ -44,6 +44,8 @@ #define MFC_HWLOCK_TIMEOUT 5000 /* Busy wait timeout */ #define MFC_BW_TIMEOUT 500 +/* MMCache invalidation timeout */ +#define MMCACHE_INVAL_TIMEOUT 1000 /* Interrupt timeout count*/ #define MFC_INT_TIMEOUT_CNT 2 diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_data_struct.h b/drivers/media/platform/exynos/mfc/s5p_mfc_data_struct.h index dcc1ddd21931..2134b7fb1cf5 100644 --- a/drivers/media/platform/exynos/mfc/s5p_mfc_data_struct.h +++ b/drivers/media/platform/exynos/mfc/s5p_mfc_data_struct.h @@ -337,6 +337,8 @@ struct s5p_mfc_debugfs { struct dentry *otf_dump; struct dentry *perf_measure_option; struct dentry *sfr_dump; + struct dentry *mmcache_dump; + struct dentry *mmcache_disable; struct dentry *debug_mode; }; @@ -672,6 +674,11 @@ struct s5p_mfc_dump_ops { void (*dump_and_stop_debug_mode)(struct s5p_mfc_dev *dev); }; +struct s5p_mfc_mmcache { + void __iomem *base; + int is_on_status; +}; + /** * struct s5p_mfc_dev - The struct containing driver internal parameters. */ @@ -710,8 +717,9 @@ struct s5p_mfc_dev { wait_queue_head_t cmd_wq; struct s5p_mfc_listable_wq hwlock_wq; - bool has_hwfc; bool has_2sysmmu; + bool has_hwfc; + bool has_mmcache; struct s5p_mfc_special_buf common_ctx_buf; struct s5p_mfc_special_buf drm_common_ctx_buf; @@ -777,6 +785,8 @@ struct s5p_mfc_dev { struct s5p_mfc_dump_ops *dump_ops; struct s5p_mfc_perf perf; + + struct s5p_mfc_mmcache mmcache; }; /** diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_debug.h b/drivers/media/platform/exynos/mfc/s5p_mfc_debug.h index 8d626590e93f..2b9f45a74388 100644 --- a/drivers/media/platform/exynos/mfc/s5p_mfc_debug.h +++ b/drivers/media/platform/exynos/mfc/s5p_mfc_debug.h @@ -25,6 +25,8 @@ extern unsigned int nal_q_disable; extern unsigned int nal_q_parallel_disable; extern unsigned int otf_dump; extern unsigned int sfr_dump; +extern unsigned int mmcache_dump; +extern unsigned int mmcache_disable; extern unsigned int debug_mode; #define mfc_debug(level, fmt, args...) \ diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_debugfs.c b/drivers/media/platform/exynos/mfc/s5p_mfc_debugfs.c index 58a824fc0803..03a98b7759fd 100644 --- a/drivers/media/platform/exynos/mfc/s5p_mfc_debugfs.c +++ b/drivers/media/platform/exynos/mfc/s5p_mfc_debugfs.c @@ -29,6 +29,8 @@ unsigned int nal_q_parallel_disable; unsigned int otf_dump; unsigned int perf_measure_option; unsigned int sfr_dump; +unsigned int mmcache_dump; +unsigned int mmcache_disable; /* It will be disable after driver is stabilized */ unsigned int debug_mode = 1; @@ -50,6 +52,9 @@ static int mfc_info_show(struct seq_file *s, void *unused) seq_printf(s, "[HWLOCK] bits: %#lx, dev: %#lx, owned_by_irq = %d, wl_count = %d\n", dev->hwlock.bits, dev->hwlock.dev, dev->hwlock.owned_by_irq, dev->hwlock.wl_count); + seq_printf(s, "[MMCACHE] %s(%s)\n", + dev->has_mmcache ? "supported" : "not supported", + dev->mmcache.is_on_status ? "enabled" : "disabled"); if (dev->nal_q_handle) seq_printf(s, "[NAL-Q] state: %d\n", dev->nal_q_handle->nal_q_state); @@ -151,6 +156,10 @@ void s5p_mfc_init_debugfs(struct s5p_mfc_dev *dev) 0644, debugfs->root, &perf_measure_option); debugfs->sfr_dump = debugfs_create_u32("sfr_dump", 0644, debugfs->root, &sfr_dump); + debugfs->mmcache_dump = debugfs_create_u32("mmcache_dump", + 0644, debugfs->root, &mmcache_dump); + debugfs->mmcache_disable = debugfs_create_u32("mmcache_disable", + 0644, debugfs->root, &mmcache_disable); debugfs->debug_mode = debugfs_create_u32("debug_mode", 0644, debugfs->root, &debug_mode); } diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_dec.c b/drivers/media/platform/exynos/mfc/s5p_mfc_dec.c index bd0f354f372f..001e3b3aedfe 100644 --- a/drivers/media/platform/exynos/mfc/s5p_mfc_dec.c +++ b/drivers/media/platform/exynos/mfc/s5p_mfc_dec.c @@ -16,6 +16,7 @@ #include "s5p_mfc_hwlock.h" #include "s5p_mfc_opr.h" #include "s5p_mfc_sync.h" +#include "s5p_mfc_mmcache.h" #include "s5p_mfc_qos.h" #include "s5p_mfc_queue.h" @@ -626,6 +627,10 @@ static int vidioc_reqbufs(struct file *file, void *priv, if (reqbufs->count == 0) { mfc_debug(2, "Freeing buffers.\n"); ret = vb2_reqbufs(&ctx->vq_dst, reqbufs); + + if (dev->has_mmcache && dev->mmcache.is_on_status) + s5p_mfc_invalidate_mmcache(dev); + s5p_mfc_release_codec_buffers(ctx); ctx->capture_state = QUEUE_FREE; return ret; diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_irq.c b/drivers/media/platform/exynos/mfc/s5p_mfc_irq.c index 228679f98349..403fdba16e65 100644 --- a/drivers/media/platform/exynos/mfc/s5p_mfc_irq.c +++ b/drivers/media/platform/exynos/mfc/s5p_mfc_irq.c @@ -22,6 +22,7 @@ #include "s5p_mfc_cal.h" #include "s5p_mfc_perf_measure.h" #include "s5p_mfc_reg.h" +#include "s5p_mfc_mmcache.h" #include "s5p_mfc_qos.h" #include "s5p_mfc_queue.h" @@ -746,6 +747,9 @@ static void mfc_enc_res_change(struct s5p_mfc_ctx *ctx) mfc_debug(2, "Encoding Resolution Status : %d\n", reg); if (reg == 2 || reg == 3) { + if (dev->has_mmcache && dev->mmcache.is_on_status) + s5p_mfc_invalidate_mmcache(dev); + s5p_mfc_release_codec_buffers(ctx); /* for INIT_BUFFER cmd */ s5p_mfc_change_state(ctx, MFCINST_HEAD_PARSED); diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_mmcache.c b/drivers/media/platform/exynos/mfc/s5p_mfc_mmcache.c new file mode 100644 index 000000000000..a5a07b7888d7 --- /dev/null +++ b/drivers/media/platform/exynos/mfc/s5p_mfc_mmcache.c @@ -0,0 +1,232 @@ +/* + * drivers/media/platform/exynos/mfc/s5p_mfc_mmcache.c + * + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * http://www.samsung.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. + */ + +#include "s5p_mfc_mmcache.h" + +#include "s5p_mfc_reg.h" + +static const unsigned char mmcache_SFR_0x0010[] = { + 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x2A, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +static const unsigned char mmcache_SFR_0x0040[] = { + 0x0E, 0x00, 0x1E, 0x00, 0x0E, 0x00, 0x1E, 0x00, 0x0E, 0x00, 0x1E, 0x00, 0x0E, 0x00, 0x1E, 0x00, + 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, + 0x10, 0x00, 0x1F, 0x00, 0x10, 0x00, 0x1F, 0x00, 0x10, 0x00, 0x1F, 0x00, 0x10, 0x00, 0x1F, 0x00, + 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, + 0x0C, 0x00, 0x1F, 0x00, 0x0C, 0x00, 0x1F, 0x00, 0x0C, 0x00, 0x1F, 0x00, 0x0C, 0x00, 0x1F, 0x00, + 0x12, 0x00, 0x3F, 0x00, 0x08, 0x00, 0x3F, 0x00, 0x0C, 0x00, 0x3D, 0x00, 0x0C, 0x00, 0x3D, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +static void mmcache_print_config(struct s5p_mfc_dev *dev) +{ + void __iomem *addr; + unsigned int size; + + mfc_debug_enter(); + + if (!mmcache_dump) + return; + + size = sizeof(mmcache_SFR_0x0010); + addr = dev->mmcache.base + MMCACHE_WAY0_CTRL; + + print_hex_dump(KERN_ERR, "[MMCACHE] Config:", DUMP_PREFIX_ADDRESS, 32, 4, addr, size, false); + + size = sizeof(mmcache_SFR_0x0040); + addr = dev->mmcache.base + MMCACHE_MASTER_GRP0_RPATH0; + + print_hex_dump(KERN_ERR, "[MMCACHE] Config:", DUMP_PREFIX_ADDRESS, 32, 4, addr, size, false); + + mfc_debug_leave(); +} + +static void mmcache_set_config(struct s5p_mfc_dev *dev) +{ + unsigned int data, i, size; + const unsigned int *sfr_dump; + + mfc_debug_enter(); + + size = sizeof(mmcache_SFR_0x0010); + sfr_dump = (const unsigned int *)mmcache_SFR_0x0010; + + for (i = 0; i < size; i += 4) { + data = sfr_dump[i / 4]; + MMCACHE_WRITEL(data, MMCACHE_WAY0_CTRL + i); + } + + size = sizeof(mmcache_SFR_0x0040); + sfr_dump = (const unsigned int *)mmcache_SFR_0x0040; + + for (i = 0; i < size; i += 4) { + data = sfr_dump[i / 4]; + MMCACHE_WRITEL(data, MMCACHE_MASTER_GRP0_RPATH0 + i); + } + + mfc_debug(2, "[MMCACHE] mmcache config setting is done\n"); + + mfc_debug_leave(); +} + +static void mmcache_reset_config(struct s5p_mfc_dev *dev) +{ + void __iomem *addr; + unsigned int data; + + mfc_debug_enter(); + + addr = dev->mmcache.base + MMCACHE_MASTER_GRP_CTRL2; + data = 0; + + mfc_debug(2, "[MMCACHE] before write 0x%X: (0x%08llX) 0x%X\n", + data, (unsigned long long)(addr), + MMCACHE_READL(MMCACHE_MASTER_GRP_CTRL2)); + + MMCACHE_WRITEL(data, MMCACHE_MASTER_GRP_CTRL2); + + mfc_debug(2, "[MMCACHE] after write 0x%X: (0x%08llX) 0x%X\n", + data, (unsigned long long)(addr), + MMCACHE_READL(MMCACHE_MASTER_GRP_CTRL2)); + + mfc_debug_leave(); +} + +static void mmcache_update_master_grp(struct s5p_mfc_dev *dev) +{ + void __iomem *addr; + unsigned int data; + + mfc_debug_enter(); + + addr = dev->mmcache.base + MMCACHE_GLOBAL_CTRL; + data = MMCACHE_GLOBAL_CTRL_VALUE; + + mfc_debug(2, "[MMCACHE] before write 0x%X: (0x%08llX) 0x%X\n", + data, (unsigned long long)(addr), + MMCACHE_READL(MMCACHE_GLOBAL_CTRL)); + + MMCACHE_WRITEL(data, MMCACHE_GLOBAL_CTRL); + + mfc_debug(2, "[MMCACHE] after write 0x%X: (0x%08llX) 0x%X\n", + data, (unsigned long long)(addr), + MMCACHE_READL(MMCACHE_GLOBAL_CTRL)); + + mfc_debug_leave(); +} + +static void mmcache_enable_clock_gating(struct s5p_mfc_dev *dev) +{ + void __iomem *addr; + unsigned int data; + + mfc_debug_enter(); + + addr = dev->mmcache.base + MMCACHE_CG_CONTROL; + data = MMCACHE_CG_CONTROL_VALUE; + + mfc_debug(2, "[MMCACHE] before write 0x%X: (0x%08llX) 0x%X\n", + data, (unsigned long long)(addr), + MMCACHE_READL(MMCACHE_CG_CONTROL)); + + MMCACHE_WRITEL(data, MMCACHE_CG_CONTROL); + + mfc_debug(2, "[MMCACHE] after write 0x%X: (0x%08llX) 0x%X\n", + data, (unsigned long long)(addr), + MMCACHE_READL(MMCACHE_CG_CONTROL)); + + mfc_debug_leave(); +} + +void s5p_mfc_mmcache_enable(struct s5p_mfc_dev *dev) +{ + mfc_debug_enter(); + + if (mmcache_disable) + return; + + mmcache_set_config(dev); + mmcache_print_config(dev); + mmcache_update_master_grp(dev); + mmcache_enable_clock_gating(dev); + + dev->mmcache.is_on_status = 1; + mfc_info_dev("[MMCACHE] enabled\n"); + MFC_TRACE_DEV("[MMCACHE] enabled\n"); + + mfc_debug_leave(); +} + +void s5p_mfc_mmcache_disable(struct s5p_mfc_dev *dev) +{ + mfc_debug_enter(); + + mmcache_reset_config(dev); + mmcache_update_master_grp(dev); + + dev->mmcache.is_on_status = 0; + mfc_info_dev("[MMCACHE] disabled\n"); + MFC_TRACE_DEV("[MMCACHE] disabled\n"); + + mfc_debug_leave(); +} + +void s5p_mfc_invalidate_mmcache(struct s5p_mfc_dev *dev) +{ + void __iomem *addr; + unsigned int data; + unsigned long timeout; + + mfc_debug_enter(); + + addr = dev->mmcache.base + MMCACHE_INVALIDATE; + data = MMCACHE_INVALIDATE_VALUE; + + mfc_debug(2, "[MMCACHE] before write 0x%X: (0x%08llX) 0x%X\n", + data, (unsigned long long)(addr), + MMCACHE_READL(MMCACHE_INVALIDATE)); + + MMCACHE_WRITEL(data, MMCACHE_INVALIDATE); + + mfc_debug(2, "[MMCACHE] after write 0x%X: (0x%08llX) 0x%X\n", + data, (unsigned long long)(addr), + MMCACHE_READL(MMCACHE_INVALIDATE)); + + addr = dev->mmcache.base + MMCACHE_INVALIDATE_STATUS; + + timeout = jiffies + msecs_to_jiffies(MMCACHE_INVAL_TIMEOUT); + while (1) { + if (MMCACHE_READL(MMCACHE_INVALIDATE_STATUS) == 0) { + mfc_debug(2, "[MMCACHE] invalidate done: (0x%08llX) 0x%X\n", + (unsigned long long)(addr), __raw_readl(addr)); + break; + } + if (time_after(jiffies, timeout)) { + mfc_err_dev("[MMCACHE] Timeout while invalidation.\n"); + call_dop(dev, dump_and_stop_debug_mode, dev); + break; + } + } + + mfc_debug(2, "[MMCACHE] invalidated\n"); + MFC_TRACE_DEV("[MMCACHE] invalidated\n"); + + mfc_debug_leave(); +} diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_mmcache.h b/drivers/media/platform/exynos/mfc/s5p_mfc_mmcache.h new file mode 100644 index 000000000000..f4cfa4d49928 --- /dev/null +++ b/drivers/media/platform/exynos/mfc/s5p_mfc_mmcache.h @@ -0,0 +1,39 @@ +/* + * drivers/media/platform/exynos/mfc/s5p_mfc_mmcache.h + * + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * http://www.samsung.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. + */ + +#ifndef __S5P_MFC_MMCACHE_H +#define __S5P_MFC_MMCACHE_H __FILE__ + +#include "s5p_mfc_common.h" + +#define MMCACHE_GLOBAL_CTRL 0x0000 +#define MMCACHE_INVALIDATE_STATUS 0x0008 +#define MMCACHE_WAY0_CTRL 0x0010 +#define MMCACHE_MASTER_GRP_CTRL2 0x0028 +#define MMCACHE_MASTER_GRP0_RPATH0 0x0040 +#define MMCACHE_CG_CONTROL 0x0400 +#define MMCACHE_INVALIDATE 0x0114 + +#define MMCACHE_GLOBAL_CTRL_VALUE 0x2 +#define MMCACHE_CG_CONTROL_VALUE 0x7FF +#define MMCACHE_INVALIDATE_VALUE 0x41 + +/* Need HW lock to call this function */ + +void s5p_mfc_mmcache_enable(struct s5p_mfc_dev *dev); +void s5p_mfc_mmcache_disable(struct s5p_mfc_dev *dev); + + +/* Need HW lock to call this function */ +void s5p_mfc_invalidate_mmcache(struct s5p_mfc_dev *dev); + +#endif /* __S5P_MFC_MMCACHE_H */ diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_reg.c b/drivers/media/platform/exynos/mfc/s5p_mfc_reg.c index e8c77f03de7c..aee8f0ebad27 100644 --- a/drivers/media/platform/exynos/mfc/s5p_mfc_reg.c +++ b/drivers/media/platform/exynos/mfc/s5p_mfc_reg.c @@ -78,7 +78,7 @@ void s5p_mfc_otf_set_hwfc_index(struct s5p_mfc_ctx *ctx, int job_id) struct s5p_mfc_dev *dev = ctx->dev; mfc_debug(2, "OTF: set hwfc index, %d\n", job_id); - MFC_WRITEL_HWFC(job_id, HWFC_ENCODING_IDX); + HWFC_WRITEL(job_id, HWFC_ENCODING_IDX); } /* Set decoding frame buffer */ diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_reg.h b/drivers/media/platform/exynos/mfc/s5p_mfc_reg.h index d8700bb91a80..bc4b11544275 100644 --- a/drivers/media/platform/exynos/mfc/s5p_mfc_reg.h +++ b/drivers/media/platform/exynos/mfc/s5p_mfc_reg.h @@ -23,7 +23,10 @@ #define MFC_MMU0_READL(offset) readl(dev->sysmmu0_base + (offset)) #define MFC_MMU1_READL(offset) readl(dev->sysmmu1_base + (offset)) -#define MFC_WRITEL_HWFC(data, offset) writel((data), dev->hwfc_base + (offset)) +#define HWFC_WRITEL(data, offset) writel((data), dev->hwfc_base + (offset)) + +#define MMCACHE_READL(offset) readl(dev->mmcache.base + (offset)) +#define MMCACHE_WRITEL(data, offset) writel((data), dev->mmcache.base + (offset)) /* version */ #define s5p_mfc_get_fimv_info() ((MFC_READL(S5P_FIMV_FW_VERSION) \